提交 437073c1 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 da6e461b
/*
* 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.util;
public class ClassUtils {
public static Class loadClass(String className) throws ClassNotFoundException {
// TODO support special syntax to load classes using another classloader
return Class.forName(className);
}
}
...@@ -151,6 +151,7 @@ public class DateTimeUtils { ...@@ -151,6 +151,7 @@ public class DateTimeUtils {
if(s.endsWith("Z")) { if(s.endsWith("Z")) {
s = s.substring(0, s.length()-1); s = s.substring(0, s.length()-1);
tz = TimeZone.getTimeZone("UTC");
} else { } else {
int timezoneStart = s.indexOf('+', s2 + 1); int timezoneStart = s.indexOf('+', s2 + 1);
if(timezoneStart < 0) { if(timezoneStart < 0) {
......
...@@ -314,7 +314,7 @@ public class FileUtils { ...@@ -314,7 +314,7 @@ public class FileUtils {
return fileName.startsWith(MEMORY_PREFIX) || fileName.startsWith(MEMORY_PREFIX_2); return fileName.startsWith(MEMORY_PREFIX) || fileName.startsWith(MEMORY_PREFIX_2);
} }
public static String createTempFile(String name, String suffix, boolean deleteOnExit) throws IOException, SQLException { public static String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException, SQLException {
name += "."; name += ".";
if(isInMemory(name)) { if(isInMemory(name)) {
for(int i=0;; i++) { for(int i=0;; i++) {
...@@ -327,12 +327,18 @@ public class FileUtils { ...@@ -327,12 +327,18 @@ public class FileUtils {
} }
} }
String prefix = new File(name).getName(); String prefix = new File(name).getName();
File dir = new File(name).getAbsoluteFile().getParentFile(); File dir;
if(inTempDir) {
dir = null;
} else {
dir = new File(name).getAbsoluteFile().getParentFile();
dir.mkdirs(); dir.mkdirs();
}
File f = File.createTempFile(prefix, suffix, dir); File f = File.createTempFile(prefix, suffix, dir);
if(deleteOnExit) { if(deleteOnExit) {
f.deleteOnExit(); f.deleteOnExit();
} }
// return f.getPath();
return f.getCanonicalPath(); return f.getCanonicalPath();
} }
...@@ -344,6 +350,7 @@ public class FileUtils { ...@@ -344,6 +350,7 @@ public class FileUtils {
} }
public static String[] listFiles(String path) throws SQLException { public static String[] listFiles(String path) throws SQLException {
//System.out.println("listFiles: " + path);
if(isInMemory(path)) { if(isInMemory(path)) {
String[] list = new String[memoryFiles.size()]; String[] list = new String[memoryFiles.size()];
MemoryFile[] l = new MemoryFile[memoryFiles.size()]; MemoryFile[] l = new MemoryFile[memoryFiles.size()];
...@@ -353,19 +360,34 @@ public class FileUtils { ...@@ -353,19 +360,34 @@ public class FileUtils {
} }
return list; return list;
} }
File f = new File(path);
try { try {
File[] files = new File(path).listFiles(); String[] list = f.list();
if(files == null) { if(list == null) {
return new String[0]; return new String[0];
} }
String[] list = new String[files.length]; String base = f.getCanonicalPath() + File.separator;
for(int i=0; i<files.length; i++) { for(int i=0; i<list.length; i++) {
list[i] = files[i].getCanonicalPath(); list[i] = base + list[i];
} }
return list; return list;
} catch (IOException e) { } catch (IOException e) {
throw Message.convert(e); throw Message.convert(e);
} }
// try {
// File[] files = new File(path).listFiles();
// if(files == null) {
// return new String[0];
// }
// String[] list = new String[files.length];
// for(int i=0; i<files.length; i++) {
// list[i] = files[i].getCanonicalPath();
// }
// return list;
// } catch (IOException e) {
// throw Message.convert(e);
// }
} }
public static boolean isDirectory(String fileName) { public static boolean isDirectory(String fileName) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.h2.util; package org.h2.util;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
...@@ -13,6 +14,8 @@ import java.sql.Statement; ...@@ -13,6 +14,8 @@ import java.sql.Statement;
import javax.sql.XAConnection; import javax.sql.XAConnection;
//#endif //#endif
import org.h2.message.Message;
public class JdbcUtils { public class JdbcUtils {
public static void closeSilently(Statement stat) { public static void closeSilently(Statement stat) {
...@@ -65,4 +68,15 @@ public class JdbcUtils { ...@@ -65,4 +68,15 @@ public class JdbcUtils {
} }
//#endif //#endif
public static Connection getConnection(String driver, String url, String user, String password) throws SQLException {
if(!StringUtils.isNullOrEmpty(driver)) {
try {
ClassUtils.loadClass(driver);
} catch (ClassNotFoundException e) {
throw Message.getSQLException(Message.CLASS_NOT_FOUND_1, new String[]{driver}, e);
}
}
return DriverManager.getConnection(url, user, password);
}
} }
...@@ -601,4 +601,8 @@ public class StringUtils { ...@@ -601,4 +601,8 @@ public class StringUtils {
return buff.append('\"').toString(); return buff.append('\"').toString();
} }
public static boolean isNullOrEmpty(String s) {
return s == null || s.length() == 0;
}
} }
...@@ -175,11 +175,13 @@ public class DataType { ...@@ -175,11 +175,13 @@ public class DataType {
createString(true), createString(true),
new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"} new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"}
); );
DataType dataType = new DataType();
dataType.prefix = "(";
dataType.suffix = "')";
add(Value.ARRAY, Types.ARRAY, "Array", add(Value.ARRAY, Types.ARRAY, "Array",
createString(false), dataType,
new String[]{"ARRAY"} new String[]{"ARRAY"}
); );
// TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types? // TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types?
} }
......
...@@ -262,7 +262,13 @@ public class Transfer { ...@@ -262,7 +262,13 @@ public class Transfer {
} }
writeLong(length); writeLong(length);
Reader reader = v.getReader(); Reader reader = v.getReader();
Writer writer = new OutputStreamWriter(out, Constants.UTF8); // below, writer.flush needs to be called to ensure the buffer is written
// but, this will also flush the output stream, and this slows things down
// so construct an output stream that will ignore this chained flush call
java.io.OutputStream out2 = new java.io.FilterOutputStream(out) {
public void flush() {}
};
Writer writer = new OutputStreamWriter(out2, Constants.UTF8);
long written = IOUtils.copyAndCloseInput(reader, writer); long written = IOUtils.copyAndCloseInput(reader, writer);
if(Constants.CHECK && written != length) { if(Constants.CHECK && written != length) {
throw Message.getInternalError("length:" + length + " written:" + written); throw Message.getInternalError("length:" + length + " written:" + written);
......
...@@ -194,9 +194,9 @@ public class ValueLob extends Value { ...@@ -194,9 +194,9 @@ public class ValueLob extends Value {
return name; return name;
} }
private static int getNewObjectId(String path) throws SQLException { private int getNewObjectId(DataHandler handler) throws SQLException {
int objectId; String path = handler.getDatabasePath();
objectId = 0; int objectId = 0;
while(true) { while(true) {
String dir = getFileNamePrefix(path, objectId); String dir = getFileNamePrefix(path, objectId);
String[] list = FileUtils.listFiles(dir); String[] list = FileUtils.listFiles(dir);
...@@ -204,7 +204,7 @@ public class ValueLob extends Value { ...@@ -204,7 +204,7 @@ public class ValueLob extends Value {
boolean[] used = new boolean[Constants.LOB_FILES_PER_DIRECTORY]; boolean[] used = new boolean[Constants.LOB_FILES_PER_DIRECTORY];
for(int i=0; i<list.length; i++) { for(int i=0; i<list.length; i++) {
String name = list[i]; String name = list[i];
if(name.endsWith(".db")) { if(name.endsWith(Constants.SUFFIX_DB_FILE)) {
name = name.substring(name.lastIndexOf(File.separatorChar) + 1); name = name.substring(name.lastIndexOf(File.separatorChar) + 1);
String n = name.substring(0, name.indexOf('.')); String n = name.substring(0, name.indexOf('.'));
int id; int id;
...@@ -282,7 +282,7 @@ public class ValueLob extends Value { ...@@ -282,7 +282,7 @@ public class ValueLob extends Value {
this.compression = compressionAlgorithm != null; this.compression = compressionAlgorithm != null;
synchronized(handler) { synchronized(handler) {
if(Constants.LOB_FILES_IN_DIRECTORIES) { if(Constants.LOB_FILES_IN_DIRECTORIES) {
objectId = getNewObjectId(handler.getDatabasePath()); objectId = getNewObjectId(handler);
fileName = getFileNamePrefix(handler.getDatabasePath(), objectId) + ".temp.db"; fileName = getFileNamePrefix(handler.getDatabasePath(), objectId) + ".temp.db";
} else { } else {
objectId = handler.allocateObjectId(false, true); objectId = handler.allocateObjectId(false, true);
...@@ -377,7 +377,7 @@ public class ValueLob extends Value { ...@@ -377,7 +377,7 @@ public class ValueLob extends Value {
if(linked) { if(linked) {
ValueLob copy = ValueLob.copy(this); ValueLob copy = ValueLob.copy(this);
if(Constants.LOB_FILES_IN_DIRECTORIES) { if(Constants.LOB_FILES_IN_DIRECTORIES) {
copy.objectId = getNewObjectId(handler.getDatabasePath()); copy.objectId = getNewObjectId(handler);
} else { } else {
copy.objectId = handler.allocateObjectId(false, true); copy.objectId = handler.allocateObjectId(false, true);
} }
......
...@@ -8,7 +8,7 @@ import java.sql.Connection; ...@@ -8,7 +8,7 @@ import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.Statement; import java.sql.Statement;
import org.h2.tools.Backup; import org.h2.tools.Script;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
import org.h2.tools.RunScript; import org.h2.tools.RunScript;
...@@ -30,9 +30,9 @@ public class Compact { ...@@ -30,9 +30,9 @@ public class Compact {
public static void compact(String dir, String dbName, String user, String password) throws Exception { public static void compact(String dir, String dbName, String user, String password) throws Exception {
String url = "jdbc:h2:" + dir + "/" + dbName; String url = "jdbc:h2:" + dir + "/" + dbName;
String script = "data/test.sql"; String file = "data/test.sql";
Backup.execute(url, user, password, script); Script.execute(url, user, password, file);
DeleteDbFiles.execute(dir, dbName, true); DeleteDbFiles.execute(dir, dbName, true);
RunScript.execute(url, user, password, script, null, false); RunScript.execute(url, user, password, file, null, false);
} }
} }
...@@ -10,6 +10,8 @@ import java.util.Properties; ...@@ -10,6 +10,8 @@ import java.util.Properties;
import org.h2.server.TcpServer; import org.h2.server.TcpServer;
import org.h2.test.jdbc.*; import org.h2.test.jdbc.*;
import org.h2.test.jdbc.xa.TestXA; import org.h2.test.jdbc.xa.TestXA;
import org.h2.test.cases.TestBlobDir;
import org.h2.test.cases.TestCalendar;
import org.h2.test.db.*; import org.h2.test.db.*;
import org.h2.test.server.TestNestedLoop; import org.h2.test.server.TestNestedLoop;
import org.h2.test.synth.TestBtreeIndex; import org.h2.test.synth.TestBtreeIndex;
...@@ -88,62 +90,77 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -88,62 +90,77 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
TestAll test = new TestAll(); TestAll test = new TestAll();
test.printSystem(); test.printSystem();
// pilar sms
/* /*
CREATE TABLE T(DATA VARCHAR(10), MYINT INTEGER); drop table people;
INSERT INTO T (DATA,MYINT) VALUES (null,1); drop table cars;
@META select ifnull(t.data, 0), myint from t; create table people (family varchar(1) not null, person
-- 1 should be VARCHAR varchar(1) not null);
select ifnull(t.data, 0), myint from t; create table cars (family varchar(1) not null, car
drop table t; varchar(1) not null);
insert into people values(1, 1);
insert into people values(2, 1);
insert into people values(2, 2);
insert into people values(3, 1);
insert into people values(5, 1);
insert into cars values(2, 1);
insert into cars values(2, 2);
insert into cars values(3, 1);
insert into cars values(3, 2);
insert into cars values(3, 3);
insert into cars values(4, 1);
select family, (select count(car) from cars where cars.family = people.family) as x
from people group by family;
*/ */
// link_table_update.patch.txt
// runscript and script: use 'script' parameter as before
// autocomplete: scroll up on new list
// doc array
// www.inventec.ch/chdh
// www.source-code.biz
/*
Pavel Ganelin
Integrate patches www.dullesopen.com/software/h2-database-03-04-07-mod.src.zip
*/
/* /*
drop all objects; drop all objects;
create table parent(id int primary key, parent int); create table parent(id int primary key, parent int);
insert into parent values(1, null), (2, 1), (3, 1); insert into parent values(1, null), (2, 1), (3, 1);
create view recursive test_view(id, parent) as with test_view(id, parent) as
select id, parent from parent select id, parent from parent where parent is null
union all
select parent.id, parent.parent from test_view, parent
where parent.parent = test_view.id
select * from test_view;
with test_view(id, parent) as
select id, parent from parent where id = 2
union all union all
select parent.id, parent.parent from test_view, parent select parent.id, parent.parent from test_view, parent
where parent.id = test_view.parent; where parent.parent = test_view.id
select * from test_view;
drop view test_view; drop view test_view;
@LOOP 10 with test_view(id, parent) as
select id, parent from parent where id = ?
union all
select parent.id, parent.parent from test_view, parent
where parent.parent = test_view.id
select * from test_view;
drop table parent; drop table parent;
*/ */
// Under certain conditions in client/server mode, obtaining text values /*
// of CLOBs becomes very slow (e.g., it could take a minimum of 200 ms create local temporary table abc(id varchar) on commit drop;
// instead of 2 ms). If I change the column type to VARCHAR, the insert into abc select * from dual;
// performance is very fast again. create local temporary table abc(id varchar) on commit drop;
// insert into abc select * from dual where 1=0;
// Between 2006-12-03 and 2006-12-17, you remarked: "Very large BLOB and create local temporary table abc(id varchar) on commit drop;
// CLOB data can now be used with the server and the cluster mode. The insert into abc select * from dual;
// objects will temporarily be buffered on the client side if they are drop table abc;
// larger than some size (currently 64 KB)." */
//
// I think the issue is now in Transfer.java, as below:
// 272: writer.flush();
// 273: writeInt(LOB_MAGIC);
//
// I believe the flush() can cause a TCP performance problem in certain
// circumstances. The reason is that when flush() occurs, the blob
// packets are flushed over the network, then a TCP ACK must be exchanged
// from client to server before the separate LOB_MAGIC packet can be sent
// from the server to client. This can cause enough latency to degrade
// application performance noticeably.
//
// I do not know of a good way to solve this, since you cannot avoid
// calling writer.flush(). One "workaround" for some applications is to
// convert CLOB to VARCHAR. However, I am currently trying something
// different. It works so far for me. My "patch" is:
//
// Transfer.java, at line 267:
// java.io.OutputStream out2 = new java.io.FilterOutputStream(out) {
// public void flush() {} };
// Writer writer = new OutputStreamWriter(out2, Constants.UTF8);
//
// James.
// TODO: fix Hibernate dialect bug / Bordea Felix (lost email) // TODO: fix Hibernate dialect bug / Bordea Felix (lost email)
...@@ -169,6 +186,102 @@ drop table parent; ...@@ -169,6 +186,102 @@ drop table parent;
// EXPLAIN SELECT * FROM test WHERE id between 2 and 3 AND flag=true; // EXPLAIN SELECT * FROM test WHERE id between 2 and 3 AND flag=true;
// EXPLAIN SELECT * FROM test WHERE id=2 AND flag; // EXPLAIN SELECT * FROM test WHERE id=2 AND flag;
/*
TODO: get FunctionAlias.java from mail
Here are the proposed changes to support function overload for variable number of arguments
Example/Test Case
public class OverloadFunction extends TestCase {
public void testOverload() throws Exception {
Class.forName("org.h2.Driver");
Connection ca = DriverManager.getConnection("jdbc:h2:mem:");
Statement sa = ca.createStatement();
sa.execute("CREATE ALIAS foo FOR \"" + this.getClass().getName() + ".foo\"");
ResultSet rs1 = sa.executeQuery("SELECT foo('a',2)");
rs1.next();
assertEquals(2.0, rs1.getDouble(1));
ResultSet rs2 = sa.executeQuery("SELECT foo('a',2,3,4)");
rs2.next();
assertEquals(9.0, rs2.getDouble(1));
try {
ResultSet rs = sa.executeQuery("SELECT foo()");
fail();
} catch (SQLException e) {
e.printStackTrace();
}
try {
ResultSet rs = sa.executeQuery("SELECT foo('a')");
fail();
} catch (SQLException e) {
e.printStackTrace();
}
try {
ResultSet rs = sa.executeQuery("SELECT foo(2,'a')");
fail();
} catch (SQLException e) {
e.printStackTrace();
}
try {
ResultSet rs = sa.executeQuery("SELECT foo('a',2,3)");
fail();
} catch (SQLException e) {
e.printStackTrace();
}
try {
ResultSet rs = sa.executeQuery("SELECT foo('a',2,3,4,5)");
fail();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static double foo(String s, int i) {
return i;
}
public static double foo(String s, int i, double d1, double d2) {
return i + d1 + d2;
}
}
Changes in the Parser
CODE
private JavaFunction readJavaFunction(String name) throws SQLException {
FunctionAlias functionAlias = database.findFunctionAlias(name);
if (functionAlias == null) {
// TODO compatibility: maybe support 'on the fly java functions' as HSQLDB ( CALL "java.lang.Math.sqrt"(2.0) )
throw Message.getSQLException(Message.FUNCTION_NOT_FOUND_1, name);
}
int paramCount = functionAlias.getParameterCount();
int max = functionAlias.getMaxParameterCount();
ObjectArray list = new ObjectArray(paramCount);
do {
if (functionAlias.isAcceptableParameterCount(list.size())) {
if (readIf(")"))
break;
}
if (list.size() == max) {
read(")"); // force syntax error for extra argument
break;
}
if (list.size() > 0) {
read(",");
}
Expression e = readExpression();
list.add(e);
} while (true);
Expression[] args = new Expression[list.size()];
for (int i = 0; i < args.length; i++) {
args[i] = (Expression) list.get(i);
}
JavaFunction func = new JavaFunction(functionAlias, args);
return func;
}
I also attached FunctionAlias.java file
Pavel
*/
// h2 // h2
// update FOO set a = dateadd('second', 4320000, a); // update FOO set a = dateadd('second', 4320000, a);
// ms sql server // ms sql server
...@@ -199,6 +312,8 @@ drop table parent; ...@@ -199,6 +312,8 @@ drop table parent;
// -- Oracle, Derby: 10, 11 // -- Oracle, Derby: 10, 11
// -- PostgreSQL, H2, HSQLDB: 1, 2 // -- PostgreSQL, H2, HSQLDB: 1, 2
// auto-upgrade application: // auto-upgrade application:
// check if new version is available // check if new version is available
// (option: digital signature) // (option: digital signature)
...@@ -428,24 +543,24 @@ drop table parent; ...@@ -428,24 +543,24 @@ drop table parent;
} }
void testUnit() { void testUnit() {
new TestBitField().runTest(this); // new TestBitField().runTest(this);
new TestCompress().runTest(this); // new TestCompress().runTest(this);
new TestDataPage().runTest(this); // new TestDataPage().runTest(this);
new TestExit().runTest(this); // new TestExit().runTest(this);
new TestFileLock().runTest(this); // new TestFileLock().runTest(this);
new TestIntArray().runTest(this); // new TestIntArray().runTest(this);
new TestIntIntHashMap().runTest(this); // new TestIntIntHashMap().runTest(this);
new TestOverflow().runTest(this); // new TestOverflow().runTest(this);
new TestPattern().runTest(this); // new TestPattern().runTest(this);
new TestReader().runTest(this); // new TestReader().runTest(this);
new TestSampleApps().runTest(this); // new TestSampleApps().runTest(this);
new TestScriptReader().runTest(this); // new TestScriptReader().runTest(this);
new TestSecurity().runTest(this); // new TestSecurity().runTest(this);
new TestStreams().runTest(this); // new TestStreams().runTest(this);
new TestStringCache().runTest(this); // new TestStringCache().runTest(this);
new TestStringUtils().runTest(this); // new TestStringUtils().runTest(this);
new TestTools().runTest(this); new TestTools().runTest(this);
new TestValueHashMap().runTest(this); // new TestValueHashMap().runTest(this);
} }
void testDatabase() throws Exception { void testDatabase() throws Exception {
...@@ -453,59 +568,60 @@ drop table parent; ...@@ -453,59 +568,60 @@ drop table parent;
beforeTest(); beforeTest();
// db // db
new TestScriptSimple().runTest(this); // new TestScriptSimple().runTest(this);
new TestScript().runTest(this); // new TestScript().runTest(this);
new TestAutoRecompile().runTest(this); // new TestAutoRecompile().runTest(this);
new TestBatchUpdates().runTest(this); // new TestBackup().runTest(this);
new TestBigDb().runTest(this); // new TestBatchUpdates().runTest(this);
new TestBigResult().runTest(this); // new TestBigDb().runTest(this);
new TestCache().runTest(this); // new TestBigResult().runTest(this);
new TestCases().runTest(this); // new TestCache().runTest(this);
new TestCheckpoint().runTest(this); // new TestCases().runTest(this);
new TestCluster().runTest(this); // new TestCheckpoint().runTest(this);
new TestCompatibility().runTest(this); // new TestCluster().runTest(this);
new TestCsv().runTest(this); // new TestCompatibility().runTest(this);
new TestFunctions().runTest(this); // new TestCsv().runTest(this);
new TestIndex().runTest(this); // new TestFunctions().runTest(this);
new TestLinkedTable().runTest(this); // new TestIndex().runTest(this);
new TestListener().runTest(this); // new TestLinkedTable().runTest(this);
new TestLob().runTest(this); // new TestListener().runTest(this);
new TestLogFile().runTest(this); // new TestLob().runTest(this);
new TestMemoryUsage().runTest(this); // new TestLogFile().runTest(this);
new TestMultiConn().runTest(this); // new TestMemoryUsage().runTest(this);
new TestMultiDimension().runTest(this); // new TestMultiConn().runTest(this);
new TestMultiThread().runTest(this); // new TestMultiDimension().runTest(this);
new TestOpenClose().runTest(this); // new TestMultiThread().runTest(this);
new TestOptimizations().runTest(this); // new TestOpenClose().runTest(this);
new TestPowerOff().runTest(this); // new TestOptimizations().runTest(this);
new TestReadOnly().runTest(this); // new TestPowerOff().runTest(this);
new TestRights().runTest(this); // new TestReadOnly().runTest(this);
new TestRunscript().runTest(this); // new TestRights().runTest(this);
new TestSQLInjection().runTest(this); // new TestRunscript().runTest(this);
new TestSequence().runTest(this); // new TestSQLInjection().runTest(this);
new TestSpaceReuse().runTest(this); // new TestSequence().runTest(this);
new TestSpeed().runTest(this); // new TestSpaceReuse().runTest(this);
new TestTempTables().runTest(this); // new TestSpeed().runTest(this);
new TestTransaction().runTest(this); // new TestTempTables().runTest(this);
new TestTriggersConstraints().runTest(this); // new TestTransaction().runTest(this);
new TestTwoPhaseCommit().runTest(this); // new TestTriggersConstraints().runTest(this);
// new TestTwoPhaseCommit().runTest(this);
// server //
new TestNestedLoop().runTest(this); // // server
// new TestNestedLoop().runTest(this);
// jdbc //
new TestCancel().runTest(this); // // jdbc
new TestDataSource().runTest(this); // new TestCancel().runTest(this);
new TestManyJdbcObjects().runTest(this); // new TestDataSource().runTest(this);
new TestMetaData().runTest(this); // new TestManyJdbcObjects().runTest(this);
new TestNativeSQL().runTest(this); // new TestMetaData().runTest(this);
new TestPreparedStatement().runTest(this); // new TestNativeSQL().runTest(this);
new TestResultSet().runTest(this); // new TestPreparedStatement().runTest(this);
new TestStatement().runTest(this); // new TestResultSet().runTest(this);
new TestTransactionIsolation().runTest(this); // new TestStatement().runTest(this);
new TestUpdatableResultSet().runTest(this); // new TestTransactionIsolation().runTest(this);
new TestXA().runTest(this); // new TestUpdatableResultSet().runTest(this);
new TestZloty().runTest(this); // new TestXA().runTest(this);
// new TestZloty().runTest(this);
afterTest(); afterTest();
} }
......
...@@ -16,6 +16,7 @@ import java.sql.SQLException; ...@@ -16,6 +16,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
...@@ -561,4 +562,24 @@ public abstract class TestBase { ...@@ -561,4 +562,24 @@ public abstract class TestBase {
} }
} }
protected void compareDatabases(Statement stat1, Statement stat2) throws Exception {
ResultSet rs1 = stat1.executeQuery("SCRIPT NOPASSWORDS");
ResultSet rs2 = stat2.executeQuery("SCRIPT NOPASSWORDS");
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
while(rs1.next()) {
check(rs2.next());
list1.add(rs1.getString(1));
list2.add(rs2.getString(1));
}
for(int i=0; i<list1.size(); i++) {
String s = (String)list1.get(i);
if(!list2.remove(s)) {
error("not found: " + s);
}
}
check(list2.size(), 0);
checkFalse(rs2.next());
}
} }
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- special grammar and test cases ---------------------------------------------------------------------------------------------
select (1, 2);
> 1, 2
> ------
> (1, 2)
> rows: 1
select * from table(id int=(1, 2), name varchar=('Hello', 'World')) x order by id;
> ID NAME
> -- -----
> 1 Hello
> 2 World
> rows (ordered): 2
create table array_test(x array);
> ok
insert into array_test values((1, 2, 3)), ((2, 3, 4));
> update count: 2
select * from array_test where x = (1, 2, 3);
> X
> ---------
> (1, 2, 3)
> rows: 1
drop table array_test;
> ok
select * from (select 1), (select 2);
> 1 2
> - -
> 1 2
> rows: 1
CREATE TABLE TEST(A VARCHAR, B VARCHAR, C VARCHAR AS LOWER(A));
> ok
ALTER TABLE TEST DROP COLUMN B;
> ok
DROP TABLE TEST;
> ok
create table t1(c1 int, c2 int); create table t1(c1 int, c2 int);
> ok > ok
...@@ -7431,8 +7474,8 @@ select ifnull(null, '1') x1, ifnull(null, null) xn, ifnull('a', 'b') xa from tes ...@@ -7431,8 +7474,8 @@ select ifnull(null, '1') x1, ifnull(null, null) xn, ifnull('a', 'b') xa from tes
select casewhen(null, '1', '2') xn, casewhen(1>0, 'n', 'y') xy, casewhen(0<1, 'a', 'b') xa from test; select casewhen(null, '1', '2') xn, casewhen(1>0, 'n', 'y') xy, casewhen(0<1, 'a', 'b') xa from test;
> XN XY XA > XN XY XA
> ---- -- -- > -- -- --
> null n a > 2 n a
> rows: 1 > rows: 1
select x, case when x=0 then 'zero' else 'not zero' end y from system_range(0, 2); select x, case when x=0 then 'zero' else 'not zero' end y from system_range(0, 2);
......
create table test(id int primary key check id>1);
drop table test;
create table table1(f1 int not null primary key);
create table table2(f2 int not null references table1(f1) on delete cascade);
drop table table2;
drop table table1;
create table table1(f1 int not null primary key);
create table table2(f2 int not null primary key references table1(f1));
drop table table1;
drop table table2;
select case when 1=null then 1 else 2 end;
> 2;
select case (1) when 1 then 1 else 2 end; select case (1) when 1 then 1 else 2 end;
> 1; > 1;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论