DRILL-429: Remove extraneous casts.

Change cast from a function call to a new, separate type of expression.
Add test to confirm functionality.


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/30ce7d71
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/30ce7d71
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/30ce7d71

Branch: refs/heads/master
Commit: 30ce7d710a1bb876a272fd454ff286b5909ff717
Parents: 822cbb0
Author: Jacques Nadeau <[email protected]>
Authored: Sat Mar 22 11:50:31 2014 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Sat Mar 22 11:50:31 2014 -0700

----------------------------------------------------------------------
 .../drill/common/expression/CastExpression.java | 65 +++++++++++++++
 .../expression/ExpressionStringBuilder.java     | 56 +++++++++++++
 .../common/expression/FunctionCallFactory.java  | 12 +--
 .../visitors/AbstractExprVisitor.java           |  6 ++
 .../expression/visitors/AggregateChecker.java   |  6 ++
 .../expression/visitors/ConstantChecker.java    |  6 ++
 .../common/expression/visitors/ExprVisitor.java |  7 +-
 .../visitors/ExpressionValidator.java           |  6 ++
 .../sig/ConstantExpressionIdentifier.java       |  7 ++
 .../drill/exec/expr/EvaluationVisitor.java      | 24 +++++-
 .../exec/expr/ExpressionTreeMaterializer.java   | 85 +++++++++++++++++++-
 .../drill/exec/planner/logical/DrillOptiq.java  | 32 ++++----
 .../drill/exec/rpc/RpcExceptionHandler.java     |  2 +-
 .../apache/drill/jdbc/test/TestJdbcQuery.java   |  1 -
 14 files changed, 280 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/CastExpression.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/CastExpression.java 
