提交 5c555202 authored 作者: Thomas Mueller Graf's avatar Thomas Mueller Graf

Formatting, Javadocs

上级 986af2a3
...@@ -144,6 +144,7 @@ public class Driver implements java.sql.Driver { ...@@ -144,6 +144,7 @@ public class Driver implements java.sql.Driver {
* [Not supported] * [Not supported]
*/ */
/*## Java 1.7 ## /*## Java 1.7 ##
@Override
public Logger getParentLogger() { public Logger getParentLogger() {
return null; return null;
} }
......
...@@ -1913,7 +1913,7 @@ public class Parser { ...@@ -1913,7 +1913,7 @@ public class Parser {
} }
} }
private static int compareTableFilters(TableFilter o1, TableFilter o2) { static int compareTableFilters(TableFilter o1, TableFilter o2) {
assert o1.getOrderInFrom() != o2.getOrderInFrom(); assert o1.getOrderInFrom() != o2.getOrderInFrom();
return o1.getOrderInFrom() > o2.getOrderInFrom() ? 1 : -1; return o1.getOrderInFrom() > o2.getOrderInFrom() ? 1 : -1;
} }
......
...@@ -9,7 +9,6 @@ import org.h2.command.dml.Query; ...@@ -9,7 +9,6 @@ import org.h2.command.dml.Query;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.SubQueryInfo;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value; import org.h2.value.Value;
......
...@@ -13,7 +13,6 @@ import org.h2.index.IndexCondition; ...@@ -13,7 +13,6 @@ import org.h2.index.IndexCondition;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.SubQueryInfo;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value; import org.h2.value.Value;
......
...@@ -12,7 +12,6 @@ import org.h2.engine.Session; ...@@ -12,7 +12,6 @@ import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.SubQueryInfo;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueArray;
......
...@@ -14,39 +14,39 @@ import org.h2.result.SearchRow; ...@@ -14,39 +14,39 @@ import org.h2.result.SearchRow;
* H2 engine will be calling {@link #addSearchRows(SearchRow, SearchRow)} until * H2 engine will be calling {@link #addSearchRows(SearchRow, SearchRow)} until
* method {@link #isBatchFull()}} will return {@code true} or there are no more * method {@link #isBatchFull()}} will return {@code true} or there are no more
* search rows to add. Then method {@link #find()} will be called to execute batched lookup. * search rows to add. Then method {@link #find()} will be called to execute batched lookup.
* Note that a single instance of {@link IndexLookupBatch} can be reused for multiple * Note that a single instance of {@link IndexLookupBatch} can be reused for multiple
* sequential batched lookups, moreover it can be reused for multiple queries for * sequential batched lookups, moreover it can be reused for multiple queries for
* the same prepared statement. * the same prepared statement.
* *
* @see Index#createLookupBatch(org.h2.table.TableFilter) * @see Index#createLookupBatch(org.h2.table.TableFilter)
* @author Sergi Vladykin * @author Sergi Vladykin
*/ */
public interface IndexLookupBatch { public interface IndexLookupBatch {
/** /**
* Add search row pair to the batch. * Add search row pair to the batch.
* *
* @param first the first row, or null for no limit * @param first the first row, or null for no limit
* @param last the last row, or null for no limit * @param last the last row, or null for no limit
* @return {@code false} if this search row pair is known to produce no results * @return {@code false} if this search row pair is known to produce no results
* and thus the given row pair was not added * and thus the given row pair was not added
* @see Index#find(TableFilter, SearchRow, SearchRow) * @see Index#find(org.h2.table.TableFilter, SearchRow, SearchRow)
*/ */
boolean addSearchRows(SearchRow first, SearchRow last); boolean addSearchRows(SearchRow first, SearchRow last);
/** /**
* Check if this batch is full. * Check if this batch is full.
* *
* @return {@code true} If batch is full, will not accept any * @return {@code true} If batch is full, will not accept any
* more rows and {@link #find()} can be executed. * more rows and {@link #find()} can be executed.
*/ */
boolean isBatchFull(); boolean isBatchFull();
/** /**
* Execute batched lookup and return future cursor for each provided * Execute batched lookup and return future cursor for each provided
* search row pair. Note that this method must return exactly the same number * search row pair. Note that this method must return exactly the same number
* of future cursors in result list as number of {@link #addSearchRows(SearchRow, SearchRow)} * of future cursors in result list as number of {@link #addSearchRows(SearchRow, SearchRow)}
* calls has been done before {@link #find()} call exactly in the same order. * calls has been done before {@link #find()} call exactly in the same order.
* *
* @return List of future cursors for collected search rows. * @return List of future cursors for collected search rows.
*/ */
List<Future<Cursor>> find(); List<Future<Cursor>> find();
......
...@@ -69,7 +69,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex { ...@@ -69,7 +69,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
columns = new Column[0]; columns = new Column[0];
this.createSession = null; this.createSession = null;
this.indexMasks = null; this.indexMasks = null;
// this is a main index of TableView, it does not need eviction time stamp // this is a main index of TableView, it does not need eviction time stamp
evaluatedAt = Long.MIN_VALUE; evaluatedAt = Long.MIN_VALUE;
} }
...@@ -171,8 +171,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex { ...@@ -171,8 +171,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
return (Query) p; return (Query) p;
} }
private Cursor findRecursive(Session session, SearchRow first, SearchRow last, private Cursor findRecursive(SearchRow first, SearchRow last) {
SearchRow intersection) {
assert recursive; assert recursive;
LocalResult recResult = view.getRecursiveResult(); LocalResult recResult = view.getRecursiveResult();
if (recResult != null) { if (recResult != null) {
...@@ -266,7 +265,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex { ...@@ -266,7 +265,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
private Cursor find(Session session, SearchRow first, SearchRow last, private Cursor find(Session session, SearchRow first, SearchRow last,
SearchRow intersection) { SearchRow intersection) {
if (recursive) { if (recursive) {
return findRecursive(session, first, last, intersection); return findRecursive(first, last);
} }
setupQueryParameters(session, first, last, intersection); setupQueryParameters(session, first, last, intersection);
LocalResult result = query.query(0); LocalResult result = query.query(0);
......
...@@ -25,7 +25,7 @@ public abstract class RowFactory { ...@@ -25,7 +25,7 @@ public abstract class RowFactory {
/** /**
* Default implementation of row factory. * Default implementation of row factory.
*/ */
private static final class DefaultRowFactory extends RowFactory { static final class DefaultRowFactory extends RowFactory {
@Override @Override
public Row createRow(Value[] data, int memory) { public Row createRow(Value[] data, int memory) {
return new RowImpl(data, memory); return new RowImpl(data, memory);
......
...@@ -33,6 +33,7 @@ public class RowImpl extends Row { ...@@ -33,6 +33,7 @@ public class RowImpl extends Row {
* *
* @return a new row with the same data * @return a new row with the same data
*/ */
@Override
public Row getCopy() { public Row getCopy() {
Value[] d2 = new Value[data.length]; Value[] d2 = new Value[data.length];
System.arraycopy(data, 0, d2, 0, data.length); System.arraycopy(data, 0, d2, 0, data.length);
...@@ -54,6 +55,7 @@ public class RowImpl extends Row { ...@@ -54,6 +55,7 @@ public class RowImpl extends Row {
return version; return version;
} }
@Override
public void setVersion(int version) { public void setVersion(int version) {
this.version = version; this.version = version;
} }
...@@ -79,6 +81,7 @@ public class RowImpl extends Row { ...@@ -79,6 +81,7 @@ public class RowImpl extends Row {
* @param dummy the template buffer * @param dummy the template buffer
* @return the number of bytes * @return the number of bytes
*/ */
@Override
public int getByteCount(Data dummy) { public int getByteCount(Data dummy) {
int size = 0; int size = 0;
for (Value v : data) { for (Value v : data) {
...@@ -96,6 +99,7 @@ public class RowImpl extends Row { ...@@ -96,6 +99,7 @@ public class RowImpl extends Row {
} }
} }
@Override
public boolean isEmpty() { public boolean isEmpty() {
return data == null; return data == null;
} }
...@@ -145,14 +149,17 @@ public class RowImpl extends Row { ...@@ -145,14 +149,17 @@ public class RowImpl extends Row {
return buff.append(')').toString(); return buff.append(')').toString();
} }
@Override
public void setDeleted(boolean deleted) { public void setDeleted(boolean deleted) {
this.deleted = deleted; this.deleted = deleted;
} }
@Override
public void setSessionId(int sessionId) { public void setSessionId(int sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }
@Override
public int getSessionId() { public int getSessionId() {
return sessionId; return sessionId;
} }
...@@ -160,14 +167,17 @@ public class RowImpl extends Row { ...@@ -160,14 +167,17 @@ public class RowImpl extends Row {
/** /**
* This record has been committed. The session id is reset. * This record has been committed. The session id is reset.
*/ */
@Override
public void commit() { public void commit() {
this.sessionId = 0; this.sessionId = 0;
} }
@Override
public boolean isDeleted() { public boolean isDeleted() {
return deleted; return deleted;
} }
@Override
public Value[] getValueList() { public Value[] getValueList() {
return data; return data;
} }
......
...@@ -31,13 +31,13 @@ import org.h2.value.ValueLong; ...@@ -31,13 +31,13 @@ import org.h2.value.ValueLong;
/** /**
* Support for asynchronous batched index lookups on joins. * Support for asynchronous batched index lookups on joins.
* *
* @see org.h2.index.Index#createLookupBatch(TableFilter) * @see org.h2.index.Index#createLookupBatch(TableFilter)
* @see IndexLookupBatch * @see IndexLookupBatch
* @author Sergi Vladykin * @author Sergi Vladykin
*/ */
public final class JoinBatch { public final class JoinBatch {
private static final Cursor EMPTY_CURSOR = new Cursor() { static final Cursor EMPTY_CURSOR = new Cursor() {
@Override @Override
public boolean previous() { public boolean previous() {
return false; return false;
...@@ -64,13 +64,12 @@ public final class JoinBatch { ...@@ -64,13 +64,12 @@ public final class JoinBatch {
} }
}; };
private static final Future<Cursor> EMPTY_FUTURE_CURSOR = new DoneFuture<Cursor>(EMPTY_CURSOR); static final Future<Cursor> EMPTY_FUTURE_CURSOR = new DoneFuture<Cursor>(EMPTY_CURSOR);
private boolean batchedSubQuery; Future<Cursor> viewTopFutureCursor;
private Future<Cursor> viewTopFutureCursor; JoinFilter top;
JoinFilter[] filters;
private JoinFilter[] filters; boolean batchedSubQuery;
private JoinFilter top;
private boolean started; private boolean started;
...@@ -104,11 +103,11 @@ public final class JoinBatch { ...@@ -104,11 +103,11 @@ public final class JoinBatch {
public IndexLookupBatch getLookupBatch(int joinFilterId) { public IndexLookupBatch getLookupBatch(int joinFilterId) {
return filters[joinFilterId].lookupBatch; return filters[joinFilterId].lookupBatch;
} }
/** /**
* Reset state of this batch. * Reset state of this batch.
* *
* @param beforeQuery {@code true} if reset was called before the query run, {@code false} if after * @param beforeQuery {@code true} if reset was called before the query run, {@code false} if after
*/ */
public void reset(boolean beforeQuery) { public void reset(boolean beforeQuery) {
current = null; current = null;
...@@ -176,8 +175,8 @@ public final class JoinBatch { ...@@ -176,8 +175,8 @@ public final class JoinBatch {
/** /**
* Get next row from the join batch. * Get next row from the join batch.
* *
* @return * @return true if there is a next row
*/ */
public boolean next() { public boolean next() {
if (!started) { if (!started) {
...@@ -229,18 +228,18 @@ public final class JoinBatch { ...@@ -229,18 +228,18 @@ public final class JoinBatch {
return false; return false;
} }
current.prev = null; current.prev = null;
final int lastJfId = filters.length - 1; final int lastJfId = filters.length - 1;
int jfId = lastJfId; int jfId = lastJfId;
while (current.row(jfId) == null) { while (current.row(jfId) == null) {
// lookup for the first non fetched filter for the current row // lookup for the first non fetched filter for the current row
jfId--; jfId--;
} }
for (;;) { for (;;) {
fetchCurrent(jfId); fetchCurrent(jfId);
if (!current.isDropped()) { if (!current.isDropped()) {
// if current was not dropped then it must be fetched successfully // if current was not dropped then it must be fetched successfully
if (jfId == lastJfId) { if (jfId == lastJfId) {
...@@ -269,12 +268,12 @@ public final class JoinBatch { ...@@ -269,12 +268,12 @@ public final class JoinBatch {
} }
assert !current.isDropped(); assert !current.isDropped();
assert jfId != lastJfId; assert jfId != lastJfId;
jfId = 0; jfId = 0;
while (current.row(jfId) != null) { while (current.row(jfId) != null) {
jfId++; jfId++;
} }
// force find on half filled batch (there must be either searchRows // force find on half filled batch (there must be either searchRows
// or Cursor.EMPTY set for null-rows) // or Cursor.EMPTY set for null-rows)
current = filters[jfId].find(current); current = filters[jfId].find(current);
} else { } else {
...@@ -290,7 +289,7 @@ public final class JoinBatch { ...@@ -290,7 +289,7 @@ public final class JoinBatch {
} }
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void fetchCurrent(final int jfId) { private void fetchCurrent(final int jfId) {
assert current.prev == null || current.prev.isRow(jfId) : "prev must be already fetched"; assert current.prev == null || current.prev.isRow(jfId) : "prev must be already fetched";
...@@ -370,7 +369,7 @@ public final class JoinBatch { ...@@ -370,7 +369,7 @@ public final class JoinBatch {
/** /**
* Create index lookup batch for a view index. * Create index lookup batch for a view index.
* *
* @param viewIndex view index * @param viewIndex view index
* @return index lookup batch or {@code null} if batching is not supported for this query * @return index lookup batch or {@code null} if batching is not supported for this query
*/ */
...@@ -391,7 +390,7 @@ public final class JoinBatch { ...@@ -391,7 +390,7 @@ public final class JoinBatch {
} }
/** /**
* Create fake index lookup batch for non-batched table filter. * Create fake index lookup batch for non-batched table filter.
* *
* @param filter the table filter * @param filter the table filter
* @return fake index lookup batch * @return fake index lookup batch
...@@ -403,7 +402,7 @@ public final class JoinBatch { ...@@ -403,7 +402,7 @@ public final class JoinBatch {
@Override @Override
public String toString() { public String toString() {
return "JoinBatch->\nprev->" + (current == null ? null : current.prev) + return "JoinBatch->\nprev->" + (current == null ? null : current.prev) +
"\ncurr->" + current + "\ncurr->" + current +
"\nnext->" + (current == null ? null : current.next); "\nnext->" + (current == null ? null : current.next);
} }
...@@ -411,13 +410,12 @@ public final class JoinBatch { ...@@ -411,13 +410,12 @@ public final class JoinBatch {
* Table filter participating in batched join. * Table filter participating in batched join.
*/ */
private static final class JoinFilter { private static final class JoinFilter {
private final TableFilter filter; final IndexLookupBatch lookupBatch;
private final JoinFilter join; final int id;
private final int id; final JoinFilter join;
final TableFilter filter;
private final IndexLookupBatch lookupBatch;
private JoinFilter(IndexLookupBatch lookupBatch, TableFilter filter, JoinFilter join) { JoinFilter(IndexLookupBatch lookupBatch, TableFilter filter, JoinFilter join) {
this.filter = filter; this.filter = filter;
this.id = filter.getJoinFilterId(); this.id = filter.getJoinFilterId();
this.join = join; this.join = join;
...@@ -425,32 +423,32 @@ public final class JoinBatch { ...@@ -425,32 +423,32 @@ public final class JoinBatch {
assert lookupBatch != null || id == 0; assert lookupBatch != null || id == 0;
} }
private void reset(boolean beforeQuery) { void reset(boolean beforeQuery) {
if (lookupBatch != null) { if (lookupBatch != null) {
lookupBatch.reset(beforeQuery); lookupBatch.reset(beforeQuery);
} }
} }
private Row getNullRow() { Row getNullRow() {
return filter.getTable().getNullRow(); return filter.getTable().getNullRow();
} }
private boolean isOuterJoin() { boolean isOuterJoin() {
return filter.isJoinOuter(); return filter.isJoinOuter();
} }
private boolean isBatchFull() { boolean isBatchFull() {
return lookupBatch.isBatchFull(); return lookupBatch.isBatchFull();
} }
private boolean isOk(boolean ignoreJoinCondition) { boolean isOk(boolean ignoreJoinCondition) {
boolean filterOk = filter.isOk(filter.getFilterCondition()); boolean filterOk = filter.isOk(filter.getFilterCondition());
boolean joinOk = filter.isOk(filter.getJoinCondition()); boolean joinOk = filter.isOk(filter.getJoinCondition());
return filterOk && (ignoreJoinCondition || joinOk); return filterOk && (ignoreJoinCondition || joinOk);
} }
private boolean collectSearchRows() { boolean collectSearchRows() {
assert !isBatchFull(); assert !isBatchFull();
IndexCursor c = filter.getIndexCursor(); IndexCursor c = filter.getIndexCursor();
c.prepare(filter.getSession(), filter.getIndexConditions()); c.prepare(filter.getSession(), filter.getIndexConditions());
...@@ -460,11 +458,11 @@ public final class JoinBatch { ...@@ -460,11 +458,11 @@ public final class JoinBatch {
return lookupBatch.addSearchRows(c.getStart(), c.getEnd()); return lookupBatch.addSearchRows(c.getStart(), c.getEnd());
} }
private List<Future<Cursor>> find() { List<Future<Cursor>> find() {
return lookupBatch.find(); return lookupBatch.find();
} }
private JoinRow find(JoinRow current) { JoinRow find(JoinRow current) {
assert current != null; assert current != null;
// lookupBatch is allowed to be empty when we have some null-rows and forced find call // lookupBatch is allowed to be empty when we have some null-rows and forced find call
...@@ -520,6 +518,9 @@ public final class JoinBatch { ...@@ -520,6 +518,9 @@ public final class JoinBatch {
private static final long S_MASK = 3; private static final long S_MASK = 3;
JoinRow prev;
JoinRow next;
/** /**
* May contain one of the following: * May contain one of the following:
* <br/>- {@code null}: means that we need to get future cursor for this row * <br/>- {@code null}: means that we need to get future cursor for this row
...@@ -530,13 +531,10 @@ public final class JoinBatch { ...@@ -530,13 +531,10 @@ public final class JoinBatch {
private Object[] row; private Object[] row;
private long state; private long state;
private JoinRow prev;
private JoinRow next;
/** /**
* @param row Row. * @param row Row.
*/ */
private JoinRow(Object[] row) { JoinRow(Object[] row) {
this.row = row; this.row = row;
} }
...@@ -563,22 +561,22 @@ public final class JoinBatch { ...@@ -563,22 +561,22 @@ public final class JoinBatch {
state += i << (joinFilterId << 1); state += i << (joinFilterId << 1);
} }
private void updateRow(int joinFilterId, Object x, long oldState, long newState) { void updateRow(int joinFilterId, Object x, long oldState, long newState) {
assert getState(joinFilterId) == oldState : "old state: " + getState(joinFilterId); assert getState(joinFilterId) == oldState : "old state: " + getState(joinFilterId);
row[joinFilterId] = x; row[joinFilterId] = x;
incrementState(joinFilterId, newState - oldState); incrementState(joinFilterId, newState - oldState);
assert getState(joinFilterId) == newState : "new state: " + getState(joinFilterId); assert getState(joinFilterId) == newState : "new state: " + getState(joinFilterId);
} }
private Object row(int joinFilterId) { Object row(int joinFilterId) {
return row[joinFilterId]; return row[joinFilterId];
} }
private boolean isRow(int joinFilterId) { boolean isRow(int joinFilterId) {
return getState(joinFilterId) == S_ROW; return getState(joinFilterId) == S_ROW;
} }
private boolean isFuture(int joinFilterId) { boolean isFuture(int joinFilterId) {
return getState(joinFilterId) == S_FUTURE; return getState(joinFilterId) == S_FUTURE;
} }
...@@ -586,15 +584,15 @@ public final class JoinBatch { ...@@ -586,15 +584,15 @@ public final class JoinBatch {
return getState(joinFilterId) == S_CURSOR; return getState(joinFilterId) == S_CURSOR;
} }
private boolean isComplete() { boolean isComplete() {
return isRow(row.length - 1); return isRow(row.length - 1);
} }
private boolean isDropped() { boolean isDropped() {
return row == null; return row == null;
} }
private void drop() { void drop() {
if (prev != null) { if (prev != null) {
prev.next = next; prev.next = next;
} }
...@@ -610,7 +608,7 @@ public final class JoinBatch { ...@@ -610,7 +608,7 @@ public final class JoinBatch {
* @param jfId The last fetched filter id. * @param jfId The last fetched filter id.
* @return The copy. * @return The copy.
*/ */
private JoinRow copyBehind(int jfId) { JoinRow copyBehind(int jfId) {
assert isCursor(jfId); assert isCursor(jfId);
assert jfId + 1 == row.length || row[jfId + 1] == null; assert jfId + 1 == row.length || row[jfId + 1] == null;
...@@ -638,7 +636,7 @@ public final class JoinBatch { ...@@ -638,7 +636,7 @@ public final class JoinBatch {
} }
/** /**
* Fake Lookup batch for indexes which do not support batching but have to participate * Fake Lookup batch for indexes which do not support batching but have to participate
* in batched joins. * in batched joins.
*/ */
private static final class FakeLookupBatch implements IndexLookupBatch { private static final class FakeLookupBatch implements IndexLookupBatch {
...@@ -651,7 +649,7 @@ public final class JoinBatch { ...@@ -651,7 +649,7 @@ public final class JoinBatch {
private final List<Future<Cursor>> result = new SingletonList<Future<Cursor>>(); private final List<Future<Cursor>> result = new SingletonList<Future<Cursor>>();
private FakeLookupBatch(TableFilter filter) { FakeLookupBatch(TableFilter filter) {
this.filter = filter; this.filter = filter;
} }
...@@ -697,7 +695,7 @@ public final class JoinBatch { ...@@ -697,7 +695,7 @@ public final class JoinBatch {
/** /**
* Simple singleton list. * Simple singleton list.
*/ */
private static final class SingletonList<E> extends AbstractList<E> { static final class SingletonList<E> extends AbstractList<E> {
private E element; private E element;
@Override @Override
...@@ -718,11 +716,11 @@ public final class JoinBatch { ...@@ -718,11 +716,11 @@ public final class JoinBatch {
return 1; return 1;
} }
} }
/** /**
* Base class for SELECT and SELECT UNION view index lookup batches. * Base class for SELECT and SELECT UNION view index lookup batches.
*/ */
private abstract static class ViewIndexLookupBatchBase<R extends QueryRunnerBase> private abstract static class ViewIndexLookupBatchBase<R extends QueryRunnerBase>
implements IndexLookupBatch { implements IndexLookupBatch {
protected final ViewIndex viewIndex; protected final ViewIndex viewIndex;
private final ArrayList<Future<Cursor>> result = New.arrayList(); private final ArrayList<Future<Cursor>> result = New.arrayList();
...@@ -783,7 +781,7 @@ public final class JoinBatch { ...@@ -783,7 +781,7 @@ public final class JoinBatch {
resultSize++; resultSize++;
return true; return true;
} }
@Override @Override
public void reset(boolean beforeQuery) { public void reset(boolean beforeQuery) {
if (resultSize != 0 && !resetAfterFind()) { if (resultSize != 0 && !resetAfterFind()) {
...@@ -794,7 +792,7 @@ public final class JoinBatch { ...@@ -794,7 +792,7 @@ public final class JoinBatch {
resultSize = 0; resultSize = 0;
} }
} }
@Override @Override
public final List<Future<Cursor>> find() { public final List<Future<Cursor>> find() {
if (resultSize == 0) { if (resultSize == 0) {
...@@ -805,7 +803,7 @@ public final class JoinBatch { ...@@ -805,7 +803,7 @@ public final class JoinBatch {
return resultSize == result.size() ? result : result.subList(0, resultSize); return resultSize == result.size() ? result : result.subList(0, resultSize);
} }
} }
/** /**
* Lazy query runner base. * Lazy query runner base.
*/ */
...@@ -831,27 +829,27 @@ public final class JoinBatch { ...@@ -831,27 +829,27 @@ public final class JoinBatch {
clear(); clear();
return false; return false;
} }
protected final ViewCursor newCursor(LocalResult localResult) { protected final ViewCursor newCursor(LocalResult localResult) {
ViewCursor cursor = new ViewCursor(viewIndex, localResult, first, last); ViewCursor cursor = new ViewCursor(viewIndex, localResult, first, last);
clear(); clear();
return cursor; return cursor;
} }
} }
/** /**
* View index lookup batch for a simple SELECT. * View index lookup batch for a simple SELECT.
*/ */
private final class ViewIndexLookupBatch extends ViewIndexLookupBatchBase<QueryRunner> { private final class ViewIndexLookupBatch extends ViewIndexLookupBatchBase<QueryRunner> {
private ViewIndexLookupBatch(ViewIndex viewIndex) { ViewIndexLookupBatch(ViewIndex viewIndex) {
super(viewIndex); super(viewIndex);
} }
@Override @Override
protected QueryRunner newQueryRunner() { protected QueryRunner newQueryRunner() {
return new QueryRunner(viewIndex); return new QueryRunner(viewIndex);
} }
@Override @Override
protected boolean collectSearchRows(QueryRunner r) { protected boolean collectSearchRows(QueryRunner r) {
return top.collectSearchRows(); return top.collectSearchRows();
...@@ -882,12 +880,13 @@ public final class JoinBatch { ...@@ -882,12 +880,13 @@ public final class JoinBatch {
* Query runner. * Query runner.
*/ */
private final class QueryRunner extends QueryRunnerBase { private final class QueryRunner extends QueryRunnerBase {
private Future<Cursor> topFutureCursor; Future<Cursor> topFutureCursor;
public QueryRunner(ViewIndex viewIndex) { public QueryRunner(ViewIndex viewIndex) {
super(viewIndex); super(viewIndex);
} }
@Override
protected void clear() { protected void clear() {
super.clear(); super.clear();
topFutureCursor = null; topFutureCursor = null;
...@@ -916,15 +915,15 @@ public final class JoinBatch { ...@@ -916,15 +915,15 @@ public final class JoinBatch {
*/ */
private static final class ViewIndexLookupBatchUnion private static final class ViewIndexLookupBatchUnion
extends ViewIndexLookupBatchBase<QueryRunnerUnion> { extends ViewIndexLookupBatchBase<QueryRunnerUnion> {
private ArrayList<JoinFilter> filters; ArrayList<JoinFilter> filters;
private ArrayList<JoinBatch> joinBatches; ArrayList<JoinBatch> joinBatches;
private boolean onlyBatchedQueries = true; private boolean onlyBatchedQueries = true;
protected ViewIndexLookupBatchUnion(ViewIndex viewIndex) { protected ViewIndexLookupBatchUnion(ViewIndex viewIndex) {
super(viewIndex); super(viewIndex);
} }
private boolean initialize() { boolean initialize() {
return collectJoinBatches(viewIndex.getQuery()) && joinBatches != null; return collectJoinBatches(viewIndex.getQuery()) && joinBatches != null;
} }
...@@ -1005,8 +1004,8 @@ public final class JoinBatch { ...@@ -1005,8 +1004,8 @@ public final class JoinBatch {
* Query runner for UNION. * Query runner for UNION.
*/ */
private static class QueryRunnerUnion extends QueryRunnerBase { private static class QueryRunnerUnion extends QueryRunnerBase {
Future<Cursor>[] topFutureCursors;
private ViewIndexLookupBatchUnion batchUnion; private ViewIndexLookupBatchUnion batchUnion;
private Future<Cursor>[] topFutureCursors;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public QueryRunnerUnion(ViewIndexLookupBatchUnion batchUnion) { public QueryRunnerUnion(ViewIndexLookupBatchUnion batchUnion) {
......
...@@ -240,6 +240,16 @@ public abstract class Table extends SchemaObjectBase { ...@@ -240,6 +240,16 @@ public abstract class Table extends SchemaObjectBase {
*/ */
public abstract Index getScanIndex(Session session); public abstract Index getScanIndex(Session session);
/**
* Get the scan index for this table.
*
* @param session the session
* @param masks the search mask
* @param filters the table filters
* @param filter the filer index
* @param sortOrder the sort order
* @return the scan index
*/
public Index getScanIndex(Session session, int[] masks, public Index getScanIndex(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder) { TableFilter[] filters, int filter, SortOrder sortOrder) {
return getScanIndex(session); return getScanIndex(session);
...@@ -699,7 +709,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -699,7 +709,7 @@ public abstract class Table extends SchemaObjectBase {
item.cost = item.getIndex().getCost(session, null, filters, filter, null); item.cost = item.getIndex().getCost(session, null, filters, filter, null);
Trace t = session.getTrace(); Trace t = session.getTrace();
if (t.isDebugEnabled()) { if (t.isDebugEnabled()) {
t.debug("Table : potential plan item cost {0} index {1}", t.debug("Table : potential plan item cost {0} index {1}",
item.cost, item.getIndex().getPlanSQL()); item.cost, item.getIndex().getPlanSQL());
} }
ArrayList<Index> indexes = getIndexes(); ArrayList<Index> indexes = getIndexes();
...@@ -708,7 +718,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -708,7 +718,7 @@ public abstract class Table extends SchemaObjectBase {
Index index = indexes.get(i); Index index = indexes.get(i);
double cost = index.getCost(session, masks, filters, filter, sortOrder); double cost = index.getCost(session, masks, filters, filter, sortOrder);
if (t.isDebugEnabled()) { if (t.isDebugEnabled()) {
t.debug("Table : potential plan item cost {0} index {1}", t.debug("Table : potential plan item cost {0} index {1}",
cost, index.getPlanSQL()); cost, index.getPlanSQL());
} }
if (cost < item.cost) { if (cost < item.cost) {
......
...@@ -21,7 +21,6 @@ import org.h2.index.Index; ...@@ -21,7 +21,6 @@ import org.h2.index.Index;
import org.h2.index.IndexCondition; import org.h2.index.IndexCondition;
import org.h2.index.IndexCursor; import org.h2.index.IndexCursor;
import org.h2.index.IndexLookupBatch; import org.h2.index.IndexLookupBatch;
import org.h2.index.ScanIndex;
import org.h2.index.ViewIndex; import org.h2.index.ViewIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -213,9 +212,9 @@ public class TableFilter implements ColumnResolver { ...@@ -213,9 +212,9 @@ public class TableFilter implements ColumnResolver {
item.cost -= item.cost * indexConditions.size() / 100 / (filter + 1); item.cost -= item.cost * indexConditions.size() / 100 / (filter + 1);
if (item1 != null && item1.cost < item.cost) { if (item1 != null && item1.cost < item.cost) {
item = item1; item = item1;
} }
if (nestedJoin != null) { if (nestedJoin != null) {
setEvaluatable(nestedJoin); setEvaluatable(nestedJoin);
item.setNestedJoinPlan(nestedJoin.getBestPlanItem(s, filters, filter)); item.setNestedJoinPlan(nestedJoin.getBestPlanItem(s, filters, filter));
...@@ -374,7 +373,6 @@ public class TableFilter implements ColumnResolver { ...@@ -374,7 +373,6 @@ public class TableFilter implements ColumnResolver {
/** /**
* Attempt to initialize batched join. * Attempt to initialize batched join.
* *
* @param id join filter id (index of this table filter in join list)
* @param jb join batch if it is already created * @param jb join batch if it is already created
* @return join batch if query runs over index which supports batched lookups, {@code null} otherwise * @return join batch if query runs over index which supports batched lookups, {@code null} otherwise
*/ */
......
...@@ -366,7 +366,7 @@ public class SourceCompiler { ...@@ -366,7 +366,7 @@ public class SourceCompiler {
boolean syntaxError = false; boolean syntaxError = false;
final BufferedReader reader = new BufferedReader(new StringReader(output)); final BufferedReader reader = new BufferedReader(new StringReader(output));
try { try {
for (String line; (line = reader.readLine()) != null; ) { for (String line; (line = reader.readLine()) != null;) {
if (line.startsWith("Note:") || line.startsWith("warning:")) { if (line.startsWith("Note:") || line.startsWith("warning:")) {
// just a warning (e.g. unchecked or unsafe operations) // just a warning (e.g. unchecked or unsafe operations)
} else { } else {
......
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.ap; package org.h2.test.ap;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -11,10 +16,14 @@ import javax.lang.model.SourceVersion; ...@@ -11,10 +16,14 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
/**
* An annotation processor for testing.
*/
public class TestAnnotationProcessor extends AbstractProcessor { public class TestAnnotationProcessor extends AbstractProcessor {
public static final String MESSAGES_KEY = TestAnnotationProcessor.class.getName() + "-messages"; public static final String MESSAGES_KEY = TestAnnotationProcessor.class.getName() + "-messages";
@Override
public Set<String> getSupportedAnnotationTypes() { public Set<String> getSupportedAnnotationTypes() {
for (OutputMessage outputMessage : findMessages()) { for (OutputMessage outputMessage : findMessages()) {
...@@ -24,26 +33,26 @@ public class TestAnnotationProcessor extends AbstractProcessor { ...@@ -24,26 +33,26 @@ public class TestAnnotationProcessor extends AbstractProcessor {
return Collections.emptySet(); return Collections.emptySet();
} }
private List<OutputMessage> findMessages() { private static List<OutputMessage> findMessages() {
final String messagesStr = System.getProperty(MESSAGES_KEY); final String messagesStr = System.getProperty(MESSAGES_KEY);
if (messagesStr == null || messagesStr.isEmpty()) { if (messagesStr == null || messagesStr.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} else { }
final List<OutputMessage> outputMessages = new ArrayList<OutputMessage>(); List<OutputMessage> outputMessages = new ArrayList<OutputMessage>();
for (String msg : messagesStr.split("\\|")) { for (String msg : messagesStr.split("\\|")) {
final String[] split = msg.split(","); String[] split = msg.split(",");
if (split.length == 2) { if (split.length == 2) {
outputMessages.add(new OutputMessage(Diagnostic.Kind.valueOf(split[0]), split[1])); outputMessages.add(new OutputMessage(Diagnostic.Kind.valueOf(split[0]), split[1]));
} else { } else {
throw new IllegalStateException("Unable to parse messages definition for: '" + messagesStr + "'"); throw new IllegalStateException("Unable to parse messages definition for: '" + messagesStr + "'");
}
} }
return outputMessages;
} }
return outputMessages;
} }
@Override
public SourceVersion getSupportedSourceVersion() { public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest(); return SourceVersion.latest();
} }
...@@ -53,11 +62,14 @@ public class TestAnnotationProcessor extends AbstractProcessor { ...@@ -53,11 +62,14 @@ public class TestAnnotationProcessor extends AbstractProcessor {
return false; return false;
} }
/**
* An output message.
*/
private static class OutputMessage { private static class OutputMessage {
public final Diagnostic.Kind kind; public final Diagnostic.Kind kind;
public final String message; public final String message;
private OutputMessage(Diagnostic.Kind kind, String message) { OutputMessage(Diagnostic.Kind kind, String message) {
this.kind = kind; this.kind = kind;
this.message = message; this.message = message;
} }
......
...@@ -33,7 +33,7 @@ public class TestRowFactory extends TestBase { ...@@ -33,7 +33,7 @@ public class TestRowFactory extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
deleteDb("rowFactory"); deleteDb("rowFactory");
Connection conn = getConnection("rowFactory;ROW_FACTORY=\"" + Connection conn = getConnection("rowFactory;ROW_FACTORY=\"" +
MyTestRowFactory.class.getName() + '"'); MyTestRowFactory.class.getName() + '"');
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table t1(id int, name varchar)"); stat.execute("create table t1(id int, name varchar)");
...@@ -49,7 +49,7 @@ public class TestRowFactory extends TestBase { ...@@ -49,7 +49,7 @@ public class TestRowFactory extends TestBase {
*/ */
public static class MyTestRowFactory extends RowFactory { public static class MyTestRowFactory extends RowFactory {
private static final AtomicInteger COUNTER = new AtomicInteger(); static final AtomicInteger COUNTER = new AtomicInteger();
@Override @Override
public Row createRow(Value[] data, int memory) { public Row createRow(Value[] data, int memory) {
......
...@@ -27,7 +27,6 @@ import java.util.concurrent.ThreadFactory; ...@@ -27,7 +27,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.h2.api.TableEngine; import org.h2.api.TableEngine;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
...@@ -351,9 +350,9 @@ public class TestTableEngines extends TestBase { ...@@ -351,9 +350,9 @@ public class TestTableEngines extends TestBase {
deleteDb("testQueryExpressionFlag"); deleteDb("testQueryExpressionFlag");
Connection conn = getConnection("testQueryExpressionFlag"); Connection conn = getConnection("testQueryExpressionFlag");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table QRY_EXPR_TEST(id int) ENGINE \"" + stat.execute("create table QRY_EXPR_TEST(id int) ENGINE \"" +
TreeSetIndexTableEngine.class.getName() + "\""); TreeSetIndexTableEngine.class.getName() + "\"");
stat.execute("create table QRY_EXPR_TEST_NO(id int) ENGINE \"" + stat.execute("create table QRY_EXPR_TEST_NO(id int) ENGINE \"" +
TreeSetIndexTableEngine.class.getName() + "\""); TreeSetIndexTableEngine.class.getName() + "\"");
stat.executeQuery("select 1 + (select 1 from QRY_EXPR_TEST)").next(); stat.executeQuery("select 1 + (select 1 from QRY_EXPR_TEST)").next();
stat.executeQuery("select 1 from QRY_EXPR_TEST_NO where id in (select id from QRY_EXPR_TEST)"); stat.executeQuery("select 1 from QRY_EXPR_TEST_NO where id in (select id from QRY_EXPR_TEST)");
...@@ -407,14 +406,14 @@ public class TestTableEngines extends TestBase { ...@@ -407,14 +406,14 @@ public class TestTableEngines extends TestBase {
assertEquals(enabled, s.isJoinBatchEnabled()); assertEquals(enabled, s.isJoinBatchEnabled());
} }
} }
private void testBatchedJoin() throws SQLException { private void testBatchedJoin() throws SQLException {
deleteDb("testBatchedJoin"); deleteDb("testBatchedJoin");
Connection conn = getConnection("testBatchedJoin;OPTIMIZE_REUSE_RESULTS=0;BATCH_JOINS=1"); Connection conn = getConnection("testBatchedJoin;OPTIMIZE_REUSE_RESULTS=0;BATCH_JOINS=1");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
setBatchingEnabled(stat, false); setBatchingEnabled(stat, false);
setBatchingEnabled(stat, true); setBatchingEnabled(stat, true);
TreeSetIndex.exec = Executors.newFixedThreadPool(8, new ThreadFactory() { TreeSetIndex.exec = Executors.newFixedThreadPool(8, new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
...@@ -423,43 +422,43 @@ public class TestTableEngines extends TestBase { ...@@ -423,43 +422,43 @@ public class TestTableEngines extends TestBase {
return t; return t;
} }
}); });
forceJoinOrder(stat, true); forceJoinOrder(stat, true);
try { try {
doTestBatchedJoinSubQueryUnion(stat); doTestBatchedJoinSubQueryUnion(stat);
TreeSetIndex.lookupBatches.set(0); TreeSetIndex.lookupBatches.set(0);
doTestBatchedJoin(stat, 1, 0, 0); doTestBatchedJoin(stat, 1, 0, 0);
doTestBatchedJoin(stat, 0, 1, 0); doTestBatchedJoin(stat, 0, 1, 0);
doTestBatchedJoin(stat, 0, 0, 1); doTestBatchedJoin(stat, 0, 0, 1);
doTestBatchedJoin(stat, 0, 2, 0); doTestBatchedJoin(stat, 0, 2, 0);
doTestBatchedJoin(stat, 0, 0, 2); doTestBatchedJoin(stat, 0, 0, 2);
doTestBatchedJoin(stat, 0, 0, 3); doTestBatchedJoin(stat, 0, 0, 3);
doTestBatchedJoin(stat, 0, 0, 4); doTestBatchedJoin(stat, 0, 0, 4);
doTestBatchedJoin(stat, 0, 0, 5); doTestBatchedJoin(stat, 0, 0, 5);
doTestBatchedJoin(stat, 0, 3, 1); doTestBatchedJoin(stat, 0, 3, 1);
doTestBatchedJoin(stat, 0, 3, 3); doTestBatchedJoin(stat, 0, 3, 3);
doTestBatchedJoin(stat, 0, 3, 7); doTestBatchedJoin(stat, 0, 3, 7);
doTestBatchedJoin(stat, 0, 4, 1); doTestBatchedJoin(stat, 0, 4, 1);
doTestBatchedJoin(stat, 0, 4, 6); doTestBatchedJoin(stat, 0, 4, 6);
doTestBatchedJoin(stat, 0, 4, 20); doTestBatchedJoin(stat, 0, 4, 20);
doTestBatchedJoin(stat, 0, 10, 0); doTestBatchedJoin(stat, 0, 10, 0);
doTestBatchedJoin(stat, 0, 0, 10); doTestBatchedJoin(stat, 0, 0, 10);
doTestBatchedJoin(stat, 0, 20, 0); doTestBatchedJoin(stat, 0, 20, 0);
doTestBatchedJoin(stat, 0, 0, 20); doTestBatchedJoin(stat, 0, 0, 20);
doTestBatchedJoin(stat, 0, 20, 20); doTestBatchedJoin(stat, 0, 20, 20);
doTestBatchedJoin(stat, 3, 7, 0); doTestBatchedJoin(stat, 3, 7, 0);
doTestBatchedJoin(stat, 0, 0, 5); doTestBatchedJoin(stat, 0, 0, 5);
doTestBatchedJoin(stat, 0, 8, 1); doTestBatchedJoin(stat, 0, 8, 1);
doTestBatchedJoin(stat, 0, 2, 1); doTestBatchedJoin(stat, 0, 2, 1);
assertTrue(TreeSetIndex.lookupBatches.get() > 0); assertTrue(TreeSetIndex.lookupBatches.get() > 0);
} finally { } finally {
forceJoinOrder(stat, false); forceJoinOrder(stat, false);
...@@ -467,8 +466,8 @@ public class TestTableEngines extends TestBase { ...@@ -467,8 +466,8 @@ public class TestTableEngines extends TestBase {
} }
deleteDb("testBatchedJoin"); deleteDb("testBatchedJoin");
} }
private void forceJoinOrder(Statement s, boolean force) throws SQLException { private static void forceJoinOrder(Statement s, boolean force) throws SQLException {
s.executeUpdate("SET FORCE_JOIN_ORDER " + force); s.executeUpdate("SET FORCE_JOIN_ORDER " + force);
} }
...@@ -564,17 +563,17 @@ public class TestTableEngines extends TestBase { ...@@ -564,17 +563,17 @@ public class TestTableEngines extends TestBase {
+ "WHERE B IS ?1) UNION (SELECT B, A FROM PUBLIC.U /++ PUBLIC.U_IDX_A: A IS ?1 ++/ " + "WHERE B IS ?1) UNION (SELECT B, A FROM PUBLIC.U /++ PUBLIC.U_IDX_A: A IS ?1 ++/ "
+ "WHERE A IS ?1): B = U.B */ ON 1=1 /* WHERE U.B = Z.B */ " + "WHERE A IS ?1): B = U.B */ ON 1=1 /* WHERE U.B = Z.B */ "
+ "INNER JOIN PUBLIC.T /* batched:test PUBLIC.T_IDX_A: A = Z.A */ ON 1=1 " + "INNER JOIN PUBLIC.T /* batched:test PUBLIC.T_IDX_A: A = Z.A */ ON 1=1 "
+ "WHERE (U.B = Z.B) AND (Z.A = T.A)"); + "WHERE (U.B = Z.B) AND (Z.A = T.A)");
checkPlan(stat, "SELECT 1 FROM PUBLIC.U /* PUBLIC.U_IDX_A */ " checkPlan(stat, "SELECT 1 FROM PUBLIC.U /* PUBLIC.U_IDX_A */ "
+ "INNER JOIN ( SELECT A, B FROM PUBLIC.U ) Z " + "INNER JOIN ( SELECT A, B FROM PUBLIC.U ) Z "
+ "/* batched:fake SELECT A, B FROM PUBLIC.U /++ PUBLIC.U_IDX_A: A IS ?1 ++/ " + "/* batched:fake SELECT A, B FROM PUBLIC.U /++ PUBLIC.U_IDX_A: A IS ?1 ++/ "
+ "WHERE A IS ?1: A = U.A */ ON 1=1 /* WHERE U.A = Z.A */ " + "WHERE A IS ?1: A = U.A */ ON 1=1 /* WHERE U.A = Z.A */ "
+ "INNER JOIN PUBLIC.T /* batched:test PUBLIC.T_IDX_B: B = Z.B */ " + "INNER JOIN PUBLIC.T /* batched:test PUBLIC.T_IDX_B: B = Z.B */ "
+ "ON 1=1 WHERE (U.A = Z.A) AND (Z.B = T.B)"); + "ON 1=1 WHERE (U.A = Z.A) AND (Z.B = T.B)");
// t: a = [ 0..20), b = [10..30) // t: a = [ 0..20), b = [10..30)
// u: a = [10..25), b = [-5..10) // u: a = [10..25), b = [-5..10)
checkBatchedQueryResult(stat, 10, checkBatchedQueryResult(stat, 10,
"select t.a from t, (select t.b from u, t where u.a = t.a) z where t.b = z.b"); "select t.a from t, (select t.b from u, t where u.a = t.a) z where t.b = z.b");
checkBatchedQueryResult(stat, 5, checkBatchedQueryResult(stat, 5,
"select t.a from (select t1.b from t t1, t t2 where t1.a = t2.b) z, t where t.b = z.b + 5"); "select t.a from (select t1.b from t t1, t t2 where t1.a = t2.b) z, t where t.b = z.b + 5");
...@@ -604,47 +603,47 @@ public class TestTableEngines extends TestBase { ...@@ -604,47 +603,47 @@ public class TestTableEngines extends TestBase {
fail("\nexpected: " + expected + "\nactual: " + actual); fail("\nexpected: " + expected + "\nactual: " + actual);
} }
} }
private void doTestBatchedJoin(Statement stat, int... batchSizes) throws SQLException { private void doTestBatchedJoin(Statement stat, int... batchSizes) throws SQLException {
ArrayList<TreeSetTable> tables = New.arrayList(batchSizes.length); ArrayList<TreeSetTable> tables = New.arrayList(batchSizes.length);
for (int i = 0; i < batchSizes.length; i++) { for (int i = 0; i < batchSizes.length; i++) {
stat.executeUpdate("DROP TABLE IF EXISTS T" + i); stat.executeUpdate("DROP TABLE IF EXISTS T" + i);
stat.executeUpdate("CREATE TABLE T" + i + "(A INT, B INT) ENGINE \"" + stat.executeUpdate("CREATE TABLE T" + i + "(A INT, B INT) ENGINE \"" +
TreeSetIndexTableEngine.class.getName() + "\""); TreeSetIndexTableEngine.class.getName() + "\"");
tables.add(TreeSetIndexTableEngine.created); tables.add(TreeSetIndexTableEngine.created);
stat.executeUpdate("CREATE INDEX IDX_B ON T" + i + "(B)"); stat.executeUpdate("CREATE INDEX IDX_B ON T" + i + "(B)");
stat.executeUpdate("CREATE INDEX IDX_A ON T" + i + "(A)"); stat.executeUpdate("CREATE INDEX IDX_A ON T" + i + "(A)");
PreparedStatement insert = stat.getConnection().prepareStatement( PreparedStatement insert = stat.getConnection().prepareStatement(
"INSERT INTO T"+ i + " VALUES (?,?)"); "INSERT INTO T"+ i + " VALUES (?,?)");
for (int j = i, size = i + 10; j < size; j++) { for (int j = i, size = i + 10; j < size; j++) {
insert.setInt(1, j); insert.setInt(1, j);
insert.setInt(2, j); insert.setInt(2, j);
insert.executeUpdate(); insert.executeUpdate();
} }
for (TreeSetTable table : tables) { for (TreeSetTable table : tables) {
assertEquals(10, table.getRowCount(null)); assertEquals(10, table.getRowCount(null));
} }
} }
int[] zeroBatchSizes = new int[batchSizes.length]; int[] zeroBatchSizes = new int[batchSizes.length];
int tests = 1 << (batchSizes.length * 4); int tests = 1 << (batchSizes.length * 4);
for (int test = 0; test < tests; test++) { for (int test = 0; test < tests; test++) {
String query = generateQuery(test, batchSizes.length); String query = generateQuery(test, batchSizes.length);
// System.out.println(Arrays.toString(batchSizes) + ": " + test + " -> " + query); // System.out.println(Arrays.toString(batchSizes) + ": " + test + " -> " + query);
setBatchSize(tables, batchSizes); setBatchSize(tables, batchSizes);
List<List<Object>> res1 = query(stat, query); List<List<Object>> res1 = query(stat, query);
setBatchSize(tables, zeroBatchSizes); setBatchSize(tables, zeroBatchSizes);
List<List<Object>> res2 = query(stat, query); List<List<Object>> res2 = query(stat, query);
// System.out.println(res1 + " " + res2); // System.out.println(res1 + " " + res2);
if (!res2.equals(res1)) { if (!res2.equals(res1)) {
...@@ -652,7 +651,7 @@ public class TestTableEngines extends TestBase { ...@@ -652,7 +651,7 @@ public class TestTableEngines extends TestBase {
System.err.println("Test " + test); System.err.println("Test " + test);
System.err.println(query); System.err.println(query);
for (TreeSetTable table : tables) { for (TreeSetTable table : tables) {
System.err.println(table.getName() + " = " + System.err.println(table.getName() + " = " +
query(stat, "select * from " + table.getName())); query(stat, "select * from " + table.getName()));
} }
fail(); fail();
...@@ -663,7 +662,7 @@ public class TestTableEngines extends TestBase { ...@@ -663,7 +662,7 @@ public class TestTableEngines extends TestBase {
} }
} }
private static void assert0(boolean condition, String message) { static void assert0(boolean condition, String message) {
if (!condition) { if (!condition) {
throw new AssertionError(message); throw new AssertionError(message);
} }
...@@ -685,18 +684,18 @@ public class TestTableEngines extends TestBase { ...@@ -685,18 +684,18 @@ public class TestTableEngines extends TestBase {
} }
} }
} }
private String generateQuery(int t, int tables) { private static String generateQuery(int t, int tables) {
final int withLeft = 1; final int withLeft = 1;
final int withFalse = 2; final int withFalse = 2;
final int withWhere = 4; final int withWhere = 4;
final int withOnIsNull = 8; final int withOnIsNull = 8;
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append("select count(*) from "); b.append("select count(*) from ");
StringBuilder where = new StringBuilder(); StringBuilder where = new StringBuilder();
for (int i = 0; i < tables; i++) { for (int i = 0; i < tables; i++) {
if (i != 0) { if (i != 0) {
if ((t & withLeft) != 0) { if ((t & withLeft) != 0) {
...@@ -722,15 +721,15 @@ public class TestTableEngines extends TestBase { ...@@ -722,15 +721,15 @@ public class TestTableEngines extends TestBase {
} }
where.append(" T").append(i).append(".A > 5"); where.append(" T").append(i).append(".A > 5");
} }
t >>>= 4; t >>>= 4;
} }
if (where.length() != 0) { if (where.length() != 0) {
b.append("\nwhere ").append(where); b.append("\nwhere ").append(where);
} }
return b.toString(); return b.toString();
} }
private void checkResultsNoOrder(Statement stat, int size, String query1, String query2) private void checkResultsNoOrder(Statement stat, int size, String query1, String query2)
throws SQLException { throws SQLException {
List<List<Object>> res1 = query(stat, query1); List<List<Object>> res1 = query(stat, query1);
...@@ -1109,9 +1108,9 @@ public class TestTableEngines extends TestBase { ...@@ -1109,9 +1108,9 @@ public class TestTableEngines extends TestBase {
* A table engine that internally uses a tree set. * A table engine that internally uses a tree set.
*/ */
public static class TreeSetIndexTableEngine implements TableEngine { public static class TreeSetIndexTableEngine implements TableEngine {
static TreeSetTable created; static TreeSetTable created;
@Override @Override
public Table createTable(CreateTableData data) { public Table createTable(CreateTableData data) {
return created = new TreeSetTable(data); return created = new TreeSetTable(data);
...@@ -1284,17 +1283,17 @@ public class TestTableEngines extends TestBase { ...@@ -1284,17 +1283,17 @@ public class TestTableEngines extends TestBase {
* An index that internally uses a tree set. * An index that internally uses a tree set.
*/ */
private static class TreeSetIndex extends BaseIndex implements Comparator<SearchRow> { private static class TreeSetIndex extends BaseIndex implements Comparator<SearchRow> {
private static AtomicInteger lookupBatches = new AtomicInteger();
/** /**
* Executor service to test batched joins. * Executor service to test batched joins.
*/ */
private static ExecutorService exec; static ExecutorService exec;
private final TreeSet<SearchRow> set = new TreeSet<SearchRow>(this); static AtomicInteger lookupBatches = new AtomicInteger();
private int preferedBatchSize; int preferedBatchSize;
final TreeSet<SearchRow> set = new TreeSet<SearchRow>(this);
TreeSetIndex(Table t, String name, IndexColumn[] cols, IndexType type) { TreeSetIndex(Table t, String name, IndexColumn[] cols, IndexType type) {
initBaseIndex(t, 0, name, cols, type); initBaseIndex(t, 0, name, cols, type);
} }
...@@ -1315,7 +1314,7 @@ public class TestTableEngines extends TestBase { ...@@ -1315,7 +1314,7 @@ public class TestTableEngines extends TestBase {
@Override @Override
public IndexLookupBatch createLookupBatch(final TableFilter filter) { public IndexLookupBatch createLookupBatch(final TableFilter filter) {
assert0(filter.getMasks() != null || "scan".equals(getName()), "masks"); assert0(filter.getMasks() != null || "scan".equals(getName()), "masks");
final int preferedSize = preferedBatchSize; final int preferedSize = preferedBatchSize;
if (preferedSize == 0) { if (preferedSize == 0) {
return null; return null;
} }
...@@ -1327,7 +1326,7 @@ public class TestTableEngines extends TestBase { ...@@ -1327,7 +1326,7 @@ public class TestTableEngines extends TestBase {
public String getPlanSQL() { public String getPlanSQL() {
return "test"; return "test";
} }
@Override public boolean isBatchFull() { @Override public boolean isBatchFull() {
return searchRows.size() >= preferedSize * 2; return searchRows.size() >= preferedSize * 2;
} }
...@@ -1384,7 +1383,7 @@ public class TestTableEngines extends TestBase { ...@@ -1384,7 +1383,7 @@ public class TestTableEngines extends TestBase {
} }
return result; return result;
} }
@Override @Override
public void close(Session session) { public void close(Session session) {
// No-op. // No-op.
...@@ -1425,7 +1424,7 @@ public class TestTableEngines extends TestBase { ...@@ -1425,7 +1424,7 @@ public class TestTableEngines extends TestBase {
} else if (first != null) { } else if (first != null) {
if (last != null) { if (last != null) {
subSet = set.subSet(first, true, last, true); subSet = set.subSet(first, true, last, true);
} else { } else {
subSet = set.tailSet(first, true); subSet = set.tailSet(first, true);
} }
} else if (last != null) { } else if (last != null) {
...@@ -1529,7 +1528,7 @@ public class TestTableEngines extends TestBase { ...@@ -1529,7 +1528,7 @@ public class TestTableEngines extends TestBase {
/** /**
*/ */
private static class IteratorCursor implements Cursor { private static class IteratorCursor implements Cursor {
private Iterator<SearchRow> it; Iterator<SearchRow> it;
private Row current; private Row current;
public IteratorCursor(Iterator<SearchRow> it) { public IteratorCursor(Iterator<SearchRow> it) {
...@@ -1560,7 +1559,7 @@ public class TestTableEngines extends TestBase { ...@@ -1560,7 +1559,7 @@ public class TestTableEngines extends TestBase {
public Row get() { public Row get() {
return current; return current;
} }
@Override @Override
public String toString() { public String toString() {
return "IterCursor->" + current; return "IterCursor->" + current;
......
...@@ -71,6 +71,7 @@ public class TestMvcc4 extends TestBase { ...@@ -71,6 +71,7 @@ public class TestMvcc4 extends TestBase {
final Thread mainThread = Thread.currentThread(); final Thread mainThread = Thread.currentThread();
final CountDownLatch executedUpdate = new CountDownLatch(1); final CountDownLatch executedUpdate = new CountDownLatch(1);
new Thread() { new Thread() {
@Override
public void run() { public void run() {
try { try {
Connection c2 = getConnection("mvcc4"); Connection c2 = getConnection("mvcc4");
...@@ -96,6 +97,7 @@ public class TestMvcc4 extends TestBase { ...@@ -96,6 +97,7 @@ public class TestMvcc4 extends TestBase {
try { try {
executedUpdate.await(); executedUpdate.await();
} catch (InterruptedException e) { } catch (InterruptedException e) {
// ignore
} }
// Execute an update. This should initially fail, and enter the waiting // Execute an update. This should initially fail, and enter the waiting
...@@ -120,7 +122,7 @@ public class TestMvcc4 extends TestBase { ...@@ -120,7 +122,7 @@ public class TestMvcc4 extends TestBase {
setup.close(); setup.close();
} }
private static void waitForThreadToBlockOnDB(Thread t) { static void waitForThreadToBlockOnDB(Thread t) {
while (true) { while (true) {
// TODO must not use getAllStackTraces, as the method names are // TODO must not use getAllStackTraces, as the method names are
// implementation details // implementation details
...@@ -135,6 +137,7 @@ public class TestMvcc4 extends TestBase { ...@@ -135,6 +137,7 @@ public class TestMvcc4 extends TestBase {
try { try {
Thread.sleep(10); Thread.sleep(10);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
// ignore
} }
} }
} }
......
...@@ -315,9 +315,8 @@ public class BuildBase { ...@@ -315,9 +315,8 @@ public class BuildBase {
newArgs.add(script); newArgs.add(script);
newArgs.addAll(args); newArgs.addAll(args);
return exec("cmd", newArgs); return exec("cmd", newArgs);
} else {
return exec(script, args);
} }
return exec(script, args);
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论