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/04/18 02:05:53 UTC

[3/3] drill git commit: Test-specific column accessor implementation. Provides a simplified, unified set of access methods for value vectors specifically for wrting simple, compact unit test code.

Test-specific column accessor implementation. Provides a simplified, unified set of access methods for value vectors specifically for wrting simple, compact unit test code.

* Interfaces for column readers and writers
* Interfaces for tuple (row and map) readers and writers
* Generated implementations
* Base implementation used by the generated code
* Factory class to create the proper reader or writer given a major
type (type and cardinality)
* Utilities for generic access, type conversions, etc.

Many vector types can be mapped to an int for get and set. One key
exception are the decimal types: decimals, by definition, require a
different representation. In Java, that is `BigDecimal`. Added get, set
and setSafe accessors as required for each decimal type that uses
`BigDecimal` to hold data.

The generated code builds on the `valueVectorTypes.tdd` file, adding
additional properties needed to generate the accessors.

The PR also includes a number of code cleanups done while reviewing
existing code. In particular `DecimalUtility` was very roughly
formatted and thus hard to follow.

Supports Drill\u2019s interval types (INTERVAL, INTERVALDAY,
INTERVALYEAR) in the form of the Joda interval class.

Adds support for Map vectors. Maps are treated as nested tuples and are
expanded out to create a flattened row in the schema. The accessors
then access rows using the flattened column index or the combined name
(\u201ca.b\u201d).

Supports arrays via a writer interface that appends values as written,
and an indexed, random-access reader interface.

Removed HTTP log parser from JDBC jar to keep the JDBC jar from getting
too big.

close apache/drill#783


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

Branch: refs/heads/master
Commit: 381eab668480062471f5bd3897a04a4b322f5d9a
Parents: 72903d0
Author: Paul Rogers <pr...@maprtech.com>
Authored: Fri Mar 10 23:03:23 2017 -0800
Committer: Aman Sinha <as...@maprtech.com>
Committed: Mon Apr 17 09:57:49 2017 -0700

----------------------------------------------------------------------
 exec/jdbc-all/pom.xml                           |   4 +
 .../src/main/codegen/data/ValueVectorTypes.tdd  |  61 +-
 .../src/main/codegen/includes/license.ftl       |   5 +-
 .../src/main/codegen/includes/vv_imports.ftl    |  24 +-
 .../codegen/templates/AbstractFieldReader.java  |  34 +-
 .../main/codegen/templates/ColumnAccessors.java | 331 ++++++++
 .../codegen/templates/FixedValueVectors.java    | 301 +++----
 .../codegen/templates/NullableValueVectors.java |  40 +-
 .../codegen/templates/RepeatedValueVectors.java |  40 +-
 .../templates/VariableLengthVectors.java        |   2 +-
 .../drill/exec/record/MaterializedField.java    |  59 +-
 .../apache/drill/exec/util/DecimalUtility.java  | 803 ++++++++++---------
 .../drill/exec/vector/BaseValueVector.java      |   2 -
 .../exec/vector/accessor/AccessorUtilities.java | 125 +++
 .../drill/exec/vector/accessor/ArrayReader.java |  52 ++
 .../drill/exec/vector/accessor/ArrayWriter.java |  42 +
 .../exec/vector/accessor/ColumnAccessor.java    |  40 +
 .../exec/vector/accessor/ColumnReader.java      |  63 ++
 .../exec/vector/accessor/ColumnWriter.java      |  45 ++
 .../exec/vector/accessor/ScalarWriter.java      |  37 +
 .../exec/vector/accessor/TupleAccessor.java     |  59 ++
 .../drill/exec/vector/accessor/TupleReader.java |  33 +
 .../drill/exec/vector/accessor/TupleWriter.java |  34 +
 .../accessor/impl/AbstractArrayReader.java      | 128 +++
 .../accessor/impl/AbstractArrayWriter.java      | 127 +++
 .../accessor/impl/AbstractColumnAccessor.java   |  43 +
 .../accessor/impl/AbstractColumnReader.java     |  98 +++
 .../accessor/impl/AbstractColumnWriter.java     |  87 ++
 .../accessor/impl/AbstractTupleAccessor.java    |  38 +
 .../accessor/impl/ColumnAccessorFactory.java    | 122 +++
 .../vector/accessor/impl/TupleReaderImpl.java   | 108 +++
 .../vector/accessor/impl/TupleWriterImpl.java   | 162 ++++
 .../exec/vector/accessor/impl/package-info.java |  27 +
 .../exec/vector/accessor/package-info.java      | 127 +++
 .../vector/complex/BaseRepeatedValueVector.java |   4 +
 .../exec/vector/complex/RepeatedMapVector.java  |   1 -
 36 files changed, 2631 insertions(+), 677 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/jdbc-all/pom.xml
----------------------------------------------------------------------
diff --git a/exec/jdbc-all/pom.xml b/exec/jdbc-all/pom.xml
index 1b015e9..17af111 100644
--- a/exec/jdbc-all/pom.xml
+++ b/exec/jdbc-all/pom.xml
@@ -143,6 +143,10 @@
           <artifactId>hazelcast</artifactId>
           <groupId>com.hazelcast</groupId>
         </exclusion>
+        <exclusion>
+	      <groupId>nl.basjes.parse.httpdlog</groupId>
+	      <artifactId>httpdlog-parser</artifactId>
+        </exclusion>
       </exclusions>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/data/ValueVectorTypes.tdd
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/data/ValueVectorTypes.tdd b/exec/vector/src/main/codegen/data/ValueVectorTypes.tdd
index 26bf02d..4d719b4 100644
--- a/exec/vector/src/main/codegen/data/ValueVectorTypes.tdd
+++ b/exec/vector/src/main/codegen/data/ValueVectorTypes.tdd
@@ -26,6 +26,8 @@
       width: 1,
       javaType: "byte",
       boxedType: "Byte",
