drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject [3/6] drill git commit: DRILL-4372: Expose the functions return type to Drill
Date Sun, 20 Mar 2016 04:17:34 GMT
http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
index 4dd7963..7fe6020 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
@@ -19,6 +19,12 @@ package org.apache.drill.exec.planner.sql;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.calcite.sql.SqlAggFunction;
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlPrefixOperator;
+import org.apache.drill.common.expression.FunctionCallFactory;
+import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlIdentifier;
@@ -28,34 +34,50 @@ import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 
 import java.util.List;
+import java.util.Map;
 
+/**
+ * Implementation of {@link SqlOperatorTable} that contains standard operators and functions provided through
+ * {@link #inner SqlStdOperatorTable}, and Drill User Defined Functions.
+ */
 public class DrillOperatorTable extends SqlStdOperatorTable {
-  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillOperatorTable.class);
-
+//  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillOperatorTable.class);
   private static final SqlOperatorTable inner = SqlStdOperatorTable.instance();
-  private List<SqlOperator> operators;
+  private List<SqlOperator> operators = Lists.newArrayList();
+  private final Map<SqlOperator, SqlOperator> calciteToWrapper = Maps.newIdentityHashMap();
   private ArrayListMultimap<String, SqlOperator> opMap = ArrayListMultimap.create();
 
   public DrillOperatorTable(FunctionImplementationRegistry registry) {
-    operators = Lists.newArrayList();
-    operators.addAll(inner.getOperatorList());
-
     registry.register(this);
+    operators.addAll(inner.getOperatorList());
+    populateWrappedCalciteOperators();
   }
 
   public void add(String name, SqlOperator op) {
     operators.add(op);
-    opMap.put(name, op);
+    opMap.put(name.toLowerCase(), op);
   }
 
   @Override
