提交 49d28824 authored 作者: Thomas Mueller's avatar Thomas Mueller

stricter checkstyle settings

上级 145ab625
......@@ -19,13 +19,29 @@ Change Log
<ul>
<li>Infinite numbers in SQL script are listed as POWER(0, -1)), negative
infinite as (-POWER(0, -1)), and NaN (not a number) as SQRT(-1).
</li><li>Comparison did not work correctly when using the special
double and float value 'NaN' (not a number).
</li><li>The special double and float values 'NaN' (not a number) did not work
correctly when sorting or comparing.
</li><li>SET QUERY_TIMEOUT and Statement.setQueryTimeout no longer commits
a transaction. The same applies to SET @VARIABLE, SET LOCK_TIMEOUT,
SET TRACE_LEVEL_*, SET THROTTLE, and SET PATH.
</li><li>ParameterMetaData now also returns the right data type for most
conditions, as in WHERE ID=?.
</li><li>Negative scale values for DECIMAL or NUMBER columns are now supported
in regular tables and in linked tables.
</li><li>MySQL compatibility: auto_increment column are no longer automatically
converted to primary key columns.
</li><li>PostgreSQL compatibility: support for BOOL_OR and BOOL_AND
aggregate functions.
</li><li>The fulltext search did not support CLOB data types. Fixed.
</li><li>The table SYSTEM_RANGE now supports expressions and parameters.
</li><li>If the drive with the database files was disconnected or unmounted
while writing, sometimes a stack overflow exception was thrown
instead of a IO exception.
</li><li>The H2 Console could not be shut down from within the tool if the
browser supports keepAlive (most browsers do).
</li><li>If the password was passed as a char array, it was kept in an internal buffer
longer than required. Theoretically the password could have been stolen
if the main memory was swapped to disk before the garbage collection was run.
</li></ul>
<h2>Version 1.0.72 (2008-05-10)</h2>
......
......@@ -263,6 +263,11 @@ PolePosition</a><br />
Open source database benchmark.
</p>
<p><a href="http://patir.rubyforge.org/rutema/index.html">
Rutema</a><br />
Rutema is a test execution and management tool for heterogeneous development environments written in Ruby.
</p>
<p><a href="http://scriptella.javaforge.com">
Scriptella</a><br />
ETL (Extract-Transform-Load) and script execution tool.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -69,7 +69,19 @@
<property name="severity" value="ignore"/>
</module>
<module name="UpperEll"/>
<module name="JavadocType"/>
<module name="EmptyForInitializerPad"/>
<module name="CovariantEquals"/>
<module name="DefaultComesLast"/>
<module name="DeclarationOrder"/>
<module name="ExplicitInitialization"/>
<module name="FallThrough"/>
<module name="IllegalThrows"/>
<module name="SuperClone"/>
<module name="UnnecessaryParentheses"/>
<module name="TrailingComment"/>
</module>
<module name="NewlineAtEndOfFile"/>
<module name="Translation"/>
<module name="PackageHtml"/>
</module>
......@@ -42,6 +42,10 @@ public class Bnf {
private Rule lastRepeat;
private ArrayList statements;
private String currentTopic;
Bnf() {
random.setSeed(1);
}
/**
* Create an instance using the grammar specified in the CSV file.
......@@ -59,10 +63,6 @@ public class Bnf {
return bnf;
}
Bnf() {
random.setSeed(1);
}
void addFixedRule(String name, int fixedType) {
Rule rule = new RuleFixed(fixedType);
addRule(name, "Fixed", rule);
......
......@@ -18,6 +18,21 @@ public class RuleList implements Rule {
private ArrayList list;
private boolean mapSet;
RuleList(Rule first, Rule next, boolean or) {
list = new ArrayList();
if (first instanceof RuleList && ((RuleList) first).or == or) {
list.addAll(((RuleList) first).list);
} else {
list.add(first);
}
if (next instanceof RuleList && ((RuleList) next).or == or) {
list.addAll(((RuleList) next).list);
} else {
list.add(next);
}
this.or = or;
}
public String toString() {
StringBuffer buff = new StringBuffer();
if (or) {
......@@ -40,21 +55,6 @@ public class RuleList implements Rule {
return buff.toString();
}
RuleList(Rule first, Rule next, boolean or) {
list = new ArrayList();
if (first instanceof RuleList && ((RuleList) first).or == or) {
list.addAll(((RuleList) first).list);
} else {
list.add(first);
}
if (next instanceof RuleList && ((RuleList) next).or == or) {
list.addAll(((RuleList) next).list);
} else {
list.add(next);
}
this.or = or;
}
public String random(Bnf config, int level) {
if (or) {
if (level > 10) {
......@@ -75,7 +75,7 @@ public class RuleList implements Rule {
}
private Rule get(int idx) {
return ((Rule) list.get(idx));
return (Rule) list.get(idx);
}
public String name() {
......
......@@ -45,6 +45,12 @@ public abstract class Command implements CommandInterface {
private volatile boolean cancel;
private final String sql;
public Command(Parser parser, String sql) {
this.session = parser.getSession();
this.sql = sql;
trace = session.getDatabase().getTrace(Trace.COMMAND);
}
/**
* Check if this command is transactional.
......@@ -82,12 +88,6 @@ public abstract class Command implements CommandInterface {
*/
public abstract LocalResult queryMeta() throws SQLException;
public Command(Parser parser, String sql) {
this.session = parser.getSession();
this.sql = sql;
trace = session.getDatabase().getTrace(Trace.COMMAND);
}
/**
* Execute an updating statement, if this is possible.
*
......
......@@ -56,6 +56,16 @@ public abstract class Prepared {
private Command command;
private int objectId;
private int currentRowNumber;
/**
* Create a new object.
*
* @param session the session
*/
public Prepared(Session session) {
this.session = session;
modificationMetaId = session.getDatabase().getModificationMetaId();
}
/**
* Check if this command is transactional.
......@@ -81,16 +91,6 @@ public abstract class Prepared {
return false;
}
/**
* Create a new object.
*
* @param session the session
*/
public Prepared(Session session) {
this.session = session;
modificationMetaId = session.getDatabase().getModificationMetaId();
}
/**
* Check if the statement needs to be re-compiled.
*
......
......@@ -54,6 +54,12 @@ public class Optimizer {
private double cost;
private Random random;
Optimizer(TableFilter[] filters, Expression condition, Session session) {
this.filters = filters;
this.condition = condition;
this.session = session;
}
private int getMaxBruteForceFilters(int filterCount) {
int i = 0, j = filterCount, total = filterCount;
while (j > 0 && total < MAX_BRUTE_FORCE) {
......@@ -64,12 +70,6 @@ public class Optimizer {
return i;
}
Optimizer(TableFilter[] filters, Expression condition, Session session) {
this.filters = filters;
this.condition = condition;
this.session = session;
}
private void calculateBestPlan() throws SQLException {
start = System.currentTimeMillis();
cost = -1;
......
......@@ -53,6 +53,10 @@ public abstract class Query extends Prepared {
private long lastEvaluated;
private LocalResult lastResult;
private Value[] lastParameters;
public Query(Session session) {
super(session);
}
/**
* Execute the query without checking the cache.
......@@ -170,10 +174,6 @@ public abstract class Query extends Prepared {
*/
public abstract void updateAggregate(Session session) throws SQLException;
public Query(Session session) {
super(session);
}
public boolean isQuery() {
return true;
}
......@@ -279,8 +279,10 @@ public abstract class Query extends Prepared {
Expression ec2 = ec.getNonAliasExpression();
if (ec2 instanceof ExpressionColumn) {
ExpressionColumn c2 = (ExpressionColumn) ec2;
String ta = exprCol.getSQL(); // exprCol.getTableAlias();
String tb = c2.getSQL(); // getTableAlias();
String ta = exprCol.getSQL();
// exprCol.getTableAlias();
String tb = c2.getSQL();
// getTableAlias();
found = col.equals(c2.getColumnName());
if (ta == null || tb == null) {
if (ta != tb) {
......
......@@ -65,6 +65,7 @@ import org.h2.value.ValueString;
*/
public class ScriptCommand extends ScriptBase {
private static final String TEMP_LOB_FILENAME = "system_temp_lob.db";
private boolean passwords;
private boolean data;
private boolean settings;
......@@ -76,7 +77,6 @@ public class ScriptCommand extends ScriptBase {
private boolean tempLobTableCreated;
private int nextLobId;
private int lobBlockSize = Constants.IO_BUFFER_SIZE;
private static final String TEMP_LOB_FILENAME = "system_temp_lob.db";
public ScriptCommand(Session session) {
super(session);
......
......@@ -1022,6 +1022,7 @@ public class Select extends Query {
}
break;
}
default:
}
visitor.incrementQueryLevel(1);
boolean result = true;
......
......@@ -61,6 +61,7 @@ public class Set extends Prepared {
case SetTypes.SCHEMA:
case SetTypes.SCHEMA_SEARCH_PATH:
return true;
default:
}
return false;
}
......
......@@ -233,6 +233,10 @@ public class SetTypes {
setType(VARIABLE, "@");
setType(QUERY_TIMEOUT, "QUERY_TIMEOUT");
}
private SetTypes() {
// utility class
}
private static void setType(int type, String name) {
while (types.size() <= type) {
......
......@@ -38,6 +38,14 @@ package org.h2.compress;
* LZF is optimized for speed.
*/
public class CompressLZF implements Compressor {
private static final int HASH_SIZE = 1 << 14;
private static final int[] EMPTY = new int[HASH_SIZE];
private static final int MAX_LITERAL = 1 << 5;
private static final int MAX_OFF = 1 << 13;
private static final int MAX_REF = (1 << 8) + (1 << 3);
private int[] hashTab;
public void setOptions(String options) {
// nothing to do
......@@ -47,11 +55,6 @@ public class CompressLZF implements Compressor {
return Compressor.LZF;
}
private static final int HASH_SIZE = (1 << 14);
private static final int MAX_LITERAL = (1 << 5);
private static final int MAX_OFF = (1 << 13);
private static final int MAX_REF = ((1 << 8) + (1 << 3));
int first(byte[] in, int inPos) {
return (in[inPos] << 8) + (in[inPos + 1] & 255);
}
......@@ -65,15 +68,12 @@ public class CompressLZF implements Compressor {
return ((h * 184117) >> 9) & (HASH_SIZE - 1);
}
private int[] hashTab;
private static int[] empty = new int[HASH_SIZE];
public int compress(byte[] in, int inLen, byte[] out, int outPos) {
int inPos = 0;
if (hashTab == null) {
hashTab = new int[HASH_SIZE];
} else {
System.arraycopy(empty, 0, hashTab, 0, HASH_SIZE);
System.arraycopy(EMPTY, 0, hashTab, 0, HASH_SIZE);
}
int literals = 0;
int hash = first(in, inPos);
......
......@@ -1785,6 +1785,10 @@ public class ErrorCode {
public static final int CAN_ONLY_ASSIGN_TO_VARIABLE_1 = 90137;
// next is 90108
private ErrorCode() {
// utility class
}
/**
* INTERNAL
......
......@@ -456,6 +456,10 @@ public class SysProperties {
private static String baseDir = getStringSetting("h2.baseDir", null);
private SysProperties() {
// utility class
}
private static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = getProperty(name);
if (s != null) {
......
......@@ -49,6 +49,12 @@ public abstract class Constraint extends SchemaObjectBase implements Comparable
*/
protected Table table;
public Constraint(Schema schema, int id, String name, Table table) {
initSchemaObjectBase(schema, id, name, Trace.CONSTRAINT);
this.table = table;
this.setTemporary(table.getTemporary());
}
/**
* The constraint type name
*
......@@ -112,12 +118,6 @@ public abstract class Constraint extends SchemaObjectBase implements Comparable
*/
public abstract void checkExistingData(Session session) throws SQLException;
public Constraint(Schema schema, int id, String name, Table table) {
initSchemaObjectBase(schema, id, name, Trace.CONSTRAINT);
this.table = table;
this.setTemporary(table.getTemporary());
}
public void checkRename() {
// ok
}
......
......@@ -54,6 +54,9 @@ public class ConstraintReferential extends Constraint {
*/
public static final int SET_NULL = 3;
protected IndexColumn[] columns;
protected IndexColumn[] refColumns;
private int deleteAction;
private int updateAction;
private Table refTable;
......@@ -61,8 +64,6 @@ public class ConstraintReferential extends Constraint {
private Index refIndex;
private boolean indexOwner;
private boolean refIndexOwner;
protected IndexColumn[] columns;
protected IndexColumn[] refColumns;
private String deleteSQL, updateSQL;
private boolean skipOwnTable;
......
......@@ -76,16 +76,6 @@ package org.h2.engine;
*/
public class Constants {
/**
* The build id is incremented for each public release.
*/
public static final int BUILD_ID = 72;
/**
* The build date is updated for each public release.
*/
private static final String BUILD_DATE = "2008-05-10";
/**
* The TCP protocol version number 5. This protocol is used by the TCP
* server and remote JDBC client.
......@@ -531,12 +521,6 @@ public class Constants {
*/
public static final String UTF8 = "UTF8";
/**
* The version of this product, consisting of major version, minor version,
* and build id.
*/
public static final String VERSION = VERSION_MAJOR + "." + VERSION_MINOR + "." + BUILD_ID;
/**
* The major version number of the supported JDBC API.
*/
......@@ -559,6 +543,30 @@ public class Constants {
*/
public static final int VIEW_INDEX_CACHE_SIZE = 64;
/**
* The build id is incremented for each public release.
*/
public static final int BUILD_ID = 72;
/**
* The build date is updated for each public release.
*/
private static final String BUILD_DATE = "2008-05-10";
private Constants() {
// utility class
}
/**
* Get the version of this product, consisting of major version, minor version,
* and build id.
*
* @return the version number
*/
public static String getVersion() {
return VERSION_MAJOR + "." + VERSION_MINOR + "." + BUILD_ID;
}
/**
* Get the complete version number of this database, consisting of
* the major version, the minor version, the build id, and the build date.
......@@ -566,7 +574,7 @@ public class Constants {
* @return the complete version
*/
public static String getFullVersion() {
return VERSION+ " (" + BUILD_DATE + ")";
return getVersion() + " (" + BUILD_DATE + ")";
}
}
......@@ -74,7 +74,9 @@ import org.h2.value.ValueLob;
* @since 2004-04-15 22:49
*/
public class Database implements DataHandler {
private static int initialPowerOffCount;
private final boolean persistent;
private final String databaseName;
private final String databaseShortName;
......@@ -95,7 +97,7 @@ public class Database implements DataHandler {
private Session exclusiveSession;
private final BitField objectIds = new BitField();
private final Object lobSyncObject = new Object();
private boolean textStorage;
private Schema mainSchema;
private Schema infoSchema;
......@@ -132,7 +134,6 @@ public class Database implements DataHandler {
private long biggestFileSize;
private int allowLiterals = Constants.DEFAULT_ALLOW_LITERALS;
private static int initialPowerOffCount;
private int powerOffCount = initialPowerOffCount;
private int closeDelay;
private DatabaseCloser delayedCloser;
......@@ -1481,6 +1482,7 @@ public class Database implements DataHandler {
case DbObject.TRIGGER:
case DbObject.USER:
return null;
default:
}
ObjectArray list = getAllSchemaObjects(DbObject.TABLE_OR_VIEW);
HashSet set = new HashSet();
......
......@@ -142,7 +142,8 @@ public class FunctionAlias extends DbObjectBase {
public synchronized void removeChildrenAndResources(Session session) throws SQLException {
database.removeMeta(session, getId());
className = methodName = null;
className = null;
methodName = null;
javaMethod = null;
invalidate();
}
......
......@@ -20,6 +20,8 @@ public class Mode {
* The name of the default mode.
*/
public static final String REGULAR = "REGULAR";
private static final HashMap MODES = new HashMap();
public boolean nullConcatIsNull;
public boolean convertInsertNullToZero;
......@@ -30,8 +32,6 @@ public class Mode {
public boolean systemColumns;
public boolean squareBracketQuotedNames;
private static final HashMap MODES = new HashMap();
private String name;
static {
......@@ -61,15 +61,15 @@ public class Mode {
add(mode);
}
private Mode(String name) {
this.name = name;
}
private static void add(Mode mode) {
MODES.put(StringUtils.toUpperEnglish(mode.name), mode);
}
private Mode(String name) {
this.name = name;
}
/**
* Get the mode with the given name.
*
......
......@@ -47,6 +47,9 @@ import org.h2.value.ValueNull;
*/
public class Session implements SessionInterface {
private static int nextSerialId;
private int serialId = nextSerialId++;
private User user;
private int id;
private Database database;
......@@ -72,8 +75,6 @@ public class Session implements SessionInterface {
private HashMap unlinkMap;
private int tempViewIndex;
private HashMap procedures;
private static int nextSerialId;
private int serialId = nextSerialId++;
private boolean undoLogEnabled = true;
private boolean autoCommitAtTransactionEnd;
private String currentTransactionName;
......
......@@ -58,7 +58,7 @@ public class User extends RightOwner {
/**
* Set the user name password hash. A random salt is generated as well.
* The parameter is nulled out after use.
* The parameter is filled with zeros after use.
*
* @param userPasswordHash the user name password hash
*/
......
......@@ -112,6 +112,8 @@ public class Aggregate extends Expression {
* The aggregate type for SELECTIVITY(expression).
*/
public static final int SELECTIVITY = 13;
private static final HashMap AGGREGATES = new HashMap();
private final Database database;
private final int type;
......@@ -126,8 +128,6 @@ public class Aggregate extends Expression {
private long precision;
private int displaySize;
private static final HashMap AGGREGATES = new HashMap();
/**
* Create a new aggregate object.
*
......
......@@ -146,7 +146,7 @@ public class AggregateData {
s = 0;
} else {
sum += distinctValues.size();
sum = (100 * sum / count);
sum = 100 * sum / count;
s = (int) sum;
s = s <= 0 ? 1 : s > 100 ? 100 : s;
}
......
......@@ -28,7 +28,9 @@ import org.h2.value.ValueString;
* Pattern matching comparison expression: WHERE NAME LIKE ?
*/
public class CompareLike extends Condition {
private static final int MATCH = 0, ONE = 1, ANY = 2;
private final CompareMode compareMode;
private final boolean regexp;
private Expression left;
......@@ -41,7 +43,6 @@ public class CompareLike extends Condition {
private Pattern patternRegexp;
private int[] types;
private int patternLength;
private static final int MATCH = 0, ONE = 1, ANY = 2;
private boolean ignoreCase;
public CompareLike(CompareMode compareMode, Expression left, Expression right, Expression escape, boolean regexp) {
......
......@@ -70,6 +70,10 @@ public class ExpressionVisitor {
private ColumnResolver resolver;
private HashSet dependencies;
private ExpressionVisitor(int type) {
this.type = type;
}
/**
* Create a new visitor object with the given type.
*
......@@ -80,10 +84,6 @@ public class ExpressionVisitor {
return new ExpressionVisitor(type);
}
private ExpressionVisitor(int type) {
this.type = type;
}
/**
* Add a new dependency to the set of dependencies.
* This is used for GET_DEPENDENCIES visitors.
......
......@@ -105,8 +105,9 @@ public class Function extends Expression implements FunctionCall {
private static final SimpleDateFormat FORMAT_MONTHNAME = new SimpleDateFormat("MMMM", Locale.ENGLISH);
private static final char[] SOUNDEX_INDEX = new char[128];
private FunctionInfo info;
protected Expression[] args;
private FunctionInfo info;
private ObjectArray varArgs;
private int dataType, scale;
private long precision;
......@@ -189,8 +190,8 @@ public class Function extends Expression implements FunctionCall {
addFunction("CHAR", CHAR, 1, Value.STRING);
addFunction("CHR", CHAR, 1, Value.STRING);
addFunction("CHAR_LENGTH", CHAR_LENGTH, 1, Value.INT);
addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT); // same as
// CHAR_LENGTH
// same as CHAR_LENGTH
addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT);
addFunctionWithNull("CONCAT", CONCAT, VAR_ARGS, Value.STRING);
addFunction("DIFFERENCE", DIFFERENCE, 2, Value.INT);
addFunction("HEXTORAW", HEXTORAW, 1, Value.STRING);
......@@ -198,9 +199,10 @@ public class Function extends Expression implements FunctionCall {
addFunction("LCASE", LCASE, 1, Value.STRING);
addFunction("LEFT", LEFT, 2, Value.STRING);
addFunction("LENGTH", LENGTH, 1, Value.INT);
addFunction("LOCATE", LOCATE, VAR_ARGS, Value.INT); // 2 or 3 arguments
addFunction("POSITION", LOCATE, 2, Value.INT); // same as LOCATE with 2
// arguments
// 2 or 3 arguments
addFunction("LOCATE", LOCATE, VAR_ARGS, Value.INT);
// same as LOCATE with 2 arguments
addFunction("POSITION", LOCATE, 2, Value.INT);
addFunction("INSTR", INSTR, VAR_ARGS, Value.INT);
addFunction("LTRIM", LTRIM, VAR_ARGS, Value.STRING);
addFunction("OCTET_LENGTH", OCTET_LENGTH, 1, Value.INT);
......@@ -298,6 +300,16 @@ public class Function extends Expression implements FunctionCall {
addFunctionWithNull("TABLE", TABLE, VAR_ARGS, Value.RESULT_SET);
addFunctionWithNull("TABLE_DISTINCT", TABLE_DISTINCT, VAR_ARGS, Value.RESULT_SET);
}
protected Function(Database database, FunctionInfo info) {
this.database = database;
this.info = info;
if (info.parameterCount == VAR_ARGS) {
varArgs = new ObjectArray();
} else {
args = new Expression[info.parameterCount];
}
}
private static void addFunction(String name, int type, int parameterCount, int dataType,
boolean nullIfParameterIsNull, boolean isDeterm) {
......@@ -355,16 +367,6 @@ public class Function extends Expression implements FunctionCall {
}
}
protected Function(Database database, FunctionInfo info) {
this.database = database;
this.info = info;
if (info.parameterCount == VAR_ARGS) {
varArgs = new ObjectArray();
} else {
args = new Expression[info.parameterCount];
}
}
/**
* Set the parameter expression at the given index.
*
......@@ -1747,9 +1749,11 @@ public class Function extends Expression implements FunctionCall {
break;
case DAYNAME:
case MONTHNAME:
precision = 20; // day and month names may be long in some languages
// day and month names may be long in some languages
precision = 20;
displaySize = (int) precision;
break;
default:
}
}
......
......@@ -90,6 +90,7 @@ public class JavaAggregate extends Expression {
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(userAggregate);
break;
default:
}
for (int i = 0; i < args.length; i++) {
Expression e = args[i];
......
......@@ -123,6 +123,7 @@ public class JavaFunction extends Expression implements FunctionCall {
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(functionAlias);
break;
default:
}
for (int i = 0; i < args.length; i++) {
Expression e = args[i];
......
......@@ -19,8 +19,6 @@ import org.h2.value.ValueNull;
* An expression representing a constant value.
*/
public class ValueExpression extends Expression {
private Value value;
/**
* The expression represents ValueNull.INSTANCE.
*/
......@@ -33,6 +31,12 @@ public class ValueExpression extends Expression {
*/
public static final ValueExpression DEFAULT = new ValueExpression(ValueNull.INSTANCE);
private Value value;
private ValueExpression(Value value) {
this.value = value;
}
/**
* Create a new expression with the given value.
*
......@@ -46,10 +50,6 @@ public class ValueExpression extends Expression {
return new ValueExpression(value);
}
private ValueExpression(Value value) {
this.value = value;
}
public Value getValue(Session session) {
return value;
}
......
......@@ -447,8 +447,9 @@ implements Trigger
case Types.DATALINK:
case Types.DISTINCT:
throw new SQLException("FULLTEXT", "Unsupported column data type: " + type);
default:
return "";
}
return "";
}
private String quoteSQL(Object data, int type) throws SQLException {
......@@ -490,8 +491,9 @@ implements Trigger
case Types.DATALINK:
case Types.DISTINCT:
throw new SQLException("FULLTEXT", "Unsupported key data type: " + type);
default:
return "";
}
return "";
}
private void insert(Object[] row) throws SQLException {
......
......@@ -34,6 +34,10 @@ public abstract class BtreePage extends Record {
protected BtreeIndex index;
protected ObjectArray pageData;
protected boolean root;
BtreePage(BtreeIndex index) {
this.index = index;
}
/**
* Add a row to the index.
......@@ -63,10 +67,6 @@ public abstract class BtreePage extends Record {
abstract void last(BtreeCursor cursor) throws SQLException;
abstract int getRealByteCount() throws SQLException;
BtreePage(BtreeIndex index) {
this.index = index;
}
SearchRow getData(int i) throws SQLException {
return (SearchRow) pageData.get(i);
}
......
......@@ -35,7 +35,8 @@ public class MultiVersionCursor implements Cursor {
this.baseCursor = base;
this.deltaCursor = delta;
this.sync = sync;
needNewDelta = needNewBase = true;
needNewDelta = true;
needNewBase = true;
}
void loadCurrent() throws SQLException {
......
......@@ -78,6 +78,9 @@ public class ViewIndex extends BaseIndex {
throw Message.getUnsupportedException();
}
/**
* A calculated cost value.
*/
static class CostElement {
long evaluatedAt;
double cost;
......
......@@ -37,6 +37,11 @@ import org.h2.message.TraceObject;
*/
public class JdbcCallableStatement extends JdbcPreparedStatement implements CallableStatement {
JdbcCallableStatement(SessionInterface session, JdbcConnection conn, String sql, int resultSetType, int id) throws SQLException {
super(session, conn, sql, resultSetType, id, false);
setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id);
}
/**
* [Not supported]
*/
......@@ -459,7 +464,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
public void setAsciiStream(String parameterName, InputStream x, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -601,11 +607,6 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
// =============================================================
JdbcCallableStatement(SessionInterface session, JdbcConnection conn, String sql, int resultSetType, int id) throws SQLException {
super(session, conn, sql, resultSetType, id, false);
setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id);
}
/**
* [Not supported]
*/
......@@ -646,7 +647,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
public void setNCharacterStream(String parameterName, Reader value, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -655,7 +657,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setNClob(String parameterName, NClob value) throws SQLException {
public void setNClob(String parameterName, NClob value)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -664,7 +667,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setClob(String parameterName, Reader reader, long length) throws SQLException {
public void setClob(String parameterName, Reader reader, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -673,7 +677,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
public void setBlob(String parameterName, InputStream inputStream, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -682,7 +687,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
public void setNClob(String parameterName, Reader reader, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -755,7 +761,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public Reader getNCharacterStream(int parameterIndex) throws SQLException {
public Reader getNCharacterStream(int parameterIndex)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -764,7 +771,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public Reader getNCharacterStream(String parameterName) throws SQLException {
public Reader getNCharacterStream(String parameterName)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -782,7 +790,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public Reader getCharacterStream(String parameterName) throws SQLException {
public Reader getCharacterStream(String parameterName)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -809,7 +818,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
public void setAsciiStream(String parameterName, InputStream x)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -825,7 +835,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
public void setBinaryStream(String parameterName, InputStream x)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -834,7 +845,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
public void setBinaryStream(String parameterName, InputStream x, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -843,7 +855,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setBlob(String parameterName, InputStream x) throws SQLException {
public void setBlob(String parameterName, InputStream x)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -852,7 +865,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setCharacterStream(String parameterName, Reader x) throws SQLException {
public void setCharacterStream(String parameterName, Reader x)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -861,7 +875,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setCharacterStream(String parameterName, Reader x, long length) throws SQLException {
public void setCharacterStream(String parameterName, Reader x, long length)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......@@ -879,7 +894,8 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
* [Not supported]
*/
/*## Java 1.6 begin ##
public void setNCharacterStream(String parameterName, Reader x) throws SQLException {
public void setNCharacterStream(String parameterName, Reader x)
throws SQLException {
throw Message.getUnsupportedException();
}
## Java 1.6 end ##*/
......
......@@ -60,7 +60,8 @@ public class JdbcConnection extends TraceObject implements Connection {
private String url;
private String user;
private int holdability = 1; // ResultSet.HOLD_CURSORS_OVER_COMMIT
// ResultSet.HOLD_CURSORS_OVER_COMMIT
private int holdability = 1;
private SessionInterface session;
private CommandInterface commit, rollback;
......@@ -79,6 +80,62 @@ public class JdbcConnection extends TraceObject implements Connection {
private String catalog;
private Statement executingStatement;
/**
* INTERNAL
*/
public JdbcConnection(String url, Properties info) throws SQLException {
this(new ConnectionInfo(url, info), true);
}
/**
* INTERNAL
*/
public JdbcConnection(ConnectionInfo ci, boolean useBaseDir) throws SQLException {
try {
checkJavaVersion();
if (ci.isRemote()) {
session = new SessionRemote().createSession(ci);
} else {
// create the session using reflection,
// so that the JDBC layer can be compiled without it
SessionInterface si = (SessionInterface) ClassUtils.loadSystemClass("org.h2.engine.Session").newInstance();
if (useBaseDir) {
String baseDir = SysProperties.getBaseDir();
if (baseDir != null) {
ci.setBaseDir(baseDir);
}
}
session = si.createSession(ci);
}
trace = session.getTrace();
int id = getNextId(TraceObject.CONNECTION);
setTrace(trace, TraceObject.CONNECTION, id);
this.user = ci.getUserName();
if (isInfoEnabled()) {
trace.infoCode("Connection " + getTraceObjectName()
+ " = DriverManager.getConnection(" + quote(ci.getOriginalURL())
+ ", " + quote(user) + ", \"\")");
}
this.url = ci.getURL();
openStackTrace = new Exception("Stack Trace");
} catch (Throwable e) {
throw logAndConvert(e);
}
}
/**
* INTERNAL
*/
public JdbcConnection(SessionInterface session, String user, String url) {
isInternal = true;
this.session = session;
trace = session.getTrace();
int id = getNextId(TraceObject.CONNECTION);
setTrace(trace, TraceObject.CONNECTION, id);
this.user = user;
this.url = url;
}
/**
* Creates a new statement.
*
......@@ -942,61 +999,6 @@ public class JdbcConnection extends TraceObject implements Connection {
// =============================================================
/**
* INTERNAL
*/
public JdbcConnection(String url, Properties info) throws SQLException {
this(new ConnectionInfo(url, info), true);
}
/**
* INTERNAL
*/
public JdbcConnection(ConnectionInfo ci, boolean useBaseDir) throws SQLException {
try {
checkJavaVersion();
if (ci.isRemote()) {
session = new SessionRemote().createSession(ci);
} else {
// create the session using reflection, so that the JDBC layer can be compiled without it
SessionInterface si = (SessionInterface) ClassUtils.loadSystemClass("org.h2.engine.Session").newInstance();
if (useBaseDir) {
String baseDir = SysProperties.getBaseDir();
if (baseDir != null) {
ci.setBaseDir(baseDir);
}
}
session = si.createSession(ci);
}
trace = session.getTrace();
int id = getNextId(TraceObject.CONNECTION);
setTrace(trace, TraceObject.CONNECTION, id);
this.user = ci.getUserName();
if (isInfoEnabled()) {
trace.infoCode("Connection " + getTraceObjectName()
+ " = DriverManager.getConnection(" + quote(ci.getOriginalURL())
+ ", " + quote(user) + ", \"\")");
}
this.url = ci.getURL();
openStackTrace = new Exception("Stack Trace");
} catch (Throwable e) {
throw logAndConvert(e);
}
}
/**
* INTERNAL
*/
public JdbcConnection(SessionInterface session, String user, String url) {
isInternal = true;
this.session = session;
trace = session.getTrace();
int id = getNextId(TraceObject.CONNECTION);
setTrace(trace, TraceObject.CONNECTION, id);
this.user = user;
this.url = url;
}
private void checkJavaVersion() throws SQLException {
try {
//## Java 1.4 begin ##
......
......@@ -29,6 +29,11 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
private JdbcConnection conn;
JdbcDatabaseMetaData(JdbcConnection conn, Trace trace, int id) {
setTrace(trace, TraceObject.DATABASE_META_DATA, id);
this.conn = conn;
}
/**
* Returns the major version of this driver.
*
......@@ -299,7 +304,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "ORDINAL_POSITION, "
+ "COLUMN_NAME, "
+ "ASC_OR_DESC, "
+ "CARDINALITY, " // TODO meta data for number of unique values in an index
// TODO meta data for number of unique values in an index
+ "CARDINALITY, "
+ "PAGES, "
+ "FILTER_CONDITION, "
+ "SORT_TYPE "
......@@ -848,8 +854,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "AND C.TABLE_NAME = ? "
+ "AND I.PRIMARY_KEY = TRUE "
+ "ORDER BY SCOPE");
prep.setInt(1, DatabaseMetaData.bestRowSession); // SCOPE
prep.setInt(2, DatabaseMetaData.bestRowNotPseudo); // PSEUDO_COLUMN
// SCOPE
prep.setInt(1, DatabaseMetaData.bestRowSession);
// PSEUDO_COLUMN
prep.setInt(2, DatabaseMetaData.bestRowNotPseudo);
prep.setString(3, getCatalogPattern(catalog));
prep.setString(4, getSchemaPattern(schema));
prep.setString(5, tableName);
......@@ -2608,11 +2616,6 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
// =============================================================
JdbcDatabaseMetaData(JdbcConnection conn, Trace trace, int id) {
setTrace(trace, TraceObject.DATABASE_META_DATA, id);
this.conn = conn;
}
private void checkClosed() throws SQLException {
conn.checkClosed();
}
......@@ -2645,7 +2648,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
* [Not supported] Gets the list of schemas.
*/
/*## Java 1.6 begin ##
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
public ResultSet getSchemas(String catalog, String schemaPattern)
throws SQLException {
debugCodeCall("getSchemas");
throw Message.getUnsupportedException();
}
......@@ -2701,7 +2705,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
* [Not supported] Gets the list of function columns.
*/
/*## Java 1.6 begin ##
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
public ResultSet getFunctionColumns(String catalog, String schemaPattern,
String functionNamePattern, String columnNamePattern)
throws SQLException {
debugCodeCall("getFunctionColumns");
throw Message.getUnsupportedException();
}
......@@ -2711,7 +2717,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
* [Not supported] Gets the list of functions.
*/
/*## Java 1.6 begin ##
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
public ResultSet getFunctions(String catalog, String schemaPattern,
String functionNamePattern) throws SQLException {
debugCodeCall("getFunctions");
throw Message.getUnsupportedException();
}
......
......@@ -32,6 +32,13 @@ implements ParameterMetaData
private int paramCount;
private ObjectArray parameters;
JdbcParameterMetaData(SessionInterface session, JdbcPreparedStatement prep, CommandInterface command, int id) {
setTrace(session.getTrace(), TraceObject.PARAMETER_META_DATA, id);
this.prep = prep;
this.parameters = command.getParameters();
this.paramCount = parameters.size();
}
/**
* Returns the number of parameters.
*
......@@ -196,13 +203,6 @@ implements ParameterMetaData
}
}
JdbcParameterMetaData(SessionInterface session, JdbcPreparedStatement prep, CommandInterface command, int id) {
setTrace(session.getTrace(), TraceObject.PARAMETER_META_DATA, id);
this.prep = prep;
this.parameters = command.getParameters();
this.paramCount = parameters.size();
}
private ParameterInterface getParameter(int param) throws SQLException {
checkClosed();
if (param < 1 || param > paramCount) {
......
......@@ -66,6 +66,12 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
private CommandInterface command;
private ObjectArray batchParameters;
JdbcPreparedStatement(SessionInterface session, JdbcConnection conn, String sql, int resultSetType, int id, boolean closeWithResultSet) throws SQLException {
super(session, conn, resultSetType, id, closeWithResultSet);
setTrace(session.getTrace(), TraceObject.PREPARED_STATEMENT, id);
command = conn.prepareCommand(sql, fetchSize);
}
/**
* Executes a query (select statement) and returns the result set. If
* another result set exists for this statement, this will be closed (even
......@@ -1210,12 +1216,6 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
// =============================================================
JdbcPreparedStatement(SessionInterface session, JdbcConnection conn, String sql, int resultSetType, int id, boolean closeWithResultSet) throws SQLException {
super(session, conn, resultSetType, id, closeWithResultSet);
setTrace(session.getTrace(), TraceObject.PREPARED_STATEMENT, id);
command = conn.prepareCommand(sql, fetchSize);
}
private void setParameter(int parameterIndex, Value value) throws SQLException {
checkClosed();
parameterIndex--;
......
......@@ -40,6 +40,14 @@ public class JdbcStatement extends TraceObject implements Statement {
private ObjectArray batchCommands;
private boolean escapeProcessing = true;
JdbcStatement(SessionInterface session, JdbcConnection conn, int resultSetType, int id, boolean closeWithResultSet) {
setTrace(session.getTrace(), TraceObject.STATEMENT, id);
this.session = session;
this.conn = conn;
this.resultSetType = resultSetType;
this.closedByResultSet = closeWithResultSet;
}
/**
* Executes a query (select statement) and returns the result set.
* If another result set exists for this statement, this will be closed
......@@ -813,14 +821,6 @@ public class JdbcStatement extends TraceObject implements Statement {
// =============================================================
JdbcStatement(SessionInterface session, JdbcConnection conn, int resultSetType, int id, boolean closeWithResultSet) {
setTrace(session.getTrace(), TraceObject.STATEMENT, id);
this.session = session;
this.conn = conn;
this.resultSetType = resultSetType;
this.closedByResultSet = closeWithResultSet;
}
void checkClosed() throws SQLException {
if (conn == null) {
throw Message.getSQLException(ErrorCode.OBJECT_CLOSED);
......
......@@ -73,6 +73,15 @@ public class JdbcConnectionPool implements DataSource {
private int activeConnections;
private boolean isDisposed;
private JdbcConnectionPool(ConnectionPoolDataSource dataSource) {
this.dataSource = dataSource;
try {
logWriter = dataSource.getLogWriter();
} catch (SQLException e) {
// ignore
}
}
/**
* Constructs a new connection pool.
*
......@@ -83,15 +92,6 @@ public class JdbcConnectionPool implements DataSource {
return new JdbcConnectionPool(dataSource);
}
private JdbcConnectionPool(ConnectionPoolDataSource dataSource) {
this.dataSource = dataSource;
try {
logWriter = dataSource.getLogWriter();
} catch (SQLException e) {
// ignore
}
}
/**
* Sets the maximum number of connections to use from now on.
* The default value is 10 connections.
......@@ -253,6 +253,10 @@ public class JdbcConnectionPool implements DataSource {
}
}
/**
* This event listener informs the connection pool that about closed and
* broken connections.
*/
class PoolConnectionEventListener implements ConnectionEventListener {
public void connectionClosed(ConnectionEvent event) {
PooledConnection pc = (PooledConnection) event.getSource();
......
......@@ -43,6 +43,8 @@ implements XAConnection, XAResource, JdbcConnectionListener
{
//## Java 1.4 begin ##
private static int nextTransactionId;
private JdbcDataSourceFactory factory;
private String url, user, password;
private JdbcConnection connSentinel;
......@@ -50,7 +52,6 @@ implements XAConnection, XAResource, JdbcConnectionListener
private ArrayList listeners = new ArrayList();
private Xid currentTransaction;
private int currentTransactionId;
private static int nextTransactionId;
static {
org.h2.Driver.load();
......
......@@ -432,9 +432,12 @@ public class LogFile {
buff.writeInt(0);
buff.writeByte((byte) 'S');
buff.writeInt(0);
buff.writeInt(0); // storageId
buff.writeInt(0); // recordId
buff.writeInt(0); // blockCount
// storageId
buff.writeInt(0);
// recordId
buff.writeInt(0);
// blockCount
buff.writeInt(0);
buff.writeByte((byte) (dataFile ? 'D' : 'I'));
if (summary == null) {
buff.writeInt(0);
......
......@@ -61,6 +61,10 @@ public class Message {
TraceSystem.traceThrowable(e);
}
}
private Message() {
// utility class
}
/**
* Gets the SQL exception object for a specific error code.
......
......@@ -153,7 +153,7 @@ public class Trace {
/**
* Write Java source code with trace level DEBUG to the trace system.
*
* @param java the source cod
* @param java the source code
*/
public void debugCode(String java) {
traceWriter.write(TraceSystem.DEBUG, module, lineSeparator + "/**/" + java, null);
......@@ -162,7 +162,7 @@ public class Trace {
/**
* Write Java source code with trace level INFO to the trace system.
*
* @param java the source cod
* @param java the source code
*/
public void infoCode(String java) {
traceWriter.write(TraceSystem.INFO, module, lineSeparator + "/**/" + java, null);
......
......@@ -29,14 +29,14 @@ public class TraceObject {
SAVEPOINT = 6, SQL_EXCEPTION = 7, STATEMENT = 8, BLOB = 9, CLOB = 10,
PARAMETER_META_DATA = 11;
protected static final int DATA_SOURCE = 12, XA_DATA_SOURCE = 13, XID = 14, ARRAY = 15;
private static final int LAST = ARRAY + 1;
private Trace trace;
private static final int[] ID = new int[LAST];
private static final String[] PREFIX = {
"call", "conn", "dbMeta", "prep", "rs", "rsMeta", "sp", "ex", "stat", "blob", "clob", "pMeta",
"ds", "xads", "xid", "ar"
};
private Trace trace;
private int type;
private int id;
......
......@@ -74,6 +74,8 @@ public class TraceSystem implements TraceWriter {
private static final int DEFAULT_MAX_FILE_SIZE = 64 * 1024 * 1024;
private static final int CHECK_FILE_TIME = 4000;
private static final int CHECK_SIZE_EACH_WRITES = 128;
private int levelSystemOut = DEFAULT_TRACE_LEVEL_SYSTEM_OUT;
private int levelFile = DEFAULT_TRACE_LEVEL_FILE;
private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
......@@ -83,7 +85,6 @@ public class TraceSystem implements TraceWriter {
private SimpleDateFormat dateFormat;
private Writer fileWriter;
private PrintWriter printWriter;
private static final int CHECK_SIZE_EACH_WRITES = 128;
private int checkSize;
private boolean closed;
private boolean manualEnabling = true;
......@@ -352,7 +353,7 @@ public class TraceSystem implements TraceWriter {
}
public void setName(String name) {
// nothing to do (the file name is aleady set)
// nothing to do (the file name is already set)
}
}
......@@ -39,8 +39,9 @@ public class TraceWriterAdapter implements TraceWriter {
return logger.isInfoEnabled();
case TraceSystem.ERROR:
return logger.isErrorEnabled();
default:
return false;
}
return false;
}
public void write(int level, String module, String s, Throwable t) {
......@@ -60,6 +61,7 @@ public class TraceWriterAdapter implements TraceWriter {
case TraceSystem.ERROR:
logger.error(s, t);
break;
default:
}
}
}
......
......@@ -1735,7 +1735,7 @@ Unlike when using VARCHAR, large CLOB objects are not kept fully in-memory.
CLOB should be used for documents and texts with arbitrary size such as
XML or HTML documents, text files, or memo fields of unlimited size.
VARCHAR should be used for text with relatively short average size (for example
shorter than 200 characters). Short CLOBs are stored inline, but there is an
shorter than 200 characters). Short CLOB values are stored inline, but there is an
overhead compared to VARCHAR.
Use PreparedStatement.setCharacterStream to store values.
","
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论