提交 6c69221a authored 作者: Thomas Mueller's avatar Thomas Mueller

Various system properties have been replaced with database level settings.

上级 a1a2fa0b
...@@ -18,9 +18,12 @@ Change Log ...@@ -18,9 +18,12 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Various system properties have been replaced with database level settings: <ul><li>Some system properties are not supported any longer, because they can
analyzeAuto, analyzeSample, databaseToUpper,... already be set in the database URL. Those settings are:
See the javadoc documentation of DbSettings for details. h2.cacheSizeDefault, h2.cacheTypeDefault
</li><li>Various system properties have been replaced with database level settings:
ALIAS_COLUMN_NAME, ANALYZE_AUTO, ANALYZE_SAMPLE, DATABASE_TO_UPPER,...
See the Javadoc documentation of DbSettings for details.
The system properties are still supported for backward compatibility. The system properties are still supported for backward compatibility.
</li><li>When the system property h2.nestedJoins was enabled, some outer joins returned the wrong result. </li><li>When the system property h2.nestedJoins was enabled, some outer joins returned the wrong result.
</li><li>Opening a database could throw a NullPointerException. </li><li>Opening a database could throw a NullPointerException.
......
...@@ -1644,7 +1644,9 @@ public class Parser { ...@@ -1644,7 +1644,9 @@ public class Parser {
Expression expr = readExpression(); Expression expr = readExpression();
if (readIf("AS") || currentTokenType == IDENTIFIER) { if (readIf("AS") || currentTokenType == IDENTIFIER) {
String alias = readAliasIdentifier(); String alias = readAliasIdentifier();
expr = new Alias(expr, alias, database.getMode().aliasColumnName); boolean aliasColumnName = database.getSettings().aliasColumnName;
aliasColumnName |= database.getMode().aliasColumnName;
expr = new Alias(expr, alias, aliasColumnName);
} }
expressions.add(expr); expressions.add(expr);
} }
...@@ -3597,7 +3599,6 @@ public class Parser { ...@@ -3597,7 +3599,6 @@ public class Parser {
read("REPLACE"); read("REPLACE");
orReplace = true; orReplace = true;
} }
boolean force = readIf("FORCE"); boolean force = readIf("FORCE");
if (readIf("VIEW")) { if (readIf("VIEW")) {
return parseCreateView(force, orReplace); return parseCreateView(force, orReplace);
......
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
*/ */
package org.h2.constant; package org.h2.constant;
import java.util.Properties; import java.util.HashMap;
import org.h2.engine.SettingsBase; import org.h2.engine.SettingsBase;
/** /**
* This class contains various database-level settings. To override the * This class contains various database-level settings. To override the
* documented default value for a database, append the setting in the database * documented default value for a database, append the setting in the database
* URL: "jdbc:h2:test;analyzeSample=100" when opening the first connection to * URL: "jdbc:h2:test;ALIAS_COLUMN_NAME=TRUE" when opening the first connection to
* the database. The settings can not be changed once the database is open. * the database. The settings can not be changed once the database is open.
* <p> * <p>
* Some settings are a last resort and temporary solution to work around a * Some settings are a last resort and temporary solution to work around a
...@@ -26,7 +26,20 @@ public class DbSettings extends SettingsBase { ...@@ -26,7 +26,20 @@ public class DbSettings extends SettingsBase {
private static DbSettings defaultSettings; private static DbSettings defaultSettings;
/** /**
* Database setting <code>analyzeAuto</code> (default: 0).<br /> * Database setting <code>ALIAS_COLUMN_NAME</code> (default: false).<br />
* When enabled, aliased columns (as in SELECT ID AS I FROM TEST) return the
* alias (I in this case) in ResultSetMetaData.getColumnName() and 'null' in
* getTableName(). If disabled, the real column name (ID in this case) and
* table name is returned.
* <br />
* This setting only affects the default and the MySQL mode. When using
* any other mode, this feature is enabled for compatibility, even if this
* database setting is not enabled explicitly.
*/
public final boolean aliasColumnName = get("ALIAS_COLUMN_NAME", false);
/**
* Database setting <code>ANALYZE_AUTO</code> (default: 0).<br />
* After changing this many rows, ANALYZE is automatically run for a table. * After changing this many rows, ANALYZE is automatically run for a table.
* Automatically running ANALYZE is disabled if set to 0. If set to 1000, * Automatically running ANALYZE is disabled if set to 0. If set to 1000,
* then ANALYZE will run against each user table after about 1000 changes to * then ANALYZE will run against each user table after about 1000 changes to
...@@ -34,13 +47,13 @@ public class DbSettings extends SettingsBase { ...@@ -34,13 +47,13 @@ public class DbSettings extends SettingsBase {
* starting the database. It is not run on local temporary tables, and * starting the database. It is not run on local temporary tables, and
* tables that have a trigger on SELECT. * tables that have a trigger on SELECT.
*/ */
public int analyzeAuto = get("analyzeAuto", 0); public final int analyzeAuto = get("ANALYZE_AUTO", 0);
/** /**
* Database setting <code>analyzeSample</code> (default: 10000).<br /> * Database setting <code>ANALYZE_SAMPLE</code> (default: 10000).<br />
* The default sample size when analyzing a table. * The default sample size when analyzing a table.
*/ */
public int analyzeSample = get("analyzeSample", 10000); public final int analyzeSample = get("ANALYZE_SAMPLE", 10000);
/** /**
* Database setting <code>databaseToUpper</code> (default: true).<br /> * Database setting <code>databaseToUpper</code> (default: true).<br />
...@@ -48,59 +61,72 @@ public class DbSettings extends SettingsBase { ...@@ -48,59 +61,72 @@ public class DbSettings extends SettingsBase {
* function, and in the CATALOG column of all database meta data methods. * function, and in the CATALOG column of all database meta data methods.
* Setting this to "false" is experimental. * Setting this to "false" is experimental.
*/ */
public boolean databaseToUpper = get("databaseToUpper", true); public final boolean databaseToUpper = get("DATABASE_TO_UPPER", true);
/** /**
* Database setting <code>defaultEscape</code> (default: \).<br /> * Database setting <code>DEFAULT_ESCAPE</code> (default: \).<br />
* The default escape character for LIKE comparisons. To select no escape * The default escape character for LIKE comparisons. To select no escape
* character, use an empty string. * character, use an empty string.
*/ */
public String defaultEscape = get("defaultEscape", "\\"); public final String defaultEscape = get("DEFAULT_ESCAPE", "\\");
/** /**
* Database setting <code>defragAlways</code> (default: false).<br /> * Database setting <code>DEFRAG_ALWAYS</code> (default: false).<br />
* Each time the database is closed, it is fully defragmented (SHUTDOWN DEFRAG). * Each time the database is closed, it is fully defragmented (SHUTDOWN DEFRAG).
*/ */
public boolean defragAlways = get("defragAlways", false); public final boolean defragAlways = get("DEFRAG_ALWAYS", false);
/** /**
* Database setting <code>dropRestrict</code> (default: false).<br /> * Database setting <code>DROP_RESTRICT</code> (default: false).<br />
* Whether the default action for DROP TABLE and DROP VIEW is RESTRICT. For * Whether the default action for DROP TABLE and DROP VIEW is RESTRICT. For
* most databases, the default action is RESTRICT, but for compatibility * most databases, the default action is RESTRICT, but for compatibility
* with older versions of H2 the default action is currently CASCADE. This will * with older versions of H2 the default action is currently CASCADE. This will
* change in a future version of H2. * change in a future version of H2.
*/ */
public boolean dropRestrict = get("dropRestrict", false); public final boolean dropRestrict = get("DROP_RESTRICT", false);
/** /**
* Database setting <code>estimatedFunctionTableRows</code> (default: * Database setting <code>ESTIMATED_FUNCTION_TABLE_ROWS</code> (default:
* 1000).<br /> * 1000).<br />
* The estimated number of rows in a function table (for example, CSVREAD or * The estimated number of rows in a function table (for example, CSVREAD or
* FTL_SEARCH). This value is used by the optimizer. * FTL_SEARCH). This value is used by the optimizer.
*/ */
public int estimatedFunctionTableRows = get("estimatedFunctionTableRows", 1000); public final int estimatedFunctionTableRows = get("ESTIMATED_FUNCTION_TABLE_ROWS", 1000);
/** /**
* Database setting <code>functionsInSchema</code> (default: * Database setting <code>FUNCTIONS_IN_SCHEMA</code> (default:
* false).<br /> * false).<br />
* If set, all functions are stored in a schema. Specially, the SCRIPT statement * If set, all functions are stored in a schema. Specially, the SCRIPT statement
* will always include the schema name in the CREATE ALIAS statement. * will always include the schema name in the CREATE ALIAS statement.
* This is not backward compatible with H2 versions 1.2.134 and older. * This is not backward compatible with H2 versions 1.2.134 and older.
*/ */
public boolean functionsInSchema = get("functionsInSchema", false); public final boolean functionsInSchema = get("FUNCTIONS_IN_SCHEMA", false);
/**
* System property <code>h2.largeResultBufferSize</code> (default: 4096).<br />
* Buffer size for large result sets. Set this value to 0 to disable the
* buffer.
*/
public final int largeResultBufferSize = get("LARGE_RESULT_BUFFER_SIZE", 4 * 1024);
/**
* System property <code>h2.largeTransactions</code> (default: false).<br />
* Support very large transactions
*/
public final boolean largeTransactions = get("LARGE_TRANSACTIONS", false);
/** /**
* Database setting <code>queryCacheSize</code> (default: 0).<br /> * Database setting <code>QUERY_CACHE_SIZE</code> (default: 0).<br />
* The size of the query cache. Each session has it's own cache with the * The size of the query cache. Each session has it's own cache with the
* given size. The cache is only used if the SQL statement and all * given size. The cache is only used if the SQL statement and all
* parameters match. Only the last returned result per query is cached. Only * parameters match. Only the last returned result per query is cached. Only
* SELECT statements are cached (excluding UNION and FOR UPDATE statements). * SELECT statements are cached (excluding UNION and FOR UPDATE statements).
* This works for both statements and prepared statement. * This works for both statements and prepared statement.
*/ */
public int queryCacheSize = get("queryCacheSize", 0); public final int queryCacheSize = get("QUERY_CACHE_SIZE", 0);
private DbSettings(Properties p) { private DbSettings(HashMap<String, String> s) {
super(p); super(s);
} }
/** /**
...@@ -110,14 +136,14 @@ public class DbSettings extends SettingsBase { ...@@ -110,14 +136,14 @@ public class DbSettings extends SettingsBase {
* @param p the properties * @param p the properties
* @return the settings * @return the settings
*/ */
public static DbSettings getInstance(Properties p) { public static DbSettings getInstance(HashMap<String, String> s) {
if (p == null || p.isEmpty()) { if (s == null || s.isEmpty()) {
if (defaultSettings == null) { if (defaultSettings == null) {
defaultSettings = new DbSettings(new Properties()); defaultSettings = new DbSettings(new HashMap<String, String>());
} }
return defaultSettings; return defaultSettings;
} }
return new DbSettings(p); return new DbSettings(s);
} }
} }
...@@ -9,6 +9,7 @@ package org.h2.engine; ...@@ -9,6 +9,7 @@ package org.h2.engine;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import org.h2.command.dml.SetTypes; import org.h2.command.dml.SetTypes;
...@@ -563,18 +564,22 @@ public class ConnectionInfo implements Cloneable { ...@@ -563,18 +564,22 @@ public class ConnectionInfo implements Cloneable {
public DbSettings getDbSettings() { public DbSettings getDbSettings() {
DbSettings defaultSettings = DbSettings.getInstance(null); DbSettings defaultSettings = DbSettings.getInstance(null);
Properties p = null; HashMap<String, String> s = null;
for (Object s : prop.keySet()) { ArrayList<String> remove = New.arrayList();
String k = s.toString(); for (Object k : prop.keySet()) {
if (!isKnownSetting(k) && defaultSettings.containsKey(k)) { String key = k.toString();
if (p == null) { if (!isKnownSetting(key) && defaultSettings.containsKey(key)) {
p = new Properties(); if (s == null) {
s = New.hashMap();
} }
p.put(k, prop.get(k)); s.put(key, prop.getProperty(key));
prop.remove(k); remove.add(key);
} }
} }
return DbSettings.getInstance(p); for (String r : remove) {
prop.remove(r);
}
return DbSettings.getInstance(s);
} }
} }
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
*/ */
package org.h2.engine; package org.h2.engine;
import java.sql.ResultSet;
import org.h2.constant.SysProperties;
/** /**
* Constants are fixed values that are used in the whole database code. * Constants are fixed values that are used in the whole database code.
*/ */
...@@ -397,6 +400,50 @@ public class Constants { ...@@ -397,6 +400,50 @@ public class Constants {
*/ */
public static final String USER_PACKAGE = "org.h2.dynamic"; public static final String USER_PACKAGE = "org.h2.dynamic";
int sortByName;
/**
* The default result set concurrency for statements created with
* Connection.createStatement() or prepareStatement(String sql).
*/
public static final int DEFAULT_RESULT_SET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
/**
* The default maximum length of an LOB that is stored with the record itself.
* Only used if h2.lobInDatabase is enabled.
*/
public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB2 = 128;
/**
* The default value for the LOCK_MODE setting.
*/
public static final int DEFAULT_LOCK_MODE = LOCK_MODE_READ_COMMITTED;
/**
* The default value for the MAX_MEMORY_UNDO setting.
*/
public static final int DEFAULT_MAX_MEMORY_UNDO = 50000;
/**
* The default maximum length of an LOB that is stored in the database file.
*/
public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB = 4096;
/**
* The default cache size in KB.
*/
public static final int CACHE_SIZE_DEFAULT = 16 * 1024;
/**
* The default cache type.
*/
public static final String CACHE_TYPE_DEFAULT = "LRU";
/**
* The default for the setting MAX_OPERATION_MEMORY.
*/
public static final int DEFAULT_MAX_OPERATION_MEMORY = 100000;
private Constants() { private Constants() {
// utility class // utility class
} }
......
...@@ -128,8 +128,8 @@ public class Database implements DataHandler { ...@@ -128,8 +128,8 @@ public class Database implements DataHandler {
private int writeDelay = Constants.DEFAULT_WRITE_DELAY; private int writeDelay = Constants.DEFAULT_WRITE_DELAY;
private DatabaseEventListener eventListener; private DatabaseEventListener eventListener;
private int maxMemoryRows = Constants.DEFAULT_MAX_MEMORY_ROWS; private int maxMemoryRows = Constants.DEFAULT_MAX_MEMORY_ROWS;
private int maxMemoryUndo = SysProperties.DEFAULT_MAX_MEMORY_UNDO; private int maxMemoryUndo = Constants.DEFAULT_MAX_MEMORY_UNDO;
private int lockMode = SysProperties.DEFAULT_LOCK_MODE; private int lockMode = Constants.DEFAULT_LOCK_MODE;
private int maxLengthInplaceLob; private int maxLengthInplaceLob;
private int allowLiterals = Constants.ALLOW_LITERALS_ALL; private int allowLiterals = Constants.ALLOW_LITERALS_ALL;
...@@ -148,7 +148,7 @@ public class Database implements DataHandler { ...@@ -148,7 +148,7 @@ public class Database implements DataHandler {
private DatabaseCloser closeOnExit; private DatabaseCloser closeOnExit;
private Mode mode = Mode.getInstance(Mode.REGULAR); private Mode mode = Mode.getInstance(Mode.REGULAR);
private boolean multiThreaded; private boolean multiThreaded;
private int maxOperationMemory = SysProperties.DEFAULT_MAX_OPERATION_MEMORY; private int maxOperationMemory = Constants.DEFAULT_MAX_OPERATION_MEMORY;
private SmallLRUCache<String, String[]> lobFileListCache; private SmallLRUCache<String, String[]> lobFileListCache;
private boolean autoServerMode; private boolean autoServerMode;
private Server server; private Server server;
...@@ -180,12 +180,12 @@ public class Database implements DataHandler { ...@@ -180,12 +180,12 @@ public class Database implements DataHandler {
this.databaseName = name; this.databaseName = name;
this.databaseShortName = parseDatabaseShortName(); this.databaseShortName = parseDatabaseShortName();
this.maxLengthInplaceLob = SysProperties.LOB_IN_DATABASE ? this.maxLengthInplaceLob = SysProperties.LOB_IN_DATABASE ?
SysProperties.DEFAULT_MAX_LENGTH_INPLACE_LOB2 : SysProperties.DEFAULT_MAX_LENGTH_INPLACE_LOB; Constants.DEFAULT_MAX_LENGTH_INPLACE_LOB2 : Constants.DEFAULT_MAX_LENGTH_INPLACE_LOB;
this.cipher = cipher; this.cipher = cipher;
String lockMethodName = ci.getProperty("FILE_LOCK", null); String lockMethodName = ci.getProperty("FILE_LOCK", null);
this.accessModeData = ci.getProperty("ACCESS_MODE_DATA", "rw").toLowerCase(); this.accessModeData = ci.getProperty("ACCESS_MODE_DATA", "rw").toLowerCase();
this.autoServerMode = ci.getProperty("AUTO_SERVER", false); this.autoServerMode = ci.getProperty("AUTO_SERVER", false);
this.cacheSize = ci.getProperty("CACHE_SIZE", SysProperties.CACHE_SIZE_DEFAULT); this.cacheSize = ci.getProperty("CACHE_SIZE", Constants.CACHE_SIZE_DEFAULT);
this.pageSize = ci.getProperty("PAGE_SIZE", SysProperties.PAGE_SIZE); this.pageSize = ci.getProperty("PAGE_SIZE", SysProperties.PAGE_SIZE);
if ("r".equals(accessModeData)) { if ("r".equals(accessModeData)) {
readOnly = true; readOnly = true;
...@@ -202,7 +202,7 @@ public class Database implements DataHandler { ...@@ -202,7 +202,7 @@ public class Database implements DataHandler {
int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE); int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE);
int traceLevelSystemOut = ci.getIntProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT, int traceLevelSystemOut = ci.getIntProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT,
TraceSystem.DEFAULT_TRACE_LEVEL_SYSTEM_OUT); TraceSystem.DEFAULT_TRACE_LEVEL_SYSTEM_OUT);
this.cacheType = StringUtils.toUpperEnglish(ci.removeProperty("CACHE_TYPE", SysProperties.CACHE_TYPE_DEFAULT)); this.cacheType = StringUtils.toUpperEnglish(ci.removeProperty("CACHE_TYPE", Constants.CACHE_TYPE_DEFAULT));
openDatabase(traceLevelFile, traceLevelSystemOut, closeAtVmShutdown); openDatabase(traceLevelFile, traceLevelSystemOut, closeAtVmShutdown);
} }
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
package org.h2.engine; package org.h2.engine;
import java.util.HashMap; import java.util.HashMap;
import org.h2.constant.SysProperties;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -115,7 +113,6 @@ public class Mode { ...@@ -115,7 +113,6 @@ public class Mode {
static { static {
Mode mode = new Mode(REGULAR); Mode mode = new Mode(REGULAR);
mode.aliasColumnName = SysProperties.ALIAS_COLUMN_NAME;
mode.nullConcatIsNull = true; mode.nullConcatIsNull = true;
add(mode); add(mode);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
package org.h2.engine; package org.h2.engine;
import java.util.Properties; import java.util.HashMap;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -15,10 +15,10 @@ import org.h2.message.DbException; ...@@ -15,10 +15,10 @@ import org.h2.message.DbException;
*/ */
public class SettingsBase { public class SettingsBase {
private Properties properties; private HashMap<String, String> settings;
protected SettingsBase(Properties p) { protected SettingsBase(HashMap<String, String> s) {
this.properties = p; this.settings = s;
} }
protected boolean get(String key, boolean defaultValue) { protected boolean get(String key, boolean defaultValue) {
...@@ -40,20 +40,35 @@ public class SettingsBase { ...@@ -40,20 +40,35 @@ public class SettingsBase {
} }
protected String get(String key, String defaultValue) { protected String get(String key, String defaultValue) {
String keyUpper = key.toUpperCase(); StringBuilder buff = new StringBuilder("h2.");
String v = properties.getProperty(keyUpper); boolean nextUpper = false;
for (char c : key.toCharArray()) {
if (c == '_') {
nextUpper = true;
} else {
// Character.toUpperCase / toLowerCase ignores the locale
buff.append(nextUpper ? Character.toUpperCase(c) : Character.toLowerCase(c));
nextUpper = false;
}
}
String sysProperty = buff.toString();
String v = settings.get(key);
if (v == null) { if (v == null) {
v = System.getProperty("h2." + key); v = System.getProperty(sysProperty);
} }
if (v == null) { if (v == null) {
properties.put(keyUpper, defaultValue); settings.put(key, defaultValue);
v = defaultValue; v = defaultValue;
} }
return v; return v;
} }
public boolean containsKey(String k) { public boolean containsKey(String k) {
return properties.containsKey(k); return settings.containsKey(k);
}
public HashMap<String, String> getSettings() {
return settings;
} }
} }
...@@ -19,6 +19,7 @@ import org.h2.util.New; ...@@ -19,6 +19,7 @@ import org.h2.util.New;
* Each session keeps a undo log if rollback is required. * Each session keeps a undo log if rollback is required.
*/ */
public class UndoLog { public class UndoLog {
private Database database; private Database database;
private ArrayList<Long> storedEntriesPos = New.arrayList(); private ArrayList<Long> storedEntriesPos = New.arrayList();
private ArrayList<UndoLogRecord> records = New.arrayList(); private ArrayList<UndoLogRecord> records = New.arrayList();
...@@ -27,6 +28,7 @@ public class UndoLog { ...@@ -27,6 +28,7 @@ public class UndoLog {
private int memoryUndo; private int memoryUndo;
private int storedEntries; private int storedEntries;
private HashMap<Integer, Table> tables; private HashMap<Integer, Table> tables;
private boolean largeTransactions;
/** /**
* Create a new undo log for the given session. * Create a new undo log for the given session.
...@@ -35,6 +37,7 @@ public class UndoLog { ...@@ -35,6 +37,7 @@ public class UndoLog {
*/ */
public UndoLog(Session session) { public UndoLog(Session session) {
this.database = session.getDatabase(); this.database = session.getDatabase();
largeTransactions = database.getSettings().largeTransactions;
} }
/** /**
...@@ -43,7 +46,7 @@ public class UndoLog { ...@@ -43,7 +46,7 @@ public class UndoLog {
* @return the number of rows * @return the number of rows
*/ */
public int size() { public int size() {
if (SysProperties.LARGE_TRANSACTIONS) { if (largeTransactions) {
return storedEntries + records.size(); return storedEntries + records.size();
} }
if (SysProperties.CHECK && memoryUndo > records.size()) { if (SysProperties.CHECK && memoryUndo > records.size()) {
...@@ -75,7 +78,7 @@ public class UndoLog { ...@@ -75,7 +78,7 @@ public class UndoLog {
*/ */
public UndoLogRecord getLast() { public UndoLogRecord getLast() {
int i = records.size() - 1; int i = records.size() - 1;
if (SysProperties.LARGE_TRANSACTIONS) { if (largeTransactions) {
if (i < 0 && storedEntries > 0) { if (i < 0 && storedEntries > 0) {
int last = storedEntriesPos.size() - 1; int last = storedEntriesPos.size() - 1;
long pos = storedEntriesPos.get(last); long pos = storedEntriesPos.get(last);
...@@ -151,7 +154,7 @@ public class UndoLog { ...@@ -151,7 +154,7 @@ public class UndoLog {
*/ */
public void add(UndoLogRecord entry) { public void add(UndoLogRecord entry) {
records.add(entry); records.add(entry);
if (SysProperties.LARGE_TRANSACTIONS) { if (largeTransactions) {
memoryUndo++; memoryUndo++;
if (memoryUndo > database.getMaxMemoryUndo() && database.isPersistent() && !database.isMultiVersion()) { if (memoryUndo > database.getMaxMemoryUndo() && database.isPersistent() && !database.isMultiVersion()) {
if (file == null) { if (file == null) {
......
...@@ -69,10 +69,7 @@ public class UndoLogRecord { ...@@ -69,10 +69,7 @@ public class UndoLogRecord {
* @return if it can be stored * @return if it can be stored
*/ */
boolean canStore() { boolean canStore() {
if (SysProperties.LARGE_TRANSACTIONS) { // if large transactions are enabled, this method is not called
// actually the method is not called in this case
return true;
}
if (table.getUniqueIndex() != null) { if (table.getUniqueIndex() != null) {
return true; return true;
} }
...@@ -145,9 +142,7 @@ public class UndoLogRecord { ...@@ -145,9 +142,7 @@ public class UndoLogRecord {
buff.writeInt(0); buff.writeInt(0);
buff.writeInt(operation); buff.writeInt(operation);
buff.writeByte(row.isDeleted() ? (byte) 1 : (byte) 0); buff.writeByte(row.isDeleted() ? (byte) 1 : (byte) 0);
if (SysProperties.LARGE_TRANSACTIONS) { buff.writeInt(log.getTableId(table));
buff.writeInt(log.getTableId(table));
}
buff.writeLong(row.getKey()); buff.writeLong(row.getKey());
buff.writeInt(row.getSessionId()); buff.writeInt(row.getSessionId());
int count = row.getColumnCount(); int count = row.getColumnCount();
...@@ -222,9 +217,7 @@ public class UndoLogRecord { ...@@ -222,9 +217,7 @@ public class UndoLogRecord {
private void load(Data buff, UndoLog log) { private void load(Data buff, UndoLog log) {
operation = (short) buff.readInt(); operation = (short) buff.readInt();
boolean deleted = buff.readByte() == 1; boolean deleted = buff.readByte() == 1;
if (SysProperties.LARGE_TRANSACTIONS) { table = log.getTable(buff.readInt());
table = log.getTable(buff.readInt());
}
long key = buff.readLong(); long key = buff.readLong();
int sessionId = buff.readInt(); int sessionId = buff.readInt();
int columnCount = buff.readInt(); int columnCount = buff.readInt();
......
...@@ -162,7 +162,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -162,7 +162,7 @@ public class JdbcConnection extends TraceObject implements Connection {
debugCodeAssign("Statement", TraceObject.STATEMENT, id, "createStatement()"); debugCodeAssign("Statement", TraceObject.STATEMENT, id, "createStatement()");
} }
checkClosed(); checkClosed();
return new JdbcStatement(this, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, false); return new JdbcStatement(this, id, ResultSet.TYPE_FORWARD_ONLY, Constants.DEFAULT_RESULT_SET_CONCURRENCY, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -230,7 +230,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -230,7 +230,7 @@ public class JdbcConnection extends TraceObject implements Connection {
} }
checkClosed(); checkClosed();
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, false); return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, Constants.DEFAULT_RESULT_SET_CONCURRENCY, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -251,7 +251,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -251,7 +251,7 @@ public class JdbcConnection extends TraceObject implements Connection {
} }
checkClosed(); checkClosed();
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY, true); return new JdbcPreparedStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, Constants.DEFAULT_RESULT_SET_CONCURRENCY, true);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -792,7 +792,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -792,7 +792,7 @@ public class JdbcConnection extends TraceObject implements Connection {
} }
checkClosed(); checkClosed();
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcCallableStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, SysProperties.DEFAULT_RESULT_SET_CONCURRENCY); return new JdbcCallableStatement(this, sql, id, ResultSet.TYPE_FORWARD_ONLY, Constants.DEFAULT_RESULT_SET_CONCURRENCY);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
......
...@@ -31,6 +31,7 @@ class ResultDiskBuffer implements ResultExternal { ...@@ -31,6 +31,7 @@ class ResultDiskBuffer implements ResultExternal {
private ResultDiskTape mainTape; private ResultDiskTape mainTape;
private SortOrder sort; private SortOrder sort;
private int columnCount; private int columnCount;
private final int maxBufferSize;
/** /**
* Represents a virtual disk tape for the merge sort algorithm. * Represents a virtual disk tape for the merge sort algorithm.
...@@ -74,6 +75,7 @@ class ResultDiskBuffer implements ResultExternal { ...@@ -74,6 +75,7 @@ class ResultDiskBuffer implements ResultExternal {
mainTape = new ResultDiskTape(); mainTape = new ResultDiskTape();
mainTape.pos = FileStore.HEADER_LENGTH; mainTape.pos = FileStore.HEADER_LENGTH;
} }
this.maxBufferSize = db.getSettings().largeResultBufferSize;
} }
public void addRows(ArrayList<Value[]> rows) { public void addRows(ArrayList<Value[]> rows) {
...@@ -84,7 +86,6 @@ class ResultDiskBuffer implements ResultExternal { ...@@ -84,7 +86,6 @@ class ResultDiskBuffer implements ResultExternal {
long start = file.getFilePointer(); long start = file.getFilePointer();
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int bufferLen = 0; int bufferLen = 0;
int maxBufferSize = SysProperties.LARGE_RESULT_BUFFER_SIZE;
for (Value[] row : rows) { for (Value[] row : rows) {
buff.reset(); buff.reset();
buff.writeInt(0); buff.writeInt(0);
......
...@@ -40,7 +40,7 @@ public class RowList { ...@@ -40,7 +40,7 @@ public class RowList {
*/ */
public RowList(Session session) { public RowList(Session session) {
this.session = session; this.session = session;
if (SysProperties.DEFAULT_MAX_OPERATION_MEMORY > 0 && session.getDatabase().isPersistent()) { if (session.getDatabase().isPersistent()) {
maxMemory = session.getDatabase().getMaxOperationMemory(); maxMemory = session.getDatabase().getMaxOperationMemory();
} }
} }
......
...@@ -15,8 +15,8 @@ import java.sql.Timestamp; ...@@ -15,8 +15,8 @@ import java.sql.Timestamp;
import java.text.Collator; import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Properties;
import org.h2.command.Command; import org.h2.command.Command;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
...@@ -862,18 +862,15 @@ public class MetaTable extends Table { ...@@ -862,18 +862,15 @@ public class MetaTable extends Table {
add(rows, "MVCC", database.isMultiVersion() ? "TRUE" : "FALSE"); add(rows, "MVCC", database.isMultiVersion() ? "TRUE" : "FALSE");
add(rows, "QUERY_TIMEOUT", "" + session.getQueryTimeout()); add(rows, "QUERY_TIMEOUT", "" + session.getQueryTimeout());
add(rows, "LOG", "" + database.getLogMode()); add(rows, "LOG", "" + database.getLogMode());
// H2-specific system properties // database settings
ArrayList<String> settingNames = New.arrayList(); ArrayList<String> settingNames = New.arrayList();
Properties p = System.getProperties(); HashMap<String, String> s = database.getSettings().getSettings();
for (Object o : p.keySet()) { for (String k : s.keySet()) {
String s = o == null ? "" : o.toString(); settingNames.add(k);
if (s.startsWith("h2.")) {
settingNames.add(s);
}
} }
Collections.sort(settingNames); Collections.sort(settingNames);
for (String s : settingNames) { for (String k : settingNames) {
add(rows, s, p.getProperty(s)); add(rows, k, s.get(k));
} }
if (database.isPersistent()) { if (database.isPersistent()) {
PageStore store = database.getPageStore(); PageStore store = database.getPageStore();
......
...@@ -382,7 +382,7 @@ public class RegularTable extends TableBase { ...@@ -382,7 +382,7 @@ public class RegularTable extends TableBase {
if (n > 0) { if (n > 0) {
nextAnalyze = n; nextAnalyze = n;
} }
int rows = SysProperties.ANALYZE_SAMPLE; int rows = session.getDatabase().getSettings().analyzeSample;
Analyze.analyzeTable(session, this, rows, false); Analyze.analyzeTable(session, this, rows, false);
} }
......
...@@ -22,7 +22,6 @@ import java.sql.Types; ...@@ -22,7 +22,6 @@ import java.sql.Types;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import org.h2.constant.SysProperties;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.store.FileLock; import org.h2.store.FileLock;
...@@ -108,7 +107,6 @@ public abstract class TestBase { ...@@ -108,7 +107,6 @@ public abstract class TestBase {
public TestBase init(TestAll conf) throws Exception { public TestBase init(TestAll conf) throws Exception {
baseDir = getTestDir(""); baseDir = getTestDir("");
System.setProperty("java.io.tmpdir", TEMP_DIR); System.setProperty("java.io.tmpdir", TEMP_DIR);
SysProperties.defragAlways = conf.defrag;
this.config = conf; this.config = conf;
return this; return this;
} }
...@@ -307,6 +305,10 @@ public abstract class TestBase { ...@@ -307,6 +305,10 @@ public abstract class TestBase {
if (config.cipher != null) { if (config.cipher != null) {
url += ";CIPHER=" + config.cipher; url += ";CIPHER=" + config.cipher;
} }
if (config.defrag) {
url += ";DEFRAG_ALWAYS=TRUE";
}
return "jdbc:h2:" + url; return "jdbc:h2:" + url;
} }
...@@ -1158,12 +1160,14 @@ public abstract class TestBase { ...@@ -1158,12 +1160,14 @@ public abstract class TestBase {
* @throws AssertionError if the databases don't match * @throws AssertionError if the databases don't match
*/ */
protected void assertEqualDatabases(Statement stat1, Statement stat2) throws SQLException { protected void assertEqualDatabases(Statement stat1, Statement stat2) throws SQLException {
if (SysProperties.ANALYZE_AUTO > 0) { ResultSet rs = stat1.executeQuery("select value from information_schema.settings where name='analyzeAuto'");
int analyzeAuto = rs.next() ? rs.getInt(1) : 0;
if (analyzeAuto > 0) {
stat1.execute("analyze"); stat1.execute("analyze");
stat2.execute("analyze"); stat2.execute("analyze");
} }
ResultSet rs1 = stat1.executeQuery("SCRIPT NOPASSWORDS"); ResultSet rs1 = stat1.executeQuery("SCRIPT simple NOPASSWORDS");
ResultSet rs2 = stat2.executeQuery("SCRIPT NOPASSWORDS"); ResultSet rs2 = stat2.executeQuery("SCRIPT simple NOPASSWORDS");
ArrayList<String> list1 = new ArrayList<String>(); ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>(); ArrayList<String> list2 = new ArrayList<String>();
while (rs1.next()) { while (rs1.next()) {
......
...@@ -16,7 +16,6 @@ import java.util.ArrayList; ...@@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Random; import java.util.Random;
import java.util.TreeSet; import java.util.TreeSet;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.New; import org.h2.util.New;
...@@ -85,21 +84,21 @@ public class TestOptimizations extends TestBase { ...@@ -85,21 +84,21 @@ public class TestOptimizations extends TestBase {
} }
private void testAutoAnalyze() throws SQLException { private void testAutoAnalyze() throws SQLException {
int auto = SysProperties.ANALYZE_AUTO;
if (auto == 0) {
return;
}
deleteDb("optimizations"); deleteDb("optimizations");
Connection conn = getConnection("optimizations"); Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table test(id int)"); ResultSet rs = stat.executeQuery("select value from information_schema.settings where name='analyzeAuto'");
stat.execute("create user onlyInsert password ''"); int auto = rs.next() ? rs.getInt(1) : 0;
stat.execute("grant insert on test to onlyInsert"); if (auto != 0) {
Connection conn2 = getConnection("optimizations", "onlyInsert", getPassword("")); stat.execute("create table test(id int)");
Statement stat2 = conn2.createStatement(); stat.execute("create user onlyInsert password ''");
stat2.execute("insert into test select x from system_range(1, " + (auto + 10) + ")"); stat.execute("grant insert on test to onlyInsert");
Connection conn2 = getConnection("optimizations", "onlyInsert", getPassword(""));
Statement stat2 = conn2.createStatement();
stat2.execute("insert into test select x from system_range(1, " + (auto + 10) + ")");
conn2.close();
}
conn.close(); conn.close();
conn2.close();
} }
private void testInAndBetween() throws SQLException { private void testInAndBetween() throws SQLException {
......
...@@ -10,7 +10,6 @@ import java.sql.Connection; ...@@ -10,7 +10,6 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
...@@ -24,16 +23,12 @@ public class TestQueryCache extends TestBase { ...@@ -24,16 +23,12 @@ public class TestQueryCache extends TestBase {
* @param a ignored * @param a ignored
*/ */
public static void main(String... a) throws Exception { public static void main(String... a) throws Exception {
System.setProperty("h2.queryCacheSize", "10");
TestBase.createCaller().init().test(); TestBase.createCaller().init().test();
} }
public void test() throws Exception { public void test() throws Exception {
if (SysProperties.QUERY_CACHE_SIZE <= 0) {
return;
}
deleteDb("queryCache"); deleteDb("queryCache");
Connection conn = getConnection("queryCache"); Connection conn = getConnection("queryCache;QUERY_CACHE_SIZE=10");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table test(id int, name varchar) as select x, space(100) from system_range(1, 1000)"); stat.execute("create table test(id int, name varchar) as select x, space(100) from system_range(1, 1000)");
PreparedStatement prep = conn.prepareStatement("select count(*) from test t1, test t2"); PreparedStatement prep = conn.prepareStatement("select count(*) from test t1, test t2");
......
...@@ -6,14 +6,12 @@ ...@@ -6,14 +6,12 @@
*/ */
package org.h2.test.db; package org.h2.test.db;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
/** /**
* Test the impact of DROP VIEW statements on dependent views. * Test the impact of DROP VIEW statements on dependent views.
...@@ -64,20 +62,23 @@ public class TestViewDropView extends TestBase { ...@@ -64,20 +62,23 @@ public class TestViewDropView extends TestBase {
private void testDropViewDefaultBehaviour() throws SQLException { private void testDropViewDefaultBehaviour() throws SQLException {
createTestData(); createTestData();
ResultSet rs = stat.executeQuery("select value from information_schema.settings where name = 'DROP_RESTRICT'");
rs.next();
boolean dropRestrict = rs.getBoolean(1);
try { try {
// Should fail because have dependencies // Should fail because have dependencies
stat.execute("drop view v1"); stat.execute("drop view v1");
if (SysProperties.DROP_RESTRICT) { if (dropRestrict) {
fail(); fail();
} }
} catch (SQLException e) { } catch (SQLException e) {
if (!SysProperties.DROP_RESTRICT) { if (!dropRestrict) {
assertEquals(ErrorCode.CANNOT_DROP_2, e.getErrorCode()); assertEquals(ErrorCode.CANNOT_DROP_2, e.getErrorCode());
} }
} }
if (SysProperties.DROP_RESTRICT) { if (dropRestrict) {
checkViewRemainsValid(); checkViewRemainsValid();
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论