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

--no commit message

--no commit message
上级 2228df8c
......@@ -577,8 +577,8 @@ By default, a database is closed when the last connection is closed. However, if
the database is closed when the virtual machine exits normally. This is done using a shutdown hook.
In some situations, the database should not be closed in this case, for example because the
database is still used at virtual machine shutdown (to store the shutdown process in the database for example).
In this case, the automatic closing of the database can be disabled.
This can be done in the database URL. The first connection (the one that is opening the database) needs to
For those cases, the automatic closing of the database can be disabled in the database URL.
The first connection (the one that is opening the database) needs to
set the option in the database URL (it is not possible to change the setting afterwards).
The database URL to disable database closing on exit is:
<pre>
......
......@@ -37,7 +37,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / 2007-TODO</h3><ul>
<li>Optimization for WHERE NOT(...) and WHERE [NOT] booleanFlagColumn.
<li>CREATE TABLE ... AS SELECT now needs less memory. While inserting the rows, the undo
log is temporarily disabled. This avoid out of memory problems when creating large tables.
</li><li>The per session undo log can now be disabled. This setting is useful for bulk operations
that don't need to be atomic, like bulk delete or update.
</li><li>The database file could get corruted when there was an OutOfMemoryException in the middle of inserting a row.
</li><li>Optimization for WHERE NOT(...) and WHERE [NOT] booleanFlagColumn.
This can be disabled using the system property h2.optimizeNot.
</li><li>Optimization for conditions like WHERE A=B AND B=X (A=X is added). This often appears in joins.
This can be disabled using the system property h2.optimizeTwoEquals.
......
......@@ -20,6 +20,7 @@ import org.h2.schema.Sequence;
import org.h2.table.Column;
import org.h2.table.TableData;
import org.h2.util.ObjectArray;
import org.h2.value.DataType;
/**
* @author Thomas
......@@ -153,12 +154,18 @@ public class CreateTable extends SchemaCommand {
command.update();
}
if(asQuery != null) {
Insert insert = new Insert(session);
insert.setTable(table);
insert.setQuery(asQuery);
insert.prepare();
int todoSetCreateAsBatchSize;
insert.update();
boolean old = session.getUndoLogEnabled();
try {
session.setUndoLogEnabled(false);
Insert insert = null;
insert = new Insert(session);
insert.setQuery(asQuery);
insert.setTable(table);
insert.prepare();
insert.update();
} finally {
session.setUndoLogEnabled(old);
}
}
} catch(SQLException e) {
db.checkPowerOff();
......@@ -169,6 +176,7 @@ 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++) {
......@@ -176,7 +184,14 @@ public class CreateTable extends SchemaCommand {
int type = expr.getType();
String name = expr.getColumnName();
long precision = expr.getPrecision();
DataType dt = DataType.getDataType(type);
if(precision > 0 && (dt.defaultPrecision == 0 || dt.defaultPrecision > precision)) {
precision = dt.defaultPrecision;
}
int scale = expr.getScale();
if(scale > 0 && (dt.defaultScale == 0 || dt.defaultScale > scale)) {
precision = dt.defaultScale;
}
Column col = new Column(name, type, precision, scale);
addColumn(col);
}
......
......@@ -457,7 +457,7 @@ public class Select extends Query {
public void prepare() throws SQLException {
if(isPrepared) {
// TODO optimization: sometimes a subquery is prepared twice. why?
// sometimes a subquery is prepared twice (CREATE TABLE AS SELECT)
return;
}
if(Constants.CHECK && !checkInit) {
......
......@@ -33,7 +33,7 @@ public class SelectUnion extends Query {
private ObjectArray orderList;
private SortOrder sort;
private boolean distinct;
private boolean checkPrepared, checkInit;
private boolean isPrepared, checkInit;
private boolean isForUpdate;
public SelectUnion(Session session, Query query) {
......@@ -181,10 +181,14 @@ public class SelectUnion extends Query {
}
public void prepare() throws SQLException {
if(Constants.CHECK && (checkPrepared || !checkInit)) {
throw Message.getInternalError("already prepared");
if(isPrepared) {
// sometimes a subquery is prepared twice (CREATE TABLE AS SELECT)
return;
}
checkPrepared = true;
if(Constants.CHECK && !checkInit) {
throw Message.getInternalError("not initialized");
}
isPrepared = true;
left.prepare();
right.prepare();
int len = left.getColumnCount();
......
......@@ -245,6 +245,14 @@ public class Set extends Prepared {
session.setSchemaSearchPath(stringValueList);
break;
}
case SetTypes.UNDO_LOG: {
int value = getIntValue();
if(value < 0 || value > 1) {
throw Message.getInvalidValueException(""+getIntValue(), "UNDO_LOG");
}
session.setUndoLogEnabled(value == 1);
break;
}
default:
throw Message.getInternalError("type="+type);
}
......
......@@ -16,7 +16,7 @@ public class SetTypes {
public static final int MAX_MEMORY_ROWS = 16, LOCK_MODE = 17, DB_CLOSE_DELAY = 18;
public static final int LOG = 19, THROTTLE = 20, MAX_MEMORY_UNDO = 21, MAX_LENGTH_INPLACE_LOB = 22;
public static final int COMPRESS_LOB = 23, ALLOW_LITERALS = 24, MULTI_THREADED = 25, SCHEMA = 26;
public static final int OPTIMIZE_REUSE_RESULTS = 27, SCHEMA_SEARCH_PATH = 28;
public static final int OPTIMIZE_REUSE_RESULTS = 27, SCHEMA_SEARCH_PATH = 28, UNDO_LOG = 29;
private static ObjectArray types = new ObjectArray();
static {
......@@ -48,6 +48,7 @@ public class SetTypes {
setType(SCHEMA, "SCHEMA");
setType(OPTIMIZE_REUSE_RESULTS, "OPTIMIZE_REUSE_RESULTS");
setType(SCHEMA_SEARCH_PATH, "SCHEMA_SEARCH_PATH");
setType(UNDO_LOG, "UNDO_LOG");
}
private static void setType(int type, String name) {
......
......@@ -63,6 +63,7 @@ public class Session implements SessionInterface {
private HashMap procedures;
private static int nextSerialId;
private int serialId = nextSerialId++;
private boolean undoLogEnabled = true;
public Session() {
}
......@@ -277,7 +278,9 @@ public class Session implements SessionInterface {
}
}
}
undoLog.add(log);
if(undoLogEnabled) {
undoLog.add(log);
}
}
public void unlockReadLocks() {
......@@ -519,5 +522,13 @@ public class Session implements SessionInterface {
public int hashCode() {
return serialId;
}
public void setUndoLogEnabled(boolean b) {
this.undoLogEnabled = b;
}
public boolean getUndoLogEnabled() {
return undoLogEnabled;
}
}
......@@ -1009,6 +1009,18 @@ This setting can be appended to the database URL: jdbc:h2:test;TRACE_MAX_FILE_SI
SET TRACE_MAX_FILE_SIZE 10
"
"Commands (Other)","SET UNDO_LOG","
SET UNDO_LOG int
","
Enables (1) or disables (0) the per session undo log.
The undo log is enabled by default.
When disabled, transactions can not be rolled back.
This setting should only be used for bulk operations
that don't need to be atomic.
","
SET UNDO_LOG 0
"
"Commands (Other)","SET WRITE_DELAY","
SET WRITE_DELAY int
","
......
......@@ -35,11 +35,11 @@ import org.h2.value.ValueUuid;
* @author Thomas
*/
public class Column {
private final int type;
private final long precision;
private final int scale;
private Table table;
private String name;
private int type;
private long precision;
private int scale;
private int columnId;
private boolean nullable = true;
private Expression defaultExpression;
......
......@@ -25,7 +25,7 @@ import org.h2.value.ValueResultSet;
public class FunctionTable extends Table {
private FunctionCall function;
private final FunctionCall function;
public FunctionTable(Schema schema, Session session, FunctionCall function) throws SQLException {
super(schema, 0, function.getName(), false);
......
......@@ -67,9 +67,9 @@ public class MetaTable extends Table {
COLUMN_PRIVILEGES = 15, COLLATIONS = 16, VIEWS = 17, IN_DOUBT = 18, CROSS_REFERENCES = 19,
CONSTRAINTS = 20, FUNCTION_COLUMNS = 21, CONSTANTS = 22, DOMAINS = 23, TRIGGERS = 24;
private int type;
private final int type;
private final int indexColumn;
private MetaIndex index;
private int indexColumn;
public MetaTable(Schema schema, int id, int type) throws SQLException {
// tableName will be set later
......
......@@ -16,10 +16,10 @@ import org.h2.util.ObjectArray;
* @author Thomas
*/
public class Plan {
private TableFilter[] filters;
private HashMap planItems = new HashMap();
private Expression[] allConditions;
private TableFilter[] allFilters;
private final TableFilter[] filters;
private final HashMap planItems = new HashMap();
private final Expression[] allConditions;
private final TableFilter[] allFilters;
public Plan(TableFilter[] filters, int count, Expression condition) {
this.filters = new TableFilter[count];
......
......@@ -11,9 +11,7 @@ import org.h2.index.Index;
*/
public class PlanItem {
public double cost;
private Index index;
private PlanItem joinPlan;
public void setIndex(Index index) {
......
......@@ -19,7 +19,7 @@ import org.h2.value.Value;
public class RangeTable extends Table {
public static final String NAME = "SYSTEM_RANGE";
private long min, max;
private final long min, max;
public RangeTable(Schema schema, long min, long max) throws SQLException {
super(schema, 0, NAME, true);
......
......@@ -9,7 +9,7 @@ import org.h2.value.Value;
public class SingleColumnResolver implements ColumnResolver {
private Column column;
private final Column column;
private Value value;
SingleColumnResolver(Column column) {
......
......@@ -44,8 +44,8 @@ public abstract class Table extends SchemaObject {
public static final String VIEW = "VIEW";
protected Column[] columns;
private HashMap columnMap = new HashMap();
private boolean persistent;
private final HashMap columnMap = new HashMap();
private final boolean persistent;
private ObjectArray triggers;
private ObjectArray constraints;
private ObjectArray sequences;
......
......@@ -44,7 +44,7 @@ public class TableData extends Table implements RecordReader {
private HashSet lockShared = new HashSet();
private Trace traceLock;
private boolean globalTemporary;
private ObjectArray indexes = new ObjectArray();
private final ObjectArray indexes = new ObjectArray();
private long lastModificationId;
public TableData(Schema schema, String tableName, int id, ObjectArray columns,
......@@ -84,7 +84,7 @@ public class TableData extends Table implements RecordReader {
}
}
rowCount++;
} catch (SQLException e) {
} catch (Throwable e) {
try {
while(--i >= 0) {
Index index = (Index) indexes.get(i);
......@@ -102,7 +102,7 @@ public class TableData extends Table implements RecordReader {
// TODO log this problem
throw e2;
}
throw e;
throw Message.convert(e);
}
}
......
......@@ -27,18 +27,18 @@ import org.h2.value.ValueInt;
* @author Thomas
*/
public class TableFilter implements ColumnResolver {
private Session session;
private Table table;
private String alias;
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 Session session;
private Index index;
private Cursor cursor;
private int scanCount;
private boolean used; // used in the plan
private Select select;
// conditions that can be used for direct index lookup (start or end)
private ObjectArray indexConditions = new ObjectArray();
private final ObjectArray indexConditions = new ObjectArray();
// conditions that can't be used for index lookup, but for row filter for this table (ID=ID, NAME LIKE '%X%')
private Expression filterCondition;
......@@ -55,7 +55,7 @@ public class TableFilter implements ColumnResolver {
private boolean outerJoin;
private boolean foundOne;
private Expression fullCondition;
private boolean rightsChecked;
private final boolean rightsChecked;
public TableFilter(Session session, Table table, String alias, boolean rightsChecked, Select select) {
this.session = session;
......
......@@ -36,8 +36,8 @@ public class TableLink extends Table {
private String driver, url, user, password, originalTable;
private Connection conn;
private HashMap prepared = new HashMap();
private ObjectArray indexes = new ObjectArray();
private boolean emitUpdates;
private final ObjectArray indexes = new ObjectArray();
private final boolean emitUpdates;
private LinkedIndex linkedIndex;
private SQLException connectException;
......
......@@ -26,7 +26,7 @@ public class TableView extends Table {
private String querySQL;
private ObjectArray tables;
private String[] columnNames;
private final String[] columnNames;
private Query viewQuery;
private ViewIndexOld indexOld;
private ViewIndex indexNew;
......
......@@ -36,8 +36,8 @@ public class Backup {
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-file filename (the default is backup.zip)
* </li><li>-dir directory (the default is the current directory)
* </li><li>-db databaseName (all databases if no name is specified)
* </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (all databases if no name is specified)
* </li><li>-quiet does not print progress information
* </li></ul>
*
......
......@@ -40,8 +40,8 @@ public class ChangePassword {
* The following options are supported:
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-dir directory (the default is the current directory)
* </li><li>-db databaseName (all databases if no name is specified)
* </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (all databases if no name is specified)
* </li><li>-cipher type (AES or XTEA)
* </li><li>-decrypt password (null if the database is not encrypted)
* </li><li>-encrypt password (null if the database should not be encrypted)
......
......@@ -29,8 +29,8 @@ public class DeleteDbFiles {
* The following options are supported:
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-dir directory (the default is the current directory)
* </li><li>-db databaseName (all databases if no name is specified)
* </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (all databases if no name is specified)
* </li><li>-quiet does not print progress information
* </li></ul>
*
......
......@@ -74,8 +74,8 @@ public class Recover implements DataHandler {
* The following options are supported:
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-dir directory (the default is the current directory)
* </li><li>-db databaseName (all databases if no name is specified)
* </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (all databases if no name is specified)
* </li><li>-log {true|false} (log additional messages)
* </li></ul>
*
......
......@@ -36,8 +36,8 @@ public class Restore {
* <ul>
* <li>-help or -? (print the list of options)
* </li><li>-file filename (the default is backup.zip)
* </li><li>-dir directory (the default is the current directory)
* </li><li>-db databaseName (as stored in the backup if no name is specified)
* </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (as stored in the backup if no name is specified)
* </li><li>-quiet does not print progress information
* </li></ul>
*
......
......@@ -11,14 +11,12 @@ import org.h2.util.StringUtils;
public class CompareMode {
public static final String OFF = "OFF";
private String name = OFF;
private Collator collator;
private final Collator collator;
private final String name;
public CompareMode(Collator collator, String name) {
this.collator = collator;
if(name != null) {
this.name = name;
}
this.name = name == null ? OFF : name;
}
public int compareString(String a, String b, boolean ignoreCase) {
......
......@@ -36,25 +36,15 @@ public class Transfer {
private static final int BUFFER_SIZE = 16 * 1024;
private static final int LOB_MAGIC = 0x1234;
private SessionInterface session;
protected Socket socket;
protected DataInputStream in;
protected DataOutputStream out;
private Exception stackTrace = new Exception();
private SessionInterface session;
public Transfer(SessionInterface session) {
this.session = session;
}
protected void finalize() {
if (!Constants.RUN_FINALIZE) {
return;
}
if(socket != null) {
throw Message.getInternalError("not closed", stackTrace);
}
}
public void setSocket(Socket s) {
socket = s;
}
......
......@@ -10,7 +10,7 @@ import java.sql.SQLException;
import org.h2.message.Message;
public class ValueArray extends Value {
private Value[] values;
private final Value[] values;
private int hash;
public static ValueArray get(Value[] list) {
......
......@@ -13,7 +13,7 @@ import java.sql.SQLException;
public class ValueBoolean extends Value {
public static final int PRECISION = 1;
private Boolean value;
private final Boolean value;
private static final ValueBoolean TRUE = new ValueBoolean(true);
private static final ValueBoolean FALSE = new ValueBoolean(false);
......
......@@ -13,7 +13,7 @@ import org.h2.message.Message;
public class ValueByte extends Value {
public static final int PRECISION = 3;
private byte value;
private final byte value;
private ValueByte(byte value) {
this.value = value;
......@@ -114,10 +114,6 @@ public class ValueByte extends Value {
return (ValueByte) Value.cache(new ValueByte(i));
}
// public String getJavaString() {
// return "(byte)" + toString();
// }
public int getDisplaySize() {
return PRECISION;
}
......
......@@ -11,7 +11,7 @@ import org.h2.util.ByteUtils;
abstract class ValueBytesBase extends Value {
private byte[] value;
private final byte[] value;
private int hash;
protected ValueBytesBase(byte[] v) {
......
......@@ -17,7 +17,7 @@ import org.h2.util.DateTimeUtils;
public class ValueDate extends Value {
public static final int PRECISION = 8;
private Date value;
private final Date value;
private ValueDate(Date value) {
this.value = value;
......
......@@ -17,7 +17,7 @@ import org.h2.util.MathUtils;
*/
public class ValueDecimal extends Value {
// TODO doc: document differences for BigDecimal 1.5 <> 1.4
private BigDecimal value;
private final BigDecimal value;
private String valueString;
private int precision;
......
......@@ -16,7 +16,7 @@ import org.h2.message.Message;
public class ValueDouble extends Value {
public static final int PRECISION = 17;
private double value;
private final double value;
private static final double DOUBLE_ZERO = 0.0;
private static final double DOUBLE_ONE = 1.0;
private static final ValueDouble ZERO = new ValueDouble(DOUBLE_ZERO);
......
......@@ -16,7 +16,7 @@ import org.h2.message.Message;
public class ValueFloat extends Value {
public static final int PRECISION = 7;
private float value;
private final float value;
private static final float FLOAT_ZERO = 0.0F;
private static final float FLOAT_ONE = 1.0F;
private static final ValueFloat ZERO = new ValueFloat(FLOAT_ZERO);
......
......@@ -16,7 +16,7 @@ import org.h2.message.Message;
public class ValueInt extends Value {
public static final int PRECISION = 10;
private int value;
private final int value;
private static final int STATIC_SIZE = 100;
private static final int DYNAMIC_SIZE = 256; // must be a power of 2
// TODO check performance of final static!
......
......@@ -13,7 +13,7 @@ import org.h2.message.Message;
public class ValueLong extends Value {
private long value;
private final long value;
public static final int PRECISION = 19;
private static final int STATIC_SIZE = 10;
......
......@@ -13,7 +13,7 @@ import org.h2.message.Message;
public class ValueShort extends Value {
public static final int PRECISION = 5;
private short value;
private final short value;
private ValueShort(short value) {
this.value = value;
......
......@@ -11,7 +11,7 @@ import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
abstract class ValueStringBase extends Value {
protected String value;
protected final String value;
protected ValueStringBase(String value) {
this.value = value;
......
......@@ -13,7 +13,7 @@ import org.h2.util.DateTimeUtils;
public class ValueTime extends Value {
public static final int PRECISION = 6;
private Time value;
private final Time value;
private ValueTime(Time value) {
this.value = value;
......
......@@ -16,7 +16,7 @@ import org.h2.util.MathUtils;
public class ValueTimestamp extends Value {
public static final int PRECISION = 23;
public static final int DEFAULT_SCALE = 10;
private Timestamp value;
private final Timestamp value;
private ValueTimestamp(Timestamp value) {
this.value = value;
......
......@@ -13,7 +13,7 @@ import org.h2.util.StringUtils;
public class ValueUuid extends Value {
public static final int PRECISION = 36;
private long high, low;
private final long high, low;
private ValueUuid(long high, long low) {
this.high = high;
......
......@@ -94,27 +94,10 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
ability to switch off undo log of the session
(and automatically switch it off for create table as select)
drop table test;
create table test as select x, space(10000) d from system_range(1, 10000);
null?
drop table test;
create table test as select x, cast(space(5000) as varchar) d from system_range(1, 10000);
select top 10 * from test;
database is not closed when killing the process (but should? why not?)
set read-committed as the default
SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = current_user;
check trace.db/ number of files, limit to 1000 or so
storages should be an int hash map
Test with newest Hibernate
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
create table test as select 1, space(10) from dual where 1=0 union all select x, cast(space(100) as varchar(101)) d from system_range(1, 100);
> ok
drop table test;
> ok
explain select * from system_range(1, 2) where x=x+1 and x=1;
> PLAN
> -------------------------------------------------------------------------------------------------------
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论