use of org.apache.groovy.ginq.dsl.expression.FilterExpression 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;
}
}
Aggregations