/*
* Copyright 1999-2011 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.druid.sql.visitor;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import com.alibaba.druid.DruidRuntimeException;
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.SQLBetweenExpr;
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.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlEvalVisitorImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleEvalVisitor;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGEvalVisitor;
import com.alibaba.druid.util.JdbcUtils;
public class SQLEvalVisitorUtils {
public static Object evalExpr(String dbType, String expr, Object... parameters) {
SQLExpr sqlExpr = SQLUtils.toSQLExpr(expr, dbType);
return eval(dbType, sqlExpr, parameters);
}
public static Object evalExpr(String dbType, String expr, List<Object> parameters) {
SQLExpr sqlExpr = SQLUtils.toSQLExpr(expr);
return eval(dbType, sqlExpr, parameters);
}
public static Object eval(String dbType, SQLObject sqlObject, Object... parameters) {
return eval(dbType, sqlObject, Arrays.asList(parameters));
}
public static Object getValue(SQLObject sqlObject) {
if (sqlObject instanceof SQLNumericLiteralExpr) {
return ((SQLNumericLiteralExpr) sqlObject).getNumber();
}
return sqlObject.getAttributes().get(EVAL_VALUE);
}
public static Object eval(String dbType, SQLObject sqlObject, List<Object> parameters) {
return eval(dbType, sqlObject, parameters, true);
}
public static Object eval(String dbType, SQLObject sqlObject, List<Object> parameters, boolean throwError) {
SQLEvalVisitor visitor = createEvalVisitor(dbType);
visitor.setParameters(parameters);
sqlObject.accept(visitor);
Object value = getValue(sqlObject);
if (value == null) {
if (throwError && !sqlObject.getAttributes().containsKey(EVAL_VALUE)) {
throw new DruidRuntimeException("eval error : " + SQLUtils.toSQLString(sqlObject, dbType));
}
}
return value;
}
public static SQLEvalVisitor createEvalVisitor(String dbType) {
if (JdbcUtils.MYSQL.equals(dbType)) {
return new MySqlEvalVisitorImpl();
}
if (JdbcUtils.H2.equals(dbType)) {
return new MySqlEvalVisitorImpl();
}
if (JdbcUtils.ORACLE.equals(dbType) || JdbcUtils.ALI_ORACLE.equals(dbType)) {
return new OracleEvalVisitor();
}
if (JdbcUtils.POSTGRESQL.equals(dbType)) {
return new PGEvalVisitor();
}
return new SQLEvalVisitorImpl();
}
public static boolean visit(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if ("concat".equalsIgnoreCase(x.getMethodName())) {
StringBuilder buf = new StringBuilder();
for (SQLExpr item : x.getParameters()) {
item.accept(visitor);
Object itemValue = item.getAttributes().get(EVAL_VALUE);
if (itemValue == null) {
continue;
}
buf.append(itemValue.toString());
}
x.getAttributes().put(EVAL_VALUE, buf.toString());
} else if ("now".equalsIgnoreCase(x.getMethodName())) {
x.getAttributes().put(EVAL_VALUE, new Date());
} else if ("ascii".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() == 0) {
return false;
}
SQLExpr param = x.getParameters().get(0);
param.accept(visitor);
Object paramValue = param.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
String strValue = paramValue.toString();
if (strValue.length() == 0) {
return false;
}
int ascii = strValue.charAt(0);
x.getAttributes().put(EVAL_VALUE, ascii);
} else if ("instr".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
String strValue0 = param0Value.toString();
String strValue1 = param1Value.toString();
int result = strValue0.indexOf(strValue1) + 1;
x.putAttribute(EVAL_VALUE, result);
} else if ("left".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
String strValue = param0Value.toString();
int intValue = _int(param1Value);
String result = strValue.substring(0, intValue);
x.putAttribute(EVAL_VALUE, result);
} else if ("right".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
String strValue = param0Value.toString();
int intValue = _int(param1Value);
String result = strValue.substring(strValue.length() - intValue, strValue.length());
x.putAttribute(EVAL_VALUE, result);
} else if ("reverse".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return false;
}
String strValue = param0Value.toString();
StringBuilder buf = new StringBuilder();
for (int i = strValue.length() - 1; i >= 0; --i) {
buf.append(strValue.charAt(i));
}
String result = buf.toString();
x.putAttribute(EVAL_VALUE, result);
} else if ("trim".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return false;
}
String strValue = param0Value.toString();
String result = strValue.trim();
x.putAttribute(EVAL_VALUE, result);
} else if ("length".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return false;
}
String strValue = param0Value.toString();
int result = strValue.length();
x.putAttribute(EVAL_VALUE, result);
} else if ("ucase".equalsIgnoreCase(x.getMethodName()) || "upper".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return false;
}
String strValue = param0Value.toString();
String result = strValue.toUpperCase();
x.putAttribute(EVAL_VALUE, result);
} else if ("lcase".equalsIgnoreCase(x.getMethodName()) || "lower".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return false;
}
String strValue = param0Value.toString();
String result = strValue.toLowerCase();
x.putAttribute(EVAL_VALUE, result);
} else if ("mod".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
int intValue0 = _int(param0Value);
int intValue1 = _int(param1Value);
int result = intValue0 % intValue1;
x.putAttribute(EVAL_VALUE, result);
} else if ("abs".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
Object result;
if (paramValue instanceof Integer) {
result = Math.abs(((Integer) paramValue).intValue());
} else if (paramValue instanceof Long) {
result = Math.abs(((Long) paramValue).longValue());
} else {
result = _decimal(paramValue).abs();
}
x.putAttribute(EVAL_VALUE, result);
} else if ("acos".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
double result = Math.acos(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("asin".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
double result = Math.asin(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("atan".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
double result = Math.atan(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("atan2".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
double doubleValue0 = _double(param0Value);
double doubleValue1 = _double(param1Value);
double result = Math.atan2(doubleValue0, doubleValue1);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("ceil".equalsIgnoreCase(x.getMethodName()) || "ceiling".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.ceil(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("cos".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.cos(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("sin".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.sin(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("log".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.log(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("log10".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.log10(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("tan".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.tan(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("sqrt".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 1) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object paramValue = param0.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return false;
}
double doubleValue = _double(paramValue);
int result = (int) Math.sqrt(doubleValue);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("power".equalsIgnoreCase(x.getMethodName())) {
if (x.getParameters().size() != 2) {
return false;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return false;
}
double doubleValue0 = _double(param0Value);
double doubleValue1 = _double(param1Value);
double result = Math.pow(doubleValue0, doubleValue1);
if (Double.isNaN(result)) {
x.putAttribute(EVAL_VALUE, null);
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("pi".equalsIgnoreCase(x.getMethodName())) {
x.putAttribute(EVAL_VALUE, Math.PI);
} else if ("rand".equalsIgnoreCase(x.getMethodName())) {
x.putAttribute(EVAL_VALUE, Math.random());
}
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLCharExpr x) {
x.putAttribute(EVAL_VALUE, x.getText());
return true;
}
public static boolean visit(SQLEvalVisitor visitor, SQLBetweenExpr x) {
x.getTestExpr().accept(visitor);
if (!x.getTestExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object value = x.getTestExpr().getAttribute(EVAL_VALUE);
x.getBeginExpr().accept(visitor);
if (!x.getBeginExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object begin = x.getBeginExpr().getAttribute(EVAL_VALUE);
if (lt(value, begin)) {
x.getAttributes().put(EVAL_VALUE, x.isNot() ? true : false);
return false;
}
x.getEndExpr().accept(visitor);
if (!x.getEndExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object end = x.getEndExpr().getAttribute(EVAL_VALUE);
if (gt(value, end)) {
x.getAttributes().put(EVAL_VALUE, x.isNot() ? true : false);
return false;
}
x.getAttributes().put(EVAL_VALUE, x.isNot() ? false : true);
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLNullExpr x) {
x.getAttributes().put(EVAL_VALUE, null);
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLCaseExpr x) {
Object value;
if (x.getValueExpr() != null) {
x.getValueExpr().accept(visitor);
if (!x.getValueExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
value = x.getValueExpr().getAttribute(EVAL_VALUE);
} else {
value = null;
}
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, SQLInListExpr x) {
SQLExpr valueExpr = x.getExpr();
valueExpr.accept(visitor);
if (!valueExpr.getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object value = valueExpr.getAttribute(EVAL_VALUE);
for (SQLExpr item : x.getTargetList()) {
item.accept(visitor);
if (!item.getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object itemValue = item.getAttribute(EVAL_VALUE);
if (eq(value, itemValue)) {
x.getAttributes().put(EVAL_VALUE, x.isNot() ? false : true);
return false;
}
}
x.getAttributes().put(EVAL_VALUE, x.isNot() ? true : false);
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLQueryExpr x) {
if (x.getSubQuery().getQuery() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getSubQuery().getQuery();
boolean nullFrom = false;
if (queryBlock.getFrom() == null) {
nullFrom = true;
} else if (queryBlock.getFrom() instanceof SQLExprTableSource) {
SQLExpr expr = ((SQLExprTableSource) queryBlock.getFrom()).getExpr();
if (expr instanceof SQLIdentifierExpr) {
if ("dual".equalsIgnoreCase(((SQLIdentifierExpr) expr).getName())) {
nullFrom = true;
}
}
}
if (nullFrom) {
List<Object> row = new ArrayList<Object>(queryBlock.getSelectList().size());
for (int i = 0; i < queryBlock.getSelectList().size(); ++i) {
SQLSelectItem item = queryBlock.getSelectList().get(i);
item.getExpr().accept(visitor);
Object cell = item.getExpr().getAttribute(EVAL_VALUE);
row.add(cell);
}
List<List<Object>> rows = new ArrayList<List<Object>>(1);
rows.add(row);
Object result = rows;
queryBlock.putAttribute(EVAL_VALUE, result);
x.getSubQuery().putAttribute(EVAL_VALUE, result);
x.putAttribute(EVAL_VALUE, result);
return false;
}
}
return false;
}
public static boolean visit(SQLEvalVisitor visitor, SQLBinaryOpExpr x) {
SQLExpr left = x.getLeft();
SQLExpr right = x.getRight();
left.accept(visitor);
if (!left.getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
right.accept(visitor);
if (!right.getAttributes().containsKey(EVAL_VALUE)) {
return false;
}
Object value = null;
switch (x.getOperator()) {
case Add:
value = add(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Subtract:
value = sub(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Multiply:
value = multi(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Divide:
value = div(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThan:
value = gt(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThanOrEqual:
value = gteq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case LessThan:
value = lt(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case LessThanOrEqual:
value = lteq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case Is:
value = eq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case IsNot:
value = !eq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
x.putAttribute(EVAL_VALUE, value);
break;
case RegExp:
case RLike: {
String pattern = _string(right.getAttributes().get(EVAL_VALUE));
String input = _string(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = Pattern.matches(pattern, input);
x.putAttribute(EVAL_VALUE, matchResult);
}
break;
case NotRegExp:
case NotRLike: {
String pattern = _string(right.getAttributes().get(EVAL_VALUE));
String input = _string(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = !Pattern.matches(pattern, input);
x.putAttribute(EVAL_VALUE, matchResult);
}
break;
default:
break;
}
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;
}
Map<String, Object> attributes = x.getAttributes();
int varIndex = x.getIndex();
if (varIndex != -1 && visitor.getParameters().size() > varIndex) {
boolean containsValue = attributes.containsKey(EVAL_VALUE);
if (!containsValue) {
Object value = visitor.getParameters().get(varIndex);
attributes.put(EVAL_VALUE, value);
}
}
return false;
}
public static Boolean _bool(Object val) {
if (val == null) {
return null;
}
if (val instanceof Boolean) {
return (Boolean) val;
}
if (val instanceof Number) {
return ((Number) val).intValue() == 1;
}
throw new IllegalArgumentException();
}
public static String _string(Object val) {
Object value = val;
if (value == null) {
return null;
}
return value.toString();
}
public static Byte _byte(Object val) {
if (val == null) {
return null;
}
if (val instanceof Byte) {
return (Byte) val;
}
return ((Number) val).byteValue();
}
public static Short _short(Object val) {
if (val == null) {
return null;
}
if (val instanceof Short) {
return (Short) val;
}
return ((Number) val).shortValue();
}
public static Integer _int(Object val) {
if (val == null) {
return null;
}
if (val instanceof Integer) {
return (Integer) val;
}
return ((Number) val).intValue();
}
public static Long _long(Object val) {
if (val == null) {
return null;
}
if (val instanceof Long) {
return (Long) val;
}
return ((Number) val).longValue();
}
public static Float _float(Object val) {
if (val == null) {
return null;
}
if (val instanceof Float) {
return (Float) val;
}
return ((Number) val).floatValue();
}
public static Double _double(Object val) {
if (val == null) {
return null;
}
if (val instanceof Double) {
return (Double) val;
}
return ((Number) val).doubleValue();
}
public static BigInteger _bigInt(Object val) {
if (val == null) {
return null;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
if (val instanceof String) {
return new BigInteger((String) val);
}
return BigInteger.valueOf(((Number) val).longValue());
}
public static Date _date(Object val) {
if (val == null) {
return null;
}
if (val instanceof Date) {
return (Date) val;
}
if (val instanceof Number) {
return new Date(((Number) val).longValue());
}
if (val instanceof String) {
return _date((String) val);
}
throw new DruidRuntimeException("can cast to date");
}
public static Date _date(String text) {
if (text == null || text.length() == 0) {
return null;
}
String format;
if (text.length() == "yyyy-MM-dd".length()) {
format = "yyyy-MM-dd";
} else {
format = "yyyy-MM-dd HH:mm:ss";
}
try {
return new SimpleDateFormat(format).parse(text);
} catch (ParseException e) {
throw new DruidRuntimeException("format : " + format + ", value : " + text, e);
}
}
public static BigDecimal _decimal(Object val) {
if (val == null) {
return null;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
if (val instanceof String) {
return new BigDecimal((String) val);
}
if (val instanceof Float) {
return new BigDecimal((Float) val);
}
if (val instanceof Double) {
return new BigDecimal((Double) val);
}
return BigDecimal.valueOf(((Number) val).longValue());
}
public static Object _sum(Object a, Object b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).add(_decimal(b));
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).add(_bigInt(b));
}
if (a instanceof Long || b instanceof Long) {
return _long(a) + _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) + _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) + _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) + _byte(b);
}
throw new IllegalArgumentException();
}
public static Object div(Object a, Object b) {
if (a == null || b == null) {
return null;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).divide(_decimal(b));
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).divide(_bigInt(b));
}
if (a instanceof Long || b instanceof Long) {
return _long(a) / _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) / _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) / _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) / _byte(b);
}
throw new IllegalArgumentException();
}
public static boolean gt(Object a, Object b) {
if (a == null) {
return false;
}
if (b == null) {
return true;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).compareTo(_decimal(b)) > 0;
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).compareTo(_bigInt(b)) > 0;
}
if (a instanceof Long || b instanceof Long) {
return _long(a) > _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) > _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) > _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) > _byte(b);
}
if (a instanceof Date || b instanceof Date) {
Date d1 = _date(a);
Date d2 = _date(b);
if (d1 == d2) {
return false;
}
if (d1 == null) {
return false;
}
if (d2 == null) {
return true;
}
return d1.compareTo(d2) > 0;
}
throw new IllegalArgumentException();
}
public static boolean gteq(Object a, Object b) {
if (eq(a, b)) {
return true;
}
return gt(a, b);
}
public static boolean lt(Object a, Object b) {
if (a == null) {
return true;
}
if (b == null) {
return false;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).compareTo(_decimal(b)) < 0;
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).compareTo(_bigInt(b)) < 0;
}
if (a instanceof Long || b instanceof Long) {
return _long(a) < _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) < _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) < _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) < _byte(b);
}
if (a instanceof Date || b instanceof Date) {
Date d1 = _date(a);
Date d2 = _date(b);
if (d1 == d2) {
return false;
}
if (d1 == null) {
return true;
}
if (d2 == null) {
return false;
}
return d1.compareTo(d2) < 0;
}
throw new IllegalArgumentException();
}
public static boolean lteq(Object a, Object b) {
if (eq(a, b)) {
return true;
}
return lt(a, b);
}
public static boolean eq(Object a, Object b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a.equals(b)) {
return true;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).compareTo(_decimal(b)) == 0;
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).compareTo(_bigInt(b)) == 0;
}
if (a instanceof Long || b instanceof Long) {
return _long(a) == _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) == _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) == _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) == _byte(b);
}
if (a instanceof Date || b instanceof Date) {
Date d1 = _date(a);
Date d2 = _date(b);
if (d1 == d2) {
return true;
}
if (d1 == null || d2 == null) {
return false;
}
return d1.equals(d2);
}
if (a instanceof String || b instanceof String) {
return _string(a).equals(_string(b));
}
throw new IllegalArgumentException();
}
public static Object add(Object a, Object b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).add(_decimal(b));
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).add(_bigInt(b));
}
if (a instanceof Double || b instanceof Double) {
return _double(a) + _double(b);
}
if (a instanceof Float || b instanceof Float) {
return _float(a) + _float(b);
}
if (a instanceof Long || b instanceof Long) {
return _long(a) + _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) + _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) + _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) + _byte(b);
}
if (a instanceof String || b instanceof String) {
return _string(a) + _string(b);
}
throw new IllegalArgumentException();
}
public static Object sub(Object a, Object b) {
if (a == null) {
return null;
}
if (b == null) {
return a;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).subtract(_decimal(b));
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).subtract(_bigInt(b));
}
if (a instanceof Double || b instanceof Double) {
return _double(a) - _double(b);
}
if (a instanceof Float || b instanceof Float) {
return _float(a) - _float(b);
}
if (a instanceof Long || b instanceof Long) {
return _long(a) - _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) - _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) - _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) - _byte(b);
}
throw new IllegalArgumentException();
}
public static Object multi(Object a, Object b) {
if (a == null || b == null) {
return null;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return _decimal(a).multiply(_decimal(b));
}
if (a instanceof BigInteger || b instanceof BigInteger) {
return _bigInt(a).multiply(_bigInt(b));
}
if (a instanceof Long || b instanceof Long) {
return _long(a) * _long(b);
}
if (a instanceof Integer || b instanceof Integer) {
return _int(a) * _int(b);
}
if (a instanceof Short || b instanceof Short) {
return _short(a) * _short(b);
}
if (a instanceof Byte || b instanceof Byte) {
return _byte(a) * _byte(b);
}
throw new IllegalArgumentException();
}
}