You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ad...@apache.org on 2016/10/28 00:25:11 UTC

drill git commit: DRILL-4968: Add column size to ColumnMetadata

Repository: drill
Updated Branches:
  refs/heads/master 4ee1d4c77 -> c6dbe6a2f


DRILL-4968: Add column size to ColumnMetadata

Add a column size to ColumnMetadata so that JDBC and ODBC clients share
the implementation and don't have to recompute it client side.

this closes #631


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

Branch: refs/heads/master
Commit: c6dbe6a2f7033114d6239a4850a9b5092e684589
Parents: 4ee1d4c
Author: Laurent Goujon <la...@dremio.com>
Authored: Wed Oct 26 15:17:33 2016 -0700
Committer: adeneche <ad...@apache.org>
Committed: Thu Oct 27 16:24:56 2016 -0700

----------------------------------------------------------------------
 .../drill/exec/store/ischema/Records.java       | 117 ++++++++++-
 .../exec/work/metadata/MetadataProvider.java    |   4 +
 .../drill/exec/proto/SchemaUserProtos.java      |   7 +
 .../org/apache/drill/exec/proto/UserProtos.java | 194 +++++++++++++------
 .../drill/exec/proto/beans/ColumnMetadata.java  |  22 +++
 protocol/src/main/protobuf/User.proto           |   1 +
 6 files changed, 282 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/Records.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/Records.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/Records.java
index 64b9907..2ff9bc6 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/Records.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/Records.java
@@ -18,13 +18,16 @@
 
 package org.apache.drill.exec.store.ischema;
 
+import static org.slf4j.LoggerFactory.getLogger;
+
 import org.apache.calcite.avatica.util.TimeUnit;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.drill.exec.planner.types.DrillRelDataTypeSystem;
 import org.slf4j.Logger;
