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

--no commit message

--no commit message
上级 93698a6d
......@@ -1318,6 +1318,9 @@ public class Parser {
currentSelect = oldSelect;
}
if (readIf("LIMIT")) {
Select temp = currentSelect;
// make sure aggregate functions will not work here
currentSelect = null;
Expression limit = readExpression().optimize(session);
command.setLimit(limit);
if (readIf("OFFSET")) {
......@@ -1333,6 +1336,7 @@ public class Parser {
if (readIf("SAMPLE_SIZE")) {
command.setSampleSize(getPositiveInt());
}
currentSelect = temp;
}
if (readIf("FOR")) {
if (readIf("UPDATE")) {
......@@ -1402,6 +1406,9 @@ public class Parser {
}
private void parseSelectSimpleSelectPart(Select command) throws SQLException {
Select temp = currentSelect;
// make sure aggregate functions will not work in TOP and LIMIT clauses
currentSelect = null;
if (readIf("TOP")) {
// can't read more complex expressions here because
// SELECT TOP 1 +? A FROM TEST could mean
......@@ -1415,6 +1422,7 @@ public class Parser {
Expression limit = readTerm().optimize(session);
command.setLimit(limit);
}
currentSelect = temp;
if (readIf("DISTINCT")) {
command.setDistinct(true);
} else {
......@@ -4323,8 +4331,7 @@ public class Parser {
command.setTableName(tableName);
command.setComment(readCommentIf());
if (readIf("AS")) {
Query query = parseSelect();
command.setQuery(query);
command.setQuery(parseSelect());
} else {
read("(");
if (!readIf(")")) {
......@@ -4389,6 +4396,9 @@ public class Parser {
} while (readIf(","));
read(")");
}
if (readIf("AS")) {
command.setQuery(parseSelect());
}
}
if (temp) {
if (readIf("ON")) {
......
......@@ -59,6 +59,9 @@ public class CreateTable extends SchemaCommand {
}
public void addColumn(Column column) {
if (columns == null) {
columns = new ObjectArray();
}
columns.add(column);
}
......@@ -97,7 +100,12 @@ public class CreateTable extends SchemaCommand {
throw Message.getSQLException(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, tableName);
}
if (asQuery != null) {
generateColumnFromQuery();
asQuery.prepare();
if (columns.size() == 0) {
generateColumnFromQuery();
} else if (columns.size() != asQuery.getColumnCount()) {
throw Message.getSQLException(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
}
if (pkColumns != null) {
int len = pkColumns.length;
......@@ -174,7 +182,6 @@ public class CreateTable extends SchemaCommand {
}
private void generateColumnFromQuery() throws SQLException {
asQuery.prepare();
int columnCount = asQuery.getColumnCount();
ObjectArray expressions = asQuery.getExpressions();
for (int i = 0; i < columnCount; i++) {
......
......@@ -445,7 +445,7 @@ TABLE [IF NOT EXISTS] name
[{AUTO_INCREMENT | IDENTITY}[(startInt [, incrementInt])]]
[SELECTIVITY selectivity]
[PRIMARY KEY [HASH] | UNIQUE]
| constraint} [,...] ) } | { AS select }
| constraint} [,...] ) [ AS select ] } | { AS select }
","
Creates a new table.
Cached tables (the default) are persistent, and the number or rows is not limited by the main memory.
......
......@@ -44,8 +44,8 @@ public class TcpServer implements Service {
// automatically use the next free port?
public static final int DEFAULT_PORT = 9092;
public static final int SHUTDOWN_NORMAL = 0;
public static final int SHUTDOWN_FORCE = 1;
private static final int SHUTDOWN_NORMAL = 0;
private static final int SHUTDOWN_FORCE = 1;
public static boolean logInternalErrors;
private int port;
......@@ -111,40 +111,34 @@ public class TcpServer implements Service {
return ports;
}
void addConnection(int id, String url, String user) {
synchronized (TcpServer.class) {
try {
managementDbAdd.setInt(1, id);
managementDbAdd.setString(2, url);
managementDbAdd.setString(3, user);
managementDbAdd.execute();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
synchronized void addConnection(int id, String url, String user) {
try {
managementDbAdd.setInt(1, id);
managementDbAdd.setString(2, url);
managementDbAdd.setString(3, user);
managementDbAdd.execute();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
}
void removeConnection(int id) {
synchronized (TcpServer.class) {
try {
managementDbRemove.setInt(1, id);
managementDbRemove.execute();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
synchronized void removeConnection(int id) {
try {
managementDbRemove.setInt(1, id);
managementDbRemove.execute();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
}
private void stopManagementDb() {
synchronized (TcpServer.class) {
if (managementDb != null) {
try {
managementDb.close();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
managementDb = null;
private synchronized void stopManagementDb() {
if (managementDb != null) {
try {
managementDb.close();
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
managementDb = null;
}
}
......@@ -183,11 +177,9 @@ public class TcpServer implements Service {
return NetUtils.isLoopbackAddress(socket);
}
public void start() throws SQLException {
synchronized (TcpServer.class) {
serverSocket = NetUtils.createServerSocket(port, ssl);
initManagementDb();
}
public synchronized void start() throws SQLException {
serverSocket = NetUtils.createServerSocket(port, ssl);
initManagementDb();
}
public void listen() {
......@@ -212,7 +204,7 @@ public class TcpServer implements Service {
stopManagementDb();
}
public boolean isRunning() {
public synchronized boolean isRunning() {
if (serverSocket == null) {
return false;
}
......@@ -225,44 +217,44 @@ public class TcpServer implements Service {
}
}
public void stop() {
public synchronized void stop() {
// TODO server: share code between web and tcp servers
synchronized (TcpServer.class) {
if (!stop) {
stopManagementDb();
stop = true;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
TraceSystem.traceThrowable(e);
}
serverSocket = null;
}
if (listenerThread != null) {
try {
listenerThread.join(1000);
} catch (InterruptedException e) {
TraceSystem.traceThrowable(e);
}
// need to remove the server first, otherwise the connection is broken
// while the server is still registered in this map
SERVERS.remove("" + port);
if (!stop) {
stopManagementDb();
stop = true;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
TraceSystem.traceThrowable(e);
}
serverSocket = null;
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running);
for (int i = 0; i < list.size(); i++) {
TcpServerThread c = (TcpServerThread) list.get(i);
c.close();
if (listenerThread != null) {
try {
c.getThread().join(100);
} catch (Exception e) {
listenerThread.join(1000);
} catch (InterruptedException e) {
TraceSystem.traceThrowable(e);
}
}
SERVERS.remove("" + port);
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running);
for (int i = 0; i < list.size(); i++) {
TcpServerThread c = (TcpServerThread) list.get(i);
c.close();
try {
c.getThread().join(100);
} catch (Exception e) {
TraceSystem.traceThrowable(e);
}
}
}
public static synchronized void stopServer(int port, String password, int shutdownMode) {
public static void stopServer(int port, String password, int shutdownMode) {
TcpServer server = (TcpServer) SERVERS.get("" + port);
if (server == null) {
return;
......@@ -270,7 +262,7 @@ public class TcpServer implements Service {
if (!server.managementPassword.equals(password)) {
return;
}
if (shutdownMode == TcpServer.SHUTDOWN_NORMAL) {
if (shutdownMode == SHUTDOWN_NORMAL) {
server.stopManagementDb();
server.stop = true;
try {
......@@ -279,7 +271,7 @@ public class TcpServer implements Service {
} catch (Exception e) {
// try to connect - so that accept returns
}
} else if (shutdownMode == TcpServer.SHUTDOWN_FORCE) {
} else if (shutdownMode == SHUTDOWN_FORCE) {
server.stop();
}
}
......@@ -318,7 +310,7 @@ public class TcpServer implements Service {
}
public void logInternalError(String string) {
if (TcpServer.logInternalErrors) {
if (logInternalErrors) {
System.out.println(string);
new Error(string).printStackTrace();
}
......@@ -339,7 +331,7 @@ public class TcpServer implements Service {
}
port = MathUtils.decodeInt(p);
}
String db = TcpServer.getManagementDbName(port);
String db = getManagementDbName(port);
try {
org.h2.Driver.load();
} catch (Throwable e) {
......@@ -353,7 +345,7 @@ public class TcpServer implements Service {
prep = conn.prepareStatement("CALL STOP_SERVER(?, ?, ?)");
prep.setInt(1, port);
prep.setString(2, password);
prep.setInt(3, force ? TcpServer.SHUTDOWN_FORCE : TcpServer.SHUTDOWN_NORMAL);
prep.setInt(3, force ? SHUTDOWN_FORCE : SHUTDOWN_NORMAL);
try {
prep.execute();
} catch (SQLException e) {
......
......@@ -80,6 +80,7 @@ import org.h2.test.synth.TestRandomSQL;
import org.h2.test.synth.TestTimer;
import org.h2.test.synth.sql.TestSynth;
import org.h2.test.synth.thread.TestMulti;
import org.h2.test.unit.SelfDestructor;
import org.h2.test.unit.TestBitField;
import org.h2.test.unit.TestCache;
import org.h2.test.unit.TestCompress;
......@@ -147,6 +148,7 @@ java org.h2.test.TestAll timer
public boolean cache2Q;
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(6 * 60);
long time = System.currentTimeMillis();
TestAll test = new TestAll();
test.printSystem();
......@@ -159,21 +161,8 @@ REUSE_SPACE_AFTER=20 or so
delete old ipowerb content (first filter, then remove)
link to new changelog and roadmap, remove pages from google groups
sourceDocs.html: move
Automate real power off tests
timer test
Can sometimes not delete log file? need test case
Adjust cache memory usage
// test with garbage at the end of the log file (must be consistently detected as such)
// extend the random join test that compared the result against PostgreSQL
// long running test with the same database
// repeatable test with a very big database (making backups of the database files)
Test Recovery with MAX_LOG_FILE_SIZE=1; test with various log file sizes
History:
Roadmap:
......
......@@ -18,6 +18,7 @@ import java.util.Random;
import org.h2.test.TestAll;
import org.h2.test.TestBase;
import org.h2.test.unit.SelfDestructor;
import org.h2.tools.Backup;
import org.h2.tools.DeleteDbFiles;
import org.h2.util.IOUtils;
......@@ -149,9 +150,9 @@ public abstract class TestHalt extends TestBase {
// for Derby and HSQLDB
// String classPath = "-cp
// .;D:/data/java/hsqldb.jar;D:/data/java/derby.jar";
String selfDestruct = SelfDestructor.getPropertyString(60);
String classPath = "";
String command = "java " + classPath + " " + getClass().getName() + " " + operations + " " + flags + " "
+ value;
String[] command = {"java", selfDestruct, classPath, getClass().getName(), "" + operations, "" + flags, "" + value};
traceOperation("start: " + command);
Process p = Runtime.getRuntime().exec(command);
InputStream in = p.getInputStream();
......
......@@ -9,6 +9,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.test.unit.SelfDestructor;
/**
* The application code for the {@link TestHalt} application.
*/
......@@ -17,6 +19,7 @@ public class TestHaltApp extends TestHalt {
private int rowCount;
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(60);
baseDir = TestHalt.DIR;
new TestHaltApp().start(args);
}
......
......@@ -12,6 +12,7 @@ import java.sql.Statement;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.test.unit.SelfDestructor;
/**
* A random recovery test. This test starts a process that executes random operations
......@@ -32,8 +33,8 @@ public class TestKill extends TestBase {
String url = getURL(DIR + "/kill" + connect, true);
String user = getUser();
String password = getPassword();
String[] procDef = new String[] { "java.exe", "-cp", "bin", "org.h2.test.synth.TestKillProcess", url, user,
String selfDestruct = SelfDestructor.getPropertyString(60);
String[] procDef = new String[] { "java", selfDestruct, "-cp", "bin", "org.h2.test.synth.TestKillProcess", url, user,
password, baseDir, "" + accounts };
for (int i = 0;; i++) {
......
......@@ -12,12 +12,14 @@ import java.util.Random;
import org.h2.store.FileLister;
import org.h2.test.TestBase;
import org.h2.test.unit.SelfDestructor;
/**
* Test application for {@link TestKill}.
*/
public class TestKillProcess {
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(60);
try {
Class.forName("org.h2.Driver");
String url = args[0], user = args[1], password = args[2];
......
......@@ -13,6 +13,7 @@ import java.sql.Statement;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.test.unit.SelfDestructor;
/**
* Standalone recovery test. A new process is started and then killed while it
......@@ -28,8 +29,8 @@ public class TestKillRestart extends TestBase {
String url = getURL("killRestart", true);
// String url = getURL("killRestart;CACHE_SIZE=2048;WRITE_DELAY=0;STORAGE=TEXT", true);
String user = getUser(), password = getPassword();
String[] procDef = new String[] { "java", "-cp", "bin", getClass().getName(), "-url", url, "-user", user,
String selfDestruct = SelfDestructor.getPropertyString(60);
String[] procDef = new String[] { "java", selfDestruct, "-cp", "bin", getClass().getName(), "-url", url, "-user", user,
"-password", password };
int len = getSize(2, 15);
......@@ -59,6 +60,7 @@ public class TestKillRestart extends TestBase {
}
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(60);
String driver = "org.h2.Driver";
String url = "jdbc:h2:test", user = "sa", password = "sa";
for (int i = 0; i < args.length; i++) {
......
......@@ -15,6 +15,7 @@ import java.util.Random;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
import org.h2.test.unit.SelfDestructor;
import org.h2.tools.Backup;
import org.h2.util.FileUtils;
......@@ -39,8 +40,8 @@ public class TestKillRestartMulti extends TestBase {
// String url = getURL("killRestartMulti;CACHE_SIZE=2048;WRITE_DELAY=0;STORAGE=TEXT", true);
user = getUser();
password = getPassword();
String[] procDef = new String[] { "java", "-cp", "bin", getClass().getName(), "-url", url, "-user", user,
String selfDestruct = SelfDestructor.getPropertyString(60);
String[] procDef = new String[] { "java", selfDestruct, "-cp", "bin", getClass().getName(), "-url", url, "-user", user,
"-password", password };
deleteDb("killRestartMulti");
int len = getSize(3, 10);
......@@ -97,6 +98,7 @@ public class TestKillRestartMulti extends TestBase {
}
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(60);
new TestKillRestartMulti().test(args);
}
......@@ -129,8 +131,6 @@ public class TestKillRestartMulti extends TestBase {
createTable(random);
}
int p = random.nextInt(100);
int todoLargeInsertsDeletes;
int todoAlterTable;
if ((p -= 2) <= 0) {
// 2%: open new connection
if (connections.size() < 5) {
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select top sum(1) 0 from dual;
> exception
create table test(id int primary key, name varchar) as select 1, 'Hello World';
> ok
select * from test;
> ID NAME
> -- -----------
> 1 Hello World
> rows: 1
drop table test;
> ok
select rtrim() from dual;
> exception
......
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
/**
* This is a self-destructor class to kill a long running process automatically after
* a pre-defined time. The class reads the number of minutes
* from the system property 'h2.selfDestruct' and starts a countdown thread
* to kill the virtual machine if it still runs then.
*/
public class SelfDestructor extends Thread {
private static final String PROPERTY_NAME = "h2.selfDestruct";
/**
* Start the countdown. If the self-destruct system property is set, this value is used,
* otherwise the given default value is used.
*
* @param defaultMinutes the default number of minutes after which the current process is killed.
*/
public static void startCountdown(int defaultMinutes) {
final int minutes = Integer.parseInt(System.getProperty(PROPERTY_NAME, "" + defaultMinutes));
if (minutes != 0) {
Thread thread = new Thread() {
public void run() {
for (int i = minutes; i >= 0; i--) {
setName("SelfDestructor " + i + " min");
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
// ignore
}
}
Runtime.getRuntime().halt(1);
}
};
thread.setDaemon(true);
thread.start();
}
}
/**
* Get the string to be added when starting the Java process.
*
* @param minutes the countdown time in minutes
* @return the setting
*/
public static String getPropertyString(int minutes) {
return "-D" + PROPERTY_NAME + "=" + minutes;
}
}
......@@ -27,7 +27,8 @@ public class TestExit extends TestBase implements DatabaseEventListener {
deleteDb("exit");
String[] procDef;
procDef = new String[] { "java", "-cp", classPath, getClass().getName(), "" + OPEN_WITH_CLOSE_ON_EXIT };
String selfDestruct = SelfDestructor.getPropertyString(60);
procDef = new String[] { "java", selfDestruct, "-cp", classPath, getClass().getName(), "" + OPEN_WITH_CLOSE_ON_EXIT };
Process proc = Runtime.getRuntime().exec(procDef);
while (true) {
int ch = proc.getErrorStream().read();
......@@ -62,6 +63,7 @@ public class TestExit extends TestBase implements DatabaseEventListener {
public static Connection conn;
public static void main(String[] args) throws Exception {
SelfDestructor.startCountdown(60);
if (args.length == 0) {
System.exit(1);
}
......
......@@ -72,7 +72,6 @@ public class TestTools extends TestBase {
result = runServer(new String[]{"-xy"}, 1);
check(result.indexOf("[options]") >= 0);
check(result.indexOf("Unknown option") >= 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "false", "-tcpPort", "9001", "-tcpPassword", "abc"}, 0);
check(result.indexOf("tcp://") >= 0);
check(result.indexOf(":9001") >= 0);
......@@ -90,8 +89,15 @@ public class TestTools extends TestBase {
check(result.indexOf("[options]") < 0);
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
conn.close();
result = runServer(new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "abcdef", "-tcpShutdownForce", "false"}, 0);
check(result.indexOf("Shutting down") >= 0);
try {
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
error();
} catch (SQLException e) {
checkNotGeneralException(e);
}
result = runServer(new String[]{
"-web", "-webPort", "9002", "-webAllowOthers", "true", "-webSSL", "true",
......@@ -113,6 +119,12 @@ public class TestTools extends TestBase {
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9005", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 0);
stop.shutdown();
try {
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9005/mem:", "sa", "sa");
error();
} catch (SQLException e) {
checkNotGeneralException(e);
}
}
private String runServer(String[] args, int exitCode) throws Exception {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论