use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class IndexCondition method getSQL.
/**
* Get the SQL snippet of this comparison.
*
* @return the SQL snippet
*/
public String getSQL() {
if (compareType == Comparison.FALSE) {
return "FALSE";
}
StatementBuilder buff = new StatementBuilder();
buff.append(column.getSQL());
switch(compareType) {
case Comparison.EQUAL:
buff.append(" = ");
break;
case Comparison.EQUAL_NULL_SAFE:
buff.append(" IS ");
break;
case Comparison.BIGGER_EQUAL:
buff.append(" >= ");
break;
case Comparison.BIGGER:
buff.append(" > ");
break;
case Comparison.SMALLER_EQUAL:
buff.append(" <= ");
break;
case Comparison.SMALLER:
buff.append(" < ");
break;
case Comparison.IN_LIST:
buff.append(" IN(");
for (Expression e : expressionList) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
buff.append(')');
break;
case Comparison.IN_QUERY:
buff.append(" IN(");
buff.append(expressionQuery.getPlanSQL());
buff.append(')');
break;
case Comparison.SPATIAL_INTERSECTS:
buff.append(" && ");
break;
default:
DbException.throwInternalError("type=" + compareType);
}
if (expression != null) {
buff.append(expression.getSQL());
}
return buff.toString();
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class IndexCursor method prepare.
/**
* Prepare this index cursor to make a lookup in index.
*
* @param s Session.
* @param indexConditions Index conditions.
*/
public void prepare(Session s, ArrayList<IndexCondition> indexConditions) {
this.session = s;
alwaysFalse = false;
start = end = null;
inList = null;
inColumn = null;
inResult = null;
inResultTested = null;
intersects = null;
// don't use enhanced for loop to avoid creating objects
for (IndexCondition condition : indexConditions) {
if (condition.isAlwaysFalse()) {
alwaysFalse = true;
break;
}
// lookups, each such lookup will perform an own table scan.
if (index.isFindUsingFullTableScan()) {
continue;
}
Column column = condition.getColumn();
if (condition.getCompareType() == Comparison.IN_LIST) {
if (start == null && end == null) {
if (canUseIndexForIn(column)) {
this.inColumn = column;
inList = condition.getCurrentValueList(s);
inListIndex = 0;
}
}
} else if (condition.getCompareType() == Comparison.IN_QUERY) {
if (start == null && end == null) {
if (canUseIndexForIn(column)) {
this.inColumn = column;
inResult = condition.getCurrentResult();
}
}
} else {
Value v = condition.getCurrentValue(s);
boolean isStart = condition.isStart();
boolean isEnd = condition.isEnd();
boolean isIntersects = condition.isSpatialIntersects();
int columnId = column.getColumnId();
if (columnId >= 0) {
IndexColumn idxCol = indexColumns[columnId];
if (idxCol != null && (idxCol.sortType & SortOrder.DESCENDING) != 0) {
// if the index column is sorted the other way, we swap
// end and start NULLS_FIRST / NULLS_LAST is not a
// problem, as nulls never match anyway
boolean temp = isStart;
isStart = isEnd;
isEnd = temp;
}
}
if (isStart) {
start = getSearchRow(start, columnId, v, true);
}
if (isEnd) {
end = getSearchRow(end, columnId, v, false);
}
if (isIntersects) {
intersects = getSpatialSearchRow(intersects, columnId, v);
}
// an X IN(..) condition, unless the X IN condition can use the index.
if ((isStart || isEnd) && !canUseIndexFor(inColumn)) {
inColumn = null;
inList = null;
inResult = null;
}
if (!session.getDatabase().getSettings().optimizeIsNull) {
if (isStart && isEnd) {
if (v == ValueNull.INSTANCE) {
// join on a column=NULL is always false
alwaysFalse = true;
}
}
}
}
}
if (inColumn != null) {
start = table.getTemplateRow();
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class PageBtreeNode method remove.
@Override
SearchRow remove(SearchRow row) {
int at = find(row, false, false, true);
// merge is not implemented to allow concurrent usage
// TODO maybe implement merge
PageBtree page = index.getPage(childPageIds[at]);
SearchRow last = page.remove(row);
index.getPageStore().logUndo(this, data);
updateRowCount(-1);
written = false;
changeCount = index.getPageStore().getChangeCount();
if (last == null) {
// the last row didn't change - nothing to do
return null;
} else if (last == row) {
// this child is now empty
index.getPageStore().free(page.getPos());
if (entryCount < 1) {
// no more children - this page is empty as well
return row;
}
if (at == entryCount) {
// removing the last child
last = getRow(at - 1);
} else {
last = null;
}
removeChild(at);
index.getPageStore().update(this);
return last;
}
// the last row is in the last child
if (at == entryCount) {
return last;
}
int child = childPageIds[at];
removeChild(at);
// TODO this can mean only the position is now stored
// should split at the next possible moment
addChild(at, child, last);
// remove and add swapped two children, fix that
int temp = childPageIds[at];
childPageIds[at] = childPageIds[at + 1];
childPageIds[at + 1] = temp;
index.getPageStore().update(this);
return null;
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class PageDataIndex method add.
@Override
public void add(Session session, Row row) {
boolean retry = false;
if (mainIndexColumn != -1) {
row.setKey(row.getValue(mainIndexColumn).getLong());
} else {
if (row.getKey() == 0) {
row.setKey((int) ++lastKey);
retry = true;
}
}
if (tableData.getContainsLargeObject()) {
for (int i = 0, len = row.getColumnCount(); i < len; i++) {
Value v = row.getValue(i);
Value v2 = v.copy(database, getId());
if (v2.isLinkedToTable()) {
session.removeAtCommitStop(v2);
}
if (v != v2) {
row.setValue(i, v2);
}
}
}
// tries are required (specially if there was originally a primary key)
if (trace.isDebugEnabled()) {
trace.debug("{0} add {1}", getName(), row);
}
long add = 0;
while (true) {
try {
addTry(session, row);
break;
} catch (DbException e) {
if (e != fastDuplicateKeyException) {
throw e;
}
if (!retry) {
throw getNewDuplicateKeyException();
}
if (add == 0) {
// in the first re-try add a small random number,
// to avoid collisions after a re-start
row.setKey((long) (row.getKey() + Math.random() * 10_000));
} else {
row.setKey(row.getKey() + add);
}
add++;
} finally {
store.incrementChangeCount();
}
}
lastKey = Math.max(lastKey, row.getKey());
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class NonUniqueHashIndex method find.
@Override
public Cursor find(Session session, SearchRow first, SearchRow last) {
if (first == null || last == null) {
throw DbException.throwInternalError(first + " " + last);
}
if (first != last) {
if (compareKeys(first, last) != 0) {
throw DbException.throwInternalError();
}
}
Value v = first.getValue(indexColumn);
/*
* Sometimes the incoming search is a similar, but not the same type
* e.g. the search value is INT, but the index column is LONG. In which
* case we need to convert, otherwise the ValueHashMap will not find the
* result.
*/
v = v.convertTo(tableData.getColumn(indexColumn).getType());
ArrayList<Long> positions = rows.get(v);
return new NonUniqueHashCursor(session, tableData, positions);
}
Aggregations