提交 12fab607 authored 作者: Thomas Mueller's avatar Thomas Mueller

Multiple nested queries in the FROM clause with parameters did not always work.

上级 0fcdc214
...@@ -939,7 +939,7 @@ public class Parser { ...@@ -939,7 +939,7 @@ public class Parser {
s = session; s = session;
} }
alias = session.getNextSystemIdentifier(sqlCommand); alias = session.getNextSystemIdentifier(sqlCommand);
table = TableView.createTempView(s, session.getUser(), alias, query); table = TableView.createTempView(s, session.getUser(), alias, query, currentSelect);
} else { } else {
TableFilter top = readTableFilter(fromOuter); TableFilter top = readTableFilter(fromOuter);
top = readJoin(top, currentSelect, fromOuter); top = readJoin(top, currentSelect, fromOuter);
......
...@@ -140,7 +140,7 @@ public class ConditionInSelect extends Condition { ...@@ -140,7 +140,7 @@ public class ConditionInSelect extends Condition {
return this; return this;
} }
String name = session.getNextSystemIdentifier(select.getSQL()); String name = session.getNextSystemIdentifier(select.getSQL());
TableView view = TableView.createTempView(session, session.getUser(), name, query); TableView view = TableView.createTempView(session, session.getUser(), name, query, select);
TableFilter filter = new TableFilter(session, view, name, false, select); TableFilter filter = new TableFilter(session, view, name, false, select);
select.addTableFilter(filter, true); select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(session.getDatabase(), null, view.getName(), alias); ExpressionColumn column = new ExpressionColumn(session.getDatabase(), null, view.getName(), alias);
......
...@@ -29,9 +29,10 @@ import org.h2.value.Value; ...@@ -29,9 +29,10 @@ import org.h2.value.Value;
*/ */
public class ViewIndex extends BaseIndex { public class ViewIndex extends BaseIndex {
private String querySQL; private final TableView view;
private ObjectArray originalParameters; private final String querySQL;
private SmallLRUCache costCache = new SmallLRUCache(Constants.VIEW_INDEX_CACHE_SIZE); private final ObjectArray originalParameters;
private final SmallLRUCache costCache = new SmallLRUCache(Constants.VIEW_INDEX_CACHE_SIZE);
private boolean recursive; private boolean recursive;
private int[] masks; private int[] masks;
private String planSQL; private String planSQL;
...@@ -40,6 +41,7 @@ public class ViewIndex extends BaseIndex { ...@@ -40,6 +41,7 @@ public class ViewIndex extends BaseIndex {
public ViewIndex(TableView view, String querySQL, ObjectArray originalParameters, boolean recursive) { public ViewIndex(TableView view, String querySQL, ObjectArray originalParameters, boolean recursive) {
initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false)); initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false));
this.view = view;
this.querySQL = querySQL; this.querySQL = querySQL;
this.originalParameters = originalParameters; this.originalParameters = originalParameters;
this.recursive = recursive; this.recursive = recursive;
...@@ -48,6 +50,7 @@ public class ViewIndex extends BaseIndex { ...@@ -48,6 +50,7 @@ public class ViewIndex extends BaseIndex {
public ViewIndex(TableView view, ViewIndex index, Session session, int[] masks) throws SQLException { public ViewIndex(TableView view, ViewIndex index, Session session, int[] masks) throws SQLException {
initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false)); initBaseIndex(view, 0, null, null, IndexType.createNonUnique(false));
this.view = view;
this.querySQL = index.querySQL; this.querySQL = index.querySQL;
this.originalParameters = index.originalParameters; this.originalParameters = index.originalParameters;
this.recursive = index.recursive; this.recursive = index.recursive;
...@@ -122,7 +125,7 @@ public class ViewIndex extends BaseIndex { ...@@ -122,7 +125,7 @@ public class ViewIndex extends BaseIndex {
Column col = table.getColumn(idx); Column col = table.getColumn(idx);
columns[i] = col; columns[i] = col;
int mask = masks[idx]; int mask = masks[idx];
int nextParamIndex = query.getParameters().size(); int nextParamIndex = query.getParameters().size() + view.getParameterOffset();
if ((mask & IndexCondition.EQUALITY) != 0) { if ((mask & IndexCondition.EQUALITY) != 0) {
Parameter param = new Parameter(nextParamIndex); Parameter param = new Parameter(nextParamIndex);
query.addGlobalCondition(param, idx, Comparison.EQUAL); query.addGlobalCondition(param, idx, Comparison.EQUAL);
...@@ -172,6 +175,7 @@ public class ViewIndex extends BaseIndex { ...@@ -172,6 +175,7 @@ public class ViewIndex extends BaseIndex {
len = 0; len = 0;
} }
int idx = originalParameters == null ? 0 : originalParameters.size(); int idx = originalParameters == null ? 0 : originalParameters.size();
idx += view.getParameterOffset();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (first != null) { if (first != null) {
Value v = first.getValue(i); Value v = first.getValue(i);
...@@ -199,6 +203,7 @@ public class ViewIndex extends BaseIndex { ...@@ -199,6 +203,7 @@ public class ViewIndex extends BaseIndex {
return query; return query;
} }
int firstIndexParam = originalParameters == null ? 0 : originalParameters.size(); int firstIndexParam = originalParameters == null ? 0 : originalParameters.size();
firstIndexParam += view.getParameterOffset();
IntArray paramIndex = new IntArray(); IntArray paramIndex = new IntArray();
for (int i = 0; i < masks.length; i++) { for (int i = 0; i < masks.length; i++) {
int mask = masks[i]; int mask = masks[i];
......
...@@ -44,6 +44,7 @@ public class TableView extends Table { ...@@ -44,6 +44,7 @@ public class TableView extends Table {
private long lastModificationCheck; private long lastModificationCheck;
private long maxDataModificationId; private long maxDataModificationId;
private User owner; private User owner;
private Query topQuery;
public TableView(Schema schema, int id, String name, String querySQL, ObjectArray params, String[] columnNames, public TableView(Schema schema, int id, String name, String querySQL, ObjectArray params, String[] columnNames,
Session session, boolean recursive) throws SQLException { Session session, boolean recursive) throws SQLException {
...@@ -342,13 +343,15 @@ public class TableView extends Table { ...@@ -342,13 +343,15 @@ public class TableView extends Table {
* @param owner the owner of the query * @param owner the owner of the query
* @param name the view name * @param name the view name
* @param query the query * @param query the query
* @param topQuery the top level query
* @return the view table * @return the view table
*/ */
public static TableView createTempView(Session session, User owner, String name, Query query) throws SQLException { public static TableView createTempView(Session session, User owner, String name, Query query, Query topQuery) throws SQLException {
Schema mainSchema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN); Schema mainSchema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN);
String querySQL = query.getPlanSQL(); String querySQL = query.getPlanSQL();
TableView v = new TableView(mainSchema, 0, name, querySQL, query.getParameters(), null, session, TableView v = new TableView(mainSchema, 0, name, querySQL, query.getParameters(), null, session,
false); false);
v.setTopQuery(topQuery);
if (v.createException != null) { if (v.createException != null) {
throw v.createException; throw v.createException;
} }
...@@ -357,8 +360,16 @@ public class TableView extends Table { ...@@ -357,8 +360,16 @@ public class TableView extends Table {
return v; return v;
} }
private void setTopQuery(Query topQuery) {
this.topQuery = topQuery;
}
public long getRowCountApproximation() { public long getRowCountApproximation() {
return ROW_COUNT_APPROXIMATION; return ROW_COUNT_APPROXIMATION;
} }
public int getParameterOffset() {
return topQuery == null ? 0 : topQuery.getParameters().size();
}
} }
...@@ -36,6 +36,8 @@ public class TestCases extends TestBase { ...@@ -36,6 +36,8 @@ public class TestCases extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testJoinWithView();
testLobDecrypt();
testInvalidDatabaseName(); testInvalidDatabaseName();
testReuseSpace(); testReuseSpace();
testDeleteGroup(); testDeleteGroup();
...@@ -68,6 +70,43 @@ public class TestCases extends TestBase { ...@@ -68,6 +70,43 @@ public class TestCases extends TestBase {
deleteDb("cases"); deleteDb("cases");
} }
private void testJoinWithView() throws SQLException {
deleteDb("cases");
Connection conn = getConnection("cases");
conn.createStatement().execute(
"create table t(i identity, n varchar) as select 1, 'x'");
PreparedStatement prep = conn.prepareStatement(
"select 1 from dual " +
"inner join(select n from t where i=?) a on a.n='x' " +
"inner join(select n from t where i=?) b on b.n='x'");
prep.setInt(1, 1);
prep.setInt(2, 1);
prep.execute();
conn.close();
}
private void testLobDecrypt() throws SQLException {
Connection conn = getConnection("cases");
String key = "key";
String value = "Hello World";
PreparedStatement prep = conn.prepareStatement("CALL ENCRYPT('AES', RAWTOHEX(?), STRINGTOUTF8(?))");
prep.setCharacterStream(1, new StringReader(key), -1);
prep.setCharacterStream(2, new StringReader(value), -1);
ResultSet rs = prep.executeQuery();
rs.next();
String encrypted = rs.getString(1);
PreparedStatement prep2 = conn
.prepareStatement("CALL TRIM(CHAR(0) FROM UTF8TOSTRING(DECRYPT('AES', RAWTOHEX(?), ?)))");
prep2.setCharacterStream(1, new StringReader(key), -1);
prep2.setCharacterStream(2, new StringReader(encrypted), -1);
ResultSet rs2 = prep2.executeQuery();
rs2.first();
String decrypted = rs2.getString(1);
prep2.close();
assertEquals(value, decrypted);
conn.close();
}
private void testReservedKeywordReconnect() throws SQLException { private void testReservedKeywordReconnect() throws SQLException {
if (config.memory) { if (config.memory) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论