calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jcama...@apache.org
Subject [20/50] [abbrv] calcite git commit: [CALCITE-913] Construct proper ColumnMetaData for arrays (Josh Elser)
Date Wed, 11 Nov 2015 12:25:26 GMT
[CALCITE-913] Construct proper ColumnMetaData for arrays (Josh Elser)


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

Branch: refs/heads/branch-release
Commit: bf178d55f88c317f36c68807649d35d3e0614e6a
Parents: 00517e7
Author: Josh Elser <elserj@apache.org>
Authored: Fri Oct 9 20:24:49 2015 -0400
Committer: Julian Hyde <jhyde@apache.org>
Committed: Mon Oct 26 12:13:42 2015 -0700

----------------------------------------------------------------------
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |   14 +-
 .../calcite/avatica/jdbc/JdbcResultSet.java     |   28 +
 .../calcite/avatica/remote/RemoteMetaTest.java  |   21 +
 .../apache/calcite/avatica/ColumnMetaData.java  |   19 +-
 .../java/org/apache/calcite/avatica/Meta.java   |  188 +--
 .../apache/calcite/avatica/proto/Common.java    | 1204 ++++++++++++++----
 .../avatica/remote/MockProtobufService.java     |    6 +-
 avatica/src/main/protobuf/common.proto          |   10 +-
 .../avatica/remote/ProtobufHandlerTest.java     |   15 +-
 9 files changed, 1167 insertions(+), 338 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
