提交 fb598f3f authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 a2b139df
......@@ -17,10 +17,10 @@ H2 Database Engine
<a href="http://www.h2database.com/h2-2007-04-20.zip">Platform-Independent Zip (3.6 MB)</a><br />
</p>
<h3>Version 1.0 / 2006-08-31 (Last Stable)</h3>
<h3>Version 1.0 / 2007-04-20 (Last Stable)</h3>
<p>
<a href="http://www.h2database.com/h2-setup-2006-08-31.exe">Windows Installer (2.4 MB)</a><br />
<a href="http://www.h2database.com/h2-2006-08-31.zip">Platform-Independent Zip (3.1 MB)</a><br />
<a href="http://www.h2database.com/h2-setup-2007-04-20.exe">Windows Installer (2.7 MB)</a><br />
<a href="http://www.h2database.com/h2-2007-04-20.zip">Platform-Independent Zip (3.6 MB)</a><br />
</p>
<p>
......
......@@ -580,7 +580,7 @@ public class Parser {
alias = readAliasIdentifier();
}
}
TableFilter filter = new TableFilter(session, table, alias, rightsChecked);
TableFilter filter = new TableFilter(session, table, alias, rightsChecked, currentSelect);
return filter;
}
......@@ -775,7 +775,7 @@ public class Parser {
alias = readAliasIdentifier();
}
}
TableFilter filter = new TableFilter(session, table, alias, rightsChecked);
TableFilter filter = new TableFilter(session, table, alias, rightsChecked, currentSelect);
return filter;
}
......@@ -1297,7 +1297,7 @@ public class Parser {
// select without FROM: convert to SELECT ... FROM SYSTEM_RANGE(1,1)
Schema main = database.findSchema(Constants.SCHEMA_MAIN);
Table dual = new RangeTable(main, 1, 1);
TableFilter filter = new TableFilter(session, dual, null, rightsChecked);
TableFilter filter = new TableFilter(session, dual, null, rightsChecked, currentSelect);
command.addTableFilter(filter, true);
} else {
parseSelectSimpleFromPart(command);
......
......@@ -74,7 +74,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
int id = getObjectId(true, true);
String name = generateConstraintName(id);
ConstraintCheck check = new ConstraintCheck(getSchema(), id, name, table);
TableFilter filter = new TableFilter(session, table, null, false);
TableFilter filter = new TableFilter(session, table, null, false, null);
checkExpression.mapColumns(filter, 0);
checkExpression = checkExpression.optimize(session);
check.setExpression(checkExpression);
......
......@@ -216,4 +216,6 @@ public abstract class Query extends Prepared {
return isEverything(visitor);
}
public abstract void updateAggregate(Session session) throws SQLException;
}
......@@ -679,6 +679,20 @@ public class Select extends Query {
}
}
}
public void updateAggregate(Session session) throws SQLException {
for(int i=0; i<expressions.size(); i++) {
Expression e = (Expression) expressions.get(i);
e.updateAggregate(session);
}
if(condition != null) {
condition.updateAggregate(session);
}
if(having != null) {
having.updateAggregate(session);
}
}
public boolean isEverything(ExpressionVisitor visitor) {
if(visitor.type == ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID) {
......
......@@ -309,4 +309,9 @@ public class SelectUnion extends Query {
public Query getRightQuery() {
return right;
}
public void updateAggregate(Session session) throws SQLException {
left.updateAggregate(session);
right.updateAggregate(session);
}
}
......@@ -32,6 +32,7 @@ public class ConnectionInfo {
private boolean remote;
private boolean ssl;
private boolean persistent;
private boolean unnamed;
static {
ObjectArray list = SetTypes.getSettings();
......@@ -84,6 +85,9 @@ public class ConnectionInfo {
name = name.substring("ssl:".length());
} else if(name.startsWith("mem:")) {
persistent = false;
if(name.equals("mem:")) {
unnamed = true;
}
} else if(name.startsWith("file:")) {
name = name.substring("file:".length());
persistent = true;
......@@ -118,6 +122,10 @@ public class ConnectionInfo {
public boolean isPersistent() {
return persistent;
}
public boolean isUnnamed() {
return unnamed;
}
private void readProperties(Properties info) throws SQLException {
Object[] list = new Object[info.size()];
......
......@@ -293,7 +293,7 @@ public class Database implements DataHandler {
public FileStore openFile(String name, boolean mustExist) throws SQLException {
if(mustExist && !FileUtils.exists(name)) {
throw Message.getSQLException(Message.FILE_CORRUPTED_1, name);
throw Message.getSQLException(Message.FILE_NOT_FOUND_1, name);
}
FileStore store = FileStore.open(this, name, getMagic(), cipher, filePasswordHash);
try {
......
......@@ -34,7 +34,12 @@ public class Engine {
private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) throws SQLException {
// may not remove properties here, otherwise they are lost if it is required to call it twice
String name = ci.getName();
Database database = (Database) databases.get(name);
Database database;
if(ci.isUnnamed()) {
database = null;
} else {
database = (Database) databases.get(name);
}
User user = null;
boolean opened = false;
if(database == null) {
......@@ -50,7 +55,9 @@ public class Engine {
user.setUserPasswordHash(ci.getUserPasswordHash());
database.setMasterUser(user);
}
databases.put(name, database);
if(!ci.isUnnamed()) {
databases.put(name, database);
}
}
synchronized(database) {
if(database.isClosing()) {
......
......@@ -119,6 +119,10 @@ public class Aggregate extends Expression {
// on.updateAggregate();
// }
HashMap group = select.getCurrentGroup();
if(group == null) {
// this is a different level (the enclosing query)
return;
}
AggregateData data = (AggregateData) group.get(this);
if(data == null) {
data = new AggregateData(type);
......
......@@ -32,17 +32,14 @@ public class ExpressionColumn extends Expression {
private int queryLevel;
private Column column;
private boolean evaluatable;
private Select select;
public ExpressionColumn(Database database, Select select, Column column) {
this.database = database;
this.select = select;
this.column = column;
}
public ExpressionColumn(Database database, Select select, String schemaName, String tableAlias, String columnName) {
this.database = database;
this.select = select;
this.schemaName = schemaName;
this.tableAlias = tableAlias;
this.columnName = columnName;
......@@ -114,10 +111,15 @@ public class ExpressionColumn extends Expression {
public void updateAggregate(Session session) throws SQLException {
Value now = resolver.getValue(column);
Select select = resolver.getSelect();
if(select == null) {
throw Message.getSQLException(Message.MUST_GROUP_BY_COLUMN_1, getSQL());
}
HashMap values = select.getCurrentGroup();
if(values == null) {
// this is a different level (the enclosing query)
return;
}
Value v = (Value)values.get(this);
if(v==null) {
values.put(this, now);
......@@ -131,6 +133,7 @@ public class ExpressionColumn extends Expression {
public Value getValue(Session session) throws SQLException {
// TODO refactor: simplify check if really part of an aggregated value / detection of
// usage of non-grouped by columns without aggregate function
Select select = resolver.getSelect();
if(select != null) {
HashMap values = select.getCurrentGroup();
if(values != null) {
......
......@@ -83,8 +83,8 @@ public class Subquery extends Expression {
return "(" + query.getPlan() +")";
}
public void updateAggregate(Session session) {
// TODO exists: is it possible that the subquery contains related aggregates? probably not
public void updateAggregate(Session session) throws SQLException {
query.updateAggregate(session);
}
private Expression getExpression() {
......
......@@ -58,6 +58,8 @@ public class AppServer {
ssl = Boolean.valueOf(args[++i]).booleanValue();
} else if("-webAllowOthers".equals(args[i])) {
allowOthers = Boolean.valueOf(args[++i]).booleanValue();
// } else if("-baseDir".equals(args[i])) {
// String baseDir = args[++i];
}
}
// TODO gcj: don't load drivers in case of GCJ
......
......@@ -359,6 +359,8 @@ function showList(s) {
} else {
showOutput('');
}
// scroll to the top left
top.h2result.scrollTo(0, 0);
}
function retrieveList(s) {
......
......@@ -249,7 +249,7 @@ public class Column {
public void prepareExpression(Session session) throws SQLException {
if(defaultExpression != null) {
computeTableFilter = new TableFilter(session, table, null, false);
computeTableFilter = new TableFilter(session, table, null, false, null);
defaultExpression.mapColumns(computeTableFilter, 0);
defaultExpression = defaultExpression.optimize(session);
}
......
......@@ -4,6 +4,7 @@
*/
package org.h2.table;
import org.h2.command.dml.Select;
import org.h2.value.Value;
public interface ColumnResolver {
......@@ -13,5 +14,6 @@ public interface ColumnResolver {
String getSchemaName();
Value getValue(Column column);
TableFilter getTableFilter();
Select getSelect();
}
......@@ -4,6 +4,7 @@
*/
package org.h2.table;
import org.h2.command.dml.Select;
import org.h2.value.Value;
public class SingleColumnResolver implements ColumnResolver {
......@@ -39,4 +40,8 @@ public class SingleColumnResolver implements ColumnResolver {
return null;
}
public Select getSelect() {
return null;
}
}
......@@ -6,6 +6,7 @@ package org.h2.table;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.engine.Constants;
import org.h2.engine.Right;
import org.h2.engine.Session;
......@@ -33,6 +34,7 @@ public class TableFilter implements ColumnResolver {
private Cursor cursor;
private int scanCount;
private boolean used; // used in the plan
private Select select;
// conditions that can be used for direct index lookup (start or end)
private ObjectArray indexConditions = new ObjectArray();
......@@ -53,11 +55,16 @@ public class TableFilter implements ColumnResolver {
private Expression fullCondition;
private boolean rightsChecked;
public TableFilter(Session session, Table table, String alias, boolean rightsChecked) {
public TableFilter(Session session, Table table, String alias, boolean rightsChecked, Select select) {
this.session = session;
this.table = table;
this.alias = alias;
this.rightsChecked = rightsChecked;
this.select = select;
}
public Select getSelect() {
return select;
}
public Session getSession() {
......
......@@ -27,7 +27,7 @@ public class Script {
private void showUsage() {
System.out.println("java "+getClass().getName()
+ " -url <url> -user <user> [-password <pwd>] [-file <filename>] [-options <option> ...]");
+ " -url <url> -user <user> [-password <pwd>] [-script <filename>] [-options <option> ...]");
}
/**
......@@ -39,7 +39,7 @@ public class Script {
* </li><li>-url jdbc:h2:... (database URL)
* </li><li>-user username
* </li><li>-password password
* </li><li>-file filename (default file name is backup.sql)
* </li><li>-script filename (default file name is backup.sql)
* </li><li>-options to specify a list of options (only for H2)
* </li></ul>
*
......@@ -63,7 +63,7 @@ public class Script {
user = args[++i];
} else if(args[i].equals("-password")) {
password = args[++i];
} else if(args[i].equals("-file")) {
} else if(args[i].equals("-script")) {
file = args[++i];
} else if(args[i].equals("-options")) {
StringBuffer buff1 = new StringBuffer();
......
......@@ -74,13 +74,13 @@ public class Server implements Runnable {
* The following options are supported:
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-web (start the Web Server)
* </li><li>-web (start the Web Server / H2 Console application)
* </li><li>-tcp (start the TCP Server)
* </li><li>-tcpShutdown {url} (shutdown the running TCP Server, URL example: tcp://localhost:9094)
* </li><li>-odbc (start the ODBC Server)
* </li><li>-browser (start a browser and open a page to connect to the Web Server)
* </li><li>-log [true|false] (enable or disable logging)
* </li><li>-baseDir {directory} (sets the base directory for database files)
* </li><li>-baseDir {directory} (sets the base directory for database files; not for H2 Console)
* </li><li>-ifExists [true|false] (only existing databases may be opened)
* </li><li>-ftp (start the FTP Server)
* </li></ul>
......
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.cases;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.tools.DeleteDbFiles;
public class TestWithRecursive {
public static void main(String[] args) throws Exception {
Class.forName("org.h2.Driver");
DeleteDbFiles.execute(".", "test", true);
String url = "jdbc:h2:test";
Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table parent(id int primary key, parent int)");
stat.execute("insert into parent values(1, null), (2, 1), (3, 1)");
ResultSet rs = stat.executeQuery(
"with test_view(id, parent) as \n"+
"select id, parent from parent where id = 1 \n"+
"union all select parent.id, parent.parent from test_view, parent \n"+
"where parent.parent = test_view.id \n" +
"select * from test_view");
System.out.println("query:");
while(rs.next()) {
System.out.println(rs.getString(1));
}
stat.execute("drop view if exists test_view");
System.out.println("prepared:");
PreparedStatement prep = conn.prepareStatement(
"with test_view(id, parent) as \n"+
"select id, parent from parent where id = ? \n"+
"union all select parent.id, parent.parent from test_view, parent \n"+
"where parent.parent = test_view.id \n" +
"select * from test_view");
prep.setInt(1, 1);
rs = prep.executeQuery();
while(rs.next()) {
System.out.println(rs.getString(1));
}
conn.close();
}
}
......@@ -17,6 +17,7 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.Random;
import org.h2.test.TestAll;
import org.h2.test.TestBase;
import org.h2.tools.Backup;
import org.h2.tools.DeleteDbFiles;
......@@ -292,5 +293,11 @@ public abstract class TestHalt extends TestBase {
}
return buff.toString();
}
public TestBase init(TestAll conf) throws Exception {
super.init(conf);
BASE_DIR = "dataHalt";
return this;
}
}
......@@ -8,6 +8,11 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import org.h2.test.TestAll;
import org.h2.test.TestBase;
import org.h2.test.db.TestScript;
public class TestHaltApp extends TestHalt {
......@@ -128,5 +133,5 @@ public class TestHaltApp extends TestHalt {
traceOperation("rollback");
conn.rollback();
}
}
--- special grammar and test cases ---------------------------------------------------------------------------------------------
create table people (family varchar(1) not null, person varchar(1) not null);
> ok
create table cars (family varchar(1) not null, car varchar(1) not null);
> ok
insert into people values(1, 1), (2, 1), (2, 2), (3, 1), (5, 1);
> update count: 5
insert into cars values(2, 1), (2, 2), (3, 1), (3, 2), (3, 3), (4, 1);
> update count: 6
select family, (select count(car) from cars where cars.family = people.family) as x
from people group by family order by family;
> FAMILY X
> ------ -
> 1 0
> 2 2
> 3 3
> 5 0
> rows (ordered): 4
drop table people, cars;
> ok
select (1, 2);
> 1, 2
> ------
......
......@@ -44,9 +44,9 @@ public class TestTools extends TestBase {
conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')");
conn.close();
Script.main(new String[]{"-url", url, "-user", user, "-password", password, "-file", fileName, "-options", "nodata", "compression", "lzf", "cipher", "xtea", "password", "'123'"});
Script.main(new String[]{"-url", url, "-user", user, "-password", password, "-script", fileName, "-options", "nodata", "compression", "lzf", "cipher", "xtea", "password", "'123'"});
DeleteDbFiles.main(new String[]{"-dir", BASE_DIR, "-db", "utils", "-quiet"});
RunScript.main(new String[]{"-url", url, "-user", user, "-password", password, "-file", fileName, "-options", "compression", "lzf", "cipher", "xtea", "password", "'123'"});
RunScript.main(new String[]{"-url", url, "-user", user, "-password", password, "-script", fileName, "-options", "compression", "lzf", "cipher", "xtea", "password", "'123'"});
conn = DriverManager.getConnection("jdbc:h2:" + BASE_DIR+ "/utils", "sa", "abc");
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
checkFalse(rs.next());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论