/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.wasp.util;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.wasp.plan.parser.Condition;
import com.alibaba.wasp.plan.parser.UnsupportedException;
import org.apache.hadoop.hbase.filter.CompareFilter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.alibaba.druid.sql.ast.expr.SQLBinaryOperator.Equality;
/**
* SQL Parser Utils.
*/
public class ParserUtils {
/**
* Parse The WHERE Clause into <name, value> pairs. For int, long, float type,
* it is can be range. Others should be equality.
*/
public static void parse(SQLExpr where,
LinkedHashMap<String, Condition> conditions, LinkedHashMap<String, Condition> ranges)
throws UnsupportedException {
if (where instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) where;
SQLBinaryOperator operator = binaryOpExpr.getOperator();
if (operator == Equality) {// one pair
SQLIdentifierExpr left = (SQLIdentifierExpr) binaryOpExpr.getLeft();
Condition value = new Condition(left.getName(),
Condition.ConditionType.EQUAL, binaryOpExpr.getRight());
conditions.put(value.getFieldName(), value);
} else if (operator == SQLBinaryOperator.BooleanAnd) {// multi pair
SQLExpr left = binaryOpExpr.getLeft();
SQLExpr right = binaryOpExpr.getRight();
parse(left, conditions, ranges);
parse(right, conditions, ranges);
} else if (operator == SQLBinaryOperator.GreaterThan
|| operator == SQLBinaryOperator.GreaterThanOrEqual
|| operator == SQLBinaryOperator.LessThan
|| operator == SQLBinaryOperator.LessThanOrEqual) {
SQLIdentifierExpr left = (SQLIdentifierExpr) binaryOpExpr.getLeft();
String fieldName = left.getName();
Condition value = getCondition(fieldName, ranges);
if (value == null) {
value = new Condition(left.getName(), Condition.ConditionType.RANGE,
binaryOpExpr.getRight(), operator);
ranges.put(value.getFieldName(), value);
} else {
value.resetValue(binaryOpExpr.getRight(), operator);
}
} else {
throw new UnsupportedException("where clause '" + where + " has '"
+ operator + "' , current this is Unsupported");
}
} else {
throw new UnsupportedException("where clause '" + where + "' Unsupported");
}
}
public static Condition getCondition(String fieldName,
Map<String, Condition> conditions) throws UnsupportedException {
if (conditions == null || conditions.size() == 0) {
return null;
}
return conditions.get(fieldName);
}
public static Condition getCondition(String fieldName,
List<Condition> conditions) throws UnsupportedException {
if (conditions == null || conditions.size() == 0) {
return null;
}
for (Condition condition : conditions) {
if (condition.getFieldName().equals(fieldName)) {
return condition;
}
}
return null;
}
public interface OperatorOpValue {
public static int EQUAL = 1;
public static int GREATER = 2;
public static int GREATER_OR_EQUAL = 3;
public static int LESS = 4;
public static int LESS_OR_EQUAL = 5;
public static int NO_OP = -1;
}
public static int parseSQLBinaryOperatorToIntValue(SQLBinaryOperator operator){
switch (operator) {
case Equality : return OperatorOpValue.EQUAL;
case GreaterThan : return OperatorOpValue.GREATER;
case GreaterThanOrEqual : return OperatorOpValue.GREATER_OR_EQUAL;
case LessThan : return OperatorOpValue.LESS;
case LessThanOrEqual : return OperatorOpValue.LESS_OR_EQUAL;
}
return OperatorOpValue.NO_OP;
}
public static CompareFilter.CompareOp convertIntValueToCompareOp(int value) {
switch (value) {
case OperatorOpValue.EQUAL:
return CompareFilter.CompareOp.EQUAL;
case OperatorOpValue.GREATER:
return CompareFilter.CompareOp.GREATER;
case OperatorOpValue.GREATER_OR_EQUAL:
return CompareFilter.CompareOp.GREATER_OR_EQUAL;
case OperatorOpValue.LESS:
return CompareFilter.CompareOp.LESS;
case OperatorOpValue.LESS_OR_EQUAL:
return CompareFilter.CompareOp.LESS_OR_EQUAL;
case OperatorOpValue.NO_OP:
return CompareFilter.CompareOp.NO_OP;
default:
return CompareFilter.CompareOp.NO_OP;
}
}
/**
* List condition column name.
*
* @param conditions
* @return
*/
public static Set<String> getColumns(
LinkedHashMap<String, Condition> conditions) {
return conditions.keySet();
}
}