Search in sources :

Example 1 with DataSourceHolder

use of org.apache.groovy.ginq.dsl.expression.DataSourceHolder in project groovy by apache.

the class GinqAstBuilder method visitMethodCallExpression.

@Override
public void visitMethodCallExpression(MethodCallExpression call) {
    final String methodName = call.getMethodAsString();
    if (KW_OVER.equals(methodName)) {
        visitingOverClause = true;
    }
    super.visitMethodCallExpression(call);
    if (KW_OVER.equals(methodName)) {
        visitingOverClause = false;
    }
    if (!KEYWORD_SET.contains(methodName)) {
        ignoredMethodCallExpressionList.add(call);
        return;
    }
    if (KW_FROM.equals(methodName)) {
        final GinqExpression ginqExpression = new GinqExpression();
        ginqExpression.setSourcePosition(call);
        // store the result
        ginqExpressionStack.push(ginqExpression);
    }
    GinqExpression currentGinqExpression = ginqExpressionStack.peek();
    AbstractGinqExpression latestGinqExpressionClause = getLatestGinqExpressionClause(call);
    if (KW_FROM.equals(methodName) || JoinExpression.isJoinExpression(methodName)) {
        ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
        if (arguments.getExpressions().size() != 1) {
            this.collectSyntaxError(new GinqSyntaxError("Only 1 argument expected for `" + methodName + "`, e.g. `" + methodName + " n in nums`", call.getLineNumber(), call.getColumnNumber()));
        }
        final Expression expression = arguments.getExpression(0);
        if (!(expression instanceof BinaryExpression && ((BinaryExpression) expression).getOperation().getType() == Types.KEYWORD_IN)) {
            this.collectSyntaxError(new GinqSyntaxError("`in` is expected for `" + methodName + "`, e.g. `" + methodName + " n in nums`", call.getLineNumber(), call.getColumnNumber()));
        }
        BinaryExpression binaryExpression = (BinaryExpression) expression;
        Expression aliasExpr = binaryExpression.getLeftExpression();
        Expression dataSourceExpr = binaryExpression.getRightExpression();
        DataSourceExpression dataSourceExpression;
        if (KW_FROM.equals(methodName)) {
            dataSourceExpression = new FromExpression(aliasExpr, dataSourceExpr);
            currentGinqExpression.setFromExpression((FromExpression) dataSourceExpression);
        } else {
            dataSourceExpression = new JoinExpression(methodName, aliasExpr, dataSourceExpr);
            currentGinqExpression.addJoinExpression((JoinExpression) dataSourceExpression);
        }
        dataSourceExpression.setSourcePosition(call.getMethod());
        setLatestGinqExpressionClause(dataSourceExpression);
        return;
    }
    if (KW_WHERE.equals(methodName) || KW_ON.equals(methodName) || KW_HAVING.equals(methodName)) {
        Expression filterExpr = ((ArgumentListExpression) call.getArguments()).getExpression(0);
        FilterExpression filterExpression;
        if (KW_WHERE.equals(methodName)) {
            filterExpression = new WhereExpression(filterExpr);
        } else if (KW_ON.equals(methodName)) {
            filterExpression = new OnExpression(filterExpr);
        } else {
            filterExpression = new HavingExpression(filterExpr);
        }
        filterExpression.setSourcePosition(call.getMethod());
        if (latestGinqExpressionClause instanceof JoinExpression && filterExpression instanceof OnExpression) {
            ((JoinExpression) latestGinqExpressionClause).setOnExpression((OnExpression) filterExpression);
        } else if (latestGinqExpressionClause instanceof DataSourceHolder && filterExpression instanceof WhereExpression) {
            if (null != currentGinqExpression.getGroupExpression() || null != currentGinqExpression.getOrderExpression() || null != currentGinqExpression.getLimitExpression()) {
                this.collectSyntaxError(new GinqSyntaxError("The preceding clause of `" + methodName + "` should be `from`/" + "join clause", call.getLineNumber(), call.getColumnNumber()));
            }
            currentGinqExpression.setWhereExpression((WhereExpression) filterExpression);
        } else if (latestGinqExpressionClause instanceof GroupExpression && filterExpression instanceof HavingExpression) {
            ((GroupExpression) latestGinqExpressionClause).setHavingExpression((HavingExpression) filterExpression);
        } else {
            this.collectSyntaxError(new GinqSyntaxError("The preceding clause of `" + methodName + "` should be " + (KW_ON.equals(methodName) ? "" : "`from`/") + "join clause", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            if (latestGinqExpressionClause instanceof DataSourceExpression) {
                filterExpression.setDataSourceExpression(((DataSourceExpression) latestGinqExpressionClause));
            } else {
                filterExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
            }
        }
        setLatestGinqExpressionClause(filterExpression);
        return;
    }
    if (KW_EXISTS.equals(methodName)) {
        if (null != latestGinqExpression) {
            ArgumentListExpression argumentListExpression = (ArgumentListExpression) call.getArguments();
            if (argumentListExpression.getExpressions().isEmpty() && isSelectMethodCallExpression(call.getObjectExpression())) {
                call.setObjectExpression(latestGinqExpression);
                // use the nested ginq and clear it
                latestGinqExpression = null;
            }
        }
    }
    if (KW_GROUPBY.equals(methodName)) {
        GroupExpression groupExpression = new GroupExpression(call.getArguments());
        groupExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setGroupExpression(groupExpression);
        if (latestGinqExpressionClause instanceof OrderExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `orderby`", call.getLineNumber(), call.getColumnNumber()));
        } else if (latestGinqExpressionClause instanceof LimitExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `limit`", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            groupExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(groupExpression);
        return;
    }
    if (KW_ORDERBY.equals(methodName) && !visitingOverClause) {
        OrderExpression orderExpression = new OrderExpression(call.getArguments());
        orderExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setOrderExpression(orderExpression);
        if (latestGinqExpressionClause instanceof LimitExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `limit`", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            orderExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(orderExpression);
        return;
    }
    if (KW_LIMIT.equals(methodName)) {
        LimitExpression limitExpression = new LimitExpression(call.getArguments());
        limitExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setLimitExpression(limitExpression);
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            limitExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(limitExpression);
        return;
    }
    if (KW_SELECT.equals(methodName)) {
        TupleExpression tupleExpression = (TupleExpression) call.getArguments();
        if (1 == tupleExpression.getExpressions().size()) {
            Expression firstExpression = tupleExpression.getExpressions().get(0);
            if (firstExpression instanceof MethodCallExpression) {
                MethodCallExpression mce = (MethodCallExpression) firstExpression;
                if (KW_DISTINCT.equals(mce.getMethodAsString())) {
                    tupleExpression = (TupleExpression) mce.getArguments();
                    currentGinqExpression.putNodeMetaData(GINQ_SELECT_DISTINCT, true);
                }
            }
        } else {
            for (Expression expression : tupleExpression.getExpressions()) {
                if (expression instanceof MethodCallExpression) {
                    MethodCallExpression mce = (MethodCallExpression) expression;
                    if (KW_DISTINCT.equals(mce.getMethodAsString())) {
                        this.collectSyntaxError(new GinqSyntaxError("Invalid usage of `distinct`", mce.getLineNumber(), mce.getColumnNumber()));
                    }
                }
            }
        }
        SelectExpression selectExpression = new SelectExpression(tupleExpression);
        selectExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setSelectExpression(selectExpression);
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            selectExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(selectExpression);
        latestGinqExpression = ginqExpressionStack.pop();
        latestGinqExpression.setSourcePosition(call);
        return;
    }
}
Also used : LimitExpression(org.apache.groovy.ginq.dsl.expression.LimitExpression) OrderExpression(org.apache.groovy.ginq.dsl.expression.OrderExpression) GinqExpression(org.apache.groovy.ginq.dsl.expression.GinqExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) SelectExpression(org.apache.groovy.ginq.dsl.expression.SelectExpression) GroupExpression(org.apache.groovy.ginq.dsl.expression.GroupExpression) FromExpression(org.apache.groovy.ginq.dsl.expression.FromExpression) OnExpression(org.apache.groovy.ginq.dsl.expression.OnExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) GinqExpression(org.apache.groovy.ginq.dsl.expression.GinqExpression) JoinExpression(org.apache.groovy.ginq.dsl.expression.JoinExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) LimitExpression(org.apache.groovy.ginq.dsl.expression.LimitExpression) Expression(org.codehaus.groovy.ast.expr.Expression) WhereExpression(org.apache.groovy.ginq.dsl.expression.WhereExpression) FilterExpression(org.apache.groovy.ginq.dsl.expression.FilterExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DataSourceExpression(org.apache.groovy.ginq.dsl.expression.DataSourceExpression) OrderExpression(org.apache.groovy.ginq.dsl.expression.OrderExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) SelectExpression(org.apache.groovy.ginq.dsl.expression.SelectExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) GroupExpression(org.apache.groovy.ginq.dsl.expression.GroupExpression) HavingExpression(org.apache.groovy.ginq.dsl.expression.HavingExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ShutdownExpression(org.apache.groovy.ginq.dsl.expression.ShutdownExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) OnExpression(org.apache.groovy.ginq.dsl.expression.OnExpression) FromExpression(org.apache.groovy.ginq.dsl.expression.FromExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) HavingExpression(org.apache.groovy.ginq.dsl.expression.HavingExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) JoinExpression(org.apache.groovy.ginq.dsl.expression.JoinExpression) DataSourceHolder(org.apache.groovy.ginq.dsl.expression.DataSourceHolder) FilterExpression(org.apache.groovy.ginq.dsl.expression.FilterExpression) DataSourceExpression(org.apache.groovy.ginq.dsl.expression.DataSourceExpression) WhereExpression(org.apache.groovy.ginq.dsl.expression.WhereExpression)

Aggregations

AbstractGinqExpression (org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression)1 DataSourceExpression (org.apache.groovy.ginq.dsl.expression.DataSourceExpression)1 DataSourceHolder (org.apache.groovy.ginq.dsl.expression.DataSourceHolder)1 FilterExpression (org.apache.groovy.ginq.dsl.expression.FilterExpression)1 FromExpression (org.apache.groovy.ginq.dsl.expression.FromExpression)1 GinqExpression (org.apache.groovy.ginq.dsl.expression.GinqExpression)1 GroupExpression (org.apache.groovy.ginq.dsl.expression.GroupExpression)1 HavingExpression (org.apache.groovy.ginq.dsl.expression.HavingExpression)1 JoinExpression (org.apache.groovy.ginq.dsl.expression.JoinExpression)1 LimitExpression (org.apache.groovy.ginq.dsl.expression.LimitExpression)1 OnExpression (org.apache.groovy.ginq.dsl.expression.OnExpression)1 OrderExpression (org.apache.groovy.ginq.dsl.expression.OrderExpression)1 SelectExpression (org.apache.groovy.ginq.dsl.expression.SelectExpression)1 ShutdownExpression (org.apache.groovy.ginq.dsl.expression.ShutdownExpression)1 WhereExpression (org.apache.groovy.ginq.dsl.expression.WhereExpression)1 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)1 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)1 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)1 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)1 Expression (org.codehaus.groovy.ast.expr.Expression)1