提交 57894811 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #568 from NiklasMehner/master

Implement MetaData.getColumns() for synonyms.
......@@ -225,6 +225,7 @@ public class Parser {
private ArrayList<String> expectedList;
private boolean rightsChecked;
private boolean recompileAlways;
private boolean literalsChecked;
private ArrayList<Parameter> indexedParameterList;
private int orderInFrom;
private ArrayList<Parameter> suppliedParameterList;
......@@ -3529,7 +3530,7 @@ public class Parser {
}
private void checkLiterals(boolean text) {
if (!session.getAllowLiterals()) {
if (!literalsChecked && !session.getAllowLiterals()) {
int allowed = database.getAllowLiterals();
if (allowed == Constants.ALLOW_LITERALS_NONE ||
(text && allowed != Constants.ALLOW_LITERALS_ALL)) {
......@@ -5036,11 +5037,11 @@ public class Parser {
// then we just compile it again.
TableView view = new TableView(schema, id, tempViewName, querySQL,
parameters, columnTemplateList.toArray(new Column[0]), session,
true/* recursive */);
true/* recursive */, false);
if (!view.isRecursiveQueryDetected()) {
view = new TableView(schema, id, tempViewName, querySQL, parameters,
columnTemplateList.toArray(new Column[0]), session,
false/* recursive */);
false/* recursive */, false);
}
view.setTableExpression(true);
view.setTemporary(true);
......@@ -6490,6 +6491,10 @@ public class Parser {
return s;
}
public void setLiteralsChecked(boolean literalsChecked) {
this.literalsChecked = literalsChecked;
}
public void setRightsChecked(boolean rightsChecked) {
this.rightsChecked = rightsChecked;
}
......
......@@ -116,9 +116,9 @@ public class CreateView extends SchemaCommand {
}
}
view = new TableView(getSchema(), id, viewName, querySQL, null,
columnTemplates, sysSession, false);
columnTemplates, sysSession, false, false);
} else {
view.replace(querySQL, sysSession, false, force);
view.replace(querySQL, sysSession, false, force, false);
view.setModified();
}
} finally {
......
......@@ -527,7 +527,7 @@ public class Session extends SessionWithState {
* @return the prepared statement
*/
public Prepared prepare(String sql) {
return prepare(sql, false);
return prepare(sql, false, false);
}
/**
......@@ -535,11 +535,14 @@ public class Session extends SessionWithState {
*
* @param sql the SQL statement
* @param rightsChecked true if the rights have already been checked
* @param literalsChecked true if the sql string has already been checked for literals (only used if
* ALLOW_LITERALS NONE is set).
* @return the prepared statement
*/
public Prepared prepare(String sql, boolean rightsChecked) {
public Prepared prepare(String sql, boolean rightsChecked, boolean literalsChecked) {
Parser parser = new Parser(this);
parser.setRightsChecked(rightsChecked);
parser.setLiteralsChecked(literalsChecked);
return parser.prepare(sql);
}
......
......@@ -173,7 +173,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
Prepared p;
session.pushSubQueryInfo(masks, filters, filter, sortOrder);
try {
p = session.prepare(sql, true);
p = session.prepare(sql, true, true);
} finally {
session.popSubQueryInfo();
}
......
......@@ -282,7 +282,7 @@ public class JdbcDatabaseMetaData extends TraceObject implements
+quote(columnNamePattern)+");");
}
checkClosed();
PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT "
String tableSql = "SELECT "
+ "TABLE_CATALOG TABLE_CAT, "
+ "TABLE_SCHEMA TABLE_SCHEM, "
+ "TABLE_NAME, "
......@@ -313,7 +313,67 @@ public class JdbcDatabaseMetaData extends TraceObject implements
+ "AND TABLE_SCHEMA LIKE ? ESCAPE ? "
+ "AND TABLE_NAME LIKE ? ESCAPE ? "
+ "AND COLUMN_NAME LIKE ? ESCAPE ? "
+ "ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
+ "ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION";
String synonymSql = "SELECT "
+ "s.SYNONYM_CATALOG TABLE_CAT, "
+ "s.SYNONYM_SCHEMA TABLE_SCHEM, "
+ "s.SYNONYM_NAME TABLE_NAME, "
+ "c.COLUMN_NAME, "
+ "c.DATA_TYPE, "
+ "c.TYPE_NAME, "
+ "c.CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, "
+ "c.CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, "
+ "c.NUMERIC_SCALE DECIMAL_DIGITS, "
+ "c.NUMERIC_PRECISION_RADIX NUM_PREC_RADIX, "
+ "c.NULLABLE, "
+ "c.REMARKS, "
+ "c.COLUMN_DEFAULT COLUMN_DEF, "
+ "c.DATA_TYPE SQL_DATA_TYPE, "
+ "ZERO() SQL_DATETIME_SUB, "
+ "c.CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH, "
+ "c.ORDINAL_POSITION, "
+ "c.IS_NULLABLE IS_NULLABLE, "
+ "CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATALOG, "
+ "CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_SCHEMA, "
+ "CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_TABLE, "
+ "c.SOURCE_DATA_TYPE, "
+ "CASE WHEN c.SEQUENCE_NAME IS NULL THEN "
+ "CAST(? AS VARCHAR) ELSE CAST(? AS VARCHAR) END IS_AUTOINCREMENT, "
+ "CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATLOG "
+ "FROM INFORMATION_SCHEMA.COLUMNS c JOIN INFORMATION_SCHEMA.SYNONYMS s ON "
+ "s.SYNONYM_FOR = c.TABLE_NAME "
+ "AND s.SYNONYM_FOR_SCHEMA = c.TABLE_SCHEMA "
+ "WHERE s.SYNONYM_CATALOG LIKE ? ESCAPE ? "
+ "AND s.SYNONYM_SCHEMA LIKE ? ESCAPE ? "
+ "AND s.SYNONYM_NAME LIKE ? ESCAPE ? "
+ "AND c.COLUMN_NAME LIKE ? ESCAPE ? ";
PreparedStatement prep = conn.prepareAutoCloseStatement("SELECT "
+ "TABLE_CAT, "
+ "TABLE_SCHEM, "
+ "TABLE_NAME, "
+ "COLUMN_NAME, "
+ "DATA_TYPE, "
+ "TYPE_NAME, "
+ "COLUMN_SIZE, "
+ "BUFFER_LENGTH, "
+ "DECIMAL_DIGITS, "
+ "NUM_PREC_RADIX, "
+ "NULLABLE, "
+ "REMARKS, "
+ "COLUMN_DEF, "
+ "SQL_DATA_TYPE, "
+ "SQL_DATETIME_SUB, "
+ "CHAR_OCTET_LENGTH, "
+ "ORDINAL_POSITION, "
+ "IS_NULLABLE, "
+ "SCOPE_CATALOG, "
+ "SCOPE_SCHEMA, "
+ "SCOPE_TABLE, "
+ "SOURCE_DATA_TYPE, "
+ "IS_AUTOINCREMENT, "
+ "SCOPE_CATLOG "
+ "FROM ((" + tableSql + ") UNION (" + synonymSql
+ ")) ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
prep.setString(1, "NO");
prep.setString(2, "YES");
prep.setString(3, getCatalogPattern(catalogPattern));
......@@ -324,6 +384,16 @@ public class JdbcDatabaseMetaData extends TraceObject implements
prep.setString(8, "\\");
prep.setString(9, getPattern(columnNamePattern));
prep.setString(10, "\\");
prep.setString(11, "NO");
prep.setString(12, "YES");
prep.setString(13, getCatalogPattern(catalogPattern));
prep.setString(14, "\\");
prep.setString(15, getSchemaPattern(schemaPattern));
prep.setString(16, "\\");
prep.setString(17, getPattern(tableNamePattern));
prep.setString(18, "\\");
prep.setString(19, getPattern(columnNamePattern));
prep.setString(20, "\\");
return prep.executeQuery();
} catch (Exception e) {
throw logAndConvert(e);
......
......@@ -546,6 +546,7 @@ public class MetaTable extends Table {
"SYNONYM_SCHEMA",
"SYNONYM_NAME",
"SYNONYM_FOR",
"SYNONYM_FOR_SCHEMA",
"TYPE_NAME",
"STATUS",
"REMARKS",
......@@ -1889,6 +1890,8 @@ public class MetaTable extends Table {
identifier(synonym.getName()),
// SYNONYM_FOR
synonym.getSynonymForName(),
// SYNONYM_FOR_SCHEMA
synonym.getSynonymForSchema().getName(),
// TYPE NAME
"SYNONYM",
// STATUS
......
......@@ -9,6 +9,7 @@ import org.h2.command.ddl.CreateSynonymData;
import org.h2.engine.Session;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.schema.Schema;
import org.h2.schema.SchemaObjectBase;
/**
......@@ -73,6 +74,10 @@ public class TableSynonym extends SchemaObjectBase {
return data.synonymFor;
}
public Schema getSynonymForSchema() {
return data.synonymForSchema;
}
public boolean isInvalid() {
return synonymFor.isValid();
}
......
......@@ -61,9 +61,9 @@ public class TableView extends Table {
public TableView(Schema schema, int id, String name, String querySQL,
ArrayList<Parameter> params, Column[] columnTemplates, Session session,
boolean recursive) {
boolean recursive, boolean literalsChecked) {
super(schema, id, name, false, true);
init(querySQL, params, columnTemplates, session, recursive);
init(querySQL, params, columnTemplates, session, recursive, literalsChecked);
}
/**
......@@ -76,34 +76,34 @@ public class TableView extends Table {
* @param force if errors should be ignored
*/
public void replace(String querySQL, Session session,
boolean recursive, boolean force) {
boolean recursive, boolean force, boolean literalsChecked) {
String oldQuerySQL = this.querySQL;
Column[] oldColumnTemplates = this.columnTemplates;
boolean oldRecursive = this.recursive;
init(querySQL, null, columnTemplates, session, recursive);
init(querySQL, null, columnTemplates, session, recursive, literalsChecked);
DbException e = recompile(session, force, true);
if (e != null) {
init(oldQuerySQL, null, oldColumnTemplates, session, oldRecursive);
init(oldQuerySQL, null, oldColumnTemplates, session, oldRecursive, literalsChecked);
recompile(session, true, false);
throw e;
}
}
private synchronized void init(String querySQL, ArrayList<Parameter> params,
Column[] columnTemplates, Session session, boolean recursive) {
Column[] columnTemplates, Session session, boolean recursive, boolean literalsChecked) {
this.querySQL = querySQL;
this.columnTemplates = columnTemplates;
this.recursive = recursive;
this.isRecursiveQueryDetected = false;
index = new ViewIndex(this, querySQL, params, recursive);
initColumnsAndTables(session);
initColumnsAndTables(session, literalsChecked);
}
private static Query compileViewQuery(Session session, String sql) {
private static Query compileViewQuery(Session session, String sql, boolean literalsChecked) {
Prepared p;
session.setParsingView(true);
try {
p = session.prepare(sql);
p = session.prepare(sql, false, literalsChecked);
} finally {
session.setParsingView(false);
}
......@@ -125,7 +125,7 @@ public class TableView extends Table {
public synchronized DbException recompile(Session session, boolean force,
boolean clearIndexCache) {
try {
compileViewQuery(session, querySQL);
compileViewQuery(session, querySQL, false);
} catch (DbException e) {
if (!force) {
return e;
......@@ -135,7 +135,7 @@ public class TableView extends Table {
if (views != null) {
views = New.arrayList(views);
}
initColumnsAndTables(session);
initColumnsAndTables(session, false);
if (views != null) {
for (TableView v : views) {
DbException e = v.recompile(session, force, false);
......@@ -150,11 +150,11 @@ public class TableView extends Table {
return force ? null : createException;
}
private void initColumnsAndTables(Session session) {
private void initColumnsAndTables(Session session, boolean literalsChecked) {
Column[] cols;
removeViewFromTables();
try {
Query query = compileViewQuery(session, querySQL);
Query query = compileViewQuery(session, querySQL, literalsChecked);
this.querySQL = query.getPlanSQL();
tables = New.arrayList(query.getTables());
ArrayList<Expression> expressions = query.getExpressions();
......@@ -539,7 +539,7 @@ public class TableView extends Table {
String querySQL = query.getPlanSQL();
TableView v = new TableView(mainSchema, 0, name,
querySQL, query.getParameters(), null, session,
false);
false, true /* literals have already been checked when parsing original query */);
if (v.createException != null) {
throw v.createException;
}
......
......@@ -171,6 +171,12 @@ public class TestSynonymForTable extends TestBase {
assertEquals(tables.getString("TABLE_TYPE"), "SYNONYM");
assertFalse(tables.next());
ResultSet columns = conn.getMetaData().getColumns(null, Constants.SCHEMA_MAIN, "TESTSYNONYM", null);
assertTrue(columns.next());
assertEquals(columns.getString("TABLE_NAME"), "TESTSYNONYM");
assertEquals(columns.getString("COLUMN_NAME"), "ID");
assertFalse(columns.next());
ResultSet synonyms = conn.createStatement().executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYNONYMS");
assertTrue(synonyms.next());
assertEquals("SYNONYM", synonyms.getString("SYNONYM_CATALOG"));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论