improve SQLEvalVisitor

This commit is contained in:
wenshao
2012-11-10 23:53:30 +08:00
parent 8397542337
commit c6215482ae
9 changed files with 231 additions and 61 deletions
@@ -19,8 +19,12 @@ import java.util.ArrayList;
import java.util.List;
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.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
@@ -67,7 +71,26 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE
public boolean visit(SQLBinaryOpExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLIntegerExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(MySqlBooleanExpr x) {
x.getAttributes().put(EVAL_VALUE, x.getValue());
return false;
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
@@ -19,7 +19,10 @@ import java.util.ArrayList;
import java.util.List;
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.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
@@ -67,6 +70,19 @@ public class OracleEvalVisitor extends OracleASTVisitorAdapter implements SQLEva
public boolean visit(SQLBinaryOpExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLIntegerExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
@@ -19,13 +19,16 @@ import java.util.ArrayList;
import java.util.List;
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.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor {
private List<Object> parameters = new ArrayList<Object>();
private int variantIndex = -1;
@@ -68,6 +71,19 @@ public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLIntegerExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
@@ -19,7 +19,10 @@ import java.util.ArrayList;
import java.util.List;
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.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalVisitor {
@@ -66,6 +69,19 @@ public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalV
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLIntegerExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
@@ -31,6 +31,7 @@ import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
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.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
@@ -106,6 +107,46 @@ public class SQLEvalVisitorUtils {
x.putAttribute(EVAL_VALUE, x.getText());
return true;
}
public static boolean visit(SQLEvalVisitor visitor, SQLCaseExpr x) {
x.getValueExpr().accept(visitor);
if (!x.getValueExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object value = x.getValueExpr().getAttribute(EVAL_VALUE);
for (SQLCaseExpr.Item item : x.getItems()) {
item.getConditionExpr().accept(visitor);
if (!item.getConditionExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object conditionValue = item.getConditionExpr().getAttribute(EVAL_VALUE);
if (_eq(value, conditionValue)) {
item.getValueExpr().accept(visitor);
if (item.getValueExpr().getAttributes().containsKey(EVAL_VALUE)) {
x.getAttributes().put(EVAL_VALUE, item.getValueExpr().getAttribute(EVAL_VALUE));
}
return false;
}
}
if (x.getElseExpr() != null) {
x.getElseExpr().accept(visitor);
if (x.getElseExpr().getAttributes().containsKey(EVAL_VALUE)) {
x.getAttributes().put(EVAL_VALUE, x.getElseExpr().getAttribute(EVAL_VALUE));
}
}
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLBinaryOpExpr x) {
x.getLeft().accept(visitor);
@@ -122,35 +163,35 @@ public class SQLEvalVisitorUtils {
Object value = null;
switch (x.getOperator()) {
case Add:
value = _add(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = add(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Subtract:
value = _sub(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = sub(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Multiply:
value = _multi(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = multi(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Divide:
value = _div(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = div(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThan:
value = _gt(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = gt(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThanOrEqual:
value = _gteq(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = gteq(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case LessThan:
value = _lt(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = lt(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case LessThanOrEqual:
value = _lteq(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
value = lteq(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
default:
@@ -160,6 +201,11 @@ public class SQLEvalVisitorUtils {
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLNumericLiteralExpr x) {
x.getAttributes().put(EVAL_VALUE, x.getNumber());
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLVariantRefExpr x) {
if (!"?".equals(x.getName())) {
return false;
@@ -394,7 +440,7 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static Object _div(Object a, Object b) {
public static Object div(Object a, Object b) {
if (a == null || b == null) {
return null;
}
@@ -426,7 +472,7 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static boolean _gt(Object a, Object b) {
public static boolean gt(Object a, Object b) {
if (a == null) {
return false;
}
@@ -481,15 +527,15 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static boolean _gteq(Object a, Object b) {
public static boolean gteq(Object a, Object b) {
if (_eq(a, b)) {
return true;
}
return _gt(a, b);
return gt(a, b);
}
public static boolean _lt(Object a, Object b) {
public static boolean lt(Object a, Object b) {
if (a == null) {
return true;
}
@@ -544,12 +590,12 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static boolean _lteq(Object a, Object b) {
public static boolean lteq(Object a, Object b) {
if (_eq(a, b)) {
return true;
}
return _lt(a, b);
return lt(a, b);
}
public static boolean _eq(Object a, Object b) {
@@ -607,7 +653,7 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static Object _add(Object a, Object b) {
public static Object add(Object a, Object b) {
if (a == null) {
return b;
}
@@ -655,7 +701,7 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static Object _sub(Object a, Object b) {
public static Object sub(Object a, Object b) {
if (a == null) {
return null;
}
@@ -699,7 +745,7 @@ public class SQLEvalVisitorUtils {
throw new IllegalArgumentException();
}
public static Object _multi(Object a, Object b) {
public static Object multi(Object a, Object b) {
if (a == null || b == null) {
return null;
}
@@ -0,0 +1,41 @@
package com.alibaba.druid.util;
public interface JdbcConstants {
public static final String JTDS = "jtds";
public static final String MOCK = "mock";
public static final String HSQL = "hsql";
public static final String DB2 = "db2";
public static final String DB2_DRIVER = "COM.ibm.db2.jdbc.app.DB2Driver";
public static final String POSTGRESQL = "postgresql";
public static final String SYBASE = "sybase";
public static final String SQL_SERVER = "sqlserver";
public static final String ORACLE = "oracle";
public static final String ALI_ORACLE = "AliOracle";
public static final String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
public static final String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
public static final String MYSQL = "mysql";
public static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public static final String DERBY = "derby";
public static final String HBASE = "hbase";
public static final String HIVE = "hive";
public static final String H2 = "h2";
public static final String H2_DRIVER = "org.h2.Driver";
}
@@ -45,44 +45,9 @@ import com.alibaba.druid.support.logging.LogFactory;
/**
* @author wenshao<szujobs@hotmail.com>
*/
public final class JdbcUtils {
public final class JdbcUtils implements JdbcConstants {
public static final String JTDS = "jtds";
public static final String MOCK = "mock";
public static final String HSQL = "hsql";
public static final String DB2 = "db2";
private static final String DB2_DRIVER = "COM.ibm.db2.jdbc.app.DB2Driver";
public static final String POSTGRESQL = "postgresql";
public static final String SYBASE = "sybase";
public static final String SQL_SERVER = "sqlserver";
public static final String ORACLE = "oracle";
public static final String ALI_ORACLE = "AliOracle";
private static final String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
public static final String MYSQL = "mysql";
private static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public static final String DERBY = "derby";
public static final String HBASE = "hbase";
public static final String HIVE = "hive";
public static final String H2 = "h2";
private static final String H2_DRIVER = "org.h2.Driver";
private final static Log LOG = LogFactory.getLog(JdbcUtils.class);
@@ -0,0 +1,15 @@
package com.alibaba.druid.bvt.sql.eval;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.Assert;
import junit.framework.TestCase;
public class EvalCaseThen extends TestCase {
public void test_eval_then() throws Exception {
Assert.assertEquals(111, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "case ? when 0 then 111 else 222 end", 0));
Assert.assertEquals(222, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "case ? when 0 then 111 else 222 end", 1));
}
}
@@ -15,21 +15,53 @@
*/
package com.alibaba.druid.bvt.sql.eval;
import java.math.BigDecimal;
import junit.framework.Assert;
import junit.framework.TestCase;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.JdbcConstants;
public class EvalTest extends TestCase {
public void testEval() throws Exception {
Assert.assertEquals("A", SQLEvalVisitorUtils.evalExpr(JdbcUtils.MYSQL, "?", "A"));
Assert.assertEquals(123, SQLEvalVisitorUtils.evalExpr(JdbcUtils.MYSQL, "?", 123));
Assert.assertEquals("A", SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "?", "A"));
Assert.assertEquals(123, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "?", 123));
}
public void testEval_1() throws Exception {
Assert.assertEquals("AB", SQLEvalVisitorUtils.evalExpr(JdbcUtils.MYSQL, "? + ?", "A", "B"));
Assert.assertEquals(234, SQLEvalVisitorUtils.evalExpr(JdbcUtils.MYSQL, "? + ?", 123, 111));
Assert.assertEquals("AB", SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? + ?", "A", "B"));
Assert.assertEquals(234, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? + ?", 123, 111));
}
public void testEval_2() throws Exception {
Assert.assertEquals(110, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * ?", 10, 11));
}
public void testEval_3() throws Exception {
Assert.assertEquals(new BigDecimal("110"), SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * ?",
new BigDecimal("10"),
new BigDecimal("11")));
}
public void testEval_4() throws Exception {
Assert.assertEquals(new BigDecimal("110"),
SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * 11", new BigDecimal("10")));
}
public void testEval_5() throws Exception {
Assert.assertEquals(new BigDecimal("110.0"),
SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * 11.0", new BigDecimal("10")));
}
public void testEval_6() throws Exception {
Assert.assertEquals(new BigDecimal("110.0"),
SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * 11", new BigDecimal("10.0")));
}
public void testEval_7() throws Exception {
Assert.assertEquals(new BigDecimal("110.0"),
SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? * 11.0", "10"));
}
}