提交 7bf58319 authored 作者: Andrei Tokar's avatar Andrei Tokar

Merge remote-tracking branch 'h2database/master' into misc-test-fixes

......@@ -1583,9 +1583,9 @@ SET MODE HSQLDB
"Commands (Other)","SET MULTI_THREADED","
SET MULTI_THREADED { 0 | 1 }
","
Enabled (1) or disabled (0) multi-threading inside the database engine. By
default, this setting is disabled. Currently, enabling this is experimental
only.
Enabled (1) or disabled (0) multi-threading inside the database engine.
MULTI_THREADED is enabled by default with default MVStore storage engine.
MULTI_THREADED is disabled by default when using PageStore storage engine, enabling this with PageStore is experimental only.
This is a global setting, which means it is not possible to open multiple databases with different modes at the same time in the same virtual machine.
This setting is not persistent, however the value is kept until the virtual machine exits or it is changed.
......
......@@ -10,6 +10,7 @@ import java.util.HashSet;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.engine.SysProperties;
import org.h2.expression.Expression;
......@@ -140,9 +141,10 @@ public class SelectUnion extends Query {
// for the value hash set
newValues = new Value[columnCount];
}
Mode mode = session.getDatabase().getMode();
for (int i = 0; i < columnCount; i++) {
Expression e = expressions.get(i);
newValues[i] = values[i].convertTo(e.getType());
newValues[i] = values[i].convertTo(e.getType(), -1, mode);
}
return newValues;
}
......
......@@ -347,8 +347,11 @@ public class Set extends Prepared {
}
break;
case SetTypes.MULTI_THREADED: {
session.getUser().checkAdmin();
database.setMultiThreaded(getIntValue() == 1);
boolean v = getIntValue() == 1;
if (database.isMultiThreaded() != v) {
session.getUser().checkAdmin();
database.setMultiThreaded(v);
}
break;
}
case SetTypes.MVCC: {
......
......@@ -188,6 +188,7 @@ public class Database implements DataHandler {
/** ie. the MVCC setting */
private boolean multiVersion;
private Mode mode = Mode.getRegular();
/** ie. the MULTI_THREADED setting */
private boolean multiThreaded;
private int maxOperationMemory =
Constants.DEFAULT_MAX_OPERATION_MEMORY;
......@@ -290,7 +291,7 @@ public class Database implements DataHandler {
this.javaObjectSerializerName =
ci.getProperty("JAVA_OBJECT_SERIALIZER", null);
this.multiThreaded =
ci.getProperty("MULTI_THREADED", false);
ci.getProperty("MULTI_THREADED", dbSettings.mvStore);
this.allowBuiltinAliasOverride =
ci.getProperty("BUILTIN_ALIAS_OVERRIDE", false);
boolean closeAtVmShutdown =
......@@ -657,6 +658,7 @@ public class Database implements DataHandler {
// Need to re-init this because the first time we do it we don't
// know if we have an mvstore or a pagestore.
multiVersion = ci.getProperty("MVCC", false);
multiThreaded = ci.getProperty("MULTI_THREADED", false);
}
if (readOnly) {
if (traceLevelFile >= TraceSystem.DEBUG) {
......@@ -2461,7 +2463,7 @@ public class Database implements DataHandler {
// supported
throw DbException.get(
ErrorCode.UNSUPPORTED_SETTING_COMBINATION,
"MVCC & MULTI_THREADED");
"MVCC & MULTI_THREADED & !MV_STORE");
}
if (lockMode == 0) {
// currently the combination of LOCK_MODE=0 and MULTI_THREADED
......
......@@ -341,12 +341,6 @@ public class DbSettings extends SettingsBase {
*/
public final boolean compressData = get("COMPRESS", false);
/**
* Database setting <code>MULTI_THREADED</code>
* (default: false).<br />
*/
public final boolean multiThreaded = get("MULTI_THREADED", false);
/**
* Database setting <code>STANDARD_DROP_TABLE_RESTRICT</code> (default:
* false).<br />
......
......@@ -410,8 +410,9 @@ public class FunctionAlias extends SchemaObjectBase {
paramClass.getComponentType(), array.length);
int componentType = DataType.getTypeFromClass(
paramClass.getComponentType());
Mode mode = session.getDatabase().getMode();
for (int i = 0; i < objArray.length; i++) {
objArray[i] = array[i].convertTo(componentType).getObject();
objArray[i] = array[i].convertTo(componentType, -1, mode).getObject();
}
o = objArray;
} else {
......
......@@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.engine.SysProperties;
import org.h2.index.IndexCondition;
......@@ -276,8 +277,9 @@ public class Comparison extends Condition {
l = l.convertToEnum(enumerators);
r = r.convertToEnum(enumerators);
} else {
l = l.convertTo(dataType);
r = r.convertTo(dataType);
Mode mode = database.getMode();
l = l.convertTo(dataType, -1, mode);
r = r.convertTo(dataType, -1, mode);
}
boolean result = compareNotNull(database, l, r, compareType);
return ValueBoolean.get(result);
......
......@@ -53,7 +53,7 @@ public class ConditionIn extends Condition {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
r = r.convertTo(l.getType());
r = r.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
if (result) {
break;
......
......@@ -7,6 +7,9 @@ package org.h2.expression;
import java.util.ArrayList;
import java.util.TreeSet;
import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.index.IndexCondition;
import org.h2.message.DbException;
......@@ -42,10 +45,12 @@ public class ConditionInConstantSet extends Condition {
ArrayList<Expression> valueList) {
this.left = left;
this.valueList = valueList;
this.valueSet = new TreeSet<>(session.getDatabase().getCompareMode());
Database database = session.getDatabase();
this.valueSet = new TreeSet<>(database.getCompareMode());
int type = left.getType();
Mode mode = database.getMode();
for (Expression expression : valueList) {
valueSet.add(expression.getValue(session).convertTo(type));
valueSet.add(expression.getValue(session).convertTo(type, -1, mode));
}
}
......@@ -153,7 +158,7 @@ public class ConditionInConstantSet extends Condition {
if (add != null) {
if (add.isConstant()) {
valueList.add(add);
valueSet.add(add.getValue(session).convertTo(left.getType()));
valueSet.add(add.getValue(session).convertTo(left.getType(), -1, session.getDatabase().getMode()));
return this;
}
}
......
......@@ -89,7 +89,7 @@ public class ConditionInParameter extends Condition {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
r = r.convertTo(l.getType());
r = r.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
if (result) {
break;
......@@ -100,7 +100,7 @@ public class ConditionInParameter extends Condition {
if (value == ValueNull.INSTANCE) {
hasNull = true;
} else {
value = value.convertTo(l.getType());
value = value.convertTo(l.getType(), -1, database.getMode());
result = Comparison.compareNotNull(database, l, value, Comparison.EQUAL);
}
}
......
......@@ -53,7 +53,7 @@ public class ConditionInSelect extends Condition {
} else if (l == ValueNull.INSTANCE) {
return l;
}
if (!session.getDatabase().getSettings().optimizeInSelect) {
if (!database.getSettings().optimizeInSelect) {
return getValueSlow(rows, l);
}
if (all || (compareType != Comparison.EQUAL &&
......@@ -64,7 +64,7 @@ public class ConditionInSelect extends Condition {
if (dataType == Value.NULL) {
return ValueBoolean.FALSE;
}
l = l.convertTo(dataType);
l = l.convertTo(dataType, -1, database.getMode());
if (rows.containsDistinct(new Value[] { l })) {
return ValueBoolean.TRUE;
}
......
......@@ -882,8 +882,8 @@ public class Function extends Expression implements FunctionCall {
break;
case CAST:
case CONVERT: {
v0 = v0.convertTo(dataType);
Mode mode = database.getMode();
v0 = v0.convertTo(dataType, -1, mode);
v0 = v0.convertScale(mode.convertOnlyToSmallerScale, scale);
v0 = v0.convertPrecision(getPrecision(), false);
result = v0;
......@@ -1078,7 +1078,7 @@ public class Function extends Expression implements FunctionCall {
}
private Value convertResult(Value v) {
return v.convertTo(dataType);
return v.convertTo(dataType, -1, database.getMode());
}
private static boolean cancelStatement(Session session, int targetSessionId) {
......
......@@ -109,21 +109,21 @@ public class Operation extends Expression {
@Override
public Value getValue(Session session) {
Value l = left.getValue(session).convertTo(dataType);
Mode mode = session.getDatabase().getMode();
Value l = left.getValue(session).convertTo(dataType, -1, mode);
Value r;
if (right == null) {
r = null;
} else {
r = right.getValue(session);
if (convertRight) {
r = r.convertTo(dataType);
r = r.convertTo(dataType, -1, mode);
}
}
switch (opType) {
case NEGATE:
return l == ValueNull.INSTANCE ? l : l.negate();
case CONCAT: {
Mode mode = session.getDatabase().getMode();
if (l == ValueNull.INSTANCE) {
if (mode.nullConcatIsNull) {
return ValueNull.INSTANCE;
......
......@@ -77,7 +77,7 @@ public class HashIndex extends BaseIndex {
* case we need to convert, otherwise the ValueHashMap will not find the
* result.
*/
v = v.convertTo(tableData.getColumn(indexColumn).getType());
v = v.convertTo(tableData.getColumn(indexColumn).getType(), -1, database.getMode());
Row result;
Long pos = rows.get(v);
if (pos == null) {
......
......@@ -101,7 +101,7 @@ public class NonUniqueHashIndex extends BaseIndex {
* case we need to convert, otherwise the ValueHashMap will not find the
* result.
*/
v = v.convertTo(tableData.getColumn(indexColumn).getType());
v = v.convertTo(tableData.getColumn(indexColumn).getType(), -1, database.getMode());
ArrayList<Long> positions = rows.get(v);
return new NonUniqueHashCursor(session, tableData, positions);
}
......
......@@ -562,7 +562,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
setParameter(parameterIndex, ValueNull.INSTANCE);
} else {
Value v = DataType.convertToValue(conn.getSession(), x, type);
setParameter(parameterIndex, v.convertTo(type));
setParameter(parameterIndex, v.convertTo(type, -1, conn.getMode()));
}
} catch (Exception e) {
throw logAndConvert(e);
......
......@@ -322,7 +322,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
int idx = c.getColumnId();
Value v = r.getValue(idx);
if (v != null) {
array[i] = v.convertTo(c.getType(), -1, null, null, c.getEnumerators());
array[i] = v.convertTo(c.getType(), -1, null, database.getMode(), c.getEnumerators());
}
}
array[keyColumns - 1] = ValueLong.get(r.getKey());
......
......@@ -18,6 +18,7 @@ import org.h2.command.dml.AllColumnsForPlan;
import org.h2.constraint.Constraint;
import org.h2.engine.Constants;
import org.h2.engine.DbObject;
import org.h2.engine.Mode;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord;
......@@ -1214,8 +1215,9 @@ public abstract class Table extends SchemaObjectBase {
a = a.convertToEnum(enumerators);
b = b.convertToEnum(enumerators);
} else {
a = a.convertTo(dataType);
b = b.convertTo(dataType);
Mode mode = database.getMode();
a = a.convertTo(dataType, -1, mode);
b = b.convertTo(dataType, -1, mode);
}
return a.compareTypeSafe(b, compareMode);
}
......
......@@ -317,9 +317,7 @@ public abstract class TestBase {
if (config.mvcc) {
url = addOption(url, "MVCC", "TRUE");
}
if (config.multiThreaded) {
url = addOption(url, "MULTI_THREADED", "TRUE");
}
url = addOption(url, "MULTI_THREADED", config.multiThreaded ? "TRUE" : "FALSE");
if (config.lazy) {
url = addOption(url, "LAZY_QUERY_EXECUTION", "1");
}
......
......@@ -325,6 +325,13 @@ public class TestCompatibility extends TestBase {
prep.setBytes(1, bytes);
assertEquals(1, prep.executeUpdate());
testMySQLBytesCheck(stat, string, bytes);
prep = conn.prepareStatement("SELECT C FROM TEST2 WHERE C = ?");
prep.setBytes(1, bytes);
testMySQLBytesCheck(prep.executeQuery(), string, bytes);
stat.execute("CREATE INDEX TEST2_C ON TEST2(C)");
prep = conn.prepareStatement("SELECT C FROM TEST2 WHERE C = ?");
prep.setBytes(1, bytes);
testMySQLBytesCheck(prep.executeQuery(), string, bytes);
stat.execute("DROP TABLE TEST2");
if (config.memory) {
......@@ -415,8 +422,10 @@ public class TestCompatibility extends TestBase {
}
private void testMySQLBytesCheck(Statement stat, String string, byte[] bytes) throws SQLException {
ResultSet rs;
rs = stat.executeQuery("SELECT C FROM TEST2");
testMySQLBytesCheck(stat.executeQuery("SELECT C FROM TEST2"), string, bytes);
}
private void testMySQLBytesCheck(ResultSet rs, String string, byte[] bytes) throws SQLException {
assertTrue(rs.next());
assertEquals(string, rs.getString(1));
assertEquals(bytes, rs.getBytes(1));
......
......@@ -74,6 +74,7 @@ public class TestMultiThread extends TestBase implements Runnable {
testViews();
testConcurrentInsert();
testConcurrentUpdate();
testConcurrentUpdate2();
}
private void testConcurrentSchemaChange() throws Exception {
......@@ -490,4 +491,64 @@ public class TestMultiThread extends TestBase implements Runnable {
deleteDb("lockMode");
}
private final class ConcurrentUpdate2 extends Thread {
private final String column;
Throwable exception;
ConcurrentUpdate2(String column) {
this.column = column;
}
@Override
public void run() {
try {
Connection c = getConnection("concurrentUpdate2");
PreparedStatement ps = c.prepareStatement("UPDATE TEST SET V = ? WHERE " + column + " = ?");
for (int test = 0; test < 1000; test++) {
for (int i = 0; i < 16; i++) {
ps.setInt(1, test);
ps.setInt(2, i);
assertEquals(16, ps.executeUpdate());
}
}
} catch (Throwable e) {
exception = e;
}
}
}
private void testConcurrentUpdate2() throws Exception {
deleteDb("concurrentUpdate2");
Connection c = getConnection("concurrentUpdate2");
Statement s = c.createStatement();
s.execute("CREATE TABLE TEST(A INT, B INT, V INT, PRIMARY KEY(A, B))");
PreparedStatement ps = c.prepareStatement("INSERT INTO TEST VALUES (?, ?, ?)");
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
ps.setInt(1, i);
ps.setInt(2, j);
ps.setInt(3, 0);
ps.executeUpdate();
}
}
ConcurrentUpdate2 a = new ConcurrentUpdate2("A");
ConcurrentUpdate2 b = new ConcurrentUpdate2("B");
a.start();
b.start();
a.join();
b.join();
deleteDb("concurrentUpdate2");
Throwable e = a.exception;
if (e == null) {
e = b.exception;
}
if (e != null) {
if (e instanceof Exception) {
throw (Exception) e;
}
throw (Error) e;
}
}
}
......@@ -27,6 +27,9 @@ public class TestSessionsLocks extends TestBase {
@Override
public void test() throws Exception {
if (!config.multiThreaded) {
return;
}
testCancelStatement();
if (!config.mvcc) {
testLocks();
......@@ -36,7 +39,7 @@ public class TestSessionsLocks extends TestBase {
private void testLocks() throws SQLException {
deleteDb("sessionsLocks");
Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1");
Connection conn = getConnection("sessionsLocks");
Statement stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from information_schema.locks " +
......@@ -82,7 +85,7 @@ public class TestSessionsLocks extends TestBase {
private void testCancelStatement() throws Exception {
deleteDb("sessionsLocks");
Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1");
Connection conn = getConnection("sessionsLocks");
Statement stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from information_schema.sessions " +
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论