Search in sources :

Example 1 with SessionLocal

use of org.h2.engine.SessionLocal in project h2database by h2database.

the class Comparison method optimizeOr.

/**
 * Replace the OR condition with IN condition if possible. Example: given
 * the two conditions A=1 OR A=2, the new condition A IN(1, 2) is returned.
 *
 * @param session the session
 * @param other the second condition
 * @return null or the joined IN condition
 */
Expression optimizeOr(SessionLocal session, Comparison other) {
    if (compareType == EQUAL && other.compareType == EQUAL) {
        Expression left2 = other.left;
        Expression right2 = other.right;
        String l2 = left2.getSQL(DEFAULT_SQL_FLAGS);
        String r2 = right2.getSQL(DEFAULT_SQL_FLAGS);
        if (left.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
            String l = left.getSQL(DEFAULT_SQL_FLAGS);
            if (l.equals(l2)) {
                return getConditionIn(left, right, right2);
            } else if (l.equals(r2)) {
                return getConditionIn(left, right, left2);
            }
        }
        if (right.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
            String r = right.getSQL(DEFAULT_SQL_FLAGS);
            if (r.equals(l2)) {
                return getConditionIn(right, left, right2);
            } else if (r.equals(r2)) {
                return getConditionIn(right, left, left2);
            }
        }
    }
    return null;
}
Also used : TypedValueExpression(org.h2.expression.TypedValueExpression) ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression)

Example 2 with SessionLocal

use of org.h2.engine.SessionLocal in project h2database by h2database.

the class Comparison method optimize.

@Override
public Expression optimize(SessionLocal session) {
    left = left.optimize(session);
    right = right.optimize(session);
    check: {
        TypeInfo leftType = left.getType(), rightType = right.getType();
        if (session.getMode().numericWithBooleanComparison) {
            switch(compareType) {
                case EQUAL:
                case NOT_EQUAL:
                case EQUAL_NULL_SAFE:
                case NOT_EQUAL_NULL_SAFE:
                    int lValueType = leftType.getValueType();
                    if (lValueType == Value.BOOLEAN) {
                        if (DataType.isNumericType(rightType.getValueType())) {
                            break check;
                        }
                    } else if (DataType.isNumericType(lValueType) && rightType.getValueType() == Value.BOOLEAN) {
                        break check;
                    }
            }
        }
        TypeInfo.checkComparable(leftType, rightType);
    }
    if (whenOperand) {
        return this;
    }
    if (right instanceof ExpressionColumn) {
        if (left.isConstant() || left instanceof Parameter) {
            Expression temp = left;
            left = right;
            right = temp;
            compareType = getReversedCompareType(compareType);
        }
    }
    if (left instanceof ExpressionColumn) {
        if (right.isConstant()) {
            Value r = right.getValue(session);
            if (r == ValueNull.INSTANCE) {
                if ((compareType & ~1) != EQUAL_NULL_SAFE) {
                    return TypedValueExpression.UNKNOWN;
                }
            }
            TypeInfo colType = left.getType(), constType = r.getType();
            int constValueType = constType.getValueType();
            if (constValueType != colType.getValueType() || constValueType >= Value.ARRAY) {
                TypeInfo resType = TypeInfo.getHigherType(colType, constType);
                // once.
                if (constValueType != resType.getValueType() || constValueType >= Value.ARRAY) {
                    Column column = ((ExpressionColumn) left).getColumn();
                    right = ValueExpression.get(r.convertTo(resType, session, column));
                }
            }
        } else if (right instanceof Parameter) {
            ((Parameter) right).setColumn(((ExpressionColumn) left).getColumn());
        }
    }
    if (left.isConstant() && right.isConstant()) {
        return ValueExpression.getBoolean(getValue(session));
    }
    if (left.isNullConstant() || right.isNullConstant()) {
        // a NULL constants
        if ((compareType & ~1) != EQUAL_NULL_SAFE) {
            return TypedValueExpression.UNKNOWN;
        } else {
            Expression e = left.isNullConstant() ? right : left;
            int type = e.getType().getValueType();
            if (type != Value.UNKNOWN && type != Value.ROW) {
                return new NullPredicate(e, compareType == NOT_EQUAL_NULL_SAFE, false);
            }
        }
    }
    return this;
}
Also used : TypedValueExpression(org.h2.expression.TypedValueExpression) ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) ExpressionColumn(org.h2.expression.ExpressionColumn) Column(org.h2.table.Column) Value(org.h2.value.Value) Parameter(org.h2.expression.Parameter) TypeInfo(org.h2.value.TypeInfo) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 3 with SessionLocal

