提交 9a25c1c1 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 4f59a3c8
...@@ -28,6 +28,7 @@ import org.h2.value.ValueArray; ...@@ -28,6 +28,7 @@ import org.h2.value.ValueArray;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueDouble; import org.h2.value.ValueDouble;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueString; import org.h2.value.ValueString;
...@@ -151,7 +152,7 @@ public class Aggregate extends Expression { ...@@ -151,7 +152,7 @@ public class Aggregate extends Expression {
switch(type) { switch(type) {
case COUNT_ALL: case COUNT_ALL:
Table table = select.getTopTableFilter().getTable(); Table table = select.getTopTableFilter().getTable();
return ValueInt.get(table.getRowCount()); return ValueLong.get(table.getRowCount());
case MIN: case MIN:
case MAX: case MAX:
boolean first = type == MIN; boolean first = type == MIN;
...@@ -261,6 +262,10 @@ public class Aggregate extends Expression { ...@@ -261,6 +262,10 @@ public class Aggregate extends Expression {
break; break;
case COUNT_ALL: case COUNT_ALL:
case COUNT: case COUNT:
dataType = Value.LONG;
scale = 0;
precision = 0;
break;
case SELECTIVITY: case SELECTIVITY:
dataType = Value.INT; dataType = Value.INT;
scale = 0; scale = 0;
......
...@@ -15,11 +15,12 @@ import org.h2.value.Value; ...@@ -15,11 +15,12 @@ import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueDouble; import org.h2.value.ValueDouble;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
public class AggregateData { public class AggregateData {
private int aggregateType; private int aggregateType;
private int count; private long count;
private ValueHashMap distinctValues; private ValueHashMap distinctValues;
private Value value; private Value value;
private double sum, vpn; private double sum, vpn;
...@@ -149,7 +150,7 @@ public class AggregateData { ...@@ -149,7 +150,7 @@ public class AggregateData {
} }
case Aggregate.COUNT: case Aggregate.COUNT:
case Aggregate.COUNT_ALL: case Aggregate.COUNT_ALL:
v = ValueInt.get(count); v = ValueLong.get(count);
break; break;
case Aggregate.SUM: case Aggregate.SUM:
case Aggregate.MIN: case Aggregate.MIN:
...@@ -199,12 +200,12 @@ public class AggregateData { ...@@ -199,12 +200,12 @@ public class AggregateData {
return v == null ? ValueNull.INSTANCE : v; return v == null ? ValueNull.INSTANCE : v;
} }
private Value divide(Value a, int count) throws SQLException { private Value divide(Value a, long count) throws SQLException {
if(count == 0) { if(count == 0) {
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
} }
int type = Value.getHigherOrder(a.getType(), Value.INT); int type = Value.getHigherOrder(a.getType(), Value.LONG);
Value b = ValueInt.get(count).convertTo(type); Value b = ValueLong.get(count).convertTo(type);
a = a.convertTo(type).divide(b); a = a.convertTo(type).divide(b);
return a; return a;
} }
......
...@@ -136,7 +136,7 @@ public class CompareLike extends Condition { ...@@ -136,7 +136,7 @@ public class CompareLike extends Condition {
return; return;
} }
int dataType = l.getColumn().getType(); int dataType = l.getColumn().getType();
if(dataType != Value.STRING && dataType != Value.STRING_IGNORECASE) { if(dataType != Value.STRING && dataType != Value.STRING_IGNORECASE && dataType != Value.STRING_FIXED) {
// column is not a varchar - can't use the index // column is not a varchar - can't use the index
return; return;
} }
......
...@@ -45,7 +45,7 @@ public class ConditionExists extends Condition { ...@@ -45,7 +45,7 @@ public class ConditionExists extends Condition {
public String getSQL() { public String getSQL() {
StringBuffer buff = new StringBuffer(); StringBuffer buff = new StringBuffer();
buff.append("EXISTS("); buff.append("EXISTS(");
buff.append(query.getPlan()); buff.append(query.getPlanSQL());
buff.append(")"); buff.append(")");
return buff.toString(); return buff.toString();
} }
......
...@@ -83,10 +83,10 @@ public class ConditionInSelect extends Condition { ...@@ -83,10 +83,10 @@ public class ConditionInSelect extends Condition {
if(left == ValueExpression.NULL) { if(left == ValueExpression.NULL) {
return left; return left;
} }
query.prepare();
if(query.getColumnCount() != 1) { if(query.getColumnCount() != 1) {
throw Message.getSQLException(Message.SUBQUERY_IS_NOT_SINGLE_COLUMN); throw Message.getSQLException(Message.SUBQUERY_IS_NOT_SINGLE_COLUMN);
} }
query.prepare();
// Can not optimize IN(SELECT...): the data may change // Can not optimize IN(SELECT...): the data may change
// However, could transform to an inner join // However, could transform to an inner join
return this; return this;
...@@ -101,7 +101,7 @@ public class ConditionInSelect extends Condition { ...@@ -101,7 +101,7 @@ public class ConditionInSelect extends Condition {
StringBuffer buff = new StringBuffer("("); StringBuffer buff = new StringBuffer("(");
buff.append(left.getSQL()); buff.append(left.getSQL());
buff.append(" IN("); buff.append(" IN(");
buff.append(query.getPlan()); buff.append(query.getPlanSQL());
buff.append("))"); buff.append("))");
return buff.toString(); return buff.toString();
} }
......
...@@ -833,7 +833,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -833,7 +833,7 @@ public class Function extends Expression implements FunctionCall {
} }
} }
Sequence getSequence(Session session, Value v0, Value v1) throws SQLException { private Sequence getSequence(Session session, Value v0, Value v1) throws SQLException {
String schemaName, sequenceName; String schemaName, sequenceName;
if(v1 == null) { if(v1 == null) {
schemaName = session.getCurrentSchemaName(); schemaName = session.getCurrentSchemaName();
......
...@@ -60,7 +60,7 @@ public class Parameter extends Expression implements ParameterInterface { ...@@ -60,7 +60,7 @@ public class Parameter extends Expression implements ParameterInterface {
public void checkSet() throws SQLException { public void checkSet() throws SQLException {
if (value == null) { if (value == null) {
throw Message.getSQLException(Message.PARAMETER_NOT_SET_1, String.valueOf(index + 1)); throw Message.getSQLException(Message.PARAMETER_NOT_SET_1, "#" + (index + 1));
} }
} }
......
...@@ -28,7 +28,7 @@ public class ParameterRemote implements ParameterInterface { ...@@ -28,7 +28,7 @@ public class ParameterRemote implements ParameterInterface {
public void checkSet() throws SQLException { public void checkSet() throws SQLException {
if (value == null) { if (value == null) {
throw Message.getSQLException(Message.PARAMETER_NOT_SET_1, String.valueOf(index + 1)); throw Message.getSQLException(Message.PARAMETER_NOT_SET_1, "#" + (index + 1));
} }
} }
......
...@@ -80,7 +80,7 @@ public class Subquery extends Expression { ...@@ -80,7 +80,7 @@ public class Subquery extends Expression {
} }
public String getSQL() { public String getSQL() {
return "(" + query.getPlan() +")"; return "(" + query.getPlanSQL() +")";
} }
public void updateAggregate(Session session) throws SQLException { public void updateAggregate(Session session) throws SQLException {
......
...@@ -18,6 +18,7 @@ import org.h2.store.RecordReader; ...@@ -18,6 +18,7 @@ import org.h2.store.RecordReader;
import org.h2.store.Storage; import org.h2.store.Storage;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.TableData; import org.h2.table.TableData;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -198,7 +199,7 @@ public class BtreeIndex extends Index implements RecordReader { ...@@ -198,7 +199,7 @@ public class BtreeIndex extends Index implements RecordReader {
} }
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
return 10 * getCostRangeIndex(masks, tableData.getRowCount()); return 10 * getCostRangeIndex(masks, tableData.getRowCount());
} }
......
...@@ -46,11 +46,11 @@ public class FunctionIndex extends Index { ...@@ -46,11 +46,11 @@ public class FunctionIndex extends Index {
return new FunctionCursor(result); return new FunctionCursor(result);
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
if(masks != null) { if(masks != null) {
throw Message.getUnsupportedException(); throw Message.getUnsupportedException();
} }
return Integer.MAX_VALUE; return Long.MAX_VALUE;
} }
public void remove(Session session) throws SQLException { public void remove(Session session) throws SQLException {
......
...@@ -120,13 +120,13 @@ public class HashIndex extends Index { ...@@ -120,13 +120,13 @@ public class HashIndex extends Index {
return new HashCursor(result); return new HashCursor(result);
} }
public int getCost(int[] masks) { public long getCost(int[] masks) {
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
Column column = columns[i]; Column column = columns[i];
int index = column.getColumnId(); int index = column.getColumnId();
int mask = masks[index]; int mask = masks[index];
if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) { if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) {
return Integer.MAX_VALUE; return Long.MAX_VALUE;
} }
} }
return 2; return 2;
......
...@@ -30,7 +30,7 @@ public abstract class Index extends SchemaObject { ...@@ -30,7 +30,7 @@ public abstract class Index extends SchemaObject {
protected Table table; protected Table table;
public IndexType indexType; public IndexType indexType;
public static final int EMPTY_HEAD = -1; public static final int EMPTY_HEAD = -1;
protected int rowCount; protected long rowCount;
public Index(Table table, int id, String name, Column[] columns, IndexType indexType) { public Index(Table table, int id, String name, Column[] columns, IndexType indexType) {
super(table.getSchema(), id, name, Trace.INDEX); super(table.getSchema(), id, name, Trace.INDEX);
...@@ -74,24 +74,24 @@ public abstract class Index extends SchemaObject { ...@@ -74,24 +74,24 @@ public abstract class Index extends SchemaObject {
public abstract void add(Session session, Row row) throws SQLException; public abstract void add(Session session, Row row) throws SQLException;
public abstract void remove(Session session, Row row) throws SQLException; public abstract void remove(Session session, Row row) throws SQLException;
public abstract Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException; public abstract Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException;
public abstract int getCost(int[] masks) throws SQLException; public abstract long getCost(int[] masks) throws SQLException;
public abstract void remove(Session session) throws SQLException; public abstract void remove(Session session) throws SQLException;
public abstract void truncate(Session session) throws SQLException; public abstract void truncate(Session session) throws SQLException;
public abstract boolean canGetFirstOrLast(boolean first); public abstract boolean canGetFirstOrLast(boolean first);
public abstract Value findFirstOrLast(Session session, boolean first) throws SQLException; public abstract Value findFirstOrLast(Session session, boolean first) throws SQLException;
public abstract boolean needRebuild(); public abstract boolean needRebuild();
public int getRowCount() { public long getRowCount() {
return rowCount; return rowCount;
} }
public int getLookupCost(int rowCount) { public int getLookupCost(long rowCount) {
return 2; return 2;
} }
public int getCostRangeIndex(int[] masks, int rowCount) throws SQLException { public long getCostRangeIndex(int[] masks, long rowCount) throws SQLException {
rowCount += Constants.COST_ROW_OFFSET; rowCount += Constants.COST_ROW_OFFSET;
int cost = rowCount; long cost = rowCount;
int totalSelectivity = 0; int totalSelectivity = 0;
for (int i = 0; masks != null && i < columns.length; i++) { for (int i = 0; masks != null && i < columns.length; i++) {
Column column = columns[i]; Column column = columns[i];
...@@ -103,11 +103,11 @@ public abstract class Index extends SchemaObject { ...@@ -103,11 +103,11 @@ public abstract class Index extends SchemaObject {
break; break;
} }
totalSelectivity = 100 - ((100-totalSelectivity) * (100-column.getSelectivity()) / 100); totalSelectivity = 100 - ((100-totalSelectivity) * (100-column.getSelectivity()) / 100);
int distinctRows = rowCount * totalSelectivity / 100; long distinctRows = rowCount * totalSelectivity / 100;
if(distinctRows <= 0) { if(distinctRows <= 0) {
distinctRows = 1; distinctRows = 1;
} }
int rowsSelected = rowCount / distinctRows; long rowsSelected = rowCount / distinctRows;
if(rowsSelected < 1) { if(rowsSelected < 1) {
rowsSelected = 1; rowsSelected = 1;
} }
......
...@@ -50,7 +50,7 @@ public class LinearHashIndex extends Index implements RecordReader { ...@@ -50,7 +50,7 @@ public class LinearHashIndex extends Index implements RecordReader {
this.tableData = table; this.tableData = table;
// TODO linear hash: currently, changes are not logged // TODO linear hash: currently, changes are not logged
String name = database.getName()+"."+id+Constants.SUFFIX_HASH_FILE; String name = database.getName()+"."+id+Constants.SUFFIX_HASH_FILE;
diskFile = new DiskFile(database, name, false, false, Constants.DEFAULT_CACHE_SIZE_LINEAR_INDEX); diskFile = new DiskFile(database, name, "rw", false, false, Constants.DEFAULT_CACHE_SIZE_LINEAR_INDEX);
diskFile.init(); diskFile.init();
bucketSize = 4 * DiskFile.BLOCK_SIZE - diskFile.getRecordOverhead(); bucketSize = 4 * DiskFile.BLOCK_SIZE - diskFile.getRecordOverhead();
blocksPerBucket = 4; blocksPerBucket = 4;
...@@ -487,13 +487,13 @@ public class LinearHashIndex extends Index implements RecordReader { ...@@ -487,13 +487,13 @@ public class LinearHashIndex extends Index implements RecordReader {
return new LinearHashCursor(tableData.getRow(key)); return new LinearHashCursor(tableData.getRow(key));
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
Column column = columns[i]; Column column = columns[i];
int index = column.getColumnId(); int index = column.getColumnId();
int mask = masks[index]; int mask = masks[index];
if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) { if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) {
return Integer.MAX_VALUE; return Long.MAX_VALUE;
} }
} }
return 100; return 100;
......
...@@ -138,7 +138,7 @@ public class LinkedIndex extends Index { ...@@ -138,7 +138,7 @@ public class LinkedIndex extends Index {
} }
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
return 100 + getCostRangeIndex(masks, rowCount + Constants.COST_ROW_OFFSET); return 100 + getCostRangeIndex(masks, rowCount + Constants.COST_ROW_OFFSET);
} }
......
...@@ -48,7 +48,7 @@ public class MetaIndex extends Index { ...@@ -48,7 +48,7 @@ public class MetaIndex extends Index {
return new MetaCursor(rows); return new MetaCursor(rows);
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
if(scan) { if(scan) {
return 10000; return 10000;
} }
......
...@@ -42,7 +42,7 @@ public class RangeIndex extends Index { ...@@ -42,7 +42,7 @@ public class RangeIndex extends Index {
return new RangeCursor(start, end); return new RangeCursor(start, end);
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
return 1; return 1;
} }
......
...@@ -142,8 +142,8 @@ public class ScanIndex extends Index { ...@@ -142,8 +142,8 @@ public class ScanIndex extends Index {
return new ScanCursor(this); return new ScanCursor(this);
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
int cost = tableData.getRowCount() + Constants.COST_ROW_OFFSET; long cost = tableData.getRowCount() + Constants.COST_ROW_OFFSET;
if(storage != null) { if(storage != null) {
cost *= 10; cost *= 10;
} }
......
...@@ -293,7 +293,7 @@ public class TreeIndex extends Index { ...@@ -293,7 +293,7 @@ public class TreeIndex extends Index {
} }
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
return getCostRangeIndex(masks, tableData.getRowCount()); return getCostRangeIndex(masks, tableData.getRowCount());
} }
......
...@@ -30,7 +30,7 @@ public class ViewIndex extends Index { ...@@ -30,7 +30,7 @@ public class ViewIndex extends Index {
private ObjectArray originalParameters; private ObjectArray originalParameters;
private Parameter[] params; private Parameter[] params;
private SmallLRUCache costCache = new SmallLRUCache(Constants.VIEW_COST_CACHE_SIZE); private SmallLRUCache costCache = new SmallLRUCache(Constants.VIEW_INDEX_CACHE_SIZE);
private Value[] lastParameters; private Value[] lastParameters;
private long lastEvaluated; private long lastEvaluated;
...@@ -39,6 +39,8 @@ public class ViewIndex extends Index { ...@@ -39,6 +39,8 @@ public class ViewIndex extends Index {
private int recurseLevel; private int recurseLevel;
private LocalResult recursiveResult; private LocalResult recursiveResult;
private String planSQL;
public ViewIndex(TableView view, String querySQL, ObjectArray originalParameters, boolean recursive) { public ViewIndex(TableView view, String querySQL, ObjectArray originalParameters, boolean recursive) {
super(view, 0, null, null, IndexType.createNonUnique(false)); super(view, 0, null, null, IndexType.createNonUnique(false));
this.querySQL = querySQL; this.querySQL = querySQL;
...@@ -48,8 +50,24 @@ public class ViewIndex extends Index { ...@@ -48,8 +50,24 @@ public class ViewIndex extends Index {
params = new Parameter[0]; params = new Parameter[0];
} }
public ViewIndex(TableView view, ViewIndex index, Session session, int[] masks) throws SQLException {
super(view, 0, null, null, IndexType.createNonUnique(false));
this.querySQL = index.querySQL;
this.originalParameters = index.originalParameters;
this.recursive = index.recursive;
columns = new Column[0];
params = new Parameter[0];
planSQL = getQuerySQL(session, masks);
}
public String getPlanSQL() { public String getPlanSQL() {
return querySQL; int testing;
// return sessionQuery.getPlanSQL();
// Query query = (Query)session.prepare(querySQL, true);
// return query.getPlanSQL();
return planSQL;
} }
public void close(Session session) throws SQLException { public void close(Session session) throws SQLException {
...@@ -82,10 +100,38 @@ public class ViewIndex extends Index { ...@@ -82,10 +100,38 @@ public class ViewIndex extends Index {
double cost; double cost;
} }
public double getCost(Session session, int[] masks) throws SQLException { private String getQuerySQL(Session session, int[] masks) throws SQLException {
if(recursive) { if(masks == null) {
return 10; return querySQL;
}
Query query = (Query)session.prepare(querySQL, true);
IntArray paramIndex = new IntArray();
for(int i=0; i<masks.length; i++) {
int mask = masks[i];
if(mask == 0) {
continue;
}
paramIndex.add(i);
} }
int len = paramIndex.size();
columns = new Column[len];
params = new Parameter[len];
for(int i=0; i<len; i++) {
int idx = paramIndex.get(i);
Column col = table.getColumn(idx);
columns[i] = col;
Parameter param = new Parameter(i);
params[i] = param;
int mask = masks[idx];
int comparisonType = getComparisonType(mask);
query.addGlobalCondition(param, idx, comparisonType);
}
String sql = query.getPlanSQL();
query = (Query)session.prepare(sql, true);
return query.getPlanSQL();
}
public double getCost(Session session, int[] masks) throws SQLException {
IntArray masksArray = new IntArray(masks == null ? new int[0] : masks); IntArray masksArray = new IntArray(masks == null ? new int[0] : masks);
CostElement cachedCost = (CostElement) costCache.get(masksArray); CostElement cachedCost = (CostElement) costCache.get(masksArray);
if(cachedCost != null) { if(cachedCost != null) {
...@@ -123,7 +169,11 @@ public class ViewIndex extends Index { ...@@ -123,7 +169,11 @@ public class ViewIndex extends Index {
if(recursive) { if(recursive) {
return 10; return 10;
} }
String sql = query.getSQL();
int testing;
// String sql = query.getSQL();
String sql = query.getPlanSQL();
query = (Query)session.prepare(sql); query = (Query)session.prepare(sql);
} }
double cost = query.getCost(); double cost = query.getCost();
...@@ -198,8 +248,15 @@ public class ViewIndex extends Index { ...@@ -198,8 +248,15 @@ public class ViewIndex extends Index {
} }
} }
} }
query.setSession(session);
LocalResult result = query.query(0); String sql = query.getPlanSQL();
Query q2 = (Query)session.prepare(sql);
LocalResult result = q2.query(0);
int testing2;
// query.setSession(session);
// LocalResult result = query.query(0);
if(canReuse) { if(canReuse) {
lastResult = result; lastResult = result;
lastParameters = params; lastParameters = params;
...@@ -208,11 +265,11 @@ public class ViewIndex extends Index { ...@@ -208,11 +265,11 @@ public class ViewIndex extends Index {
return new ViewCursor(table, result); return new ViewCursor(table, result);
} }
public int getCost(int[] masks) throws SQLException { public long getCost(int[] masks) throws SQLException {
if(masks != null) { if(masks != null) {
throw Message.getUnsupportedException(); throw Message.getUnsupportedException();
} }
return Integer.MAX_VALUE; return Long.MAX_VALUE;
} }
public void remove(Session session) throws SQLException { public void remove(Session session) throws SQLException {
......
...@@ -15,9 +15,7 @@ import java.sql.PreparedStatement; ...@@ -15,9 +15,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
//#ifdef JDK14
import java.sql.Savepoint; import java.sql.Savepoint;
//#endif
import java.sql.Statement; import java.sql.Statement;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
...@@ -239,25 +237,28 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -239,25 +237,28 @@ public class JdbcConnection extends TraceObject implements Connection {
if(executingStatement != null) { if(executingStatement != null) {
executingStatement.cancel(); executingStatement.cancel();
} }
if (session != null && !session.isClosed()) { if (session == null) {
try { return;
rollbackInternal(); }
commit = closeAndSetNull(commit); try {
rollback = closeAndSetNull(rollback); if (!session.isClosed()) {
setAutoCommitTrue = closeAndSetNull(setAutoCommitTrue);
setAutoCommitFalse = closeAndSetNull(setAutoCommitFalse);
getAutoCommit = closeAndSetNull(getAutoCommit);
getReadOnly = closeAndSetNull(getReadOnly);
getGeneratedKeys = closeAndSetNull(getGeneratedKeys);
getLockMode = closeAndSetNull(getLockMode);
setLockMode = closeAndSetNull(setLockMode);
} finally {
try { try {
session.close(); rollbackInternal();
commit = closeAndSetNull(commit);
rollback = closeAndSetNull(rollback);
setAutoCommitTrue = closeAndSetNull(setAutoCommitTrue);
setAutoCommitFalse = closeAndSetNull(setAutoCommitFalse);
getAutoCommit = closeAndSetNull(getAutoCommit);
getReadOnly = closeAndSetNull(getReadOnly);
getGeneratedKeys = closeAndSetNull(getGeneratedKeys);
getLockMode = closeAndSetNull(getLockMode);
setLockMode = closeAndSetNull(setLockMode);
} finally { } finally {
session = null; session.close();
} }
} }
} finally {
session = null;
} }
} catch(Throwable e) { } catch(Throwable e) {
throw logAndConvert(e); throw logAndConvert(e);
......
...@@ -242,7 +242,7 @@ public class Message { ...@@ -242,7 +242,7 @@ public class Message {
public static final int IO_EXCEPTION_1 = 90028; public static final int IO_EXCEPTION_1 = 90028;
public static final int NOT_ON_UPDATABLE_ROW = 90029; public static final int NOT_ON_UPDATABLE_ROW = 90029;
public static final int FILE_CORRUPTED_1 = 90030; public static final int FILE_CORRUPTED_1 = 90030;
public static final int CONNECTION_NOT_CLOSED = 90031;
public static final int USER_NOT_FOUND_1 = 90032; public static final int USER_NOT_FOUND_1 = 90032;
public static final int USER_ALREADY_EXISTS_1 = 90033; public static final int USER_ALREADY_EXISTS_1 = 90033;
public static final int LOG_FILE_ERROR_1 = 90034; public static final int LOG_FILE_ERROR_1 = 90034;
......
...@@ -68,14 +68,14 @@ public class TraceObject { ...@@ -68,14 +68,14 @@ public class TraceObject {
if(!trace.debug()) { if(!trace.debug()) {
return; return;
} }
trace.debugCode(className + " " + toString() + " = "); trace.debugCode(className + " " + PREFIX[type] + id + " = ");
} }
protected void infoCodeAssign(String className, int type, int id) { protected void infoCodeAssign(String className, int type, int id) {
if(!trace.info()) { if(!trace.info()) {
return; return;
} }
trace.infoCode(className + " " + toString() + " = "); trace.infoCode(className + " " + PREFIX[type] + id + " = ");
} }
protected void debugCodeCall(String text) { protected void debugCodeCall(String text) {
......
...@@ -11,10 +11,10 @@ import java.sql.DriverManager; ...@@ -11,10 +11,10 @@ import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.SmallLRUCache;
/** /**
* It is possible to write after close was called, but that means for each write the * It is possible to write after close was called, but that means for each write the
...@@ -38,7 +38,7 @@ public class TraceSystem { ...@@ -38,7 +38,7 @@ public class TraceSystem {
private int maxFileSize = DEFAULT_MAX_FILE_SIZE; private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
private String fileName; private String fileName;
private long lastCheck; private long lastCheck;
private HashMap traces; private SmallLRUCache traces;
private SimpleDateFormat dateFormat; private SimpleDateFormat dateFormat;
private FileWriter fileWriter; private FileWriter fileWriter;
private PrintWriter printWriter; private PrintWriter printWriter;
...@@ -60,7 +60,7 @@ public class TraceSystem { ...@@ -60,7 +60,7 @@ public class TraceSystem {
public TraceSystem(String fileName) { public TraceSystem(String fileName) {
this.fileName = fileName; this.fileName = fileName;
traces = new HashMap(); traces = new SmallLRUCache(100);
dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss "); dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss ");
if(fileName != null) { if(fileName != null) {
try { try {
......
...@@ -1087,14 +1087,18 @@ A natural join is an inner join, where the condition is automatically on the col ...@@ -1087,14 +1087,18 @@ A natural join is an inner join, where the condition is automatically on the col
"," ","
TEST AS T LEFT JOIN TEST AS T1 ON T.ID = T1.ID TEST AS T LEFT JOIN TEST AS T1 ON T.ID = T1.ID
" "
"Other Grammar","Order"," "Other Grammar","Order","
{int | expression} [ASC | DESC] {int | expression} [ASC | DESC]
[NULLS {FIRST | LAST}] [NULLS {FIRST | LAST}]
"," ","
Groups the result by the column or expression. Sorts the result by the given column number, or by an expression.
If the expression is a single parameter, then the value is interpreted
as a column number. Negative column numbers reverse the sort order.
"," ","
NAME DESC NULLS LAST NAME DESC NULLS LAST
" "
"Other Grammar","Expression"," "Other Grammar","Expression","
andCondition [OR andCondition] andCondition [OR andCondition]
"," ","
...@@ -1218,7 +1222,7 @@ ID AS VALUE ...@@ -1218,7 +1222,7 @@ ID AS VALUE
"Other Grammar","Data Type"," "Other Grammar","Data Type","
intType | booleanType | tinyintType | smallintType | bigintType | identityType | intType | booleanType | tinyintType | smallintType | bigintType | identityType |
decimalType | doubleType | realType | dateType | timeType | timestampType | decimalType | doubleType | realType | dateType | timeType | timestampType |
binaryType | otherType | varcharType | varcharIgnorecaseType | binaryType | otherType | varcharType | varcharIgnorecaseType | charType
blobType | clobType | uuidType | arrayType blobType | clobType | uuidType | arrayType
"," ","
A data type definition. A data type definition.
...@@ -1484,8 +1488,8 @@ OTHER ...@@ -1484,8 +1488,8 @@ OTHER
" "
"Data Types","VARCHAR Type"," "Data Types","VARCHAR Type","
{VARCHAR | CHAR | CHARACTER | LONGVARCHAR | {VARCHAR | LONGVARCHAR |
VARCHAR2 | NCHAR | NVARCHAR | NVARCHAR2 | VARCHAR_CASESENSITIVE} VARCHAR2 | NVARCHAR | NVARCHAR2 | VARCHAR_CASESENSITIVE}
[( precisionInt )] [( precisionInt )]
"," ","
Unicode String. Use two single quotes ('') to create a quote. Unicode String. Use two single quotes ('') to create a quote.
...@@ -1505,6 +1509,19 @@ For large text data CLOB should be used. ...@@ -1505,6 +1509,19 @@ For large text data CLOB should be used.
VARCHAR_IGNORECASE VARCHAR_IGNORECASE
" "
"Data Types","CHAR Type","
{CHAR | CHARACTER | NCHAR}
[( precisionInt )]
","
This type is supported for compatibility with other databases and older applications.
The difference to VARCHAR is that trailing spaces are ignored.
Unicode String. Use two single quotes ('') to create a quote.
There is no maximum precision. The maximum size is the memory available.
For large text data CLOB should be used.
","
CHAR(10)
"
"Data Types","BLOB Type"," "Data Types","BLOB Type","
{BLOB | TINYBLOB | MEDIUMBLOB | LONGBLOB | IMAGE | OID} {BLOB | TINYBLOB | MEDIUMBLOB | LONGBLOB | IMAGE | OID}
[( precisionInt )] [( precisionInt )]
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
02000=No data is available 02000=No data is available
07001=Invalid parameter count, expected count: {0} 07001=Invalid parameter count, expected count: {0}
08000=Error opening database 08000=Error opening database
08004=Wrong user/password 08004=Wrong user name or password
21S02=Column count does not match 21S02=Column count does not match
22003=Numeric value out of range 22003=Numeric value out of range
22012=Division by zero: {0} 22012=Division by zero: {0}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
42000=Syntax error in SQL statement {0} 42000=Syntax error in SQL statement {0}
42001=Syntax error in SQL statement {0}; expected {1} 42001=Syntax error in SQL statement {0}; expected {1}
42S01=Table {0} already exists 42S01=Table {0} already exists
42S02=Table {0} not found 42S02=Table {0} not found. Possible reasons: typo; the table is in another database or schema; case mismatch (use double quotes)
42S11=Index {0} already exists 42S11=Index {0} already exists
42S12=Index {0} not found 42S12=Index {0} not found
42S21=Duplicate column name {0} 42S21=Duplicate column name {0}
...@@ -21,18 +21,18 @@ ...@@ -21,18 +21,18 @@
42S32=Setting {0} not found 42S32=Setting {0} not found
90000=Function {0} must return a result set 90000=Function {0} must return a result set
90001=Method is not allowed for a query 90001=Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate
90002=Method is only allowed for a query 90002=Method is only allowed for a query. Use execute or executeUpdate instead of executeQuery
90003=Hexadecimal string with odd number of characters: {0} 90003=Hexadecimal string with odd number of characters: {0}
90004=Hexadecimal string contains non hex character: {0} 90004=Hexadecimal string contains non-hex character: {0}
90005=Value too long for column {0} 90005=Value too long for column {0}
90006=Null not allowed for column {0} 90006=NULL not allowed for column {0}
90007=The object is already closed 90007=The object is already closed
90008=Invalid value {0} for parameter {1} 90008=Invalid value {0} for parameter {1}
90009=Cannot parse date constant {0} 90009=Cannot parse date constant {0}
90010=Cannot parse time constant {0} 90010=Cannot parse time constant {0}
90011=Cannot parse timestamp constant {0} 90011=Cannot parse timestamp constant {0}
90012=Parameter number {0} is not set 90012=Parameter {0} is not set
90013=Database {0} not found 90013=Database {0} not found
90014=Error parsing {0} 90014=Error parsing {0}
90015=SUM or AVG on wrong data type for {0} 90015=SUM or AVG on wrong data type for {0}
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
90017=Attempt to define a second primary key 90017=Attempt to define a second primary key
90018=The connection was not closed by the application and is garbage collected 90018=The connection was not closed by the application and is garbage collected
90019=Cannot drop the current user 90019=Cannot drop the current user
90020=Database may be already open: {0} 90020=Database may be already in use: {0}. Possible solution: use the server mode
90021=Data conversion error converting {0} 90021=Data conversion error converting {0}
90022=Function {0} not found 90022=Function {0} not found
90023=Column {0} must not be nullable 90023=Column {0} must not be nullable
...@@ -50,8 +50,8 @@ ...@@ -50,8 +50,8 @@
90027=Deserialization failed 90027=Deserialization failed
90028=IO Exception: {0} 90028=IO Exception: {0}
90029=Currently not on an updatable row 90029=Currently not on an updatable row
90030=File corrupted while reading record: {0} 90030=File corrupted while reading record: {0}. Possible solution: use the recovery tool
90031=The connection was not closed
90032=User {0} not found 90032=User {0} not found
90033=User {0} already exists 90033=User {0} already exists
90034=Log file error: {0} 90034=Log file error: {0}
......
...@@ -31,7 +31,7 @@ class ResultDiskBuffer { ...@@ -31,7 +31,7 @@ class ResultDiskBuffer {
Database db = session.getDatabase(); Database db = session.getDatabase();
rowBuff = DataPage.create(db, Constants.DEFAULT_DATA_PAGE_SIZE); rowBuff = DataPage.create(db, Constants.DEFAULT_DATA_PAGE_SIZE);
String fileName = session.getDatabase().createTempFile(); String fileName = session.getDatabase().createTempFile();
file = session.getDatabase().openFile(fileName, false); file = session.getDatabase().openFile(fileName, "rw", false);
file.setCheckedWriting(false); file.setCheckedWriting(false);
file.autoDelete(); file.autoDelete();
file.seek(FileStore.HEADER_LENGTH); file.seek(FileStore.HEADER_LENGTH);
......
...@@ -22,8 +22,8 @@ public class SecureFileStore extends FileStore { ...@@ -22,8 +22,8 @@ public class SecureFileStore extends FileStore {
private byte[] bufferForInitVector; private byte[] bufferForInitVector;
private int keyIterations; private int keyIterations;
public SecureFileStore(DataHandler handler, String name, byte[] magic, String cipher, byte[] key, int keyIterations) throws SQLException { public SecureFileStore(DataHandler handler, String name, String mode, byte[] magic, String cipher, byte[] key, int keyIterations) throws SQLException {
super(handler, name, magic); super(handler, name, mode, magic);
this.key = key; this.key = key;
if ("XTEA".equalsIgnoreCase(cipher)) { if ("XTEA".equalsIgnoreCase(cipher)) {
this.cipher = new XTEA(); this.cipher = new XTEA();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论