-import static org.slf4j.LoggerFactory.getLogger;
+
+import com.google.common.base.MoreObjects;
 
 public class Records {
 
@@ -59,6 +62,7 @@ public class Records {
     public final String COLUMN_DEFAULT;
     public final String IS_NULLABLE;
     public final String DATA_TYPE;
+    public final Integer COLUMN_SIZE;
     public final Integer CHARACTER_MAXIMUM_LENGTH;
     public final Integer CHARACTER_OCTET_LENGTH;
     public final Integer NUMERIC_PRECISION;
@@ -154,6 +158,8 @@ public class Records {
           else {
             this.CHARACTER_OCTET_LENGTH = Integer.MAX_VALUE;
           }
+          // Column size is the number of characters
+          this.COLUMN_SIZE = this.CHARACTER_MAXIMUM_LENGTH;
           this.NUMERIC_PRECISION = null;
           this.NUMERIC_PRECISION_RADIX = null;
           this.NUMERIC_SCALE = null;
@@ -161,10 +167,13 @@ public class Records {
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
           break;
+
         case BINARY:
         case VARBINARY:
           this.CHARACTER_MAXIMUM_LENGTH = relDataType.getPrecision();
           this.CHARACTER_OCTET_LENGTH = this.CHARACTER_MAXIMUM_LENGTH;
+          // Column size is the number of bytes
+          this.COLUMN_SIZE = this.CHARACTER_MAXIMUM_LENGTH;
           this.NUMERIC_PRECISION = null;
           this.NUMERIC_PRECISION_RADIX = null;
           this.NUMERIC_SCALE = null;
@@ -172,6 +181,7 @@ public class Records {
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
           break;
+
         case TINYINT:
         case SMALLINT:
         case INTEGER:
@@ -191,11 +201,14 @@ public class Records {
               //break;
           }
           this.NUMERIC_PRECISION_RADIX = 2;
+          // Column size is the number of digits, based on the precision radix
+          this.COLUMN_SIZE = NUMERIC_PRECISION;
           this.NUMERIC_SCALE = 0;
           this.DATETIME_PRECISION = null;
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
           break;
+
         case DECIMAL:
           this.CHARACTER_MAXIMUM_LENGTH = null;
           this.CHARACTER_OCTET_LENGTH = null;
@@ -203,11 +216,14 @@ public class Records {
           // NUMERIC_PRECISION_RADIX is 10.
           this.NUMERIC_PRECISION = relDataType.getPrecision();
           this.NUMERIC_PRECISION_RADIX = 10;
+          // Column size is the number of digits, based on the precision radix
+          this.COLUMN_SIZE = NUMERIC_PRECISION;
           this.NUMERIC_SCALE = relDataType.getScale();
           this.DATETIME_PRECISION = null;
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
           break;
+
         case REAL:
         case FLOAT:
         case DOUBLE:
@@ -224,11 +240,14 @@ public class Records {
               //break;
           }
           this.NUMERIC_PRECISION_RADIX = 2;
+          // Column size is the number of digits, based on the precision radix
+          this.COLUMN_SIZE = NUMERIC_PRECISION;
           this.NUMERIC_SCALE = null;
           this.DATETIME_PRECISION = null;
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
           break;
+
         case DATE:
         case TIME:
         case TIMESTAMP:
@@ -243,6 +262,23 @@ public class Records {
           this.DATETIME_PRECISION = relDataType.getPrecision();
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
+          switch(sqlTypeName) {
+          case DATE: this.COLUMN_SIZE = 10; break;// yyyy-MM-dd
+          case TIME: this.COLUMN_SIZE = this.DATETIME_PRECISION == 0
+              ? 8 // HH::mm::ss
+              : 8 + 1 + this.DATETIME_PRECISION;
+            break;
+
+          case TIMESTAMP: this.COLUMN_SIZE = this.DATETIME_PRECISION == 0
+              ? 10 + 1 + 8 // date + "T" + time
+              : 10 + 1 + 8 + 1 + this.DATETIME_PRECISION;
+            break;
+
+          default:
+            throw new AssertionError(
+                "Unexpected type " + sqlTypeName + " in approximate-types branch" );
+
+          }
           break;
         case INTERVAL_YEAR_MONTH:
         case INTERVAL_DAY_TIME:
@@ -270,21 +306,87 @@ public class Records {
                   "Unexpected type " + sqlTypeName + " in interval-types branch" );
               //break;
           }
+          this.INTERVAL_PRECISION =
+              relDataType
+              .getIntervalQualifier()
+              .getStartPrecision(DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM);
           {
             final TimeUnit start = relDataType.getIntervalQualifier().getStartUnit();
-            final TimeUnit end = relDataType.getIntervalQualifier().getEndUnit();
             // NOTE: getEndUnit() returns null instead of YEAR for "INTERVAL YEAR".
-            if ( start == end || null == end ) {
+            final TimeUnit end = MoreObjects.firstNonNull(relDataType.getIntervalQualifier().getEndUnit(), start);
+            if ( start == end ) {
               this.INTERVAL_TYPE = start.name();
             }
             else {
               this.INTERVAL_TYPE = start + " TO " + end;
             }
+
+            // extra size for fractional types
+            final int extraSecondIntervalSize = this.DATETIME_PRECISION > 0
+              ? DATETIME_PRECISION + 1 // add 1 for decimal point
+              : 0;
+
+            switch(start) {
+            case YEAR:
+              switch(end) {
+              case YEAR: this.COLUMN_SIZE = INTERVAL_PRECISION + 2; break;// P..Y
+              case MONTH: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 5; break; // P..Y12M
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+            case MONTH:
+              switch(end) {
+              case MONTH: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 2; break; // P..M
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+            case DAY:
+              switch(end) {
+              case DAY: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 2; break; // P..D
+              case HOUR: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 6; break; // P..DT12H
+              case MINUTE: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 9; break; // P..DT12H60M
+              case SECOND: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 12 + extraSecondIntervalSize; break; // P..DT12H60M60....S
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+            case HOUR:
+              switch(end) {
+              case HOUR: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 3; break; // PT..H
+              case MINUTE: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 6; break; // PT..H60M
+              case SECOND: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 9 + extraSecondIntervalSize; break; // PT..H12M60....S
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+            case MINUTE:
+              switch(end) {
+              case MINUTE: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 3; break; // PT...M
+              case SECOND: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 6 + extraSecondIntervalSize; break; // PT..M60....S
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+
+            case SECOND:
+              switch(end) {
+              case SECOND: this.COLUMN_SIZE = this.INTERVAL_PRECISION + 3 + extraSecondIntervalSize; break; // PT....S
+              default:
+                throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+              }
+              break;
+
+            default:
+              throw new AssertionError("Unexpected interval type " + this.INTERVAL_TYPE + " in interval-types branch" );
+            }
           }
-          this.INTERVAL_PRECISION =
-              relDataType
-              .getIntervalQualifier()
-              .getStartPrecision(DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM);
           break;
 
         default:
@@ -296,6 +398,7 @@ public class Records {
           this.DATETIME_PRECISION = null;
           this.INTERVAL_TYPE = null;
           this.INTERVAL_PRECISION = null;
+          this.COLUMN_SIZE = null;
         break;
       }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/exec/java-exec/src/main/java/org/apache/drill/exec/work/metadata/MetadataProvider.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/metadata/MetadataProvider.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/metadata/MetadataProvider.java
index d433d12..8365418 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/metadata/MetadataProvider.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/metadata/MetadataProvider.java
@@ -402,6 +402,10 @@ public class MetadataProvider {
             columnBuilder.setIntervalPrecision(c.INTERVAL_PRECISION);
           }
 
+          if (c.COLUMN_SIZE != null) {
+            columnBuilder.setColumnSize(c.COLUMN_SIZE);
+          }
+
           metadata.add(columnBuilder.build());
         }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserProtos.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserProtos.java b/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserProtos.java
index 9725741..f2cc7b9 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserProtos.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserProtos.java
@@ -2548,6 +2548,8 @@ public final class SchemaUserProtos
                     output.writeString(15, message.getIntervalType(), false);
                 if(message.hasIntervalPrecision())
                     output.writeInt32(16, message.getIntervalPrecision(), false);
+                if(message.hasColumnSize())
+                    output.writeInt32(17, message.getColumnSize(), false);
             }
             public boolean isInitialized(org.apache.drill.exec.proto.UserProtos.ColumnMetadata message)
             {
@@ -2635,6 +2637,9 @@ public final class SchemaUserProtos
                         case 16:
                             builder.setIntervalPrecision(input.readInt32());
                             break;
+                        case 17:
+                            builder.setColumnSize(input.readInt32());
+                            break;
                         default:
                             input.handleUnknownField(number, this);
                     }
@@ -2691,6 +2696,7 @@ public final class SchemaUserProtos
                 case 14: return "dateTimePrecision";
                 case 15: return "intervalType";
                 case 16: return "intervalPrecision";
+                case 17: return "columnSize";
                 default: return null;
             }
         }
@@ -2718,6 +2724,7 @@ public final class SchemaUserProtos
             fieldMap.put("dateTimePrecision", 14);
             fieldMap.put("intervalType", 15);
             fieldMap.put("intervalPrecision", 16);
+            fieldMap.put("columnSize", 17);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/protocol/src/main/java/org/apache/drill/exec/proto/UserProtos.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/UserProtos.java b/protocol/src/main/java/org/apache/drill/exec/proto/UserProtos.java
index f4f740d..ee429b9 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/UserProtos.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/UserProtos.java
@@ -18499,6 +18499,16 @@ public final class UserProtos {
      * <code>optional int32 interval_precision = 16;</code>
      */
     int getIntervalPrecision();
+
+    // optional int32 column_size = 17;
+    /**
+     * <code>optional int32 column_size = 17;</code>
+     */
+    boolean hasColumnSize();
+    /**
+     * <code>optional int32 column_size = 17;</code>
+     */
+    int getColumnSize();
   }
   /**
    * Protobuf type {@code exec.user.ColumnMetadata}
@@ -18636,6 +18646,11 @@ public final class UserProtos {
               intervalPrecision_ = input.readInt32();
               break;
             }
+            case 136: {
+              bitField0_ |= 0x00010000;
+              columnSize_ = input.readInt32();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -19121,6 +19136,22 @@ public final class UserProtos {
       return intervalPrecision_;
     }
 
+    // optional int32 column_size = 17;
+    public static final int COLUMN_SIZE_FIELD_NUMBER = 17;
+    private int columnSize_;
+    /**
+     * <code>optional int32 column_size = 17;</code>
+     */
+    public boolean hasColumnSize() {
+      return ((bitField0_ & 0x00010000) == 0x00010000);
+    }
+    /**
+     * <code>optional int32 column_size = 17;</code>
+     */
+    public int getColumnSize() {
+      return columnSize_;
+    }
+
     private void initFields() {
       catalogName_ = "";
       schemaName_ = "";
@@ -19138,6 +19169,7 @@ public final class UserProtos {
       dateTimePrecision_ = 0;
       intervalType_ = "";
       intervalPrecision_ = 0;
+      columnSize_ = 0;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -19199,6 +19231,9 @@ public final class UserProtos {
       if (((bitField0_ & 0x00008000) == 0x00008000)) {
         output.writeInt32(16, intervalPrecision_);
       }
+      if (((bitField0_ & 0x00010000) == 0x00010000)) {
+        output.writeInt32(17, columnSize_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -19272,6 +19307,10 @@ public final class UserProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeInt32Size(16, intervalPrecision_);
       }
+      if (((bitField0_ & 0x00010000) == 0x00010000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(17, columnSize_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -19425,6 +19464,8 @@ public final class UserProtos {
         bitField0_ = (bitField0_ & ~0x00004000);
         intervalPrecision_ = 0;
         bitField0_ = (bitField0_ & ~0x00008000);
+        columnSize_ = 0;
+        bitField0_ = (bitField0_ & ~0x00010000);
         return this;
       }
 
@@ -19517,6 +19558,10 @@ public final class UserProtos {
           to_bitField0_ |= 0x00008000;
         }
         result.intervalPrecision_ = intervalPrecision_;
+        if (((from_bitField0_ & 0x00010000) == 0x00010000)) {
+          to_bitField0_ |= 0x00010000;
+        }
+        result.columnSize_ = columnSize_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -19595,6 +19640,9 @@ public final class UserProtos {
         if (other.hasIntervalPrecision()) {
           setIntervalPrecision(other.getIntervalPrecision());
         }
+        if (other.hasColumnSize()) {
+          setColumnSize(other.getColumnSize());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -20437,6 +20485,39 @@ public final class UserProtos {
         return this;
       }
 
+      // optional int32 column_size = 17;
+      private int columnSize_ ;
+      /**
+       * <code>optional int32 column_size = 17;</code>
+       */
+      public boolean hasColumnSize() {
+        return ((bitField0_ & 0x00010000) == 0x00010000);
+      }
+      /**
+       * <code>optional int32 column_size = 17;</code>
+       */
+      public int getColumnSize() {
+        return columnSize_;
+      }
+      /**
+       * <code>optional int32 column_size = 17;</code>
+       */
+      public Builder setColumnSize(int value) {
+        bitField0_ |= 0x00010000;
+        columnSize_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 column_size = 17;</code>
+       */
+      public Builder clearColumnSize() {
+        bitField0_ = (bitField0_ & ~0x00010000);
+        columnSize_ = 0;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:exec.user.ColumnMetadata)
     }
 
@@ -29167,7 +29248,7 @@ public final class UserProtos {
       "\001(\0132\025.exec.user.LikeFilter\0220\n\021table_name" +
       "_filter\030\003 \001(\0132\025.exec.user.LikeFilter\0221\n\022" +
       "column_name_filter\030\004 \001(\0132\025.exec.user.Lik" +
-      "eFilter\"\224\003\n\016ColumnMetadata\022\024\n\014catalog_na" +
+      "eFilter\"\251\003\n\016ColumnMetadata\022\024\n\014catalog_na" +
       "me\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022\n\ntable_n" +
       "ame\030\003 \001(\t\022\023\n\013column_name\030\004 \001(\t\022\030\n\020ordina" +
       "l_position\030\005 \001(\005\022\025\n\rdefault_value\030\006 \001(\t\022",
@@ -29177,60 +29258,61 @@ public final class UserProtos {
       "\n\027numeric_precision_radix\030\014 \001(\005\022\025\n\rnumer" +
       "ic_scale\030\r \001(\005\022\033\n\023date_time_precision\030\016 " +
       "\001(\005\022\025\n\rinterval_type\030\017 \001(\t\022\032\n\022interval_p" +
-      "recision\030\020 \001(\005\"\220\001\n\016GetColumnsResp\022(\n\006sta" +
-      "tus\030\001 \001(\0162\030.exec.user.RequestStatus\022*\n\007c" +
-      "olumns\030\002 \003(\0132\031.exec.user.ColumnMetadata\022" +
-      "(\n\005error\030\003 \001(\0132\031.exec.shared.DrillPBErro",
-      "r\"/\n\032CreatePreparedStatementReq\022\021\n\tsql_q" +
-      "uery\030\001 \001(\t\"\326\003\n\024ResultColumnMetadata\022\024\n\014c" +
-      "atalog_name\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022" +
-      "\n\ntable_name\030\003 \001(\t\022\023\n\013column_name\030\004 \001(\t\022" +
-      "\r\n\005label\030\005 \001(\t\022\021\n\tdata_type\030\006 \001(\t\022\023\n\013is_" +
-      "nullable\030\007 \001(\010\022\021\n\tprecision\030\010 \001(\005\022\r\n\005sca" +
-      "le\030\t \001(\005\022\016\n\006signed\030\n \001(\010\022\024\n\014display_size" +
-      "\030\013 \001(\005\022\022\n\nis_aliased\030\014 \001(\010\0225\n\rsearchabil" +
-      "ity\030\r \001(\0162\036.exec.user.ColumnSearchabilit" +
-      "y\0223\n\014updatability\030\016 \001(\0162\035.exec.user.Colu",
-      "mnUpdatability\022\026\n\016auto_increment\030\017 \001(\010\022\030" +
-      "\n\020case_sensitivity\030\020 \001(\010\022\020\n\010sortable\030\021 \001" +
-      "(\010\022\022\n\nclass_name\030\022 \001(\t\022\023\n\013is_currency\030\024 " +
-      "\001(\010\".\n\027PreparedStatementHandle\022\023\n\013server" +
-      "_info\030\001 \001(\014\"\200\001\n\021PreparedStatement\0220\n\007col" +
-      "umns\030\001 \003(\0132\037.exec.user.ResultColumnMetad" +
-      "ata\0229\n\rserver_handle\030\002 \001(\0132\".exec.user.P" +
-      "reparedStatementHandle\"\253\001\n\033CreatePrepare" +
-      "dStatementResp\022(\n\006status\030\001 \001(\0162\030.exec.us" +
-      "er.RequestStatus\0228\n\022prepared_statement\030\002",
-      " \001(\0132\034.exec.user.PreparedStatement\022(\n\005er" +
-      "ror\030\003 \001(\0132\031.exec.shared.DrillPBError\"\353\001\n" +
-      "\010RunQuery\0221\n\014results_mode\030\001 \001(\0162\033.exec.u" +
-      "ser.QueryResultsMode\022$\n\004type\030\002 \001(\0162\026.exe" +
-      "c.shared.QueryType\022\014\n\004plan\030\003 \001(\t\0221\n\tfrag" +
-      "ments\030\004 \003(\0132\036.exec.bit.control.PlanFragm" +
-      "ent\022E\n\031prepared_statement_handle\030\005 \001(\0132\"" +
-      ".exec.user.PreparedStatementHandle*\310\003\n\007R" +
-      "pcType\022\r\n\tHANDSHAKE\020\000\022\007\n\003ACK\020\001\022\013\n\007GOODBY" +
-      "E\020\002\022\r\n\tRUN_QUERY\020\003\022\020\n\014CANCEL_QUERY\020\004\022\023\n\017",
-      "REQUEST_RESULTS\020\005\022\027\n\023RESUME_PAUSED_QUERY" +
-      "\020\013\022\034\n\030GET_QUERY_PLAN_FRAGMENTS\020\014\022\020\n\014GET_" +
-      "CATALOGS\020\016\022\017\n\013GET_SCHEMAS\020\017\022\016\n\nGET_TABLE" +
-      "S\020\020\022\017\n\013GET_COLUMNS\020\021\022\035\n\031CREATE_PREPARED_" +
-      "STATEMENT\020\026\022\016\n\nQUERY_DATA\020\006\022\020\n\014QUERY_HAN" +
-      "DLE\020\007\022\030\n\024QUERY_PLAN_FRAGMENTS\020\r\022\014\n\010CATAL" +
-      "OGS\020\022\022\013\n\007SCHEMAS\020\023\022\n\n\006TABLES\020\024\022\013\n\007COLUMN" +
-      "S\020\025\022\026\n\022PREPARED_STATEMENT\020\027\022\026\n\022REQ_META_" +
-      "FUNCTIONS\020\010\022\026\n\022RESP_FUNCTION_LIST\020\t\022\020\n\014Q" +
-      "UERY_RESULT\020\n*#\n\020QueryResultsMode\022\017\n\013STR",
-      "EAM_FULL\020\001*^\n\017HandshakeStatus\022\013\n\007SUCCESS" +
-      "\020\001\022\030\n\024RPC_VERSION_MISMATCH\020\002\022\017\n\013AUTH_FAI" +
-      "LED\020\003\022\023\n\017UNKNOWN_FAILURE\020\004*D\n\rRequestSta" +
-      "tus\022\022\n\016UNKNOWN_STATUS\020\000\022\006\n\002OK\020\001\022\n\n\006FAILE" +
-      "D\020\002\022\013\n\007TIMEOUT\020\003*Y\n\023ColumnSearchability\022" +
-      "\031\n\025UNKNOWN_SEARCHABILITY\020\000\022\010\n\004NONE\020\001\022\010\n\004" +
-      "CHAR\020\002\022\n\n\006NUMBER\020\003\022\007\n\003ALL\020\004*K\n\022ColumnUpd" +
-      "atability\022\030\n\024UNKNOWN_UPDATABILITY\020\000\022\r\n\tR" +
-      "EAD_ONLY\020\001\022\014\n\010WRITABLE\020\002B+\n\033org.apache.d" +
-      "rill.exec.protoB\nUserProtosH\001"
+      "recision\030\020 \001(\005\022\023\n\013column_size\030\021 \001(\005\"\220\001\n\016" +
+      "GetColumnsResp\022(\n\006status\030\001 \001(\0162\030.exec.us" +
+      "er.RequestStatus\022*\n\007columns\030\002 \003(\0132\031.exec" +
+      ".user.ColumnMetadata\022(\n\005error\030\003 \001(\0132\031.ex",
+      "ec.shared.DrillPBError\"/\n\032CreatePrepared" +
+      "StatementReq\022\021\n\tsql_query\030\001 \001(\t\"\326\003\n\024Resu" +
+      "ltColumnMetadata\022\024\n\014catalog_name\030\001 \001(\t\022\023" +
+      "\n\013schema_name\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022" +
+      "\023\n\013column_name\030\004 \001(\t\022\r\n\005label\030\005 \001(\t\022\021\n\td" +
+      "ata_type\030\006 \001(\t\022\023\n\013is_nullable\030\007 \001(\010\022\021\n\tp" +
+      "recision\030\010 \001(\005\022\r\n\005scale\030\t \001(\005\022\016\n\006signed\030" +
+      "\n \001(\010\022\024\n\014display_size\030\013 \001(\005\022\022\n\nis_aliase" +
+      "d\030\014 \001(\010\0225\n\rsearchability\030\r \001(\0162\036.exec.us" +
+      "er.ColumnSearchability\0223\n\014updatability\030\016",
+      " \001(\0162\035.exec.user.ColumnUpdatability\022\026\n\016a" +
+      "uto_increment\030\017 \001(\010\022\030\n\020case_sensitivity\030" +
+      "\020 \001(\010\022\020\n\010sortable\030\021 \001(\010\022\022\n\nclass_name\030\022 " +
+      "\001(\t\022\023\n\013is_currency\030\024 \001(\010\".\n\027PreparedStat" +
+      "ementHandle\022\023\n\013server_info\030\001 \001(\014\"\200\001\n\021Pre" +
+      "paredStatement\0220\n\007columns\030\001 \003(\0132\037.exec.u" +
+      "ser.ResultColumnMetadata\0229\n\rserver_handl" +
+      "e\030\002 \001(\0132\".exec.user.PreparedStatementHan" +
+      "dle\"\253\001\n\033CreatePreparedStatementResp\022(\n\006s" +
+      "tatus\030\001 \001(\0162\030.exec.user.RequestStatus\0228\n",
+      "\022prepared_statement\030\002 \001(\0132\034.exec.user.Pr" +
+      "eparedStatement\022(\n\005error\030\003 \001(\0132\031.exec.sh" +
+      "ared.DrillPBError\"\353\001\n\010RunQuery\0221\n\014result" +
+      "s_mode\030\001 \001(\0162\033.exec.user.QueryResultsMod" +
+      "e\022$\n\004type\030\002 \001(\0162\026.exec.shared.QueryType\022" +
+      "\014\n\004plan\030\003 \001(\t\0221\n\tfragments\030\004 \003(\0132\036.exec." +
+      "bit.control.PlanFragment\022E\n\031prepared_sta" +
+      "tement_handle\030\005 \001(\0132\".exec.user.Prepared" +
+      "StatementHandle*\310\003\n\007RpcType\022\r\n\tHANDSHAKE" +
+      "\020\000\022\007\n\003ACK\020\001\022\013\n\007GOODBYE\020\002\022\r\n\tRUN_QUERY\020\003\022",
+      "\020\n\014CANCEL_QUERY\020\004\022\023\n\017REQUEST_RESULTS\020\005\022\027" +
+      "\n\023RESUME_PAUSED_QUERY\020\013\022\034\n\030GET_QUERY_PLA" +
+      "N_FRAGMENTS\020\014\022\020\n\014GET_CATALOGS\020\016\022\017\n\013GET_S" +
+      "CHEMAS\020\017\022\016\n\nGET_TABLES\020\020\022\017\n\013GET_COLUMNS\020" +
+      "\021\022\035\n\031CREATE_PREPARED_STATEMENT\020\026\022\016\n\nQUER" +
+      "Y_DATA\020\006\022\020\n\014QUERY_HANDLE\020\007\022\030\n\024QUERY_PLAN" +
+      "_FRAGMENTS\020\r\022\014\n\010CATALOGS\020\022\022\013\n\007SCHEMAS\020\023\022" +
+      "\n\n\006TABLES\020\024\022\013\n\007COLUMNS\020\025\022\026\n\022PREPARED_STA" +
+      "TEMENT\020\027\022\026\n\022REQ_META_FUNCTIONS\020\010\022\026\n\022RESP" +
+      "_FUNCTION_LIST\020\t\022\020\n\014QUERY_RESULT\020\n*#\n\020Qu",
+      "eryResultsMode\022\017\n\013STREAM_FULL\020\001*^\n\017Hands" +
+      "hakeStatus\022\013\n\007SUCCESS\020\001\022\030\n\024RPC_VERSION_M" +
+      "ISMATCH\020\002\022\017\n\013AUTH_FAILED\020\003\022\023\n\017UNKNOWN_FA" +
+      "ILURE\020\004*D\n\rRequestStatus\022\022\n\016UNKNOWN_STAT" +
+      "US\020\000\022\006\n\002OK\020\001\022\n\n\006FAILED\020\002\022\013\n\007TIMEOUT\020\003*Y\n" +
+      "\023ColumnSearchability\022\031\n\025UNKNOWN_SEARCHAB" +
+      "ILITY\020\000\022\010\n\004NONE\020\001\022\010\n\004CHAR\020\002\022\n\n\006NUMBER\020\003\022" +
+      "\007\n\003ALL\020\004*K\n\022ColumnUpdatability\022\030\n\024UNKNOW" +
+      "N_UPDATABILITY\020\000\022\r\n\tREAD_ONLY\020\001\022\014\n\010WRITA" +
+      "BLE\020\002B+\n\033org.apache.drill.exec.protoB\nUs",
+      "erProtosH\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -29356,7 +29438,7 @@ public final class UserProtos {
           internal_static_exec_user_ColumnMetadata_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_exec_user_ColumnMetadata_descriptor,
-              new java.lang.String[] { "CatalogName", "SchemaName", "TableName", "ColumnName", "OrdinalPosition", "DefaultValue", "IsNullable", "DataType", "CharMaxLength", "CharOctetLength", "NumericPrecision", "NumericPrecisionRadix", "NumericScale", "DateTimePrecision", "IntervalType", "IntervalPrecision", });
+              new java.lang.String[] { "CatalogName", "SchemaName", "TableName", "ColumnName", "OrdinalPosition", "DefaultValue", "IsNullable", "DataType", "CharMaxLength", "CharOctetLength", "NumericPrecision", "NumericPrecisionRadix", "NumericScale", "DateTimePrecision", "IntervalType", "IntervalPrecision", "ColumnSize", });
           internal_static_exec_user_GetColumnsResp_descriptor =
             getDescriptor().getMessageTypes().get(20);
           internal_static_exec_user_GetColumnsResp_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/protocol/src/main/java/org/apache/drill/exec/proto/beans/ColumnMetadata.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/beans/ColumnMetadata.java b/protocol/src/main/java/org/apache/drill/exec/proto/beans/ColumnMetadata.java
index a5e7e5d..8d31b0d 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/beans/ColumnMetadata.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/beans/ColumnMetadata.java
@@ -63,6 +63,7 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
     private int dateTimePrecision;
     private String intervalType;
     private int intervalPrecision;
+    private int columnSize;
 
     public ColumnMetadata()
     {
@@ -279,6 +280,19 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
         return this;
     }
 
+    // columnSize
+
+    public int getColumnSize()
+    {
+        return columnSize;
+    }
+
+    public ColumnMetadata setColumnSize(int columnSize)
+    {
+        this.columnSize = columnSize;
+        return this;
+    }
+
     // java serialization
 
     public void readExternal(ObjectInput in) throws IOException
@@ -381,6 +395,9 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
                 case 16:
                     message.intervalPrecision = input.readInt32();
                     break;
+                case 17:
+                    message.columnSize = input.readInt32();
+                    break;
                 default:
                     input.handleUnknownField(number, this);
             }   
@@ -437,6 +454,9 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
 
         if(message.intervalPrecision != 0)
             output.writeInt32(16, message.intervalPrecision, false);
+
+        if(message.columnSize != 0)
+            output.writeInt32(17, message.columnSize, false);
     }
 
     public String getFieldName(int number)
@@ -459,6 +479,7 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
             case 14: return "dateTimePrecision";
             case 15: return "intervalType";
             case 16: return "intervalPrecision";
+            case 17: return "columnSize";
             default: return null;
         }
     }
@@ -488,6 +509,7 @@ public final class ColumnMetadata implements Externalizable, Message<ColumnMetad
         __fieldMap.put("dateTimePrecision", 14);
         __fieldMap.put("intervalType", 15);
         __fieldMap.put("intervalPrecision", 16);
+        __fieldMap.put("columnSize", 17);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/c6dbe6a2/protocol/src/main/protobuf/User.proto
----------------------------------------------------------------------
diff --git a/protocol/src/main/protobuf/User.proto b/protocol/src/main/protobuf/User.proto
index fe8dc3d..f78ea2b 100644
--- a/protocol/src/main/protobuf/User.proto
+++ b/protocol/src/main/protobuf/User.proto
@@ -247,6 +247,7 @@ message ColumnMetadata {
   optional int32 date_time_precision = 14;
   optional string interval_type = 15;
   optional int32 interval_precision = 16;
+  optional int32 column_size = 17;
 }
 
 /*