b/common/src/main/java/org/apache/drill/common/expression/CastExpression.java
new file mode 100644
index 0000000..7e5eea0
--- /dev/null
+++ 
b/common/src/main/java/org/apache/drill/common/expression/CastExpression.java
@@ -0,0 +1,65 @@
+/**
+ * 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.Collections;
+import java.util.Iterator;
+
+import org.apache.drill.common.expression.visitors.ExprVisitor;
+import org.apache.drill.common.types.TypeProtos.MajorType;
+
+public class CastExpression extends LogicalExpressionBase implements 
Iterable<LogicalExpression>{
+  
+  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(CastExpression.class);
+  
+  private final LogicalExpression input;
+  private final MajorType type;
+  
+  public CastExpression(LogicalExpression input, MajorType type, 
ExpressionPosition pos) {
+    super(pos);
+    this.input = input;
+    this.type = type;
+  }
+
+  @Override
+  public <T, V, E extends Exception> T accept(ExprVisitor<T, V, E> visitor, V 
value) throws E {
+    return visitor.visitCastExpression(this, value);
+  }
+
+  @Override
+  public Iterator<LogicalExpression> iterator() {
+    return Collections.singleton(input).iterator();
+  }
+
+  public LogicalExpression getInput() {
+    return input;
+  }
+
+  @Override
+  public MajorType getMajorType() {
+    return type;
+  }
+
+  @Override
+  public String toString() {
+    return "CastExpression [input=" + input + ", type=" + type + "]";
+  }
+
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
index 80dfbac..80fd41b 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
@@ -20,9 +20,12 @@ package org.apache.drill.common.expression;
 import org.apache.drill.common.expression.IfExpression.IfCondition;
 import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
 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.LongExpression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.drill.common.types.TypeProtos.MajorType;
 
 import com.google.common.collect.ImmutableList;
 
@@ -96,6 +99,59 @@ public class ExpressionStringBuilder extends 
AbstractExprVisitor<Void, StringBui
     sb.append("\"");
     return null;
   }
+
+  @Override
+  public Void visitCastExpression(CastExpression e, StringBuilder sb) throws 
RuntimeException {
+    MajorType mt = e.getMajorType();
+    
+    sb.append("cast( (");
+    e.getInput().accept(this, sb);
+    sb.append(" ) as ");
+    sb.append(mt.getMinorType().name());
+    
+    switch(mt.getMinorType()){
+    case FLOAT4:
+    case FLOAT8:
+    case INT:
+    case SMALLINT:
+    case BIGINT:
+    case UINT1:
+    case UINT2:
+    case UINT4:
+    case UINT8:
+      // do nothing else.
+      break;
+    case VAR16CHAR:
+    case VARBINARY:
+    case VARCHAR:
+    case FIXED16CHAR:
+    case FIXEDBINARY:
+    case FIXEDCHAR:
+      // add size in parens
+      sb.append("(");
+      sb.append(mt.getWidth());
+      sb.append(")");
+      break;
+    default:
+      throw new UnsupportedOperationException(String.format("Unable to convert 
cast expression %s into string.", e));
+    }
+    sb.append(" )");
+    return null;
+  }
+
+  @Override
+  public Void visitFloatConstant(FloatExpression fExpr, StringBuilder sb) 
throws RuntimeException {
+    sb.append(fExpr.getFloat());
+    return null;
+  }
+
+  @Override
+  public Void visitIntConstant(IntExpression intExpr, StringBuilder sb) throws 
RuntimeException {
+    sb.append(intExpr.getInt());
+    return null;
+  }
+  
+  
   
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
 
b/common/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
index df4fcb7..c6c7074 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/FunctionCallFactory.java
@@ -72,17 +72,7 @@ public class FunctionCallFactory {
    *             expr -- input expression
    */
   public static LogicalExpression createCast(MajorType type, 
ExpressionPosition ep, LogicalExpression expr){
-    String castFuncWithType = "cast" + type.getMinorType().name();
-
-    List<LogicalExpression> newArgs = Lists.newArrayList();
-    newArgs.add(expr);  //input_expr
-
-    //VarLen type
-    if (!Types.isFixedWidthType(type)) {
-      newArgs.add(new ValueExpressions.LongExpression(type.getWidth(), null));
-    }
-
-    return new FunctionCall(castFuncWithType, newArgs, ep);
+    return new CastExpression(expr, type, ep);
   }
 
   public static LogicalExpression createExpression(String functionName, 
List<LogicalExpression> args){

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
index ef96cab..727a3dc 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/AbstractExprVisitor.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -83,6 +84,11 @@ public abstract class AbstractExprVisitor<T, VAL, EXCEP 
extends Exception> imple
   }
 
   @Override
