Unverified 提交 96883799 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #1084 from grandinj/testing_pagestore

re-enable some pagestore testing
...@@ -20,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -20,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.JavaObjectSerializer; import org.h2.api.JavaObjectSerializer;
...@@ -94,6 +93,7 @@ public class Database implements DataHandler { ...@@ -94,6 +93,7 @@ public class Database implements DataHandler {
private static int initialPowerOffCount; private static int initialPowerOffCount;
private static final ThreadLocal<Session> META_LOCK_DEBUGGING = new ThreadLocal<>(); private static final ThreadLocal<Session> META_LOCK_DEBUGGING = new ThreadLocal<>();
private static final ThreadLocal<Database> META_LOCK_DEBUGGING_DB = new ThreadLocal<>();
private static final ThreadLocal<Throwable> META_LOCK_DEBUGGING_STACK = new ThreadLocal<>(); private static final ThreadLocal<Throwable> META_LOCK_DEBUGGING_STACK = new ThreadLocal<>();
/** /**
...@@ -211,6 +211,7 @@ public class Database implements DataHandler { ...@@ -211,6 +211,7 @@ public class Database implements DataHandler {
public Database(ConnectionInfo ci, String cipher) { public Database(ConnectionInfo ci, String cipher) {
META_LOCK_DEBUGGING.set(null); META_LOCK_DEBUGGING.set(null);
META_LOCK_DEBUGGING_DB.set(null);
META_LOCK_DEBUGGING_STACK.set(null); META_LOCK_DEBUGGING_STACK.set(null);
String name = ci.getName(); String name = ci.getName();
this.dbSettings = ci.getDbSettings(); this.dbSettings = ci.getDbSettings();
...@@ -932,17 +933,23 @@ public class Database implements DataHandler { ...@@ -932,17 +933,23 @@ public class Database implements DataHandler {
return true; return true;
} }
if (SysProperties.CHECK2) { if (SysProperties.CHECK2) {
final Session prev = META_LOCK_DEBUGGING.get(); // If we are locking two different databases in the same stack, just ignore it.
if (prev == null) { // This only happens in TestLinkedTable where we connect to another h2 DB in the same process.
META_LOCK_DEBUGGING.set(session); if (META_LOCK_DEBUGGING_DB.get() != null
META_LOCK_DEBUGGING_STACK.set(new Throwable("Last meta lock granted in this stack trace, "+ && META_LOCK_DEBUGGING_DB.get() != this) {
"this is debug information for following IllegalStateException")); final Session prev = META_LOCK_DEBUGGING.get();
} else if (prev != session) { if (prev == null) {
META_LOCK_DEBUGGING_STACK.get().printStackTrace(); META_LOCK_DEBUGGING.set(session);
throw new IllegalStateException("meta currently locked by " META_LOCK_DEBUGGING_DB.set(this);
+ prev +", sessionid="+ prev.getId() META_LOCK_DEBUGGING_STACK.set(new Throwable("Last meta lock granted in this stack trace, "+
+ " and trying to be locked by different session, " "this is debug information for following IllegalStateException"));
+ session +", sessionid="+ session.getId() + " on same thread"); } else if (prev != session) {
META_LOCK_DEBUGGING_STACK.get().printStackTrace();
throw new IllegalStateException("meta currently locked by "
+ prev +", sessionid="+ prev.getId()
+ " and trying to be locked by different session, "
+ session +", sessionid="+ session.getId() + " on same thread");
}
} }
} }
return meta.lock(session, true, true); return meta.lock(session, true, true);
...@@ -969,6 +976,7 @@ public class Database implements DataHandler { ...@@ -969,6 +976,7 @@ public class Database implements DataHandler {
if (SysProperties.CHECK2) { if (SysProperties.CHECK2) {
if (META_LOCK_DEBUGGING.get() == session) { if (META_LOCK_DEBUGGING.get() == session) {
META_LOCK_DEBUGGING.set(null); META_LOCK_DEBUGGING.set(null);
META_LOCK_DEBUGGING_DB.set(null);
META_LOCK_DEBUGGING_STACK.set(null); META_LOCK_DEBUGGING_STACK.set(null);
} }
} }
...@@ -1440,7 +1448,7 @@ public class Database implements DataHandler { ...@@ -1440,7 +1448,7 @@ public class Database implements DataHandler {
} }
} }
reconnectModified(false); reconnectModified(false);
if (mvStore != null) { if (mvStore != null && !mvStore.getStore().isClosed()) {
long maxCompactTime = dbSettings.maxCompactTime; long maxCompactTime = dbSettings.maxCompactTime;
if (compactMode == CommandInterface.SHUTDOWN_COMPACT) { if (compactMode == CommandInterface.SHUTDOWN_COMPACT) {
mvStore.compactFile(dbSettings.maxCompactTime); mvStore.compactFile(dbSettings.maxCompactTime);
......
...@@ -1426,7 +1426,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -1426,7 +1426,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
@Override @Override
public String toString() { public String toString() {
return "#" + serialId + " (user: " + user.getName() + ")"; return "#" + serialId + " (user: " + (user == null ? "<null>" : user.getName()) + ")";
} }
public void setUndoLogEnabled(boolean b) { public void setUndoLogEnabled(boolean b) {
......
...@@ -312,8 +312,11 @@ public class PageDataIndex extends PageIndex { ...@@ -312,8 +312,11 @@ public class PageDataIndex extends PageIndex {
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
AllColumnsForPlan allColumnsSet) { AllColumnsForPlan allColumnsSet) {
// The +200 is so that indexes that can return the same data, but have less columns, will take precedence.
// This all works out easier in the MVStore case, because MVStore uses the same cost calculation
// code for the ScanIndex (i.e. the MVPrimaryIndex) and all other indices.
return 10 * (tableData.getRowCountApproximation() + return 10 * (tableData.getRowCountApproximation() +
Constants.COST_ROW_OFFSET); Constants.COST_ROW_OFFSET) + 200;
} }
@Override @Override
......
...@@ -49,29 +49,33 @@ public class RangeIndex extends BaseIndex { ...@@ -49,29 +49,33 @@ public class RangeIndex extends BaseIndex {
long min = rangeTable.getMin(session); long min = rangeTable.getMin(session);
long max = rangeTable.getMax(session); long max = rangeTable.getMax(session);
long step = rangeTable.getStep(session); long step = rangeTable.getStep(session);
try { if (first != null) {
long v = first.getValue(0).getLong(); try {
if (step > 0) { long v = first.getValue(0).getLong();
if (v > min) { if (step > 0) {
min += (v - min + step - 1) / step * step; if (v > min) {
min += (v - min + step - 1) / step * step;
}
} else if (v > max) {
max = v;
} }
} else if (v > max) { } catch (DbException e) {
max = v; // error when converting the value - ignore
} }
} catch (Exception e) {
// error when converting the value - ignore
} }
try { if (last != null) {
long v = last.getValue(0).getLong(); try {
if (step > 0) { long v = last.getValue(0).getLong();
if (v < max) { if (step > 0) {
max = v; if (v < max) {
max = v;
}
} else if (v < min) {
min -= (min - v - step - 1) / step * step;
} }
} else if (v < min) { } catch (DbException e) {
min -= (min - v - step - 1) / step * step; // error when converting the value - ignore
} }
} catch (Exception e) {
// error when converting the value - ignore
} }
return new RangeCursor(session, min, max, step); return new RangeCursor(session, min, max, step);
} }
......
...@@ -133,7 +133,7 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex { ...@@ -133,7 +133,7 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex {
} }
Value v = row.getValue(columnIds[0]); Value v = row.getValue(columnIds[0]);
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
return null; return new SpatialKey(row.getKey());
} }
Geometry g = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getGeometryNoCopy(); Geometry g = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getGeometryNoCopy();
Envelope env = g.getEnvelopeInternal(); Envelope env = g.getEnvelopeInternal();
......
...@@ -449,7 +449,7 @@ public class MVTable extends TableBase { ...@@ -449,7 +449,7 @@ public class MVTable extends TableBase {
} }
} }
synchronized (getLockSyncObject()) { synchronized (getLockSyncObject()) {
if (lockSharedSessions.size() > 0) { if (!lockSharedSessions.isEmpty()) {
lockSharedSessions.remove(s); lockSharedSessions.remove(s);
if (SysProperties.THREAD_DEADLOCK_DETECTOR) { if (SysProperties.THREAD_DEADLOCK_DETECTOR) {
if (SHARED_LOCKS.get() != null) { if (SHARED_LOCKS.get() != null) {
......
...@@ -18,7 +18,6 @@ import java.sql.ResultSetMetaData; ...@@ -18,7 +18,6 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Arrays; import java.util.Arrays;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
...@@ -26,6 +25,7 @@ import org.h2.message.DbException; ...@@ -26,6 +25,7 @@ import org.h2.message.DbException;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.Bits; import org.h2.util.Bits;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.DataType; import org.h2.value.DataType;
...@@ -90,6 +90,7 @@ public class Data { ...@@ -90,6 +90,7 @@ public class Data {
private static final int LOCAL_TIME = 132; private static final int LOCAL_TIME = 132;
private static final int LOCAL_DATE = 133; private static final int LOCAL_DATE = 133;
private static final int LOCAL_TIMESTAMP = 134; private static final int LOCAL_TIMESTAMP = 134;
private static final byte CUSTOM_DATA_TYPE = (byte)135;
private static final long MILLIS_PER_MINUTE = 1000 * 60; private static final long MILLIS_PER_MINUTE = 1000 * 60;
...@@ -694,6 +695,14 @@ public class Data { ...@@ -694,6 +695,14 @@ public class Data {
break; break;
} }
default: default:
if (JdbcUtils.customDataTypesHandler != null) {
byte[] b = v.getBytesNoCopy();
writeByte(CUSTOM_DATA_TYPE);
writeVarInt(type);
writeVarInt(b.length);
write(b, 0, b.length);
break;
}
DbException.throwInternalError("type=" + v.getType()); DbException.throwInternalError("type=" + v.getType());
} }
if (SysProperties.CHECK2) { if (SysProperties.CHECK2) {
...@@ -878,6 +887,18 @@ public class Data { ...@@ -878,6 +887,18 @@ public class Data {
} }
return ValueResultSet.get(rs); return ValueResultSet.get(rs);
} }
case CUSTOM_DATA_TYPE: {
if (JdbcUtils.customDataTypesHandler != null) {
int customType = readVarInt();
int len = readVarInt();
byte[] b = Utils.newBytes(len);
read(b, 0, len);
return JdbcUtils.customDataTypesHandler.convert(
ValueBytes.getNoCopy(b), customType);
}
throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1,
"No CustomDataTypesHandler has been set up");
}
default: default:
if (type >= INT_0_15 && type < INT_0_15 + 16) { if (type >= INT_0_15 && type < INT_0_15 + 16) {
return ValueInt.get(type - INT_0_15); return ValueInt.get(type - INT_0_15);
...@@ -1126,6 +1147,11 @@ public class Data { ...@@ -1126,6 +1147,11 @@ public class Data {
return len; return len;
} }
default: default:
if (JdbcUtils.customDataTypesHandler != null) {
byte[] b = v.getBytesNoCopy();
return 1 + getVarIntLen(v.getType())
+ getVarIntLen(b.length) + b.length;
}
throw DbException.throwInternalError("type=" + v.getType()); throw DbException.throwInternalError("type=" + v.getType());
} }
} }
......
...@@ -11,8 +11,8 @@ import java.util.Collections; ...@@ -11,8 +11,8 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
...@@ -55,7 +55,10 @@ public class RegularTable extends TableBase { ...@@ -55,7 +55,10 @@ public class RegularTable extends TableBase {
private Index scanIndex; private Index scanIndex;
private long rowCount; private long rowCount;
private volatile Session lockExclusiveSession; private volatile Session lockExclusiveSession;
private HashSet<Session> lockSharedSessions = new HashSet<>();
// using a ConcurrentHashMap as a set
private ConcurrentHashMap<Session, Session> lockSharedSessions =
new ConcurrentHashMap<>();
/** /**
* The queue of sessions waiting to lock the table. It is a FIFO queue to * The queue of sessions waiting to lock the table. It is a FIFO queue to
...@@ -434,11 +437,6 @@ public class RegularTable extends TableBase { ...@@ -434,11 +437,6 @@ public class RegularTable extends TableBase {
session.markTableForAnalyze(this); session.markTableForAnalyze(this);
} }
@Override
public boolean isLockedExclusivelyBy(Session session) {
return lockExclusiveSession == session;
}
@Override @Override
public boolean lock(Session session, boolean exclusive, public boolean lock(Session session, boolean exclusive,
boolean forceLockEvenInMvcc) { boolean forceLockEvenInMvcc) {
...@@ -460,10 +458,10 @@ public class RegularTable extends TableBase { ...@@ -460,10 +458,10 @@ public class RegularTable extends TableBase {
if (lockExclusiveSession == session) { if (lockExclusiveSession == session) {
return true; return true;
} }
if (!exclusive && lockSharedSessions.containsKey(session)) {
return true;
}
synchronized (database) { synchronized (database) {
if (lockExclusiveSession == session) {
return true;
}
if (!exclusive && lockSharedSessions.contains(session)) { if (!exclusive && lockSharedSessions.contains(session)) {
return true; return true;
} }
...@@ -543,7 +541,7 @@ public class RegularTable extends TableBase { ...@@ -543,7 +541,7 @@ public class RegularTable extends TableBase {
lockExclusiveSession = session; lockExclusiveSession = session;
return true; return true;
} else if (lockSharedSessions.size() == 1 && } else if (lockSharedSessions.size() == 1 &&
lockSharedSessions.contains(session)) { lockSharedSessions.containsKey(session)) {
traceLock(session, exclusive, "add (upgraded) for "); traceLock(session, exclusive, "add (upgraded) for ");
lockExclusiveSession = session; lockExclusiveSession = session;
return true; return true;
...@@ -562,10 +560,10 @@ public class RegularTable extends TableBase { ...@@ -562,10 +560,10 @@ public class RegularTable extends TableBase {
return true; return true;
} }
} }
if (!lockSharedSessions.contains(session)) { if (!lockSharedSessions.containsKey(session)) {
traceLock(session, exclusive, "ok"); traceLock(session, exclusive, "ok");
session.addLock(this); session.addLock(this);
lockSharedSessions.add(session); lockSharedSessions.put(session, session);
} }
return true; return true;
} }
...@@ -626,7 +624,7 @@ public class RegularTable extends TableBase { ...@@ -626,7 +624,7 @@ public class RegularTable extends TableBase {
} }
visited.add(session); visited.add(session);
ArrayList<Session> error = null; ArrayList<Session> error = null;
for (Session s : lockSharedSessions) { for (Session s : lockSharedSessions.keySet()) {
if (s == session) { if (s == session) {
// it doesn't matter if we have locked the object already // it doesn't matter if we have locked the object already
continue; continue;
...@@ -640,10 +638,13 @@ public class RegularTable extends TableBase { ...@@ -640,10 +638,13 @@ public class RegularTable extends TableBase {
} }
} }
} }
if (error == null && lockExclusiveSession != null) { // take a local copy so we don't see inconsistent data, since we are
Table t = lockExclusiveSession.getWaitForLock(); // not locked while checking the lockExclusiveSession value
Session copyOfLockExclusiveSession = lockExclusiveSession;
if (error == null && copyOfLockExclusiveSession != null) {
Table t = copyOfLockExclusiveSession.getWaitForLock();
if (t != null) { if (t != null) {
error = t.checkDeadlock(lockExclusiveSession, clash, visited); error = t.checkDeadlock(copyOfLockExclusiveSession, clash, visited);
if (error != null) { if (error != null) {
error.add(session); error.add(session);
} }
...@@ -665,11 +666,17 @@ public class RegularTable extends TableBase { ...@@ -665,11 +666,17 @@ public class RegularTable extends TableBase {
return lockExclusiveSession != null; return lockExclusiveSession != null;
} }
@Override
public boolean isLockedExclusivelyBy(Session session) {
return lockExclusiveSession == session;
}
@Override @Override
public void unlock(Session s) { public void unlock(Session s) {
if (database != null) { if (database != null) {
traceLock(s, lockExclusiveSession == s, "unlock"); traceLock(s, lockExclusiveSession == s, "unlock");
if (lockExclusiveSession == s) { if (lockExclusiveSession == s) {
lockSharedSessions.remove(s);
lockExclusiveSession = null; lockExclusiveSession = null;
} }
synchronized (database) { synchronized (database) {
......
...@@ -30,7 +30,6 @@ import java.util.ArrayList; ...@@ -30,7 +30,6 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcResultSetBackwardsCompat; import org.h2.jdbc.JdbcResultSetBackwardsCompat;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -243,7 +242,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -243,7 +242,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
@Override @Override
public void beforeFirst() throws SQLException { public void beforeFirst() throws SQLException {
if (autoClose) { if (autoClose) {
throw DbException.get(ErrorCode.RESULT_SET_NOT_SCROLLABLE); throw DbException.get(ErrorCode.RESULT_SET_NOT_SCROLLABLE).getSQLException();
} }
rowId = -1; rowId = -1;
if (source != null) { if (source != null) {
...@@ -2253,6 +2252,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -2253,6 +2252,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
// --- private ----------------------------- // --- private -----------------------------
private void update(int columnIndex, Object obj) throws SQLException { private void update(int columnIndex, Object obj) throws SQLException {
checkClosed();
checkColumnIndex(columnIndex); checkColumnIndex(columnIndex);
this.currentRow[columnIndex - 1] = obj; this.currentRow[columnIndex - 1] = obj;
} }
...@@ -2269,6 +2269,12 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -2269,6 +2269,12 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
getSQLException(); getSQLException();
} }
private void checkClosed() throws SQLException {
if (columns == null) {
throw DbException.get(ErrorCode.OBJECT_CLOSED).getSQLException();
}
}
private void checkColumnIndex(int columnIndex) throws SQLException { private void checkColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1 || columnIndex > columns.size()) { if (columnIndex < 1 || columnIndex > columns.size()) {
throw DbException.getInvalidValueException( throw DbException.getInvalidValueException(
......
...@@ -11,7 +11,6 @@ import java.util.ArrayList; ...@@ -11,7 +11,6 @@ import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.Driver; import org.h2.Driver;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.store.fs.FilePathRec; import org.h2.store.fs.FilePathRec;
...@@ -642,6 +641,16 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -642,6 +641,16 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
test(); test();
testUnit(); testUnit();
// basic pagestore testing
memory = false;
multiThreaded = false;
mvStore = false;
mvcc = false;
test();
testUnit();
mvStore = true;
mvcc = true;
memory = true; memory = true;
multiThreaded = false; multiThreaded = false;
networked = true; networked = true;
...@@ -1112,7 +1121,11 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -1112,7 +1121,11 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
appendIf(buff, lazy, "lazy"); appendIf(buff, lazy, "lazy");
appendIf(buff, mvStore, "mvStore"); if (mvStore) {
buff.append("mvStore ");
} else {
buff.append("pageStore ");
}
appendIf(buff, big, "big"); appendIf(buff, big, "big");
appendIf(buff, networked, "net"); appendIf(buff, networked, "net");
appendIf(buff, memory, "memory"); appendIf(buff, memory, "memory");
......
...@@ -244,6 +244,8 @@ public abstract class TestBase { ...@@ -244,6 +244,8 @@ public abstract class TestBase {
if (config.mvStore) { if (config.mvStore) {
name = addOption(name, "MV_STORE", "true"); name = addOption(name, "MV_STORE", "true");
// name = addOption(name, "MVCC", "true"); // name = addOption(name, "MVCC", "true");
} else {
name = addOption(name, "MV_STORE", "false");
} }
return name; return name;
} }
......
...@@ -156,6 +156,23 @@ public class TestDateStorage extends TestBase { ...@@ -156,6 +156,23 @@ public class TestDateStorage extends TestBase {
if (config.mvStore) { if (config.mvStore) {
return; return;
} }
/**
* Disabled this test for now, explanation from Evgenij Ryazanov:<br>
* This test is executed only in PageStore mode because there is no
* reason to test it with MVStore that stores date-time values in local
* time.<br>
* There is a hard-coded configuration option for PageStore,
* org.h2.store.Data::STORE_LOCAL_TIME. <br>
* This test completes normally if this constant is changed to true.
* Probably this test was designed for this mode. But with
* STORE_LOCAL_TIME = false this test is useless. On Java 10 only 57% of
* conversions tested by this test are successful, the remaining 43%
* have different offsets due to differences in DST transitions between
* timezones.
*/
if (!config.mvStore) {
return;
}
String db = getTestName() + ";LOG=0;FILE_LOCK=NO"; String db = getTestName() + ";LOG=0;FILE_LOCK=NO";
Connection conn = getConnection(db); Connection conn = getConnection(db);
Statement stat; Statement stat;
......
...@@ -118,6 +118,10 @@ public class TestLob extends TestBase { ...@@ -118,6 +118,10 @@ public class TestLob extends TestBase {
if (config.memory || config.cipher != null) { if (config.memory || config.cipher != null) {
return; return;
} }
// TODO fails in pagestore mode
if (!config.mvStore) {
return;
}
deleteDb("lob"); deleteDb("lob");
Connection conn = getConnection("lob"); Connection conn = getConnection("lob");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
...@@ -677,6 +681,10 @@ public class TestLob extends TestBase { ...@@ -677,6 +681,10 @@ public class TestLob extends TestBase {
if (config.memory || config.mvStore) { if (config.memory || config.mvStore) {
return; return;
} }
// TODO fails in pagestore mode
if (!config.mvStore) {
return;
}
deleteDb("lob"); deleteDb("lob");
Connection conn; Connection conn;
Statement stat; Statement stat;
...@@ -730,6 +738,10 @@ public class TestLob extends TestBase { ...@@ -730,6 +738,10 @@ public class TestLob extends TestBase {
if (config.mvStore) { if (config.mvStore) {
return; return;
} }
// TODO fails in pagestore mode
if (!config.mvStore) {
return;
}
deleteDb("lob"); deleteDb("lob");
Connection conn = getConnection("lob"); Connection conn = getConnection("lob");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
...@@ -34,6 +34,10 @@ public class TestMergeUsing extends TestBase implements Trigger { ...@@ -34,6 +34,10 @@ public class TestMergeUsing extends TestBase implements Trigger {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
// TODO breaks in pagestore case
if (!config.mvStore) {
return;
}
// Simple ID,NAME inserts, target table with PK initially empty // Simple ID,NAME inserts, target table with PK initially empty
testMergeUsing( testMergeUsing(
......
...@@ -60,6 +60,10 @@ public class TestMultiThread extends TestBase implements Runnable { ...@@ -60,6 +60,10 @@ public class TestMultiThread extends TestBase implements Runnable {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
// pagestore and multithreaded was always experimental, we're not going to fix that
if (!config.mvStore) {
return;
}
testConcurrentSchemaChange(); testConcurrentSchemaChange();
testConcurrentLobAdd(); testConcurrentLobAdd();
testConcurrentView(); testConcurrentView();
......
...@@ -8,7 +8,6 @@ package org.h2.test.db; ...@@ -8,7 +8,6 @@ package org.h2.test.db;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
......
...@@ -1024,6 +1024,10 @@ public class TestSpatial extends TestBase { ...@@ -1024,6 +1024,10 @@ public class TestSpatial extends TestBase {
} }
private void testNullableGeometryUpdate() throws SQLException { private void testNullableGeometryUpdate() throws SQLException {
// TODO breaks in pagestore case
if (!config.mvStore) {
return;
}
deleteDb("spatial"); deleteDb("spatial");
Connection conn = getConnection(URL); Connection conn = getConnection(URL);
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
...@@ -12,7 +12,6 @@ import java.sql.SQLException; ...@@ -12,7 +12,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -118,9 +117,8 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -118,9 +117,8 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
stat.execute("create table test(id int) as select 1"); stat.execute("create table test(id int) as select 1");
stat.execute("create trigger test_u before update on test " + stat.execute("create trigger test_u before update on test " +
"for each row call \"" + DeleteTrigger.class.getName() + "\""); "for each row call \"" + DeleteTrigger.class.getName() + "\"");
// this threw a NullPointerException // this used to throw a NullPointerException before we fixed it
assertThrows(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, stat). stat.execute("update test set id = 2");
execute("update test set id = 2");
stat.execute("drop table test"); stat.execute("drop table test");
conn.close(); conn.close();
} }
......
...@@ -10,7 +10,6 @@ import java.sql.ResultSet; ...@@ -10,7 +10,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
...@@ -122,6 +121,10 @@ public class TestTwoPhaseCommit extends TestBase { ...@@ -122,6 +121,10 @@ public class TestTwoPhaseCommit extends TestBase {
if (config.memory) { if (config.memory) {
return; return;
} }
// TODO fails in pagestore mode
if (!config.mvStore) {
return;
}
deleteDb("twoPhaseCommit"); deleteDb("twoPhaseCommit");
Connection conn = getConnection("twoPhaseCommit"); Connection conn = getConnection("twoPhaseCommit");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
...@@ -35,7 +35,7 @@ public class TestMvcc4 extends TestBase { ...@@ -35,7 +35,7 @@ public class TestMvcc4 extends TestBase {
@Override @Override
public void test() throws SQLException { public void test() throws SQLException {
if (config.networked) { if (config.networked || !config.mvcc) {
return; return;
} }
testSelectForUpdateAndUpdateConcurrency(); testSelectForUpdateAndUpdateConcurrency();
......
...@@ -31,6 +31,9 @@ public class TestMvccMultiThreaded extends TestBase { ...@@ -31,6 +31,9 @@ public class TestMvccMultiThreaded extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
if (!config.mvcc) {
return;
}
testConcurrentSelectForUpdate(); testConcurrentSelectForUpdate();
testMergeWithUniqueKeyViolation(); testMergeWithUniqueKeyViolation();
// not supported currently // not supported currently
......
...@@ -43,6 +43,9 @@ public class TestMvccMultiThreaded2 extends TestBase { ...@@ -43,6 +43,9 @@ public class TestMvccMultiThreaded2 extends TestBase {
@Override @Override
public void test() throws SQLException, InterruptedException { public void test() throws SQLException, InterruptedException {
if (!config.mvcc) {
return;
}
testSelectForUpdateConcurrency(); testSelectForUpdateConcurrency();
} }
......
...@@ -26,13 +26,6 @@ public class RecoverLobTest extends TestBase { ...@@ -26,13 +26,6 @@ public class RecoverLobTest extends TestBase {
TestBase.createCaller().init().test(); TestBase.createCaller().init().test();
} }
@Override
public TestBase init() throws Exception {
TestBase tb = super.init();
config.mvStore = false;
return tb;
}
@Override @Override
public void test() throws Exception { public void test() throws Exception {
if (config.mvStore || config.memory) { if (config.mvStore || config.memory) {
......
...@@ -47,7 +47,6 @@ public class TestScript extends TestBase { ...@@ -47,7 +47,6 @@ public class TestScript extends TestBase {
private Statement stat; private Statement stat;
private String fileName; private String fileName;
private LineNumberReader in; private LineNumberReader in;
private int outputLineNo;
private PrintStream out; private PrintStream out;
private final ArrayList<String[]> result = new ArrayList<>(); private final ArrayList<String[]> result = new ArrayList<>();
private String putBack; private String putBack;
...@@ -177,7 +176,6 @@ public class TestScript extends TestBase { ...@@ -177,7 +176,6 @@ public class TestScript extends TestBase {
stat = null; stat = null;
fileName = null; fileName = null;
in = null; in = null;
outputLineNo = 0;
out = null; out = null;
result.clear(); result.clear();
putBack = null; putBack = null;
...@@ -550,7 +548,6 @@ public class TestScript extends TestBase { ...@@ -550,7 +548,6 @@ public class TestScript extends TestBase {
} }
private void write(String s) { private void write(String s) {
outputLineNo++;
out.println(s); out.println(s);
} }
......
...@@ -204,7 +204,8 @@ is null or three.val>=DATE'2006-07-01'; ...@@ -204,7 +204,8 @@ is null or three.val>=DATE'2006-07-01';
explain select * from one natural join two left join two three on explain select * from one natural join two left join two three on
one.id=three.id left join one four on two.id=four.id where three.val one.id=three.id left join one four on two.id=four.id where three.val
is null or three.val>=DATE'2006-07-01'; is null or three.val>=DATE'2006-07-01';
>> SELECT ONE.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.ONE.tableScan */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_14: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ ON 1=1 /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID */ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_14: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01')) #+mvStore#>> SELECT ONE.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.ONE.tableScan */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_14: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ ON 1=1 /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID */ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_14: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01'))
#-mvStore#>> SELECT ONE.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.PRIMARY_KEY_1 */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_14: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ ON 1=1 /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID */ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_14: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01'))
-- Query #4: same as #3, but the joins have been manually re-ordered -- Query #4: same as #3, but the joins have been manually re-ordered
-- Correct result set, same as expected for #3. -- Correct result set, same as expected for #3.
...@@ -254,7 +255,7 @@ inner join test2 on test1.id=test2.id left ...@@ -254,7 +255,7 @@ inner join test2 on test1.id=test2.id left
outer join test3 on test2.id=test3.id outer join test3 on test2.id=test3.id
where test3.id is null; where test3.id is null;
#+mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID) #+mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
#-mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST1 /* PUBLIC.TEST1.tableScan */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_4C: ID = TEST1.ID AND ID = TEST1.ID */ ON 1=1 /* WHERE TEST1.ID = TEST2.ID */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID) #-mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4 */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_4C: ID = TEST1.ID AND ID = TEST1.ID */ ON 1=1 /* WHERE TEST1.ID = TEST2.ID */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
insert into test1 select x from system_range(2, 1000); insert into test1 select x from system_range(2, 1000);
> update count: 999 > update count: 999
...@@ -271,7 +272,8 @@ explain select * from test1 ...@@ -271,7 +272,8 @@ explain select * from test1
inner join test2 on test1.id=test2.id inner join test2 on test1.id=test2.id
left outer join test3 on test2.id=test3.id left outer join test3 on test2.id=test3.id
where test3.id is null; where test3.id is null;
>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID) #+mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
#-mvStore#>> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_4C */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_4C0: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID INNER JOIN PUBLIC.TEST1 /* PUBLIC.PRIMARY_KEY_4: ID = TEST2.ID */ ON 1=1 WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
SELECT TEST1.ID, TEST2.ID, TEST3.ID SELECT TEST1.ID, TEST2.ID, TEST3.ID
FROM TEST2 FROM TEST2
......
...@@ -50,6 +50,9 @@ public class TestMVTableEngine extends TestBase { ...@@ -50,6 +50,9 @@ public class TestMVTableEngine extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
if (!config.mvStore) {
return;
}
testLobCopy(); testLobCopy();
testLobReuse(); testLobReuse();
testShutdownDuringLobCreation(); testShutdownDuringLobCreation();
......
...@@ -11,7 +11,6 @@ import java.sql.ResultSet; ...@@ -11,7 +11,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Random; import java.util.Random;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.Task; import org.h2.util.Task;
...@@ -37,8 +36,11 @@ public class TestConcurrentUpdate extends TestBase { ...@@ -37,8 +36,11 @@ public class TestConcurrentUpdate extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
if (!config.multiThreaded) {
return;
}
deleteDb("concurrent"); deleteDb("concurrent");
final String url = getURL("concurrent;MULTI_THREADED=TRUE", true); final String url = getURL("concurrent", true);
Connection conn = getConnection(url); Connection conn = getConnection(url);
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar)"); stat.execute("create table test(id int primary key, name varchar)");
......
...@@ -17,7 +17,6 @@ import java.sql.SQLException; ...@@ -17,7 +17,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.util.Properties; import java.util.Properties;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.Server; import org.h2.tools.Server;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论