-  public void lookupOperatorOverloads(SqlIdentifier opName, SqlFunctionCategory category, SqlSyntax syntax, List<SqlOperator> operatorList) {
-    inner.lookupOperatorOverloads(opName, category, syntax, operatorList);
-
-    if (operatorList.isEmpty() && syntax == SqlSyntax.FUNCTION && opName.isSimple()) {
-      List<SqlOperator> drillOps = opMap.get(opName.getSimple().toLowerCase());
-      if (drillOps != null) {
-        operatorList.addAll(drillOps);
+  public void lookupOperatorOverloads(SqlIdentifier opName, SqlFunctionCategory category,
+      SqlSyntax syntax, List<SqlOperator> operatorList) {
+    final List<SqlOperator> calciteOperatorList = Lists.newArrayList();
+    inner.lookupOperatorOverloads(opName, category, syntax, calciteOperatorList);
+    if(!calciteOperatorList.isEmpty()) {
+      for(SqlOperator calciteOperator : calciteOperatorList) {
+        if(calciteToWrapper.containsKey(calciteOperator)) {
+          operatorList.add(calciteToWrapper.get(calciteOperator));
+        } else {
+          operatorList.add(calciteOperator);
+        }
+      }
+    } else {
+      // if no function is found, check in Drill UDFs
+      if (operatorList.isEmpty() && syntax == SqlSyntax.FUNCTION && opName.isSimple()) {
+        List<SqlOperator> drillOps = opMap.get(opName.getSimple().toLowerCase());
+        if (drillOps != null && !drillOps.isEmpty()) {
+          operatorList.addAll(drillOps);
+        }
       }
     }
   }
@@ -69,4 +91,46 @@ public class DrillOperatorTable extends SqlStdOperatorTable {
   public List<SqlOperator> getSqlOperator(String name) {
     return opMap.get(name.toLowerCase());
   }
+
+  private void populateWrappedCalciteOperators() {
+    for(SqlOperator calciteOperator : inner.getOperatorList()) {
+      final SqlOperator wrapper;
+      if(calciteOperator instanceof SqlAggFunction) {
+        wrapper = new DrillCalciteSqlAggFunctionWrapper((SqlAggFunction) calciteOperator,
+            getFunctionList(calciteOperator.getName()));
+      } else if(calciteOperator instanceof SqlFunction) {
+        wrapper = new DrillCalciteSqlFunctionWrapper((SqlFunction) calciteOperator,
+            getFunctionList(calciteOperator.getName()));
+      } else {
+        final String drillOpName = FunctionCallFactory.replaceOpWithFuncName(calciteOperator.getName());
+        final List<DrillFuncHolder> drillFuncHolders = getFunctionList(drillOpName);
+        if(drillFuncHolders.isEmpty() || calciteOperator == SqlStdOperatorTable.UNARY_MINUS) {
+          continue;
+        }
+
+        wrapper = new DrillCalciteSqlOperatorWrapper(calciteOperator, drillOpName, drillFuncHolders);
+      }
+      calciteToWrapper.put(calciteOperator, wrapper);
+    }
+  }
+
+  private List<DrillFuncHolder> getFunctionList(String name) {
+    final List<DrillFuncHolder> functions = Lists.newArrayList();
+    for(SqlOperator sqlOperator : opMap.get(name.toLowerCase())) {
+      if(sqlOperator instanceof DrillSqlOperator) {
+        final List<DrillFuncHolder> list = ((DrillSqlOperator) sqlOperator).getFunctions();
+        if(list != null) {
+          functions.addAll(list);
+        }
+      }
+
+      if(sqlOperator instanceof DrillSqlAggOperator) {
+        final List<DrillFuncHolder> list = ((DrillSqlAggOperator) sqlOperator).getFunctions();
+        if(list != null) {
+          functions.addAll(list);
+        }
+      }
+    }
+    return functions;
+  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
index 2136201..81c744c 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
@@ -6,9 +6,9 @@
  * 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
- *
+ * <p/>
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
  * 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.
@@ -17,47 +17,36 @@
  */
 package org.apache.drill.exec.planner.sql;
 
-import java.util.List;
-
 import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.sql.SqlAggFunction;
-import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.parser.SqlParserPos;
-import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.calcite.sql.validate.SqlValidator;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
+import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 
-import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
 
 public class DrillSqlAggOperator extends SqlAggFunction {
-  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillSqlAggOperator.class);
-
-
-  public DrillSqlAggOperator(String name, int argCount) {
-    super(name, new SqlIdentifier(name, SqlParserPos.ZERO), SqlKind.OTHER_FUNCTION, DynamicReturnType.INSTANCE, null, new Checker(argCount), SqlFunctionCategory.USER_DEFINED_FUNCTION);
-  }
-
-  @Override
-  public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
-    return getAny(validator.getTypeFactory());
+  // private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillSqlAggOperator.class);
+  private final List<DrillFuncHolder> functions;
+
+  public DrillSqlAggOperator(String name, List<DrillFuncHolder> functions, int argCount) {
+    super(name,
+        new SqlIdentifier(name, SqlParserPos.ZERO),
+        SqlKind.OTHER_FUNCTION,
+        TypeInferenceUtils.getDrillSqlReturnTypeInference(
+            name,
+            functions),
+        null,
+        Checker.getChecker(argCount, argCount),
+        SqlFunctionCategory.USER_DEFINED_FUNCTION);
+    this.functions = functions;
   }
 
-  private RelDataType getAny(RelDataTypeFactory factory){
-    return factory.createSqlType(SqlTypeName.ANY);
-//    return new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory);
+  public List<DrillFuncHolder> getFunctions() {
+    return functions;
   }
-
-//  @Override
-//  public List<RelDataType> getParameterTypes(RelDataTypeFactory typeFactory) {
-//    return ImmutableList.of(typeFactory.createSqlType(SqlTypeName.ANY));
-//  }
-//
-//  @Override
-//  public RelDataType getReturnType(RelDataTypeFactory typeFactory) {
-//    return getAny(typeFactory);
-//  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlOperator.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlOperator.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlOperator.java
index 7b5a99d..0873c8d 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlOperator.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlOperator.java
@@ -6,9 +6,9 @@
  * 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
- *
+ * <p/>
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
  * 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.
@@ -18,69 +18,50 @@
 
 package org.apache.drill.exec.planner.sql;
 
-import com.google.common.base.Preconditions;
-import org.apache.drill.common.types.TypeProtos.MajorType;
-import org.apache.drill.common.types.TypeProtos.MinorType;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.sql.SqlCall;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.parser.SqlParserPos;
-import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.calcite.sql.validate.SqlValidator;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
+import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 
 public class DrillSqlOperator extends SqlFunction {
-  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillSqlOperator.class);
-
-  private static final MajorType NONE = MajorType.getDefaultInstance();
-  private final MajorType returnType;
+  // static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillSqlOperator.class);
   private final boolean isDeterministic;
+  private final List<DrillFuncHolder> functions;
 
+  /**
+   * This constructor exists for the legacy reason.
+   *
+   * It is because Drill cannot access to DrillOperatorTable at the place where this constructor is being called.
+   * In principle, if Drill needs a DrillSqlOperator, it is supposed to go to DrillOperatorTable for pickup.
+   */
+  @Deprecated
   public DrillSqlOperator(String name, int argCount, boolean isDeterministic) {
-    this(name, argCount, MajorType.getDefaultInstance(), isDeterministic);
+    this(name, new ArrayList<DrillFuncHolder>(), argCount, argCount, isDeterministic);
   }
 
-  public DrillSqlOperator(String name, int argCount, MajorType returnType, boolean isDeterminisitic) {
-    super(new SqlIdentifier(name, SqlParserPos.ZERO), DynamicReturnType.INSTANCE, null, new Checker(argCount), null, SqlFunctionCategory.USER_DEFINED_FUNCTION);
-    this.returnType = Preconditions.checkNotNull(returnType);
-    this.isDeterministic = isDeterminisitic;
+  public DrillSqlOperator(String name, List<DrillFuncHolder> functions, int argCountMin, int argCountMax, boolean isDeterministic) {
+    super(new SqlIdentifier(name, SqlParserPos.ZERO),
+        TypeInferenceUtils.getDrillSqlReturnTypeInference(
+            name,
+            functions),
+        null,
+        Checker.getChecker(argCountMin, argCountMax),
+        null,
+        SqlFunctionCategory.USER_DEFINED_FUNCTION);
+    this.functions = functions;
+    this.isDeterministic = isDeterministic;
   }
 
+  @Override
   public boolean isDeterministic() {
     return isDeterministic;
   }
 
-  protected RelDataType getReturnDataType(final RelDataTypeFactory factory) {
-    if (MinorType.BIT.equals(returnType.getMinorType())) {
-      return factory.createSqlType(SqlTypeName.BOOLEAN);
-    }
-    return factory.createTypeWithNullability(factory.createSqlType(SqlTypeName.ANY), true);
-  }
-
-  private RelDataType getNullableReturnDataType(final RelDataTypeFactory factory) {
-    return factory.createTypeWithNullability(getReturnDataType(factory), true);
-  }
-
-  @Override
-  public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
-    if (NONE.equals(returnType)) {
-      return validator.getTypeFactory().createSqlType(SqlTypeName.ANY);
-    }
-    /*
-     * We return a nullable output type both in validation phase and in
-     * Sql to Rel phase. We don't know the type of the output until runtime
-     * hence have to choose the least restrictive type to avoid any wrong
-     * results.
-     */
-    return getNullableReturnDataType(validator.getTypeFactory());
-  }
-
-  @Override
-  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
-    return getNullableReturnDataType(opBinding.getTypeFactory());
+  public List<DrillFuncHolder> getFunctions() {
+    return functions;
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/TypeInferenceUtils.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/TypeInferenceUtils.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/TypeInferenceUtils.java
new file mode 100644
index 0000000..8914b11
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/TypeInferenceUtils.java
@@ -0,0 +1,649 @@
+/**
+ * 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.planner.sql;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import org.apache.calcite.avatica.util.TimeUnit;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.sql.SqlCallBinding;
+import org.apache.calcite.sql.SqlCharStringLiteral;
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperatorBinding;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlReturnTypeInference;
+import org.apache.calcite.sql.type.SqlTypeName;
+
+import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.FunctionCallFactory;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.MajorTypeInLogicalExpression;
+import org.apache.drill.common.exceptions.UserException;
+import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.common.types.Types;
+import org.apache.drill.exec.expr.TypeHelper;
+import org.apache.drill.exec.expr.fn.DrillFuncHolder;
+import org.apache.drill.exec.resolver.FunctionResolver;
+import org.apache.drill.exec.resolver.FunctionResolverFactory;
+import org.apache.drill.exec.resolver.TypeCastRules;
+
+import java.util.List;
+
+public class TypeInferenceUtils {
+  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TypeInferenceUtils.class);
+
+  public static final TypeProtos.MajorType UNKNOWN_TYPE = TypeProtos.MajorType.getDefaultInstance();
+  private static final ImmutableMap<TypeProtos.MinorType, SqlTypeName> DRILL_TO_CALCITE_TYPE_MAPPING = ImmutableMap.<TypeProtos.MinorType, SqlTypeName> builder()
+      .put(TypeProtos.MinorType.INT, SqlTypeName.INTEGER)
+      .put(TypeProtos.MinorType.BIGINT, SqlTypeName.BIGINT)
+      .put(TypeProtos.MinorType.FLOAT4, SqlTypeName.FLOAT)
+      .put(TypeProtos.MinorType.FLOAT8, SqlTypeName.DOUBLE)
+      .put(TypeProtos.MinorType.VARCHAR, SqlTypeName.VARCHAR)
+      .put(TypeProtos.MinorType.BIT, SqlTypeName.BOOLEAN)
+      .put(TypeProtos.MinorType.DATE, SqlTypeName.DATE)
+      .put(TypeProtos.MinorType.DECIMAL9, SqlTypeName.DECIMAL)
+      .put(TypeProtos.MinorType.DECIMAL18, SqlTypeName.DECIMAL)
+      .put(TypeProtos.MinorType.DECIMAL28SPARSE, SqlTypeName.DECIMAL)
+      .put(TypeProtos.MinorType.DECIMAL38SPARSE, SqlTypeName.DECIMAL)
+      .put(TypeProtos.MinorType.TIME, SqlTypeName.TIME)
+      .put(TypeProtos.MinorType.TIMESTAMP, SqlTypeName.TIMESTAMP)
+      .put(TypeProtos.MinorType.VARBINARY, SqlTypeName.VARBINARY)
+      .put(TypeProtos.MinorType.INTERVALYEAR, SqlTypeName.INTERVAL_YEAR_MONTH)
+      .put(TypeProtos.MinorType.INTERVALDAY, SqlTypeName.INTERVAL_DAY_TIME)
+      .put(TypeProtos.MinorType.MAP, SqlTypeName.MAP)
+      .put(TypeProtos.MinorType.LIST, SqlTypeName.ARRAY)
+      .put(TypeProtos.MinorType.LATE, SqlTypeName.ANY)
+
+      // These are defined in the Drill type system but have been turned off for now
+      // .put(TypeProtos.MinorType.TINYINT, SqlTypeName.TINYINT)
+      // .put(TypeProtos.MinorType.SMALLINT, SqlTypeName.SMALLINT)
+      // Calcite types currently not supported by Drill, nor defined in the Drill type list:
+      //      - CHAR, SYMBOL, MULTISET, DISTINCT, STRUCTURED, ROW, OTHER, CURSOR, COLUMN_LIST
+      .build();
+
+  private static final ImmutableMap<SqlTypeName, TypeProtos.MinorType> CALCITE_TO_DRILL_MAPPING = ImmutableMap.<SqlTypeName, TypeProtos.MinorType> builder()
+      .put(SqlTypeName.INTEGER, TypeProtos.MinorType.INT)
+      .put(SqlTypeName.BIGINT, TypeProtos.MinorType.BIGINT)
+      .put(SqlTypeName.FLOAT, TypeProtos.MinorType.FLOAT4)
+      .put(SqlTypeName.DOUBLE, TypeProtos.MinorType.FLOAT8)
+      .put(SqlTypeName.VARCHAR, TypeProtos.MinorType.VARCHAR)
+      .put(SqlTypeName.BOOLEAN, TypeProtos.MinorType.BIT)
+      .put(SqlTypeName.DATE, TypeProtos.MinorType.DATE)
+      .put(SqlTypeName.TIME, TypeProtos.MinorType.TIME)
+      .put(SqlTypeName.TIMESTAMP, TypeProtos.MinorType.TIMESTAMP)
+      .put(SqlTypeName.VARBINARY, TypeProtos.MinorType.VARBINARY)
+      .put(SqlTypeName.INTERVAL_YEAR_MONTH, TypeProtos.MinorType.INTERVALYEAR)
+      .put(SqlTypeName.INTERVAL_DAY_TIME, TypeProtos.MinorType.INTERVALDAY)
+
+      // SqlTypeName.CHAR is the type for Literals in Calcite, Drill treats Literals as VARCHAR also
+      .put(SqlTypeName.CHAR, TypeProtos.MinorType.VARCHAR)
+
+      // The following types are not added due to a variety of reasons:
+      // (1) Disabling decimal type
+      //.put(SqlTypeName.DECIMAL, TypeProtos.MinorType.DECIMAL9)
+      //.put(SqlTypeName.DECIMAL, TypeProtos.MinorType.DECIMAL18)
+      //.put(SqlTypeName.DECIMAL, TypeProtos.MinorType.DECIMAL28SPARSE)
+      //.put(SqlTypeName.DECIMAL, TypeProtos.MinorType.DECIMAL38SPARSE)
+
+      // (2) These 2 types are defined in the Drill type system but have been turned off for now
+      // .put(SqlTypeName.TINYINT, TypeProtos.MinorType.TINYINT)
+      // .put(SqlTypeName.SMALLINT, TypeProtos.MinorType.SMALLINT)
+
+      // (3) Calcite types currently not supported by Drill, nor defined in the Drill type list:
+      //      - SYMBOL, MULTISET, DISTINCT, STRUCTURED, ROW, OTHER, CURSOR, COLUMN_LIST
+      // .put(SqlTypeName.MAP, TypeProtos.MinorType.MAP)
+      // .put(SqlTypeName.ARRAY, TypeProtos.MinorType.LIST)
+      .build();
+
+  private static final ImmutableMap<String, SqlReturnTypeInference> funcNameToInference = ImmutableMap.<String, SqlReturnTypeInference> builder()
+      .put("DATE_PART", DrillDatePartSqlReturnTypeInference.INSTANCE)
+      .put("SUM", DrillSumSqlReturnTypeInference.INSTANCE)
+      .put("COUNT", DrillCountSqlReturnTypeInference.INSTANCE)
+      .put("CONCAT", DrillConcatSqlReturnTypeInference.INSTANCE)
+      .put("LENGTH", DrillLengthSqlReturnTypeInference.INSTANCE)
+      .put("LPAD", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("RPAD", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("LTRIM", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("RTRIM", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("BTRIM", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("TRIM", DrillPadTrimSqlReturnTypeInference.INSTANCE)
+      .put("CONVERT_TO", DrillConvertToSqlReturnTypeInference.INSTANCE)
+      .put("EXTRACT", DrillExtractSqlReturnTypeInference.INSTANCE)
+      .put("SQRT", DrillSqrtSqlReturnTypeInference.INSTANCE)
+      .put("CAST", DrillCastSqlReturnTypeInference.INSTANCE)
+      .put("FLATTEN", DrillDeferToExecSqlReturnTypeInference.INSTANCE)
+      .put("KVGEN", DrillDeferToExecSqlReturnTypeInference.INSTANCE)
+      .put("CONVERT_FROM", DrillDeferToExecSqlReturnTypeInference.INSTANCE)
+      .build();
+
+  /**
+   * Given a Drill's TypeProtos.MinorType, return a Calcite's corresponding SqlTypeName
+   */
+  public static SqlTypeName getCalciteTypeFromDrillType(final TypeProtos.MinorType type) {
+    if(!DRILL_TO_CALCITE_TYPE_MAPPING.containsKey(type)) {
+      return SqlTypeName.ANY;
+    }
+
+    return DRILL_TO_CALCITE_TYPE_MAPPING.get(type);
+  }
+
+  /**
+   * Given a Calcite's RelDataType, return a Drill's corresponding TypeProtos.MinorType
+   */
+  public static TypeProtos.MinorType getDrillTypeFromCalciteType(final RelDataType relDataType) {
+    final SqlTypeName sqlTypeName = relDataType.getSqlTypeName();
+    return getDrillTypeFromCalciteType(sqlTypeName);
+  }
+
+  /**
+   * Given a Calcite's SqlTypeName, return a Drill's corresponding TypeProtos.MinorType
+   */
+  public static TypeProtos.MinorType getDrillTypeFromCalciteType(final SqlTypeName sqlTypeName) {
+    if(!CALCITE_TO_DRILL_MAPPING.containsKey(sqlTypeName)) {
+      return TypeProtos.MinorType.LATE;
+    }
+
+    return CALCITE_TO_DRILL_MAPPING.get(sqlTypeName);
+  }
+
+  /**
+   * Give the name and DrillFuncHolder list, return the inference mechanism.
+   */
+  public static SqlReturnTypeInference getDrillSqlReturnTypeInference(
+      final String name,
+      final List<DrillFuncHolder> functions) {
+
+    final String nameCap = name.toUpperCase();
+    if(funcNameToInference.containsKey(nameCap)) {
+      return funcNameToInference.get(nameCap);
+    } else {
+      return new DrillDefaultSqlReturnTypeInference(functions);
+    }
+  }
+
+  private static class DrillDefaultSqlReturnTypeInference implements SqlReturnTypeInference {
+    private final List<DrillFuncHolder> functions;
+
+    public DrillDefaultSqlReturnTypeInference(List<DrillFuncHolder> functions) {
+      this.functions = functions;
+    }
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      if (functions.isEmpty()) {
+        return factory.createTypeWithNullability(
+            factory.createSqlType(SqlTypeName.ANY),
+            true);
+      }
+
+      // The following logic is just a safe play:
+      // Even if any of the input arguments has ANY type,
+      // it "might" still be possible to determine the return type based on other non-ANY types
+      for (RelDataType type : opBinding.collectOperandTypes()) {
+        if (getDrillTypeFromCalciteType(type) == TypeProtos.MinorType.LATE) {
+          // This code for boolean output type is added for addressing DRILL-1729
+          // In summary, if we have a boolean output function in the WHERE-CLAUSE,
+          // this logic can validate and execute user queries seamlessly
+          boolean allBooleanOutput = true;
+          for (DrillFuncHolder function : functions) {
+            if (function.getReturnType().getMinorType() != TypeProtos.MinorType.BIT) {
+              allBooleanOutput = false;
+              break;
+            }
+          }
+
+          if(allBooleanOutput) {
+            return factory.createTypeWithNullability(
+                factory.createSqlType(SqlTypeName.BOOLEAN), true);
+          } else {
+            return factory.createTypeWithNullability(
+                factory.createSqlType(SqlTypeName.ANY),
+                true);
+          }
+        }
+      }
+
+      final DrillFuncHolder func = resolveDrillFuncHolder(opBinding, functions);
+      final RelDataType returnType = getReturnType(opBinding, func);
+      return returnType;
+    }
+
+    private static RelDataType getReturnType(final SqlOperatorBinding opBinding, final DrillFuncHolder func) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+
+      // least restrictive type (nullable ANY type)
+      final RelDataType nullableAnyType = factory.createTypeWithNullability(
+          factory.createSqlType(SqlTypeName.ANY),
+          true);
+
+      final TypeProtos.MajorType returnType = func.getReturnType();
+      if (UNKNOWN_TYPE.equals(returnType)) {
+        return nullableAnyType;
+      }
+
+      final TypeProtos.MinorType minorType = returnType.getMinorType();
+      final SqlTypeName sqlTypeName = getCalciteTypeFromDrillType(minorType);
+      if (sqlTypeName == null) {
+        return nullableAnyType;
+      }
+
+      final boolean isNullable;
+      switch (returnType.getMode()) {
+        case REPEATED:
+        case OPTIONAL:
+          isNullable = true;
+          break;
+
+        case REQUIRED:
+          switch (func.getNullHandling()) {
+            case INTERNAL:
+              isNullable = false;
+              break;
+
+            case NULL_IF_NULL:
+              boolean isNull = false;
+              for (int i = 0; i < opBinding.getOperandCount(); ++i) {
+                if (opBinding.getOperandType(i).isNullable()) {
+                  isNull = true;
+                  break;
+                }
+              }
+
+              isNullable = isNull;
+              break;
+            default:
+              throw new UnsupportedOperationException();
+          }
+          break;
+
+        default:
+          throw new UnsupportedOperationException();
+      }
+
+      return createCalciteTypeWithNullability(
+          factory,
+          sqlTypeName,
+          isNullable);
+    }
+  }
+
+  private static class DrillDeferToExecSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillDeferToExecSqlReturnTypeInference INSTANCE = new DrillDeferToExecSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      return factory.createTypeWithNullability(
+          factory.createSqlType(SqlTypeName.ANY),
+          true);
+    }
+  }
+
+  private static class DrillSumSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillSumSqlReturnTypeInference INSTANCE = new DrillSumSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      // If there is group-by and the imput type is Non-nullable,
+      // the output is Non-nullable;
+      // Otherwise, the output is nullable.
+      final boolean isNullable = opBinding.getGroupCount() == 0
+          || opBinding.getOperandType(0).isNullable();
+
+      if(getDrillTypeFromCalciteType(opBinding.getOperandType(0)) == TypeProtos.MinorType.LATE) {
+        return createCalciteTypeWithNullability(
+            factory,
+            SqlTypeName.ANY,
+            isNullable);
+      }
+
+      final RelDataType operandType = opBinding.getOperandType(0);
+      final TypeProtos.MinorType inputMinorType = getDrillTypeFromCalciteType(operandType);
+      if(TypeCastRules.getLeastRestrictiveType(Lists.newArrayList(inputMinorType, TypeProtos.MinorType.BIGINT))
+          == TypeProtos.MinorType.BIGINT) {
+        return createCalciteTypeWithNullability(
+            factory,
+            SqlTypeName.BIGINT,
+            isNullable);
+      } else if(TypeCastRules.getLeastRestrictiveType(Lists.newArrayList(inputMinorType, TypeProtos.MinorType.FLOAT8))
+          == TypeProtos.MinorType.FLOAT8) {
+        return createCalciteTypeWithNullability(
+            factory,
+            SqlTypeName.DOUBLE,
+            isNullable);
+      } else {
+        throw UserException
+            .functionError()
+            .message(String.format("%s does not support operand types (%s)",
+                opBinding.getOperator().getName(),
+                opBinding.getOperandType(0).getSqlTypeName()))
+            .build(logger);
+      }
+    }
+  }
+
+  private static class DrillCountSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillCountSqlReturnTypeInference INSTANCE = new DrillCountSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final SqlTypeName type = SqlTypeName.BIGINT;
+      return createCalciteTypeWithNullability(
+          factory,
+          type,
+          false);
+    }
+  }
+
+  private static class DrillConcatSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillConcatSqlReturnTypeInference INSTANCE = new DrillConcatSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+
+      boolean isNullable = true;
+      int precision = 0;
+      for(RelDataType relDataType : opBinding.collectOperandTypes()) {
+        if(!relDataType.isNullable()) {
+          isNullable = false;
+        }
+
+        // If the underlying columns cannot offer information regarding the precision (i.e., the length) of the VarChar,
+        // Drill uses the largest to represent it
+        if(relDataType.getPrecision() == TypeHelper.VARCHAR_DEFAULT_CAST_LEN
+            || relDataType.getPrecision() == RelDataType.PRECISION_NOT_SPECIFIED) {
+          precision = TypeHelper.VARCHAR_DEFAULT_CAST_LEN;
+        } else {
+          precision += relDataType.getPrecision();
+        }
+      }
+
+      return factory.createTypeWithNullability(
+          factory.createSqlType(SqlTypeName.VARCHAR, precision),
+          isNullable);
+    }
+  }
+
+  private static class DrillLengthSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillLengthSqlReturnTypeInference INSTANCE = new DrillLengthSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final SqlTypeName sqlTypeName = SqlTypeName.BIGINT;
+
+      // We need to check only the first argument because
+      // the second one is used to represent encoding type
+      final boolean isNullable = opBinding.getOperandType(0).isNullable();
+      return createCalciteTypeWithNullability(
+          factory,
+          sqlTypeName,
+          isNullable);
+    }
+  }
+
+  private static class DrillPadTrimSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillPadTrimSqlReturnTypeInference INSTANCE = new DrillPadTrimSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final SqlTypeName sqlTypeName = SqlTypeName.VARCHAR;
+
+      for(int i = 0; i < opBinding.getOperandCount(); ++i) {
+        if(opBinding.getOperandType(i).isNullable()) {
+          return createCalciteTypeWithNullability(
+              factory, sqlTypeName, true);
+        }
+      }
+
+      return createCalciteTypeWithNullability(
+          factory, sqlTypeName, false);
+    }
+  }
+
+  private static class DrillConvertToSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillConvertToSqlReturnTypeInference INSTANCE = new DrillConvertToSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final SqlTypeName type = SqlTypeName.VARBINARY;
+
+      return createCalciteTypeWithNullability(
+          factory, type, opBinding.getOperandType(0).isNullable());
+    }
+  }
+
+  private static class DrillExtractSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillExtractSqlReturnTypeInference INSTANCE = new DrillExtractSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final TimeUnit timeUnit = opBinding.getOperandType(0).getIntervalQualifier().getStartUnit();
+      final boolean isNullable = opBinding.getOperandType(1).isNullable();
+
+      final SqlTypeName sqlTypeName = getSqlTypeNameForTimeUnit(timeUnit.name());
+      return createCalciteTypeWithNullability(
+          factory,
+          sqlTypeName,
+          isNullable);
+    }
+  }
+
+  private static class DrillSqrtSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillSqrtSqlReturnTypeInference INSTANCE = new DrillSqrtSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final boolean isNullable = opBinding.getOperandType(0).isNullable();
+      return createCalciteTypeWithNullability(
+          factory,
+          SqlTypeName.DOUBLE,
+          isNullable);
+    }
+  }
+
+  private static class DrillDatePartSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillDatePartSqlReturnTypeInference INSTANCE = new DrillDatePartSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+
+      final SqlNode firstOperand = ((SqlCallBinding) opBinding).operand(0);
+      if(!(firstOperand instanceof SqlCharStringLiteral)) {
+        return createCalciteTypeWithNullability(factory,
+            SqlTypeName.ANY,
+            opBinding.getOperandType(1).isNullable());
+      }
+
+      final String part = ((SqlCharStringLiteral) firstOperand)
+          .getNlsString()
+          .getValue()
+          .toUpperCase();
+
+      final SqlTypeName sqlTypeName = getSqlTypeNameForTimeUnit(part);
+      final boolean isNullable = opBinding.getOperandType(1).isNullable();
+      return createCalciteTypeWithNullability(
+          factory,
+          sqlTypeName,
+          isNullable);
+    }
+  }
+
+  private static class DrillCastSqlReturnTypeInference implements SqlReturnTypeInference {
+    private static final DrillCastSqlReturnTypeInference INSTANCE = new DrillCastSqlReturnTypeInference();
+
+    @Override
+    public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+      final RelDataTypeFactory factory = opBinding.getTypeFactory();
+      final boolean isNullable = opBinding
+          .getOperandType(0)
+          .isNullable();
+
+      RelDataType ret = factory.createTypeWithNullability(
+          opBinding.getOperandType(1),
+          isNullable);
+
+      if (opBinding instanceof SqlCallBinding) {
+        SqlCallBinding callBinding = (SqlCallBinding) opBinding;
+        SqlNode operand0 = callBinding.operand(0);
+
+        // dynamic parameters and null constants need their types assigned
+        // to them using the type they are casted to.
+        if (((operand0 instanceof SqlLiteral)
+                && (((SqlLiteral) operand0).getValue() == null))
+                || (operand0 instanceof SqlDynamicParam)) {
+          callBinding.getValidator().setValidatedNodeType(
+                  operand0,
+                  ret);
+        }
+      }
+
+      return ret;
+    }
+  }
+
+  private static DrillFuncHolder resolveDrillFuncHolder(final SqlOperatorBinding opBinding, final List<DrillFuncHolder> functions) {
+    final FunctionCall functionCall = convertSqlOperatorBindingToFunctionCall(opBinding);
+    final FunctionResolver functionResolver = FunctionResolverFactory.getResolver(functionCall);
+    final DrillFuncHolder func = functionResolver.getBestMatch(functions, functionCall);
+
+    // Throw an exception
+    // if no DrillFuncHolder matched for the given list of operand types
+    if(func == null) {
+      String operandTypes = "";
+      for(int i = 0; i < opBinding.getOperandCount(); ++i) {
+        operandTypes += opBinding.getOperandType(i).getSqlTypeName();
+        if(i < opBinding.getOperandCount() - 1) {
+          operandTypes += ",";
+        }
+      }
+
+      throw UserException
+          .functionError()
+          .message(String.format("%s does not support operand types (%s)",
+              opBinding.getOperator().getName(),
+              operandTypes))
+          .build(logger);
+    }
+    return func;
+  }
+
+  /**
+   * For Extract and date_part functions, infer the return types based on timeUnit
+   */
+  public static SqlTypeName getSqlTypeNameForTimeUnit(String timeUnit) {
+    switch (timeUnit.toUpperCase()){
+      case "YEAR":
+      case "MONTH":
+      case "DAY":
+      case "HOUR":
+      case "MINUTE":
+        return SqlTypeName.BIGINT;
+      case "SECOND":
+        return SqlTypeName.DOUBLE;
+      default:
+        throw UserException
+            .functionError()
+            .message("extract function supports the following time units: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND")
+            .build(logger);
+    }
+  }
+
+  /**
+   * Given a {@link SqlTypeName} and nullability, create a RelDataType from the RelDataTypeFactory
+   *
+   * @param typeFactory RelDataTypeFactory used to create the RelDataType
+   * @param sqlTypeName the given SqlTypeName
+   * @param isNullable  the nullability of the created RelDataType
+   * @return RelDataType Type of call
+   */
+  public static RelDataType createCalciteTypeWithNullability(RelDataTypeFactory typeFactory,
+                                                             SqlTypeName sqlTypeName,
+                                                             boolean isNullable) {
+    RelDataType type;
+    if (sqlTypeName == SqlTypeName.INTERVAL_DAY_TIME) {
+      type = typeFactory.createSqlIntervalType(
+          new SqlIntervalQualifier(
+              TimeUnit.DAY,
+              TimeUnit.MINUTE,
+              SqlParserPos.ZERO));
+    } else if (sqlTypeName == SqlTypeName.INTERVAL_YEAR_MONTH) {
+      type = typeFactory.createSqlIntervalType(
+          new SqlIntervalQualifier(
+              TimeUnit.YEAR,
+              TimeUnit.MONTH,
+              SqlParserPos.ZERO));
+    } else if (sqlTypeName == SqlTypeName.VARCHAR) {
+      type = typeFactory.createSqlType(sqlTypeName, TypeHelper.VARCHAR_DEFAULT_CAST_LEN);
+    } else {
+      type = typeFactory.createSqlType(sqlTypeName);
+    }
+    return typeFactory.createTypeWithNullability(type, isNullable);
+  }
+
+  /**
+   * Given a SqlOperatorBinding, convert it to FunctionCall
+   * @param  opBinding    the given SqlOperatorBinding
+   * @return FunctionCall the converted FunctionCall
+   */
+  public static FunctionCall convertSqlOperatorBindingToFunctionCall(final SqlOperatorBinding opBinding) {
+    final List<LogicalExpression> args = Lists.newArrayList();
+
+    for (int i = 0; i < opBinding.getOperandCount(); ++i) {
+      final RelDataType type = opBinding.getOperandType(i);
+      final TypeProtos.MinorType minorType = getDrillTypeFromCalciteType(type);
+      final TypeProtos.MajorType majorType;
+      if (type.isNullable()) {
+        majorType = Types.optional(minorType);
+      } else {
+        majorType = Types.required(minorType);
+      }
+
+      args.add(new MajorTypeInLogicalExpression(majorType));
+    }
+
+    final String drillFuncName = FunctionCallFactory.replaceOpWithFuncName(opBinding.getOperator().getName());
+    final FunctionCall functionCall = new FunctionCall(
+        drillFuncName,
+        args,
+        ExpressionPosition.UNKNOWN);
+    return functionCall;
+  }
+
+  /**
+   * This class is not intended to be instantiated
+   */
+  private TypeInferenceUtils() {
+
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
index 0ebb557..b6ffde6 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
@@ -234,7 +234,7 @@ public class CreateTableHandler extends DefaultSqlHandler {
 
   private RexNode composeDisjunction(final RexBuilder rexBuilder, List<RexNode> compFuncs) {
     final DrillSqlOperator booleanOrFunc
-             = new DrillSqlOperator("orNoShortCircuit", 2, MajorType.getDefaultInstance(), true);
+             = new DrillSqlOperator("orNoShortCircuit", 2, true);
     RexNode node = compFuncs.remove(0);
     while (!compFuncs.isEmpty()) {
       node = rexBuilder.makeCall(booleanOrFunc, node, compFuncs.remove(0));

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
index 5152fa6..4ca9fe4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
@@ -234,14 +234,17 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
         convertedRelNode = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.JOIN_PLANNING, intermediateNode2);
       }
 
-      final DrillRel drillRel = (DrillRel) convertedRelNode;
+      // Convert SUM to $SUM0
+      final RelNode convertedRelNodeWithSum0 = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.SUM_CONVERSION, convertedRelNode);
+
+      final DrillRel drillRel = (DrillRel) convertedRelNodeWithSum0;
 
       if (drillRel instanceof DrillStoreRel) {
         throw new UnsupportedOperationException();
       } else {
 
         // If the query contains a limit 0 clause, disable distributed mode since it is overkill for determining schema.
-        if (FindLimit0Visitor.containsLimit0(convertedRelNode)) {
+        if (FindLimit0Visitor.containsLimit0(convertedRelNodeWithSum0)) {
           context.getPlannerSettings().forceSingleMode();
         }
 
@@ -613,7 +616,8 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
      */
 
     PreProcessLogicalRel visitor = PreProcessLogicalRel.createVisitor(config.getConverter().getTypeFactory(),
-        context.getDrillOperatorTable());
+        context.getDrillOperatorTable(),
+        rel.getCluster().getRexBuilder());
     try {
       rel = rel.accept(visitor);
     } catch (UnsupportedOperationException ex) {

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
index e90aa3b..528cadc 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
@@ -25,6 +25,7 @@ import org.apache.drill.exec.ExecConstants;
 import org.apache.drill.exec.exception.UnsupportedOperatorCollector;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.physical.PlannerSettings;
+import org.apache.drill.exec.planner.sql.DrillCalciteSqlWrapper;
 import org.apache.drill.exec.work.foreman.SqlUnsupportedException;
 
 import org.apache.calcite.sql.SqlSelectKeyword;
@@ -351,7 +352,7 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
       }
     }
 
-    if(sqlCall.getOperator() instanceof SqlCountAggFunction) {
+    if(extractSqlOperatorFromWrapper(sqlCall.getOperator()) instanceof SqlCountAggFunction) {
       for(SqlNode sqlNode : sqlCall.getOperandList()) {
         if(containsFlatten(sqlNode)) {
           unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION,
@@ -415,7 +416,7 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
     @Override
     public boolean test(SqlNode sqlNode) {
       if (sqlNode instanceof SqlCall) {
-        final SqlOperator operator = ((SqlCall) sqlNode).getOperator();
+        final SqlOperator operator = extractSqlOperatorFromWrapper(((SqlCall) sqlNode).getOperator());
         if (operator == SqlStdOperatorTable.ROLLUP
             || operator == SqlStdOperatorTable.CUBE
             || operator == SqlStdOperatorTable.GROUPING_SETS) {
@@ -433,10 +434,10 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
     @Override
     public boolean test(SqlNode sqlNode) {
       if (sqlNode instanceof SqlCall) {
-        final SqlOperator operator = ((SqlCall) sqlNode).getOperator();
-        if (operator == SqlStdOperatorTable.GROUPING
-            || operator == SqlStdOperatorTable.GROUPING_ID
-            || operator == SqlStdOperatorTable.GROUP_ID) {
+        final SqlOperator operator = extractSqlOperatorFromWrapper(((SqlCall) sqlNode).getOperator());
+          if (operator == SqlStdOperatorTable.GROUPING
+              || operator == SqlStdOperatorTable.GROUPING_ID
+              || operator == SqlStdOperatorTable.GROUP_ID) {
           return true;
         }
       }
@@ -554,4 +555,12 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
       }
     }
   }
+
+  private SqlOperator extractSqlOperatorFromWrapper(SqlOperator sqlOperator) {
+    if(sqlOperator instanceof DrillCalciteSqlWrapper) {
+      return ((DrillCalciteSqlWrapper) sqlOperator).getOperator();
+    } else {
+      return sqlOperator;
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/DefaultFunctionResolver.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/DefaultFunctionResolver.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/DefaultFunctionResolver.java
index 6904272..bf125d7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/DefaultFunctionResolver.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/DefaultFunctionResolver.java
@@ -21,7 +21,10 @@ package org.apache.drill.exec.resolver;
 import java.util.LinkedList;
 import java.util.List;
 
+import com.google.common.collect.Lists;
 import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 import org.apache.drill.exec.util.AssertionUtil;
 
@@ -30,7 +33,7 @@ public class DefaultFunctionResolver implements FunctionResolver {
   private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DefaultFunctionResolver.class);
 
   @Override
-  public DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods,FunctionCall call) {
+  public DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods, FunctionCall call) {
 
     int bestcost = Integer.MAX_VALUE;
     int currcost = Integer.MAX_VALUE;
@@ -38,8 +41,11 @@ public class DefaultFunctionResolver implements FunctionResolver {
     final List<DrillFuncHolder> bestMatchAlternatives = new LinkedList<>();
 
     for (DrillFuncHolder h : methods) {
-
-      currcost = TypeCastRules.getCost(call, h);
+      final List<TypeProtos.MajorType> argumentTypes = Lists.newArrayList();
+      for (LogicalExpression expression : call.args) {
+        argumentTypes.add(expression.getMajorType());
+      }
+      currcost = TypeCastRules.getCost(argumentTypes, h);
 
       // if cost is lower than 0, func implementation is not matched, either w/ or w/o implicit casts
       if (currcost  < 0 ) {
@@ -79,5 +85,4 @@ public class DefaultFunctionResolver implements FunctionResolver {
       return bestmatch;
     }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ExactFunctionResolver.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ExactFunctionResolver.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ExactFunctionResolver.java
index ab6be33..72e27ef 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ExactFunctionResolver.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ExactFunctionResolver.java
@@ -17,7 +17,10 @@
  */
 package org.apache.drill.exec.resolver;
 
+import com.google.common.collect.Lists;
 import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 
 import java.util.List;
@@ -37,8 +40,11 @@ public class ExactFunctionResolver implements FunctionResolver {
     int currcost;
 
     for (DrillFuncHolder h : methods) {
-
-      currcost = TypeCastRules.getCost(call, h);
+      final List<TypeProtos.MajorType> argumentTypes = Lists.newArrayList();
+      for (LogicalExpression expression : call.args) {
+        argumentTypes.add(expression.getMajorType());
+      }
+      currcost = TypeCastRules.getCost(argumentTypes, h);
 
       // Return if we found a function that has an exact match with the input arguments
       if (currcost  == 0){

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolver.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolver.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolver.java
index 14d46c9..e2a9622 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolver.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolver.java
@@ -23,8 +23,19 @@ import java.util.List;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 
+/**
+ * An implementing class of FunctionResolver provide their own algorithm to choose a DrillFuncHolder from a given list of
+ * candidates, with respect to a given FunctionCall
+ */
 public interface FunctionResolver {
-
-  public DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods, FunctionCall call);
-
+  /**
+   * Creates a placeholder SqlFunction for an invocation of a function with a
+   * possibly qualified name. This name must be resolved into either a builtin
+   * function or a user-defined function.
+   *
+   * @param methods   a list of candidates of DrillFuncHolder to be chosen from
+   * @param call      a given function call whose DrillFuncHolder is to be determined via this method
+   * @return DrillFuncHolder the chosen DrillFuncHolder
+   */
+  DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods, FunctionCall call);
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolverFactory.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolverFactory.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolverFactory.java
index b9070af..ab6934b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolverFactory.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/FunctionResolverFactory.java
@@ -21,7 +21,6 @@ package org.apache.drill.exec.resolver;
 import org.apache.drill.common.expression.FunctionCall;
 
 public class FunctionResolverFactory {
-
   public static FunctionResolver getResolver(FunctionCall call) {
     return new DefaultFunctionResolver();
   }
@@ -29,6 +28,4 @@ public class FunctionResolverFactory {
   public static FunctionResolver getExactResolver(FunctionCall call) {
     return new ExactFunctionResolver();
   }
-
-
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
index 7ee8ebe..ae42937 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
@@ -26,7 +26,8 @@ import java.util.Set;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.MajorTypeInLogicalExpression;
+import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.types.TypeProtos.DataMode;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.common.types.TypeProtos.MinorType;
@@ -834,10 +835,10 @@ public class TypeCastRules {
    * implicit cast > 0: cost associated with implicit cast. ==0: parms are
    * exactly same type of arg. No need of implicit.
    */
-  public static int getCost(FunctionCall call, DrillFuncHolder holder) {
+  public static int getCost(List<MajorType> argumentTypes, DrillFuncHolder holder) {
     int cost = 0;
 
-    if (call.args.size() != holder.getParamCount()) {
+    if (argumentTypes.size() != holder.getParamCount()) {
       return -1;
     }
 
@@ -852,14 +853,21 @@ public class TypeCastRules {
      * the function can fit the precision that we need based on the input types.
      */
     if (holder.checkPrecisionRange() == true) {
-      if (DecimalUtility.getMaxPrecision(holder.getReturnType().getMinorType()) < holder.getReturnType(call.args).getPrecision()) {
+      List<LogicalExpression> logicalExpressions = Lists.newArrayList();
+      for(MajorType majorType : argumentTypes) {
+        logicalExpressions.add(
+            new MajorTypeInLogicalExpression(majorType));
+      }
+
+      if (DecimalUtility.getMaxPrecision(holder.getReturnType().getMinorType()) <
+          holder.getReturnType(logicalExpressions).getPrecision()) {
         return -1;
       }
     }
 
     final int numOfArgs = holder.getParamCount();
     for (int i = 0; i < numOfArgs; i++) {
-      final MajorType argType = call.args.get(i).getMajorType();
+      final MajorType argType = argumentTypes.get(i);
       final MajorType parmType = holder.getParmMajorType(i);
 
       //@Param FieldReader will match any type

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java b/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
index fdf39c1..5f6cd9c 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
@@ -29,16 +29,6 @@ public class TestDisabledFunctionality extends BaseTestQuery{
   static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestExampleQueries.class);
 
   @Test(expected = UserException.class)  // see DRILL-2054
-  public void testBooleanORExpression() throws Exception {
-        test("select (1 = 1) || (1 > 0) from cp.`tpch/nation.parquet` ");
-    }
-
-  @Test(expected = UserException.class)  // see DRILL-2054
-  public void testBooleanORSelectClause() throws Exception {
-    test("select true || true from cp.`tpch/nation.parquet` ");
-  }
-
-  @Test(expected = UserException.class)  // see DRILL-2054
   public void testBooleanORWhereClause() throws Exception {
     test("select * from cp.`tpch/nation.parquet` where (true || true) ");
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsWithTypeExpoQueries.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsWithTypeExpoQueries.java b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsWithTypeExpoQueries.java
index 7d3f6d0..81d093c 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsWithTypeExpoQueries.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsWithTypeExpoQueries.java
@@ -18,16 +18,13 @@
 package org.apache.drill;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.common.util.FileUtils;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.List;
-import java.util.Map;
 
 public class TestFunctionsWithTypeExpoQueries extends BaseTestQuery {
   @Test
@@ -50,10 +47,45 @@ public class TestFunctionsWithTypeExpoQueries extends BaseTestQuery {
   }
 
   @Test
-  public void testTrimOnlyOneArg() throws Exception {
-    final String query1 = "SELECT ltrim('drill') as col FROM (VALUES(1)) limit 0";
-    final String query2 = "SELECT rtrim('drill') as col FROM (VALUES(1)) limit 0";
-    final String query3 = "SELECT btrim('drill') as col FROM (VALUES(1)) limit 0";
+  public void testRow_NumberInView() throws Exception {
+    try {
+      test("use dfs_test.tmp;");
+      final String view1 =
+          "create view TestFunctionsWithTypeExpoQueries_testViewShield1 as \n" +
+              "select rnum, position_id, " +
+              "   ntile(4) over(order by position_id) " +
+              " from (select position_id, row_number() " +
+              "       over(order by position_id) as rnum " +
+              "       from cp.`employee.json`)";
+
+
+      final String view2 =
+          "create view TestFunctionsWithTypeExpoQueries_testViewShield2 as \n" +
+              "select row_number() over(order by position_id) as rnum, " +
+              "    position_id, " +
+              "    ntile(4) over(order by position_id) " +
+              " from cp.`employee.json`";
+
+      test(view1);
+      test(view2);
+
+      testBuilder()
+          .sqlQuery("select * from TestFunctionsWithTypeExpoQueries_testViewShield1")
+          .ordered()
+          .sqlBaselineQuery("select * from TestFunctionsWithTypeExpoQueries_testViewShield2")
+          .build()
+          .run();
+    } finally {
+      test("drop view TestFunctionsWithTypeExpoQueries_testViewShield1;");
+      test("drop view TestFunctionsWithTypeExpoQueries_testViewShield2;");
+    }
+  }
+
+  @Test
+  public void testLRBTrimOneArg() throws Exception {
+    final String query1 = "SELECT ltrim('drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query2 = "SELECT rtrim('drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query3 = "SELECT btrim('drill') as col FROM cp.`tpch/region.parquet` limit 0";
 
     List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
     TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
@@ -82,18 +114,64 @@ public class TestFunctionsWithTypeExpoQueries extends BaseTestQuery {
   }
 
   @Test
-  public void testExtract() throws Exception {
-    final String query = "select extract(second from time '02:30:45.100') as col \n" +
-        "from cp.`employee.json` limit 0";
+  public void testTrimOneArg() throws Exception {
+    final String query1 = "SELECT trim(leading 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query2 = "SELECT trim(trailing 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query3 = "SELECT trim(both 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+
     List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
     TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
-        .setMinorType(TypeProtos.MinorType.FLOAT8)
-        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .setMinorType(TypeProtos.MinorType.VARCHAR)
+        .setMode(TypeProtos.DataMode.REQUIRED)
         .build();
     expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
 
     testBuilder()
-        .sqlQuery(query)
+        .sqlQuery(query1)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+
+    testBuilder()
+        .sqlQuery(query2)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+
+    testBuilder()
+        .sqlQuery(query3)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testTrimTwoArg() throws Exception {
+    final String query1 = "SELECT trim(leading ' ' from 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query2 = "SELECT trim(trailing ' ' from 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+    final String query3 = "SELECT trim(both ' ' from 'drill') as col FROM cp.`tpch/region.parquet` limit 0";
+
+    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.VARCHAR)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query1)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+
+    testBuilder()
+        .sqlQuery(query2)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+
+    testBuilder()
+        .sqlQuery(query3)
         .schemaBaseLine(expectedSchema)
         .build()
         .run();
@@ -105,7 +183,7 @@ public class TestFunctionsWithTypeExpoQueries extends BaseTestQuery {
     List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
     TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
         .setMinorType(TypeProtos.MinorType.BIT)
-        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .setMode(TypeProtos.DataMode.REQUIRED)
         .build();
     expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
 
@@ -115,4 +193,179 @@ public class TestFunctionsWithTypeExpoQueries extends BaseTestQuery {
         .build()
         .run();
   }
+
+  /**
+   * In the following query, the extract function would be borrowed from Calcite,
+   * which asserts the return type as be BIG-INT
+   */
+  @Test
+  public void testExtractSecond() throws Exception {
+    String query = "select extract(second from time '02:30:45.100') as col \n" +
+        "from cp.`tpch/region.parquet` \n" +
+        "limit 0";
+
+    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.FLOAT8)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testMetaDataExposeType() throws Exception {
+    final String root = FileUtils.getResourceAsFile("/typeExposure/metadata_caching").toURI().toString();
+    final String query = String.format("select count(*) as col \n" +
+        "from dfs_test.`%s` \n" +
+        "where concat(a, 'asdf') = 'asdf'", root);
+
+    // Validate the plan
+    final String[] expectedPlan = {"Scan.*a.parquet.*numFiles=1"};
+    final String[] excludedPlan = {"Filter"};
+    PlanTestBase.testPlanMatchingPatterns(query, expectedPlan, excludedPlan);
+
+    // Validate the result
+    testBuilder()
+        .sqlQuery(query)
+        .ordered()
+        .baselineColumns("col")
+        .baselineValues(1l)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testDate_Part() throws Exception {
+    final String query = "select date_part('year', date '2008-2-23') as col \n" +
+        "from cp.`tpch/region.parquet` \n" +
+        "limit 0";
+
+    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.BIGINT)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testNegativeByInterpreter() throws Exception {
+    final String query = "select * from cp.`tpch/region.parquet` \n" +
+        "where r_regionkey = negative(-1)";
+
+    // Validate the plan
+    final String[] expectedPlan = {"Filter.*condition=\\[=\\(.*, 1\\)\\]\\)"};
+    final String[] excludedPlan = {};
+    PlanTestBase.testPlanMatchingPatterns(query, expectedPlan, excludedPlan);
+  }
+
+  @Test
+  public void testSumRequiredType() throws Exception {
+    final String query = "SELECT \n" +
+        "SUM(CASE WHEN (CAST(n_regionkey AS INT) = 1) THEN 1 ELSE 0 END) AS col \n" +
+        "FROM cp.`tpch/nation.parquet` \n" +
+        "GROUP BY CAST(n_regionkey AS INT) \n" +
+        "limit 0";
+
+    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.BIGINT)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testSQRT() throws Exception {
+    final String query = "SELECT sqrt(5.1) as col \n" +
+        "from cp.`tpch/nation.parquet` \n" +
+        "limit 0";
+
+    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.FLOAT8)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testTimestampDiff() throws Exception {
+    final String query = "select to_timestamp('2014-02-13 00:30:30','YYYY-MM-dd HH:mm:ss') - to_timestamp('2014-02-13 00:30:30','YYYY-MM-dd HH:mm:ss') as col \n" +
+        "from cp.`tpch/region.parquet` \n" +
+        "limit 0";
+
+    final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    final TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.INTERVALDAY)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testAvgAndSUM() throws Exception {
+    final String query = "SELECT AVG(cast(r_regionkey as float)) AS `col1`, \n" +
+        "SUM(cast(r_regionkey as float)) AS `col2`, \n" +
+        "SUM(1) AS `col3` \n" +
+        "FROM cp.`tpch/region.parquet` \n" +
+        "GROUP BY CAST(r_regionkey AS INTEGER) \n" +
+        "LIMIT 0";
+
+    final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
+    final TypeProtos.MajorType majorType1 = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.FLOAT8)
+        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .build();
+
+    final TypeProtos.MajorType majorType2 = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.FLOAT8)
+        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .build();
+
+    final TypeProtos.MajorType majorType3 = TypeProtos.MajorType.newBuilder()
+        .setMinorType(TypeProtos.MinorType.BIGINT)
+        .setMode(TypeProtos.DataMode.REQUIRED)
+        .build();
+
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col1"), majorType1));
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col2"), majorType2));
+    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col3"), majorType3));
+
+    testBuilder()
+        .sqlQuery(query)
+        .schemaBaseLine(expectedSchema)
+        .build()
+        .run();
+  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
index e1ef7c9..0ff789a 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
@@ -56,4 +56,89 @@ public class TestStringFunctions extends BaseTestQuery {
         .build()
         .run();
   }
+
+  @Test
+  public void testLpadTwoArgConvergeToLpad() throws Exception {
+    final String query_1 = "SELECT lpad(r_name, 25) \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+
+    final String query_2 = "SELECT lpad(r_name, 25, ' ') \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+    testBuilder()
+        .sqlQuery(query_1)
+        .unOrdered()
+        .sqlBaselineQuery(query_2)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testRpadTwoArgConvergeToRpad() throws Exception {
+    final String query_1 = "SELECT rpad(r_name, 25) \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+
+    final String query_2 = "SELECT rpad(r_name, 25, ' ') \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+    testBuilder()
+        .sqlQuery(query_1)
+        .unOrdered()
+        .sqlBaselineQuery(query_2)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testLtrimOneArgConvergeToLtrim() throws Exception {
+    final String query_1 = "SELECT ltrim(concat(' ', r_name, ' ')) \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+
+    final String query_2 = "SELECT ltrim(concat(' ', r_name, ' '), ' ') \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+    testBuilder()
+        .sqlQuery(query_1)
+        .unOrdered()
+        .sqlBaselineQuery(query_2)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testRtrimOneArgConvergeToRtrim() throws Exception {
+    final String query_1 = "SELECT rtrim(concat(' ', r_name, ' ')) \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+
+    final String query_2 = "SELECT rtrim(concat(' ', r_name, ' '), ' ') \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+    testBuilder()
+        .sqlQuery(query_1)
+        .unOrdered()
+        .sqlBaselineQuery(query_2)
+        .build()
+        .run();
+  }
+
+  @Test
+  public void testBtrimOneArgConvergeToBtrim() throws Exception {
+    final String query_1 = "SELECT btrim(concat(' ', r_name, ' ')) \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+
+    final String query_2 = "SELECT btrim(concat(' ', r_name, ' '), ' ') \n" +
+        "FROM cp.`tpch/region.parquet`";
+
+    testBuilder()
+        .sqlQuery(query_1)
+        .unOrdered()
+        .sqlBaselineQuery(query_2)
+        .build()
+        .run();
+  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/resources/testframework/testFunctionsWithTypeExpoQueries/testConcatWithMoreThanTwoArgs.tsv
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/testframework/testFunctionsWithTypeExpoQueries/testConcatWithMoreThanTwoArgs.tsv b/exec/java-exec/src/test/resources/testframework/testFunctionsWithTypeExpoQueries/testConcatWithMoreThanTwoArgs.tsv
new file mode 100644
index 0000000..887c45f
--- /dev/null
+++ b/exec/java-exec/src/test/resources/testframework/testFunctionsWithTypeExpoQueries/testConcatWithMoreThanTwoArgs.tsv
@@ -0,0 +1,5 @@
+AFRICAAFRICAAFRICA
+AMERICAAMERICAAMERICA
+ASIAASIAASIA
+EUROPEEUROPEEUROPE
+MIDDLE EASTMIDDLE EASTMIDDLE EAST
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/resources/typeExposure/metadata_caching/a.parquet
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/typeExposure/metadata_caching/a.parquet b/exec/java-exec/src/test/resources/typeExposure/metadata_caching/a.parquet
new file mode 100644
index 0000000..bdbba9e
Binary files /dev/null and b/exec/java-exec/src/test/resources/typeExposure/metadata_caching/a.parquet differ

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/exec/java-exec/src/test/resources/typeExposure/metadata_caching/b.parquet
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/typeExposure/metadata_caching/b.parquet b/exec/java-exec/src/test/resources/typeExposure/metadata_caching/b.parquet
new file mode 100644
index 0000000..f582ca7
Binary files /dev/null and b/exec/java-exec/src/test/resources/typeExposure/metadata_caching/b.parquet differ

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/logical/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java b/logical/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
index 9128a78..982819c 100644
--- a/logical/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
+++ b/logical/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
@@ -62,7 +62,7 @@ public class FunctionCallFactory {
     opToFuncTable.put("u-", "negative");
   }
 
-  private static String replaceOpWithFuncName(String op) {
+  public static String replaceOpWithFuncName(String op) {
     return (opToFuncTable.containsKey(op)) ? (opToFuncTable.get(op)) : op;
   }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/logical/src/main/java/org/apache/drill/common/expression/MajorTypeInLogicalExpression.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/MajorTypeInLogicalExpression.java b/logical/src/main/java/org/apache/drill/common/expression/MajorTypeInLogicalExpression.java
new file mode 100644
index 0000000..5619a69
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/expression/MajorTypeInLogicalExpression.java
@@ -0,0 +1,63 @@
+/**
+ * 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.util.Iterator;
+
+import org.apache.drill.common.expression.visitors.ExprVisitor;
+import org.apache.drill.common.types.TypeProtos;
+
+/**
+ * MajorTypeInLogicalExpression is a LogicalExpression, which wraps a given @{TypeProtos.MajorType}
+ */
+public class MajorTypeInLogicalExpression implements LogicalExpression {
+  private TypeProtos.MajorType majorType;
+
+  public MajorTypeInLogicalExpression(TypeProtos.MajorType majorType) {
+    this.majorType = majorType;
+  }
+
+  @Override
+  public TypeProtos.MajorType getMajorType() {
+    return majorType;
+  }
+
+  @Override
+  public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V value) throws E {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public ExpressionPosition getPosition() {
+    throw new UnsupportedOperationException();
+  }
+
+  public int getSelfCost() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public int getCumulativeCost() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Iterator<LogicalExpression> iterator() {
+    throw new UnsupportedOperationException();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/c0293354/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1379cfe..4dfa682 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1279,7 +1279,7 @@
           <dependency>
             <groupId>org.apache.calcite</groupId>
             <artifactId>calcite-core</artifactId>
-            <version>1.4.0-drill-r10</version>
+            <version>1.4.0-drill-test-r16</version>
             <exclusions>
               <exclusion>
                 <groupId>org.jgrapht</groupId>


Mime
View raw message