index be885ce..b8e4ea4 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -44,6 +44,7 @@ import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
@@ -190,9 +191,14 @@ public class JdbcMeta implements Meta {
     for (int i = 1; i <= metaData.getColumnCount(); i++) {
       final SqlType sqlType = SqlType.valueOf(metaData.getColumnType(i));
       final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(sqlType.internal);
-      ColumnMetaData.AvaticaType t =
-          ColumnMetaData.scalar(metaData.getColumnType(i),
-              metaData.getColumnTypeName(i), rep);
+      final ColumnMetaData.AvaticaType t;
+      if (sqlType == SqlType.ARRAY || sqlType == SqlType.STRUCT || sqlType == SqlType.MULTISET) {
+        ColumnMetaData.AvaticaType arrayValueType = ColumnMetaData.scalar(Types.JAVA_OBJECT,
+            metaData.getColumnTypeName(i), ColumnMetaData.Rep.OBJECT);
+        t = ColumnMetaData.array(arrayValueType, metaData.getColumnTypeName(i), rep);
+      } else {
+        t = ColumnMetaData.scalar(metaData.getColumnType(i), metaData.getColumnTypeName(i), rep);
+      }
       ColumnMetaData md =
           new ColumnMetaData(i - 1, metaData.isAutoIncrement(i),
               metaData.isCaseSensitive(i), metaData.isSearchable(i),
@@ -210,7 +216,7 @@ public class JdbcMeta implements Meta {
   }
 
   /**
-   * Converts from JDBC metadata to Avatica parameters.
+   * Converts from JDBC metadata to Avatica parameters
    */
   protected static List<AvaticaParameter> parameters(ParameterMetaData metaData)
       throws SQLException {

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
index d0a57ab..30ee7f4 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
@@ -20,16 +20,19 @@ import org.apache.calcite.avatica.AvaticaStatement;
 import org.apache.calcite.avatica.Meta;
 import org.apache.calcite.avatica.util.DateTimeUtils;
 
+import java.sql.Array;
 import java.sql.Date;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.Struct;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
+import java.util.TreeMap;
 
 /** Implementation of {@link org.apache.calcite.avatica.Meta.MetaResultSet}
  *  upon a JDBC {@link java.sql.ResultSet}.
@@ -172,6 +175,31 @@ class JdbcResultSet extends Meta.MetaResultSet {
     case Types.TIMESTAMP:
       final Timestamp aTimestamp = resultSet.getTimestamp(j + 1, calendar);
       return aTimestamp == null ? null : aTimestamp.getTime();
+    case Types.ARRAY:
+      final Array array = resultSet.getArray(j + 1);
+      if (null == array) {
+        return null;
+      }
+      ResultSet arrayValues = array.getResultSet();
+      TreeMap<Integer, Object> map = new TreeMap<>();
+      while (arrayValues.next()) {
+        // column 1 is the index in the array, column 2 is the value.
+        // Recurse on `getValue` to unwrap nested types correctly.
+        // `j` is zero-indexed and incremented for us, thus we have `1` being used twice.
+        map.put(arrayValues.getInt(1), getValue(arrayValues, array.getBaseType(), 1, calendar));
+      }
+      // If the result set is not in the same order as the actual Array, TreeMap fixes that.
+      // Need to make a concrete list to ensure Jackson serialization.
+      //return new ListLike<Object>(new ArrayList<>(map.values()), ListLikeType.ARRAY);
+      return new ArrayList<>(map.values());
+    case Types.STRUCT:
+      Struct struct = resultSet.getObject(j + 1, Struct.class);
+      Object[] attrs = struct.getAttributes();
+      List<Object> list = new ArrayList<>(attrs.length);
+      for (Object o : attrs) {
+        list.add(o);
+      }
+      return list;
     default:
       return resultSet.getObject(j + 1);
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
index 903167e..3ccebf8 100644
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
+++ b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
@@ -29,6 +29,7 @@ import org.apache.calcite.avatica.server.AvaticaProtobufHandler;
 import org.apache.calcite.avatica.server.HttpServer;
 import org.apache.calcite.avatica.server.Main;
 import org.apache.calcite.avatica.server.Main.HandlerFactory;
+import org.apache.calcite.avatica.util.ArrayImpl;
 
 import com.google.common.cache.Cache;
 
@@ -41,6 +42,7 @@ import org.junit.runners.Parameterized.Parameters;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.sql.Array;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
@@ -54,6 +56,7 @@ import java.util.UUID;
 
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
@@ -395,6 +398,24 @@ public class RemoteMetaTest {
     // default fetch size is 100, we are well beyond it
     assertTrue(rowCount > 900);
   }
+
+  @Test public void testArrays() throws SQLException {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+         Statement stmt = conn.createStatement()) {
+      ResultSet resultSet =
+          stmt.executeQuery("select * from (values ('a', array['b', 'c']));");
+
+      assertTrue(resultSet.next());
+      assertEquals("a", resultSet.getString(1));
+      Array arr = resultSet.getArray(2);
+      assertTrue(arr instanceof ArrayImpl);
+      Object[] values = (Object[]) ((ArrayImpl) arr).getArray();
+      assertArrayEquals(new String[]{"b", "c"}, values);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
 }
 
 // End RemoteMetaTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java b/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
index b1e70c4..170c310 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
@@ -26,9 +26,11 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.google.protobuf.Descriptors.Descriptor;
 
 import java.lang.reflect.Type;
+import java.sql.Array;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Struct;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
@@ -444,6 +446,11 @@ public class ColumnMetaData {
     /** Values are represented as some sub-class of {@link Number}.
      * The JSON encoding does this. */
     NUMBER(Number.class),
+
+    ARRAY(Array.class),
+    MULTISET(List.class),
+    STRUCT(Struct.class),
+
     OBJECT(Object.class);
 
     public final Class clazz;
@@ -512,6 +519,10 @@ public class ColumnMetaData {
         return resultSet.getTime(i);
       case JAVA_SQL_TIMESTAMP:
         return resultSet.getTimestamp(i);
+      case ARRAY:
+        return resultSet.getArray(i);
+      case STRUCT:
+        return resultSet.getObject(i, Struct.class);
       default:
         return resultSet.getObject(i);
       }
@@ -694,8 +705,12 @@ public class ColumnMetaData {
   public static class ArrayType extends AvaticaType {
     public final AvaticaType component;
 
-    private ArrayType(int type, String typeName, Rep representation,
-        AvaticaType component) {
+    /**
+     * Not for public use. Use {@link ColumnMetaData#array(AvaticaType, String, Rep)}.
+     */
+    @JsonCreator
+    public ArrayType(@JsonProperty("type") int type, @JsonProperty("name") String typeName,
+        @JsonProperty("rep") Rep representation, @JsonProperty("component") AvaticaType component) {
       super(type, typeName, representation);
       this.component = component;
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
index c5c8030..6c51b1c 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -864,49 +864,21 @@ public interface Meta {
           final Common.Row.Builder rowBuilder = Common.Row.newBuilder();
 
           for (Object element : (Object[]) row) {
-            final Common.TypedValue.Builder valueBuilder = Common.TypedValue.newBuilder();
-
-            // Numbers
-            if (element instanceof Byte) {
-              valueBuilder.setType(Common.Rep.BYTE).setNumberValue(((Byte) element).longValue());
-            } else if (element instanceof Short) {
-              valueBuilder.setType(Common.Rep.SHORT).setNumberValue(((Short) element).longValue());
-            } else if (element instanceof Integer) {
-              valueBuilder.setType(Common.Rep.INTEGER)
-                .setNumberValue(((Integer) element).longValue());
-            } else if (element instanceof Long) {
-              valueBuilder.setType(Common.Rep.LONG).setNumberValue((Long) element);
-            } else if (element instanceof Double) {
-              valueBuilder.setType(Common.Rep.DOUBLE)
-                .setDoubleValue(((Double) element).doubleValue());
-            } else if (element instanceof Float) {
-              valueBuilder.setType(Common.Rep.FLOAT).setNumberValue(((Float) element).longValue());
-            } else if (element instanceof BigDecimal) {
-              valueBuilder.setType(Common.Rep.NUMBER)
-                .setDoubleValue(((BigDecimal) element).doubleValue());
-            // Strings
-            } else if (element instanceof String) {
-              valueBuilder.setType(Common.Rep.STRING)
-                .setStringValue((String) element);
-            } else if (element instanceof Character) {
-              valueBuilder.setType(Common.Rep.CHARACTER)
-                .setStringValue(((Character) element).toString());
-            // Bytes
-            } else if (element instanceof byte[]) {
-              valueBuilder.setType(Common.Rep.BYTE_STRING)
-                .setBytesValues(ByteString.copyFrom((byte[]) element));
-            // Boolean
-            } else if (element instanceof Boolean) {
-              valueBuilder.setType(Common.Rep.BOOLEAN).setBoolValue((boolean) element);
-            } else if (null == element) {
-              valueBuilder.setType(Common.Rep.NULL);
-            // Unhandled
+            final Common.ColumnValue.Builder columnBuilder = Common.ColumnValue.newBuilder();
+
+            if (element instanceof List) {
+              List<?> list = (List<?>) element;
+              // Add each element in the list/array to the column's value
+              for (Object listItem : list) {
+                columnBuilder.addValue(serializeScalar(listItem));
+              }
             } else {
-              throw new RuntimeException("Unhandled type in Frame: " + element.getClass());
+              // Only one value for this column, a scalar.
+              columnBuilder.addValue(serializeScalar(element));
             }
 
             // Add value to row
-            rowBuilder.addValue(valueBuilder.build());
+            rowBuilder.addValue(columnBuilder.build());
           }
 
           // Collect all rows
@@ -920,58 +892,70 @@ public interface Meta {
       return builder.build();
     }
 
+    static Common.TypedValue serializeScalar(Object element) {
+      final Common.TypedValue.Builder valueBuilder = Common.TypedValue.newBuilder();
+
+      // Numbers
+      if (element instanceof Byte) {
+        valueBuilder.setType(Common.Rep.BYTE).setNumberValue(((Byte) element).longValue());
+      } else if (element instanceof Short) {
+        valueBuilder.setType(Common.Rep.SHORT).setNumberValue(((Short) element).longValue());
+      } else if (element instanceof Integer) {
+        valueBuilder.setType(Common.Rep.INTEGER)
+          .setNumberValue(((Integer) element).longValue());
+      } else if (element instanceof Long) {
+        valueBuilder.setType(Common.Rep.LONG).setNumberValue((Long) element);
+      } else if (element instanceof Double) {
+        valueBuilder.setType(Common.Rep.DOUBLE)
+          .setDoubleValue(((Double) element).doubleValue());
+      } else if (element instanceof Float) {
+        valueBuilder.setType(Common.Rep.FLOAT).setNumberValue(((Float) element).longValue());
+      } else if (element instanceof BigDecimal) {
+        valueBuilder.setType(Common.Rep.NUMBER)
+          .setDoubleValue(((BigDecimal) element).doubleValue());
+      // Strings
+      } else if (element instanceof String) {
+        valueBuilder.setType(Common.Rep.STRING)
+          .setStringValue((String) element);
+      } else if (element instanceof Character) {
+        valueBuilder.setType(Common.Rep.CHARACTER)
+          .setStringValue(((Character) element).toString());
+      // Bytes
+      } else if (element instanceof byte[]) {
+        valueBuilder.setType(Common.Rep.BYTE_STRING)
+          .setBytesValues(ByteString.copyFrom((byte[]) element));
+      // Boolean
+      } else if (element instanceof Boolean) {
+        valueBuilder.setType(Common.Rep.BOOLEAN).setBoolValue((boolean) element);
+      } else if (null == element) {
+        valueBuilder.setType(Common.Rep.NULL);
+      // Unhandled
+      } else {
+        throw new RuntimeException("Unhandled type in Frame: " + element.getClass());
+      }
+
+      return valueBuilder.build();
+    }
+
     public static Frame fromProto(Common.Frame proto) {
       List<Object> parsedRows = new ArrayList<>(proto.getRowsCount());
       for (Common.Row protoRow : proto.getRowsList()) {
         ArrayList<Object> row = new ArrayList<>(protoRow.getValueCount());
-        for (Common.TypedValue protoElement : protoRow.getValueList()) {
-          Object element;
-
-          // TODO Should these be primitives or Objects?
-          switch (protoElement.getType()) {
-          case BYTE:
-            element = Long.valueOf(protoElement.getNumberValue()).byteValue();
-            break;
-          case SHORT:
-            element = Long.valueOf(protoElement.getNumberValue()).shortValue();
-            break;
-          case INTEGER:
-            element = Long.valueOf(protoElement.getNumberValue()).intValue();
-            break;
-          case LONG:
-            element = protoElement.getNumberValue();
-            break;
-          case FLOAT:
-            element = Long.valueOf(protoElement.getNumberValue()).floatValue();
-            break;
-          case DOUBLE:
-            element = Double.valueOf(protoElement.getDoubleValue());
-            break;
-          case NUMBER:
-            // TODO more cases here to expand on? BigInteger?
-            element = BigDecimal.valueOf(protoElement.getDoubleValue());
-            break;
-          case STRING:
-            element = protoElement.getStringValue();
-            break;
-          case CHARACTER:
-            // A single character in the string
-            element = protoElement.getStringValue().charAt(0);
-            break;
-          case BYTE_STRING:
-            element = protoElement.getBytesValues().toByteArray();
-            break;
-          case BOOLEAN:
-            element = protoElement.getBoolValue();
-            break;
-          case NULL:
-            element = null;
-            break;
-          default:
-            throw new RuntimeException("Unhandled type: " + protoElement.getType());
+        for (Common.ColumnValue protoColumn : protoRow.getValueList()) {
+          Object value;
+          if (protoColumn.getValueCount() > 1) {
+            // Array
+            List<Object> array = new ArrayList<>(protoColumn.getValueCount());
+            for (Common.TypedValue columnValue : protoColumn.getValueList()) {
+              array.add(getScalarValue(columnValue));
+            }
+            value = array;
+          } else {
+            // Scalar
+            value = getScalarValue(protoColumn.getValue(0));
           }
 
-          row.add(element);
+          row.add(value);
         }
 
         parsedRows.add(row);
@@ -980,6 +964,40 @@ public interface Meta {
       return new Frame(proto.getOffset(), proto.getDone(), parsedRows);
     }
 
+    static Object getScalarValue(Common.TypedValue protoElement) {
+      // TODO Should these be primitives or Objects?
+      switch (protoElement.getType()) {
+      case BYTE:
+        return Long.valueOf(protoElement.getNumberValue()).byteValue();
+      case SHORT:
+        return Long.valueOf(protoElement.getNumberValue()).shortValue();
+      case INTEGER:
+        return Long.valueOf(protoElement.getNumberValue()).intValue();
+      case LONG:
+        return protoElement.getNumberValue();
+      case FLOAT:
+        return Long.valueOf(protoElement.getNumberValue()).floatValue();
+      case DOUBLE:
+        return Double.valueOf(protoElement.getDoubleValue());
+      case NUMBER:
+        // TODO more cases here to expand on? BigInteger?
+        return BigDecimal.valueOf(protoElement.getDoubleValue());
+      case STRING:
+        return protoElement.getStringValue();
+      case CHARACTER:
+        // A single character in the string
+        return protoElement.getStringValue().charAt(0);
+      case BYTE_STRING:
+        return protoElement.getBytesValues().toByteArray();
+      case BOOLEAN:
+        return protoElement.getBoolValue();
+      case NULL:
+        return null;
+      default:
+        throw new RuntimeException("Unhandled type: " + protoElement.getType());
+      }
+    }
+
     @Override public int hashCode() {
       final int prime = 31;
       int result = 1;

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java b/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java
index c63355d..b693b77 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java
@@ -323,6 +323,18 @@ package org.apache.calcite.avatica.proto;
      * <code>NULL = 24;</code>
      */
     NULL(26, 24),
+    /**
+     * <code>ARRAY = 27;</code>
+     */
+    ARRAY(27, 27),
+    /**
+     * <code>STRUCT = 28;</code>
+     */
+    STRUCT(28, 28),
+    /**
+     * <code>MULTISET = 29;</code>
+     */
+    MULTISET(29, 29),
     UNRECOGNIZED(-1, -1),
     ;
 
@@ -434,6 +446,18 @@ package org.apache.calcite.avatica.proto;
      * <code>NULL = 24;</code>
      */
     public static final int NULL_VALUE = 24;
+    /**
+     * <code>ARRAY = 27;</code>
+     */
+    public static final int ARRAY_VALUE = 27;
+    /**
+     * <code>STRUCT = 28;</code>
+     */
+    public static final int STRUCT_VALUE = 28;
+    /**
+     * <code>MULTISET = 29;</code>
+     */
+    public static final int MULTISET_VALUE = 29;
 
 
     public final int getNumber() {
@@ -473,6 +497,9 @@ package org.apache.calcite.avatica.proto;
         case 22: return NUMBER;
         case 23: return OBJECT;
         case 24: return NULL;
+        case 27: return ARRAY;
+        case 28: return STRUCT;
+        case 29: return MULTISET;
         default: return null;
       }
     }
@@ -9809,27 +9836,27 @@ package org.apache.calcite.avatica.proto;
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> 
+    java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue> 
         getValueList();
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index);
+    org.apache.calcite.avatica.proto.Common.ColumnValue getValue(int index);
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
     int getValueCount();
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+    java.util.List<? extends org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder> 
         getValueOrBuilderList();
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+    org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder getValueOrBuilder(
         int index);
   }
   /**
@@ -9877,10 +9904,10 @@ package org.apache.calcite.avatica.proto;
             }
             case 10: {
               if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.TypedValue>();
+                value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.ColumnValue>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              value_.add(input.readMessage(org.apache.calcite.avatica.proto.Common.TypedValue.parser(), extensionRegistry));
+              value_.add(input.readMessage(org.apache.calcite.avatica.proto.Common.ColumnValue.parser(), extensionRegistry));
               break;
             }
           }
@@ -9911,36 +9938,36 @@ package org.apache.calcite.avatica.proto;
     }
 
     public static final int VALUE_FIELD_NUMBER = 1;
-    private java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> value_;
+    private java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue> value_;
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> getValueList() {
+    public java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue> getValueList() {
       return value_;
     }
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    public java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+    public java.util.List<? extends org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder> 
         getValueOrBuilderList() {
       return value_;
     }
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
     public int getValueCount() {
       return value_.size();
     }
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    public org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index) {
+    public org.apache.calcite.avatica.proto.Common.ColumnValue getValue(int index) {
       return value_.get(index);
     }
     /**
-     * <code>repeated .TypedValue value = 1;</code>
+     * <code>repeated .ColumnValue value = 1;</code>
      */
-    public org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+    public org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder getValueOrBuilder(
         int index) {
       return value_.get(index);
     }
@@ -10193,22 +10220,22 @@ package org.apache.calcite.avatica.proto;
       }
       private int bitField0_;
 
-      private java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> value_ =
+      private java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue> value_ =
         java.util.Collections.emptyList();
       private void ensureValueIsMutable() {
         if (!((bitField0_ & 0x00000001) == 0x00000001)) {
-          value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.TypedValue>(value_);
+          value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.ColumnValue>(value_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> valueBuilder_;
+          org.apache.calcite.avatica.proto.Common.ColumnValue, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder, org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder> valueBuilder_;
 
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> getValueList() {
+      public java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue> getValueList() {
         if (valueBuilder_ == null) {
           return java.util.Collections.unmodifiableList(value_);
         } else {
@@ -10216,7 +10243,7 @@ package org.apache.calcite.avatica.proto;
         }
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public int getValueCount() {
         if (valueBuilder_ == null) {
@@ -10226,9 +10253,9 @@ package org.apache.calcite.avatica.proto;
         }
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index) {
+      public org.apache.calcite.avatica.proto.Common.ColumnValue getValue(int index) {
         if (valueBuilder_ == null) {
           return value_.get(index);
         } else {
@@ -10236,10 +10263,10 @@ package org.apache.calcite.avatica.proto;
         }
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder setValue(
-          int index, org.apache.calcite.avatica.proto.Common.TypedValue value) {
+          int index, org.apache.calcite.avatica.proto.Common.ColumnValue value) {
         if (valueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
@@ -10253,10 +10280,10 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder setValue(
-          int index, org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+          int index, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder builderForValue) {
         if (valueBuilder_ == null) {
           ensureValueIsMutable();
           value_.set(index, builderForValue.build());
@@ -10267,9 +10294,9 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public Builder addValue(org.apache.calcite.avatica.proto.Common.TypedValue value) {
+      public Builder addValue(org.apache.calcite.avatica.proto.Common.ColumnValue value) {
         if (valueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
@@ -10283,10 +10310,10 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder addValue(
-          int index, org.apache.calcite.avatica.proto.Common.TypedValue value) {
+          int index, org.apache.calcite.avatica.proto.Common.ColumnValue value) {
         if (valueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
@@ -10300,10 +10327,10 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder addValue(
-          org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+          org.apache.calcite.avatica.proto.Common.ColumnValue.Builder builderForValue) {
         if (valueBuilder_ == null) {
           ensureValueIsMutable();
           value_.add(builderForValue.build());
@@ -10314,10 +10341,10 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder addValue(
-          int index, org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+          int index, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder builderForValue) {
         if (valueBuilder_ == null) {
           ensureValueIsMutable();
           value_.add(index, builderForValue.build());
@@ -10328,10 +10355,10 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder addAllValue(
-          java.lang.Iterable<? extends org.apache.calcite.avatica.proto.Common.TypedValue> values) {
+          java.lang.Iterable<? extends org.apache.calcite.avatica.proto.Common.ColumnValue> values) {
         if (valueBuilder_ == null) {
           ensureValueIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
@@ -10343,7 +10370,7 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder clearValue() {
         if (valueBuilder_ == null) {
@@ -10356,7 +10383,7 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
       public Builder removeValue(int index) {
         if (valueBuilder_ == null) {
@@ -10369,16 +10396,16 @@ package org.apache.calcite.avatica.proto;
         return this;
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder getValueBuilder(
+      public org.apache.calcite.avatica.proto.Common.ColumnValue.Builder getValueBuilder(
           int index) {
         return getValueFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+      public org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder getValueOrBuilder(
           int index) {
         if (valueBuilder_ == null) {
           return value_.get(index);  } else {
@@ -10386,9 +10413,9 @@ package org.apache.calcite.avatica.proto;
         }
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+      public java.util.List<? extends org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder> 
            getValueOrBuilderList() {
         if (valueBuilder_ != null) {
           return valueBuilder_.getMessageOrBuilderList();
@@ -10397,33 +10424,33 @@ package org.apache.calcite.avatica.proto;
         }
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder addValueBuilder() {
+      public org.apache.calcite.avatica.proto.Common.ColumnValue.Builder addValueBuilder() {
         return getValueFieldBuilder().addBuilder(
-            org.apache.calcite.avatica.proto.Common.TypedValue.getDefaultInstance());
+            org.apache.calcite.avatica.proto.Common.ColumnValue.getDefaultInstance());
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder addValueBuilder(
+      public org.apache.calcite.avatica.proto.Common.ColumnValue.Builder addValueBuilder(
           int index) {
         return getValueFieldBuilder().addBuilder(
-            index, org.apache.calcite.avatica.proto.Common.TypedValue.getDefaultInstance());
+            index, org.apache.calcite.avatica.proto.Common.ColumnValue.getDefaultInstance());
       }
       /**
-       * <code>repeated .TypedValue value = 1;</code>
+       * <code>repeated .ColumnValue value = 1;</code>
        */
-      public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue.Builder> 
+      public java.util.List<org.apache.calcite.avatica.proto.Common.ColumnValue.Builder> 
            getValueBuilderList() {
         return getValueFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+          org.apache.calcite.avatica.proto.Common.ColumnValue, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder, org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder> 
           getValueFieldBuilder() {
         if (valueBuilder_ == null) {
           valueBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
-              org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder>(
+              org.apache.calcite.avatica.proto.Common.ColumnValue, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder, org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder>(
                   value_,
                   ((bitField0_ & 0x00000001) == 0x00000001),
                   getParentForChildren(),
@@ -11654,113 +11681,51 @@ package org.apache.calcite.avatica.proto;
 
   }
 
-  public interface TypedValueOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:TypedValue)
+  public interface ColumnValueOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:ColumnValue)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>optional .Rep type = 1;</code>
-     *
-     * <pre>
-     * The actual type that was serialized in the general attribute below
-     * </pre>
-     */
-    int getTypeValue();
-    /**
-     * <code>optional .Rep type = 1;</code>
-     *
-     * <pre>
-     * The actual type that was serialized in the general attribute below
-     * </pre>
-     */
-    org.apache.calcite.avatica.proto.Common.Rep getType();
-
-    /**
-     * <code>optional bool bool_value = 2;</code>
-     *
-     * <pre>
-     * boolean
-     * </pre>
-     */
-    boolean getBoolValue();
-
-    /**
-     * <code>optional string string_value = 3;</code>
-     *
-     * <pre>
-     * char/varchar
-     * </pre>
-     */
-    java.lang.String getStringValue();
-    /**
-     * <code>optional string string_value = 3;</code>
-     *
-     * <pre>
-     * char/varchar
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    com.google.protobuf.ByteString
-        getStringValueBytes();
-
+    java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> 
+        getValueList();
     /**
-     * <code>optional sint64 number_value = 4;</code>
-     *
-     * <pre>
-     * var-len encoding lets us shove anything from byte to long
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    long getNumberValue();
-
+    org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index);
     /**
-     * <code>optional bytes bytes_values = 5;</code>
-     *
-     * <pre>
-     * includes numeric types and date/time types.
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    com.google.protobuf.ByteString getBytesValues();
-
+    int getValueCount();
     /**
-     * <code>optional double double_value = 6;</code>
-     *
-     * <pre>
-     * big numbers
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    double getDoubleValue();
-
+    java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+        getValueOrBuilderList();
     /**
-     * <code>optional bool null = 7;</code>
-     *
-     * <pre>
-     * a null object
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    boolean getNull();
+    org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+        int index);
   }
   /**
-   * Protobuf type {@code TypedValue}
+   * Protobuf type {@code ColumnValue}
    *
    * <pre>
-   * Generic wrapper to support any SQL type. Struct-like to work around no polymorphism construct.
+   * A value might be a TypedValue or an Array of TypedValue's
    * </pre>
    */
-  public  static final class TypedValue extends
+  public  static final class ColumnValue extends
       com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:TypedValue)
-      TypedValueOrBuilder {
-    // Use TypedValue.newBuilder() to construct.
-    private TypedValue(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      // @@protoc_insertion_point(message_implements:ColumnValue)
+      ColumnValueOrBuilder {
+    // Use ColumnValue.newBuilder() to construct.
+    private ColumnValue(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
       super(builder);
     }
-    private TypedValue() {
-      type_ = 0;
-      boolValue_ = false;
-      stringValue_ = "";
-      numberValue_ = 0L;
-      bytesValues_ = com.google.protobuf.ByteString.EMPTY;
-      doubleValue_ = 0D;
-      null_ = false;
+    private ColumnValue() {
+      value_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
@@ -11768,7 +11733,7 @@ package org.apache.calcite.avatica.proto;
     getUnknownFields() {
       return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
-    private TypedValue(
+    private ColumnValue(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
       this();
@@ -11787,41 +11752,12 @@ package org.apache.calcite.avatica.proto;
               }
               break;
             }
-            case 8: {
-              int rawValue = input.readEnum();
-
-              type_ = rawValue;
-              break;
-            }
-            case 16: {
-
-              boolValue_ = input.readBool();
-              break;
-            }
-            case 26: {
-              String s = input.readStringRequireUtf8();
-
-              stringValue_ = s;
-              break;
-            }
-            case 32: {
-
-              numberValue_ = input.readSInt64();
-              break;
-            }
-            case 42: {
-
-              bytesValues_ = input.readBytes();
-              break;
-            }
-            case 49: {
-
-              doubleValue_ = input.readDouble();
-              break;
-            }
-            case 56: {
-
-              null_ = input.readBool();
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.TypedValue>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              value_.add(input.readMessage(org.apache.calcite.avatica.proto.Common.TypedValue.parser(), extensionRegistry));
               break;
             }
           }
@@ -11833,53 +11769,830 @@ package org.apache.calcite.avatica.proto;
             new com.google.protobuf.InvalidProtocolBufferException(
                 e.getMessage()).setUnfinishedMessage(this));
       } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          value_ = java.util.Collections.unmodifiableList(value_);
+        }
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.internal_static_TypedValue_descriptor;
+      return org.apache.calcite.avatica.proto.Common.internal_static_ColumnValue_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Common.internal_static_TypedValue_fieldAccessorTable
+      return org.apache.calcite.avatica.proto.Common.internal_static_ColumnValue_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Common.TypedValue.class, org.apache.calcite.avatica.proto.Common.TypedValue.Builder.class);
+              org.apache.calcite.avatica.proto.Common.ColumnValue.class, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder.class);
     }
 
-    public static final int TYPE_FIELD_NUMBER = 1;
-    private int type_;
+    public static final int VALUE_FIELD_NUMBER = 1;
+    private java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> value_;
     /**
-     * <code>optional .Rep type = 1;</code>
-     *
-     * <pre>
-     * The actual type that was serialized in the general attribute below
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    public int getTypeValue() {
-      return type_;
+    public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> getValueList() {
+      return value_;
     }
     /**
-     * <code>optional .Rep type = 1;</code>
-     *
-     * <pre>
-     * The actual type that was serialized in the general attribute below
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
      */
-    public org.apache.calcite.avatica.proto.Common.Rep getType() {
-      org.apache.calcite.avatica.proto.Common.Rep result = org.apache.calcite.avatica.proto.Common.Rep.valueOf(type_);
-      return result == null ? org.apache.calcite.avatica.proto.Common.Rep.UNRECOGNIZED : result;
+    public java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+        getValueOrBuilderList() {
+      return value_;
     }
-
-    public static final int BOOL_VALUE_FIELD_NUMBER = 2;
-    private boolean boolValue_;
     /**
-     * <code>optional bool bool_value = 2;</code>
-     *
-     * <pre>
-     * boolean
-     * </pre>
+     * <code>repeated .TypedValue value = 1;</code>
+     */
+    public int getValueCount() {
+      return value_.size();
+    }
+    /**
+     * <code>repeated .TypedValue value = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index) {
+      return value_.get(index);
+    }
+    /**
+     * <code>repeated .TypedValue value = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+        int index) {
+      return value_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < value_.size(); i++) {
+        output.writeMessage(1, value_.get(i));
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < value_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, value_.get(i));
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(org.apache.calcite.avatica.proto.Common.ColumnValue prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code ColumnValue}
+     *
+     * <pre>
+     * A value might be a TypedValue or an Array of TypedValue's
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:ColumnValue)
+        org.apache.calcite.avatica.proto.Common.ColumnValueOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ColumnValue_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ColumnValue_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Common.ColumnValue.class, org.apache.calcite.avatica.proto.Common.ColumnValue.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Common.ColumnValue.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getValueFieldBuilder();
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        if (valueBuilder_ == null) {
+          value_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          valueBuilder_.clear();
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ColumnValue_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ColumnValue getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Common.ColumnValue.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ColumnValue build() {
+        org.apache.calcite.avatica.proto.Common.ColumnValue result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ColumnValue buildPartial() {
+        org.apache.calcite.avatica.proto.Common.ColumnValue result = new org.apache.calcite.avatica.proto.Common.ColumnValue(this);
+        int from_bitField0_ = bitField0_;
+        if (valueBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            value_ = java.util.Collections.unmodifiableList(value_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.value_ = value_;
+        } else {
+          result.value_ = valueBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Common.ColumnValue) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Common.ColumnValue)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Common.ColumnValue other) {
+        if (other == org.apache.calcite.avatica.proto.Common.ColumnValue.getDefaultInstance()) return this;
+        if (valueBuilder_ == null) {
+          if (!other.value_.isEmpty()) {
+            if (value_.isEmpty()) {
+              value_ = other.value_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureValueIsMutable();
+              value_.addAll(other.value_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.value_.isEmpty()) {
+            if (valueBuilder_.isEmpty()) {
+              valueBuilder_.dispose();
+              valueBuilder_ = null;
+              value_ = other.value_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              valueBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getValueFieldBuilder() : null;
+            } else {
+              valueBuilder_.addAllMessages(other.value_);
+            }
+          }
+        }
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.calcite.avatica.proto.Common.ColumnValue parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Common.ColumnValue) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> value_ =
+        java.util.Collections.emptyList();
+      private void ensureValueIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          value_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Common.TypedValue>(value_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> valueBuilder_;
+
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue> getValueList() {
+        if (valueBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(value_);
+        } else {
+          return valueBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public int getValueCount() {
+        if (valueBuilder_ == null) {
+          return value_.size();
+        } else {
+          return valueBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.TypedValue getValue(int index) {
+        if (valueBuilder_ == null) {
+          return value_.get(index);
+        } else {
+          return valueBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder setValue(
+          int index, org.apache.calcite.avatica.proto.Common.TypedValue value) {
+        if (valueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureValueIsMutable();
+          value_.set(index, value);
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder setValue(
+          int index, org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+        if (valueBuilder_ == null) {
+          ensureValueIsMutable();
+          value_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder addValue(org.apache.calcite.avatica.proto.Common.TypedValue value) {
+        if (valueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureValueIsMutable();
+          value_.add(value);
+          onChanged();
+        } else {
+          valueBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder addValue(
+          int index, org.apache.calcite.avatica.proto.Common.TypedValue value) {
+        if (valueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureValueIsMutable();
+          value_.add(index, value);
+          onChanged();
+        } else {
+          valueBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder addValue(
+          org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+        if (valueBuilder_ == null) {
+          ensureValueIsMutable();
+          value_.add(builderForValue.build());
+          onChanged();
+        } else {
+          valueBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder addValue(
+          int index, org.apache.calcite.avatica.proto.Common.TypedValue.Builder builderForValue) {
+        if (valueBuilder_ == null) {
+          ensureValueIsMutable();
+          value_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          valueBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder addAllValue(
+          java.lang.Iterable<? extends org.apache.calcite.avatica.proto.Common.TypedValue> values) {
+        if (valueBuilder_ == null) {
+          ensureValueIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, value_);
+          onChanged();
+        } else {
+          valueBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder clearValue() {
+        if (valueBuilder_ == null) {
+          value_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          valueBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public Builder removeValue(int index) {
+        if (valueBuilder_ == null) {
+          ensureValueIsMutable();
+          value_.remove(index);
+          onChanged();
+        } else {
+          valueBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder getValueBuilder(
+          int index) {
+        return getValueFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder getValueOrBuilder(
+          int index) {
+        if (valueBuilder_ == null) {
+          return value_.get(index);  } else {
+          return valueBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public java.util.List<? extends org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+           getValueOrBuilderList() {
+        if (valueBuilder_ != null) {
+          return valueBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(value_);
+        }
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder addValueBuilder() {
+        return getValueFieldBuilder().addBuilder(
+            org.apache.calcite.avatica.proto.Common.TypedValue.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.TypedValue.Builder addValueBuilder(
+          int index) {
+        return getValueFieldBuilder().addBuilder(
+            index, org.apache.calcite.avatica.proto.Common.TypedValue.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .TypedValue value = 1;</code>
+       */
+      public java.util.List<org.apache.calcite.avatica.proto.Common.TypedValue.Builder> 
+           getValueBuilderList() {
+        return getValueFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder> 
+          getValueFieldBuilder() {
+        if (valueBuilder_ == null) {
+          valueBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.calcite.avatica.proto.Common.TypedValue, org.apache.calcite.avatica.proto.Common.TypedValue.Builder, org.apache.calcite.avatica.proto.Common.TypedValueOrBuilder>(
+                  value_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          value_ = null;
+        }
+        return valueBuilder_;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:ColumnValue)
+    }
+
+    // @@protoc_insertion_point(class_scope:ColumnValue)
+    private static final org.apache.calcite.avatica.proto.Common.ColumnValue DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Common.ColumnValue();
+    }
+
+    public static org.apache.calcite.avatica.proto.Common.ColumnValue getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<ColumnValue>
+        PARSER = new com.google.protobuf.AbstractParser<ColumnValue>() {
+      public ColumnValue parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new ColumnValue(input, extensionRegistry);
+        } catch (RuntimeException e) {
+          if (e.getCause() instanceof
+              com.google.protobuf.InvalidProtocolBufferException) {
+            throw (com.google.protobuf.InvalidProtocolBufferException)
+                e.getCause();
+          }
+          throw e;
+        }
+      }
+    };
+
+    public static com.google.protobuf.Parser<ColumnValue> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ColumnValue> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Common.ColumnValue getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface TypedValueOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:TypedValue)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional .Rep type = 1;</code>
+     *
+     * <pre>
+     * The actual type that was serialized in the general attribute below
+     * </pre>
+     */
+    int getTypeValue();
+    /**
+     * <code>optional .Rep type = 1;</code>
+     *
+     * <pre>
+     * The actual type that was serialized in the general attribute below
+     * </pre>
+     */
+    org.apache.calcite.avatica.proto.Common.Rep getType();
+
+    /**
+     * <code>optional bool bool_value = 2;</code>
+     *
+     * <pre>
+     * boolean
+     * </pre>
+     */
+    boolean getBoolValue();
+
+    /**
+     * <code>optional string string_value = 3;</code>
+     *
+     * <pre>
+     * char/varchar
+     * </pre>
+     */
+    java.lang.String getStringValue();
+    /**
+     * <code>optional string string_value = 3;</code>
+     *
+     * <pre>
+     * char/varchar
+     * </pre>
+     */
+    com.google.protobuf.ByteString
+        getStringValueBytes();
+
+    /**
+     * <code>optional sint64 number_value = 4;</code>
+     *
+     * <pre>
+     * var-len encoding lets us shove anything from byte to long
+     * </pre>
+     */
+    long getNumberValue();
+
+    /**
+     * <code>optional bytes bytes_values = 5;</code>
+     *
+     * <pre>
+     * includes numeric types and date/time types.
+     * </pre>
+     */
+    com.google.protobuf.ByteString getBytesValues();
+
+    /**
+     * <code>optional double double_value = 6;</code>
+     *
+     * <pre>
+     * big numbers
+     * </pre>
+     */
+    double getDoubleValue();
+
+    /**
+     * <code>optional bool null = 7;</code>
+     *
+     * <pre>
+     * a null object
+     * </pre>
+     */
+    boolean getNull();
+  }
+  /**
+   * Protobuf type {@code TypedValue}
+   *
+   * <pre>
+   * Generic wrapper to support any SQL type. Struct-like to work around no polymorphism construct.
+   * </pre>
+   */
+  public  static final class TypedValue extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:TypedValue)
+      TypedValueOrBuilder {
+    // Use TypedValue.newBuilder() to construct.
+    private TypedValue(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private TypedValue() {
+      type_ = 0;
+      boolValue_ = false;
+      stringValue_ = "";
+      numberValue_ = 0L;
+      bytesValues_ = com.google.protobuf.ByteString.EMPTY;
+      doubleValue_ = 0D;
+      null_ = false;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private TypedValue(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+      this();
+      int mutable_bitField0_ = 0;
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!input.skipField(tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              int rawValue = input.readEnum();
+
+              type_ = rawValue;
+              break;
+            }
+            case 16: {
+
+              boolValue_ = input.readBool();
+              break;
+            }
+            case 26: {
+              String s = input.readStringRequireUtf8();
+
+              stringValue_ = s;
+              break;
+            }
+            case 32: {
+
+              numberValue_ = input.readSInt64();
+              break;
+            }
+            case 42: {
+
+              bytesValues_ = input.readBytes();
+              break;
+            }
+            case 49: {
+
+              doubleValue_ = input.readDouble();
+              break;
+            }
+            case 56: {
+
+              null_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw new RuntimeException(e.setUnfinishedMessage(this));
+      } catch (java.io.IOException e) {
+        throw new RuntimeException(
+            new com.google.protobuf.InvalidProtocolBufferException(
+                e.getMessage()).setUnfinishedMessage(this));
+      } finally {
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.internal_static_TypedValue_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Common.internal_static_TypedValue_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Common.TypedValue.class, org.apache.calcite.avatica.proto.Common.TypedValue.Builder.class);
+    }
+
+    public static final int TYPE_FIELD_NUMBER = 1;
+    private int type_;
+    /**
+     * <code>optional .Rep type = 1;</code>
+     *
+     * <pre>
+     * The actual type that was serialized in the general attribute below
+     * </pre>
+     */
+    public int getTypeValue() {
+      return type_;
+    }
+    /**
+     * <code>optional .Rep type = 1;</code>
+     *
+     * <pre>
+     * The actual type that was serialized in the general attribute below
+     * </pre>
+     */
+    public org.apache.calcite.avatica.proto.Common.Rep getType() {
+      org.apache.calcite.avatica.proto.Common.Rep result = org.apache.calcite.avatica.proto.Common.Rep.valueOf(type_);
+      return result == null ? org.apache.calcite.avatica.proto.Common.Rep.UNRECOGNIZED : result;
+    }
+
+    public static final int BOOL_VALUE_FIELD_NUMBER = 2;
+    private boolean boolValue_;
+    /**
+     * <code>optional bool bool_value = 2;</code>
+     *
+     * <pre>
+     * boolean
+     * </pre>
      */
     public boolean getBoolValue() {
       return boolValue_;
@@ -12726,6 +13439,11 @@ package org.apache.calcite.avatica.proto;
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_WireMessage_fieldAccessorTable;
   private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_ColumnValue_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ColumnValue_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
     internal_static_TypedValue_descriptor;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
@@ -12774,33 +13492,35 @@ package org.apache.calcite.avatica.proto;
       "Style\022\n\n\006OBJECT\020\000\022\n\n\006RECORD\020\001\022\025\n\021RECORD_" +
       "PROJECTION\020\002\022\t\n\005ARRAY\020\003\022\010\n\004LIST\020\004\022\007\n\003MAP" +
       "\020\005\"9\n\005Frame\022\016\n\006offset\030\001 \001(\004\022\014\n\004done\030\002 \001(" +
-      "\010\022\022\n\004rows\030\003 \003(\0132\004.Row\"!\n\003Row\022\032\n\005value\030\001 " +
-      "\003(\0132\013.TypedValue\"3\n\020DatabaseProperty\022\014\n\004" +
-      "name\030\001 \001(\t\022\021\n\tfunctions\030\002 \003(\t\"4\n\013WireMes" +
-      "sage\022\014\n\004name\030\001 \001(\t\022\027\n\017wrapped_message\030\002 " +
-      "\001(\014\"\232\001\n\nTypedValue\022\022\n\004type\030\001 \001(\0162\004.Rep\022\022",
-      "\n\nbool_value\030\002 \001(\010\022\024\n\014string_value\030\003 \001(\t" +
-      "\022\024\n\014number_value\030\004 \001(\022\022\024\n\014bytes_values\030\005" +
-      " \001(\014\022\024\n\014double_value\030\006 \001(\001\022\014\n\004null\030\007 \001(\010" +
-      "*\237\001\n\rStatementType\022\n\n\006SELECT\020\000\022\n\n\006INSERT" +
-      "\020\001\022\n\n\006UPDATE\020\002\022\n\n\006DELETE\020\003\022\n\n\006UPSERT\020\004\022\t" +
-      "\n\005MERGE\020\005\022\r\n\tOTHER_DML\020\006\022\n\n\006CREATE\020\007\022\010\n\004" +
-      "DROP\020\010\022\t\n\005ALTER\020\t\022\r\n\tOTHER_DDL\020\n\022\010\n\004CALL" +
-      "\020\013*\275\003\n\003Rep\022\025\n\021PRIMITIVE_BOOLEAN\020\000\022\022\n\016PRI" +
-      "MITIVE_BYTE\020\001\022\022\n\016PRIMITIVE_CHAR\020\002\022\023\n\017PRI" +
-      "MITIVE_SHORT\020\003\022\021\n\rPRIMITIVE_INT\020\004\022\022\n\016PRI",
-      "MITIVE_LONG\020\005\022\023\n\017PRIMITIVE_FLOAT\020\006\022\024\n\020PR" +
-      "IMITIVE_DOUBLE\020\007\022\013\n\007BOOLEAN\020\010\022\010\n\004BYTE\020\t\022" +
-      "\r\n\tCHARACTER\020\n\022\t\n\005SHORT\020\013\022\013\n\007INTEGER\020\014\022\010" +
-      "\n\004LONG\020\r\022\t\n\005FLOAT\020\016\022\n\n\006DOUBLE\020\017\022\017\n\013BIG_I" +
-      "NTEGER\020\031\022\017\n\013BIG_DECIMAL\020\032\022\021\n\rJAVA_SQL_TI" +
-      "ME\020\020\022\026\n\022JAVA_SQL_TIMESTAMP\020\021\022\021\n\rJAVA_SQL" +
-      "_DATE\020\022\022\022\n\016JAVA_UTIL_DATE\020\023\022\017\n\013BYTE_STRI" +
-      "NG\020\024\022\n\n\006STRING\020\025\022\n\n\006NUMBER\020\026\022\n\n\006OBJECT\020\027" +
-      "\022\010\n\004NULL\020\030*^\n\010Severity\022\024\n\020UNKNOWN_SEVERI" +
-      "TY\020\000\022\022\n\016FATAL_SEVERITY\020\001\022\022\n\016ERROR_SEVERI",
-      "TY\020\002\022\024\n\020WARNING_SEVERITY\020\003B\"\n org.apache" +
-      ".calcite.avatica.protob\006proto3"
+      "\010\022\022\n\004rows\030\003 \003(\0132\004.Row\"\"\n\003Row\022\033\n\005value\030\001 " +
+      "\003(\0132\014.ColumnValue\"3\n\020DatabaseProperty\022\014\n" +
+      "\004name\030\001 \001(\t\022\021\n\tfunctions\030\002 \003(\t\"4\n\013WireMe" +
+      "ssage\022\014\n\004name\030\001 \001(\t\022\027\n\017wrapped_message\030\002" +
+      " \001(\014\")\n\013ColumnValue\022\032\n\005value\030\001 \003(\0132\013.Typ",
+      "edValue\"\232\001\n\nTypedValue\022\022\n\004type\030\001 \001(\0162\004.R" +
+      "ep\022\022\n\nbool_value\030\002 \001(\010\022\024\n\014string_value\030\003" +
+      " \001(\t\022\024\n\014number_value\030\004 \001(\022\022\024\n\014bytes_valu" +
+      "es\030\005 \001(\014\022\024\n\014double_value\030\006 \001(\001\022\014\n\004null\030\007" +
+      " \001(\010*\237\001\n\rStatementType\022\n\n\006SELECT\020\000\022\n\n\006IN" +
+      "SERT\020\001\022\n\n\006UPDATE\020\002\022\n\n\006DELETE\020\003\022\n\n\006UPSERT" +
+      "\020\004\022\t\n\005MERGE\020\005\022\r\n\tOTHER_DML\020\006\022\n\n\006CREATE\020\007" +
+      "\022\010\n\004DROP\020\010\022\t\n\005ALTER\020\t\022\r\n\tOTHER_DDL\020\n\022\010\n\004" +
+      "CALL\020\013*\342\003\n\003Rep\022\025\n\021PRIMITIVE_BOOLEAN\020\000\022\022\n" +
+      "\016PRIMITIVE_BYTE\020\001\022\022\n\016PRIMITIVE_CHAR\020\002\022\023\n",
+      "\017PRIMITIVE_SHORT\020\003\022\021\n\rPRIMITIVE_INT\020\004\022\022\n" +
+      "\016PRIMITIVE_LONG\020\005\022\023\n\017PRIMITIVE_FLOAT\020\006\022\024" +
+      "\n\020PRIMITIVE_DOUBLE\020\007\022\013\n\007BOOLEAN\020\010\022\010\n\004BYT" +
+      "E\020\t\022\r\n\tCHARACTER\020\n\022\t\n\005SHORT\020\013\022\013\n\007INTEGER" +
+      "\020\014\022\010\n\004LONG\020\r\022\t\n\005FLOAT\020\016\022\n\n\006DOUBLE\020\017\022\017\n\013B" +
+      "IG_INTEGER\020\031\022\017\n\013BIG_DECIMAL\020\032\022\021\n\rJAVA_SQ" +
+      "L_TIME\020\020\022\026\n\022JAVA_SQL_TIMESTAMP\020\021\022\021\n\rJAVA" +
+      "_SQL_DATE\020\022\022\022\n\016JAVA_UTIL_DATE\020\023\022\017\n\013BYTE_" +
+      "STRING\020\024\022\n\n\006STRING\020\025\022\n\n\006NUMBER\020\026\022\n\n\006OBJE" +
+      "CT\020\027\022\010\n\004NULL\020\030\022\t\n\005ARRAY\020\033\022\n\n\006STRUCT\020\034\022\014\n",
+      "\010MULTISET\020\035*^\n\010Severity\022\024\n\020UNKNOWN_SEVER" +
+      "ITY\020\000\022\022\n\016FATAL_SEVERITY\020\001\022\022\n\016ERROR_SEVER" +
+      "ITY\020\002\022\024\n\020WARNING_SEVERITY\020\003B\"\n org.apach" +
+      "e.calcite.avatica.protob\006proto3"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
         new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
@@ -12880,8 +13600,14 @@ package org.apache.calcite.avatica.proto;
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_WireMessage_descriptor,
         new java.lang.String[] { "Name", "WrappedMessage", });
-    internal_static_TypedValue_descriptor =
+    internal_static_ColumnValue_descriptor =
       getDescriptor().getMessageTypes().get(11);
+    internal_static_ColumnValue_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_ColumnValue_descriptor,
+        new java.lang.String[] { "Value", });
+    internal_static_TypedValue_descriptor =
+      getDescriptor().getMessageTypes().get(12);
     internal_static_TypedValue_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_TypedValue_descriptor,

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
index 8cca9d9..3ca21f7 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
@@ -54,11 +54,13 @@ public class MockProtobufService extends ProtobufService {
     // Get the schema, no.. schema..?
     mappings.put(
         new SchemasRequest(connectionId, null, null),
-        new ResultSetResponse(null, 1, true, null, Meta.Frame.EMPTY, -1));
+        // ownStatement=false just to avoid the extra close statement call.
+        new ResultSetResponse(null, 1, false, null, Meta.Frame.EMPTY, -1));
 
     // Get the tables, no tables exist
     mappings.put(new TablesRequest(connectionId, null, null, null, Collections.<String>emptyList()),
-        new ResultSetResponse(null, 150, true, null, Meta.Frame.EMPTY, -1));
+        // ownStatement=false just to avoid the extra close statement call.
+        new ResultSetResponse(null, 150, false, null, Meta.Frame.EMPTY, -1));
 
     // Create a statement, get back an id
     mappings.put(new CreateStatementRequest("0"), new CreateStatementResponse("0", 1));

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/main/protobuf/common.proto
----------------------------------------------------------------------
diff --git a/avatica/src/main/protobuf/common.proto b/avatica/src/main/protobuf/common.proto
index 3716c7e..f4de1f9 100644
--- a/avatica/src/main/protobuf/common.proto
+++ b/avatica/src/main/protobuf/common.proto
@@ -114,6 +114,9 @@ enum Rep {
   NUMBER = 22;
   OBJECT = 23;
   NULL = 24;
+  ARRAY = 27;
+  STRUCT = 28;
+  MULTISET = 29;
 }
 
 // Base class for a column type
@@ -162,7 +165,7 @@ message Frame {
 
 // A row is a collection of values
 message Row {
-  repeated TypedValue value = 1;
+  repeated ColumnValue value = 1;
 }
 
 // Database property, list of functions the database provides for a certain operation
@@ -177,6 +180,11 @@ message WireMessage {
   bytes wrapped_message = 2;
 }
 
+// A value might be a TypedValue or an Array of TypedValue's
+message ColumnValue {
+  repeated TypedValue value = 1;
+}
+
 // Generic wrapper to support any SQL type. Struct-like to work around no polymorphism construct.
 message TypedValue {
   Rep type = 1; // The actual type that was serialized in the general attribute below

http://git-wip-us.apache.org/repos/asf/calcite/blob/bf178d55/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java b/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
index aa03c3c..f91f597 100644
--- a/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
+++ b/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
@@ -105,17 +105,22 @@ public class ProtobufHandlerTest {
     List<Common.Row> rows = protoFrame.getRowsList();
     assertEquals(1, rows.size());
     Common.Row row = rows.get(0);
-    List<Common.TypedValue> rowValues = row.getValueList();
-    assertEquals(2, rowValues.size());
+    List<Common.ColumnValue> columnValues = row.getValueList();
+    assertEquals(2, columnValues.size());
 
-    Iterator<Common.TypedValue> iter = rowValues.iterator();
+    Iterator<Common.ColumnValue> iter = columnValues.iterator();
     assertTrue(iter.hasNext());
-    Common.TypedValue value = iter.next();
+    Common.ColumnValue column = iter.next();
+    assertEquals(1, column.getValueCount());
+
+    Common.TypedValue value = column.getValue(0);
     assertEquals(Common.Rep.BOOLEAN, value.getType());
     assertEquals(true, value.getBoolValue());
 
     assertTrue(iter.hasNext());
-    value = iter.next();
+    column = iter.next();
+    assertEquals(1, column.getValueCount());
+    value = column.getValue(0);
     assertEquals(Common.Rep.STRING, value.getType());
     assertEquals("my_string", value.getStringValue());
   }


Mime
View raw message