/*
* Copyright 1999-2013 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.garuda.plan.logical;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.garuda.parser.visitor.GarudaASTVisitorAdapter;
import com.alibaba.garuda.plan.logical.expression.AddExpression;
import com.alibaba.garuda.plan.logical.expression.AndExpression;
import com.alibaba.garuda.plan.logical.expression.ConstantExpression;
import com.alibaba.garuda.plan.logical.expression.DivideExpression;
import com.alibaba.garuda.plan.logical.expression.EqualExpression;
import com.alibaba.garuda.plan.logical.expression.GreaterThanEqualExpression;
import com.alibaba.garuda.plan.logical.expression.GreaterThanExpression;
import com.alibaba.garuda.plan.logical.expression.LessThanEqualExpression;
import com.alibaba.garuda.plan.logical.expression.LessThanExpression;
import com.alibaba.garuda.plan.logical.expression.LogicalExpression;
import com.alibaba.garuda.plan.logical.expression.LogicalExpressionPlan;
import com.alibaba.garuda.plan.logical.expression.MultiplyExpression;
import com.alibaba.garuda.plan.logical.expression.OrExpression;
import com.alibaba.garuda.plan.logical.expression.ProjectExpression;
import com.alibaba.garuda.plan.logical.expression.RegexExpression;
import com.alibaba.garuda.plan.logical.expression.SubtractExpression;
import com.alibaba.garuda.plan.logical.expression.UserFuncExpression;
/**
* @author Min Zhou (coderplay@gmail.com)
*/
public class LogicalExpressionPlanGenerator extends GarudaASTVisitorAdapter {
private static final String EXPRESSION_CACHE = "expression.cache";
private LogicalExpressionPlan exprPlan = new LogicalExpressionPlan();
// private LogicalRelationalOperator parent;
// public LogicalExpressionPlanGenerator(LogicalRelationalOperator parent) {
// this.parent = parent;
// }
public LogicalExpressionPlan getPlan() {
return exprPlan;
}
@Override
public boolean visit(SQLIdentifierExpr x) {
// x.putAttribute(EXPRESSION_CACHE, new ProjectExpression(exprPlan, 0, 0,
// parent));
x.putAttribute(EXPRESSION_CACHE, new ProjectExpression(exprPlan, 0, 0,
null));
return false;
}
@Override
public boolean visit(SQLPropertyExpr x) {
// x.getOwner().accept(this);
// print(".");
// print(x.getName());
return false;
}
@Override
public boolean visit(SQLCharExpr x) {
x.putAttribute(EXPRESSION_CACHE,
new ConstantExpression(exprPlan, x.getText()));
return false;
}
@Override
public boolean visit(SQLVariantRefExpr x) {
return false;
}
@Override
public boolean visit(SQLUnaryExpr x) {
return false;
}
public boolean visit(SQLBinaryOpExpr x) {
SQLExpr left = x.getLeft();
SQLExpr right = x.getRight();
left.accept(this);
if (!left.getAttributes().containsKey(EXPRESSION_CACHE)) {
return false;
}
right.accept(this);
if (!right.getAttributes().containsKey(EXPRESSION_CACHE)) {
return false;
}
LogicalExpression value = null;
switch (x.getOperator()) {
case BooleanAnd:
value = new AndExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttributes().get(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case BooleanOr:
value = new OrExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttributes().get(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case Add:
value = new AddExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttributes().get(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case Subtract:
value = new SubtractExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case Multiply:
value = new MultiplyExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case Divide:
value = new DivideExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case GreaterThan:
value = new GreaterThanExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case GreaterThanOrEqual:
value = new GreaterThanEqualExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case LessThan:
value = new LessThanExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case LessThanOrEqual:
value = new LessThanEqualExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case Is:
case Equality:
value = new EqualExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
break;
case IsNot:
// TODO:
break;
case RegExp:
case RLike: {
value = new RegexExpression(exprPlan,
(LogicalExpression) left.getAttribute(EXPRESSION_CACHE),
(LogicalExpression) right.getAttribute(EXPRESSION_CACHE));
x.putAttribute(EXPRESSION_CACHE, value);
}
break;
default:
break;
}
return false;
}
@Override
public boolean visit(SQLIntegerExpr x) {
x.putAttribute(EXPRESSION_CACHE,
new ConstantExpression(exprPlan, x.getNumber()));
return false;
}
@Override
public boolean visit(SQLNumberExpr x) {
x.putAttribute(EXPRESSION_CACHE,
new ConstantExpression(exprPlan, x.getNumber()));
return false;
}
@Override
public boolean visit(SQLCaseExpr x) {
return false;
}
@Override
public boolean visit(SQLInListExpr x) {
return false;
}
@Override
public boolean visit(SQLNullExpr x) {
return false;
}
@Override
public boolean visit(SQLMethodInvokeExpr x) {
x.putAttribute(EXPRESSION_CACHE, new UserFuncExpression(exprPlan));
return false;
}
@Override
public boolean visit(SQLAggregateExpr x) {
x.putAttribute(EXPRESSION_CACHE, new UserFuncExpression(exprPlan));
return false;
}
@Override
public boolean visit(SQLQueryExpr x) {
return false;
}
}