提交 8bce218b authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 f11e7263
...@@ -962,7 +962,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -962,7 +962,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>Support ARRAY data type </li><li>Support ARRAY data type
</li><li>Implement more JDBC 4.0 features </li><li>Implement more JDBC 4.0 features
</li><li>H2 Console: implement a servlet to allow simple web app integration </li><li>H2 Console: implement a servlet to allow simple web app integration
</li><li>Support ISO 8601 timestamp / date / time with timezone
</li><li>Support TRANSFORM / PIVOT as in MS Access </li><li>Support TRANSFORM / PIVOT as in MS Access
</li><li>Sequence: PostgreSQL compatibility (rename, create) (http://www.postgresql.org/docs/8.2/static/sql-altersequence.html) </li><li>Sequence: PostgreSQL compatibility (rename, create) (http://www.postgresql.org/docs/8.2/static/sql-altersequence.html)
</li><li>SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) </li><li>SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...)
...@@ -1036,6 +1035,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1036,6 +1035,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>Clustering: adding a node should be very fast and without interrupting clients (very short lock) </li><li>Clustering: adding a node should be very fast and without interrupting clients (very short lock)
</li><li>Updatable result sets: DatabaseMetaData.ownUpdatesAreVisible = true </li><li>Updatable result sets: DatabaseMetaData.ownUpdatesAreVisible = true
</li><li>Cache size should be in KB </li><li>Cache size should be in KB
</li><li>Support materialized views (using triggers)
</li><li>Store dates in local timezone (portability of database files)
</li><li>Ability to resize the cache array when resizing the cache </li><li>Ability to resize the cache array when resizing the cache
</li><li>Index usage for WHERE NOT FLAG (flag is a boolean column) </li><li>Index usage for WHERE NOT FLAG (flag is a boolean column)
</li><li>Automatic conversion from WHERE ID=1 AND ID=2 to WHERE FALSE </li><li>Automatic conversion from WHERE ID=1 AND ID=2 to WHERE FALSE
......
...@@ -721,7 +721,7 @@ public class Parser { ...@@ -721,7 +721,7 @@ public class Parser {
command.addRow(expr); command.addRow(expr);
} while(readIf(",")); } while(readIf(","));
} else { } else {
command.setQuery(parseQueryWithParams()); command.setQuery(parseSelect());
} }
return command; return command;
} }
...@@ -759,7 +759,7 @@ public class Parser { ...@@ -759,7 +759,7 @@ public class Parser {
command.addRow(expr); command.addRow(expr);
} while(readIf(",")); } while(readIf(","));
} else { } else {
command.setQuery(parseQueryWithParams()); command.setQuery(parseSelect());
} }
return command; return command;
} }
...@@ -769,7 +769,7 @@ public class Parser { ...@@ -769,7 +769,7 @@ public class Parser {
Schema mainSchema = database.getSchema(Constants.SCHEMA_MAIN); Schema mainSchema = database.getSchema(Constants.SCHEMA_MAIN);
if(readIf("(")) { if(readIf("(")) {
if(isToken("SELECT") || isToken("FROM")) { if(isToken("SELECT") || isToken("FROM")) {
Query query = parseQueryWithParams(); Query query = parseSelect();
String querySQL = query.getSQL(); String querySQL = query.getSQL();
Session s; Session s;
if(prepared != null && prepared instanceof CreateView) { if(prepared != null && prepared instanceof CreateView) {
...@@ -1141,24 +1141,18 @@ public class Parser { ...@@ -1141,24 +1141,18 @@ public class Parser {
} }
return command; return command;
} }
private Query parseSelect() throws SQLException { private Query parseSelect() throws SQLException {
Query command = parseSelectUnion();
command.init();
return command;
}
private Query parseQueryWithParams() throws SQLException {
int paramIndex = parameters.size(); int paramIndex = parameters.size();
Query command = parseSelectUnion(); Query command = parseSelectUnion();
command.init();
ObjectArray params = new ObjectArray(); ObjectArray params = new ObjectArray();
for(int i=paramIndex; i<parameters.size(); i++) { for(int i=paramIndex; i<parameters.size(); i++) {
params.add(parameters.get(i)); params.add(parameters.get(i));
} }
command.setParameterList(params); command.setParameterList(params);
command.init();
return command; return command;
} }
private Query parseSelectUnion() throws SQLException { private Query parseSelectUnion() throws SQLException {
int start = lastParseIndex; int start = lastParseIndex;
...@@ -1402,6 +1396,8 @@ public class Parser { ...@@ -1402,6 +1396,8 @@ public class Parser {
Expression condition = readExpression(); Expression condition = readExpression();
command.setHaving(condition); command.setHaving(condition);
} }
// TODO optimization: not all parameters may be referenced
command.setParameterList(parameters);
currentSelect = oldSelect; currentSelect = oldSelect;
setSQL(command, "SELECT", start); setSQL(command, "SELECT", start);
return command; return command;
...@@ -1438,7 +1434,7 @@ public class Parser { ...@@ -1438,7 +1434,7 @@ public class Parser {
} }
if (readIf("EXISTS")) { if (readIf("EXISTS")) {
read("("); read("(");
Query query = parseQueryWithParams(); Query query = parseSelect();
// can not reduce expression because it might be a union except query with distinct // can not reduce expression because it might be a union except query with distinct
read(")"); read(")");
return new ConditionExists(query); return new ConditionExists(query);
...@@ -1484,7 +1480,7 @@ public class Parser { ...@@ -1484,7 +1480,7 @@ public class Parser {
r = ValueExpression.get(ValueBoolean.get(false)); r = ValueExpression.get(ValueBoolean.get(false));
} else { } else {
if (isToken("SELECT") || isToken("FROM")) { if (isToken("SELECT") || isToken("FROM")) {
Query query = parseQueryWithParams(); Query query = parseSelect();
r = new ConditionInSelect(database, r, query, false, Comparison.EQUAL); r = new ConditionInSelect(database, r, query, false, Comparison.EQUAL);
} else { } else {
ObjectArray v = new ObjectArray(); ObjectArray v = new ObjectArray();
...@@ -1519,12 +1515,12 @@ public class Parser { ...@@ -1519,12 +1515,12 @@ public class Parser {
read(); read();
if(readIf("ALL")) { if(readIf("ALL")) {
read("("); read("(");
Query query = parseQueryWithParams(); Query query = parseSelect();
r = new ConditionInSelect(database, r, query, true, compareType); r = new ConditionInSelect(database, r, query, true, compareType);
read(")"); read(")");
} else if(readIf("ANY") || readIf("SOME")) { } else if(readIf("ANY") || readIf("SOME")) {
read("("); read("(");
Query query = parseQueryWithParams(); Query query = parseSelect();
r = new ConditionInSelect(database, r, query, false, compareType); r = new ConditionInSelect(database, r, query, false, compareType);
read(")"); read(")");
} else { } else {
...@@ -1871,7 +1867,7 @@ public class Parser { ...@@ -1871,7 +1867,7 @@ public class Parser {
break; break;
case KEYWORD: case KEYWORD:
if(isToken("SELECT") || isToken("FROM")) { if(isToken("SELECT") || isToken("FROM")) {
Query query = parseQueryWithParams(); Query query = parseSelect();
return new Subquery(query); return new Subquery(query);
} }
throw getSyntaxError(); throw getSyntaxError();
...@@ -4047,7 +4043,7 @@ public class Parser { ...@@ -4047,7 +4043,7 @@ public class Parser {
command.setTableName(tableName); command.setTableName(tableName);
command.setComment(readCommentIf()); command.setComment(readCommentIf());
if(readIf("AS")) { if(readIf("AS")) {
Query query = parseQueryWithParams(); Query query = parseSelect();
command.setQuery(query); command.setQuery(query);
} else { } else {
read("("); read("(");
......
...@@ -461,7 +461,7 @@ public class Select extends Query { ...@@ -461,7 +461,7 @@ public class Select extends Query {
return; return;
} }
if(Constants.CHECK && !checkInit) { if(Constants.CHECK && !checkInit) {
throw Message.getInternalError("already prepared"); throw Message.getInternalError("not initialized");
} }
isPrepared = true; isPrepared = true;
if(orderList != null) { if(orderList != null) {
......
...@@ -330,4 +330,5 @@ public class SelectUnion extends Query { ...@@ -330,4 +330,5 @@ public class SelectUnion extends Query {
left.updateAggregate(session); left.updateAggregate(session);
right.updateAggregate(session); right.updateAggregate(session);
} }
} }
...@@ -96,6 +96,53 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -96,6 +96,53 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
H2 Console: the result set is not updatable by default. Need to change in web console, and test other databases H2 Console: the result set is not updatable by default. Need to change in web console, and test other databases
drop table tc, ts, tx;
CREATE MEMORY TABLE tc(ARG0 INT, ARG1 INT);
-- 8 = SELECT COUNT(*) FROM tc;
INSERT INTO tc(ARG0, ARG1) VALUES(1, 0);
INSERT INTO tc(ARG0, ARG1) VALUES(2, 0);
INSERT INTO tc(ARG0, ARG1) VALUES(3, 0);
INSERT INTO tc(ARG0, ARG1) VALUES(4, 0);
INSERT INTO tc(ARG0, ARG1) VALUES(5, 0);
INSERT INTO tc(ARG0, ARG1) VALUES(7, 6);
INSERT INTO tc(ARG0, ARG1) VALUES(8, 6);
INSERT INTO tc(ARG0, ARG1) VALUES(5, 6);
CREATE INDEX tc01 ON tc(ARG0, ARG1);
CREATE INDEX tc1 ON tc(ARG1);
CREATE MEMORY TABLE ts(ARG0 INT, ARG1 INT, ARG2 INT);
-- 0 = SELECT COUNT(*) FROM ts;
CREATE INDEX ts02 ON ts(ARG0, ARG2);
CREATE INDEX ts12 ON ts(ARG1, ARG2);
CREATE INDEX ts2 ON ts(ARG2);
CREATE FORCE VIEW v1(ARG0, ARG1) AS (SELECT ARG0, ARG1 FROM tc UNION SELECT ARG0, ARG2 FROM ts);
create table tx (ARG1 int);
insert into tx values (0),(6);
-- This query produce the correct results only with -Dh2.indexOld=true
select * from v1 natural join tx;
drop view V;
drop table A, B;
CREATE TABLE A(A INT);
INSERT INTO A(A) VALUES(6);
CREATE TABLE B(B INT PRIMARY KEY);
CREATE VIEW V(V) AS (SELECT A FROM A UNION SELECT B FROM B);
drop table C;
create table C(C int);
delete from C;
insert into C values (0), (6);
select * from V, C where V.V = C.C;
I forgot to mention a litte documentation bug.
In the code sample of the feature section "Compacting a Database" there is the line
Backup.execute(url, user, password, script);
Correctly it should be
Script.execute(url, user, password, script);
check trace.db/ number of files, limit to 1000 or so check trace.db/ number of files, limit to 1000 or so
storages should be an int hash map storages should be an int hash map
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论