| /* |
| * 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 org.apache.drill.exec.expr; |
| |
| import com.google.common.collect.Lists; |
| import org.apache.drill.common.expression.BooleanOperator; |
| import org.apache.drill.common.expression.CastExpression; |
| import org.apache.drill.common.expression.ConvertExpression; |
| import org.apache.drill.common.expression.FunctionCall; |
| import org.apache.drill.common.expression.FunctionHolderExpression; |
| import org.apache.drill.common.expression.IfExpression; |
| import org.apache.drill.common.expression.LogicalExpression; |
| import org.apache.drill.common.expression.NullExpression; |
| import org.apache.drill.common.expression.SchemaPath; |
| import org.apache.drill.common.expression.TypedNullConstant; |
| import org.apache.drill.common.expression.ValueExpressions.BooleanExpression; |
| import org.apache.drill.common.expression.ValueExpressions.DateExpression; |
| import org.apache.drill.common.expression.ValueExpressions.Decimal18Expression; |
| import org.apache.drill.common.expression.ValueExpressions.Decimal28Expression; |
| import org.apache.drill.common.expression.ValueExpressions.Decimal38Expression; |
| import org.apache.drill.common.expression.ValueExpressions.Decimal9Expression; |
| import org.apache.drill.common.expression.ValueExpressions.DoubleExpression; |
| import org.apache.drill.common.expression.ValueExpressions.FloatExpression; |
| import org.apache.drill.common.expression.ValueExpressions.IntExpression; |
| import org.apache.drill.common.expression.ValueExpressions.IntervalDayExpression; |
| import org.apache.drill.common.expression.ValueExpressions.IntervalYearExpression; |
| import org.apache.drill.common.expression.ValueExpressions.LongExpression; |
| import org.apache.drill.common.expression.ValueExpressions.QuotedString; |
| import org.apache.drill.common.expression.ValueExpressions.TimeExpression; |
| import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression; |
| import org.apache.drill.common.expression.ValueExpressions.VarDecimalExpression; |
| import org.apache.drill.common.expression.visitors.AbstractExprVisitor; |
| |
| import java.util.List; |
| |
| class EqualityVisitor extends AbstractExprVisitor<Boolean,LogicalExpression,RuntimeException> { |
| |
| @Override |
| public Boolean visitFunctionCall(FunctionCall call, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof FunctionCall)) { |
| return false; |
| } |
| if (!checkType(call, value)) { |
| return false; |
| } |
| if (!call.getName().equals(((FunctionCall) value).getName())) { |
| return false; |
| } |
| return checkChildren(call, value); |
| } |
| |
| @Override |
| public Boolean visitFunctionHolderExpression(FunctionHolderExpression holder, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof FunctionHolderExpression)) { |
| return false; |
| } |
| if (!checkType(holder, value)) { |
| return false; |
| } |
| if (!holder.getName().equals(((FunctionHolderExpression) value).getName())) { |
| return false; |
| } |
| if (holder.isRandom()) { |
| return false; |
| } |
| return checkChildren(holder, value); |
| } |
| |
| @Override |
| public Boolean visitIfExpression(IfExpression ifExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof IfExpression)) { |
| return false; |
| } |
| return checkChildren(ifExpr, value); |
| } |
| |
| @Override |
| public Boolean visitBooleanOperator(BooleanOperator call, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof BooleanOperator)) { |
| return false; |
| } |
| if (!call.getName().equals(((BooleanOperator) value).getName())) { |
| return false; |
| } |
| return checkChildren(call, value); |
| } |
| |
| @Override |
| public Boolean visitSchemaPath(SchemaPath path, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof SchemaPath)) { |
| return false; |
| } |
| return path.equals(value); |
| } |
| |
| @Override |
| public Boolean visitIntConstant(IntExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof IntExpression)) { |
| return false; |
| } |
| return intExpr.getInt() == ((IntExpression) value).getInt(); |
| } |
| |
| @Override |
| public Boolean visitFloatConstant(FloatExpression fExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof FloatExpression)) { |
| return false; |
| } |
| return fExpr.getFloat() == ((FloatExpression) value).getFloat(); |
| } |
| |
| @Override |
| public Boolean visitLongConstant(LongExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof LongExpression)) { |
| return false; |
| } |
| return intExpr.getLong() == ((LongExpression) value).getLong(); |
| } |
| |
| @Override |
| public Boolean visitDateConstant(DateExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof DateExpression)) { |
| return false; |
| } |
| return intExpr.getDate() == ((DateExpression) value).getDate(); |
| } |
| |
| @Override |
| public Boolean visitTimeConstant(TimeExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof TimeExpression)) { |
| return false; |
| } |
| return intExpr.getTime() == ((TimeExpression) value).getTime(); |
| } |
| |
| @Override |
| public Boolean visitTimeStampConstant(TimeStampExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof TimeStampExpression)) { |
| return false; |
| } |
| return intExpr.getTimeStamp() == ((TimeStampExpression) value).getTimeStamp(); |
| } |
| |
| @Override |
| public Boolean visitIntervalYearConstant(IntervalYearExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof IntervalYearExpression)) { |
| return false; |
| } |
| return intExpr.getIntervalYear() == ((IntervalYearExpression) value).getIntervalYear(); |
| } |
| |
| @Override |
| public Boolean visitIntervalDayConstant(IntervalDayExpression intExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof IntervalDayExpression)) { |
| return false; |
| } |
| return intExpr.getIntervalDay() == ((IntervalDayExpression) value).getIntervalDay() |
| && intExpr.getIntervalMillis() == ((IntervalDayExpression) value).getIntervalMillis(); |
| } |
| |
| @Override |
| public Boolean visitDecimal9Constant(Decimal9Expression decExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof Decimal9Expression)) { |
| return false; |
| } |
| if (decExpr.getIntFromDecimal() != ((Decimal9Expression) value).getIntFromDecimal()) { |
| return false; |
| } |
| if (decExpr.getScale() != ((Decimal9Expression) value).getScale()) { |
| return false; |
| } |
| if (decExpr.getPrecision() != ((Decimal9Expression) value).getPrecision()) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public Boolean visitDecimal18Constant(Decimal18Expression decExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof Decimal18Expression)) { |
| return false; |
| } |
| if (decExpr.getLongFromDecimal() != ((Decimal18Expression) value).getLongFromDecimal()) { |
| return false; |
| } |
| if (decExpr.getScale() != ((Decimal18Expression) value).getScale()) { |
| return false; |
| } |
| if (decExpr.getPrecision() != ((Decimal18Expression) value).getPrecision()) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public Boolean visitDecimal28Constant(Decimal28Expression decExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof Decimal28Expression)) { |
| return false; |
| } |
| if (decExpr.getBigDecimal() != ((Decimal28Expression) value).getBigDecimal()) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public Boolean visitDecimal38Constant(Decimal38Expression decExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof Decimal38Expression)) { |
| return false; |
| } |
| if (decExpr.getBigDecimal() != ((Decimal38Expression) value).getBigDecimal()) { |
| return false; |
| } |
| if (!decExpr.getMajorType().equals(((Decimal38Expression) value).getMajorType())) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public Boolean visitVarDecimalConstant(VarDecimalExpression decExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof VarDecimalExpression)) { |
| return false; |
| } |
| if (!decExpr.getMajorType().equals(value.getMajorType())) { |
| return false; |
| } |
| if (!decExpr.getBigDecimal().equals(((VarDecimalExpression) value).getBigDecimal())) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public Boolean visitDoubleConstant(DoubleExpression dExpr, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof DoubleExpression)) { |
| return false; |
| } |
| return dExpr.getDouble() == ((DoubleExpression) value).getDouble(); |
| } |
| |
| @Override |
| public Boolean visitBooleanConstant(BooleanExpression e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof BooleanExpression)) { |
| return false; |
| } |
| return e.getBoolean() == ((BooleanExpression) value).getBoolean(); |
| } |
| |
| @Override |
| public Boolean visitQuotedStringConstant(QuotedString e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof QuotedString)) { |
| return false; |
| } |
| return e.getString().equals(((QuotedString) value).getString()); |
| } |
| |
| @Override |
| public Boolean visitNullExpression(NullExpression e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof NullExpression)) { |
| return false; |
| } |
| return e.getMajorType().equals(value.getMajorType()); |
| } |
| |
| @Override |
| public Boolean visitCastExpression(CastExpression e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof CastExpression)) { |
| return false; |
| } |
| if (!e.getMajorType().equals(value.getMajorType())) { |
| return false; |
| } |
| return checkChildren(e, value); |
| } |
| |
| @Override |
| public Boolean visitConvertExpression(ConvertExpression e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof ConvertExpression)) { |
| return false; |
| } |
| if (!e.getConvertFunction().equals(((ConvertExpression) value).getConvertFunction())) { |
| return false; |
| } |
| return checkChildren(e, value); |
| } |
| |
| @Override |
| public Boolean visitNullConstant(TypedNullConstant e, LogicalExpression value) throws RuntimeException { |
| if (!(value instanceof TypedNullConstant)) { |
| return false; |
| } |
| return value.getMajorType().equals(e.getMajorType()); |
| } |
| |
| @Override |
| public Boolean visitUnknown(LogicalExpression e, LogicalExpression value) throws RuntimeException { |
| if (e instanceof ValueVectorReadExpression && value instanceof ValueVectorReadExpression) { |
| return visitValueVectorReadExpression((ValueVectorReadExpression) e, (ValueVectorReadExpression) value); |
| } |
| return false; |
| } |
| |
| private Boolean visitValueVectorReadExpression(ValueVectorReadExpression e, ValueVectorReadExpression value) { |
| return e.getTypedFieldId().equals(value.getTypedFieldId()); |
| } |
| |
| |
| private boolean checkChildren(LogicalExpression thisExpr, LogicalExpression thatExpr) { |
| List<LogicalExpression> theseChildren = Lists.newArrayList(thisExpr); |
| List<LogicalExpression> thoseChildren = Lists.newArrayList(thatExpr); |
| |
| if (theseChildren.size() != thoseChildren.size()) { |
| return false; |
| } |
| for (int i = 0; i < theseChildren.size(); i++) { |
| if (!theseChildren.get(i).accept(this, thoseChildren.get(i))) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private boolean checkType(LogicalExpression e1, LogicalExpression e2) { |
| return e1.getMajorType().equals(e2.getMajorType()); |
| } |
| } |