You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by am...@apache.org on 2017/05/20 14:26:01 UTC

[2/6] drill git commit: DRILL-5399: Fix race condition in DrillComplexWriterFuncHolder

DRILL-5399: Fix race condition in DrillComplexWriterFuncHolder


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

Branch: refs/heads/master
Commit: 9972669df1a78c3d4e60f93b4295ad35b43207f0
Parents: 2988f71
Author: Volodymyr Vysotskyi <vv...@gmail.com>
Authored: Fri May 12 18:21:10 2017 +0000
Committer: Aman Sinha <as...@maprtech.com>
Committed: Fri May 19 09:51:35 2017 -0700

----------------------------------------------------------------------
 .../drill/exec/expr/fn/HiveFuncHolder.java      | 17 +++-----
 .../drill/exec/expr/DrillFuncHolderExpr.java    | 10 +----
 .../drill/exec/expr/EvaluationVisitor.java      |  2 +-
 .../drill/exec/expr/fn/AbstractFuncHolder.java  | 25 ++++++++++-
 .../drill/exec/expr/fn/DrillAggFuncHolder.java  | 22 +++++-----
 .../expr/fn/DrillComplexWriterFuncHolder.java   | 45 +++++++++-----------
 .../drill/exec/expr/fn/DrillFuncHolder.java     | 11 -----
 .../exec/expr/fn/DrillSimpleFuncHolder.java     | 17 +++++---
 .../impl/flatten/FlattenRecordBatch.java        |  5 +--
 .../impl/project/ProjectRecordBatch.java        | 19 ++++-----
 .../expression/FunctionHolderExpression.java    | 20 ++++++++-
 11 files changed, 104 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFuncHolder.java
----------------------------------------------------------------------
diff --git a/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFuncHolder.java b/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFuncHolder.java
index 0a3cf18..8e7b645 100644
--- a/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFuncHolder.java
+++ b/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFuncHolder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -20,6 +20,7 @@ package org.apache.drill.exec.expr.fn;
 import java.util.List;
 
 import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.types.TypeProtos;
@@ -142,17 +143,11 @@ public class HiveFuncHolder extends AbstractFuncHolder {
     return workspaceJVars;
   }
 
-  /**
-   * Complete code generation
-   * @param g
-   * @param inputVariables
-   * @param workspaceJVars
-   * @return HoldingContainer for return value
-   */
   @Override
