drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From par...@apache.org
Subject [1/7] drill git commit: DRILL-5419: Calculate return string length for literals & some string functions
Date Sat, 13 May 2017 17:38:59 GMT
Repository: drill
Updated Branches:
  refs/heads/master 41ffed50f -> 0dc237e31


http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/ColumnDef.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/ColumnDef.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/ColumnDef.java
index 2300990..c1137bd 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/ColumnDef.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/ColumnDef.java
@@ -37,9 +37,8 @@ public class ColumnDef {
   public ColumnDef(MockColumn mockCol) {
     this.mockCol = mockCol;
     name = mockCol.getName();
-    if (mockCol.getMinorType() == MinorType.VARCHAR &&
-        mockCol.getWidth() > 0) {
-      width = mockCol.getWidth();
+    if (mockCol.getMinorType() == MinorType.VARCHAR && mockCol.getPrecision() > 0) {
+      width = mockCol.getPrecision();
     } else {
       width = TypeHelper.getSize(mockCol.getMajorType());
     }

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.java
index daadcfc..45b3a8d 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.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
@@ -99,6 +99,7 @@ public class PreparedStatementProvider {
       .put(MinorType.TIME, Time.class.getName())
       .put(MinorType.TIMESTAMP, Timestamp.class.getName())
       .put(MinorType.VARBINARY, byte[].class.getName())
+      .put(MinorType.INTERVAL, Period.class.getName())
       .put(MinorType.INTERVALYEAR, Period.class.getName())
       .put(MinorType.INTERVALDAY, Period.class.getName())
       .put(MinorType.MAP, Object.class.getName())
@@ -354,7 +355,7 @@ public class PreparedStatementProvider {
     /**
      * For numeric data, this is the maximum precision.
      * For character data, this is the length in characters.
-     * For datetime datatypes, this is the length in characters of the String representation
+     * For datetime data types, this is the length in characters of the String representation
      *    (assuming the maximum allowed precision of the fractional seconds component).
      * For binary data, this is the length in bytes.
      * For all other types 0 is returned where the column size is not applicable.

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestEarlyLimit0Optimization.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestEarlyLimit0Optimization.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestEarlyLimit0Optimization.java
index 70b0cb3..44035c5 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestEarlyLimit0Optimization.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestEarlyLimit0Optimization.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
@@ -57,7 +57,7 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
         "CAST(salary AS FLOAT) AS fsalary, " +
         "CAST((CASE WHEN marital_status = 'S' THEN true ELSE false END) AS BOOLEAN) AS single, " +
         "CAST(education_level AS VARCHAR(60)) AS education_level," +
-        "CAST(gender AS CHAR) AS gender " +
+        "CAST(gender AS CHAR(1)) AS gender " +
         "FROM cp.`employee.json` " +
         "ORDER BY employee_id " +
         "LIMIT 1;", viewName));
@@ -121,7 +121,7 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
     @SuppressWarnings("unchecked")
     final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList(
         Pair.of(SchemaPath.getSimplePath("employee_id"), Types.optional(TypeProtos.MinorType.INT)),
-        Pair.of(SchemaPath.getSimplePath("full_name"), Types.optional(TypeProtos.MinorType.VARCHAR)),
+        Pair.of(SchemaPath.getSimplePath("full_name"), Types.withPrecision(TypeProtos.MinorType.VARCHAR, TypeProtos.DataMode.OPTIONAL, 25)),
         Pair.of(SchemaPath.getSimplePath("position_id"), Types.optional(TypeProtos.MinorType.INT)),
         Pair.of(SchemaPath.getSimplePath("department_id"), Types.optional(TypeProtos.MinorType.BIGINT)),
         Pair.of(SchemaPath.getSimplePath("birth_date"), Types.optional(TypeProtos.MinorType.DATE)),
@@ -129,8 +129,8 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
         Pair.of(SchemaPath.getSimplePath("salary"), Types.optional(TypeProtos.MinorType.FLOAT8)),
         Pair.of(SchemaPath.getSimplePath("fsalary"), Types.optional(TypeProtos.MinorType.FLOAT4)),
         Pair.of(SchemaPath.getSimplePath("single"), Types.required(TypeProtos.MinorType.BIT)),
-        Pair.of(SchemaPath.getSimplePath("education_level"), Types.optional(TypeProtos.MinorType.VARCHAR)),
-        Pair.of(SchemaPath.getSimplePath("gender"), Types.optional(TypeProtos.MinorType.VARCHAR)));
+        Pair.of(SchemaPath.getSimplePath("education_level"), Types.withPrecision(TypeProtos.MinorType.VARCHAR, TypeProtos.DataMode.OPTIONAL, 60)),
+        Pair.of(SchemaPath.getSimplePath("gender"), Types.withPrecision(TypeProtos.MinorType.VARCHAR, TypeProtos.DataMode.OPTIONAL, 1)));
 
     testBuilder()
         .sqlQuery(wrapLimit0(String.format("SELECT * FROM %s", viewName)))
@@ -527,10 +527,11 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
     checkThatQueryPlanIsOptimized(query);
   }
 
-  public void concatTest(final String query) throws Exception {
+  public void concatTest(final String query, int precision, boolean isNullable) throws Exception {
     @SuppressWarnings("unchecked")
-    final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList(
-        Pair.of(SchemaPath.getSimplePath("c"), Types.optional(TypeProtos.MinorType.VARCHAR)));
+    final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema =
+        Lists.newArrayList(Pair.of(SchemaPath.getSimplePath("c"), Types.withPrecision(TypeProtos.MinorType.VARCHAR,
+            isNullable ? TypeProtos.DataMode.OPTIONAL : TypeProtos.DataMode.REQUIRED, precision)));
 
     testBuilder()
         .sqlQuery(query)
@@ -549,12 +550,12 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
 
   @Test
   public void concat() throws Exception {
-    concatTest("SELECT CONCAT(full_name, education_level) AS c FROM " + viewName);
+    concatTest("SELECT CONCAT(full_name, education_level) AS c FROM " + viewName, 85, false);
   }
 
   @Test
   public void concatOp() throws Exception {
-    concatTest("SELECT full_name || education_level AS c FROM " + viewName);
+    concatTest("SELECT full_name || education_level AS c FROM " + viewName, 85, true);
   }
 
   @Test
@@ -601,7 +602,7 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
     @SuppressWarnings("unchecked")
     final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList(
         Pair.of(SchemaPath.getSimplePath("b"), Types.required(TypeProtos.MinorType.BIT)),
-        Pair.of(SchemaPath.getSimplePath("c"), Types.optional(TypeProtos.MinorType.VARCHAR)),
+        Pair.of(SchemaPath.getSimplePath("c"), Types.withPrecision(TypeProtos.MinorType.VARCHAR, TypeProtos.DataMode.OPTIONAL, 85)),
         Pair.of(SchemaPath.getSimplePath("d"), Types.optional(TypeProtos.MinorType.INT)),
         Pair.of(SchemaPath.getSimplePath("e"), Types.optional(TypeProtos.MinorType.BIT)),
         Pair.of(SchemaPath.getSimplePath("g"), Types.optional(TypeProtos.MinorType.BIT)),
@@ -631,10 +632,10 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
     checkThatQueryPlanIsOptimized(query);
   }
 
-  public void substringTest(final String query) throws Exception {
+  public void substringTest(final String query, int precision) throws Exception {
     @SuppressWarnings("unchecked")
     final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList(
-        Pair.of(SchemaPath.getSimplePath("s"), Types.optional(TypeProtos.MinorType.VARCHAR)));
+        Pair.of(SchemaPath.getSimplePath("s"), Types.withPrecision(TypeProtos.MinorType.VARCHAR, TypeProtos.DataMode.OPTIONAL, precision)));
 
     testBuilder()
         .sqlQuery(query)
@@ -653,11 +654,11 @@ public class TestEarlyLimit0Optimization extends BaseTestQuery {
 
   @Test
   public void substring() throws Exception {
-    substringTest("SELECT SUBSTRING(full_name, 1, 5) AS s FROM " + viewName);
+    substringTest("SELECT SUBSTRING(full_name, 1, 5) AS s FROM " + viewName, Types.MAX_VARCHAR_LENGTH);
   }
 
   @Test
   public void substr() throws Exception {
-    substringTest("SELECT SUBSTR(full_name, 1, 5) AS s FROM " + viewName);
+    substringTest("SELECT SUBSTR(full_name, 1, 5) AS s FROM " + viewName, Types.MAX_VARCHAR_LENGTH);
   }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/PreparedStatementTestBase.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/PreparedStatementTestBase.java b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/PreparedStatementTestBase.java
new file mode 100644
index 0000000..814414c
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/PreparedStatementTestBase.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.work.prepare;
+
+import org.apache.drill.BaseTestQuery;
+import org.apache.drill.exec.proto.UserBitShared;
+import org.apache.drill.exec.proto.UserProtos;
+import org.apache.drill.exec.store.ischema.InfoSchemaConstants;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class PreparedStatementTestBase extends BaseTestQuery {
+
+  /* Helper method which creates a prepared statement for given query. */
+  protected UserProtos.PreparedStatement createPrepareStmt(String query,
+                                                        boolean expectFailure,
+                                                        UserBitShared.DrillPBError.ErrorType errorType) throws Exception {
+    UserProtos.CreatePreparedStatementResp resp = client.createPreparedStatement(query).get();
+
+    if (expectFailure) {
+      assertEquals(UserProtos.RequestStatus.FAILED, resp.getStatus());
+      assertEquals(errorType, resp.getError().getErrorType());
+    } else {
+      String message = resp.hasError() ? resp.getError().getMessage() : "No errors";
+      assertEquals(message, UserProtos.RequestStatus.OK, resp.getStatus());
+    }
+
+    return resp.getPreparedStatement();
+  }
+
+  protected void verifyMetadata(List<ExpectedColumnResult> expMetadata,
+                                     List<UserProtos.ResultColumnMetadata> actMetadata) {
+    assertEquals(expMetadata.size(), actMetadata.size());
+
+    int i = 0;
+    for (ExpectedColumnResult exp : expMetadata) {
+      UserProtos.ResultColumnMetadata act = actMetadata.get(i++);
+
+      assertTrue("Failed to find the expected column metadata: " + exp + ". Was: " + toString(act), exp.isEqualsTo(act));
+    }
+  }
+
+  protected static class ExpectedColumnResult {
+    final String columnName;
+    final String type;
+    final boolean nullable;
+    final int displaySize;
+    final int precision;
+    final int scale;
+    final boolean signed;
+    final String className;
+
+    ExpectedColumnResult(String columnName, String type, boolean nullable, int displaySize, int precision, int scale,
+                         boolean signed, String className) {
+      this.columnName = columnName;
+      this.type = type;
+      this.nullable = nullable;
+      this.displaySize = displaySize;
+      this.precision = precision;
+      this.scale = scale;
+      this.signed = signed;
+      this.className = className;
+    }
+
+    boolean isEqualsTo(UserProtos.ResultColumnMetadata result) {
+      return
+          result.getCatalogName().equals(InfoSchemaConstants.IS_CATALOG_NAME) &&
+              result.getSchemaName().isEmpty() &&
+              result.getTableName().isEmpty() &&
+              result.getColumnName().equals(columnName) &&
+              result.getLabel().equals(columnName) &&
+              result.getDataType().equals(type) &&
+              result.getIsNullable() == nullable &&
+              result.getPrecision() == precision &&
+              result.getScale() == scale &&
+              result.getSigned() == signed &&
+              result.getDisplaySize() == displaySize &&
+              result.getClassName().equals(className) &&
+              result.getSearchability() == UserProtos.ColumnSearchability.ALL &&
+              result.getAutoIncrement() == false &&
+              result.getCaseSensitivity() == false &&
+              result.getUpdatability() == UserProtos.ColumnUpdatability.READ_ONLY &&
+              result.getIsAliased() == true &&
+              result.getIsCurrency() == false;
+    }
+
+    @Override
+    public String toString() {
+      return "ExpectedColumnResult[" +
+          "columnName='" + columnName + '\'' +
+          ", type='" + type + '\'' +
+          ", nullable=" + nullable +
+          ", displaySize=" + displaySize +
+          ", precision=" + precision +
+          ", scale=" + scale +
+          ", signed=" + signed +
+          ", className='" + className + '\'' +
+          ']';
+    }
+  }
+
+  private static String toString(UserProtos.ResultColumnMetadata metadata) {
+    return "ResultColumnMetadata[" +
+        "columnName='" + metadata.getColumnName() + '\'' +
+        ", type='" + metadata.getDataType() + '\'' +
+        ", nullable=" + metadata.getIsNullable() +
+        ", displaySize=" + metadata.getDisplaySize() +
+        ", precision=" + metadata.getPrecision() +
+        ", scale=" + metadata.getScale() +
+        ", signed=" + metadata.getSigned() +
+        ", className='" + metadata.getClassName() + '\'' +
+        ']';
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestLimit0VsRegularQueriesMetadata.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestLimit0VsRegularQueriesMetadata.java b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestLimit0VsRegularQueriesMetadata.java
new file mode 100644
index 0000000..f6a9401
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestLimit0VsRegularQueriesMetadata.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.work.prepare;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.drill.common.types.Types;
+import org.apache.drill.exec.ExecConstants;
+import org.junit.Test;
+
+import java.util.List;
+
+public class TestLimit0VsRegularQueriesMetadata extends PreparedStatementTestBase {
+
+  @Test
+  public void stringCasts() throws Exception {
+    String query = "select\n" +
+        "cast(col_int as varchar(30)) as col_int,\n" +
+        "cast(col_vrchr as varchar(31)) as col_vrchr,\n" +
+        "cast(col_dt as varchar(32)) as col_dt,\n" +
+        "cast(col_tim as varchar(33)) as col_tim,\n" +
+        "cast(col_tmstmp as varchar(34)) as col_tmstmp,\n" +
+        "cast(col_flt as varchar(35)) as col_flt,\n" +
+        "cast(col_intrvl_yr as varchar(36)) as col_intrvl_yr,\n" +
+        "cast(col_bln as varchar(37)) as col_bln\n" +
+        "from cp.`parquet/alltypes_optional.parquet`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_int", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_vrchr", "CHARACTER VARYING", true, 31, 31, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_dt", "CHARACTER VARYING", true, 32, 32, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_tim", "CHARACTER VARYING", true, 33, 33, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_tmstmp", "CHARACTER VARYING", true, 34, 34, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_flt", "CHARACTER VARYING", true, 35, 35, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_intrvl_yr", "CHARACTER VARYING", true, 36, 36, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_bln", "CHARACTER VARYING", true, 37, 37, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void stringCastForDecimal() throws Exception {
+    try {
+      test("alter session set `planner.enable_decimal_data_type` = true");
+      String query = "select cast(commission_pct as varchar(50)) as commission_pct from cp.`parquet/fixedlenDecimal.parquet`";
+      List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+          new ExpectedColumnResult("commission_pct", "CHARACTER VARYING", true, 50, 50, 0, false, String.class.getName()));
+
+      verifyResults(query, expectedMetadata);
+    } finally {
+      test("alter session reset `planner.enable_decimal_data_type`");
+    }
+  }
+
+  @Test
+  public void constants() throws Exception {
+    String query = "select\n" +
+        "'aaa' as col_a,\n" +
+        "10 as col_i\n," +
+        "cast(null as varchar(5)) as col_n\n," +
+        "cast('aaa' as varchar(5)) as col_a_short,\n" +
+        "cast(10 as varchar(5)) as col_i_short,\n" +
+        "cast('aaaaaaaaaaaaa' as varchar(5)) as col_a_long,\n" +
+        "cast(1000000000 as varchar(5)) as col_i_long\n" +
+        "from (values(1))";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_a", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_i", "INTEGER", false, 11, 0, 0, true, Integer.class.getName()),
+        new ExpectedColumnResult("col_n", "CHARACTER VARYING", true, 5, 5, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_a_short", "CHARACTER VARYING", false, 5, 5, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_i_short", "CHARACTER VARYING", false, 5, 5, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_a_long", "CHARACTER VARYING", false, 5, 5, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_i_long", "CHARACTER VARYING", false, 5, 5, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void windowFunctions() throws Exception {
+    String query = "select\n" +
+        "lead(sales_country) over (partition by sales_country order by region_id) as col_lead,\n" +
+        "lag(sales_country) over (partition by sales_country order by region_id) as col_lag,\n" +
+        "first_value(sales_country) over (partition by sales_country order by region_id) as col_first_value,\n" +
+        "last_value(sales_country) over (partition by sales_country order by region_id) as col_last_value\n" +
+        "from (select cast(sales_country as varchar(30)) as sales_country, region_id from cp.`region.json`)";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_lead", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_lag", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_first_value", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_last_value", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void functionsWithSameInOutLength() throws Exception {
+    String query = "select\n" +
+        "lower(sales_city) as lower_col,\n" +
+        "upper(sales_city) as upper_col,\n" +
+        "initcap(sales_city) as initcap_col,\n" +
+        "reverse(sales_city) as reverse_col,\n" +
+        "lower(cast(sales_city as varchar(30))) as lower_cast_col,\n" +
+        "upper(cast(sales_city as varchar(30))) as upper_cast_col,\n" +
+        "initcap(cast(sales_city as varchar(30))) as initcap_cast_col,\n" +
+        "reverse(cast(sales_city as varchar(30))) as reverse_cast_col\n" +
+        "from cp.`region.json`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("lower_col", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("upper_col", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("initcap_col", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("reverse_col", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("lower_cast_col", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("upper_cast_col", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("initcap_cast_col", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName()),
+        new ExpectedColumnResult("reverse_cast_col", "CHARACTER VARYING", true, 30, 30, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void ifExpression() throws Exception {
+    String query = "select\n" +
+        "case when sales_state_province = 'CA' then 'a' when sales_state_province = 'DB' then 'aa' else 'aaa' end as col_123,\n" +
+        "case when sales_state_province = 'CA' then 'aa' when sales_state_province = 'DB' then 'a' else 'aaa' end as col_213,\n" +
+        "case when sales_state_province = 'CA' then 'a' when sales_state_province = 'DB' then 'aaa' else 'aa' end as col_132,\n" +
+        "case when sales_state_province = 'CA' then 'aa' when sales_state_province = 'DB' then 'aaa' else 'a' end as col_231,\n" +
+        "case when sales_state_province = 'CA' then 'aaa' when sales_state_province = 'DB' then 'aa' else 'a' end as col_321,\n" +
+        "case when sales_state_province = 'CA' then 'aaa' when sales_state_province = 'DB' then 'a' else 'aa' end as col_312,\n" +
+        "case when sales_state_province = 'CA' then sales_state_province when sales_state_province = 'DB' then 'a' else 'aa' end as col_unk1,\n" +
+        "case when sales_state_province = 'CA' then 'aaa' when sales_state_province = 'DB' then sales_state_province else 'aa' end as col_unk2,\n" +
+        "case when sales_state_province = 'CA' then 'aaa' when sales_state_province = 'DB' then 'a' else sales_state_province end as col_unk3\n" +
+        "from cp.`region.json`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_123", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_213", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_132", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_231", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_321", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_312", "CHARACTER VARYING", false, 3, 3, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_unk1", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_unk2", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_unk3", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void coalesce() throws Exception {
+    String query = "select\n" +
+        "coalesce(cast(sales_city as varchar(10)), 'unknown') as col_first_cond,\n" +
+        "coalesce(cast(sales_city as varchar(10)), cast('unknown' as varchar(20))) as col_second_cond,\n" +
+        "coalesce(cast(null as varchar(10)), 'unknown') as col_null,\n" +
+        "coalesce(sales_city, sales_country) as col_unk\n" +
+        "from cp.`region.json`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_first_cond", "CHARACTER VARYING", true, 10, 10, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_second_cond", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_null", "CHARACTER VARYING", true, 10, 10, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_unk", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void pad() throws Exception {
+    String query = "SELECT\n" +
+        "%1$s(cast(sales_city as varchar(10)), 10, 'A') as col_same_pad,\n" +
+        "%1$s(cast(sales_city as varchar(10)), 0, 'A') as col_zero_pad,\n" +
+        "%1$s(cast(sales_city as varchar(10)), -1, 'A') as col_negative_pad,\n" +
+        "%1$s(cast(sales_city as varchar(10)), 9, 'A') as col_lower_pad,\n" +
+        "%1$s(cast(sales_city as varchar(10)), 20, 'A') as col_greater_pad,\n" +
+        "%1$s(sales_city, 10, 'A') as col_unk_source_length,\n" +
+        "%1$s(cast(sales_city as varchar(10)), '10', 'A') as col_length_char\n" +
+        "from cp.`region.json`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_same_pad", "CHARACTER VARYING", true, 10, 10, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_zero_pad", "CHARACTER VARYING", true, 0, 0, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_negative_pad", "CHARACTER VARYING", true, 0, 0, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_lower_pad", "CHARACTER VARYING", true, 9, 9, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_greater_pad", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_unk_source_length", "CHARACTER VARYING", true, 10, 10, 0, false, String.class.getName()),
+        new ExpectedColumnResult("col_length_char", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName())
+    );
+
+    List<String> padFunctions = Lists.newArrayList("rpad", "lpad");
+    for (String function : padFunctions) {
+      verifyResults(String.format(query, function), expectedMetadata);
+    }
+  }
+
+  @Test
+  public void concat() throws Exception {
+    String query = "select\n" +
+        "concat(cast(sales_city as varchar(10)), cast(sales_city as varchar(10))) as concat_two_casts,\n" +
+        "concat(cast(sales_city as varchar(60000)), cast(sales_city as varchar(60000))) as concat_max_length,\n" +
+        "concat(cast(sales_city as varchar(10)), sales_city) as concat_one_unknown,\n" +
+        "concat(sales_city, sales_city) as concat_two_unknown,\n" +
+        "concat(cast(sales_city as varchar(10)), 'a') as concat_one_constant,\n" +
+        "concat('a', 'a') as concat_two_constants,\n" +
+        "concat(cast(sales_city as varchar(10)), cast(null as varchar(10))) as concat_right_null,\n" +
+        "concat(cast(null as varchar(10)), cast(sales_city as varchar(10))) as concat_left_null,\n" +
+        "concat(cast(null as varchar(10)), cast(null as varchar(10))) as concat_both_null,\n" +
+        "concat(cast(sales_district_id as integer), '_D') as concat_with_int,\n" +
+
+        "cast(sales_city as varchar(10)) || cast(sales_city as varchar(10)) as concat_op_two_casts,\n" +
+        "cast(sales_city as varchar(60000)) || cast(sales_city as varchar(60000)) as concat_op_max_length,\n" +
+        "cast(sales_city as varchar(10)) || sales_city as concat_op_one_unknown,\n" +
+        "sales_city || sales_city as concat_op_two_unknown,\n" +
+        "cast(sales_city as varchar(10)) || 'a' as concat_op_one_constant,\n" +
+        "'a' || 'a' as concat_op_two_constants,\n" +
+        "cast(sales_city as varchar(10)) || cast(null as varchar(10)) as concat_op_right_null,\n" +
+        "cast(null as varchar(10)) || cast(sales_city as varchar(10)) as concat_op_left_null,\n" +
+        "cast(null as varchar(10)) || cast(null as varchar(10)) as concat_op_both_null,\n" +
+        "cast(sales_district_id as integer) || '_D' as concat_op_with_int\n" +
+        "from cp.`region.json`";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("concat_two_casts", "CHARACTER VARYING", false, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_max_length", "CHARACTER VARYING", false, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_one_unknown", "CHARACTER VARYING", false, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_two_unknown", "CHARACTER VARYING", false, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_one_constant", "CHARACTER VARYING", false, 11, 11, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_two_constants", "CHARACTER VARYING", false, 2, 2, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_right_null", "CHARACTER VARYING", false, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_left_null", "CHARACTER VARYING", false, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_both_null", "CHARACTER VARYING", false, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_with_int", "CHARACTER VARYING", false, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+
+        new ExpectedColumnResult("concat_op_two_casts", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_max_length", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_one_unknown", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_two_unknown", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_one_constant", "CHARACTER VARYING", true, 11, 11, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_two_constants", "CHARACTER VARYING", false, 2, 2, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_right_null", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_left_null", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_both_null", "CHARACTER VARYING", true, 20, 20, 0, false, String.class.getName()),
+        new ExpectedColumnResult("concat_op_with_int", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName())
+        );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void unionWithConstants() throws Exception {
+    String query = "select * from (\n" +
+        "select cast('AAA' as varchar(3)) as col_const from (values(1))\n" +
+        "union all\n" +
+        "select cast('AAA' as varchar(5)) as col_const from (values(1))\n" +
+        ")";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_const", "CHARACTER VARYING", false, 5, 5, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  @Test
+  public void unionWithOptionalRequired() throws Exception {
+    String query = "select * from (\n" +
+        "select cast('AAA' as varchar(10)) as col_const from (values(1))\n" +
+        "union all\n" +
+        "select cast(sales_city as varchar(10)) as col_const from cp.`region.json`\n" +
+        ")";
+
+    List<ExpectedColumnResult> expectedMetadata = ImmutableList.of(
+        new ExpectedColumnResult("col_const", "CHARACTER VARYING", true, 10, 10, 0, false, String.class.getName())
+    );
+
+    verifyResults(query, expectedMetadata);
+  }
+
+  private void verifyResults(String query, List<ExpectedColumnResult> expectedMetadata) throws Exception {
+    // regular query
+    verifyMetadata(expectedMetadata, createPrepareStmt(query, false, null).getColumnsList());
+
+    // limit 0 query
+    try {
+      test("alter session set `%s` = true", ExecConstants.EARLY_LIMIT0_OPT_KEY);
+      verifyMetadata(expectedMetadata, createPrepareStmt(String.format("select * from (%s) t limit 0", query), false, null)
+          .getColumnsList());
+    } finally {
+      test("alter session reset `%s`", ExecConstants.EARLY_LIMIT0_OPT_KEY);
+    }
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestPreparedStatementProvider.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestPreparedStatementProvider.java b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestPreparedStatementProvider.java
index 15fbc4f..ca47a02 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestPreparedStatementProvider.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/work/prepare/TestPreparedStatementProvider.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
@@ -17,21 +17,12 @@
  */
 package org.apache.drill.exec.work.prepare;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 import java.sql.Date;
 import java.util.List;
 
-import org.apache.drill.BaseTestQuery;
+import org.apache.drill.common.types.Types;
 import org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType;
-import org.apache.drill.exec.proto.UserProtos.ColumnSearchability;
-import org.apache.drill.exec.proto.UserProtos.ColumnUpdatability;
-import org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp;
 import org.apache.drill.exec.proto.UserProtos.PreparedStatement;
-import org.apache.drill.exec.proto.UserProtos.RequestStatus;
-import org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata;
-import org.apache.drill.exec.store.ischema.InfoSchemaConstants;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
@@ -39,8 +30,7 @@ import com.google.common.collect.ImmutableList;
 /**
  * Tests for creating and executing prepared statements.
  */
-public class TestPreparedStatementProvider extends BaseTestQuery {
-  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestPreparedStatementProvider.class);
+public class TestPreparedStatementProvider extends PreparedStatementTestBase {
 
   /**
    * Simple query.
@@ -53,11 +43,11 @@ public class TestPreparedStatementProvider extends BaseTestQuery {
 
     List<ExpectedColumnResult> expMetadata = ImmutableList.of(
         new ExpectedColumnResult("region_id", "BIGINT", true, 20, 0, 0, true, Long.class.getName()),
-        new ExpectedColumnResult("sales_city", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
-        new ExpectedColumnResult("sales_state_province", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
-        new ExpectedColumnResult("sales_district", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
-        new ExpectedColumnResult("sales_region", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
-        new ExpectedColumnResult("sales_country", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_city", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_state_province", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_district", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_region", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_country", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
         new ExpectedColumnResult("sales_district_id", "BIGINT", true, 20, 0, 0, true, Long.class.getName())
     );
 
@@ -82,7 +72,7 @@ public class TestPreparedStatementProvider extends BaseTestQuery {
     PreparedStatement preparedStatement = createPrepareStmt(query, false, null);
 
     List<ExpectedColumnResult> expMetadata = ImmutableList.of(
-        new ExpectedColumnResult("sales_city", "CHARACTER VARYING", true, 65536, 65536, 0, false, String.class.getName()),
+        new ExpectedColumnResult("sales_city", "CHARACTER VARYING", true, Types.MAX_VARCHAR_LENGTH, Types.MAX_VARCHAR_LENGTH, 0, false, String.class.getName()),
         new ExpectedColumnResult("cnt", "BIGINT", false, 20, 0, 0, true, Long.class.getName())
     );
 
@@ -132,103 +122,4 @@ public class TestPreparedStatementProvider extends BaseTestQuery {
   public void invalidQueryValidationError() throws Exception {
     createPrepareStmt("SELECT * sdflkgdh", true, ErrorType.PARSE /** Drill returns incorrect error for parse error*/);
   }
-
-  /* Helper method which creates a prepared statement for given query. */
-  private static PreparedStatement createPrepareStmt(String query, boolean expectFailure, ErrorType errorType) throws Exception {
-    CreatePreparedStatementResp resp = client.createPreparedStatement(query).get();
-
-    assertEquals(expectFailure ? RequestStatus.FAILED : RequestStatus.OK, resp.getStatus());
-
-    if (expectFailure) {
-      assertEquals(errorType, resp.getError().getErrorType());
-    } else {
-      logger.error("Prepared statement creation failed: {}", resp.getError().getMessage());
-    }
-
-    return resp.getPreparedStatement();
-  }
-
-  private static class ExpectedColumnResult {
-    final String columnName;
-    final String type;
-    final boolean nullable;
-    final int displaySize;
-    final int precision;
-    final int scale;
-    final boolean signed;
-    final String className;
-
-    ExpectedColumnResult(String columnName, String type, boolean nullable, int displaySize, int precision, int scale,
-        boolean signed, String className) {
-      this.columnName = columnName;
-      this.type = type;
-      this.nullable = nullable;
-      this.displaySize = displaySize;
-      this.precision = precision;
-      this.scale = scale;
-      this.signed = signed;
-      this.className = className;
-    }
-
-    boolean isEqualsTo(ResultColumnMetadata result) {
-      return
-          result.getCatalogName().equals(InfoSchemaConstants.IS_CATALOG_NAME) &&
-          result.getSchemaName().isEmpty() &&
-          result.getTableName().isEmpty() &&
-          result.getColumnName().equals(columnName) &&
-          result.getLabel().equals(columnName) &&
-          result.getDataType().equals(type) &&
-          result.getIsNullable() == nullable &&
-          result.getPrecision() == precision &&
-          result.getScale() == scale &&
-          result.getSigned() == signed &&
-          result.getDisplaySize() == displaySize &&
-          result.getClassName().equals(className) &&
-          result.getSearchability() == ColumnSearchability.ALL &&
-          result.getAutoIncrement() == false &&
-          result.getCaseSensitivity() == false &&
-          result.getUpdatability() == ColumnUpdatability.READ_ONLY &&
-          result.getIsAliased() == true &&
-          result.getIsCurrency() == false;
-    }
-
-    @Override
-    public String toString() {
-      return "ExpectedColumnResult[" +
-          "columnName='" + columnName + '\'' +
-          ", type='" + type + '\'' +
-          ", nullable=" + nullable +
-          ", displaySize=" + displaySize +
-          ", precision=" + precision +
-          ", scale=" + scale +
-          ", signed=" + signed +
-          ", className='" + className + '\'' +
-          ']';
-    }
-  }
-
-  private static String toString(ResultColumnMetadata metadata) {
-    return "ResultColumnMetadata[" +
-        "columnName='" + metadata.getColumnName() + '\'' +
-        ", type='" + metadata.getDataType() + '\'' +
-        ", nullable=" + metadata.getIsNullable() +
-        ", displaySize=" + metadata.getDisplaySize() +
-        ", precision=" + metadata.getPrecision() +
-        ", scale=" + metadata.getScale() +
-        ", signed=" + metadata.getSigned() +
-        ", className='" + metadata.getClassName() + '\'' +
-        ']';
-  }
-
-  private static void verifyMetadata(List<ExpectedColumnResult> expMetadata,
-      List<ResultColumnMetadata> actMetadata) {
-    assertEquals(expMetadata.size(), actMetadata.size());
-
-    int i = 0;
-    for(ExpectedColumnResult exp : expMetadata) {
-      ResultColumnMetadata act = actMetadata.get(i++);
-
-      assertTrue("Failed to find the expected column metadata: " + exp + ". Was: " + toString(act), exp.isEqualsTo(act));
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
index 8e65869..359b0bc 100644
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.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
@@ -1024,7 +1024,7 @@ public class DatabaseMetaDataGetColumnsTest extends JdbcTestBase {
 
   @Test
   public void test_COLUMN_SIZE_hasRightValue_mdrOptVARCHAR() throws SQLException {
-    assertThat(getIntOrNull(mdrOptVARCHAR, "COLUMN_SIZE"), equalTo(65536));
+    assertThat(getIntOrNull(mdrOptVARCHAR, "COLUMN_SIZE"), equalTo(org.apache.drill.common.types.Types.MAX_VARCHAR_LENGTH));
   }
 
   @Test
@@ -2168,7 +2168,7 @@ public class DatabaseMetaDataGetColumnsTest extends JdbcTestBase {
   @Test
   public void test_CHAR_OCTET_LENGTH_hasRightValue_mdrOptVARCHAR() throws SQLException {
     assertThat( getIntOrNull( mdrOptVARCHAR, "CHAR_OCTET_LENGTH" ),
-        equalTo(65536 /* chars. (default of 65536) */
+        equalTo(org.apache.drill.common.types.Types.MAX_VARCHAR_LENGTH /* chars. (default of 65535) */
                          * 4  /* max. UTF-8 bytes per char. */ ) );
   }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/jdbc/src/test/java/org/apache/drill/jdbc/PreparedStatementTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/PreparedStatementTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/PreparedStatementTest.java
index 2e93864..f931e1f 100644
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/PreparedStatementTest.java
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/PreparedStatementTest.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
@@ -114,7 +114,7 @@ public class PreparedStatementTest extends JdbcTestBase {
         "SELECT " +
             "cast(1 as INTEGER ) as int_field, " +
             "cast(12384729 as BIGINT ) as bigint_field, " +
-            "'varchar_value' as varchar_field, " +
+            "cast('varchar_value' as varchar(50)) as varchar_field, " +
             "timestamp '2008-2-23 10:00:20.123' as ts_field, " +
             "date '2008-2-23' as date_field, " +
             "cast('99999912399.4567' as decimal(18, 5)) as decimal_field" +
@@ -123,7 +123,7 @@ public class PreparedStatementTest extends JdbcTestBase {
       List<ExpectedColumnResult> exp = ImmutableList.of(
           new ExpectedColumnResult("int_field", INTEGER, columnNoNulls, 11, 0, 0, true, Integer.class.getName()),
           new ExpectedColumnResult("bigint_field", BIGINT, columnNoNulls, 20, 0, 0, true, Long.class.getName()),
-          new ExpectedColumnResult("varchar_field", VARCHAR, columnNoNulls, 65536, 65536, 0, false, String.class.getName()),
+          new ExpectedColumnResult("varchar_field", VARCHAR, columnNoNulls, 50, 50, 0, false, String.class.getName()),
           new ExpectedColumnResult("ts_field", TIMESTAMP, columnNoNulls, 19, 0, 0, false, Timestamp.class.getName()),
           new ExpectedColumnResult("date_field", DATE, columnNoNulls, 10, 0, 0, false, Date.class.getName()),
           new ExpectedColumnResult("decimal_field", DECIMAL, columnNoNulls, 20, 18, 5, true, BigDecimal.class.getName())

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestInformationSchemaColumns.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestInformationSchemaColumns.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestInformationSchemaColumns.java
index 5faf4dc..6c43295 100644
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestInformationSchemaColumns.java
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestInformationSchemaColumns.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
@@ -1154,7 +1154,7 @@ public class TestInformationSchemaColumns extends JdbcTestBase {
 
   @Test
   public void test_CHARACTER_MAXIMUM_LENGTH_hasRightValue_mdrOptVARCHAR() throws SQLException {
-    assertThat(getIntOrNull(mdrOptVARCHAR, "CHARACTER_MAXIMUM_LENGTH"), equalTo(65536));
+    assertThat(getIntOrNull(mdrOptVARCHAR, "CHARACTER_MAXIMUM_LENGTH"), equalTo(org.apache.drill.common.types.Types.MAX_VARCHAR_LENGTH));
   }
 
   @Test
@@ -1318,7 +1318,7 @@ public class TestInformationSchemaColumns extends JdbcTestBase {
   @Test
   public void test_CHARACTER_OCTET_LENGTH_hasRightValue_mdrOptVARCHAR() throws SQLException {
     assertThat( getIntOrNull( mdrOptVARCHAR, "CHARACTER_OCTET_LENGTH" ),
-        equalTo(65536 /* chars. (default of 65536) */
+        equalTo(org.apache.drill.common.types.Types.MAX_VARCHAR_LENGTH /* chars. (default of 65535) */
                          * 4  /* max. UTF-8 bytes per char. */ ) );
   }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/exec/vector/src/main/codegen/templates/BasicTypeHelper.java
----------------------------------------------------------------------
diff --git a/exec/vector/src/main/codegen/templates/BasicTypeHelper.java b/exec/vector/src/main/codegen/templates/BasicTypeHelper.java
index 452c331..016199a 100644
--- a/exec/vector/src/main/codegen/templates/BasicTypeHelper.java
+++ b/exec/vector/src/main/codegen/templates/BasicTypeHelper.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,6 +31,7 @@ import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.exec.record.MaterializedField;
 import org.apache.drill.exec.vector.complex.RepeatedMapVector;
 import org.apache.drill.exec.util.CallBack;
+import org.apache.drill.common.types.Types;
 /*
  * This class is generated using freemarker and the ${.template_name} template.
  */
@@ -39,11 +40,6 @@ public class BasicTypeHelper {
 
   private static final int WIDTH_ESTIMATE = 50;
 
-  // Default length when casting to varchar : 65536 = 2^16
-  // This only defines an absolute maximum for values, setting
-  // a high value like this will not inflate the size for small values
-  public static final int VARCHAR_DEFAULT_CAST_LEN = 65536;
-
   protected static String buildErrorMessage(final String operation, final MinorType type, final DataMode mode) {
     return String.format("Unable to %s for minor type [%s] and mode [%s]", operation, type, mode);
   }
@@ -62,9 +58,9 @@ public class BasicTypeHelper {
                                minor.class?substring(0, 3) == "MSG"> + WIDTH_ESTIMATE</#if>;
   </#list>
 </#list>
-      case FIXEDCHAR: return major.getWidth();
-      case FIXED16CHAR: return major.getWidth();
-      case FIXEDBINARY: return major.getWidth();
+      case FIXEDCHAR: return major.getPrecision();
+      case FIXED16CHAR: return major.getPrecision();
+      case FIXEDBINARY: return major.getPrecision();
     }
     throw new UnsupportedOperationException(buildErrorMessage("get size", major));
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/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 e192107..bc1ec3a 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
@@ -157,7 +157,7 @@ public class MaterializedField {
 
   public MaterializedField getOtherNullableVersion() {
     MajorType mt = type;
-    DataMode newDataMode = null;
+    DataMode newDataMode;
     switch (mt.getMode()){
     case OPTIONAL:
       newDataMode = DataMode.REQUIRED;
@@ -199,16 +199,48 @@ public class MaterializedField {
             Objects.equals(this.type, other.type);
   }
 
+  /**
+   * <p>Creates materialized field string representation.
+   * Includes field name, its type with precision and scale if any and data mode.
+   * Nested fields if any are included. Number of nested fields to include is limited to 10.</p>
+   *
+   * <b>FIELD_NAME(TYPE(PRECISION,SCALE):DATA_MODE)[NESTED_FIELD_1, NESTED_FIELD_2]</b>
+   * <p>Example: ok(BIT:REQUIRED), col(VARCHAR(3):OPTIONAL), emp_id(DECIMAL28SPARSE(6,0):REQUIRED)</p>
+   *
+   * @return materialized field string representation
+   */
   @Override
   public String toString() {
     final int maxLen = 10;
-    String childStr = children != null && !children.isEmpty() ? toString(children, maxLen) : "";
-    return name + "(" + type.getMinorType().name() + ":" + type.getMode().name() + ")" + childStr;
-  }
+    String childString = children != null && !children.isEmpty() ? toString(children, maxLen) : "";
+    StringBuilder builder = new StringBuilder();
+    builder
+        .append(name)
+        .append("(")
+        .append(type.getMinorType().name());
+
+    if (type.hasPrecision()) {
+      builder.append("(");
+      builder.append(type.getPrecision());
+      if (type.hasScale()) {
+        builder.append(",");
+        builder.append(type.getScale());
+      }
+      builder.append(")");
+    }
+
+    builder
+        .append(":")
+        .append(type.getMode().name())
+        .append(")")
+        .append(childString);
+
+    return builder.toString();
+}
 
   private String toString(Collection<?> collection, int maxLen) {
     StringBuilder builder = new StringBuilder();
-    builder.append("[");
+    builder.append(" [");
     int i = 0;
     for (Iterator<?> iterator = collection.iterator(); iterator.hasNext() && i < maxLen; i++) {
       if (i > 0){

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g
----------------------------------------------------------------------
diff --git a/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g b/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g
index 600b791..12048b0 100644
--- a/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g
+++ b/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g
@@ -122,8 +122,8 @@ numType returns [MajorType type]
 	;
 
 charType returns [MajorType type]
-	:  VARCHAR typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARCHAR).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build(); }
-	|  VARBINARY typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARBINARY).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build();}	
+	:  VARCHAR typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARCHAR).setMode(DataMode.REQUIRED).setPrecision($typeLen.length.intValue()).build(); }
+	|  VARBINARY typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARBINARY).setMode(DataMode.REQUIRED).setPrecision($typeLen.length.intValue()).build();}
 	;
 
 precision returns [Integer value]
@@ -314,7 +314,7 @@ lookup returns [LogicalExpression e]
   | convertCall {$e = $convertCall.e; }
   | castCall {$e = $castCall.e; }
   | pathSegment {$e = new SchemaPath($pathSegment.seg, pos($pathSegment.start) ); }
-  | String {$e = new ValueExpressions.QuotedString($String.text, pos($String) ); }
+  | String {$e = new ValueExpressions.QuotedString($String.text, $String.text.length(), pos($String) ); }
   | OParen expression CParen  {$e = $expression.e; }
   | SingleQuote Identifier SingleQuote {$e = new SchemaPath($Identifier.text, pos($Identifier) ); }
   ;

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java b/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
index 85547bc..34736df 100644
--- a/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
+++ b/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.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
@@ -283,7 +283,7 @@ public class ExpressionStringBuilder extends AbstractExprVisitor<Void, StringBui
 
       // add size in parens
       sb.append("(");
-      sb.append(mt.getWidth());
+      sb.append(mt.getPrecision());
       sb.append(")");
       break;
     case DECIMAL9:

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/logical/src/main/java/org/apache/drill/common/expression/IfExpression.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/IfExpression.java b/logical/src/main/java/org/apache/drill/common/expression/IfExpression.java
index e85caa0..147129b 100644
--- a/logical/src/main/java/org/apache/drill/common/expression/IfExpression.java
+++ b/logical/src/main/java/org/apache/drill/common/expression/IfExpression.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
@@ -26,6 +26,7 @@ import org.apache.drill.common.expression.visitors.ExprVisitor;
 import org.apache.drill.common.types.TypeProtos.DataMode;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.common.types.TypeProtos.MinorType;
+import org.apache.drill.common.types.Types;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -77,7 +78,7 @@ public class IfExpression extends LogicalExpressionBase {
 
     public Builder setElse(LogicalExpression elseExpression) {
       this.elseExpression = elseExpression;
-            return this;
+      return this;
     }
 
     public Builder setIfCondition(IfCondition conditions) {
@@ -104,13 +105,14 @@ public class IfExpression extends LogicalExpressionBase {
       return outputType;
     }
 
-    MajorType majorType = elseExpression.getMajorType();
-    if (majorType.getMinorType() == MinorType.UNION) {
+    MajorType elseType = elseExpression.getMajorType();
+    MajorType ifType = ifCondition.expression.getMajorType();
+    if (elseType.getMinorType() == MinorType.UNION) {
       Set<MinorType> subtypes = Sets.newHashSet();
-      for (MinorType subtype : majorType.getSubTypeList()) {
+      for (MinorType subtype : elseType.getSubTypeList()) {
         subtypes.add(subtype);
       }
-      for (MinorType subtype : ifCondition.expression.getMajorType().getSubTypeList()) {
+      for (MinorType subtype : ifType.getSubTypeList()) {
         subtypes.add(subtype);
       }
       MajorType.Builder builder = MajorType.newBuilder().setMinorType(MinorType.UNION).setMode(DataMode.OPTIONAL);
@@ -119,17 +121,11 @@ public class IfExpression extends LogicalExpressionBase {
       }
       return builder.build();
     }
-    if (majorType.getMode() == DataMode.OPTIONAL) {
-      return majorType;
-    }
-
-    if (ifCondition.expression.getMajorType().getMode() == DataMode.OPTIONAL) {
-      assert ifCondition.expression.getMajorType().getMinorType() == majorType.getMinorType();
-
-      return ifCondition.expression.getMajorType();
-    }
 
-    return majorType;
+    MajorType.Builder builder = MajorType.newBuilder().setMinorType(ifType.getMinorType());
+    builder.setMode(elseType.getMode() == DataMode.OPTIONAL || ifType.getMode() == DataMode.OPTIONAL ? DataMode.OPTIONAL : elseType.getMode());
+    builder = Types.calculateTypePrecisionAndScale(ifType, elseType, builder);
+    return builder.build();
   }
 
   public static Builder newBuilder() {

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java b/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
index 662258d..556135f 100644
--- a/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.java
+++ b/logical/src/main/java/org/apache/drill/common/expression/ValueExpressions.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
@@ -51,8 +51,8 @@ public class ValueExpressions {
     return new BooleanExpression(Boolean.toString(b), ExpressionPosition.UNKNOWN);
   }
 
-  public static LogicalExpression getChar(String s){
-    return new QuotedString(s, ExpressionPosition.UNKNOWN);
+  public static LogicalExpression getChar(String s, int precision){
+    return new QuotedString(s, precision, ExpressionPosition.UNKNOWN);
   }
 
   public static LogicalExpression getDate(GregorianCalendar date) {
@@ -650,10 +650,13 @@ public class ValueExpressions {
 
   public static class QuotedString extends ValueExpression<String> {
 
-    private static final MajorType QUOTED_STRING_CONSTANT = Types.required(MinorType.VARCHAR);
+    public static final QuotedString EMPTY_STRING = new QuotedString("", 0, ExpressionPosition.UNKNOWN);
 
-    public QuotedString(String value, ExpressionPosition pos) {
+    private final int precision;
+
+    public QuotedString(String value, int precision, ExpressionPosition pos) {
       super(value, pos);
+      this.precision = precision;
     }
 
     public String getString() {
@@ -667,7 +670,7 @@ public class ValueExpressions {
 
     @Override
     public MajorType getMajorType() {
-      return QUOTED_STRING_CONSTANT;
+      return Types.withPrecision(MinorType.VARCHAR, DataMode.REQUIRED, precision);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java b/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java
index 07efdbf..ff5698a 100644
--- a/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java
+++ b/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java
@@ -850,18 +850,10 @@ public final class TypeProtos {
     // optional int32 width = 3;
     /**
      * <code>optional int32 width = 3;</code>
-     *
-     * <pre>
-     * optional width for fixed size values.
-     * </pre>
      */
     boolean hasWidth();
     /**
      * <code>optional int32 width = 3;</code>
-     *
-     * <pre>
-     * optional width for fixed size values.
-     * </pre>
      */
     int getWidth();
 
@@ -870,7 +862,7 @@ public final class TypeProtos {
      * <code>optional int32 precision = 4;</code>
      *
      * <pre>
-     * used for decimal types
+     * used for decimal types or as optional length for fixed size value
      * </pre>
      */
     boolean hasPrecision();
@@ -878,7 +870,7 @@ public final class TypeProtos {
      * <code>optional int32 precision = 4;</code>
      *
      * <pre>
-     * used for decimal types
+     * used for decimal types or as optional length for fixed size value
      * </pre>
      */
     int getPrecision();
@@ -1151,20 +1143,12 @@ public final class TypeProtos {
     private int width_;
     /**
      * <code>optional int32 width = 3;</code>
-     *
-     * <pre>
-     * optional width for fixed size values.
-     * </pre>
      */
     public boolean hasWidth() {
       return ((bitField0_ & 0x00000004) == 0x00000004);
     }
     /**
      * <code>optional int32 width = 3;</code>
-     *
-     * <pre>
-     * optional width for fixed size values.
-     * </pre>
      */
     public int getWidth() {
       return width_;
@@ -1177,7 +1161,7 @@ public final class TypeProtos {
      * <code>optional int32 precision = 4;</code>
      *
      * <pre>
-     * used for decimal types
+     * used for decimal types or as optional length for fixed size value
      * </pre>
      */
     public boolean hasPrecision() {
@@ -1187,7 +1171,7 @@ public final class TypeProtos {
      * <code>optional int32 precision = 4;</code>
      *
      * <pre>
-     * used for decimal types
+     * used for decimal types or as optional length for fixed size value
      * </pre>
      */
     public int getPrecision() {
@@ -1694,30 +1678,18 @@ public final class TypeProtos {
       private int width_ ;
       /**
        * <code>optional int32 width = 3;</code>
-       *
-       * <pre>
-       * optional width for fixed size values.
-       * </pre>
        */
       public boolean hasWidth() {
         return ((bitField0_ & 0x00000004) == 0x00000004);
       }
       /**
        * <code>optional int32 width = 3;</code>
-       *
-       * <pre>
-       * optional width for fixed size values.
-       * </pre>
        */
       public int getWidth() {
         return width_;
       }
       /**
        * <code>optional int32 width = 3;</code>
-       *
-       * <pre>
-       * optional width for fixed size values.
-       * </pre>
        */
       public Builder setWidth(int value) {
         bitField0_ |= 0x00000004;
@@ -1727,10 +1699,6 @@ public final class TypeProtos {
       }
       /**
        * <code>optional int32 width = 3;</code>
-       *
-       * <pre>
-       * optional width for fixed size values.
-       * </pre>
        */
       public Builder clearWidth() {
         bitField0_ = (bitField0_ & ~0x00000004);
@@ -1745,7 +1713,7 @@ public final class TypeProtos {
        * <code>optional int32 precision = 4;</code>
        *
        * <pre>
-       * used for decimal types
+       * used for decimal types or as optional length for fixed size value
        * </pre>
        */
       public boolean hasPrecision() {
@@ -1755,7 +1723,7 @@ public final class TypeProtos {
        * <code>optional int32 precision = 4;</code>
        *
        * <pre>
-       * used for decimal types
+       * used for decimal types or as optional length for fixed size value
        * </pre>
        */
       public int getPrecision() {
@@ -1765,7 +1733,7 @@ public final class TypeProtos {
        * <code>optional int32 precision = 4;</code>
        *
        * <pre>
-       * used for decimal types
+       * used for decimal types or as optional length for fixed size value
        * </pre>
        */
       public Builder setPrecision(int value) {
@@ -1778,7 +1746,7 @@ public final class TypeProtos {
        * <code>optional int32 precision = 4;</code>
        *
        * <pre>
-       * used for decimal types
+       * used for decimal types or as optional length for fixed size value
        * </pre>
        */
       public Builder clearPrecision() {

http://git-wip-us.apache.org/repos/asf/drill/blob/6741e68a/protocol/src/main/protobuf/Types.proto
----------------------------------------------------------------------
diff --git a/protocol/src/main/protobuf/Types.proto b/protocol/src/main/protobuf/Types.proto
index ca88fe9..71fa4ac 100644
--- a/protocol/src/main/protobuf/Types.proto
+++ b/protocol/src/main/protobuf/Types.proto
@@ -70,8 +70,8 @@ enum MinorType {
 message MajorType {
   optional MinorType minor_type = 1;
   optional DataMode mode = 2;
-  optional int32 width = 3; // optional width for fixed size values.
-  optional int32 precision = 4; // used for decimal types
+  optional int32 width = 3;
+  optional int32 precision = 4; // used for decimal types or as optional length for fixed size value
   optional int32 scale = 5; // used for decimal types
   optional int32 timeZone = 6; // used by TimeStamp type
   repeated MinorType sub_type = 7; // used by Union type


Mime
View raw message