Search in sources :

Example 1 with ConditionInConstantSet

use of org.h2.expression.ConditionInConstantSet 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)

Example 2 with ConditionInConstantSet

use of org.h2.expression.ConditionInConstantSet in project ignite by apache.

the class GridSqlQueryParser method parseExpression0.

/**
 * @param expression Expression.
 * @param calcTypes Calculate types for all the expressions.
 * @return Parsed expression.
 */
private GridSqlElement parseExpression0(Expression expression, boolean calcTypes) {
    if (expression instanceof ExpressionColumn) {
        ExpressionColumn expCol = (ExpressionColumn) expression;
        return new GridSqlColumn(expCol.getColumn(), parseTableFilter(expCol.getTableFilter()), SCHEMA_NAME.get(expCol), expCol.getOriginalTableAliasName(), expCol.getColumnName());
    }
    if (expression instanceof Alias)
        return new GridSqlAlias(expression.getAlias(), parseExpression(expression.getNonAliasExpression(), calcTypes), true);
    if (expression instanceof ValueExpression)
        // == comparison is legit, see ValueExpression#getSQL()
        return expression == ValueExpression.getDefault() ? GridSqlKeyword.DEFAULT : new GridSqlConst(expression.getValue(null));
    if (expression instanceof Operation) {
        Operation operation = (Operation) expression;
        Operation.OpType type = OPERATION_TYPE.get(operation);
        if (type == Operation.OpType.NEGATE) {
            assert OPERATION_RIGHT.get(operation) == null;
            return new GridSqlOperation(GridSqlOperationType.NEGATE, parseExpression(OPERATION_LEFT.get(operation), calcTypes));
        }
        return new GridSqlOperation(mapOperationType(type), parseExpression(OPERATION_LEFT.get(operation), calcTypes), parseExpression(OPERATION_RIGHT.get(operation), calcTypes));
    }
    if (expression instanceof Comparison) {
        Comparison cmp = (Comparison) expression;
        GridSqlOperationType opType = COMPARISON_TYPES[COMPARISON_TYPE.get(cmp)];
        assert opType != null : COMPARISON_TYPE.get(cmp);
        Expression leftExp = COMPARISON_LEFT.get(cmp);
        GridSqlElement left = parseExpression(leftExp, calcTypes);
        if (opType.childrenCount() == 1)
            return new GridSqlOperation(opType, left);
        Expression rightExp = COMPARISON_RIGHT.get(cmp);
        GridSqlElement right = parseExpression(rightExp, calcTypes);
        return new GridSqlOperation(opType, left, right);
    }
    if (expression instanceof ConditionNot)
        return new GridSqlOperation(NOT, parseExpression(expression.getNotIfPossible(null), calcTypes));
    if (expression instanceof ConditionAndOr) {
        ConditionAndOr andOr = (ConditionAndOr) expression;
        int type = ANDOR_TYPE.get(andOr);
        assert type == ConditionAndOr.AND || type == ConditionAndOr.OR;
        return new GridSqlOperation(type == ConditionAndOr.AND ? AND : OR, parseExpression(ANDOR_LEFT.get(andOr), calcTypes), parseExpression(ANDOR_RIGHT.get(andOr), calcTypes));
    }
    if (expression instanceof Subquery) {
        Query qry = ((Subquery) expression).getQuery();
        return parseQueryExpression(qry);
    }
    if (expression instanceof ConditionIn) {
        GridSqlOperation res = new GridSqlOperation(IN);
        res.addChild(parseExpression(LEFT_CI.get((ConditionIn) expression), calcTypes));
        List<Expression> vals = VALUE_LIST_CI.get((ConditionIn) expression);
        for (Expression val : vals) res.addChild(parseExpression(val, calcTypes));
        return res;
    }
    if (expression instanceof ConditionInConstantSet) {
        GridSqlOperation res = new GridSqlOperation(IN);
        res.addChild(parseExpression(LEFT_CICS.get((ConditionInConstantSet) expression), calcTypes));
        List<Expression> vals = VALUE_LIST_CICS.get((ConditionInConstantSet) expression);
        for (Expression val : vals) res.addChild(parseExpression(val, calcTypes));
        return res;
    }
    if (expression instanceof ConditionInSelect) {
        GridSqlOperation res = new GridSqlOperation(IN);
        boolean all = ALL.get((ConditionInSelect) expression);
        int compareType = COMPARE_TYPE.get((ConditionInSelect) expression);
        assert0(!all, expression);
        assert0(compareType == Comparison.EQUAL, expression);
        res.addChild(parseExpression(LEFT_CIS.get((ConditionInSelect) expression), calcTypes));
        Query qry = QUERY_IN.get((ConditionInSelect) expression);
        res.addChild(parseQueryExpression(qry));
        return res;
    }
    if (expression instanceof CompareLike) {
        assert0(ESCAPE.get((CompareLike) expression) == null, expression);
        boolean regexp = REGEXP_CL.get((CompareLike) expression);
        return new GridSqlOperation(regexp ? REGEXP : LIKE, parseExpression(LEFT.get((CompareLike) expression), calcTypes), parseExpression(RIGHT.get((CompareLike) expression), calcTypes));
    }
    if (expression instanceof Function) {
        Function f = (Function) expression;
        GridSqlFunction res = new GridSqlFunction(null, f.getName());
        if (f.getArgs() != null) {
            if (f.getFunctionType() == Function.TABLE || f.getFunctionType() == Function.TABLE_DISTINCT) {
                Column[] cols = FUNC_TBL_COLS.get((TableFunction) f);
                Expression[] args = f.getArgs();
                assert cols.length == args.length;
                for (int i = 0; i < cols.length; i++) {
                    GridSqlElement arg = parseExpression(args[i], calcTypes);
                    GridSqlAlias alias = new GridSqlAlias(cols[i].getName(), arg, false);
                    alias.resultType(fromColumn(cols[i]));
                    res.addChild(alias);
                }
            } else {
                for (Expression arg : f.getArgs()) {
                    if (arg == null) {
                        if (f.getFunctionType() != Function.CASE)
                            throw new IllegalStateException("Function type with null arg: " + f.getFunctionType());
                        res.addChild(GridSqlPlaceholder.EMPTY);
                    } else
                        res.addChild(parseExpression(arg, calcTypes));
                }
            }
        }
        if (f.getFunctionType() == Function.CAST || f.getFunctionType() == Function.CONVERT) {
            checkTypeSupported(f.getType(), "[expSql=" + f.getSQL() + ']');
            res.resultType(fromExpression(f));
        }
        return res;
    }
    if (expression instanceof JavaFunction) {
        JavaFunction f = (JavaFunction) expression;
        FunctionAlias alias = FUNC_ALIAS.get(f);
        GridSqlFunction res = new GridSqlFunction(alias.getSchema().getName(), f.getName());
        if (f.getArgs() != null) {
            for (Expression arg : f.getArgs()) res.addChild(parseExpression(arg, calcTypes));
        }
        return res;
    }
    if (expression instanceof Parameter)
        return new GridSqlParameter(((Parameter) expression).getIndex());
    if (expression instanceof Aggregate) {
        Aggregate.AggregateType type = TYPE.get((Aggregate) expression);
        if (GridSqlAggregateFunction.isValidType(type)) {
            GridSqlAggregateFunction res = new GridSqlAggregateFunction(DISTINCT.get((Aggregate) expression), type);
            Expression on = ON.get((Aggregate) expression);
            if (on != null)
                res.addChild(parseExpression(on, calcTypes));
            ArrayList<SelectOrderBy> orders = GROUP_CONCAT_ORDER_LIST.get((Aggregate) expression);
            if (!F.isEmpty(orders))
                parseGroupConcatOrder(res, orders, calcTypes);
            Expression separator = GROUP_CONCAT_SEPARATOR.get((Aggregate) expression);
            if (separator != null)
                res.setGroupConcatSeparator(parseExpression(separator, calcTypes));
            return res;
        }
    }
    if (expression instanceof ExpressionList) {
        Expression[] exprs = EXPR_LIST.get((ExpressionList) expression);
        GridSqlArray res = new GridSqlArray(exprs.length);
        for (Expression expr : exprs) res.addChild(parseExpression(expr, calcTypes));
        return res;
    }
    if (expression instanceof ConditionExists) {
        Query qry = QUERY_EXISTS.get((ConditionExists) expression);
        GridSqlOperation res = new GridSqlOperation(EXISTS);
        res.addChild(parseQueryExpression(qry));
        return res;
    }
    throw new IgniteException("Unsupported expression: " + expression + " [type=" + expression.getClass().getSimpleName() + ']');
}
Also used : SelectOrderBy(org.h2.command.dml.SelectOrderBy) ConditionNot(org.h2.expression.ConditionNot) Query(org.h2.command.dml.Query) JavaFunction(org.h2.expression.JavaFunction) Operation(org.h2.expression.Operation) ConditionAndOr(org.h2.expression.ConditionAndOr) Subquery(org.h2.expression.Subquery) ExpressionColumn(org.h2.expression.ExpressionColumn) Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) Comparison(org.h2.expression.Comparison) GridSqlType.fromColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) IgniteException(org.apache.ignite.IgniteException) ExpressionList(org.h2.expression.ExpressionList) FunctionAlias(org.h2.engine.FunctionAlias) ConditionIn(org.h2.expression.ConditionIn) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) CompareLike(org.h2.expression.CompareLike) ConditionInConstantSet(org.h2.expression.ConditionInConstantSet) ConditionInSelect(org.h2.expression.ConditionInSelect) Expression(org.h2.expression.Expression) GridSqlType.fromExpression(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromExpression) ValueExpression(org.h2.expression.ValueExpression) FunctionAlias(org.h2.engine.FunctionAlias) Alias(org.h2.expression.Alias) ValueExpression(org.h2.expression.ValueExpression) Parameter(org.h2.expression.Parameter) Aggregate(org.h2.expression.Aggregate) ConditionExists(org.h2.expression.ConditionExists)

Aggregations

IgniteException (org.apache.ignite.IgniteException)1 GridSqlType.fromColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn)1 GridSqlType.fromExpression (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromExpression)1 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)1 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)1 Query (org.h2.command.dml.Query)1 SelectOrderBy (org.h2.command.dml.SelectOrderBy)1 FunctionAlias (org.h2.engine.FunctionAlias)1 Aggregate (org.h2.expression.Aggregate)1 Alias (org.h2.expression.Alias)1 CompareLike (org.h2.expression.CompareLike)1 Comparison (org.h2.expression.Comparison)1 ConditionAndOr (org.h2.expression.ConditionAndOr)1 ConditionExists (org.h2.expression.ConditionExists)1 ConditionIn (org.h2.expression.ConditionIn)1 ConditionInConstantSet (org.h2.expression.ConditionInConstantSet)1 ConditionInSelect (org.h2.expression.ConditionInSelect)1 ConditionNot (org.h2.expression.ConditionNot)1 Expression (org.h2.expression.Expression)1 ExpressionColumn (org.h2.expression.ExpressionColumn)1