private GridSqlElement parseExpression0()

in modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java [2096:2338]


    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() + ']');
    }