Search in sources :

Example 1 with Comparison

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;
}
Also used : ValueString(org.h2.value.ValueString)

Example 2 with Comparison

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;
}
Also used : TableFilter(org.h2.table.TableFilter) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Comparison(org.h2.expression.Comparison) ValueString(org.h2.value.ValueString) ConditionAndOr(org.h2.expression.ConditionAndOr) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 3 with Comparison

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;
}
Also used : Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) Expression(org.h2.expression.Expression) Comparison(org.h2.expression.Comparison) MVPrimaryIndex(org.h2.mvstore.db.MVPrimaryIndex) ConditionAndOr(org.h2.expression.ConditionAndOr) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 4 with Comparison

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());
        }
    }
}
Also used : ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) Comparison(org.h2.expression.Comparison) ValueExpression(org.h2.expression.ValueExpression) ConditionAndOr(org.h2.expression.ConditionAndOr) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 5 with Comparison

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;
}
Also used : Value(org.h2.value.Value)

Aggregations

Expression (org.h2.expression.Expression)7 Comparison (org.h2.expression.Comparison)6 ConditionAndOr (org.h2.expression.ConditionAndOr)6 ExpressionColumn (org.h2.expression.ExpressionColumn)6 ValueExpression (org.h2.expression.ValueExpression)5 Column (org.h2.table.Column)4 Value (org.h2.value.Value)4 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)3 IndexColumn (org.h2.table.IndexColumn)3 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)2 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)2 Query (org.h2.command.dml.Query)2 Constraint (org.h2.constraint.Constraint)2 CompareLike (org.h2.expression.CompareLike)2 ConditionExists (org.h2.expression.ConditionExists)2 ConditionIn (org.h2.expression.ConditionIn)2 ConditionInSelect (org.h2.expression.ConditionInSelect)2 ConditionNot (org.h2.expression.ConditionNot)2 Function (org.h2.expression.Function)2 JavaFunction (org.h2.expression.JavaFunction)2