提交 0717e820 authored 作者: Thomas Mueller's avatar Thomas Mueller

Views with IN(..) that used a view itself did not work.

上级 bf091791
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>The license change a bit: so far the license was modified to say
<ul><li>Views with IN(..) that used a view itself did not work.
</li><li>Union queries with LIMIT or ORDER BY that are used in a view or subquery did not work.
</li><li>The license change a bit: so far the license was modified to say
'Swiss law'. This is now changed back to the original 'US law'.
This was requested by a user, and I don't see a problem.
</li><li>Constraints for local temporary tables now session scoped. So far they were global.
......
......@@ -1328,19 +1328,10 @@ a regular database.
<br /><a name="low_disk_space"></a>
<h2>Graceful Handling of Low Disk Space Situations</h2>
<p>
The database is able to deal with situations where the disk space available is running low.
Whenever the database starts, an 'emergency space' file is created (size is 1 MB),
and if there is no more space available, the file will shrink. If the space available
is lower than 128 KB, the database will go into a special read only mode, where
writing operations are no longer allowed: All writing operations will throw the
exception 'No disk space available' from this point on. To go back to the normal operating
mode, all connections to the database need to be closed first, and space needs to
be freed up.
</p><p>
It is possible to install a database event listener to detect low disk space situations early on
(when only 1 MB if space is available). To do this, use the SQL statement
SET DATABASE_EVENT_LISTENER.
The listener can also be set at connection time, using an URL of the form
If the database needs more disk space, it calls the database event listener if one is installed.
The application may then delete temporary files, or display a message and wait until
the user has resolved the problem. To install a listener, run the SQL statement
SET DATABASE_EVENT_LISTENER or use a database URL of the form
jdbc:h2:~/test;DATABASE_EVENT_LISTENER='com.acme.DbListener'
(the quotes around the class name are required).
See also the DatabaseEventListener API.
......
......@@ -24,20 +24,19 @@ Of course, patches are always welcome, but are not always applied as is. Patches
<h2>Priority 1</h2>
<ul>
<li>Bugfixes
</li><li>Write more tests and documentation for MVCC (Multi Version Concurrency Control)
</li><li>Page store: new storage mechanism
</li><li>[Requires page store] Support large updates (use the transaction log to undo).
</li><li>[Requires page store] Shutdown compact
</li><li>More tests with MULTI_THREADED=1
</li><li>RECOVER=1 should automatically recover, =2 should run the recovery tool if required
</li><li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox)
</li><li>Optimization: result set caching (like MySQL)
</li><li>Support large updates (use the transaction log to undo).
</li><li>Shutdown compact
</li><li>Server side cursors
</li><li>Support nested outer joins (see todo.txt).
</li></ul>
<h2>Priority 2</h2>
<ul>
<li>Improve test code coverage
</li><li>Fulltext search: support streaming CLOB data.
</li><li>Optimize .. OR .. to IN(..) or UNION if the cost is lower
</li><li>Support OSGi: http://oscar-osgi.sourceforge.net, http://incubator.apache.org/felix/index.html
</li><li>Test multi-threaded in-memory db access
......@@ -54,7 +53,6 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Change LOB mechanism (less files, keep index of lob files, point to files and row, delete unused files earlier, maybe bundle files into a tar file)
</li><li>Clustering: recovery needs to becomes fully automatic. Global write lock feature.
</li><li>Option for Java functions: [DETERMINISTIC] FOR ...
</li><li>Fulltext search: support streaming CLOB data.
</li><li>Support mixed clustering mode (one embedded, the other server mode)
</li><li>Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE
</li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED)
......@@ -68,9 +66,12 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Console: add accesskey to most important commands (A, AREA, BUTTON, INPUT, LABEL, LEGEND, TEXTAREA)
</li><li>Feature: a setting to delete the the log or not (for backup)
</li><li>Test with Sun ASPE1_4; JEE Sun AS PE1.4
</li><li>Support nested outer joins (see todo.txt).
</li><li>Test performance again with SQL Server, Oracle, DB2
</li><li>Test with dbmonster (http://dbmonster.kernelpanic.pl/)
</li><li>Test with dbcopy (http://dbcopyplugin.sourceforge.net)
</li><li>Test with Spatial DB in a box / JTS
</li><li>Write more tests and documentation for MVCC (Multi Version Concurrency Control)
</li><li>Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after
</li><li>Implement, test, document XAConnection and so on
</li><li>Pluggable data type (for compression, validation, conversion, encryption)
......@@ -86,6 +87,7 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Count index range query (count(*) where id between 10 and 20)
</li><li>Eclipse plugin
</li><li>Asynchronous queries to support publish/subscribe: SELECT ... FOR READ WAIT [maxMillisToWait]
</li><li>Improved fulltext search (reader / tokenizer / filter).
</li><li>iReport to support H2
</li><li>Implement missing JDBC API (CallableStatement,...)
</li><li>Compression of the cache
......@@ -164,7 +166,6 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility)
</li><li>Backup tool should work with other databases as well
</li><li>Console: -ifExists doesn't work for the console. Add a flag to disable other dbs
</li><li>Improved fulltext search (reader / tokenizer / filter).
</li><li>Performance: Update in-place
</li><li>Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess)
</li><li>Java static code analysis: http://pmd.sourceforge.net/
......@@ -387,6 +388,8 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Fulltext search: lazy result generation using SimpleRowSource.
</li><li>Support transformation to join for user defined functions, as for IN(SELECT...).
</li><li>Fulltext search: Support alternative syntax: WHERE FTL_CONTAINS(name, 'hello').
</li><li>MySQL compatibility: support REPLACE, see http://dev.mysql.com/doc/refman/5.1/de/replace.html
</li><li>MySQL compatibility: support INSERT INTO table SET column1 = value1, column2 = value2
</li></ul>
<h2>Not Planned</h2>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -938,8 +938,8 @@ public class Parser {
} else {
s = session;
}
table = TableView.createTempView(s, session.getUser(), query);
alias = table.getName();
alias = session.getNextSystemIdentifier(sqlCommand);
table = TableView.createTempView(s, session.getUser(), alias, query);
} else {
TableFilter top = readTableFilter(fromOuter);
top = readJoin(top, currentSelect, fromOuter);
......
......@@ -1134,7 +1134,8 @@ public class Select extends Query {
return expr.getAlias();
}
Mode mode = session.getDatabase().getMode();
expr = new Alias(expr, session.getNextTempViewName() + "_X", mode.aliasColumnName);
String name = session.getNextSystemIdentifier(getSQL());
expr = new Alias(expr, name, mode.aliasColumnName);
expressions.set(0, expr);
return expr.getAlias();
}
......
......@@ -295,8 +295,9 @@ public class SelectUnion extends Query {
public String getPlanSQL() {
StringBuffer buff = new StringBuffer();
buff.append(left.getPlanSQL());
buff.append(' ');
buff.append('(');
buff.append(StringUtils.unEnclose(left.getPlanSQL()));
buff.append(')');
switch (unionType) {
case UNION_ALL:
buff.append("UNION ALL ");
......@@ -314,7 +315,7 @@ public class SelectUnion extends Query {
Message.throwInternalError("type=" + unionType);
}
buff.append('(');
buff.append(right.getPlanSQL());
buff.append(StringUtils.unEnclose(right.getPlanSQL()));
buff.append(')');
Expression[] exprList = new Expression[expressions.size()];
expressions.toArray(exprList);
......
......@@ -12,7 +12,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import org.h2.command.Command;
import org.h2.command.CommandInterface;
import org.h2.command.Parser;
......@@ -49,6 +48,11 @@ import org.h2.value.ValueNull;
*/
public class Session implements SessionInterface {
/**
* The prefix of generated identifiers. It may not have letters, because
* they are case sensitive.
*/
private static final String SYSTEM_IDENTIFIER_PREFIX = "_";
private static int nextSerialId;
private final int serialId = nextSerialId++;
......@@ -77,7 +81,7 @@ public class Session implements SessionInterface {
private String[] schemaSearchPath;
private String traceModuleName;
private HashMap unlinkMap;
private int tempViewIndex;
private int systemIdentifier;
private HashMap procedures;
private boolean undoLogEnabled = true;
private boolean autoCommitAtTransactionEnd;
......@@ -923,8 +927,19 @@ public class Session implements SessionInterface {
}
}
public String getNextTempViewName() {
return "TEMP_VIEW_" + tempViewIndex++;
/**
* Get the next system generated identifiers. The identifier returned does
* not occur within the given SQL statement.
*
* @param sql the SQL statement
* @return the new identifier
*/
public String getNextSystemIdentifier(String sql) {
String id;
do {
id = SYSTEM_IDENTIFIER_PREFIX + systemIdentifier++;
} while (sql.indexOf(id) >= 0);
return id;
}
/**
......
......@@ -229,12 +229,12 @@ public class ConditionIn extends Condition {
function.doneWithParameters();
ObjectArray columns = new ObjectArray();
int dataType = left.getType();
String columnName = session.getNextTempViewName() + "_X";
String columnName = session.getNextSystemIdentifier(select.getSQL());
Column col = new Column(columnName, dataType);
columns.add(col);
function.setColumns(columns);
FunctionTable table = new FunctionTable(mainSchema, session, function);
String viewName = session.getNextTempViewName();
String viewName = session.getNextSystemIdentifier(select.getSQL());
TableFilter filter = new TableFilter(session, table, viewName, false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(db, null, viewName, columnName);
......
......@@ -139,8 +139,9 @@ public class ConditionInSelect extends Condition {
if (alias == null) {
return this;
}
TableView view = TableView.createTempView(session, session.getUser(), query);
TableFilter filter = new TableFilter(session, view, view.getName(), false, select);
String name = session.getNextSystemIdentifier(select.getSQL());
TableView view = TableView.createTempView(session, session.getUser(), name, query);
TableFilter filter = new TableFilter(session, view, name, false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(session.getDatabase(), null, view.getName(), alias);
Expression on = new Comparison(session, Comparison.EQUAL, left, column);
......
......@@ -340,14 +340,14 @@ public class TableView extends Table {
*
* @param session the session
* @param owner the owner of the query
* @param name the view name
* @param query the query
* @return the view table
*/
public static TableView createTempView(Session session, User owner, Query query) throws SQLException {
String tempViewName = session.getNextTempViewName();
public static TableView createTempView(Session session, User owner, String name, Query query) throws SQLException {
Schema mainSchema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN);
String querySQL = query.getPlanSQL();
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, session,
TableView v = new TableView(mainSchema, 0, name, querySQL, query.getParameters(), null, session,
false);
if (v.createException != null) {
throw v.createException;
......
......@@ -896,4 +896,19 @@ public class StringUtils {
return s;
}
/**
* Check if a string only contains numbers.
*
* @param s the string
* @return true if it only contains digits 0 - 9
*/
public static boolean isNumber(String identifier) {
for (int i = 0; i < identifier.length(); i++) {
if (!Character.isDigit(identifier.charAt(i))) {
return false;
}
}
return true;
}
}
......@@ -278,6 +278,7 @@ java org.h2.test.TestAll timer
System.setProperty("h2.check2", "true");
/*
remove google analytics
JCR: for each node type, create a table; one 'dynamic' table with parameter;
option to cache the results
<link rel="icon" type="image/png" href="/path/image.png">
......
......@@ -18,6 +18,15 @@ import org.h2.test.TestBase;
*/
public class TestView extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String[] a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws SQLException {
testUnionReconnect();
testManyViews();
......
select count(*)from((select 1 from dual limit 1)union(select 2 from dual limit 1));
> 2;
select sum(cast(x as int)) from system_range(2147483547, 2147483637);
> 195421006872;
select sum(x) from system_range(9223372036854775707, 9223372036854775797);
......
......@@ -575,4 +575,5 @@ bleyl donald conservative offsets diabetes ansorg allocating osmond gluco
joachim mysqladmin sudo mysqld indicator wire ring relates expedites
approximated approximation dvan dsn dobysoft ebean syswow tmueller dbbench
connecturl problematic transformation lazy querydsl squill empire liq fle
xive evolving mssqlserver eric respond faulhaber fixing
xive evolving mssqlserver eric respond faulhaber fixing northern lying
federal santa america county clara courts california york venue
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论