提交 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
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Various system properties have been replaced with database level settings:
analyzeAuto, analyzeSample, databaseToUpper,...
See the javadoc documentation of DbSettings for details.
<ul><li>Some system properties are not supported any longer, because they can
already be set in the database URL. Those settings are:
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.
</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.
......
......@@ -1644,7 +1644,9 @@ public class Parser {
Expression expr = readExpression();
if (readIf("AS") || currentTokenType == IDENTIFIER) {
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);
}
......@@ -3597,7 +3599,6 @@ public class Parser {
read("REPLACE");
orReplace = true;
}
boolean force = readIf("FORCE");
if (readIf("VIEW")) {
return parseCreateView(force, orReplace);
......
......@@ -6,13 +6,13 @@
*/
package org.h2.constant;
import java.util.Properties;
import java.util.HashMap;
import org.h2.engine.SettingsBase;
/**
* This class contains various database-level settings. To override the
* 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.
* <p>
* Some settings are a last resort and temporary solution to work around a
......@@ -26,7 +26,20 @@ public class DbSettings extends SettingsBase {
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.
* 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
......@@ -34,13 +47,13 @@ public class DbSettings extends SettingsBase {
* starting the database. It is not run on local temporary tables, and
* 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.
*/
public int analyzeSample = get("analyzeSample", 10000);
public final int analyzeSample = get("ANALYZE_SAMPLE", 10000);
/**
* Database setting <code>databaseToUpper</code> (default: true).<br />
......@@ -48,59 +61,72 @@ public class DbSettings extends SettingsBase {
* function, and in the CATALOG column of all database meta data methods.
* 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
* 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).
*/
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
* most databases, the default action is RESTRICT, but for compatibility
* with older versions of H2 the default action is currently CASCADE. This will
* 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 />
* The estimated number of rows in a function table (for example, CSVREAD or
* 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 />
* If set, all functions are stored in a schema. Specially, the SCRIPT 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.
*/
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
* 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
* SELECT statements are cached (excluding UNION and FOR UPDATE statements).
* 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) {
super(p);
private DbSettings(HashMap<String, String> s) {
super(s);
}
/**
......@@ -110,14 +136,14 @@ public class DbSettings extends SettingsBase {
* @param p the properties
* @return the settings
*/
public static DbSettings getInstance(Properties p) {
if (p == null || p.isEmpty()) {
public static DbSettings getInstance(HashMap<String, String> s) {
if (s == null || s.isEmpty()) {
if (defaultSettings == null) {
defaultSettings = new DbSettings(new Properties());
defaultSettings = new DbSettings(new HashMap<String, String>());
}
return defaultSettings;
}
return new DbSettings(p);
return new DbSettings(s);
}
}
......@@ -6,8 +6,6 @@
*/
package org.h2.constant;
import java.sql.ResultSet;
import org.h2.engine.Constants;
import org.h2.message.TraceSystem;
import org.h2.util.MathUtils;
......@@ -43,11 +41,13 @@ public class SysProperties {
* INTERNAL
*/
public static final String H2_MAX_QUERY_TIMEOUT = "h2.maxQueryTimeout";
// TODO DbSettings
/**
* INTERNAL
*/
public static final String H2_COLLATOR_CACHE_SIZE = "h2.collatorCacheSize";
// TODO DbSettings
/**
* System property <code>file.encoding</code> (default: Cp1252).<br />
......@@ -81,38 +81,6 @@ public class SysProperties {
*/
public static final String USER_HOME = getStringSetting("user.home", "");
/**
* System property <code>h2.analyzeSample</code> (default: 10000).<br />
* The default sample size when analyzing a table.
*/
// DbSettings
public static final int ANALYZE_SAMPLE = getIntSetting("h2.analyzeSample", 10000);
/**
* System property <code>h2.analyzeAuto</code> (default: 0).<br />
* 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,
* then ANALYZE will run against each user table after about 1000 changes to
* that table. The time between running ANALYZE doubles each time since
* starting the database. It is not run on local temporary tables, and
* tables that have a trigger on SELECT.
*/
// DbSettings
public static final int ANALYZE_AUTO = getIntSetting("h2.analyzeAuto", 0);
/**
* System property <code>h2.aliasColumnName</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. This setting only affects the default mode.
* <br />
* When using different modes, this feature is disabled for compatibility
* for all databases except MySQL. For MySQL, it is always enabled.
*/
public static final boolean ALIAS_COLUMN_NAME = getBooleanSetting("h2.aliasColumnName", false);
// TODO Mode
/**
* System property <code>h2.allowBigDecimalExtensions</code> (default:
* false).<br />
......@@ -149,22 +117,6 @@ public class SysProperties {
*/
public static final String BIND_ADDRESS = getStringSetting("h2.bindAddress", null);
/**
* System property <code>h2.cacheSizeDefault</code> (default: 16384).<br />
* The default cache size in KB.
*/
public static final int CACHE_SIZE_DEFAULT = getIntSetting("h2.cacheSizeDefault", 16 * 1024);
// TODO constant
/**
* System property <code>h2.cacheTypeDefault</code> (default: LRU).<br />
* How many time the cache size value is divided by two to get the index
* cache size. The index cache size is calculated like this: cacheSize >>
* cacheSizeIndexShift.
*/
public static final String CACHE_TYPE_DEFAULT = getStringSetting("h2.cacheTypeDefault", "LRU");
// TODO constant
/**
* System property <code>h2.check</code> (default: true).<br />
* Assertions in the database engine.
......@@ -197,81 +149,12 @@ public class SysProperties {
*/
public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/");
/**
* System property <code>h2.queryCacheSize</code> (default: 0).<br />
* 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
* parameters match. Only the last returned result per query is cached. Only
* SELECT statements are cached (excluding UNION and FOR UPDATE statements).
* This works for both statements and prepared statement.
*/
// DbSettings
public static final int QUERY_CACHE_SIZE = getIntSetting("h2.queryCacheSize", 0);
/**
* System property <code>h2.consoleStream</code> (default: true).<br />
* H2 Console: stream query results.
*/
public static final boolean CONSOLE_STREAM = getBooleanSetting("h2.consoleStream", true);
/**
* System property <code>h2.databaseToUpper</code> (default: true).<br />
* Database short names are converted to uppercase for the DATABASE()
* function, and in the CATALOG column of all database meta data methods.
* Setting this to "false" is experimental.
*/
// DbSettings
public static final boolean DATABASE_TO_UPPER = getBooleanSetting("h2.databaseToUpper", true);
/**
* System property <code>h2.defaultEscape</code> (default: \).<br />
* The default escape character for LIKE comparisons. To select no escape
* character, use an empty string.
*/
// DbSettings
public static final String DEFAULT_ESCAPE = getStringSetting("h2.defaultEscape", "\\");
/**
* System property <code>h2.defaultMaxOperationMemory</code> (default:
* 100000).<br />
* The default for the setting MAX_OPERATION_MEMORY.
*/
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
// TODO constant
/**
* System property <code>h2.defaultMaxLengthInplaceLob</code>
* (default: 4096).<br />
* The default maximum length of an LOB that is stored in the database file.
*/
public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB = getIntSetting("h2.defaultMaxLengthInplaceLob", 4096);
// TODO constant
/**
* System property <code>h2.defaultMaxLengthInplaceLob2</code>
* (default: 128).<br />
* 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 = getIntSetting("h2.defaultMaxLengthInplaceLob2", 128);
// TODO constant
/**
* System property <code>h2.defaultResultSetConcurrency</code> (default:
* ResultSet.CONCUR_READ_ONLY).<br />
* The default result set concurrency for statements created with
* Connection.createStatement() or prepareStatement(String sql).
*/
public static final int DEFAULT_RESULT_SET_CONCURRENCY = getIntSetting("h2.defaultResultSetConcurrency", ResultSet.CONCUR_READ_ONLY);
// TODO constant
/**
* System property <code>h2.defragAlways</code> (default: false).<br />
* Each time the database is closed, it is fully defragmented (SHUTDOWN DEFRAG).
*/
public static boolean defragAlways = getBooleanSetting("h2.defragAlways", false);
// DbSettings
/**
* System property <code>h2.dataSourceTraceLevel</code> (default: 1).<br />
* The trace level of the data source implementation. Default is 1 for
......@@ -279,20 +162,6 @@ public class SysProperties {
*/
public static final int DATASOURCE_TRACE_LEVEL = getIntSetting("h2.dataSourceTraceLevel", TraceSystem.ERROR);
/**
* System property <code>h2.defaultMaxMemoryUndo</code> (default: 50000).<br />
* The default value for the MAX_MEMORY_UNDO setting.
*/
public static final int DEFAULT_MAX_MEMORY_UNDO = getIntSetting("h2.defaultMaxMemoryUndo", 50000);
// TODO constant
/**
* System property <code>h2.defaultLockMode</code> (default: 3).<br />
* The default value for the LOCK_MODE setting.
*/
public static final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED);
// TODO constant
/**
* System property <code>h2.delayWrongPasswordMin</code> (default: 250).<br />
* The minimum delay in milliseconds before an exception is thrown for using
......@@ -312,62 +181,12 @@ public class SysProperties {
*/
public static final int DELAY_WRONG_PASSWORD_MAX = getIntSetting("h2.delayWrongPasswordMax", 4000);
/**
* System property <code>h2.dropRestrict</code> (default: false).<br />
* Whether the default action for DROP TABLE and DROP VIEW is RESTRICT. For
* most databases, the default action is RESTRICT, but for compatibility
* with older versions of H2 the default action is currently CASCADE. This will
* change in a future version of H2.
*/
// DbSettings
public static final boolean DROP_RESTRICT = getBooleanSetting("h2.dropRestrict", false);
/**
* System property <code>h2.estimatedFunctionTableRows</code> (default:
* 1000).<br />
* The estimated number of rows in a function table (for example, CSVREAD or
* FTL_SEARCH). This value is used by the optimizer.
*/
// DbSettings
public static final int ESTIMATED_FUNCTION_TABLE_ROWS = getIntSetting("h2.estimatedFunctionTableRows", 1000);
/**
* System property <code>h2.emptyPassword</code> (default: true).<br />
* Don't use a secure hash if the user name and password are empty or not set.
*/
public static final boolean EMPTY_PASSWORD = getBooleanSetting("h2.emptyPassword", true);
/**
* System property <code>h2.functionsInSchema</code> (default:
* false).<br />
* If set, all functions are stored in a schema. Specially, the SCRIPT 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.
*/
// DbSettings
public static final boolean FUNCTIONS_IN_SCHEMA = getBooleanSetting("h2.functionsInSchema", false);
/**
* System property <code>h2.identifiersToUpper</code> (default: true).<br />
* Unquoted identifiers in SQL statements are case insensitive and converted
* to uppercase.
*/
// DbSettings
public static final boolean IDENTIFIERS_TO_UPPER = getBooleanSetting("h2.identifiersToUpper", true);
/**
* 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 static final int LARGE_RESULT_BUFFER_SIZE = getIntSetting("h2.largeResultBufferSize", 4 * 1024);
/**
* System property <code>h2.largeTransactions</code> (default: false).<br />
* Support very large transactions
*/
public static final boolean LARGE_TRANSACTIONS = getBooleanSetting("h2.largeTransactions", false);
/**
* System property <code>h2.lobCloseBetweenReads</code> (default: false).<br />
* Close LOB files between read operations.
......@@ -385,6 +204,7 @@ public class SysProperties {
* Store LOB files in the database.
*/
public static final boolean LOB_IN_DATABASE = getBooleanSetting("h2.lobInDatabase", false);
// DbSettings
/**
* System property <code>h2.lobClientMaxSizeMemory</code> (default: 65536).<br />
......@@ -412,12 +232,14 @@ public class SysProperties {
* The maximum number of pages to move when closing a database.
*/
public static final int MAX_COMPACT_COUNT = getIntSetting("h2.maxCompactCount", Integer.MAX_VALUE);
// DbSettings
/**
* System property <code>h2.maxCompactTime</code> (default: 200).<br />
* The maximum time in milliseconds used to compact a database when closing.
*/
public static final int MAX_COMPACT_TIME = getIntSetting("h2.maxCompactTime", 200);
// DbSettings
/**
* System property <code>h2.maxFileRetry</code> (default: 16).<br />
......@@ -437,6 +259,7 @@ public class SysProperties {
* used.
*/
public static final int MAX_MEMORY_ROWS_DISTINCT = getIntSetting("h2.maxMemoryRowsDistinct", Integer.MAX_VALUE);
// DbSettings
/**
* System property <code>h2.maxReconnect</code> (default: 3).<br />
......@@ -449,6 +272,7 @@ public class SysProperties {
* The maximum size of a LOB value that is written as data to the trace system.
*/
public static final long MAX_TRACE_DATA_LENGTH = getIntSetting("h2.maxTraceDataLength", 65535);
// DbSettings
/**
* System property <code>h2.minColumnNameMap</code> (default: 3).<br />
......@@ -462,12 +286,14 @@ public class SysProperties {
* The minimum write delay that causes commits to be delayed.
*/
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
// DbSettings
/**
* System property <code>h2.nestedJoins</code> (default: false).<br />
* Whether nested joins should be supported.
*/
public static final boolean NESTED_JOINS = getBooleanSetting("h2.nestedJoins", false);
// DbSettings
/**
* System property <code>h2.nioLoadMapped</code> (default: false).<br />
......@@ -513,6 +339,7 @@ public class SysProperties {
* This also applies to create table as select.
*/
public static boolean optimizeInsertFromSelect = getBooleanSetting("h2.optimizeInsertFromSelect", false);
// DbSettings
/**
* System property <code>h2.optimizeDistinct</code> (default: true).<br />
......@@ -527,6 +354,7 @@ public class SysProperties {
* </ul>
*/
public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true);
// DbSettings
/**
* System property <code>h2.optimizeUpdate</code> (default: true).<br />
......@@ -534,6 +362,7 @@ public class SysProperties {
* page unless necessary.
*/
public static final boolean OPTIMIZE_UPDATE = getBooleanSetting("h2.optimizeUpdate", true);
// DbSettings
/**
* System property <code>h2.optimizeEvaluatableSubqueries</code> (default:
......@@ -541,6 +370,7 @@ public class SysProperties {
* Optimize subqueries that are not dependent on the outer query.
*/
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
// DbSettings
/**
* System property <code>h2.optimizeInList</code> (default: true).<br />
......@@ -548,24 +378,28 @@ public class SysProperties {
* optimization for SELECT, DELETE, and UPDATE.
*/
public static final boolean OPTIMIZE_IN_LIST = getBooleanSetting("h2.optimizeInList", true);
// DbSettings
/**
* System property <code>h2.optimizeIsNull</code> (default: false).<br />
* Use an index for condition of the form columnName IS NULL.
*/
public static final boolean OPTIMIZE_IS_NULL = getBooleanSetting("h2.optimizeIsNull", true);
// DbSettings
/**
* System property <code>h2.optimizeOr</code> (default: false).<br />
* Convert (C=? OR C=?) to (C IN(?, ?)).
*/
public static final boolean OPTIMIZE_OR = getBooleanSetting("h2.optimizeOr", false);
// DbSettings
/**
* System property <code>h2.optimizeSubqueryCache</code> (default: true).<br />
* Cache subquery results.
*/
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
// DbSettings
/**
* System property <code>h2.optimizeTwoEquals</code> (default: true).<br />
......@@ -573,24 +407,28 @@ public class SysProperties {
* added so an index on A can be used.
*/
public static final boolean OPTIMIZE_TWO_EQUALS = getBooleanSetting("h2.optimizeTwoEquals", true);
// DbSettings
/**
* System property <code>h2.pageSize</code> (default: 2048).<br />
* The page size to use for new databases.
*/
public static final int PAGE_SIZE = getIntSetting("h2.pageSize", 2048);
// DbSettings (already!)
/**
* System property <code>h2.pageStoreTrim</code> (default: true).<br />
* Trim the database size when closing.
*/
public static final boolean PAGE_STORE_TRIM = getBooleanSetting("h2.pageStoreTrim", true);
// DbSettings
/**
* System property <code>h2.pageStoreInternalCount</code> (default: false).<br />
* Update the row counts on a node level.
*/
public static final boolean PAGE_STORE_INTERNAL_COUNT = getBooleanSetting("h2.pageStoreInternalCount", false);
// DbSettings
/**
* System property <code>h2.pgClientEncoding</code> (default: UTF-8).<br />
......@@ -610,6 +448,7 @@ public class SysProperties {
* Always recompile prepared statements.
*/
public static final boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false);
// DbSettings
/**
* System property <code>h2.reconnectCheckDelay</code> (default: 200).<br />
......@@ -619,12 +458,7 @@ public class SysProperties {
* milliseconds before updating the database.
*/
public static final int RECONNECT_CHECK_DELAY = getIntSetting("h2.reconnectCheckDelay", 200);
/**
* System property <code>h2.redoBufferSize</code> (default: 262144).<br />
* Size of the redo buffer (used at startup when recovering).
*/
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
// DbSettings
/**
* System property <code>h2.returnLobObjects</code> (default: true).<br />
......@@ -645,6 +479,7 @@ public class SysProperties {
* If set, SELECT .. FOR UPDATE queries lock the rows when using MVCC.
*/
public static final boolean SELECT_FOR_UPDATE_MVCC = getBooleanSetting("h2.selectForUpdateMvcc", false);
// DbSettings
/**
* System property <code>h2.serverCachedObjects</code> (default: 64).<br />
......@@ -667,6 +502,7 @@ public class SysProperties {
* database.
*/
public static final boolean SHARE_LINKED_CONNECTIONS = getBooleanSetting("h2.shareLinkedConnections", true);
// DbSettings
/**
* System property <code>h2.socketConnectRetry</code> (default: 16).<br />
......
......@@ -9,6 +9,7 @@ package org.h2.engine;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import org.h2.command.dml.SetTypes;
......@@ -563,18 +564,22 @@ public class ConnectionInfo implements Cloneable {
public DbSettings getDbSettings() {
DbSettings defaultSettings = DbSettings.getInstance(null);
Properties p = null;
for (Object s : prop.keySet()) {
String k = s.toString();
if (!isKnownSetting(k) && defaultSettings.containsKey(k)) {
if (p == null) {
p = new Properties();
HashMap<String, String> s = null;
ArrayList<String> remove = New.arrayList();
for (Object k : prop.keySet()) {
String key = k.toString();
if (!isKnownSetting(key) && defaultSettings.containsKey(key)) {
if (s == null) {
s = New.hashMap();
}
p.put(k, prop.get(k));
prop.remove(k);
s.put(key, prop.getProperty(key));
remove.add(key);
}
}
return DbSettings.getInstance(p);
for (String r : remove) {
prop.remove(r);
}
return DbSettings.getInstance(s);
}
}
......@@ -6,6 +6,9 @@
*/
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.
*/
......@@ -397,6 +400,50 @@ public class Constants {
*/
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() {
// utility class
}
......
......@@ -128,8 +128,8 @@ public class Database implements DataHandler {
private int writeDelay = Constants.DEFAULT_WRITE_DELAY;
private DatabaseEventListener eventListener;
private int maxMemoryRows = Constants.DEFAULT_MAX_MEMORY_ROWS;
private int maxMemoryUndo = SysProperties.DEFAULT_MAX_MEMORY_UNDO;
private int lockMode = SysProperties.DEFAULT_LOCK_MODE;
private int maxMemoryUndo = Constants.DEFAULT_MAX_MEMORY_UNDO;
private int lockMode = Constants.DEFAULT_LOCK_MODE;
private int maxLengthInplaceLob;
private int allowLiterals = Constants.ALLOW_LITERALS_ALL;
......@@ -148,7 +148,7 @@ public class Database implements DataHandler {
private DatabaseCloser closeOnExit;
private Mode mode = Mode.getInstance(Mode.REGULAR);
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 boolean autoServerMode;
private Server server;
......@@ -180,12 +180,12 @@ public class Database implements DataHandler {
this.databaseName = name;
this.databaseShortName = parseDatabaseShortName();
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;
String lockMethodName = ci.getProperty("FILE_LOCK", null);
this.accessModeData = ci.getProperty("ACCESS_MODE_DATA", "rw").toLowerCase();
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);
if ("r".equals(accessModeData)) {
readOnly = true;
......@@ -202,7 +202,7 @@ public class Database implements DataHandler {
int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE);
int traceLevelSystemOut = ci.getIntProperty(SetTypes.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);
}
......
......@@ -7,8 +7,6 @@
package org.h2.engine;
import java.util.HashMap;
import org.h2.constant.SysProperties;
import org.h2.util.New;
import org.h2.util.StringUtils;
......@@ -115,7 +113,6 @@ public class Mode {
static {
Mode mode = new Mode(REGULAR);
mode.aliasColumnName = SysProperties.ALIAS_COLUMN_NAME;
mode.nullConcatIsNull = true;
add(mode);
......
......@@ -6,7 +6,7 @@
*/
package org.h2.engine;
import java.util.Properties;
import java.util.HashMap;
import org.h2.constant.ErrorCode;
import org.h2.message.DbException;
......@@ -15,10 +15,10 @@ import org.h2.message.DbException;
*/
public class SettingsBase {
private Properties properties;
private HashMap<String, String> settings;
protected SettingsBase(Properties p) {
this.properties = p;
protected SettingsBase(HashMap<String, String> s) {
this.settings = s;
}
protected boolean get(String key, boolean defaultValue) {
......@@ -40,20 +40,35 @@ public class SettingsBase {
}
protected String get(String key, String defaultValue) {
String keyUpper = key.toUpperCase();
String v = properties.getProperty(keyUpper);
StringBuilder buff = new StringBuilder("h2.");
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) {
v = System.getProperty("h2." + key);
v = System.getProperty(sysProperty);
}
if (v == null) {
properties.put(keyUpper, defaultValue);
settings.put(key, defaultValue);
v = defaultValue;
}
return v;
}
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;
* Each session keeps a undo log if rollback is required.
*/
public class UndoLog {
private Database database;
private ArrayList<Long> storedEntriesPos = New.arrayList();
private ArrayList<UndoLogRecord> records = New.arrayList();
......@@ -27,6 +28,7 @@ public class UndoLog {
private int memoryUndo;
private int storedEntries;
private HashMap<Integer, Table> tables;
private boolean largeTransactions;
/**
* Create a new undo log for the given session.
......@@ -35,6 +37,7 @@ public class UndoLog {
*/
public UndoLog(Session session) {
this.database = session.getDatabase();
largeTransactions = database.getSettings().largeTransactions;
}
/**
......@@ -43,7 +46,7 @@ public class UndoLog {
* @return the number of rows
*/
public int size() {
if (SysProperties.LARGE_TRANSACTIONS) {
if (largeTransactions) {
return storedEntries + records.size();
}
if (SysProperties.CHECK && memoryUndo > records.size()) {
......@@ -75,7 +78,7 @@ public class UndoLog {
*/
public UndoLogRecord getLast() {
int i = records.size() - 1;
if (SysProperties.LARGE_TRANSACTIONS) {
if (largeTransactions) {
if (i < 0 && storedEntries > 0) {
int last = storedEntriesPos.size() - 1;
long pos = storedEntriesPos.get(last);
......@@ -151,7 +154,7 @@ public class UndoLog {
*/
public void add(UndoLogRecord entry) {
records.add(entry);
if (SysProperties.LARGE_TRANSACTIONS) {
if (largeTransactions) {
memoryUndo++;
if (memoryUndo > database.getMaxMemoryUndo() && database.isPersistent() && !database.isMultiVersion()) {
if (file == null) {
......
......@@ -69,10 +69,7 @@ public class UndoLogRecord {
* @return if it can be stored
*/
boolean canStore() {
if (SysProperties.LARGE_TRANSACTIONS) {
// actually the method is not called in this case
return true;
}
// if large transactions are enabled, this method is not called
if (table.getUniqueIndex() != null) {
return true;
}
......@@ -145,9 +142,7 @@ public class UndoLogRecord {
buff.writeInt(0);
buff.writeInt(operation);
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.writeInt(row.getSessionId());
int count = row.getColumnCount();
......@@ -222,9 +217,7 @@ public class UndoLogRecord {
private void load(Data buff, UndoLog log) {
operation = (short) buff.readInt();
boolean deleted = buff.readByte() == 1;
if (SysProperties.LARGE_TRANSACTIONS) {
table = log.getTable(buff.readInt());
}
table = log.getTable(buff.readInt());
long key = buff.readLong();
int sessionId = buff.readInt();
int columnCount = buff.readInt();
......
......@@ -162,7 +162,7 @@ public class JdbcConnection extends TraceObject implements Connection {
debugCodeAssign("Statement", TraceObject.STATEMENT, id, "createStatement()");
}
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) {
throw logAndConvert(e);
}
......@@ -230,7 +230,7 @@ public class JdbcConnection extends TraceObject implements Connection {
}
checkClosed();
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) {
throw logAndConvert(e);
}
......@@ -251,7 +251,7 @@ public class JdbcConnection extends TraceObject implements Connection {
}
checkClosed();
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) {
throw logAndConvert(e);
}
......@@ -792,7 +792,7 @@ public class JdbcConnection extends TraceObject implements Connection {
}
checkClosed();
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) {
throw logAndConvert(e);
}
......
......@@ -31,6 +31,7 @@ class ResultDiskBuffer implements ResultExternal {
private ResultDiskTape mainTape;
private SortOrder sort;
private int columnCount;
private final int maxBufferSize;
/**
* Represents a virtual disk tape for the merge sort algorithm.
......@@ -74,6 +75,7 @@ class ResultDiskBuffer implements ResultExternal {
mainTape = new ResultDiskTape();
mainTape.pos = FileStore.HEADER_LENGTH;
}
this.maxBufferSize = db.getSettings().largeResultBufferSize;
}
public void addRows(ArrayList<Value[]> rows) {
......@@ -84,7 +86,6 @@ class ResultDiskBuffer implements ResultExternal {
long start = file.getFilePointer();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int bufferLen = 0;
int maxBufferSize = SysProperties.LARGE_RESULT_BUFFER_SIZE;
for (Value[] row : rows) {
buff.reset();
buff.writeInt(0);
......
......@@ -40,7 +40,7 @@ public class RowList {
*/
public RowList(Session session) {
this.session = session;
if (SysProperties.DEFAULT_MAX_OPERATION_MEMORY > 0 && session.getDatabase().isPersistent()) {
if (session.getDatabase().isPersistent()) {
maxMemory = session.getDatabase().getMaxOperationMemory();
}
}
......
......@@ -15,8 +15,8 @@ import java.sql.Timestamp;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Properties;
import org.h2.command.Command;
import org.h2.constant.SysProperties;
import org.h2.constraint.Constraint;
......@@ -862,18 +862,15 @@ public class MetaTable extends Table {
add(rows, "MVCC", database.isMultiVersion() ? "TRUE" : "FALSE");
add(rows, "QUERY_TIMEOUT", "" + session.getQueryTimeout());
add(rows, "LOG", "" + database.getLogMode());
// H2-specific system properties
// database settings
ArrayList<String> settingNames = New.arrayList();
Properties p = System.getProperties();
for (Object o : p.keySet()) {
String s = o == null ? "" : o.toString();
if (s.startsWith("h2.")) {
settingNames.add(s);
}
HashMap<String, String> s = database.getSettings().getSettings();
for (String k : s.keySet()) {
settingNames.add(k);
}
Collections.sort(settingNames);
for (String s : settingNames) {
add(rows, s, p.getProperty(s));
for (String k : settingNames) {
add(rows, k, s.get(k));
}
if (database.isPersistent()) {
PageStore store = database.getPageStore();
......
......@@ -382,7 +382,7 @@ public class RegularTable extends TableBase {
if (n > 0) {
nextAnalyze = n;
}
int rows = SysProperties.ANALYZE_SAMPLE;
int rows = session.getDatabase().getSettings().analyzeSample;
Analyze.analyzeTable(session, this, rows, false);
}
......
......@@ -22,7 +22,6 @@ import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import org.h2.constant.SysProperties;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.TraceSystem;
import org.h2.store.FileLock;
......@@ -108,7 +107,6 @@ public abstract class TestBase {
public TestBase init(TestAll conf) throws Exception {
baseDir = getTestDir("");
System.setProperty("java.io.tmpdir", TEMP_DIR);
SysProperties.defragAlways = conf.defrag;
this.config = conf;
return this;
}
......@@ -307,6 +305,10 @@ public abstract class TestBase {
if (config.cipher != null) {
url += ";CIPHER=" + config.cipher;
}
if (config.defrag) {
url += ";DEFRAG_ALWAYS=TRUE";
}
return "jdbc:h2:" + url;
}
......@@ -1158,12 +1160,14 @@ public abstract class TestBase {
* @throws AssertionError if the databases don't match
*/
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");
stat2.execute("analyze");
}
ResultSet rs1 = stat1.executeQuery("SCRIPT NOPASSWORDS");
ResultSet rs2 = stat2.executeQuery("SCRIPT NOPASSWORDS");
ResultSet rs1 = stat1.executeQuery("SCRIPT simple NOPASSWORDS");
ResultSet rs2 = stat2.executeQuery("SCRIPT simple NOPASSWORDS");
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
while (rs1.next()) {
......
......@@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.TreeSet;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase;
import org.h2.tools.SimpleResultSet;
import org.h2.util.New;
......@@ -85,21 +84,21 @@ public class TestOptimizations extends TestBase {
}
private void testAutoAnalyze() throws SQLException {
int auto = SysProperties.ANALYZE_AUTO;
if (auto == 0) {
return;
}
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
stat.execute("create table test(id int)");
stat.execute("create user onlyInsert password ''");
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) + ")");
ResultSet rs = stat.executeQuery("select value from information_schema.settings where name='analyzeAuto'");
int auto = rs.next() ? rs.getInt(1) : 0;
if (auto != 0) {
stat.execute("create table test(id int)");
stat.execute("create user onlyInsert password ''");
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();
conn2.close();
}
private void testInAndBetween() throws SQLException {
......
......@@ -10,7 +10,6 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase;
/**
......@@ -24,16 +23,12 @@ public class TestQueryCache extends TestBase {
* @param a ignored
*/
public static void main(String... a) throws Exception {
System.setProperty("h2.queryCacheSize", "10");
TestBase.createCaller().init().test();
}
public void test() throws Exception {
if (SysProperties.QUERY_CACHE_SIZE <= 0) {
return;
}
deleteDb("queryCache");
Connection conn = getConnection("queryCache");
Connection conn = getConnection("queryCache;QUERY_CACHE_SIZE=10");
Statement stat = conn.createStatement();
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");
......
......@@ -6,14 +6,12 @@
*/
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.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
/**
* Test the impact of DROP VIEW statements on dependent views.
......@@ -64,20 +62,23 @@ public class TestViewDropView extends TestBase {
private void testDropViewDefaultBehaviour() throws SQLException {
createTestData();
ResultSet rs = stat.executeQuery("select value from information_schema.settings where name = 'DROP_RESTRICT'");
rs.next();
boolean dropRestrict = rs.getBoolean(1);
try {
// Should fail because have dependencies
stat.execute("drop view v1");
if (SysProperties.DROP_RESTRICT) {
if (dropRestrict) {
fail();
}
} catch (SQLException e) {
if (!SysProperties.DROP_RESTRICT) {
if (!dropRestrict) {
assertEquals(ErrorCode.CANNOT_DROP_2, e.getErrorCode());
}
}
if (SysProperties.DROP_RESTRICT) {
if (dropRestrict) {
checkViewRemainsValid();
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论