package org.wonderdb.query.plan; /******************************************************************************* * Copyright 2013 Vilas Athavale * * 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. *******************************************************************************/ import java.util.List; import org.wonderdb.expression.BasicExpression; import org.wonderdb.expression.Expression; import org.wonderdb.expression.Operand; import org.wonderdb.expression.VariableOperand; import org.wonderdb.query.parse.CollectionAlias; import org.wonderdb.query.parse.StaticOperand; import org.wonderdb.types.DBType; import org.wonderdb.types.StringLikeType; import org.wonderdb.types.StringType; import org.wonderdb.types.record.TableRecord; public class ExpressionEvaluator { private static ExpressionEvaluator instance = new ExpressionEvaluator(); private ExpressionEvaluator() { } public static ExpressionEvaluator getInstance() { return instance; } public int compareTo(List<BasicExpression> expList, DataContext dataContext, CollectionAlias ca) { int c = -1; for (int i = 0; i < expList.size(); i++) { BasicExpression exp = (BasicExpression) expList.get(i); Operand left = exp.getLeftOperand(); Operand right = exp.getRightOperand(); DBType leftVal = null; DBType rightVal = null; boolean invert = false; if (left instanceof VariableOperand) { VariableOperand vo = (VariableOperand) left; leftVal = dataContext.getValue(vo.getCollectionAlias(), vo.getColumnId(), vo.getPath()); } else { invert = true; leftVal = ((StaticOperand) left).getValue((TableRecord) null, null); } if (right instanceof VariableOperand) { VariableOperand vo = (VariableOperand) right; rightVal = dataContext.getValue(vo.getCollectionAlias(), vo.getColumnId(), vo.getPath()); invert = true; } else { invert = false; rightVal = ((StaticOperand) right).getValue((TableRecord) null, null); } int op = exp.getOperator(); op = mapOp(invert, op); if (invert) { c = evaluate(rightVal, leftVal, op); } else { c = evaluate(leftVal, rightVal, op); } // if (invert) { // c = c*-1; // } if (c != 0) { break; } } return c; } private int mapOp(boolean invert, int op) { switch (op) { case Expression.EQ: return Expression.GE; case Expression.GE: if (!invert) { return Expression.GE; } return Expression.LE; case Expression.LE: if (!invert) { return Expression.LE; } return Expression.GE; case Expression.LT: if (!invert) { return Expression.LT; } return Expression.GT; } return op; } public int evaluate(DBType left, DBType right, int op) { switch (op) { case Expression.EQ: return evaluateEQOrLike(left, right); case Expression.LIKE: if (right instanceof StringType) { right = new StringLikeType(((StringType) right).get()); } return evaluateEQOrLike(left, right); case Expression.GE: return evaluateGE(left, right); case Expression.GT: return evaluateGT(left, right); case Expression.LE: return evaluateLE(left, right); case Expression.LT: return evaluateLT(left, right); } return -1; } private int evaluateEQOrLike(DBType left, DBType right) { if (left == null && right == null) { return 0; } if (left == null) { return -1; } int c = left.compareTo(right); return c <= 0 ? 1 : -1; } private int evaluateGE(DBType left, DBType right) { if (left == null) { if (right == null) { return 0; } else { return -1; } } int c = left.compareTo(right); return c >= 0 ? 1 : -1; } private int evaluateGT(DBType left, DBType right) { if (left == null) { return -1; } int c = left.compareTo(right); return c > 0 ? 1 : -1; } private int evaluateLE(DBType left, DBType right) { if (left == null) { return 0; } return 1; // int c = left.compareTo(right); // return c < 0 ? -1 : 1; } private int evaluateLT(DBType left, DBType right) { if (left == null) { return 0; } return 1; // int c = left.compareTo(right); // return c < 0 ? 1 : -1; } }