提交 616fe6cb authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 184b84e6
......@@ -832,8 +832,18 @@ public class Parser {
String alias = null;
Schema mainSchema = database.getSchema(Constants.SCHEMA_MAIN);
if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM") || isToken("(")) {
Query query = parseSelect();
if (isToken("SELECT") || isToken("FROM")) {
int start = lastParseIndex;
int paramIndex = parameters.size();
Query query = parseSelectUnion();
read(")");
query = parseSelectUnionExtension(query, start);
ObjectArray params = new ObjectArray();
for (int i = paramIndex; i < parameters.size(); i++) {
params.add(parameters.get(i));
}
query.setParameterList(params);
query.init();
Session s;
if (prepared != null && prepared instanceof CreateView) {
s = database.getSystemSession();
......@@ -842,11 +852,14 @@ public class Parser {
}
table = TableView.createTempView(s, session.getUser(), query);
alias = table.getName();
read(")");
} else {
TableFilter top = readTableFilter(fromOuter);
top = readJoin(top, currentSelect, fromOuter);
read(")");
alias = readFromAlias(null);
if (alias != null) {
top.setAlias(alias);
}
return top;
}
} else {
......@@ -871,6 +884,11 @@ public class Parser {
table = readTableOrView(tableName);
}
}
alias = readFromAlias(alias);
return new TableFilter(session, table, alias, rightsChecked, currentSelect);
}
String readFromAlias(String alias) throws SQLException {
if (readIf("AS")) {
alias = readAliasIdentifier();
} else if (currentTokenType == IDENTIFIER) {
......@@ -880,7 +898,7 @@ public class Parser {
alias = readAliasIdentifier();
}
}
return new TableFilter(session, table, alias, rightsChecked, currentSelect);
return alias;
}
private Prepared parseTruncate() throws SQLException {
......@@ -1228,6 +1246,10 @@ public class Parser {
private Query parseSelectUnion() throws SQLException {
int start = lastParseIndex;
Query command = parseSelectSub();
return parseSelectUnionExtension(command, start);
}
private Query parseSelectUnionExtension(Query command, int start) throws SQLException {
while (true) {
if (readIf("UNION")) {
SelectUnion union = new SelectUnion(session, command);
......
......@@ -84,7 +84,7 @@ public abstract class Query extends Prepared {
return params;
}
public final LocalResult query(int limit) throws SQLException {
public LocalResult query(int limit) throws SQLException {
if (!session.getDatabase().getOptimizeReuseResults()) {
return queryWithoutCache(limit);
}
......@@ -246,10 +246,17 @@ public abstract class Query extends Prepared {
public abstract int getColumnCount();
public abstract void mapColumns(ColumnResolver resolver, int level) throws SQLException;
public abstract void setEvaluatable(TableFilter tableFilter, boolean b);
public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException;
public abstract void addGlobalCondition(Parameter param, int columnId, int comparisonType) throws SQLException;
public abstract void setDistinct(boolean b);
public abstract String getFirstColumnAlias(Session session);
void addParameter(Parameter param) {
if (parameters == null) {
parameters = new ObjectArray();
}
parameters.add(param);
}
public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize;
}
......
......@@ -16,6 +16,7 @@ import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Parameter;
import org.h2.expression.Wildcard;
import org.h2.index.Index;
import org.h2.message.Message;
......@@ -702,10 +703,11 @@ public class Select extends Query {
return isQuickQuery;
}
public void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException {
public void addGlobalCondition(Parameter param, int columnId, int comparisonType) throws SQLException {
addParameter(param);
Expression col = (Expression) expressions.get(columnId);
col = col.getNonAliasExpression();
Expression comp = new Comparison(session, comparisonType, col, expr);
Expression comp = new Comparison(session, comparisonType, col, param);
comp = comp.optimize(session);
boolean addToCondition = true;
if (isGroupQuery) {
......
......@@ -13,6 +13,7 @@ import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Parameter;
import org.h2.expression.ValueExpression;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.Message;
......@@ -252,17 +253,18 @@ public class SelectUnion extends Query {
right.setEvaluatable(tableFilter, b);
}
public void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException {
public void addGlobalCondition(Parameter param, int columnId, int comparisonType) throws SQLException {
addParameter(param);
switch (unionType) {
case UNION_ALL:
case UNION:
case INTERSECT: {
left.addGlobalCondition(expr, columnId, comparisonType);
right.addGlobalCondition(expr, columnId, comparisonType);
left.addGlobalCondition(param, columnId, comparisonType);
right.addGlobalCondition(param, columnId, comparisonType);
break;
}
case EXCEPT: {
left.addGlobalCondition(expr, columnId, comparisonType);
left.addGlobalCondition(param, columnId, comparisonType);
break;
}
default:
......@@ -316,6 +318,11 @@ public class SelectUnion extends Query {
return buff.toString();
}
public LocalResult query(int limit) throws SQLException {
// union doesn't always know the parameter list of the left and right queries
return queryWithoutCache(limit);
}
public boolean isEverything(ExpressionVisitor visitor) {
return left.isEverything(visitor) && right.isEverything(visitor);
}
......
......@@ -448,14 +448,14 @@ public class Database implements DataHandler {
fileData.init();
try {
fileIndex.init();
} catch (SQLException e) {
} catch (Throwable e) {
if (recovery) {
traceSystem.getTrace(Trace.DATABASE).error("opening index", e);
fileIndex.close();
fileIndex.delete();
openFileIndex();
} else {
throw e;
throw Message.convert(e);
}
}
reserveLobFileObjectIds();
......
......@@ -108,16 +108,17 @@ public class ViewIndex extends BaseIndex {
Column col = table.getColumn(idx);
columns[i] = col;
int mask = masks[idx];
int nextParamIndex = query.getParameters().size();
if ((mask & IndexCondition.EQUALITY) != 0) {
Parameter param = new Parameter(0);
Parameter param = new Parameter(nextParamIndex);
query.addGlobalCondition(param, idx, Comparison.EQUAL);
} else {
if ((mask & IndexCondition.START) != 0) {
Parameter param = new Parameter(0);
Parameter param = new Parameter(nextParamIndex);
query.addGlobalCondition(param, idx, Comparison.BIGGER_EQUAL);
}
if ((mask & IndexCondition.END) != 0) {
Parameter param = new Parameter(0);
Parameter param = new Parameter(nextParamIndex);
query.addGlobalCondition(param, idx, Comparison.SMALLER_EQUAL);
}
}
......
......@@ -113,7 +113,8 @@ If no file name is specified, the script is returned as a result set.
This command can be used to create a backup of the database.
If the DROP option is specified, drop statements are created for tables, views, and sequences.
If the block size is set, CLOB and BLOB values larger than this size are split into separate blocks.
If a file name is specified, a result set without insert statements is returned.
If a file name is specified, then the whole script (including insert statements) is written to this file,
and a result set without the insert statements is returned.
When using encryption, only DEFLATE and LZF are supported.
The password must be in single quotes. It is case sensitive and can contain spaces.
","
......
......@@ -32,8 +32,8 @@ import org.h2.value.Value;
public class TableFilter implements ColumnResolver {
private static final int BEFORE_FIRST = 0, FOUND = 1, AFTER_LAST = 2, NULL_ROW = 3;
private final Table table;
private final String alias;
private final Select select;
private String alias;
private Session session;
private Index index;
private IndexColumn[] indexColumns;
......@@ -52,9 +52,9 @@ public class TableFilter implements ColumnResolver {
private SearchRow currentSearchRow;
private Row current;
private int state;
private TableFilter join;
private boolean outerJoin;
private boolean foundOne;
private Expression fullCondition;
......@@ -290,7 +290,7 @@ public class TableFilter implements ColumnResolver {
state = AFTER_LAST;
return false;
}
private void logScanCount() {
// System.out.println(this.alias+ " " + table.getName() + ": " + scanCount);
}
......@@ -567,4 +567,8 @@ public class TableFilter implements ColumnResolver {
return this;
}
public void setAlias(String alias) {
this.alias = alias;
}
}
......@@ -154,18 +154,13 @@ java org.h2.test.TestAll timer
/*
add link to:
www.s-appsys.com
documentation: package.html
write to the db file what version was used to create a database
History:
CSV tool: the character # could not be used as a separator when reading.
CSV tool: some escape/separator character combinations did not work. Fixed.
Roadmap:
remove
* Stop the server: close all open databases first
Web site:
......
......@@ -4,10 +4,29 @@
*/
package org.h2.test.bench;
/**
* The interface for benchmark tests.
*/
public interface Bench {
/**
* Initialize the database. This includes creating tables and inserting data.
*
* @param db the database object
* @param size the amount of data
*/
void init(Database db, int size) throws Exception;
/**
* Run the test.
*/
void runTest() throws Exception;
/**
* Get the name of the test.
*
* @return the test name
*/
String getName();
}
......@@ -9,6 +9,9 @@ import java.sql.PreparedStatement;
import java.util.Random;
/**
* This test is similar to the TPC-A test of the Transaction Processing Council (TPC).
* However, only one connection and one thread is used.
*<p>
* See also: http://www.tpc.org/tpca/spec/tpca_current.pdf
*/
public class BenchA implements Bench {
......@@ -19,14 +22,14 @@ public class BenchA implements Bench {
private int tellers;
private int accounts;
private int size;
private static final String FILLER = "abcdefghijklmnopqrstuvwxyz";
private static final int DELTA = 10000;
public void init(Database db, int size) throws Exception {
this.db = db;
this.size = size;
int scale = 1;
accounts = size * 50;
tellers = Math.max(accounts / 10, 1);
......@@ -49,7 +52,7 @@ public class BenchA implements Bench {
for (int i = 0; i < create.length; i++) {
db.update(create[i]);
}
PreparedStatement prep;
db.setAutoCommit(false);
int commitEvery = 1000;
......@@ -59,7 +62,7 @@ public class BenchA implements Bench {
db.update(prep, "insertBranches");
if (i % commitEvery == 0) {
db.commit();
}
}
}
db.commit();
prep = db.prepare("INSERT INTO TELLERS(TID,BID,TBALANCE,FILLER) VALUES(?,?,10000.00,'" + FILLER + "')");
......@@ -69,7 +72,7 @@ public class BenchA implements Bench {
db.update(prep, "insertTellers");
if (i % commitEvery == 0) {
db.commit();
}
}
}
db.commit();
int len = accounts * scale;
......@@ -80,16 +83,16 @@ public class BenchA implements Bench {
db.update(prep, "insertAccounts");
if (i % commitEvery == 0) {
db.commit();
}
}
}
db.commit();
db.closeConnection();
db.end();
// db.start(this, "Open/Close");
// db.openConnection();
// db.closeConnection();
// db.end();
// db.end();
}
public void runTest() throws Exception {
......@@ -99,20 +102,20 @@ public class BenchA implements Bench {
processTransactions();
db.closeConnection();
db.end();
db.openConnection();
processTransactions();
db.logMemory(this, "Memory Usage");
db.closeConnection();
}
private void processTransactions() throws Exception {
Random random = db.getRandom();
int branch = random.nextInt(branches);
int teller = random.nextInt(tellers);
int transactions = size * 30;
PreparedStatement updateAccount = db.prepare("UPDATE ACCOUNTS SET ABALANCE=ABALANCE+? WHERE AID=?");
PreparedStatement selectBalance = db.prepare("SELECT ABALANCE FROM ACCOUNTS WHERE AID=?");
PreparedStatement updateTeller = db.prepare("UPDATE TELLERS SET TBALANCE=TBALANCE+? WHERE TID=?");
......@@ -136,18 +139,18 @@ public class BenchA implements Bench {
updateAccount.setBigDecimal(1, delta);
updateAccount.setInt(2, account);
db.update(updateAccount, "updateAccount");
db.update(updateAccount, "updateAccount");
updateTeller.setBigDecimal(1, delta);
updateTeller.setInt(2, teller);
db.update(updateTeller, "updateTeller");
db.update(updateTeller, "updateTeller");
updateBranch.setBigDecimal(1, delta);
updateBranch.setInt(2, branch);
db.update(updateBranch, "updateBranch");
db.update(updateBranch, "updateBranch");
selectBalance.setInt(1, account);
db.queryReadResult(selectBalance);
db.queryReadResult(selectBalance);
insertHistory.setInt(1, account);
insertHistory.setInt(2, teller);
......
......@@ -11,20 +11,23 @@ import java.sql.SQLException;
import java.util.Random;
/**
* See also http://www.tpc.org/tpcb
* This test is similar to the TPC-B test of the Transaction Processing Council (TPC).
* Multiple threads are used (one thread per connection).
* Referential integrity is not implemented.
*<p>
* See also http://www.tpc.org/tpcb
*/
public class BenchB implements Bench, Runnable {
// master data
private Database db;
private int scale = 1;
private int branches = 1;
private int tellers = 10;
private int accounts = 100000;
private int scale = 1;
private int branches = 1;
private int tellers = 10;
private int accounts = 100000;
private int clients = 10;
private int transactionPerClient;
// client data
private BenchB master;
private Connection conn;
......@@ -34,14 +37,14 @@ public class BenchB implements Bench, Runnable {
private PreparedStatement updateBranch;
private PreparedStatement insertHistory;
private Random random;
public BenchB() {
}
public void init(Database db, int size) throws Exception {
this.db = db;
this.transactionPerClient = size;
db.start(this, "Init");
db.openConnection();
db.dropTable("BRANCHES");
......@@ -88,7 +91,7 @@ public class BenchB implements Bench, Runnable {
db.update(prep, "insertAccounts");
if (i % commitEvery == 0) {
db.commit();
}
}
}
db.commit();
db.closeConnection();
......@@ -96,9 +99,9 @@ public class BenchB implements Bench, Runnable {
// db.start(this, "Open/Close");
// db.openConnection();
// db.closeConnection();
// db.end();
// db.end();
}
private BenchB(BenchB master, int seed) throws Exception {
this.master = master;
random = new Random(seed);
......@@ -115,7 +118,7 @@ public class BenchB implements Bench, Runnable {
insertHistory = conn.prepareStatement(
"INSERT INTO HISTORY(TID, BID, AID, DELTA) VALUES(?, ?, ?, ?)");
}
public void run() {
int accountsPerBranch = accounts / branches;
for (int i = 0; i < master.transactionPerClient; i++) {
......@@ -136,21 +139,21 @@ public class BenchB implements Bench, Runnable {
// ignore
}
}
private void doOne(int branch, int teller, int account, int delta) {
try {
// UPDATE ACCOUNTS SET ABALANCE=ABALANCE+? WHERE AID=?
updateAccount.setInt(1, delta);
updateAccount.setInt(2, account);
updateAccount.executeUpdate();
// SELECT ABALANCE FROM ACCOUNTS WHERE AID=?
selectAccount.setInt(1, account);
ResultSet rs = selectAccount.executeQuery();
while (rs.next()) {
rs.getInt(1);
}
// UPDATE TELLERS SET TBALANCE=TABLANCE+? WHERE TID=?
updateTeller.setInt(1, delta);
updateTeller.setInt(2, teller);
......@@ -160,7 +163,7 @@ public class BenchB implements Bench, Runnable {
updateBranch.setInt(1, delta);
updateBranch.setInt(2, branch);
updateBranch.executeUpdate();
// INSERT INTO HISTORY(TID, BID, AID, DELTA) VALUES(?, ?, ?, ?)
insertHistory.setInt(1, teller);
insertHistory.setInt(2, branch);
......@@ -172,7 +175,7 @@ public class BenchB implements Bench, Runnable {
e.printStackTrace();
}
}
public void runTest() throws Exception {
db.start(this, "Transactions");
......@@ -185,7 +188,7 @@ public class BenchB implements Bench, Runnable {
db.logMemory(this, "Memory Usage");
db.closeConnection();
}
private void processTransactions() throws Exception {
Thread[] threads = new Thread[clients];
for (int i = 0; i < clients; i++) {
......@@ -198,7 +201,7 @@ public class BenchB implements Bench, Runnable {
threads[i].join();
}
}
public String getName() {
return "BenchB";
}
......
......@@ -9,6 +9,13 @@ import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.sql.Types;
/**
* This test is similar to the TPC-C test of the Transaction Processing Council (TPC).
* Only one connection and one thread is used.
* Referential integrity is not implemented.
*<p>
* See also http://www.tpc.org
*/
public class BenchC implements Bench {
private Database db;
......
......@@ -8,10 +8,13 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Random;
/**
* The random data generator used for BenchC.
*/
public class BenchCRandom {
private Random random = new Random(10);
int getNonUniform(int a, int min, int max) {
int c = 0;
return (((getInt(0, a) | getInt(min, max)) + c) % (max - min + 1))
......
......@@ -10,6 +10,9 @@ import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.HashMap;
/**
* This class implements the functionality of one thread of BenchC.
*/
public class BenchCThread {
private Database db;
......
......@@ -7,15 +7,20 @@ package org.h2.test.bench;
import java.sql.PreparedStatement;
import java.util.Random;
/**
* This is a very simple benchmark application. One table is created
* where rows are inserted, updated, selected (in sequential and random order),
* and then deleted.
*/
public class BenchSimple implements Bench {
Database db;
int records;
public void init(Database db, int size) throws Exception {
this.db = db;
this.records = size * 60;
db.start(this, "Init");
db.openConnection();
db.dropTable("TEST");
......@@ -35,20 +40,20 @@ public class BenchSimple implements Bench {
db.commit();
db.closeConnection();
db.end();
// db.start(this, "Open/Close");
// db.openConnection();
// db.closeConnection();
// db.end();
// db.end();
}
public void runTest() throws Exception {
PreparedStatement prep;
Random random = db.getRandom();
db.openConnection();
db.start(this, "Query (random)");
prep = db.prepare("SELECT * FROM TEST WHERE ID=?");
for (int i = 0; i < records; i++) {
......@@ -56,7 +61,7 @@ public class BenchSimple implements Bench {
db.queryReadResult(prep);
}
db.end();
db.start(this, "Query (sequential)");
prep = db.prepare("SELECT * FROM TEST WHERE ID=?");
for (int i = 0; i < records; i++) {
......@@ -90,10 +95,10 @@ public class BenchSimple implements Bench {
for (int i = 0; i < records; i++) {
prep.setInt(1, random.nextInt(records));
db.queryReadResult(prep);
}
}
db.logMemory(this, "Memory Usage");
db.closeConnection();
}
public String getName() {
......
......@@ -23,8 +23,11 @@ import org.h2.tools.Server;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils;
/**
* Represents a database in the benchmark test application.
*/
class Database {
private TestPerformance test;
private int id;
private String name, url, user, password;
......@@ -39,27 +42,27 @@ class Database {
private ArrayList results = new ArrayList();
private int totalTime;
private int executedStatements;
private Server serverH2;
private Object serverDerby;
private boolean serverHSQLDB;
String getName() {
return name;
}
int getTotalTime() {
return totalTime;
}
ArrayList getResults() {
return results;
}
Random getRandom() {
return random;
}
void startServer() throws Exception {
if (url.startsWith("jdbc:h2:tcp:")) {
serverH2 = Server.createTcpServer(new String[0]).start();
......@@ -156,12 +159,12 @@ class Database {
}
return conn;
}
void openConnection() throws Exception {
conn = DriverManager.getConnection(url, user, password);
stat = conn.createStatement();
}
void closeConnection() throws Exception {
// if(!serverHSQLDB && url.startsWith("jdbc:hsqldb:")) {
// stat.execute("SHUTDOWN");
......@@ -185,12 +188,12 @@ class Database {
}
}
}
PreparedStatement prepare(String sql) throws Exception {
sql = getSQL(sql);
return conn.prepareStatement(sql);
}
public String getSQL(String sql) {
for (int i = 0; i < replace.size(); i++) {
String[] pair = (String[]) replace.get(i);
......@@ -293,7 +296,7 @@ class Database {
}
}
}
int getExecutedStatements() {
return executedStatements;
}
......
......@@ -18,20 +18,24 @@ import org.h2.test.TestBase;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
/**
* The main controller class of the benchmark application.
* To run the benchmark, call the main method of this class.
*/
public class TestPerformance {
boolean collect;
boolean log;
public static void main(String[] args) throws Exception {
new TestPerformance().test(args);
}
private Connection getResultConnection() throws Exception {
Class.forName("org.h2.Driver");
return DriverManager.getConnection("jdbc:h2:data/results");
}
private void openResults(boolean init) throws Exception {
Connection conn = null;
Statement stat = null;
......@@ -65,7 +69,7 @@ public class TestPerformance {
}
}
openResults(init);
Properties prop = new Properties();
prop.load(getClass().getResourceAsStream("test.properties"));
int size = Integer.parseInt(prop.getProperty("size"));
......@@ -121,7 +125,7 @@ public class TestPerformance {
prep.execute();
}
}
writer = new PrintWriter(new FileWriter(out));
ResultSet rs = stat.executeQuery(
"CALL '<table><tr><th>Test Case</th><th>Unit</th>' "
......@@ -143,7 +147,7 @@ public class TestPerformance {
JdbcUtils.closeSilently(conn);
IOUtils.closeSilently(writer);
}
// ResultSet rsDbs = conn.createStatement().executeQuery("SELECT DB RESULTS GROUP BY DBID, DB ORDER BY DBID");
// while(rsDbs.next()) {
// writer.println("<th>" + rsDbs.getString(1) + "</th>");
......@@ -153,10 +157,10 @@ public class TestPerformance {
// writer.println("<tr><td>" + rs.getString(1) + "</td>");
// writer.println("<td>" + rs.getString(2) + "</td>");
// ResultSet rsRes = conn.createStatement().executeQuery("SELECT RESULT FROM RESULTS WHERE TESTID=? ORDER BY DBID");
//
//
//
//
// }
// PrintWriter writer = new PrintWriter(new FileWriter("benchmark.html"));
// writer.println("<table><tr><th>Test Case</th><th>Unit</th>");
// for(int j=0; j<dbs.size(); j++) {
......@@ -181,7 +185,7 @@ public class TestPerformance {
System.out.println("Test finished");
System.exit(0);
}
private void testAll(ArrayList dbs, ArrayList tests, int size) throws Exception {
for (int i = 0; i < dbs.size(); i++) {
if (i > 0) {
......@@ -212,7 +216,7 @@ public class TestPerformance {
runTest(db, bench, size);
}
}
private void runTest(Database db, Bench bench, int size) throws Exception {
bench.init(db, size);
bench.runTest();
......
......@@ -9,6 +9,7 @@ import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.h2.test.TestBase;
import org.h2.util.ScriptReader;
......@@ -33,19 +34,24 @@ public class TestScriptSimple extends TestBase {
break;
}
sql = sql.trim();
if ("@reconnect".equals(sql.toLowerCase())) {
reconnect();
} else if (sql.length() == 0) {
// ignore
} else if (sql.toLowerCase().startsWith("select")) {
ResultSet rs = conn.createStatement().executeQuery(sql);
while (rs.next()) {
String expected = reader.readStatement().trim();
String got = "> " + rs.getString(1);
check(expected, got);
try {
if ("@reconnect".equals(sql.toLowerCase())) {
reconnect();
} else if (sql.length() == 0) {
// ignore
} else if (sql.toLowerCase().startsWith("select")) {
ResultSet rs = conn.createStatement().executeQuery(sql);
while (rs.next()) {
String expected = reader.readStatement().trim();
String got = "> " + rs.getString(1);
check(expected, got);
}
} else {
conn.createStatement().execute(sql);
}
} else {
conn.createStatement().execute(sql);
} catch (SQLException e) {
System.out.println(sql);
throw e;
}
}
is.close();
......
......@@ -12,5 +12,14 @@ insert into test values(null);
-- 2 rows even in ANSI mode (correct is 1 row):
select * from test where id=id and 1=1;
MS SQL Server 2005
--------------------------------------------------------------------------------------------------------
Problems when trying to select large objects (even if ResultSet.getBinaryStream is used).
The workaround responseBuffering=adaptive doesn't always seem to work
(jdbc:sqlserver://localhost:4220;DatabaseName=test;responseBuffering=adaptive)
PostgreSQL
--------------------------------------------------------------------------------------------------------
......@@ -9,6 +9,10 @@ import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* The listener application for the power off test.
* The listener runs on a computer that stays on during the whole test.
*/
public class Listener implements Runnable {
public static void main(String[] args) throws Exception {
......
......@@ -18,6 +18,12 @@ import java.sql.Statement;
import org.h2.util.FileUtils;
/**
* This application tests the durability / non-durability of file systems and databases.
* Two computers with network connection are required to run this test. Before
* starting this application, the Listener application must be started on another
* computer.
*/
public class Test {
String driver;
......
......@@ -29,6 +29,9 @@ import java.util.zip.ZipOutputStream;
import org.h2.util.IOUtils;
/**
* This standalone test checks if recovery of a database works after power failure.
*/
public class TestRecover {
private Random random;
......
......@@ -13,6 +13,10 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
/**
* This test shows the raw file access performance using various file modes.
* It also tests databases.
*/
public class TestWrite {
public static void main(String[] args) throws Exception {
testFile("rw", false);
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select * from system_range(1, 2) a,
(select * from system_range(1, 2) union select * from system_range(1, 2)
union select * from system_range(1, 1)) v where a.x = v.x;
> X X
> - -
> 1 1
> 2 2
> rows: 2
create table test(id int);
> ok
select * from ((select * from test) union (select * from test)) where id = 0;
> ID
> --
> rows: 0
select * from ((test d1 inner join test d2 on d1.id = d2.id) inner join test d3 on d1.id = d3.id) inner join test d4 on d4.id = d1.id;
> ID ID ID ID
> -- -- -- --
> rows: 0
select * from dual a left join dual b on b.x=(select max(x) from dual);
> exception
drop table test;
> ok
select count(*) from system_range(1, 2) where x in(1, 1, 1);
> COUNT(*)
> --------
......
create table test(id int);
select count(*) from (select * from ((select * from test) union (select * from test)) a) b where id = 0;
> 0;
select count(*) from (select * from ((select * from test) union select * from test) a) b where id = 0;
> 0;
select count(*) from (select * from (select * from test union select * from test) a) b where id = 0;
> 0;
select 1 from ((test d1 inner join test d2 on d1.id = d2.id) inner join test d3 on d1.id = d3.id) inner join test d4 on d4.id = d1.id;
drop table test;
select lpad('string', 10, '+');
> ++++string;
select rpad('string', 10, '+');
......
......@@ -24,7 +24,7 @@ Please provide any additional information below.
Corrupted database
I am sorry to say that, but it looks like a corruption problem. I am very interested in analyzing and solving this problem. It has top priority for me. I have a few question:
I am sorry to say that, but it looks like a corruption problem. I am very interested in analyzing and solving this problem. Corruption problem have top priority for me. I have a few question:
- What is your database URL?
- What version H2 are you using?
......@@ -32,8 +32,8 @@ I am sorry to say that, but it looks like a corruption problem. I am very intere
- On what operating system, file system, and virtual machine?
- How big is the database?
- Is the database usually closed normally, or is process terminated forcefully or the computer switched off?
- Is it possible to reproduce this problem using a fresh database?
- Are there any other exceptions (maybe in the .trace.db file)? Could you post them please?
- Is it possible to reproduce this problem using a fresh database (sometimes, or always)?
- Are there any other exceptions (maybe in the .trace.db file)? Could you send them to me please?
- Was the database originally created with an older version of H2?
- Do you still have any .trace.db files, and if yes could you send them?
- Could you send me the .data.db file where this exception occurs?
......@@ -10,6 +10,11 @@ import java.io.RandomAccessFile;
import org.h2.util.ByteUtils;
/**
* This tool checks that source code files only contain the allowed set of characters,
* and that the copyright license is included in each file.
* It also removes trailing spaces.
*/
public class CheckTextFiles {
public static void main(String[] args) throws Exception {
new CheckTextFiles().run();
......
......@@ -10,9 +10,11 @@ import java.io.RandomAccessFile;
import java.util.ArrayList;
/**
* @author Thomas TODO codeswitch: replace with ant 'Replace' task is possible
* This application allows to switch source code to different 'modes', so that
* it can be compiled for different JDKs.
*/
public class CodeSwitch {
// TODO codeswitch: replace with ant 'Replace' task is possible
private boolean recurse;
private ArrayList list = new ArrayList();
private ArrayList switchOn = new ArrayList();
......
......@@ -21,6 +21,11 @@ import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils;
/**
* This application generates sections of the documentation
* by converting the built-in help section (INFORMATION_SCHEMA.HELP)
* to cross linked html.
*/
public class GenerateDoc {
public static void main(String[] args) throws Exception {
......
......@@ -15,6 +15,10 @@ import org.h2.util.IOUtils;
import org.h2.util.StartBrowser;
import org.h2.util.StringUtils;
/**
* The link checker makes sure that each link in the documentation
* points to an existing target.
*/
public class LinkChecker {
private static final boolean OPEN_EXTERNAL_LINKS = false;
......
......@@ -11,6 +11,10 @@ import java.io.PrintWriter;
import org.h2.util.StringUtils;
/**
* This application merges the html documentation to one file
* (onePage.html), so that the PDF document can be created.
*/
public class MergeDocs {
String baseDir = "docs/html";
......
......@@ -17,6 +17,11 @@ import java.util.StringTokenizer;
import org.h2.util.IOUtils;
/**
* The spell checker makes sure that each word used in the source code
* is spelled correctly, by comparing the words with a word list.
* Camel case and uppercase words are checked as well.
*/
public class SpellChecker {
private HashSet dictionary = new HashSet();
......
......@@ -11,6 +11,10 @@ import java.io.Reader;
import java.io.StringWriter;
import java.util.Stack;
/**
* This class checks that the HTML and XML part of the source code
* is well-formed XML.
*/
public class XMLChecker {
public static void main(String[] args) throws Exception {
......
......@@ -4,6 +4,10 @@
*/
package org.h2.tools.doc;
/**
* This class implements a simple XML pull parser.
* Only a subset of the XML pull parser API is implemented.
*/
public class XMLParser {
public static final int ERROR = 0;
......
......@@ -22,6 +22,10 @@ import com.sun.javadoc.Tag;
import com.sun.javadoc.ThrowsTag;
import com.sun.javadoc.Type;
/**
* This class is a custom doclet implementation to generate the
* Javadoc for this product.
*/
public class Doclet {
public static boolean start(RootDoc root) throws IOException {
ClassDoc[] classes = root.classes();
......
......@@ -33,6 +33,11 @@ import org.h2.util.IOUtils;
import org.h2.util.SortedProperties;
import org.h2.util.StringUtils;
/**
* This class updates the translation source code files by parsing
* the HTML documentation. It also generates the translated HTML
* documentation.
*/
public class PrepareTranslation {
private static final String MAIN_LANGUAGE = "en";
private static final String DELETED_PREFIX = "~";
......
......@@ -27,6 +27,10 @@ import org.h2.util.IOUtils;
import org.h2.util.SortedProperties;
import org.h2.util.StringUtils;
/**
* This class converts a file stored in the UTF-8 encoding format to
* a properties file and vice versa.
*/
public class PropertiesToUTF8 {
public static void main(String[] args) throws Exception {
......
......@@ -6,6 +6,10 @@ package org.h2.tools.indexer;
import java.util.HashMap;
/**
* This class replaces HTML entities in text (for example &uuml;) to the correct
* character and vice versa.
*/
public class HtmlConverter {
private static HashMap charMap = new HashMap();
private static HashMap codeMap = new HashMap();
......
......@@ -18,6 +18,10 @@ import java.util.StringTokenizer;
import org.h2.util.IOUtils;
import org.h2.util.StringUtils;
/**
* The indexer creates the fulltext index of the HTML documentation.
* It is used for the built-in HTML javascript search.
*/
public class Indexer {
ArrayList pages = new ArrayList();
......
......@@ -4,7 +4,9 @@
*/
package org.h2.tools.indexer;
/**
* Represents a page of the indexer.
*/
public class Page {
int id;
String fileName;
......@@ -12,7 +14,7 @@ public class Page {
// TODO page.totalWeight is currently not used
int totalWeight;
int relations;
Page(int id, String fileName) {
this.id = id;
this.fileName = fileName;
......
......@@ -4,6 +4,9 @@
*/
package org.h2.tools.indexer;
/**
* Represents a weight of a token in a page.
*/
public class Weight {
static final int TITLE = 10000, HEADER = 100, PARAGRAPH = 1;
Page page;
......
......@@ -9,6 +9,9 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/**
* Represents a word of the full text index.
*/
public class Word {
String name;
HashMap pages = new HashMap();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论