-  public HoldingContainer renderEnd(ClassGenerator<?> g, HoldingContainer[] inputVariables, JVar[]  workspaceJVars) {
-    generateSetup(g, workspaceJVars);
-    return generateEval(g, inputVariables, workspaceJVars);
+  public HoldingContainer renderEnd(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables,
+                                    JVar[] workspaceJVars, FieldReference fieldReference) {
+    generateSetup(classGenerator, workspaceJVars);
+    return generateEval(classGenerator, inputVariables, workspaceJVars);
   }
 
   private JInvocation getUDFInstance(JCodeModel m) {

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
index 96b0485..90368c4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -23,9 +23,7 @@ import java.util.List;
 import org.apache.drill.common.expression.ExpressionPosition;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.LogicalExpression;
-import org.apache.drill.common.expression.fn.FuncHolder;
 import org.apache.drill.common.types.TypeProtos.MajorType;
-import org.apache.drill.exec.expr.fn.DrillComplexWriterFuncHolder;
 import org.apache.drill.exec.expr.fn.DrillFuncHolder;
 
 public class DrillFuncHolderExpr extends FunctionHolderExpression implements Iterable<LogicalExpression>{
@@ -49,7 +47,7 @@ public class DrillFuncHolderExpr extends FunctionHolderExpression implements Ite
   }
 
   @Override
-  public FuncHolder getHolder() {
+  public DrillFuncHolder getHolder() {
     return holder;
   }
 
@@ -68,10 +66,6 @@ public class DrillFuncHolderExpr extends FunctionHolderExpression implements Ite
     return holder.isConstant(i);
   }
 
-  public boolean isComplexWriterFuncHolder() {
-    return holder instanceof DrillComplexWriterFuncHolder;
-  }
-
   @Override
   public int getSelfCost() {
     return holder.getCostCategory();

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/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 f299df2..5131772 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
@@ -202,7 +202,7 @@ public class EvaluationVisitor {
         generator.getMappingSet().exitChild();
       }
 
-      return holder.renderEnd(generator, args, workspaceVars);
+      return holder.renderEnd(generator, args, workspaceVars, holderExpr.getFieldReference());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/AbstractFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/AbstractFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/AbstractFuncHolder.java
index 48420ab..4902260 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/AbstractFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/AbstractFuncHolder.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -20,6 +20,7 @@ package org.apache.drill.exec.expr.fn;
 import java.util.List;
 
 import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.fn.FuncHolder;
@@ -37,7 +38,17 @@ public abstract class AbstractFuncHolder implements FuncHolder {
     // default implementation is add no code
   }
 
-  public abstract HoldingContainer renderEnd(ClassGenerator<?> g, HoldingContainer[] inputVariables, JVar[] workspaceJVars);
+  /**
+   * Generate methods body and complete the code generation.
+   *
+   * @param classGenerator the class responsible for code generation
+   * @param inputVariables the source of the vector holders
+   * @param workspaceJVars class fields
+   * @param fieldReference reference of the output field
+   * @return HoldingContainer for return value
+   */
+  public abstract HoldingContainer renderEnd(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables,
+                                             JVar[] workspaceJVars, FieldReference fieldReference);
 
   public boolean isNested() {
     return false;
@@ -48,4 +59,14 @@ public abstract class AbstractFuncHolder implements FuncHolder {
   public abstract MajorType getParmMajorType(int i);
 
   public abstract int getParamCount();
+
+  /**
+   * Checks that the current function holder stores output value
+   * using field writer instead of vector holder.
+   *
+   * @return true if current function holder uses field writer to store the output value
+   */
+  public boolean isComplexWriterFuncHolder() {
+    return false;
+  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
index a52cc16..e1cd96f 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
@@ -20,6 +20,7 @@ package org.apache.drill.exec.expr.fn;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.types.TypeProtos.DataMode;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.common.types.Types;
@@ -125,18 +126,19 @@ class DrillAggFuncHolder extends DrillFuncHolder {
 
 
   @Override
-  public HoldingContainer renderEnd(ClassGenerator<?> g, HoldingContainer[] inputVariables, JVar[]  workspaceJVars) {
-    HoldingContainer out = g.declare(getReturnType(), false);
+  public HoldingContainer renderEnd(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables,
+                                    JVar[] workspaceJVars, FieldReference fieldReference) {
+    HoldingContainer out = classGenerator.declare(getReturnType(), false);
     JBlock sub = new JBlock();
-    g.getEvalBlock().add(sub);
-    JVar internalOutput = sub.decl(JMod.FINAL, g.getHolderType(getReturnType()), getReturnValue().getName(), JExpr._new(g.getHolderType(getReturnType())));
-    addProtectedBlock(g, sub, output(), null, workspaceJVars, false);
+    classGenerator.getEvalBlock().add(sub);
+    JVar internalOutput = sub.decl(JMod.FINAL, classGenerator.getHolderType(getReturnType()), getReturnValue().getName(), JExpr._new(classGenerator.getHolderType(getReturnType())));
+    addProtectedBlock(classGenerator, sub, output(), null, workspaceJVars, false);
     sub.assign(out.getHolder(), internalOutput);
-        //hash aggregate uses workspace vectors. Initialization is done in "setup" and does not require "reset" block.
-        if (!g.getMappingSet().isHashAggMapping()) {
-          generateBody(g, BlockType.RESET, reset(), null, workspaceJVars, false);
-        }
-       generateBody(g, BlockType.CLEANUP, cleanup(), null, workspaceJVars, false);
+    //hash aggregate uses workspace vectors. Initialization is done in "setup" and does not require "reset" block.
+    if (!classGenerator.getMappingSet().isHashAggMapping()) {
+      generateBody(classGenerator, BlockType.RESET, reset(), null, workspaceJVars, false);
+    }
+    generateBody(classGenerator, BlockType.CLEANUP, cleanup(), null, workspaceJVars, false);
 
     return out;
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillComplexWriterFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillComplexWriterFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillComplexWriterFuncHolder.java
index 2488e41..061dd3d 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillComplexWriterFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillComplexWriterFuncHolder.java
@@ -34,56 +34,52 @@ import com.sun.codemodel.JVar;
 
 public class DrillComplexWriterFuncHolder extends DrillSimpleFuncHolder {
 
-  private FieldReference ref;
-
   public DrillComplexWriterFuncHolder(FunctionAttributes functionAttributes, FunctionInitializer initializer) {
     super(functionAttributes, initializer);
   }
 
-  public void setReference(FieldReference ref) {
-    this.ref = ref;
-  }
-
-  public FieldReference getReference() {
-    return ref;
+  @Override
+  public boolean isComplexWriterFuncHolder() {
+    return true;
   }
 
   @Override
-  protected HoldingContainer generateEvalBody(ClassGenerator<?> g, HoldingContainer[] inputVariables, String body, JVar[] workspaceJVars) {
+  protected HoldingContainer generateEvalBody(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables, String body,
+                                              JVar[] workspaceJVars, FieldReference fieldReference) {
 
-    g.getEvalBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", getRegisteredNames()[0]));
+    classGenerator.getEvalBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", getRegisteredNames()[0]));
 
     JBlock sub = new JBlock(true, true);
     JBlock topSub = sub;
 
-    JVar complexWriter = g.declareClassField("complexWriter", g.getModel()._ref(ComplexWriter.class));
+    JVar complexWriter = classGenerator.declareClassField("complexWriter", classGenerator.getModel()._ref(ComplexWriter.class));
 
 
-    JInvocation container = g.getMappingSet().getOutgoing().invoke("getOutgoingContainer");
+    JInvocation container = classGenerator.getMappingSet().getOutgoing().invoke("getOutgoingContainer");
 
     //Default name is "col", if not passed in a reference name for the output vector.
-    String refName = ref == null? "col" : ref.getRootSegment().getPath();
+    String refName = fieldReference == null ? "col" : fieldReference.getRootSegment().getPath();
 
-    JClass cwClass = g.getModel().ref(VectorAccessibleComplexWriter.class);
-    g.getSetupBlock().assign(complexWriter, cwClass.staticInvoke("getWriter").arg(refName).arg(container));
+    JClass cwClass = classGenerator.getModel().ref(VectorAccessibleComplexWriter.class);
+    classGenerator.getSetupBlock().assign(complexWriter, cwClass.staticInvoke("getWriter").arg(refName).arg(container));
 
-    JClass projBatchClass = g.getModel().ref(ProjectRecordBatch.class);
-    JExpression projBatch = JExpr.cast(projBatchClass, g.getMappingSet().getOutgoing());
+    JClass projBatchClass = classGenerator.getModel().ref(ProjectRecordBatch.class);
+    JExpression projBatch = JExpr.cast(projBatchClass, classGenerator.getMappingSet().getOutgoing());
 
-    g.getSetupBlock().add(projBatch.invoke("addComplexWriter").arg(complexWriter));
+    classGenerator.getSetupBlock().add(projBatch.invoke("addComplexWriter").arg(complexWriter));
 
 
-    g.getEvalBlock().add(complexWriter.invoke("setPosition").arg(g.getMappingSet().getValueWriteIndex()));
+    classGenerator.getEvalBlock().add(complexWriter.invoke("setPosition").arg(classGenerator.getMappingSet().getValueWriteIndex()));
 
-    sub.decl(g.getModel()._ref(ComplexWriter.class), getReturnValue().getName(), complexWriter);
+    sub.decl(classGenerator.getModel()._ref(ComplexWriter.class), getReturnValue().getName(), complexWriter);
 
     // add the subblock after the out declaration.
-    g.getEvalBlock().add(topSub);
+    classGenerator.getEvalBlock().add(topSub);
 
-    addProtectedBlock(g, sub, body, inputVariables, workspaceJVars, false);
+    addProtectedBlock(classGenerator, sub, body, inputVariables, workspaceJVars, false);
 
 
-//    JConditional jc = g.getEvalBlock()._if(complexWriter.invoke("ok").not());
+//    JConditional jc = classGenerator.getEvalBlock()._if(complexWriter.invoke("ok").not());
 
 //    jc._then().add(complexWriter.invoke("reset"));
     //jc._then().directStatement("System.out.println(\"debug : write ok fail!, inIndex = \" + inIndex);");
@@ -91,9 +87,8 @@ public class DrillComplexWriterFuncHolder extends DrillSimpleFuncHolder {
 
     //jc._else().directStatement("System.out.println(\"debug : write successful, inIndex = \" + inIndex);");
 
-    g.getEvalBlock().directStatement(String.format("//---- end of eval portion of %s function. ----//", getRegisteredNames()[0]));
+    classGenerator.getEvalBlock().directStatement(String.format("//---- end of eval portion of %s function. ----//", getRegisteredNames()[0]));
 
     return null;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
index b25aa43..9df5305 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
@@ -85,17 +85,6 @@ public abstract class DrillFuncHolder extends AbstractFuncHolder {
   }
 
   @Override
-  public void renderMiddle(ClassGenerator<?> g, HoldingContainer[] inputVariables, JVar[] workspaceJVars) {
-  }
-
-  @Override
-  public abstract HoldingContainer renderEnd(ClassGenerator<?> g, HoldingContainer[] inputVariables,
-      JVar[] workspaceJVars);
-
-  @Override
-  public abstract boolean isNested();
-
-  @Override
   public FunctionHolderExpression getExpr(String name, List<LogicalExpression> args, ExpressionPosition pos) {
     return new DrillFuncHolderExpr(name, this, args, pos);
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
index 8f0591f..30e9281 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.sun.codemodel.JOp;
 import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.types.TypeProtos.DataMode;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.exec.expr.ClassGenerator;
@@ -73,22 +74,24 @@ public class DrillSimpleFuncHolder extends DrillFuncHolder {
   }
 
   @Override
-  public HoldingContainer renderEnd(ClassGenerator<?> g, HoldingContainer[] inputVariables, JVar[]  workspaceJVars){
+  public HoldingContainer renderEnd(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables,
+                                    JVar[] workspaceJVars, FieldReference fieldReference) {
     //If the function's annotation specifies a parameter has to be constant expression, but the HoldingContainer
     //for the argument is not, then raise exception.
-    for (int i =0; i < inputVariables.length; i++) {
+    for (int i = 0; i < inputVariables.length; i++) {
       if (getParameters()[i].isConstant() && !inputVariables[i].isConstant()) {
         throw new DrillRuntimeException(String.format("The argument '%s' of Function '%s' has to be constant!", getParameters()[i].getName(), this.getRegisteredNames()[0]));
       }
     }
-    generateBody(g, BlockType.SETUP, setupBody(), inputVariables, workspaceJVars, true);
-    HoldingContainer c = generateEvalBody(g, inputVariables, evalBody(), workspaceJVars);
-    generateBody(g, BlockType.RESET, resetBody(), null, workspaceJVars, false);
-    generateBody(g, BlockType.CLEANUP, cleanupBody(), null, workspaceJVars, false);
+    generateBody(classGenerator, BlockType.SETUP, setupBody(), inputVariables, workspaceJVars, true);
+    HoldingContainer c = generateEvalBody(classGenerator, inputVariables, evalBody(), workspaceJVars, fieldReference);
+    generateBody(classGenerator, BlockType.RESET, resetBody(), null, workspaceJVars, false);
+    generateBody(classGenerator, BlockType.CLEANUP, cleanupBody(), null, workspaceJVars, false);
     return c;
   }
 
-  protected HoldingContainer generateEvalBody(ClassGenerator<?> g, HoldingContainer[] inputVariables, String body, JVar[] workspaceJVars) {
+  protected HoldingContainer generateEvalBody(ClassGenerator<?> g, HoldingContainer[] inputVariables, String body,
+                                              JVar[] workspaceJVars, FieldReference ref) {
 
     g.getEvalBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", getRegisteredNames()[0]));
 

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/flatten/FlattenRecordBatch.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/flatten/FlattenRecordBatch.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/flatten/FlattenRecordBatch.java
index fda00f8..8fd9441 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/flatten/FlattenRecordBatch.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/flatten/FlattenRecordBatch.java
@@ -38,7 +38,6 @@ import org.apache.drill.exec.expr.ExpressionTreeMaterializer;
 import org.apache.drill.exec.expr.TypeHelper;
 import org.apache.drill.exec.expr.ValueVectorReadExpression;
 import org.apache.drill.exec.expr.ValueVectorWriteExpression;
-import org.apache.drill.exec.expr.fn.DrillComplexWriterFuncHolder;
 import org.apache.drill.exec.ops.FragmentContext;
 import org.apache.drill.exec.physical.config.FlattenPOP;
 import org.apache.drill.exec.record.AbstractSingleRecordBatch;
@@ -353,7 +352,7 @@ public class FlattenRecordBatch extends AbstractSingleRecordBatch<FlattenPOP> {
         throw new SchemaChangeException(String.format("Failure while trying to materialize incoming schema.  Errors:\n %s.", collector.toErrorString()));
       }
       if (expr instanceof DrillFuncHolderExpr &&
-          ((DrillFuncHolderExpr) expr).isComplexWriterFuncHolder())  {
+          ((DrillFuncHolderExpr) expr).getHolder().isComplexWriterFuncHolder()) {
         // Need to process ComplexWriter function evaluation.
         // Lazy initialization of the list of complex writers, if not done yet.
         if (complexWriters == null) {
@@ -361,7 +360,7 @@ public class FlattenRecordBatch extends AbstractSingleRecordBatch<FlattenPOP> {
         }
 
         // The reference name will be passed to ComplexWriter, used as the name of the output vector from the writer.
-        ((DrillComplexWriterFuncHolder) ((DrillFuncHolderExpr) expr).getHolder()).setReference(namedExpression.getRef());
+        ((DrillFuncHolderExpr) expr).getFieldReference(namedExpression.getRef());
         cg.addExpr(expr);
       } else {
         // need to do evaluation.

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectRecordBatch.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectRecordBatch.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectRecordBatch.java
index a35e3f1..676849a 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectRecordBatch.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectRecordBatch.java
@@ -47,7 +47,6 @@ import org.apache.drill.exec.expr.DrillFuncHolderExpr;
 import org.apache.drill.exec.expr.ExpressionTreeMaterializer;
 import org.apache.drill.exec.expr.ValueVectorReadExpression;
 import org.apache.drill.exec.expr.ValueVectorWriteExpression;
-import org.apache.drill.exec.expr.fn.DrillComplexWriterFuncHolder;
 import org.apache.drill.exec.ops.FragmentContext;
 import org.apache.drill.exec.physical.config.Project;
 import org.apache.drill.exec.planner.StarColumnHelper;
@@ -76,7 +75,7 @@ public class ProjectRecordBatch extends AbstractSingleRecordBatch<Project> {
   private Projector projector;
   private List<ValueVector> allocationVectors;
   private List<ComplexWriter> complexWriters;
-  private List<DrillComplexWriterFuncHolder> complexExprList;
+  private List<FieldReference> complexFieldReferencesList;
   private boolean hasRemainder = false;
   private int remainderIndex = 0;
   private int recordCount;
@@ -165,8 +164,8 @@ public class ProjectRecordBatch extends AbstractSingleRecordBatch<Project> {
 
             // Only need to add the schema for the complex exprs because others should already have
             // been setup during setupNewSchema
-            for (DrillComplexWriterFuncHolder f : complexExprList) {
-              container.addOrGet(f.getReference().getRootSegment().getPath(),
+            for (FieldReference fieldReference : complexFieldReferencesList) {
+              container.addOrGet(fieldReference.getRootSegment().getPath(),
                   Types.required(MinorType.MAP), MapVector.class);
             }
             container.buildSchema(SelectionVectorMode.NONE);
@@ -443,7 +442,7 @@ public class ProjectRecordBatch extends AbstractSingleRecordBatch<Project> {
         transfers.add(tp);
         transferFieldIds.add(vectorRead.getFieldId().getFieldIds()[0]);
       } else if (expr instanceof DrillFuncHolderExpr &&
-          ((DrillFuncHolderExpr) expr).isComplexWriterFuncHolder())  {
+          ((DrillFuncHolderExpr) expr).getHolder().isComplexWriterFuncHolder()) {
         // Need to process ComplexWriter function evaluation.
         // Lazy initialization of the list of complex writers, if not done yet.
         if (complexWriters == null) {
@@ -453,13 +452,13 @@ public class ProjectRecordBatch extends AbstractSingleRecordBatch<Project> {
         }
 
         // The reference name will be passed to ComplexWriter, used as the name of the output vector from the writer.
-        ((DrillComplexWriterFuncHolder) ((DrillFuncHolderExpr) expr).getHolder()).setReference(namedExpression.getRef());
+        ((DrillFuncHolderExpr) expr).getFieldReference(namedExpression.getRef());
         cg.addExpr(expr, ClassGenerator.BlkCreateMode.TRUE_IF_BOUND);
-        if (complexExprList == null) {
-          complexExprList = Lists.newArrayList();
+        if (complexFieldReferencesList == null) {
+          complexFieldReferencesList = Lists.newArrayList();
         }
-        // save the expr for later for getting schema when input is empty
-        complexExprList.add((DrillComplexWriterFuncHolder)((DrillFuncHolderExpr)expr).getHolder());
+        // save the field reference for later for getting schema when input is empty
+        complexFieldReferencesList.add(namedExpression.getRef());
       } else {
         // need to do evaluation.
         final ValueVector vector = container.addOrGet(outputField, callBack);

http://git-wip-us.apache.org/repos/asf/drill/blob/9972669d/logical/src/main/java/org/apache/drill/common/expression/FunctionHolderExpression.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/FunctionHolderExpression.java b/logical/src/main/java/org/apache/drill/common/expression/FunctionHolderExpression.java
index d5497f7..ecb0ae6 100644
--- a/logical/src/main/java/org/apache/drill/common/expression/FunctionHolderExpression.java
+++ b/logical/src/main/java/org/apache/drill/common/expression/FunctionHolderExpression.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -29,6 +29,12 @@ public abstract class FunctionHolderExpression extends LogicalExpressionBase {
   public final ImmutableList<LogicalExpression> args;
   public final String nameUsed;
 
+  /**
+   * A field reference identifies the output field and
+   * is used to reference that field in the generated classes.
+   */
+  private FieldReference fieldReference;
+
   public FunctionHolderExpression(String nameUsed, ExpressionPosition pos, List<LogicalExpression> args) {
     super(pos);
     if (args == null) {
@@ -80,4 +86,16 @@ public abstract class FunctionHolderExpression extends LogicalExpressionBase {
   /** Return the underlying function implementation holder. */
   public abstract FuncHolder getHolder();
 
+  public FieldReference getFieldReference() {
+    return fieldReference;
+  }
+
+  /**
+   * Set the FieldReference to be used during generating code.
+   *
+   * @param fieldReference FieldReference to set.
+   */
+  public void getFieldReference(FieldReference fieldReference) {
+    this.fieldReference = fieldReference;
+  }
 }