use of org.h2.engine.SessionLocal in project h2database by h2database.

the class ConditionInConstantSet method getAdditional.

/**
 * Add an additional element if possible. Example: given two conditions
 * A IN(1, 2) OR A=3, the constant 3 is added: A IN(1, 2, 3).
 *
 * @param session the session
 * @param other the second condition
 * @return null if the condition was not added, or the new condition
 */
Expression getAdditional(SessionLocal session, Comparison other) {
    if (!not && !whenOperand && left.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
        Expression add = other.getIfEquals(left);
        if (add != null) {
            if (add.isConstant()) {
                ArrayList<Expression> list = new ArrayList<>(valueList.size() + 1);
                list.addAll(valueList);
                list.add(add);
                return new ConditionInConstantSet(session, left, false, false, list);
            }
        }
    }
    return null;
}
Also used : Expression(org.h2.expression.Expression) ArrayList(java.util.ArrayList)

Example 4 with SessionLocal

use of org.h2.engine.SessionLocal in project h2database by h2database.

the class ConditionAndOr method optimizeIfConstant.

/**
 * Optimize the condition if at least one part is constant.
 *
 * @param session the session
 * @param andOrType the type
 * @param left the left part of the condition
 * @param right the right part of the condition
 * @return the optimized condition, or {@code null} if condition cannot be optimized
 */
static Expression optimizeIfConstant(SessionLocal session, int andOrType, Expression left, Expression right) {
    if (!left.isConstant()) {
        if (!right.isConstant()) {
            return null;
        } else {
            return optimizeConstant(session, andOrType, right.getValue(session), left);
        }
    }
    Value l = left.getValue(session);
    if (!right.isConstant()) {
        return optimizeConstant(session, andOrType, l, right);
    }
    Value r = right.getValue(session);
    switch(andOrType) {
        case AND:
            {
                if (l.isFalse() || r.isFalse()) {
                    return ValueExpression.FALSE;
                }
                if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
                    return TypedValueExpression.UNKNOWN;
                }
                return ValueExpression.TRUE;
            }
        case OR:
            {
                if (l.isTrue() || r.isTrue()) {
                    return ValueExpression.TRUE;
                }
                if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
                    return TypedValueExpression.UNKNOWN;
                }
                return ValueExpression.FALSE;
            }
        default:
            throw DbException.getInternalError("type=" + andOrType);
    }
}
Also used : Value(org.h2.value.Value)

Example 5 with SessionLocal

use of org.h2.engine.SessionLocal in project h2database by h2database.

the class ConditionAndOr method getValue.

@Override
public Value getValue(SessionLocal session) {
    Value l = left.getValue(session);
    Value r;
    switch(andOrType) {
        case AND:
            {
                if (l.isFalse() || (r = right.getValue(session)).isFalse()) {
                    return ValueBoolean.FALSE;
                }
                if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
                    return ValueNull.INSTANCE;
                }
                return ValueBoolean.TRUE;
            }
        case OR:
            {
                if (l.isTrue() || (r = right.getValue(session)).isTrue()) {
                    return ValueBoolean.TRUE;
                }
                if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
                    return ValueNull.INSTANCE;
                }
                return ValueBoolean.FALSE;
            }
        default:
            throw DbException.getInternalError("type=" + andOrType);
    }
}
Also used : Value(org.h2.value.Value)

Aggregations

Value (org.h2.value.Value)228 Constraint (org.h2.constraint.Constraint)84 Expression (org.h2.expression.Expression)75 TypeInfo (org.h2.value.TypeInfo)59 Schema (org.h2.schema.Schema)57 DbException (org.h2.message.DbException)53 SearchRow (org.h2.result.SearchRow)50 ValueBigint (org.h2.value.ValueBigint)50 ArrayList (java.util.ArrayList)42 Column (org.h2.table.Column)41 SessionLocal (org.h2.engine.SessionLocal)40 ValueExpression (org.h2.expression.ValueExpression)40 Index (org.h2.index.Index)40 Row (org.h2.result.Row)40 Table (org.h2.table.Table)32 SQLException (java.sql.SQLException)30 TypedValueExpression (org.h2.expression.TypedValueExpression)28 ExpressionColumn (org.h2.expression.ExpressionColumn)27 Database (org.h2.engine.Database)26 JdbcConnection (org.h2.jdbc.JdbcConnection)25