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