use of org.h2.expression.Comparison in project ignite by apache.
the class InlineIndexHelper method compareAsString.
/**
* @param pageAddr Page address.
* @param off Offset.
* @param v Value to compare.
* @param ignoreCase {@code True} if a case-insensitive comparison should be used.
* @return Compare result ({@code -2} means we can't compare).
*/
private int compareAsString(long pageAddr, int off, Value v, boolean ignoreCase) {
String s = v.getString();
int len1 = PageUtils.getShort(pageAddr, off + 1) & 0x7FFF;
int len2 = s.length();
int c, c2, c3, c4, cntr1 = 0, cntr2 = 0;
char v1, v2;
// Skip length and type byte.
long addr = pageAddr + off + 3;
// Try reading ASCII.
while (cntr1 < len1 && cntr2 < len2) {
c = (int) GridUnsafe.getByte(addr) & 0xFF;
if (c > 127)
break;
cntr1++;
addr++;
v1 = (char) c;
v2 = s.charAt(cntr2++);
if (ignoreCase) {
v1 = Character.toUpperCase(v1);
v2 = Character.toUpperCase(v2);
}
if (v1 != v2)
return fixSort(Integer.signum(v1 - v2), sortType());
}
// read other
while (cntr1 < len1 && cntr2 < len2) {
c = (int) GridUnsafe.getByte(addr++) & 0xFF;
switch(c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
/* 0xxxxxxx*/
cntr1++;
v1 = (char) c;
break;
case 12:
case 13:
/* 110x xxxx 10xx xxxx*/
cntr1 += 2;
if (cntr1 > len1)
throw new IllegalStateException("Malformed input (partial character at the end).");
c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
if ((c2 & 0xC0) != 0x80)
throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 2));
c = c & 0x1F;
c = (c << 6) | (c2 & 0x3F);
v1 = (char) c;
break;
case 14:
/* 1110 xxxx 10xx xxxx 10xx xxxx */
cntr1 += 3;
if (cntr1 > len1)
throw new IllegalStateException("Malformed input (partial character at the end).");
c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
c3 = (int) GridUnsafe.getByte(addr++) & 0xFF;
if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 3));
c = c & 0x0F;
c = (c << 6) | (c2 & 0x3F);
c = (c << 6) | (c3 & 0x3F);
v1 = (char) c;
break;
case 15:
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
cntr1 += 4;
if (cntr1 > len1)
throw new IllegalStateException("Malformed input (partial character at the end).");
c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
c3 = (int) GridUnsafe.getByte(addr++) & 0xFF;
c4 = (int) GridUnsafe.getByte(addr++) & 0xFF;
if (((c & 0xF8) != 0xf0) || ((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80) || ((c4 & 0xC0) != 0x80))
throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 4));
c = c & 0x07;
c = (c << 6) | (c2 & 0x3F);
c = (c << 6) | (c3 & 0x3F);
c = (c << 6) | (c4 & 0x3F);
// Subtract 0x010000, c is now 0..fffff (20 bits)
c = c - 0x010000;
// height surrogate
v1 = (char) (0xD800 + ((c >> 10) & 0x7FF));
v2 = s.charAt(cntr2++);
if (v1 != v2)
return fixSort(Integer.signum(v1 - v2), sortType());
if (cntr2 == len2)
// Finish comparison here.
return fixSort(1, sortType());
// Low surrogate.
v1 = (char) (0xDC00 + (c & 0x3FF));
v2 = s.charAt(cntr2++);
if (v1 != v2)
return fixSort(Integer.signum(v1 - v2), sortType());
continue;
default:
/* 10xx xxxx */
throw new IllegalStateException("Malformed input around byte: " + cntr1);
}
v2 = s.charAt(cntr2++);
if (ignoreCase) {
v1 = Character.toUpperCase(v1);
v2 = Character.toUpperCase(v2);
}
if (v1 != v2)
return fixSort(Integer.signum(v1 - v2), sortType());
}
int res = cntr1 == len1 && cntr2 == len2 ? 0 : cntr1 == len1 ? -1 : 1;
if (isValueFull(pageAddr, off))
return fixSort(res, sortType());
if (res >= 0)
// b) Even truncated current value is longer, so that it's bigger.
return fixSort(1, sortType());
return -2;
}
use of org.h2.expression.Comparison in project h2database by h2database.
the class Parser method readJoin.
private TableFilter readJoin(TableFilter top) {
TableFilter last = top;
while (true) {
TableFilter join;
if (readIf("RIGHT")) {
readIf("OUTER");
read("JOIN");
// the right hand side is the 'inner' table usually
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(join, top, true, on);
top = join;
} else if (readIf("LEFT")) {
readIf("OUTER");
read("JOIN");
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, true, on);
} else if (readIf("FULL")) {
throw getSyntaxError();
} else if (readIf("INNER")) {
read("JOIN");
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("JOIN")) {
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("CROSS")) {
read("JOIN");
join = readTableFilter();
addJoin(top, join, false, null);
} else if (readIf("NATURAL")) {
read("JOIN");
join = readTableFilter();
Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns();
String tableSchema = last.getTable().getSchema().getName();
String joinSchema = join.getTable().getSchema().getName();
Expression on = null;
for (Column tc : tableCols) {
String tableColumnName = tc.getName();
for (Column c : joinCols) {
String joinColumnName = c.getName();
if (equalsToken(tableColumnName, joinColumnName)) {
join.addNaturalJoinColumn(c);
Expression tableExpr = new ExpressionColumn(database, tableSchema, last.getTableAlias(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, joinSchema, join.getTableAlias(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) {
on = equal;
} else {
on = new ConditionAndOr(ConditionAndOr.AND, on, equal);
}
}
}
}
addJoin(top, join, false, on);
} else {
break;
}
last = join;
}
return top;
}
use of org.h2.expression.Comparison in project h2database by h2database.
the class Insert method prepareUpdateCondition.
private Expression prepareUpdateCondition(Index foundIndex) {
// MVPrimaryIndex is playing fast and loose with it's implementation of
// the Index interface.
// It returns all of the columns in the table when we call
// getIndexColumns() or getColumns().
// Don't have time right now to fix that, so just special-case it.
final Column[] indexedColumns;
if (foundIndex instanceof MVPrimaryIndex) {
MVPrimaryIndex foundMV = (MVPrimaryIndex) foundIndex;
indexedColumns = new Column[] { foundMV.getIndexColumns()[foundMV.getMainIndexColumn()].column };
} else {
indexedColumns = foundIndex.getColumns();
}
Expression[] row = list.get(getCurrentRowNumber() - 1);
Expression condition = null;
for (Column column : indexedColumns) {
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), table.getSchema().getName(), table.getName(), column.getName());
for (int i = 0; i < columns.length; i++) {
if (expr.getColumnName().equals(columns[i].getName())) {
if (condition == null) {
condition = new Comparison(session, Comparison.EQUAL, expr, row[i]);
} else {
condition = new ConditionAndOr(ConditionAndOr.AND, condition, new Comparison(session, Comparison.EQUAL, expr, row[i]));
}
break;
}
}
}
return condition;
}
use of org.h2.expression.Comparison in project h2database by h2database.
the class FullText method addColumnData.
private static void addColumnData(ArrayList<String> columns, ArrayList<String> data, Expression expr) {
if (expr instanceof ConditionAndOr) {
ConditionAndOr and = (ConditionAndOr) expr;
Expression left = and.getExpression(true);
Expression right = and.getExpression(false);
addColumnData(columns, data, left);
addColumnData(columns, data, right);
} else {
Comparison comp = (Comparison) expr;
ExpressionColumn ec = (ExpressionColumn) comp.getExpression(true);
ValueExpression ev = (ValueExpression) comp.getExpression(false);
String columnName = ec.getColumnName();
columns.add(columnName);
if (ev == null) {
data.add(null);
} else {
data.add(ev.getValue(null).getString());
}
}
}
use of org.h2.expression.Comparison in project h2database by h2database.
the class ConditionAndOr method optimize.
@Override
public Expression optimize(Session session) {
// NULL handling: see wikipedia,
// http://www-cs-students.stanford.edu/~wlam/compsci/sqlnulls
left = left.optimize(session);
right = right.optimize(session);
int lc = left.getCost(), rc = right.getCost();
if (rc < lc) {
Expression t = left;
left = right;
right = t;
}
// SELECT * FROM TEST WHERE NOT (B=A AND B=0 AND A=0); // 1, NULL
if (session.getDatabase().getSettings().optimizeTwoEquals && andOrType == AND) {
// try to add conditions (A=B AND B=1: add A=1)
if (left instanceof Comparison && right instanceof Comparison) {
Comparison compLeft = (Comparison) left;
Comparison compRight = (Comparison) right;
Expression added = compLeft.getAdditional(session, compRight, true);
if (added != null) {
added = added.optimize(session);
return new ConditionAndOr(AND, this, added);
}
}
}
// (A=1 AND (B=2 OR B=3))
if (andOrType == OR && session.getDatabase().getSettings().optimizeOr) {
// try to add conditions (A=B AND B=1: add A=1)
if (left instanceof Comparison && right instanceof Comparison) {
Comparison compLeft = (Comparison) left;
Comparison compRight = (Comparison) right;
Expression added = compLeft.getAdditional(session, compRight, false);
if (added != null) {
return added.optimize(session);
}
} else if (left instanceof ConditionIn && right instanceof Comparison) {
Expression added = ((ConditionIn) left).getAdditional((Comparison) right);
if (added != null) {
return added.optimize(session);
}
} else if (right instanceof ConditionIn && left instanceof Comparison) {
Expression added = ((ConditionIn) right).getAdditional((Comparison) left);
if (added != null) {
return added.optimize(session);
}
} else if (left instanceof ConditionInConstantSet && right instanceof Comparison) {
Expression added = ((ConditionInConstantSet) left).getAdditional(session, (Comparison) right);
if (added != null) {
return added.optimize(session);
}
} else if (right instanceof ConditionInConstantSet && left instanceof Comparison) {
Expression added = ((ConditionInConstantSet) right).getAdditional(session, (Comparison) left);
if (added != null) {
return added.optimize(session);
}
}
}
// TODO optimization: convert .. OR .. to UNION if the cost is lower
Value l = left.isConstant() ? left.getValue(session) : null;
Value r = right.isConstant() ? right.getValue(session) : null;
if (l == null && r == null) {
return this;
}
if (l != null && r != null) {
return ValueExpression.get(getValue(session));
}
switch(andOrType) {
case AND:
if (l != null) {
if (l != ValueNull.INSTANCE && !l.getBoolean()) {
return ValueExpression.get(l);
} else if (l.getBoolean()) {
return right;
}
} else if (r != null) {
if (r != ValueNull.INSTANCE && !r.getBoolean()) {
return ValueExpression.get(r);
} else if (r.getBoolean()) {
return left;
}
}
break;
case OR:
if (l != null) {
if (l.getBoolean()) {
return ValueExpression.get(l);
} else if (l != ValueNull.INSTANCE) {
return right;
}
} else if (r != null) {
if (r.getBoolean()) {
return ValueExpression.get(r);
} else if (r != ValueNull.INSTANCE) {
return left;
}
}
break;
default:
DbException.throwInternalError("type=" + andOrType);
}
return this;
}
Aggregations