+      accessorType: "int",
+      accessorCast: "set",
       fields: [{name: "value", type: "byte"}],
       minor: [
         { class: "TinyInt", valueHolder: "IntHolder" },
@@ -37,15 +39,19 @@
       width: 2,
       javaType: "char",
       boxedType: "Character",
+      accessorType: "int",
       fields: [{name: "value", type: "char"}],
       minor: [
-        { class: "UInt2", valueHolder: "UInt2Holder"}
+        { class: "UInt2", valueHolder: "UInt2Holder", accessorCast: "set"}
       ]
-    },    {
+    },
+    {
       major: "Fixed",
       width: 2,
       javaType: "short",
       boxedType: "Short",
+      accessorType: "int",
+      accessorCast: "set",
       fields: [{name: "value", type: "short"}],
       minor: [
         { class: "SmallInt", valueHolder: "Int2Holder"},
@@ -60,10 +66,13 @@
       minor: [
         { class: "Int", valueHolder: "IntHolder"},
         { class: "UInt4", valueHolder: "UInt4Holder" },
-        { class: "Float4", javaType: "float" , boxedType: "Float", fields: [{name: "value", type: "float"}]},
-        { class: "Time", javaType: "int", friendlyType: "DateTime" },
+        { class: "Float4", javaType: "float" , boxedType: "Float", accessorType: "double", accessorCast: "set",
+          fields: [{name: "value", type: "float"}]},
+        { class: "Time", javaType: "int", friendlyType: "DateTime", accessorType: "int" },
         { class: "IntervalYear", javaType: "int", friendlyType: "Period" }
-        { class: "Decimal9", maxPrecisionDigits: 9, friendlyType: "BigDecimal", fields: [{name:"value", type:"int"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] },
+        { class: "Decimal9", maxPrecisionDigits: 9, friendlyType: "BigDecimal",
+          fields: [{name:"value", type:"int"}, {name: "scale", type: "int", include: false},
+                   {name: "precision", type: "int", include: false}] },
       ]
     },
     {
@@ -76,9 +85,11 @@
         { class: "BigInt"},
         { class: "UInt8" },
         { class: "Float8", javaType: "double" , boxedType: "Double", fields: [{name: "value", type: "double"}], },
-        { class: "Date", javaType: "long", friendlyType: "DateTime" },
-        { class: "TimeStamp", javaType: "long", friendlyType: "DateTime" }
-        { class: "Decimal18", maxPrecisionDigits: 18, friendlyType: "BigDecimal", fields: [{name:"value", type:"long"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] },
+        { class: "Date", javaType: "long", friendlyType: "DateTime", accessorType: "long" },
+        { class: "TimeStamp", javaType: "long", friendlyType: "DateTime", accessorType: "long" }
+        { class: "Decimal18", maxPrecisionDigits: 18, friendlyType: "BigDecimal",
+          fields: [{name:"value", type:"long"}, {name: "scale", type: "int", include: false},
+                   {name: "precision", type: "int", include: false}] },
         <#--
         { class: "Money", maxPrecisionDigits: 2, scale: 1, },
         -->
@@ -90,16 +101,18 @@
       javaType: "DrillBuf",
       boxedType: "DrillBuf",
       minor: [
-        { class: "IntervalDay", millisecondsOffset: 4, friendlyType: "Period", fields: [ {name: "days", type:"int"}, {name: "milliseconds", type:"int"}] }
+        { class: "IntervalDay", millisecondsOffset: 4, friendlyType: "Period",
+          fields: [ {name: "days", type:"int"}, {name: "milliseconds", type:"int"}] }
       ]
     },
     {
       major: "Fixed",
       width: 16,
       javaType: "DrillBuf"
-      boxedType: "DrillBuf",      
+      boxedType: "DrillBuf",
       minor: [
-        { class: "Interval", daysOffset: 4, millisecondsOffset: 8, friendlyType: "Period", fields: [ {name: "months", type: "int"}, {name: "days", type:"int"}, {name: "milliseconds", type:"int"}] }
+        { class: "Interval", daysOffset: 4, millisecondsOffset: 8, friendlyType: "Period",
+          fields: [ {name: "months", type: "int"}, {name: "days", type:"int"}, {name: "milliseconds", type:"int"}] }
       ]
     },
     {
@@ -107,12 +120,15 @@
       width: 12,
       javaType: "DrillBuf",
       boxedType: "DrillBuf",
+      accessorDisabled: true,
       minor: [
         <#--
         { class: "TimeTZ" },
         { class: "Interval" }
         -->
-        { class: "Decimal28Dense", maxPrecisionDigits: 28, nDecimalDigits: 3, friendlyType: "BigDecimal", fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
+        { class: "Decimal28Dense", maxPrecisionDigits: 28, nDecimalDigits: 3, friendlyType: "BigDecimal",
+          fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"},
+                   {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
       ]
     },
     {
@@ -120,9 +136,11 @@
       width: 16,
       javaType: "DrillBuf",
       boxedType: "DrillBuf",
-      
+      accessorDisabled: true,
       minor: [
-        { class: "Decimal38Dense", maxPrecisionDigits: 38, nDecimalDigits: 4, friendlyType: "BigDecimal", fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
+        { class: "Decimal38Dense", maxPrecisionDigits: 38, nDecimalDigits: 4,friendlyType: "BigDecimal",
+          fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"},
+                   {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
       ]
     },
     {
@@ -131,7 +149,9 @@
       javaType: "DrillBuf",
       boxedType: "DrillBuf",
       minor: [
-        { class: "Decimal38Sparse", maxPrecisionDigits: 38, nDecimalDigits: 6, friendlyType: "BigDecimal", fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
+        { class: "Decimal38Sparse", maxPrecisionDigits: 38, nDecimalDigits: 6, friendlyType: "BigDecimal",
+          fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"},
+                   {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
       ]
     },
     {
@@ -140,7 +160,9 @@
       javaType: "DrillBuf",
       boxedType: "DrillBuf",
       minor: [
-        { class: "Decimal28Sparse", maxPrecisionDigits: 28, nDecimalDigits: 5, friendlyType: "BigDecimal", fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"}, {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
+        { class: "Decimal28Sparse", maxPrecisionDigits: 28, nDecimalDigits: 5, friendlyType: "BigDecimal",
+          fields: [{name: "start", type: "int"}, {name: "buffer", type: "DrillBuf"},
+                   {name: "scale", type: "int", include: false}, {name: "precision", type: "int", include: false}] }
       ]
     },
     {
@@ -150,8 +172,8 @@
       boxedType: "DrillBuf",
       fields: [{name: "start", type: "int"}, {name: "end", type: "int"}, {name: "buffer", type: "DrillBuf"}],
       minor: [
-        { class: "VarBinary" , friendlyType: "byte[]" },
-        { class: "VarChar" , friendlyType: "Text" },
+        { class: "VarBinary" , friendlyType: "byte[]", accessorType: "byte[]", accessorLabel: "Bytes" },
+        { class: "VarChar" , friendlyType: "Text", accessorType: "String" },
         { class: "Var16Char" , friendlyType: "String" }
       ]
     },
@@ -161,7 +183,8 @@
       javaType: "int",
       boxedType: "Integer",
       minor: [
-        { class: "Bit" , friendlyType: "Boolean", fields: [{name: "value", type: "int"}] }
+        { class: "Bit" , friendlyType: "Boolean", accessorType: "int"
+          fields: [{name: "value", type: "int"}] }
       ]
     }
   ]

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/includes/license.ftl
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/includes/license.ftl b/exec/vector/src/main/codegen/includes/license.ftl
index 0455fd8..586b456 100644
--- a/exec/vector/src/main/codegen/includes/license.ftl
+++ b/exec/vector/src/main/codegen/includes/license.ftl
@@ -1,5 +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
@@ -15,4 +14,4 @@
  * 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.
- ******************************************************************************/
\ No newline at end of file
+ ******************************************************************************/

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/includes/vv_imports.ftl
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/includes/vv_imports.ftl b/exec/vector/src/main/codegen/includes/vv_imports.ftl
index 11e0f5d..87a2106 100644
--- a/exec/vector/src/main/codegen/includes/vv_imports.ftl
+++ b/exec/vector/src/main/codegen/includes/vv_imports.ftl
@@ -1,12 +1,12 @@
-<#-- 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 
+<#-- 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. -->
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -65,9 +65,3 @@ import org.joda.time.DateTime;
 import org.joda.time.Period;
 
 import org.apache.drill.exec.util.Text;
-
-
-
-
-
-

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/AbstractFieldReader.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/AbstractFieldReader.java b/exec/vector/src/main/codegen/templates/AbstractFieldReader.java
index 289aa60..0e48853 100644
--- a/exec/vector/src/main/codegen/templates/AbstractFieldReader.java
+++ b/exec/vector/src/main/codegen/templates/AbstractFieldReader.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
@@ -31,7 +31,7 @@ package org.apache.drill.exec.vector.complex.impl;
  */
 @SuppressWarnings("unused")
 abstract class AbstractFieldReader extends AbstractBaseReader implements FieldReader{
-  
+
   AbstractFieldReader(){
     super();
   }
@@ -44,24 +44,24 @@ abstract class AbstractFieldReader extends AbstractBaseReader implements FieldRe
     return true;
   }
 
-  <#list ["Object", "BigDecimal", "Integer", "Long", "Boolean", 
+  <#list ["Object", "BigDecimal", "Integer", "Long", "Boolean",
           "Character", "DateTime", "Period", "Double", "Float",
           "Text", "String", "Byte", "Short", "byte[]"] as friendlyType>
   <#assign safeType=friendlyType />
   <#if safeType=="byte[]"><#assign safeType="ByteArray" /></#if>
-  
+
   public ${friendlyType} read${safeType}(int arrayIndex){
     fail("read${safeType}(int arrayIndex)");
     return null;
   }
-  
+
   public ${friendlyType} read${safeType}(){
     fail("read${safeType}()");
     return null;
   }
-  
+
   </#list>
-  
+
   public void copyAsValue(MapWriter writer){
     fail("CopyAsValue MapWriter");
   }
@@ -72,7 +72,7 @@ abstract class AbstractFieldReader extends AbstractBaseReader implements FieldRe
   public void copyAsField(String name, ListWriter writer){
     fail("CopyAsFieldList");
   }
-  
+
   <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
   <#assign boxedType = (minor.boxedType!type.boxedType) />
 
@@ -83,15 +83,15 @@ abstract class AbstractFieldReader extends AbstractBaseReader implements FieldRe
   public void read(Nullable${name}Holder holder){
     fail("${name}");
   }
-  
+
   public void read(int arrayIndex, ${name}Holder holder){
     fail("Repeated${name}");
   }
-  
+
   public void read(int arrayIndex, Nullable${name}Holder holder){
     fail("Repeated${name}");
   }
-  
+
   public void copyAsValue(${name}Writer writer){
     fail("CopyAsValue${name}");
   }
@@ -99,7 +99,7 @@ abstract class AbstractFieldReader extends AbstractBaseReader implements FieldRe
     fail("CopyAsField${name}");
   }
   </#list></#list>
-  
+
   public FieldReader reader(String name){
     fail("reader(String name)");
     return null;
@@ -108,19 +108,19 @@ abstract class AbstractFieldReader extends AbstractBaseReader implements FieldRe
   public FieldReader reader(){
     fail("reader()");
     return null;
-    
+
   }
-  
+
   public int size(){
     fail("size()");
     return -1;
   }
-  
+
   private void fail(String name){
     throw new IllegalArgumentException(String.format("You tried to read a [%s] type when you are using a field reader of type [%s].", name, this.getClass().getSimpleName()));
   }
-  
-  
+
+
 }
 
 

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/ColumnAccessors.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/ColumnAccessors.java b/exec/vector/src/main/codegen/templates/ColumnAccessors.java
new file mode 100644
index 0000000..f1fbf2f
--- /dev/null
+++ b/exec/vector/src/main/codegen/templates/ColumnAccessors.java
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+<@pp.dropOutputFile />
+<@pp.changeOutputFile name="/org/apache/drill/exec/vector/accessor/ColumnAccessors.java" />
+<#include "/@includes/license.ftl" />
+<#macro getType label>
+    @Override
+    public ValueType valueType() {
+  <#if label == "Int">
+      return ValueType.INTEGER;
+  <#else>
+      return ValueType.${label?upper_case};
+  </#if>
+    }
+</#macro>
+<#macro bindReader prefix drillType>
+  <#if drillType = "Decimal9" || drillType == "Decimal18">
+    private MaterializedField field;
+  </#if>
+    private ${prefix}${drillType}Vector.Accessor accessor;
+
+    @Override
+    public void bind(RowIndex vectorIndex, ValueVector vector) {
+      bind(vectorIndex);
+  <#if drillType = "Decimal9" || drillType == "Decimal18">
+      field = vector.getField();
+  </#if>
+      accessor = ((${prefix}${drillType}Vector) vector).getAccessor();
+    }
+
+  <#if drillType = "Decimal9" || drillType == "Decimal18">
+    @Override
+    public void bind(RowIndex vectorIndex, MaterializedField field, VectorAccessor va) {
+      bind(vectorIndex, field, va);
+      this.field = field;
+    }
+
+ </#if>
+   private ${prefix}${drillType}Vector.Accessor accessor() {
+      if (vectorAccessor == null) {
+        return accessor;
+      } else {
+        return ((${prefix}${drillType}Vector) vectorAccessor.vector()).getAccessor();
+      }
+    }
+</#macro>
+<#macro get drillType accessorType label isArray>
+    @Override
+    public ${accessorType} get${label}(<#if isArray>int index</#if>) {
+  <#if isArray>
+    <#assign index=", index"/>
+    <#assign getObject="getSingleObject">
+  <#else>
+    <#assign index=""/>
+    <#assign getObject="getObject">
+  </#if>
+  <#if drillType == "VarChar">
+      return new String(accessor().get(vectorIndex.index()${index}), Charsets.UTF_8);
+  <#elseif drillType == "Var16Char">
+      return new String(accessor().get(vectorIndex.index()${index}), Charsets.UTF_16);
+  <#elseif drillType == "VarBinary">
+      return accessor().get(vectorIndex.index()${index});
+  <#elseif drillType == "Decimal9" || drillType == "Decimal18">
+      return DecimalUtility.getBigDecimalFromPrimitiveTypes(
+                accessor().get(vectorIndex.index()${index}),
+                field.getScale(),
+                field.getPrecision());
+  <#elseif accessorType == "BigDecimal" || accessorType == "Period">
+      return accessor().${getObject}(vectorIndex.index()${index});
+  <#else>
+      return accessor().get(vectorIndex.index()${index});
+  </#if>
+    }
+</#macro>
+<#macro bindWriter prefix drillType>
+  <#if drillType = "Decimal9" || drillType == "Decimal18">
+    private MaterializedField field;
+  </#if>
+    private ${prefix}${drillType}Vector.Mutator mutator;
+
+    @Override
+    public void bind(RowIndex vectorIndex, ValueVector vector) {
+      bind(vectorIndex);
+  <#if drillType = "Decimal9" || drillType == "Decimal18">
+      field = vector.getField();
+  </#if>
+      this.mutator = ((${prefix}${drillType}Vector) vector).getMutator();
+    }
+</#macro>
+<#macro set drillType accessorType label nullable verb>
+    @Override
+    public void set${label}(${accessorType} value) {
+  <#if drillType == "VarChar">
+      byte bytes[] = value.getBytes(Charsets.UTF_8);
+      mutator.${verb}Safe(vectorIndex.index(), bytes, 0, bytes.length);
+  <#elseif drillType == "Var16Char">
+      byte bytes[] = value.getBytes(Charsets.UTF_16);
+      mutator.${verb}Safe(vectorIndex.index(), bytes, 0, bytes.length);
+  <#elseif drillType == "VarBinary">
+      mutator.${verb}Safe(vectorIndex.index(), value, 0, value.length);
+  <#elseif drillType == "Decimal9">
+      mutator.${verb}Safe(vectorIndex.index(),
+          DecimalUtility.getDecimal9FromBigDecimal(value,
+              field.getScale(), field.getPrecision()));
+  <#elseif drillType == "Decimal18">
+      mutator.${verb}Safe(vectorIndex.index(),
+          DecimalUtility.getDecimal18FromBigDecimal(value,
+              field.getScale(), field.getPrecision()));
+  <#elseif drillType == "IntervalYear">
+      mutator.${verb}Safe(vectorIndex.index(), value.getYears() * 12 + value.getMonths());
+  <#elseif drillType == "IntervalDay">
+      mutator.${verb}Safe(vectorIndex.index(),<#if nullable> 1,</#if>
+                      value.getDays(),
+                      ((value.getHours() * 60 + value.getMinutes()) * 60 +
+                       value.getSeconds()) * 1000 + value.getMillis());
+  <#elseif drillType == "Interval">
+      mutator.${verb}Safe(vectorIndex.index(),<#if nullable> 1,</#if>
+                      value.getYears() * 12 + value.getMonths(),
+                      value.getDays(),
+                      ((value.getHours() * 60 + value.getMinutes()) * 60 +
+                       value.getSeconds()) * 1000 + value.getMillis());
+  <#else>
+      mutator.${verb}Safe(vectorIndex.index(), <#if cast=="set">(${javaType}) </#if>value);
+  </#if>
+    }
+</#macro>
+
+package org.apache.drill.exec.vector.accessor;
+
+import java.math.BigDecimal;
+
+import org.apache.drill.common.types.TypeProtos.DataMode;
+import org.apache.drill.common.types.TypeProtos.MinorType;
+import org.apache.drill.exec.vector.*;
+import org.apache.drill.exec.record.MaterializedField;
+import org.apache.drill.exec.util.DecimalUtility;
+import org.apache.drill.exec.vector.accessor.impl.AbstractColumnReader;
+import org.apache.drill.exec.vector.accessor.impl.AbstractColumnWriter;
+import org.apache.drill.exec.vector.complex.BaseRepeatedValueVector;
+import org.apache.drill.exec.vector.accessor.impl.AbstractArrayReader;
+import org.apache.drill.exec.vector.accessor.impl.AbstractArrayWriter;
+import org.apache.drill.exec.vector.accessor.impl.AbstractColumnReader.VectorAccessor;
+
+import com.google.common.base.Charsets;
+import org.joda.time.Period;
+
+/**
+ * Basic accessors for most Drill vector types and modes. These are bare-bones
+ * accessors: they do only the most rudimentary type conversions. For all,
+ * there is only one way to get/set values; they don't convert from, say,
+ * a double to an int or visa-versa.
+ * <p>
+ * Writers work only with single vectors. Readers work with either single
+ * vectors or a "hyper vector": a collection of vectors indexed together.
+ * The details are hidden behind the {@link RowIndex} interface. If the reader
+ * accesses a single vector, then the mutator is cached at bind time. However,
+ * if the reader works with a hyper vector, then the vector is null at bind
+ * time and must be retrieved for each row (since the vector differs row-by-
+ * row.)
+ */
+
+// This class is generated using freemarker and the ${.template_name} template.
+
+public class ColumnAccessors {
+
+<#list vv.types as type>
+  <#list type.minor as minor>
+    <#assign drillType=minor.class>
+    <#assign javaType=minor.javaType!type.javaType>
+    <#assign accessorType=minor.accessorType!type.accessorType!minor.friendlyType!javaType>
+    <#assign label=minor.accessorLabel!type.accessorLabel!accessorType?capitalize>
+    <#assign notyet=minor.accessorDisabled!type.accessorDisabled!false>
+    <#assign cast=minor.accessorCast!minor.accessorCast!type.accessorCast!"none">
+    <#assign friendlyType=minor.friendlyType!"">
+    <#if accessorType=="BigDecimal">
+      <#assign label="Decimal">
+    </#if>
+    <#if ! notyet>
+  //------------------------------------------------------------------------
+  // ${drillType} readers and writers
+
+  public static class ${drillType}ColumnReader extends AbstractColumnReader {
+
+    <@bindReader "" drillType />
+
+    <@getType label />
+
+    <@get drillType accessorType label false/>
+  }
+
+  public static class Nullable${drillType}ColumnReader extends AbstractColumnReader {
+
+    <@bindReader "Nullable" drillType />
+
+    <@getType label />
+
+    @Override
+    public boolean isNull() {
+      return accessor().isNull(vectorIndex.index());
+    }
+
+    <@get drillType accessorType label false/>
+  }
+
+  public static class Repeated${drillType}ColumnReader extends AbstractArrayReader {
+
+    <@bindReader "Repeated" drillType />
+
+    <@getType label />
+
+    @Override
+    public int size() {
+      return accessor().getInnerValueCountAt(vectorIndex.index());
+    }
+
+    <@get drillType accessorType label true/>
+  }
+
+  public static class ${drillType}ColumnWriter extends AbstractColumnWriter {
+
+    <@bindWriter "" drillType />
+
+    <@getType label />
+
+    <@set drillType accessorType label false "set" />
+  }
+
+  public static class Nullable${drillType}ColumnWriter extends AbstractColumnWriter {
+
+    <@bindWriter "Nullable" drillType />
+
+    <@getType label />
+
+    @Override
+    public void setNull() {
+      mutator.setNull(vectorIndex.index());
+    }
+
+    <@set drillType accessorType label true "set" />
+  }
+
+  public static class Repeated${drillType}ColumnWriter extends AbstractArrayWriter {
+
+    <@bindWriter "Repeated" drillType />
+
+    <@getType label />
+
+    protected BaseRepeatedValueVector.BaseRepeatedMutator mutator() {
+      return mutator;
+    }
+
+    <@set drillType accessorType label false "add" />
+  }
+
+    </#if>
+  </#list>
+</#list>
+  public static void defineReaders(
+      Class<? extends AbstractColumnReader> readers[][]) {
+<#list vv.types as type>
+  <#list type.minor as minor>
+    <#assign drillType=minor.class>
+    <#assign notyet=minor.accessorDisabled!type.accessorDisabled!false>
+    <#if ! notyet>
+    <#assign typeEnum=drillType?upper_case>
+    readers[MinorType.${typeEnum}.ordinal()][DataMode.REQUIRED.ordinal()] = ${drillType}ColumnReader.class;
+    readers[MinorType.${typeEnum}.ordinal()][DataMode.OPTIONAL.ordinal()] = Nullable${drillType}ColumnReader.class;
+    </#if>
+  </#list>
+</#list>
+  }
+
+  public static void defineWriters(
+      Class<? extends AbstractColumnWriter> writers[][]) {
+<#list vv.types as type>
+  <#list type.minor as minor>
+    <#assign drillType=minor.class>
+    <#assign notyet=minor.accessorDisabled!type.accessorDisabled!false>
+    <#if ! notyet>
+    <#assign typeEnum=drillType?upper_case>
+    writers[MinorType.${typeEnum}.ordinal()][DataMode.REQUIRED.ordinal()] = ${drillType}ColumnWriter.class;
+    writers[MinorType.${typeEnum}.ordinal()][DataMode.OPTIONAL.ordinal()] = Nullable${drillType}ColumnWriter.class;
+    </#if>
+  </#list>
+</#list>
+  }
+
+  public static void defineArrayReaders(
+      Class<? extends AbstractArrayReader> readers[]) {
+<#list vv.types as type>
+  <#list type.minor as minor>
+    <#assign drillType=minor.class>
+    <#assign notyet=minor.accessorDisabled!type.accessorDisabled!false>
+    <#if ! notyet>
+    <#assign typeEnum=drillType?upper_case>
+    readers[MinorType.${typeEnum}.ordinal()] = Repeated${drillType}ColumnReader.class;
+    </#if>
+  </#list>
+</#list>
+  }
+
+  public static void defineArrayWriters(
+      Class<? extends AbstractArrayWriter> writers[]) {
+<#list vv.types as type>
+  <#list type.minor as minor>
+    <#assign drillType=minor.class>
+    <#assign notyet=minor.accessorDisabled!type.accessorDisabled!false>
+    <#if ! notyet>
+    <#assign typeEnum=drillType?upper_case>
+    writers[MinorType.${typeEnum}.ordinal()] = Repeated${drillType}ColumnWriter.class;
+    </#if>
+  </#list>
+</#list>
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/FixedValueVectors.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/FixedValueVectors.java b/exec/vector/src/main/codegen/templates/FixedValueVectors.java
index b2a5dc3..23188ce 100644
--- a/exec/vector/src/main/codegen/templates/FixedValueVectors.java
+++ b/exec/vector/src/main/codegen/templates/FixedValueVectors.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
@@ -16,8 +16,6 @@
  * limitations under the License.
  */
 
-import java.lang.Override;
-
 <@pp.dropOutputFile />
 <#list vv.types as type>
 <#list type.minor as minor>
@@ -30,6 +28,7 @@ import java.lang.Override;
 package org.apache.drill.exec.vector;
 
 <#include "/@includes/vv_imports.ftl" />
+import org.apache.drill.exec.util.DecimalUtility;
 
 /**
  * ${minor.class} implements a vector of fixed width values.  Elements in the vector are accessed
@@ -137,7 +136,7 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     allocationMonitor = 0;
     zeroVector();
     super.reset();
-    }
+  }
 
   private void allocateBytes(final long size) {
     if (size > MAX_ALLOCATION_SIZE) {
@@ -198,6 +197,7 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     data.writerIndex(actualLength);
   }
 
+  @Override
   public TransferPair getTransferPair(BufferAllocator allocator){
     return new TransferImpl(getField(), allocator);
   }
@@ -304,7 +304,6 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     }
 
     <#if (type.width > 8)>
-
     public ${minor.javaType!type.javaType} get(int index) {
       return data.slice(index * ${type.width}, ${type.width});
     }
@@ -423,27 +422,27 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     <#elseif (minor.class == "Decimal28Sparse") || (minor.class == "Decimal38Sparse") || (minor.class == "Decimal28Dense") || (minor.class == "Decimal38Dense")>
 
     public void get(int index, ${minor.class}Holder holder) {
-        holder.start = index * ${type.width};
-        holder.buffer = data;
-        holder.scale = getField().getScale();
-        holder.precision = getField().getPrecision();
+      holder.start = index * ${type.width};
+      holder.buffer = data;
+      holder.scale = getField().getScale();
+      holder.precision = getField().getPrecision();
     }
 
     public void get(int index, Nullable${minor.class}Holder holder) {
-        holder.isSet = 1;
-        holder.start = index * ${type.width};
-        holder.buffer = data;
-        holder.scale = getField().getScale();
-        holder.precision = getField().getPrecision();
+      holder.isSet = 1;
+      holder.start = index * ${type.width};
+      holder.buffer = data;
+      holder.scale = getField().getScale();
+      holder.precision = getField().getPrecision();
     }
 
-      @Override
-      public ${friendlyType} getObject(int index) {
+    @Override
+    public ${friendlyType} getObject(int index) {
       <#if (minor.class == "Decimal28Sparse") || (minor.class == "Decimal38Sparse")>
       // Get the BigDecimal object
-      return org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale());
+      return DecimalUtility.getBigDecimalFromSparse(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale());
       <#else>
-      return org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDense(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale(), ${minor.maxPrecisionDigits}, ${type.width});
+      return DecimalUtility.getBigDecimalFromDense(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale(), ${minor.maxPrecisionDigits}, ${type.width});
       </#if>
     }
 
@@ -585,150 +584,165 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     * @param value   value to set
     */
   <#if (type.width > 8)>
-   public void set(int index, <#if (type.width > 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
-     data.setBytes(index * ${type.width}, value, 0, ${type.width});
-   }
+    public void set(int index, <#if (type.width > 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
+      data.setBytes(index * ${type.width}, value, 0, ${type.width});
+    }
 
-   public void setSafe(int index, <#if (type.width > 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
-     while(index >= getValueCapacity()) {
-       reAlloc();
-     }
-     data.setBytes(index * ${type.width}, value, 0, ${type.width});
-   }
+    public void setSafe(int index, <#if (type.width > 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      data.setBytes(index * ${type.width}, value, 0, ${type.width});
+    }
 
   <#if (minor.class == "Interval")>
-   public void set(int index, int months, int days, int milliseconds){
-     final int offsetIndex = index * ${type.width};
-     data.setInt(offsetIndex, months);
-     data.setInt((offsetIndex + ${minor.daysOffset}), days);
-     data.setInt((offsetIndex + ${minor.millisecondsOffset}), milliseconds);
-   }
-
-   protected void set(int index, ${minor.class}Holder holder){
-     set(index, holder.months, holder.days, holder.milliseconds);
-   }
-
-   protected void set(int index, Nullable${minor.class}Holder holder){
-     set(index, holder.months, holder.days, holder.milliseconds);
-   }
-
-   public void setSafe(int index, int months, int days, int milliseconds){
-     while(index >= getValueCapacity()) {
-       reAlloc();
-     }
-     set(index, months, days, milliseconds);
-   }
-
-   public void setSafe(int index, Nullable${minor.class}Holder holder){
-     setSafe(index, holder.months, holder.days, holder.milliseconds);
-   }
-
-   public void setSafe(int index, ${minor.class}Holder holder){
-     setSafe(index, holder.months, holder.days, holder.milliseconds);
-   }
-
-   <#elseif (minor.class == "IntervalDay")>
-   public void set(int index, int days, int milliseconds){
-     final int offsetIndex = index * ${type.width};
-     data.setInt(offsetIndex, days);
-     data.setInt((offsetIndex + ${minor.millisecondsOffset}), milliseconds);
-   }
-
-   protected void set(int index, ${minor.class}Holder holder){
-     set(index, holder.days, holder.milliseconds);
-   }
-   protected void set(int index, Nullable${minor.class}Holder holder){
-     set(index, holder.days, holder.milliseconds);
-   }
-
-   public void setSafe(int index, int days, int milliseconds){
-     while(index >= getValueCapacity()) {
-       reAlloc();
-     }
-     set(index, days, milliseconds);
-   }
+    public void set(int index, int months, int days, int milliseconds){
+      final int offsetIndex = index * ${type.width};
+      data.setInt(offsetIndex, months);
+      data.setInt((offsetIndex + ${minor.daysOffset}), days);
+      data.setInt((offsetIndex + ${minor.millisecondsOffset}), milliseconds);
+    }
 
-   public void setSafe(int index, ${minor.class}Holder holder){
-     setSafe(index, holder.days, holder.milliseconds);
-   }
+    protected void set(int index, ${minor.class}Holder holder){
+      set(index, holder.months, holder.days, holder.milliseconds);
+    }
 
-   public void setSafe(int index, Nullable${minor.class}Holder holder){
-     setSafe(index, holder.days, holder.milliseconds);
-   }
+    protected void set(int index, Nullable${minor.class}Holder holder){
+      set(index, holder.months, holder.days, holder.milliseconds);
+    }
+
+    public void setSafe(int index, int months, int days, int milliseconds){
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      set(index, months, days, milliseconds);
+    }
+
+    public void setSafe(int index, Nullable${minor.class}Holder holder){
+      setSafe(index, holder.months, holder.days, holder.milliseconds);
+    }
 
-   <#elseif (minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse") || (minor.class == "Decimal28Dense") || (minor.class == "Decimal38Dense")>
+    public void setSafe(int index, ${minor.class}Holder holder){
+      setSafe(index, holder.months, holder.days, holder.milliseconds);
+    }
 
-   public void set(int index, ${minor.class}Holder holder){
-     set(index, holder.start, holder.buffer);
-   }
+  <#elseif (minor.class == "IntervalDay")>
+    public void set(int index, int days, int milliseconds){
+      final int offsetIndex = index * ${type.width};
+      data.setInt(offsetIndex, days);
+      data.setInt((offsetIndex + ${minor.millisecondsOffset}), milliseconds);
+    }
 
-   void set(int index, Nullable${minor.class}Holder holder){
-     set(index, holder.start, holder.buffer);
-   }
+    protected void set(int index, ${minor.class}Holder holder){
+      set(index, holder.days, holder.milliseconds);
+    }
 
-   public void setSafe(int index,  Nullable${minor.class}Holder holder){
-     setSafe(index, holder.start, holder.buffer);
-   }
-   public void setSafe(int index,  ${minor.class}Holder holder){
-     setSafe(index, holder.start, holder.buffer);
-   }
+    protected void set(int index, Nullable${minor.class}Holder holder){
+      set(index, holder.days, holder.milliseconds);
+    }
 
-   public void setSafe(int index, int start, DrillBuf buffer){
-     while(index >= getValueCapacity()) {
-       reAlloc();
-     }
-     set(index, start, buffer);
-   }
+    public void setSafe(int index, int days, int milliseconds){
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      set(index, days, milliseconds);
+    }
 
-   public void set(int index, int start, DrillBuf buffer){
-     data.setBytes(index * ${type.width}, buffer, start, ${type.width});
-   }
+    public void setSafe(int index, ${minor.class}Holder holder){
+      setSafe(index, holder.days, holder.milliseconds);
+    }
 
-   <#else>
+    public void setSafe(int index, Nullable${minor.class}Holder holder){
+      setSafe(index, holder.days, holder.milliseconds);
+    }
 
-   protected void set(int index, ${minor.class}Holder holder){
-     set(index, holder.start, holder.buffer);
-   }
+  <#elseif (minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse") || (minor.class == "Decimal28Dense") || (minor.class == "Decimal38Dense")>
+    public void set(int index, ${minor.class}Holder holder){
+      set(index, holder.start, holder.buffer);
+    }
 
-   public void set(int index, Nullable${minor.class}Holder holder){
-     set(index, holder.start, holder.buffer);
-   }
+    void set(int index, Nullable${minor.class}Holder holder){
+      set(index, holder.start, holder.buffer);
+    }
 
-   public void set(int index, int start, DrillBuf buffer){
-     data.setBytes(index * ${type.width}, buffer, start, ${type.width});
-   }
+    public void setSafe(int index,  Nullable${minor.class}Holder holder){
+      setSafe(index, holder.start, holder.buffer);
+    }
 
-   public void setSafe(int index, ${minor.class}Holder holder){
-     setSafe(index, holder.start, holder.buffer);
-   }
-   public void setSafe(int index, Nullable${minor.class}Holder holder){
-     setSafe(index, holder.start, holder.buffer);
-   }
+    public void setSafe(int index,  ${minor.class}Holder holder){
+      setSafe(index, holder.start, holder.buffer);
+    }
 
-   public void setSafe(int index, int start, DrillBuf buffer){
-     while(index >= getValueCapacity()) {
-       reAlloc();
-     }
-     set(index, holder);
-   }
-
-   public void set(int index, Nullable${minor.class}Holder holder){
-     data.setBytes(index * ${type.width}, holder.buffer, holder.start, ${type.width});
-   }
+    public void setSafe(int index, int start, DrillBuf buffer){
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      set(index, start, buffer);
+    }
+
+  <#if minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse">
+    public void set(int index, BigDecimal value) {
+      DecimalUtility.getSparseFromBigDecimal(value, data, index * ${type.width},
+           field.getScale(), field.getPrecision(), ${minor.nDecimalDigits});
+    }
+
+    public void setSafe(int index, BigDecimal value) {
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      set(index, value);
+    }
+
+  </#if>
+    public void set(int index, int start, DrillBuf buffer){
+      data.setBytes(index * ${type.width}, buffer, start, ${type.width});
+    }
+
+  <#else>
+    protected void set(int index, ${minor.class}Holder holder){
+      set(index, holder.start, holder.buffer);
+    }
+
+    public void set(int index, Nullable${minor.class}Holder holder){
+      set(index, holder.start, holder.buffer);
+    }
+
+    public void set(int index, int start, DrillBuf buffer){
+      data.setBytes(index * ${type.width}, buffer, start, ${type.width});
+    }
+
+    public void setSafe(int index, ${minor.class}Holder holder){
+      setSafe(index, holder.start, holder.buffer);
+    }
+
+    public void setSafe(int index, Nullable${minor.class}Holder holder){
+      setSafe(index, holder.start, holder.buffer);
+    }
+
+    public void setSafe(int index, int start, DrillBuf buffer){
+      while(index >= getValueCapacity()) {
+        reAlloc();
+      }
+      set(index, holder);
+    }
+
+    public void set(int index, Nullable${minor.class}Holder holder){
+      data.setBytes(index * ${type.width}, holder.buffer, holder.start, ${type.width});
+    }
    </#if>
 
-   @Override
-   public void generateTestData(int count) {
-     setValueCount(count);
-     boolean even = true;
-     final int valueCount = getAccessor().getValueCount();
-     for(int i = 0; i < valueCount; i++, even = !even) {
-       final byte b = even ? Byte.MIN_VALUE : Byte.MAX_VALUE;
-       for(int w = 0; w < ${type.width}; w++){
-         data.setByte(i + w, b);
-       }
-     }
-   }
+    @Override
+    public void generateTestData(int count) {
+      setValueCount(count);
+      boolean even = true;
+      final int valueCount = getAccessor().getValueCount();
+      for(int i = 0; i < valueCount; i++, even = !even) {
+        final byte b = even ? Byte.MIN_VALUE : Byte.MAX_VALUE;
+        for(int w = 0; w < ${type.width}; w++){
+          data.setByte(i + w, b);
+        }
+      }
+    }
 
    <#else> <#-- type.width <= 8 -->
     public void set(int index, <#if (type.width >= 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
@@ -792,7 +806,6 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     }
 
   </#if> <#-- type.width -->
-
     @Override
     public void setValueCount(int valueCount) {
       final int currentValueCapacity = getValueCapacity();

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/NullableValueVectors.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/NullableValueVectors.java b/exec/vector/src/main/codegen/templates/NullableValueVectors.java
index fcbe79a..170c606 100644
--- a/exec/vector/src/main/codegen/templates/NullableValueVectors.java
+++ b/exec/vector/src/main/codegen/templates/NullableValueVectors.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
@@ -15,6 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+import org.apache.drill.exec.util.DecimalUtility;
 import org.apache.drill.exec.vector.BaseDataValueVector;
 import org.apache.drill.exec.vector.NullableVectorDefinitionSetter;
 
@@ -252,7 +253,6 @@ public final class ${className} extends BaseDataValueVector implements <#if type
   }
   </#if>
 
-
   @Override
   public void load(SerializedField metadata, DrillBuf buffer) {
     clear();
@@ -486,7 +486,6 @@ public final class ${className} extends BaseDataValueVector implements <#if type
     }
 
     <#if type.major == "VarLen">
-
     private void fillEmpties(int index){
       final ${valuesName}.Mutator valuesMutator = values.getMutator();
       for (int i = lastSet; i < index; i++) {
@@ -547,7 +546,6 @@ public final class ${className} extends BaseDataValueVector implements <#if type
       values.getMutator().set(index, holder);
     }
 
-
     public void set(int index, Nullable${minor.class}Holder holder){
       final ${valuesName}.Mutator valuesMutator = values.getMutator();
       <#if type.major == "VarLen">
@@ -602,9 +600,7 @@ public final class ${className} extends BaseDataValueVector implements <#if type
       <#if type.major == "VarLen">lastSet = index;</#if>
     }
 
-
     public void setSafe(int index, Nullable${minor.class}Holder value) {
-
       <#if type.major == "VarLen">
       if (index > lastSet + 1) {
         fillEmpties(index);
@@ -617,7 +613,6 @@ public final class ${className} extends BaseDataValueVector implements <#if type
     }
 
     public void setSafe(int index, ${minor.class}Holder value) {
-
       <#if type.major == "VarLen">
       if (index > lastSet + 1) {
         fillEmpties(index);
@@ -630,19 +625,32 @@ public final class ${className} extends BaseDataValueVector implements <#if type
     }
 
     <#if !(type.major == "VarLen" || minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse" || minor.class == "Decimal28Dense" || minor.class == "Decimal38Dense" || minor.class == "Interval" || minor.class == "IntervalDay")>
-      public void setSafe(int index, ${minor.javaType!type.javaType} value) {
-        <#if type.major == "VarLen">
-        if (index > lastSet + 1) {
-          fillEmpties(index);
-        }
-        </#if>
-        bits.getMutator().setSafe(index, 1);
-        values.getMutator().setSafe(index, value);
-        setCount++;
+    public void setSafe(int index, ${minor.javaType!type.javaType} value) {
+      <#if type.major == "VarLen">
+      if (index > lastSet + 1) {
+        fillEmpties(index);
       }
+      </#if>
+      bits.getMutator().setSafe(index, 1);
+      values.getMutator().setSafe(index, value);
+      setCount++;
+    }
 
     </#if>
+    <#if minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse">
+    public void set(int index, BigDecimal value) {
+      bits.getMutator().set(index, 1);
+      values.getMutator().set(index, value);
+      setCount++;
+    }
 
+    public void setSafe(int index, BigDecimal value) {
+      bits.getMutator().setSafe(index, 1);
+      values.getMutator().setSafe(index, value);
+      setCount++;
+    }
+
+    </#if>
     @Override
     public void setValueCount(int valueCount) {
       assert valueCount >= 0;

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/RepeatedValueVectors.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/RepeatedValueVectors.java b/exec/vector/src/main/codegen/templates/RepeatedValueVectors.java
index 2a758eb..159a8e7 100644
--- a/exec/vector/src/main/codegen/templates/RepeatedValueVectors.java
+++ b/exec/vector/src/main/codegen/templates/RepeatedValueVectors.java
@@ -160,23 +160,23 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
     }
   }
 
-    public void copyFrom(int inIndex, int outIndex, Repeated${minor.class}Vector v) {
-      final Accessor vAccessor = v.getAccessor();
-      final int count = vAccessor.getInnerValueCountAt(inIndex);
-      mutator.startNewValue(outIndex);
-      for (int i = 0; i < count; i++) {
-        mutator.add(outIndex, vAccessor.get(inIndex, i));
-      }
+  public void copyFrom(int inIndex, int outIndex, Repeated${minor.class}Vector v) {
+    final Accessor vAccessor = v.getAccessor();
+    final int count = vAccessor.getInnerValueCountAt(inIndex);
+    mutator.startNewValue(outIndex);
+    for (int i = 0; i < count; i++) {
+      mutator.add(outIndex, vAccessor.get(inIndex, i));
     }
+  }
 
-    public void copyFromSafe(int inIndex, int outIndex, Repeated${minor.class}Vector v) {
-      final Accessor vAccessor = v.getAccessor();
-      final int count = vAccessor.getInnerValueCountAt(inIndex);
-      mutator.startNewValue(outIndex);
-      for (int i = 0; i < count; i++) {
-        mutator.addSafe(outIndex, vAccessor.get(inIndex, i));
-      }
+  public void copyFromSafe(int inIndex, int outIndex, Repeated${minor.class}Vector v) {
+    final Accessor vAccessor = v.getAccessor();
+    final int count = vAccessor.getInnerValueCountAt(inIndex);
+    mutator.startNewValue(outIndex);
+    for (int i = 0; i < count; i++) {
+      mutator.addSafe(outIndex, vAccessor.get(inIndex, i));
     }
+  }
 
   public boolean allocateNewSafe() {
     /* boolean to keep track if all the memory allocation were successful
@@ -236,7 +236,6 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
   }
 
   <#else>
-
   @Override
   public void allocateNew(int valueCount, int innerValueCount) {
     clear();
@@ -258,7 +257,6 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
   }
 
   </#if>
-
   // This is declared a subclass of the accessor declared inside of FixedWidthVector, this is also used for
   // variable length vectors, as they should ahve consistent interface as much as possible, if they need to diverge
   // in the future, the interface shold be declared in the respective value vector superclasses for fixed and variable
@@ -348,7 +346,6 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
     }
 
     <#else>
-
     public void addSafe(int index, ${minor.javaType!type.javaType} srcValue) {
       final int nextOffset = offsets.getAccessor().get(index+1);
       values.getMutator().setSafe(nextOffset, srcValue);
@@ -356,7 +353,6 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
     }
 
     </#if>
-
     public void setSafe(int index, Repeated${minor.class}Holder h) {
       final ${minor.class}Holder ih = new ${minor.class}Holder();
       final ${minor.class}Vector.Accessor hVectorAccessor = h.vector.getAccessor();
@@ -385,8 +381,16 @@ public final class Repeated${minor.class}Vector extends BaseRepeatedValueVector
       values.getMutator().setSafe(nextOffset, <#list fields as field>${field.name}<#if field_has_next>, </#if></#list>);
       offsets.getMutator().setSafe(arrayIndex+1, nextOffset+1);
     }
+
     </#if>
+    <#if minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse">
+    public void addSafe(int index, BigDecimal value) {
+      int nextOffset = offsets.getAccessor().get(index+1);
+      values.getMutator().setSafe(nextOffset, value);
+      offsets.getMutator().setSafe(index+1, nextOffset+1);
+    }
 
+    </#if>
     protected void add(int index, ${minor.class}Holder holder) {
       int nextOffset = offsets.getAccessor().get(index+1);
       values.getMutator().set(nextOffset, holder);

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/codegen/templates/VariableLengthVectors.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/VariableLengthVectors.java b/exec/vector/src/main/codegen/templates/VariableLengthVectors.java
index e970271..105ea47 100644
--- a/exec/vector/src/main/codegen/templates/VariableLengthVectors.java
+++ b/exec/vector/src/main/codegen/templates/VariableLengthVectors.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

http://git-wip-us.apache.org/repos/asf/drill/blob/381eab66/exec/vector/src/main/java/org/apache/drill/exec/record/MaterializedField.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/java/org/apache/drill/exec/record/MaterializedField.java b/exec/vector/src/main/java/org/apache/drill/exec/record/MaterializedField.java
index 92019ec..e192107 100644
--- a/exec/vector/src/main/java/org/apache/drill/exec/record/MaterializedField.java
+++ b/exec/vector/src/main/java/org/apache/drill/exec/record/MaterializedField.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,11 @@ import org.apache.drill.exec.expr.BasicTypeHelper;
 import org.apache.drill.exec.proto.UserBitShared.NamePart;
 import org.apache.drill.exec.proto.UserBitShared.SerializedField;
 
+/**
+ * Meta-data description of a column characterized by a name and a type
+ * (including both data type and cardinality AKA mode). For map types,
+ * the description includes the nested columns.)
+ */
 
 public class MaterializedField {
   private final String name;
@@ -44,7 +49,7 @@ public class MaterializedField {
 
   public static MaterializedField create(SerializedField serField){
     LinkedHashSet<MaterializedField> children = new LinkedHashSet<>();
-    for (SerializedField sf:serField.getChildList()) {
+    for (SerializedField sf : serField.getChildList()) {
       children.add(MaterializedField.create(sf));
     }
     return new MaterializedField(serField.getNamePart().getName(), serField.getMajorType(), children);
@@ -61,7 +66,6 @@ public class MaterializedField {
     return serializedFieldBuilder.build();
   }
 
-
   public SerializedField.Builder getAsBuilder(){
     return SerializedField.newBuilder()
         .setMajorType(type)
@@ -110,7 +114,6 @@ public class MaterializedField {
 //    return seg.getNameSegment().getPath();
 //  }
 
-
   // TODO: rewrite without as direct match rather than conversion then match.
   public boolean matches(SerializedField field){
     MaterializedField f = create(field);
@@ -142,41 +145,17 @@ public class MaterializedField {
 //    return sb.toString();
 //  }
 
-  public String getPath() {
-    return getName();
-  }
-
-  public String getLastName() {
-    return getName();
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public int getWidth() {
-    return type.getWidth();
-  }
-
-  public MajorType getType() {
-    return type;
-  }
-
-  public int getScale() {
-      return type.getScale();
-  }
-  public int getPrecision() {
-      return type.getPrecision();
-  }
-  public boolean isNullable() {
-    return type.getMode() == DataMode.OPTIONAL;
-  }
-
-  public DataMode getDataMode() {
-    return type.getMode();
-  }
-
-  public MaterializedField getOtherNullableVersion(){
+  public String getPath() { return getName(); }
+  public String getLastName() { return getName(); }
+  public String getName() { return name; }
+  public int getWidth() { return type.getWidth(); }
+  public MajorType getType() { return type; }
+  public int getScale() { return type.getScale(); }
+  public int getPrecision() { return type.getPrecision(); }
+  public boolean isNullable() { return type.getMode() == DataMode.OPTIONAL; }
+  public DataMode getDataMode() { return type.getMode(); }
+
+  public MaterializedField getOtherNullableVersion() {
     MajorType mt = type;
     DataMode newDataMode = null;
     switch (mt.getMode()){
@@ -220,7 +199,6 @@ public class MaterializedField {
             Objects.equals(this.type, other.type);
   }
 
-
   @Override
   public String toString() {
     final int maxLen = 10;
@@ -228,7 +206,6 @@ public class MaterializedField {
     return name + "(" + type.getMinorType().name() + ":" + type.getMode().name() + ")" + childStr;
   }
 
-
   private String toString(Collection<?> collection, int maxLen) {
     StringBuilder builder = new StringBuilder();
     builder.append("[");