drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jacq...@apache.org
Subject [34/45] drill git commit: DRILL-3987: (MOVE) Move logical expressions and operators out of common. Move to new drill-logical model.
Date Fri, 13 Nov 2015 02:38:04 GMT
http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java b/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
new file mode 100644
index 0000000..2fd8e67
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
@@ -0,0 +1,664 @@
+/**
+ * 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.common.expression;
+
+import java.math.BigDecimal;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+
+import org.apache.drill.common.expression.visitors.ExprVisitor;
+import org.apache.drill.common.types.TypeProtos.DataMode;
+import org.apache.drill.common.types.TypeProtos.MajorType;
+import org.apache.drill.common.types.TypeProtos.MinorType;
+import org.apache.drill.common.types.Types;
+import org.apache.drill.common.util.CoreDecimalUtility;
+
+import com.google.common.collect.Iterators;
+
+public class ValueExpressions {
+
+  public static LogicalExpression getBigInt(long l){
+    return new LongExpression(l);
+  }
+
+  public static LogicalExpression getInt(int i){
+    return new IntExpression(i, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getFloat8(double d){
+    return new DoubleExpression(d, ExpressionPosition.UNKNOWN);
+  }
+  public static LogicalExpression getFloat4(float f){
+    return new FloatExpression(f, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getBit(boolean b){
+    return new BooleanExpression(Boolean.toString(b), ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getChar(String s){
+    return new QuotedString(s, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getDate(GregorianCalendar date) {
+    return new org.apache.drill.common.expression.ValueExpressions.DateExpression(date.getTimeInMillis());
+  }
+
+  public static LogicalExpression getTime(GregorianCalendar time) {
+      int millis = time.get(GregorianCalendar.HOUR_OF_DAY) * 60 * 60 * 1000 +
+                   time.get(GregorianCalendar.MINUTE) * 60 * 1000 +
+                   time.get(GregorianCalendar.SECOND) * 1000 +
+                   time.get(GregorianCalendar.MILLISECOND);
+
+      return new TimeExpression(millis);
+  }
+
+  public static LogicalExpression getTimeStamp(GregorianCalendar date) {
+    return new org.apache.drill.common.expression.ValueExpressions.TimeStampExpression(date.getTimeInMillis());
+  }
+  public static LogicalExpression getIntervalYear(int months) {
+    return new IntervalYearExpression(months);
+  }
+
+  public static LogicalExpression getIntervalDay(long intervalInMillis) {
+      return new IntervalDayExpression(intervalInMillis);
+  }
+
+  public static LogicalExpression getDecimal9(BigDecimal i) {
+    return new Decimal9Expression(i, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getDecimal18(BigDecimal i) {
+    return new Decimal18Expression(i, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getDecimal28(BigDecimal i) {
+    return new Decimal28Expression(i, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getDecimal38(BigDecimal i) {
+      return new Decimal38Expression(i, ExpressionPosition.UNKNOWN);
+  }
+
+  public static LogicalExpression getNumericExpression(String sign, String s, ExpressionPosition ep) {
+    String numStr = (sign == null) ? s : sign+s;
+    try {
+        int a = Integer.parseInt(numStr);
+        return new IntExpression(a, ep);
+    } catch (Exception e) {
+
+    }
+    try {
+      long l = Long.parseLong(numStr);
+      return new LongExpression(l, ep);
+    } catch (Exception e) {
+
+    }
+
+    try {
+      double d = Double.parseDouble(numStr);
+      return new DoubleExpression(d, ep);
+    } catch (Exception e) {
+
+    }
+
+    throw new IllegalArgumentException(String.format("Unable to parse string %s as integer or floating point number.",
+        numStr));
+
+  }
+
+  protected static abstract class ValueExpression<V> extends LogicalExpressionBase {
+    public final V value;
+
+    protected ValueExpression(String value, ExpressionPosition pos) {
+      super(pos);
+      this.value = parseValue(value);
+    }
+
+    protected abstract V parseValue(String s);
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+  }
+
+  public static class BooleanExpression extends ValueExpression<Boolean> {
+
+
+    public BooleanExpression(String value, ExpressionPosition pos) {
+      super(value, pos);
+    }
+
+
+    @Override
+    protected Boolean parseValue(String s) {
+      return Boolean.parseBoolean(s);
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return Types.REQUIRED_BIT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitBooleanConstant(this, value);
+    }
+
+    public boolean getBoolean() {
+      return value;
+    }
+
+  }
+
+  public static class FloatExpression extends LogicalExpressionBase {
+    private float f;
+
+    private static final MajorType FLOAT_CONSTANT = Types.required(MinorType.FLOAT4);
+
+    public FloatExpression(float f, ExpressionPosition pos) {
+      super(pos);
+      this.f = f;
+    }
+
+    public float getFloat() {
+      return f;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return FLOAT_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitFloatConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class IntExpression extends LogicalExpressionBase {
+
+    private static final MajorType INT_CONSTANT = Types.required(MinorType.INT);
+
+    private int i;
+
+    public IntExpression(int i, ExpressionPosition pos) {
+      super(pos);
+      this.i = i;
+    }
+
+    public int getInt() {
+      return i;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return INT_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitIntConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class Decimal9Expression extends LogicalExpressionBase {
+
+    private int decimal;
+    private int scale;
+    private int precision;
+
+    public Decimal9Expression(BigDecimal input, ExpressionPosition pos) {
+      super(pos);
+      this.scale = input.scale();
+      this.precision = input.precision();
+      this.decimal = CoreDecimalUtility.getDecimal9FromBigDecimal(input, scale, precision);
+    }
+
+
+    public int getIntFromDecimal() {
+      return decimal;
+    }
+
+    public int getScale() {
+      return scale;
+    }
+
+    public int getPrecision() {
+      return precision;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return MajorType.newBuilder().setMinorType(MinorType.DECIMAL9).setScale(scale).setPrecision(precision).setMode(DataMode.REQUIRED).build();
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDecimal9Constant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+  }
+
+  public static class Decimal18Expression extends LogicalExpressionBase {
+
+    private long decimal;
+    private int scale;
+    private int precision;
+
+    public Decimal18Expression(BigDecimal input, ExpressionPosition pos) {
+      super(pos);
+      this.scale = input.scale();
+      this.precision = input.precision();
+      this.decimal = CoreDecimalUtility.getDecimal18FromBigDecimal(input, scale, precision);
+    }
+
+
+    public long getLongFromDecimal() {
+      return decimal;
+    }
+
+    public int getScale() {
+      return scale;
+    }
+
+    public int getPrecision() {
+      return precision;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return MajorType.newBuilder().setMinorType(MinorType.DECIMAL18).setScale(scale).setPrecision(precision).setMode(DataMode.REQUIRED).build();
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDecimal18Constant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class Decimal28Expression extends LogicalExpressionBase {
+
+    private BigDecimal bigDecimal;
+
+    public Decimal28Expression(BigDecimal input, ExpressionPosition pos) {
+      super(pos);
+      this.bigDecimal = input;
+    }
+
+
+    public BigDecimal getBigDecimal() {
+      return bigDecimal;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return MajorType.newBuilder().setMinorType(MinorType.DECIMAL28SPARSE).setScale(bigDecimal.scale()).setPrecision(bigDecimal.precision()).setMode(DataMode.REQUIRED).build();
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDecimal28Constant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class Decimal38Expression extends LogicalExpressionBase {
+
+    private BigDecimal bigDecimal;
+
+    public Decimal38Expression(BigDecimal input, ExpressionPosition pos) {
+      super(pos);
+      this.bigDecimal = input;
+    }
+
+    public BigDecimal getBigDecimal() {
+      return bigDecimal;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return MajorType.newBuilder().setMinorType(MinorType.DECIMAL38SPARSE).setScale(bigDecimal.scale()).setPrecision(bigDecimal.precision()).setMode(DataMode.REQUIRED).build();
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDecimal38Constant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+
+  public static class DoubleExpression extends LogicalExpressionBase {
+    private double d;
+
+    private static final MajorType DOUBLE_CONSTANT = Types.required(MinorType.FLOAT8);
+
+    public DoubleExpression(double d, ExpressionPosition pos) {
+      super(pos);
+      this.d = d;
+    }
+
+    public double getDouble() {
+      return d;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return DOUBLE_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDoubleConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class LongExpression extends LogicalExpressionBase {
+
+    private static final MajorType LONG_CONSTANT = Types.required(MinorType.BIGINT);
+
+    private long l;
+
+    public LongExpression(long l) {
+      this(l, ExpressionPosition.UNKNOWN);
+    }
+
+      public LongExpression(long l, ExpressionPosition pos) {
+      super(pos);
+      this.l = l;
+    }
+
+    public long getLong() {
+      return l;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return LONG_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitLongConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+
+  public static class DateExpression extends LogicalExpressionBase {
+
+    private static final MajorType DATE_CONSTANT = Types.required(MinorType.DATE);
+
+    private long dateInMillis;
+
+    public DateExpression(long l) {
+      this(l, ExpressionPosition.UNKNOWN);
+    }
+
+      public DateExpression(long dateInMillis, ExpressionPosition pos) {
+      super(pos);
+      this.dateInMillis = dateInMillis;
+    }
+
+    public long getDate() {
+      return dateInMillis;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return DATE_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitDateConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+
+  public static class TimeExpression extends LogicalExpressionBase {
+
+    private static final MajorType TIME_CONSTANT = Types.required(MinorType.TIME);
+
+    private int timeInMillis;
+
+    public TimeExpression(int timeInMillis) {
+      this(timeInMillis, ExpressionPosition.UNKNOWN);
+    }
+
+      public TimeExpression(int timeInMillis, ExpressionPosition pos) {
+      super(pos);
+      this.timeInMillis = timeInMillis;
+    }
+
+    public int getTime() {
+      return timeInMillis;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return TIME_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitTimeConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class TimeStampExpression extends LogicalExpressionBase {
+
+    private static final MajorType TIMESTAMP_CONSTANT = Types.required(MinorType.TIMESTAMP);
+
+    private long timeInMillis;
+
+    public TimeStampExpression(long timeInMillis) {
+      this(timeInMillis, ExpressionPosition.UNKNOWN);
+    }
+
+      public TimeStampExpression(long timeInMillis, ExpressionPosition pos) {
+      super(pos);
+      this.timeInMillis = timeInMillis;
+    }
+
+    public long getTimeStamp() {
+      return timeInMillis;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return TIMESTAMP_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitTimeStampConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class IntervalYearExpression extends LogicalExpressionBase {
+
+    private static final MajorType INTERVALYEAR_CONSTANT = Types.required(MinorType.INTERVALYEAR);
+
+    private int months;
+
+    public IntervalYearExpression(int months) {
+      this(months, ExpressionPosition.UNKNOWN);
+    }
+
+      public IntervalYearExpression(int months, ExpressionPosition pos) {
+      super(pos);
+      this.months = months;
+    }
+
+    public int getIntervalYear() {
+      return months;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return INTERVALYEAR_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitIntervalYearConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class IntervalDayExpression extends LogicalExpressionBase {
+
+    private static final MajorType INTERVALDAY_CONSTANT = Types.required(MinorType.INTERVALDAY);
+    private static final long MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
+
+    private int days;
+    private int millis;
+
+    public IntervalDayExpression(long intervalInMillis) {
+      this((int) (intervalInMillis / MILLIS_IN_DAY), (int) (intervalInMillis % MILLIS_IN_DAY), ExpressionPosition.UNKNOWN);
+    }
+
+      public IntervalDayExpression(int days, int millis, ExpressionPosition pos) {
+      super(pos);
+      this.days = days;
+      this.millis = millis;
+    }
+
+    public int getIntervalDay() {
+      return days;
+    }
+
+    public int getIntervalMillis() {
+        return millis;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return INTERVALDAY_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitIntervalDayConstant(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalExpression> iterator() {
+      return Iterators.emptyIterator();
+    }
+
+  }
+
+  public static class QuotedString extends ValueExpression<String> {
+
+    private static final MajorType QUOTED_STRING_CONSTANT = Types.required(MinorType.VARCHAR);
+
+    public QuotedString(String value, ExpressionPosition pos) {
+      super(value, pos);
+    }
+
+    public String getString() {
+      return value;
+    }
+
+    @Override
+    protected String parseValue(String s) {
+      return s;
+    }
+
+    @Override
+    public MajorType getMajorType() {
+      return QUOTED_STRING_CONSTANT;
+    }
+
+    @Override
+    public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+      return visitor.visitQuotedStringConstant(this, value);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java b/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java
new file mode 100644
index 0000000..34997ab
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java
@@ -0,0 +1,151 @@
+/**
+ * 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.common.expression.fn;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.common.types.TypeProtos.MinorType;
+
+public class CastFunctions {
+
+  private static Map<MinorType, String> TYPE2FUNC = new HashMap<>();
+  /** The cast functions that need to be replaced (if
+   * "drill.exec.functions.cast_empty_string_to_null" is set to true). */
+  private static Set<String> CAST_FUNC_REPLACEMENT_NEEDED = new HashSet<>();
+  /** Map from the replaced functions to the new ones (for non-nullable VARCHAR). */
+  private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE = new HashMap<>();
+  /** Map from the replaced functions to the new ones (for nullable VARCHAR). */
+  private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NULLABLE = new HashMap<>();
+
+  static {
+    TYPE2FUNC.put(MinorType.UNION, "castUNION");
+    TYPE2FUNC.put(MinorType.BIGINT, "castBIGINT");
+    TYPE2FUNC.put(MinorType.INT, "castINT");
+    TYPE2FUNC.put(MinorType.BIT, "castBIT");
+    TYPE2FUNC.put(MinorType.TINYINT, "castTINYINT");
+    TYPE2FUNC.put(MinorType.FLOAT4, "castFLOAT4");
+    TYPE2FUNC.put(MinorType.FLOAT8, "castFLOAT8");
+    TYPE2FUNC.put(MinorType.VARCHAR, "castVARCHAR");
+    TYPE2FUNC.put(MinorType.VAR16CHAR, "castVAR16CHAR");
+    TYPE2FUNC.put(MinorType.VARBINARY, "castVARBINARY");
+    TYPE2FUNC.put(MinorType.DATE, "castDATE");
+    TYPE2FUNC.put(MinorType.TIME, "castTIME");
+    TYPE2FUNC.put(MinorType.TIMESTAMP, "castTIMESTAMP");
+    TYPE2FUNC.put(MinorType.TIMESTAMPTZ, "castTIMESTAMPTZ");
+    TYPE2FUNC.put(MinorType.INTERVALDAY, "castINTERVALDAY");
+    TYPE2FUNC.put(MinorType.INTERVALYEAR, "castINTERVALYEAR");
+    TYPE2FUNC.put(MinorType.INTERVAL, "castINTERVAL");
+    TYPE2FUNC.put(MinorType.DECIMAL9, "castDECIMAL9");
+    TYPE2FUNC.put(MinorType.DECIMAL18, "castDECIMAL18");
+    TYPE2FUNC.put(MinorType.DECIMAL28SPARSE, "castDECIMAL28SPARSE");
+    TYPE2FUNC.put(MinorType.DECIMAL28DENSE, "castDECIMAL28DENSE");
+    TYPE2FUNC.put(MinorType.DECIMAL38SPARSE, "castDECIMAL38SPARSE");
+    TYPE2FUNC.put(MinorType.DECIMAL38DENSE, "castDECIMAL38DENSE");
+
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.INT));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.BIGINT));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.FLOAT4));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.FLOAT8));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL9));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL18));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE));
+    CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE));
+
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringVarCharToNullableINT");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringVarCharToNullableBIGINT");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringVarCharToNullableFLOAT4");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringVarCharToNullableFLOAT8");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringVarCharToNullableDECIMAL9");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringVarCharToNullableDECIMAL18");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringVarCharToNullableDECIMAL28SPARSE");
+    CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringVarCharToNullableDECIMAL38SPARSE");
+
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringNullableVarCharToNullableINT");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringNullableVarCharToNullableBIGINT");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringNullableVarCharToNullableFLOAT4");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringNullableVarCharToNullableFLOAT8");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringNullableVarCharToNullableDECIMAL9");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringNullableVarCharToNullableDECIMAL18");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL28SPARSE");
+    CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL38SPARSE");
+  }
+
+  /**
+  * Given the target type, get the appropriate cast function
+  * @param targetMinorType the target data type
+  * @return
+  */
+  public static String getCastFunc(MinorType targetMinorType) {
+    String func = TYPE2FUNC.get(targetMinorType);
+    if (func != null) {
+      return func;
+    }
+
+    throw new RuntimeException(
+      String.format("cast function for type %s is not defined", targetMinorType.name()));
+  }
+
+  /**
+  * Get a replacing cast function for the original function, based on the specified data mode
+  * @param originalCastFunction original cast function
+  * @param dataMode data mode of the input data
+  * @return
+  */
+  public static String getReplacingCastFunction(String originalCastFunction, org.apache.drill.common.types.TypeProtos.DataMode dataMode) {
+    if(dataMode == TypeProtos.DataMode.OPTIONAL) {
+      return getReplacingCastFunctionFromNullable(originalCastFunction);
+    }
+
+    if(dataMode == TypeProtos.DataMode.REQUIRED) {
+      return getReplacingCastFunctionFromNonNullable(originalCastFunction);
+    }
+
+    throw new RuntimeException(
+       String.format("replacing cast function for datatype %s is not defined", dataMode));
+  }
+
+  /**
+  * Check if a replacing cast function is available for the the original function
+  * @param originalfunction original cast function
+  * @return
+  */
+  public static boolean isReplacementNeeded(MinorType inputType, String originalfunction) {
+    return inputType == MinorType.VARCHAR && CAST_FUNC_REPLACEMENT_NEEDED.contains(originalfunction);
+  }
+
+  private static String getReplacingCastFunctionFromNonNullable(String originalCastFunction) {
+    if(CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.containsKey(originalCastFunction)) {
+      return CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.get(originalCastFunction);
+    }
+
+    throw new RuntimeException(
+      String.format("replacing cast function for %s is not defined", originalCastFunction));
+  }
+
+  private static String getReplacingCastFunctionFromNullable(String originalCastFunction) {
+    if(CAST_FUNC_REPLACEMENT_FROM_NULLABLE.containsKey(originalCastFunction)) {
+      return CAST_FUNC_REPLACEMENT_FROM_NULLABLE.get(originalCastFunction);
+    }
+
+    throw new RuntimeException(
+      String.format("replacing cast function for %s is not defined", originalCastFunction));
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/fn/FuncHolder.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/fn/FuncHolder.java b/logical/src/main/java/org/apache/drill/common/expression/fn/FuncHolder.java
new file mode 100644
index 0000000..a8824e0
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/fn/FuncHolder.java
@@ -0,0 +1,23 @@
+/**
+ * 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.common.expression.fn;
+
+/** This should be removed once common and exec/java-exec modules are merged (DRILL-507). */
+public interface FuncHolder {
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/fn/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/fn/package-info.java b/logical/src/main/java/org/apache/drill/common/expression/fn/package-info.java
new file mode 100644
index 0000000..6af3f5f
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/fn/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Logical function definitions.
+ */
+package org.apache.drill.common.expression.fn;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/package-info.java b/logical/src/main/java/org/apache/drill/common/expression/package-info.java
new file mode 100644
index 0000000..0c32bf6
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/package-info.java
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+/**
+ * Logical expression tree representation.
+ *
+ * Drill manages expressions provided in many different parts of SQL queries.
+ * This includes scalar expressions in select, filter and join conditions, as
+ * well as aggregate and window functions. These expressions are represented
+ * logically as ASTs during planning. The classes defined here provide the
+ * different nodes in the expression tree, as well as utilities for building
+ * and manipulating expressions during parsing and planning.
+ *
+ */
+package org.apache.drill.common.expression;

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/types/AtomType.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/types/AtomType.java b/logical/src/main/java/org/apache/drill/common/expression/types/AtomType.java
new file mode 100644
index 0000000..2918216
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/types/AtomType.java
@@ -0,0 +1,68 @@
+/**
+ * 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.common.expression.types;
+
+
+public class AtomType extends DataType {
+  private String name;
+  private Comparability comparability;
+  private boolean isNumericType;
+
+  public AtomType(String name, Comparability comparability, boolean isNumericType) {
+    super();
+    this.name = name;
+    this.comparability = comparability;
+    this.isNumericType = isNumericType;
+  }
+
+
+  @Override
+  public boolean isNumericType() {
+    return isNumericType;
+  }
+
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public boolean isLateBind() {
+    return false;
+  }
+
+  @Override
+  public boolean hasChildType() {
+    return false;
+  }
+
+  @Override
+  public DataType getChildType() {
+    return null;
+  }
+
+  @Override
+  public Comparability getComparability() {
+    return comparability;
+  }
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/types/DataType.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/types/DataType.java b/logical/src/main/java/org/apache/drill/common/expression/types/DataType.java
new file mode 100644
index 0000000..56102ee
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/types/DataType.java
@@ -0,0 +1,147 @@
+/**
+ * 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.common.expression.types;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+@JsonSerialize(using = DataType.Se.class)
+@JsonDeserialize(using = DataType.De.class)
+abstract class DataType {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DataType.class);
+
+  public static enum Comparability{
+    UNKNOWN, NONE, EQUAL, ORDERED;
+  }
+
+  public abstract String getName();
+  public abstract boolean isLateBind();
+  public abstract boolean hasChildType();
+  public abstract DataType getChildType();
+  public abstract Comparability getComparability();
+  public abstract boolean isNumericType();
+
+
+
+  public static final DataType LATEBIND = new LateBindType();
+  public static final DataType BOOLEAN = new AtomType("BOOLEAN", Comparability.EQUAL, false);
+  public static final DataType BYTES = new AtomType("BYTES", Comparability.ORDERED, false);
+  public static final DataType SIGNED_BYTE = new AtomType("SIGNED_BYTE", Comparability.ORDERED, true);
+  public static final DataType SIGNED_INT16 = new AtomType("SIGNED_INT16", Comparability.ORDERED, true);
+  public static final DataType NVARCHAR = new AtomType("VARCHAR", Comparability.ORDERED, false);
+  public static final DataType FLOAT32 = new AtomType("FLOAT32", Comparability.ORDERED, true);
+  public static final DataType FLOAT64 = new AtomType("FLOAT64", Comparability.ORDERED, true);
+  public static final DataType INT64 = new AtomType("INT64", Comparability.ORDERED, true);
+  public static final DataType INT32 = new AtomType("INT32", Comparability.ORDERED, true);
+  public static final DataType INT16 = new AtomType("INT16", Comparability.ORDERED, true);
+  public static final DataType UINT16 = new AtomType("UINT16", Comparability.ORDERED, true);
+//  public static final DataType INT16 = new AtomType("int16", Comparability.ORDERED, true);
+//  public static final DataType BIG_INTEGER = new AtomType("bigint", Comparability.ORDERED, true);
+//  public static final DataType BIG_DECIMAL = new AtomType("bigdecimal", Comparability.ORDERED, true);
+  public static final DataType DATE = new AtomType("DATE", Comparability.ORDERED, false);
+  public static final DataType DATETIME = new AtomType("DATETIME", Comparability.ORDERED, false);
+  public static final DataType MAP = new AtomType("MAP", Comparability.NONE, false);
+  public static final DataType ARRAY = new AtomType("ARRAY", Comparability.NONE, false);
+  public static final DataType NULL = new AtomType("NULL", Comparability.NONE, false);
+
+  //TODO: Hack to get some size data, needs to be fixed so that each type reveals it's size.
+  public int size() {
+    if(this == BOOLEAN) {
+      return 1;
+    }else if(this == INT32) {
+      return 4;
+    }else if(this == INT16) {
+      return 4;
+    }
+    return 2;
+  }
+
+  static final Map<String, DataType> TYPES;
+  static {
+    Field[] fields = DataType.class.getFields();
+    Map<String, DataType> types = new HashMap<String, DataType>();
+    for (Field f : fields) {
+      //logger.debug("Reviewing {}, Field: {}", f.getClass(), f);
+      if (Modifier.isStatic(f.getModifiers())) {
+        try {
+          Object o = f.get(null);
+          //logger.debug("Object {}", o);
+
+          if (o instanceof DataType) {
+            types.put(((DataType) o).getName(), (DataType) o);
+          }
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+          logger.warn("Failure while reading DataType.", e);
+        }
+      }
+    }
+    TYPES = Collections.unmodifiableMap(types);
+  }
+
+  public static DataType getDataType(String name) {
+    if (TYPES.containsKey(name)) {
+      return TYPES.get(name);
+    } else {
+      throw new IllegalArgumentException(String.format("Unknown type requested of [%s].", name));
+    }
+  }
+
+  public static class De extends StdDeserializer<DataType> {
+
+    public De() {
+      super(DataType.class);
+    }
+
+    @Override
+    public DataType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
+        JsonProcessingException {
+      return getDataType(this._parseString(jp, ctxt));
+    }
+
+  }
+
+  public static class Se extends StdSerializer<DataType> {
+
+    public Se() {
+      super(DataType.class);
+    }
+
+    @Override
+    public void serialize(DataType value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
+        JsonGenerationException {
+      jgen.writeString(value.getName());
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/types/DataTypeFactory.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/types/DataTypeFactory.java b/logical/src/main/java/org/apache/drill/common/expression/types/DataTypeFactory.java
new file mode 100644
index 0000000..c95bf1f
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/types/DataTypeFactory.java
@@ -0,0 +1,25 @@
+/**
+ * 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.common.expression.types;
+
+public abstract class DataTypeFactory {
+
+  public abstract DataType getArrayType(DataType containedType);
+  public abstract DataType getMapType(DataType keyType, DataType valueType);
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/types/LateBindType.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/types/LateBindType.java b/logical/src/main/java/org/apache/drill/common/expression/types/LateBindType.java
new file mode 100644
index 0000000..db0b09c
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/types/LateBindType.java
@@ -0,0 +1,53 @@
+/**
+ * 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.common.expression.types;
+
+class LateBindType extends DataType {
+
+  @Override
+  public String getName() {
+    return "LATE";
+  }
+
+  @Override
+  public boolean isLateBind() {
+    return true;
+  }
+
+  @Override
+  public boolean hasChildType() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public DataType getChildType() {
+    throw new UnsupportedOperationException();
+  }
+
+
+  @Override
+  public boolean isNumericType() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Comparability getComparability() {
+    return Comparability.UNKNOWN;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/types/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/types/package-info.java b/logical/src/main/java/org/apache/drill/common/expression/types/package-info.java
new file mode 100644
index 0000000..744b174
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/types/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Logical type definitions.
+ */
+package org.apache.drill.common.expression.types;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
new file mode 100644
index 0000000..a31e6e8
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
@@ -0,0 +1,176 @@
+/**
+ * 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.common.expression.visitors;
+
+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;
+
+public abstract class AbstractExprVisitor<T, VAL, EXCEP extends Exception> implements ExprVisitor<T, VAL, EXCEP> {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AbstractExprVisitor.class);
+
+  @Override
+  public T visitFunctionCall(FunctionCall call, VAL value) throws EXCEP {
+    return visitUnknown(call, value);
+  }
+
+  @Override
+  public T visitFunctionHolderExpression(FunctionHolderExpression holder, VAL value) throws EXCEP {
+    return visitUnknown(holder, value);
+  }
+
+  @Override
+  public T visitIfExpression(IfExpression ifExpr, VAL value) throws EXCEP {
+    return visitUnknown(ifExpr, value);
+  }
+
+  @Override
+  public T visitBooleanOperator(BooleanOperator op, VAL value) throws EXCEP {
+    return visitUnknown(op, value);
+  }
+
+  @Override
+  public T visitSchemaPath(SchemaPath path, VAL value) throws EXCEP {
+    return visitUnknown(path, value);
+  }
+
+  @Override
+  public T visitFloatConstant(FloatExpression fExpr, VAL value) throws EXCEP {
+    return visitUnknown(fExpr, value);
+  }
+
+  @Override
+  public T visitIntConstant(IntExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitLongConstant(LongExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+
+  @Override
+  public T visitDecimal9Constant(Decimal9Expression decExpr, VAL value) throws EXCEP {
+    return visitUnknown(decExpr, value);
+  }
+
+  @Override
+  public T visitDecimal18Constant(Decimal18Expression decExpr, VAL value) throws EXCEP {
+    return visitUnknown(decExpr, value);
+  }
+
+  @Override
+  public T visitDecimal28Constant(Decimal28Expression decExpr, VAL value) throws EXCEP {
+    return visitUnknown(decExpr, value);
+  }
+
+  @Override
+  public T visitDecimal38Constant(Decimal38Expression decExpr, VAL value) throws EXCEP {
+    return visitUnknown(decExpr, value);
+  }
+
+  @Override
+  public T visitDateConstant(DateExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitTimeConstant(TimeExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitTimeStampConstant(TimeStampExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitIntervalYearConstant(IntervalYearExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitIntervalDayConstant(IntervalDayExpression intExpr, VAL value) throws EXCEP {
+    return visitUnknown(intExpr, value);
+  }
+
+  @Override
+  public T visitDoubleConstant(DoubleExpression dExpr, VAL value) throws EXCEP {
+    return visitUnknown(dExpr, value);
+  }
+
+  @Override
+  public T visitBooleanConstant(BooleanExpression e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitQuotedStringConstant(QuotedString e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitCastExpression(CastExpression e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitConvertExpression(ConvertExpression e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitNullConstant(TypedNullConstant e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitNullExpression(NullExpression e, VAL value) throws EXCEP {
+    return visitUnknown(e, value);
+  }
+
+  @Override
+  public T visitUnknown(LogicalExpression e, VAL value) throws EXCEP {
+    throw new UnsupportedOperationException(String.format("Expression of type %s not handled by visitor type %s.", e.getClass().getCanonicalName(), this.getClass().getCanonicalName()));
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
new file mode 100644
index 0000000..46789e3
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
@@ -0,0 +1,206 @@
+/**
+ * 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.common.expression.visitors;
+
+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.ErrorCollector;
+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.IfExpression.IfCondition;
+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;
+
+public final class AggregateChecker implements ExprVisitor<Boolean, ErrorCollector, RuntimeException>{
+
+  public static final AggregateChecker INSTANCE = new AggregateChecker();
+
+  public static boolean isAggregating(LogicalExpression e, ErrorCollector errors) {
+    return e.accept(INSTANCE, errors);
+  }
+
+  @Override
+  public Boolean visitFunctionCall(FunctionCall call, ErrorCollector errors) {
+    throw new UnsupportedOperationException("FunctionCall is not expected here. "+
+      "It should have been converted to FunctionHolderExpression in materialization");
+  }
+
+  @Override
+  public Boolean visitFunctionHolderExpression(FunctionHolderExpression holder, ErrorCollector errors) {
+    if (holder.isAggregating()) {
+      for (int i = 0; i < holder.args.size(); i++) {
+        LogicalExpression e = holder.args.get(i);
+        if(e.accept(this, errors)) {
+          errors.addGeneralError(e.getPosition(),
+            String.format("Aggregating function call %s includes nested aggregations at arguments number %d. " +
+              "This isn't allowed.", holder.getName(), i));
+        }
+      }
+      return true;
+    } else {
+      for (LogicalExpression e : holder.args) {
+        if (e.accept(this, errors)) {
+          return true;
+        }
+      }
+      return false;
+    }
+  }
+
+  @Override
+  public Boolean visitBooleanOperator(BooleanOperator op, ErrorCollector errors) {
+    for (LogicalExpression arg : op.args) {
+      if (arg.accept(this, errors)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public Boolean visitIfExpression(IfExpression ifExpr, ErrorCollector errors) {
+    IfCondition c = ifExpr.ifCondition;
+    if (c.condition.accept(this, errors) || c.expression.accept(this, errors)) {
+      return true;
+    }
+    return ifExpr.elseExpression.accept(this, errors);
+  }
+
+  @Override
+  public Boolean visitSchemaPath(SchemaPath path, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitIntConstant(IntExpression intExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitFloatConstant(FloatExpression fExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitLongConstant(LongExpression intExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDoubleConstant(DoubleExpression dExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitBooleanConstant(BooleanExpression e, ErrorCollector errors) {
+    return false;
+  }
+  public Boolean visitDecimal9Constant(Decimal9Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal18Constant(Decimal18Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal28Constant(Decimal28Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal38Constant(Decimal38Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitQuotedStringConstant(QuotedString e, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitUnknown(LogicalExpression e, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitCastExpression(CastExpression e, ErrorCollector errors) {
+    return e.getInput().accept(this, errors);
+  }
+
+  @Override
+  public Boolean visitConvertExpression(ConvertExpression e, ErrorCollector errors) throws RuntimeException {
+    return e.getInput().accept(this, errors);
+  }
+
+  @Override
+  public Boolean visitDateConstant(DateExpression intExpr, ErrorCollector errors) {
+      return false;
+  }
+
+  @Override
+  public Boolean visitTimeConstant(TimeExpression intExpr, ErrorCollector errors) {
+      return false;
+  }
+
+  @Override
+  public Boolean visitTimeStampConstant(TimeStampExpression intExpr, ErrorCollector errors) {
+      return false;
+  }
+
+  @Override
+  public Boolean visitIntervalYearConstant(IntervalYearExpression intExpr, ErrorCollector errors) {
+      return false;
+  }
+
+  @Override
+  public Boolean visitIntervalDayConstant(IntervalDayExpression intExpr, ErrorCollector errors) {
+      return false;
+  }
+
+  @Override
+  public Boolean visitNullConstant(TypedNullConstant e, ErrorCollector value) throws RuntimeException {
+    return false;
+  }
+
+  @Override
+  public Boolean visitNullExpression(NullExpression e, ErrorCollector value) throws RuntimeException {
+    return false;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/ConditionalExprOptimizer.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/ConditionalExprOptimizer.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/ConditionalExprOptimizer.java
new file mode 100644
index 0000000..254926a
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/ConditionalExprOptimizer.java
@@ -0,0 +1,112 @@
+/**
+ * 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.common.expression.visitors;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+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.IfExpression.IfCondition;
+import org.apache.drill.common.expression.LogicalExpression;
+
+import com.google.common.collect.Lists;
+
+public class ConditionalExprOptimizer extends AbstractExprVisitor<LogicalExpression, Void, RuntimeException> {
+
+  public static ConditionalExprOptimizer INSTANCE = new ConditionalExprOptimizer();
+
+  @Override
+  public LogicalExpression visitBooleanOperator(BooleanOperator op, Void value) throws RuntimeException {
+
+    List<LogicalExpression> newArgs = Lists.newArrayList();
+
+    newArgs.addAll(op.args);
+
+    Collections.sort(newArgs, costComparator);
+
+    return new BooleanOperator(op.getName(), newArgs, op.getPosition());
+  }
+
+
+  @Override
+  public LogicalExpression visitFunctionHolderExpression(FunctionHolderExpression holder, Void value) throws RuntimeException {
+    List<LogicalExpression> args = Lists.newArrayList();
+    for (int i = 0; i < holder.args.size(); ++i) {
+      LogicalExpression newExpr = holder.args.get(i).accept(this, value);
+      assert newExpr != null;
+      args.add(newExpr);
+    }
+
+    //replace with a new function call, since its argument could be changed.
+
+    return holder.copy(args);
+  }
+
+  @Override
+  public LogicalExpression visitUnknown(LogicalExpression e, Void value) throws RuntimeException {
+    return e;
+  }
+
+
+  @Override
+  public LogicalExpression visitIfExpression(IfExpression ifExpr, Void value) throws RuntimeException{
+    LogicalExpression newElseExpr = ifExpr.elseExpression.accept(this, value);
+    IfCondition conditions = ifExpr.ifCondition;
+
+    LogicalExpression newCondition = conditions.condition.accept(this, value);
+    LogicalExpression newExpr = conditions.expression.accept(this, value);
+    conditions = new IfExpression.IfCondition(newCondition, newExpr);
+
+    return IfExpression.newBuilder().setElse(newElseExpr).setIfCondition(conditions).build();
+  }
+
+  @Override
+  public LogicalExpression visitFunctionCall(FunctionCall call, Void value) throws RuntimeException {
+    throw new UnsupportedOperationException("FunctionCall is not expected here. "
+        + "It should have been converted to FunctionHolderExpression in materialization");
+  }
+
+  @Override
+  public LogicalExpression visitCastExpression(CastExpression cast, Void value) throws RuntimeException {
+    throw new UnsupportedOperationException("CastExpression is not expected here. "
+        + "It should have been converted to FunctionHolderExpression in materialization");
+  }
+
+
+  @Override
+  public LogicalExpression visitConvertExpression(ConvertExpression cast, Void value) throws RuntimeException {
+    throw new UnsupportedOperationException("ConvertExpression is not expected here. "
+        + "It should have been converted to FunctionHolderExpression in materialization");
+  }
+
+  private static Comparator<LogicalExpression> costComparator = new Comparator<LogicalExpression> () {
+    public int compare(LogicalExpression e1, LogicalExpression e2) {
+      return e1.getCumulativeCost() <= e2.getCumulativeCost() ? -1 : 1;
+    }
+  };
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
new file mode 100644
index 0000000..ccb11a6
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
@@ -0,0 +1,210 @@
+/**
+ * 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.common.expression.visitors;
+
+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.ErrorCollector;
+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.IfExpression.IfCondition;
+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;
+
+final class ConstantChecker implements ExprVisitor<Boolean, ErrorCollector, RuntimeException> {
+
+
+  private final static ConstantChecker INSTANCE = new ConstantChecker();
+
+  private ConstantChecker() {}
+
+  public static void checkConstants(LogicalExpression e, ErrorCollector errors) {
+    e.accept(INSTANCE, errors);
+  }
+
+  @Override
+  public Boolean visitFunctionCall(FunctionCall call, ErrorCollector errors) {
+    throw new UnsupportedOperationException("FunctionCall is not expected here. "
+        + "It should have been converted to FunctionHolderExpression in materialization");
+  }
+
+  @Override
+  public Boolean visitFunctionHolderExpression(FunctionHolderExpression holder, ErrorCollector errors) {
+    boolean allArgsAreConstant = true;
+    for (int i = 0; i < holder.args.size(); i++) {
+      boolean thisArgIsConstant = holder.args.get(i).accept(this, errors);
+      if (!thisArgIsConstant) {
+        allArgsAreConstant = false;
+        if (holder.argConstantOnly(i)) {
+          errors.addGeneralError( //
+              holder.args.get(i).getPosition(), //
+              String.format("Function %s expects constant input for argument number %d", holder.getName(), i));
+        }
+      }
+    }
+    return allArgsAreConstant;
+  }
+
+  @Override
+  public Boolean visitBooleanOperator(BooleanOperator op, ErrorCollector errors) {
+    for (LogicalExpression e : op.args) {
+      if (!e.accept(this, errors)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override
+  public Boolean visitIfExpression(IfExpression ifExpr, ErrorCollector errors) {
+    IfCondition c = ifExpr.ifCondition;
+    if (!c.condition.accept(this, errors) || !c.expression.accept(this, errors)) {
+      return false;
+    }
+
+    if (!ifExpr.elseExpression.accept(this, errors)) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public Boolean visitSchemaPath(SchemaPath path, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitIntConstant(IntExpression intExpr, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitFloatConstant(FloatExpression fExpr, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitLongConstant(LongExpression intExpr, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitDateConstant(DateExpression intExpr, ErrorCollector errors) {
+      return true;
+  }
+
+  @Override
+  public Boolean visitTimeConstant(TimeExpression intExpr, ErrorCollector errors) {
+      return true;
+  }
+
+  @Override
+  public Boolean visitTimeStampConstant(TimeStampExpression intExpr, ErrorCollector errors) {
+      return true;
+  }
+
+  @Override
+  public Boolean visitIntervalYearConstant(IntervalYearExpression intExpr, ErrorCollector errors) {
+      return true;
+  }
+
+  @Override
+  public Boolean visitIntervalDayConstant(IntervalDayExpression intExpr, ErrorCollector errors) {
+      return true;
+  }
+
+  @Override
+  public Boolean visitDecimal9Constant(Decimal9Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal18Constant(Decimal18Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal28Constant(Decimal28Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDecimal38Constant(Decimal38Expression decExpr, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitDoubleConstant(DoubleExpression dExpr, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitBooleanConstant(BooleanExpression e, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitQuotedStringConstant(QuotedString e, ErrorCollector errors) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitUnknown(LogicalExpression e, ErrorCollector errors) {
+    return false;
+  }
+
+  @Override
+  public Boolean visitCastExpression(CastExpression e, ErrorCollector value) throws RuntimeException {
+    return e.getInput().accept(this, value);
+  }
+
+  @Override
+  public Boolean visitConvertExpression(ConvertExpression e, ErrorCollector value) throws RuntimeException {
+    return e.getInput().accept(this, value);
+  }
+
+  @Override
+  public Boolean visitNullConstant(TypedNullConstant e, ErrorCollector value) throws RuntimeException {
+    return true;
+  }
+
+  @Override
+  public Boolean visitNullExpression(NullExpression e, ErrorCollector value) throws RuntimeException {
+    return true;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
new file mode 100644
index 0000000..2d0cd8c
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
@@ -0,0 +1,72 @@
+/**
+ * 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.common.expression.visitors;
+
+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;
+
+public interface ExprVisitor<T, VAL, EXCEP extends Exception> {
+  public T visitFunctionCall(FunctionCall call, VAL value) throws EXCEP;
+  public T visitFunctionHolderExpression(FunctionHolderExpression holder, VAL value) throws EXCEP;
+  public T visitIfExpression(IfExpression ifExpr, VAL value) throws EXCEP;
+  public T visitBooleanOperator(BooleanOperator call, VAL value) throws EXCEP;
+  public T visitSchemaPath(SchemaPath path, VAL value) throws EXCEP;
+  public T visitIntConstant(IntExpression intExpr, VAL value) throws EXCEP;
+  public T visitFloatConstant(FloatExpression fExpr, VAL value) throws EXCEP;
+  public T visitLongConstant(LongExpression intExpr, VAL value) throws EXCEP;
+  public T visitDateConstant(DateExpression intExpr, VAL value) throws EXCEP;
+  public T visitTimeConstant(TimeExpression intExpr, VAL value) throws EXCEP;
+  public T visitTimeStampConstant(TimeStampExpression intExpr, VAL value) throws EXCEP;
+  public T visitIntervalYearConstant(IntervalYearExpression intExpr, VAL value) throws EXCEP;
+  public T visitIntervalDayConstant(IntervalDayExpression intExpr, VAL value) throws EXCEP;
+  public T visitDecimal9Constant(Decimal9Expression decExpr, VAL value) throws EXCEP;
+  public T visitDecimal18Constant(Decimal18Expression decExpr, VAL value) throws EXCEP;
+  public T visitDecimal28Constant(Decimal28Expression decExpr, VAL value) throws EXCEP;
+  public T visitDecimal38Constant(Decimal38Expression decExpr, VAL value) throws EXCEP;
+  public T visitDoubleConstant(DoubleExpression dExpr, VAL value) throws EXCEP;
+  public T visitBooleanConstant(BooleanExpression e, VAL value) throws EXCEP;
+  public T visitQuotedStringConstant(QuotedString e, VAL value) throws EXCEP;
+  public T visitNullConstant(TypedNullConstant e, VAL value) throws EXCEP;
+  public T visitNullExpression(NullExpression e, VAL value) throws EXCEP;
+  public T visitUnknown(LogicalExpression e, VAL value) throws EXCEP;
+  public T visitCastExpression(CastExpression e, VAL value) throws EXCEP;
+  public T visitConvertExpression(ConvertExpression e, VAL value) throws EXCEP;
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
new file mode 100644
index 0000000..e905638
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
@@ -0,0 +1,31 @@
+/**
+ * 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.common.expression.visitors;
+
+public class ExpressionValidationError {
+    String message;
+
+    public ExpressionValidationError(String message) {
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        return message;
+    }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
new file mode 100644
index 0000000..3d944da
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
@@ -0,0 +1,38 @@
+/**
+ * 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.common.expression.visitors;
+
+public class ExpressionValidationException extends RuntimeException {
+
+  public ExpressionValidationException() {
+    super();
+  }
+
+  public ExpressionValidationException(String arg0, Throwable arg1) {
+    super(arg0, arg1);
+  }
+
+  public ExpressionValidationException(String arg0) {
+    super(arg0);
+  }
+
+  public ExpressionValidationException(Throwable arg0) {
+    super(arg0);
+  }
+
+}


Mime
View raw message