+  public T visitCastExpression(CastExpression 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/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
index 71ac82e..630d00a 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/AggregateChecker.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -111,6 +112,11 @@ public final class AggregateChecker extends 
SimpleExprVisitor<Boolean>{
   public Boolean visitUnknown(LogicalExpression e, Void value) throws 
RuntimeException {
     return false;
   }
+
+  @Override
+  public Boolean visitCastExpression(CastExpression e, Void value) throws 
RuntimeException {
+    return e.getInput().accept(this, value);
+  }
        
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
index 1391c84..60e997f 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.ErrorCollector;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
@@ -115,4 +116,9 @@ final class ConstantChecker implements ExprVisitor<Boolean, 
ErrorCollector, Runt
     return false;
   }
 
+  @Override
+  public Boolean visitCastExpression(CastExpression e, ErrorCollector value) 
throws RuntimeException {
+    return e.getInput().accept(this, value);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
index 10b0acf..e199f21 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExprVisitor.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -24,10 +25,10 @@ import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
 import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
-import org.apache.drill.common.expression.ValueExpressions.LongExpression;
-import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
 import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 
 
 public interface ExprVisitor<T, VAL, EXCEP extends Exception> {
@@ -42,4 +43,6 @@ public interface ExprVisitor<T, VAL, EXCEP extends Exception> 
{
   public T visitBooleanConstant(BooleanExpression e, VAL value) throws EXCEP;
   public T visitQuotedStringConstant(QuotedString e, VAL value) throws EXCEP;
   public T visitUnknown(LogicalExpression e, VAL value) throws EXCEP;
+  public T visitCastExpression(CastExpression e, VAL value) throws EXCEP;
+  
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
index 396517a..96666bd 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.ErrorCollector;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
@@ -137,4 +138,9 @@ public class ExpressionValidator implements 
ExprVisitor<Void, ErrorCollector, Ru
     return null;
   }
 
+  @Override
+  public Void visitCastExpression(CastExpression e, ErrorCollector value) 
throws RuntimeException {
+    return e.accept(this, value);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
index fbb7cc8..e476897 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
@@ -22,6 +22,7 @@ import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -139,6 +140,12 @@ public class ConstantExpressionIdentifier implements 
ExprVisitor<Boolean, Identi
   }
 
   @Override
+  public Boolean visitCastExpression(CastExpression e, 
IdentityHashMap<LogicalExpression, Object> value)
+      throws RuntimeException {
+    return e.getInput().accept(this, value);
+  }
+
+  @Override
   public Boolean visitUnknown(LogicalExpression e, 
IdentityHashMap<LogicalExpression, Object> value){
     return checkChildren(e, value, false);
   }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
index c7f7336..8dfba76 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
@@ -17,9 +17,10 @@
  */
 package org.apache.drill.exec.expr;
 
-import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -27,6 +28,7 @@ import 
org.apache.drill.common.expression.IfExpression.IfCondition;
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.expression.TypedNullConstant;
+import org.apache.drill.common.expression.ValueExpressions;
 import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
 import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
 import org.apache.drill.common.expression.ValueExpressions.LongExpression;
@@ -35,10 +37,9 @@ import 
org.apache.drill.common.expression.visitors.AbstractExprVisitor;
 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.exec.compile.sig.ConstantExpressionIdentifier;
 import org.apache.drill.exec.expr.ClassGenerator.BlockType;
 import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
-import org.apache.drill.exec.compile.sig.ConstantExpressionIdentifier;
 import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
 import org.apache.drill.exec.expr.fn.HiveFuncHolder;
@@ -46,6 +47,7 @@ import 
org.apache.drill.exec.physical.impl.filter.ReturnValueExpression;
 import org.apache.drill.exec.record.NullExpression;
 import org.apache.drill.exec.vector.ValueHolderHelper;
 
+import com.google.common.collect.Lists;
 import com.sun.codemodel.JBlock;
 import com.sun.codemodel.JClass;
 import com.sun.codemodel.JConditional;
@@ -317,6 +319,22 @@ public class EvaluationVisitor {
       setup.assign(var, 
((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getVarCharHolder").arg(stringLiteral));
       return new HoldingContainer(majorType, var, null, null);
     }
+
+    @Override
+    public HoldingContainer visitCastExpression(CastExpression e, 
ClassGenerator<?> value) throws RuntimeException {
+      // we create
+      MajorType type = e.getMajorType();
+      String castFuncWithType = "cast" + type.getMinorType().name();
+
+      List<LogicalExpression> newArgs = Lists.newArrayList();
+      newArgs.add(e.getInput());  //input_expr
+
+      //VarLen type
+      if (!Types.isFixedWidthType(type)) {
+        newArgs.add(new ValueExpressions.LongExpression(type.getWidth(), 
null));
+      }
+      FunctionCall fc = new FunctionCall(castFuncWithType, newArgs, 
e.getPosition());
+      return fc.accept(this, value);    }
   }
 
   private class ConstantFilter extends EvalVisitor {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index def54d9..f764d32 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -19,6 +19,7 @@ package org.apache.drill.exec.expr;
 
 import java.util.List;
 
+import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.ErrorCollector;
 import org.apache.drill.common.expression.ExpressionPosition;
 import org.apache.drill.common.expression.FunctionCall;
@@ -27,6 +28,7 @@ import org.apache.drill.common.expression.IfExpression;
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.expression.TypedNullConstant;
+import org.apache.drill.common.expression.ValueExpressions;
 import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
 import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
 import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
@@ -37,6 +39,7 @@ import org.apache.drill.common.expression.fn.CastFunctions;
 import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
 import org.apache.drill.common.expression.visitors.ExpressionValidator;
 import org.apache.drill.common.types.TypeProtos;
+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.exec.expr.annotations.FunctionTemplate;
@@ -90,8 +93,8 @@ public class ExpressionTreeMaterializer {
 
     @Override
     public LogicalExpression 
visitFunctionHolderExpression(FunctionHolderExpression holder, 
FunctionImplementationRegistry value) throws RuntimeException {
-      throw new UnsupportedOperationException(
-        String.format("Can't support materialize %s", 
holder.getClass().getCanonicalName()));
+      // a function holder is already materialized, no need to rematerialize.  
generally this won't be used unless we materialize a partial tree and 
rematerialize the whole tree.
+      return holder;
     }
 
     @Override
@@ -242,5 +245,83 @@ public class ExpressionTreeMaterializer {
     public LogicalExpression visitQuotedStringConstant(QuotedString e, 
FunctionImplementationRegistry registry) {
       return e;
     }
+
+    @Override
+    public LogicalExpression visitCastExpression(CastExpression e, 
FunctionImplementationRegistry value){
+      
+      // if the cast is pointless, remove it.
+      LogicalExpression input = e.getInput().accept(this,  value);
+
+      MajorType newMajor = e.getMajorType();
+      MinorType newMinor = input.getMajorType().getMinorType();
+      
+      if(castEqual(e.getPosition(), newMajor, input.getMajorType())) return 
input; // don't do pointless cast.
+      
+      
+      if(newMinor == MinorType.LATE || newMinor == MinorType.NULL){
+        // if the type still isn't fully bound, leave as cast expression.
+        return new CastExpression(input, e.getMajorType(), e.getPosition());
+      }else{
+        // if the type is fully bound, convert to functioncall and materialze 
the function.
+        MajorType type = e.getMajorType();
+        String castFuncWithType = "cast" + type.getMinorType().name();
+
+        List<LogicalExpression> newArgs = Lists.newArrayList();
+        newArgs.add(e.getInput());  //input_expr
+
+        //VarLen type
+        if (!Types.isFixedWidthType(type)) {
+          newArgs.add(new ValueExpressions.LongExpression(type.getWidth(), 
null));
+        }
+        FunctionCall fc = new FunctionCall(castFuncWithType, newArgs, 
e.getPosition());
+        return fc.accept(this, value);   
+      }
+      
+      
+      
+    }
+  
+  private boolean castEqual(ExpressionPosition pos, MajorType from, MajorType 
to){
+    if(!from.getMinorType().equals(to.getMinorType())) return false;
+    switch(from.getMinorType()){
+    case FLOAT4:
+    case FLOAT8:
+    case INT:
+    case BIGINT:
+    case BIT:
+    case TINYINT:
+    case UINT1:
+    case UINT2:
+    case UINT4:
+    case UINT8:      
+      // nothing else matters.
+      return true;
+     
+    case FIXED16CHAR:
+    case FIXEDBINARY:
+    case FIXEDCHAR:
+      // width always matters
+      this.errorCollector.addGeneralError(pos, "Casting fixed width types are 
not yet supported..");
+      return false;
+      
+    case VAR16CHAR:
+    case VARBINARY:
+    case VARCHAR:
+      if(to.getWidth() < from.getWidth() && to.getWidth() > 0){
+        this.errorCollector.addGeneralError(pos, "Casting from a longer 
variable length type to a shorter variable length type is not currently 
supported.");
+        return false;
+      }else{
+        return true;
+      }
+
+    default:
+      errorCollector.addGeneralError(pos, String.format("Casting rules are 
unknown for type %s.", from));
+      return false;
+    
+    }
+
   }
+  
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
index b39b230..7398d78 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
@@ -21,16 +21,17 @@ import java.math.BigDecimal;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.drill.common.expression.ExpressionPosition;
 import org.apache.drill.common.expression.FieldReference;
-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.SchemaPath;
 import org.apache.drill.common.expression.ValueExpressions;
-import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+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.exec.record.NullExpression;
 import org.eigenbase.rel.RelNode;
-import org.eigenbase.relopt.RelOptPlanner;
 import org.eigenbase.reltype.RelDataTypeField;
 import org.eigenbase.rex.RexCall;
 import org.eigenbase.rex.RexCorrelVariable;
@@ -45,9 +46,9 @@ import org.eigenbase.rex.RexRangeRef;
 import org.eigenbase.rex.RexVisitorImpl;
 import org.eigenbase.sql.SqlSyntax;
 import org.eigenbase.sql.fun.SqlStdOperatorTable;
+import org.eigenbase.util.NlsString;
 
 import com.google.common.collect.Lists;
-import org.eigenbase.util.NlsString;
 
 /**
  * Utilities for Drill's planner.
@@ -163,20 +164,21 @@ public class DrillOptiq {
 
     private LogicalExpression getDrillCastFunctionFromOptiq(RexCall call){
       LogicalExpression arg = call.getOperands().get(0).accept(this);
-      List<LogicalExpression> args = Collections.singletonList(arg);
-      String fname = null;
+      MajorType castType = null;
+      
       switch(call.getType().getSqlTypeName().getName()){
-      case "VARCHAR": {
-        args = Lists.newArrayList(arg, new 
LongExpression(call.getType().getPrecision()));
-        return FunctionCallFactory.createExpression("castVARCHAR", args);
-      }
-      case "INTEGER": fname = "castINT"; break;
-      case "FLOAT": fname = "castFLOAT4"; break;
-      case "DOUBLE": fname = "castFLOAT8"; break;
+      case "VARCHAR": 
+        castType = 
Types.required(MinorType.VARCHAR).toBuilder().setWidth(call.getType().getPrecision()).build();
+        break;
+      
+      case "INTEGER": castType = Types.required(MinorType.INT); break;
+      case "FLOAT": Types.required(MinorType.FLOAT4); break;
+      case "DOUBLE": Types.required(MinorType.FLOAT8); break;
       case "DECIMAL": throw new UnsupportedOperationException("Need to add 
decimal.");
-      default: fname = "cast" + call.getType().getSqlTypeName().getName();
+      default: castType = 
Types.required(MinorType.valueOf(call.getType().getSqlTypeName().getName()));
       }
-      return FunctionCallFactory.createExpression(fname, args);
+      
+      return FunctionCallFactory.createCast(castType, 
ExpressionPosition.UNKNOWN, arg);
 
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/RpcExceptionHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/RpcExceptionHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/RpcExceptionHandler.java
index 42f733b..ee42ee5 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/RpcExceptionHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/RpcExceptionHandler.java
@@ -30,7 +30,7 @@ public class RpcExceptionHandler implements ChannelHandler{
   @Override
   public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
throws Exception {
     
-    if(!ctx.channel().isOpen()){
+    if(!ctx.channel().isOpen() || cause.getMessage().equals("Connection reset 
by peer")){
       logger.warn("Exception with closed channel", cause);
       return;
     }else{

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/30ce7d71/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
----------------------------------------------------------------------
diff --git 
a/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java 
b/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
index 8ea758d..21de9f4 100644
--- a/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
+++ b/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
@@ -101,7 +101,6 @@ public class TestJdbcQuery {
   }
 
   @Test
-  @Ignore // failing due to a bug in cast to varchar function
   public void testVarCharLiteral() throws Exception {
     testQuery(String.format("select cast('test literal' as VARCHAR) from 
INFORMATION_SCHEMA.TABLES LIMIT 1"));
   }

Reply via email to