http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/DriverVersion.java
----------------------------------------------------------------------
diff --git 
a/avatica/core/src/main/java/org/apache/calcite/avatica/DriverVersion.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/DriverVersion.java
deleted file mode 100644
index 15c966a..0000000
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/DriverVersion.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-/**
- * Driver version information.
- *
- * <p>Each driver implementation must provide an instance of this class, in
- * order to implement {@link UnregisteredDriver#createDriverVersion()}.</p>
- *
- * <p>There are two typical ways for a driver to instantiate its version
- * information:</p>
- *
- * <ul>
- *
- * <li>A driver might create a subclass in a with a constructor that provides
- * all of the arguments for the base class. The instance is held in a separate
- * file, so that that version information can be generated.</li>
- *
- * <li>A driver might store the version information in a .properties file and
- * load it using {@link #load}.</li>
- *
- * </ul>
- */
-public class DriverVersion {
-  public final int majorVersion;
-  public final int minorVersion;
-  public final String name;
-  public final String versionString;
-  public final String productName;
-  public final String productVersion;
-  public final boolean jdbcCompliant;
-  public final int databaseMajorVersion;
-  public final int databaseMinorVersion;
-
-  /** Creates a DriverVersion. */
-  public DriverVersion(
-      String name,
-      String versionString,
-      String productName,
-      String productVersion,
-      boolean jdbcCompliant,
-      int majorVersion,
-      int minorVersion,
-      int databaseMajorVersion,
-      int databaseMinorVersion) {
-    this.majorVersion = majorVersion;
-    this.minorVersion = minorVersion;
-    this.name = name;
-    this.versionString = versionString;
-    this.productName = productName;
-    this.productVersion = productVersion;
-    this.jdbcCompliant = jdbcCompliant;
-    this.databaseMajorVersion = databaseMajorVersion;
-    this.databaseMinorVersion = databaseMinorVersion;
-  }
-
-  /** Loads a driver version from a properties file, read from the classpath.
-   * The arguments provide defaults if the properties cannot be loaded.
-   *
-   * @param driverClass Class of driver; used to find resource
-   * @param resourceName Name of resource file
-   * @param driverName Fallback name of driver
-   * @param driverVersion Fallback version of driver
-   * @param productName Fallback product name
-   * @param productVersion Fallback product version
-   * @return A populated driver version object, never null
-   */
-  public static DriverVersion load(
-      Class<? extends UnregisteredDriver> driverClass,
-      String resourceName,
-      String driverName,
-      String driverVersion,
-      String productName,
-      String productVersion) {
-    boolean jdbcCompliant = true;
-    int majorVersion = 0;
-    int minorVersion = 0;
-    int databaseMajorVersion = 0;
-    int databaseMinorVersion = 0;
-    try {
-      final InputStream inStream =
-          driverClass.getClassLoader().getResourceAsStream(resourceName);
-      if (inStream != null) {
-        final Properties properties = new Properties();
-        properties.load(inStream);
-        driverName = properties.getProperty("driver.name");
-        driverVersion = properties.getProperty("driver.version");
-        productName = properties.getProperty("product.name");
-        productVersion = properties.getProperty("product.version");
-        jdbcCompliant =
-            Boolean.valueOf(properties.getProperty("jdbc.compliant"));
-        String[] s = driverVersion.replaceAll("-.*$", "").split("\\.");
-        final int major = Integer.valueOf(s[0]);
-        final int minor = Integer.valueOf(s[1]);
-        try {
-          majorVersion =
-              Integer.valueOf(properties.getProperty("driver.version.major"));
-        } catch (NumberFormatException e) {
-          majorVersion = major;
-        }
-        try {
-          minorVersion =
-              Integer.valueOf(properties.getProperty("driver.version.minor"));
-        } catch (NumberFormatException e) {
-          minorVersion = minor;
-        }
-        try {
-          databaseMajorVersion =
-              
Integer.valueOf(properties.getProperty("database.version.major"));
-        } catch (NumberFormatException e) {
-          databaseMajorVersion = major;
-        }
-        try {
-          databaseMinorVersion =
-              
Integer.valueOf(properties.getProperty("database.version.minor"));
-        } catch (NumberFormatException e) {
-          databaseMinorVersion = minor;
-        }
-      }
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-    return new DriverVersion(
-        driverName, driverVersion, productName, productVersion,
-        jdbcCompliant, majorVersion, minorVersion, databaseMajorVersion,
-        databaseMinorVersion);
-  }
-}
-
-// End DriverVersion.java

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/Handler.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/Handler.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/Handler.java
deleted file mode 100644
index 831e66d..0000000
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/Handler.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import java.sql.SQLException;
-
-/**
- * Called at various points in the JDBC lifecycle.
- *
- * <p>Most drivers will use {@link HandlerImpl}, which provides no-op
- * implementations of all methods. You only need to override methods if you
- * need to achieve special effects.</p>
- */
-public interface Handler {
-  /** Called by container when a connection is being created.
-   *
-   * <p>If the implementation of this method throws, the connection
-   * will not be created.</p>
-   *
-   * @param connection Connection
-   * @throws SQLException on error
-   */
-  void onConnectionInit(AvaticaConnection connection) throws SQLException;
-
-  /** Called by container when a connection is being closed.
-   *
-   * <p>If the implementation of this method throws, the call to
-   * {@link java.sql.Connection#close} that triggered this method will throw an
-   * exception, but the connection will still be marked closed.</p>
-   *
-   * @param connection Connection
-   */
-  void onConnectionClose(AvaticaConnection connection);
-
-  /** Called by container when a statement is being executed.
-   *
-   * <p>If the session would like the statement results stored in a temporary
-   * table, {@code resultSink} is not null.
-   * The provider must call its {@link ResultSink#toBeCompleted}
-   * method at some point during execution (not necessarily before the call to
-   * this method returns).</p>
-   *
-   * @param statement Statement
-   * @param resultSink Place to put result of query. Null if container does not
-   *                   want results stored to a temporary table
-   * @throws RuntimeException on error
-   */
-  void onStatementExecute(
-      AvaticaStatement statement,
-      ResultSink resultSink);
-
-  /** Called by container when a statement is being closed.
-   *
-   * <p>This method is called after marking the statement closed, and after
-   * closing any open {@link java.sql.ResultSet} objects.</p>
-   *
-   * <p>If the implementation of this method throws, the call to
-   * {@link java.sql.Statement#close} that triggered this method will throw an
-   * exception, but the statement will still be marked closed.
-   *
-   * @param statement Statement
-   * @throws RuntimeException on error
-   */
-  void onStatementClose(AvaticaStatement statement);
-
-  /** Handler for temporary tables. */
-  interface ResultSink {
-    /** Registers a temporary table. */
-    void toBeCompleted();
-  }
-}
-
-// End Handler.java

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
----------------------------------------------------------------------
diff --git 
a/avatica/core/src/main/java/org/apache/calcite/avatica/HandlerImpl.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
deleted file mode 100644
index c2e6c1a..0000000
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of {@link Handler} that does nothing for each callback.
- * It is recommended implementations of {@code Handler} use this as a base
- * class, to ensure forward compatibility.
- */
-public class HandlerImpl implements Handler {
-  public void onConnectionInit(AvaticaConnection connection)
-      throws SQLException {
-    // nothing
-  }
-
-  public void onConnectionClose(AvaticaConnection connection) {
-    // nothing
-  }
-
-  public void onStatementExecute(
-      AvaticaStatement statement,
-      ResultSink resultSink) {
-    // nothing
-  }
-
-  public void onStatementClose(AvaticaStatement statement) {
-    // nothing
-  }
-}
-
-// End HandlerImpl.java

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/Helper.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/Helper.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/Helper.java
deleted file mode 100644
index 27c6056..0000000
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/Helper.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-
-/**
- * Utility methods, mainly concerning error-handling.
- */
-public class Helper {
-  public static final Helper INSTANCE = new Helper();
-
-  private Helper() {
-  }
-
-  public RuntimeException todo() {
-    return new RuntimeException("todo: implement this method");
-  }
-
-  public RuntimeException wrap(String message, Exception e) {
-    return new RuntimeException(message, e);
-  }
-
-  public SQLException createException(String message, Exception e) {
-    return createException(message, null, e);
-  }
-
-  public SQLException createException(String message, String sql, Exception e) 
{
-    if (e instanceof AvaticaClientRuntimeException) {
-      // The AvaticaClientRuntimeException contains extra information about 
what/why
-      // the exception was thrown that we can pass back to the user.
-      AvaticaClientRuntimeException rte = (AvaticaClientRuntimeException) e;
-      String serverAddress = null;
-      if (null != rte.getRpcMetadata()) {
-        serverAddress = rte.getRpcMetadata().serverAddress;
-      }
-      return new AvaticaSqlException(message, rte.getSqlState(), 
rte.getErrorCode(),
-          rte.getServerExceptions(), serverAddress);
-    }
-    return new SQLException(message, e);
-  }
-
-  public SQLException createException(String message) {
-    return new SQLException(message);
-  }
-
-  public SQLException toSQLException(SQLException exception) {
-    return exception;
-  }
-
-  public SQLException unsupported() {
-    return new SQLFeatureNotSupportedException();
-  }
-
-  public SQLClientInfoException clientInfo() {
-    return new SQLClientInfoException();
-  }
-}
-
-// End Helper.java

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/InternalProperty.java
----------------------------------------------------------------------
diff --git 
a/avatica/core/src/main/java/org/apache/calcite/avatica/InternalProperty.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/InternalProperty.java
deleted file mode 100644
index a5a3852..0000000
--- 
a/avatica/core/src/main/java/org/apache/calcite/avatica/InternalProperty.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import org.apache.calcite.avatica.ConnectionProperty.Type;
-import org.apache.calcite.avatica.util.Casing;
-import org.apache.calcite.avatica.util.Quoting;
-
-import java.util.Map;
-
-/**
- * Definitions of properties that drive the behavior of
- * {@link org.apache.calcite.avatica.AvaticaDatabaseMetaData}.
- */
-public enum InternalProperty {
-  /** Whether identifiers are matched case-sensitively. */
-  CASE_SENSITIVE(Type.BOOLEAN, true),
-
-  /** Character that quotes identifiers. */
-  SQL_KEYWORDS(Type.STRING, null),
-
-  /** How identifiers are quoted. */
-  QUOTING(Quoting.class, Quoting.DOUBLE_QUOTE),
-
-  /** How identifiers are stored if they are quoted. */
-  QUOTED_CASING(Casing.class, Casing.UNCHANGED),
-
-  /** How identifiers are stored if they are not quoted. */
-  UNQUOTED_CASING(Casing.class, Casing.TO_UPPER),
-
-  /** How identifiers are stored if they are not quoted. */
-  NULL_SORTING(NullSorting.class, NullSorting.END);
-
-  private final Type type;
-  private final Class enumClass;
-  private final Object defaultValue;
-
-  /** Creates an InternalProperty based on an enum. */
-  <E extends Enum> InternalProperty(Class<E> enumClass, E defaultValue) {
-    this(Type.ENUM, enumClass, defaultValue);
-  }
-
-  /** Creates an InternalProperty based on a non-enum type. */
-  InternalProperty(Type type, Object defaultValue) {
-    this(type, null, defaultValue);
-  }
-
-  private InternalProperty(Type type, Class enumClass, Object defaultValue) {
-    this.type = type;
-    this.enumClass = enumClass;
-    this.defaultValue = defaultValue;
-  }
-
-  private <T> T get_(Map<InternalProperty, Object> map, T defaultValue) {
-    final Object s = map.get(this);
-    if (s != null) {
-      return (T) s;
-    }
-    if (defaultValue != null) {
-      return (T) defaultValue;
-    }
-    throw new RuntimeException("Required property '" + name()
-        + "' not specified");
-  }
-
-  /** Returns the string value of this property, or null if not specified and
-   * no default. */
-  public String getString(Map<InternalProperty, Object> map) {
-    assert type == Type.STRING;
-    return get_(map, (String) defaultValue);
-  }
-
-  /** Returns the boolean value of this property. Throws if not set and no
-   * default. */
-  public boolean getBoolean(Map<InternalProperty, Object> map) {
-    assert type == Type.BOOLEAN;
-    return get_(map, (Boolean) defaultValue);
-  }
-
-  /** Returns the enum value of this property. Throws if not set and no
-   * default. */
-  public <E extends Enum> E getEnum(Map<InternalProperty, Object> map,
-      Class<E> enumClass) {
-    assert type == Type.ENUM;
-    //noinspection unchecked
-    return get_(map, (E) defaultValue);
-  }
-
-  /** Where nulls appear in a sorted relation. */
-  enum NullSorting {
-    START, END, LOW, HIGH,
-  }
-}
-
-// End InternalProperty.java

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
deleted file mode 100644
index 7df9ade..0000000
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import org.apache.calcite.avatica.proto.Common;
-import org.apache.calcite.avatica.remote.TypedValue;
-import org.apache.calcite.avatica.util.FilteredConstants;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-
-/**
- * Command handler for getting various metadata. Should be implemented by each
- * driver.
- *
- * <p>Also holds other abstract methods that are not related to metadata
- * that each provider must implement. This is not ideal.</p>
- */
-public interface Meta {
-
-  /**
-   * Returns a map of static database properties.
-   *
-   * <p>The provider can omit properties whose value is the same as the
-   * default.
-   */
-  Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch);
-
-  /** Per {@link DatabaseMetaData#getTables(String, String, String, 
String[])}. */
-  MetaResultSet getTables(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      List<String> typeList);
-
-  /** Per {@link DatabaseMetaData#getColumns(String, String, String, String)}. 
*/
-  MetaResultSet getColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      Pat columnNamePattern);
-
-  MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat 
schemaPattern);
-
-  /** Per {@link DatabaseMetaData#getCatalogs()}. */
-  MetaResultSet getCatalogs(ConnectionHandle ch);
-
-  /** Per {@link DatabaseMetaData#getTableTypes()}. */
-  MetaResultSet getTableTypes(ConnectionHandle ch);
-
-  /** Per {@link DatabaseMetaData#getProcedures(String, String, String)}. */
-  MetaResultSet getProcedures(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat procedureNamePattern);
-
-  /** Per {@link DatabaseMetaData#getProcedureColumns(String, String, String, 
String)}. */
-  MetaResultSet getProcedureColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat procedureNamePattern,
-      Pat columnNamePattern);
-
-  /** Per {@link DatabaseMetaData#getColumnPrivileges(String, String, String, 
String)}. */
-  MetaResultSet getColumnPrivileges(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table,
-      Pat columnNamePattern);
-
-  /** Per {@link DatabaseMetaData#getTablePrivileges(String, String, String)}. 
*/
-  MetaResultSet getTablePrivileges(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern);
-
-  /** Per
-   * {@link DatabaseMetaData#getBestRowIdentifier(String, String, String, int, 
boolean)}. */
-  MetaResultSet getBestRowIdentifier(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table,
-      int scope,
-      boolean nullable);
-
-  /** Per {@link DatabaseMetaData#getVersionColumns(String, String, String)}. 
*/
-  MetaResultSet getVersionColumns(ConnectionHandle ch, String catalog, String 
schema, String table);
-
-  /** Per {@link DatabaseMetaData#getPrimaryKeys(String, String, String)}. */
-  MetaResultSet getPrimaryKeys(ConnectionHandle ch, String catalog, String 
schema, String table);
-
-  /** Per {@link DatabaseMetaData#getImportedKeys(String, String, String)}. */
-  MetaResultSet getImportedKeys(ConnectionHandle ch, String catalog, String 
schema, String table);
-
-  /** Per {@link DatabaseMetaData#getExportedKeys(String, String, String)}. */
-  MetaResultSet getExportedKeys(ConnectionHandle ch, String catalog, String 
schema, String table);
-
-  /** Per
-   * {@link DatabaseMetaData#getCrossReference(String, String, String, String, 
String, String)}. */
-  MetaResultSet getCrossReference(ConnectionHandle ch,
-      String parentCatalog,
-      String parentSchema,
-      String parentTable,
-      String foreignCatalog,
-      String foreignSchema,
-      String foreignTable);
-
-  /** Per {@link DatabaseMetaData#getTypeInfo()}. */
-  MetaResultSet getTypeInfo(ConnectionHandle ch);
-
-  /** Per {@link DatabaseMetaData#getIndexInfo(String, String, String, 
boolean, boolean)}. */
-  MetaResultSet getIndexInfo(ConnectionHandle ch, String catalog,
-      String schema,
-      String table,
-      boolean unique,
-      boolean approximate);
-
-  /** Per {@link DatabaseMetaData#getUDTs(String, String, String, int[])}. */
-  MetaResultSet getUDTs(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern,
-      int[] types);
-
-  /** Per {@link DatabaseMetaData#getSuperTypes(String, String, String)}. */
-  MetaResultSet getSuperTypes(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern);
-
-  /** Per {@link DatabaseMetaData#getSuperTables(String, String, String)}. */
-  MetaResultSet getSuperTables(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern);
-
-  /** Per {@link DatabaseMetaData#getAttributes(String, String, String, 
String)}. */
-  MetaResultSet getAttributes(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern,
-      Pat attributeNamePattern);
-
-  /** Per {@link DatabaseMetaData#getClientInfoProperties()}. */
-  MetaResultSet getClientInfoProperties(ConnectionHandle ch);
-
-  /** Per {@link DatabaseMetaData#getFunctions(String, String, String)}. */
-  MetaResultSet getFunctions(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat functionNamePattern);
-
-  /** Per {@link DatabaseMetaData#getFunctionColumns(String, String, String, 
String)}. */
-  MetaResultSet getFunctionColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat functionNamePattern,
-      Pat columnNamePattern);
-
-  /** Per {@link DatabaseMetaData#getPseudoColumns(String, String, String, 
String)}. */
-  MetaResultSet getPseudoColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      Pat columnNamePattern);
-
-  /** Creates an iterable for a result set.
-   *
-   * <p>The default implementation just returns {@code iterable}, which it
-   * requires to be not null; derived classes may instead choose to execute the
-   * relational expression in {@code signature}. */
-  Iterable<Object> createIterable(StatementHandle stmt, QueryState state, 
Signature signature,
-      List<TypedValue> parameterValues, Frame firstFrame);
-
-  /** Prepares a statement.
-   *
-   * @param ch Connection handle
-   * @param sql SQL query
-   * @param maxRowCount Negative for no limit (different meaning than JDBC)
-   * @return Signature of prepared statement
-   */
-  StatementHandle prepare(ConnectionHandle ch, String sql, long maxRowCount);
-
-  /** Prepares and executes a statement.
-   *
-   * @param h Statement handle
-   * @param sql SQL query
-   * @param maxRowCount Negative for no limit (different meaning than JDBC)
-   * @param callback Callback to lock, clear and assign cursor
-   *
-   * @return Result containing statement ID, and if a query, a result set and
-   *     first frame of data
-   * @deprecated See {@link #prepareAndExecute(StatementHandle, String, long, 
int, PrepareCallback)}
-   */
-  @Deprecated // to be removed before 2.0
-  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      long maxRowCount, PrepareCallback callback) throws 
NoSuchStatementException;
-
-  /** Prepares and executes a statement.
-   *
-   * @param h Statement handle
-   * @param sql SQL query
-   * @param maxRowCount Maximum number of rows for the entire query. Negative 
for no limit
-   *    (different meaning than JDBC).
-   * @param maxRowsInFirstFrame Maximum number of rows for the first frame. 
This value should
-   *    always be less than or equal to {@code maxRowCount} as the number of 
results are guaranteed
-   *    to be restricted by {@code maxRowCount} and the underlying database.
-   * @param callback Callback to lock, clear and assign cursor
-   *
-   * @return Result containing statement ID, and if a query, a result set and
-   *     first frame of data
-   */
-  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      long maxRowCount, int maxRowsInFirstFrame, PrepareCallback callback)
-      throws NoSuchStatementException;
-
-  /** Prepares a statement and then executes a number of SQL commands in one 
pass.
-   *
-   * @param h Statement handle
-   * @param sqlCommands SQL commands to run
-   * @return An array of update counts containing one element for each command 
in the batch.
-   */
-  ExecuteBatchResult prepareAndExecuteBatch(StatementHandle h, List<String> 
sqlCommands)
-      throws NoSuchStatementException;
-
-  /** Executes a collection of bound parameter values on a prepared statement.
-   *
-   * @param h Statement handle
-   * @param parameterValues A collection of list of typed values, one list per 
batch
-   * @return An array of update counts containing one element for each command 
in the batch.
-   */
-  ExecuteBatchResult executeBatch(StatementHandle h, List<List<TypedValue>> 
parameterValues)
-      throws NoSuchStatementException;
-
-  /** Returns a frame of rows.
-   *
-   * <p>The frame describes whether there may be another frame. If there is not
-   * another frame, the current iteration is done when we have finished the
-   * rows in the this frame.
-   *
-   * <p>The default implementation always returns null.
-   *
-   * @param h Statement handle
-   * @param offset Zero-based offset of first row in the requested frame
-   * @param fetchMaxRowCount Maximum number of rows to return; negative means
-   * no limit
-   * @return Frame, or null if there are no more
-   */
-  Frame fetch(StatementHandle h, long offset, int fetchMaxRowCount) throws
-      NoSuchStatementException, MissingResultsException;
-
-  /** Executes a prepared statement.
-   *
-   * @param h Statement handle
-   * @param parameterValues A list of parameter values; may be empty, not null
-   * @param maxRowCount Maximum number of rows to return; negative means
-   * no limit
-   * @return Execute result
-   * @deprecated See {@link #execute(StatementHandle, List, int)}
-   */
-  @Deprecated // to be removed before 2.0
-  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
-      long maxRowCount) throws NoSuchStatementException;
-
-  /** Executes a prepared statement.
-   *
-   * @param h Statement handle
-   * @param parameterValues A list of parameter values; may be empty, not null
-   * @param maxRowsInFirstFrame Maximum number of rows to return in the Frame.
-   * @return Execute result
-   */
-  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
-      int maxRowsInFirstFrame) throws NoSuchStatementException;
-
-  /** Called during the creation of a statement to allocate a new handle.
-   *
-   * @param ch Connection handle
-   */
-  StatementHandle createStatement(ConnectionHandle ch);
-
-  /** Closes a statement.
-   *
-   * <p>If the statement handle is not known, or is already closed, does
-   * nothing.
-   *
-   * @param h Statement handle
-   */
-  void closeStatement(StatementHandle h);
-
-  /**
-   * Opens (creates) a connection. The client allocates its own connection ID 
which the server is
-   * then made aware of through the {@link ConnectionHandle}. The Map {@code 
info} argument is
-   * analogous to the {@link Properties} typically passed to a "normal" JDBC 
Driver. Avatica
-   * specific properties should not be included -- only properties for the 
underlying driver.
-   *
-   * @param ch A ConnectionHandle encapsulates information about the 
connection to be opened
-   *    as provided by the client.
-   * @param info A Map corresponding to the Properties typically passed to a 
JDBC Driver.
-   */
-  void openConnection(ConnectionHandle ch, Map<String, String> info);
-
-  /** Closes a connection */
-  void closeConnection(ConnectionHandle ch);
-
-  /**
-   * Re-sets the {@link ResultSet} on a Statement. Not a JDBC method.
-   *
-   * @return True if there are results to fetch after resetting to the given 
offset. False otherwise
-   */
-  boolean syncResults(StatementHandle sh, QueryState state, long offset)
-      throws NoSuchStatementException;
-
-  /**
-   * Makes all changes since the last commit/rollback permanent. Analogous to
-   * {@link Connection#commit()}.
-   *
-   * @param ch A reference to the real JDBC Connection
-   */
-  void commit(ConnectionHandle ch);
-
-  /**
-   * Undoes all changes since the last commit/rollback. Analogous to
-   * {@link Connection#rollback()};
-   *
-   * @param ch A reference to the real JDBC Connection
-   */
-  void rollback(ConnectionHandle ch);
-
-  /** Synchronizes client and server view of connection properties.
-   *
-   * <p>Note: this interface is considered "experimental" and may undergo 
further changes as this
-   * functionality is extended to other aspects of state management for
-   * {@link java.sql.Connection}, {@link java.sql.Statement}, and {@link 
java.sql.ResultSet}.</p>
-   */
-  ConnectionProperties connectionSync(ConnectionHandle ch, 
ConnectionProperties connProps);
-
-  /** Factory to create instances of {@link Meta}. */
-  interface Factory {
-    Meta create(List<String> args);
-  }
-
-  /** Wrapper to remind API calls that a parameter is a pattern (allows '%' and
-   * '_' wildcards, per the JDBC spec) rather than a string to be matched
-   * exactly. */
-  class Pat {
-    public final String s;
-
-    private Pat(String s) {
-      this.s = s;
-    }
-
-    @Override public String toString() {
-      return "Pat[" + s + "]";
-    }
-
-    @JsonCreator
-    public static Pat of(@JsonProperty("s") String name) {
-      return new Pat(name);
-    }
-  }
-
-  /** Database property.
-   *
-   * <p>Values exist for methods, such as
-   * {@link DatabaseMetaData#getSQLKeywords()}, which always return the same
-   * value at all times and across connections.
-   *
-   * @see #getDatabaseProperties(Meta.ConnectionHandle)
-   */
-  enum DatabaseProperty {
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getNumericFunctions()}. */
-    GET_NUMERIC_FUNCTIONS(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getStringFunctions()}. */
-    GET_STRING_FUNCTIONS(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getSystemFunctions()}. */
-    GET_SYSTEM_FUNCTIONS(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getTimeDateFunctions()}. */
-    GET_TIME_DATE_FUNCTIONS(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getSQLKeywords()}. */
-    GET_S_Q_L_KEYWORDS(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDefaultTransactionIsolation()}. */
-    GET_DEFAULT_TRANSACTION_ISOLATION(Connection.TRANSACTION_NONE),
-
-    /** Database property which is the Avatica version */
-    AVATICA_VERSION(FilteredConstants.VERSION),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDriverVersion()}. */
-    GET_DRIVER_VERSION(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDriverMinorVersion()}. */
-    GET_DRIVER_MINOR_VERSION(-1),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDriverMajorVersion()}. */
-    GET_DRIVER_MAJOR_VERSION(-1),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDriverName()}. */
-    GET_DRIVER_NAME(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDatabaseMinorVersion()}. */
-    GET_DATABASE_MINOR_VERSION(-1),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDatabaseMajorVersion()}. */
-    GET_DATABASE_MAJOR_VERSION(-1),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDatabaseProductName()}. */
-    GET_DATABASE_PRODUCT_NAME(""),
-
-    /** Database property containing the value of
-     * {@link DatabaseMetaData#getDatabaseProductVersion()}. */
-    GET_DATABASE_PRODUCT_VERSION("");
-
-    public final Class<?> type;
-    public final Object defaultValue;
-    public final Method method;
-    public final boolean isJdbc;
-
-    <T> DatabaseProperty(T defaultValue) {
-      this.defaultValue = defaultValue;
-      final String methodName = AvaticaUtils.toCamelCase(name());
-      Method localMethod = null;
-      try {
-        localMethod = DatabaseMetaData.class.getMethod(methodName);
-      } catch (NoSuchMethodException e) {
-        // Pass, localMethod stays null.
-      }
-
-      if (null == localMethod) {
-        this.method = null;
-        this.type = null;
-        this.isJdbc = false;
-      } else {
-        this.method = localMethod;
-        this.type = AvaticaUtils.box(method.getReturnType());
-        this.isJdbc = true;
-      }
-
-      // It's either: 1) not a JDBC method, 2) has no default value,
-      // 3) the defaultValue is of the expected type
-      assert !isJdbc || defaultValue == null || defaultValue.getClass() == 
type;
-    }
-
-    /** Returns a value of this property, using the default value if the map
-     * does not contain an explicit value. */
-    public <T> T getProp(Meta meta, ConnectionHandle ch, Class<T> aClass) {
-      return getProp(meta.getDatabaseProperties(ch), aClass);
-    }
-
-    /** Returns a value of this property, using the default value if the map
-     * does not contain an explicit value. */
-    public <T> T getProp(Map<DatabaseProperty, Object> map, Class<T> aClass) {
-      assert aClass == type;
-      Object v = map.get(this);
-      if (v == null) {
-        v = defaultValue;
-      }
-      return aClass.cast(v);
-    }
-
-    public static DatabaseProperty fromProto(Common.DatabaseProperty proto) {
-      return DatabaseProperty.valueOf(proto.getName());
-    }
-
-    public Common.DatabaseProperty toProto() {
-      return Common.DatabaseProperty.newBuilder().setName(name()).build();
-    }
-  }
-
-  /** Response from execute.
-   *
-   * <p>Typically a query will have a result set and rowCount = -1;
-   * a DML statement will have a rowCount and no result sets.
-   */
-  class ExecuteResult {
-    public final List<MetaResultSet> resultSets;
-
-    public ExecuteResult(List<MetaResultSet> resultSets) {
-      this.resultSets = resultSets;
-    }
-  }
-
-  /**
-   * Response from a collection of SQL commands or parameter values in a 
single batch.
-   */
-  class ExecuteBatchResult {
-    public final long[] updateCounts;
-
-    public ExecuteBatchResult(long[] updateCounts) {
-      this.updateCounts = Objects.requireNonNull(updateCounts);
-    }
-  }
-
-  /** Meta data from which a result set can be constructed.
-   *
-   * <p>If {@code updateCount} is not -1, the result is just a count. A result
-   * set cannot be constructed. */
-  class MetaResultSet {
-    public final String connectionId;
-    public final int statementId;
-    public final boolean ownStatement;
-    public final Frame firstFrame;
-    public final Signature signature;
-    public final long updateCount;
-
-    @Deprecated // to be removed before 2.0
-    protected MetaResultSet(String connectionId, int statementId,
-        boolean ownStatement, Signature signature, Frame firstFrame,
-        int updateCount) {
-      this(connectionId, statementId, ownStatement, signature, firstFrame,
-          (long) updateCount);
-    }
-
-    protected MetaResultSet(String connectionId, int statementId,
-        boolean ownStatement, Signature signature, Frame firstFrame,
-        long updateCount) {
-      this.signature = signature;
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.ownStatement = ownStatement;
-      this.firstFrame = firstFrame; // may be null even if signature is not 
null
-      this.updateCount = updateCount;
-    }
-
-    public static MetaResultSet create(String connectionId, int statementId,
-        boolean ownStatement, Signature signature, Frame firstFrame) {
-      return new MetaResultSet(connectionId, statementId, ownStatement,
-          Objects.requireNonNull(signature), firstFrame, -1L);
-    }
-
-    public static MetaResultSet count(String connectionId, int statementId,
-        long updateCount) {
-      assert updateCount >= 0
-          : "Meta.count(" + connectionId + ", " + statementId + ", "
-          + updateCount + ")";
-      return new MetaResultSet(connectionId, statementId, false, null, null,
-          updateCount);
-    }
-  }
-
-  /** Information necessary to convert an {@link Iterable} into a
-   * {@link org.apache.calcite.avatica.util.Cursor}. */
-  final class CursorFactory {
-    private static final FieldDescriptor CLASS_NAME_DESCRIPTOR = 
Common.CursorFactory.
-        
getDescriptor().findFieldByNumber(Common.CursorFactory.CLASS_NAME_FIELD_NUMBER);
-
-    public final Style style;
-    public final Class clazz;
-    @JsonIgnore
-    public final List<Field> fields;
-    public final List<String> fieldNames;
-
-    private CursorFactory(Style style, Class clazz, List<Field> fields,
-        List<String> fieldNames) {
-      assert (fieldNames != null)
-          == (style == Style.RECORD_PROJECTION || style == Style.MAP);
-      assert (fields != null) == (style == Style.RECORD_PROJECTION);
-      this.style = Objects.requireNonNull(style);
-      this.clazz = clazz;
-      this.fields = fields;
-      this.fieldNames = fieldNames;
-    }
-
-    @JsonCreator
-    public static CursorFactory create(@JsonProperty("style") Style style,
-        @JsonProperty("clazz") Class clazz,
-        @JsonProperty("fieldNames") List<String> fieldNames) {
-      switch (style) {
-      case OBJECT:
-        return OBJECT;
-      case ARRAY:
-        return ARRAY;
-      case LIST:
-        return LIST;
-      case RECORD:
-        return record(clazz);
-      case RECORD_PROJECTION:
-        return record(clazz, null, fieldNames);
-      case MAP:
-        return map(fieldNames);
-      default:
-        throw new AssertionError("unknown style: " + style);
-      }
-    }
-
-    public static final CursorFactory OBJECT =
-        new CursorFactory(Style.OBJECT, null, null, null);
-
-    public static final CursorFactory ARRAY =
-        new CursorFactory(Style.ARRAY, null, null, null);
-
-    public static final CursorFactory LIST =
-        new CursorFactory(Style.LIST, null, null, null);
-
-    public static CursorFactory record(Class resultClazz) {
-      return new CursorFactory(Style.RECORD, resultClazz, null, null);
-    }
-
-    public static CursorFactory record(Class resultClass, List<Field> fields,
-        List<String> fieldNames) {
-      if (fields == null) {
-        fields = new ArrayList<>();
-        for (String fieldName : fieldNames) {
-          try {
-            fields.add(resultClass.getField(fieldName));
-          } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
-          }
-        }
-      }
-      return new CursorFactory(Style.RECORD_PROJECTION, resultClass, fields,
-          fieldNames);
-    }
-
-    public static CursorFactory map(List<String> fieldNames) {
-      return new CursorFactory(Style.MAP, null, null, fieldNames);
-    }
-
-    public static CursorFactory deduce(List<ColumnMetaData> columns,
-        Class resultClazz) {
-      if (columns.size() == 1) {
-        return OBJECT;
-      }
-      if (resultClazz == null) {
-        return ARRAY;
-      }
-      if (resultClazz.isArray()) {
-        return ARRAY;
-      }
-      if (List.class.isAssignableFrom(resultClazz)) {
-        return LIST;
-      }
-      return record(resultClazz);
-    }
-
-    public Common.CursorFactory toProto() {
-      Common.CursorFactory.Builder builder = Common.CursorFactory.newBuilder();
-
-      if (null != clazz) {
-        builder.setClassName(clazz.getName());
-      }
-      builder.setStyle(style.toProto());
-      if (null != fieldNames) {
-        builder.addAllFieldNames(fieldNames);
-      }
-
-      return builder.build();
-    }
-
-    public static CursorFactory fromProto(Common.CursorFactory proto) {
-      // Reconstruct CursorFactory
-      Class<?> clz = null;
-
-      if (proto.hasField(CLASS_NAME_DESCRIPTOR)) {
-        try {
-          clz = Class.forName(proto.getClassName());
-        } catch (ClassNotFoundException e) {
-          throw new RuntimeException(e);
-        }
-      }
-
-      return CursorFactory.create(Style.fromProto(proto.getStyle()), clz,
-          proto.getFieldNamesList());
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(clazz, fieldNames, fields, style);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CursorFactory
-          && Objects.equals(clazz, ((CursorFactory) o).clazz)
-          && Objects.equals(fieldNames, ((CursorFactory) o).fieldNames)
-          && Objects.equals(fields, ((CursorFactory) o).fields)
-          && style == ((CursorFactory) o).style;
-    }
-  }
-
-  /** How logical fields are represented in the objects returned by the
-   * iterator. */
-  enum Style {
-    OBJECT,
-    RECORD,
-    RECORD_PROJECTION,
-    ARRAY,
-    LIST,
-    MAP;
-
-    public Common.CursorFactory.Style toProto() {
-      return Common.CursorFactory.Style.valueOf(name());
-    }
-
-    public static Style fromProto(Common.CursorFactory.Style proto) {
-      return Style.valueOf(proto.name());
-    }
-  }
-
-  /** Result of preparing a statement. */
-  public class Signature {
-    private static final FieldDescriptor SQL_DESCRIPTOR = Common.Signature
-        .getDescriptor().findFieldByNumber(Common.Signature.SQL_FIELD_NUMBER);
-    private static final FieldDescriptor CURSOR_FACTORY_DESCRIPTOR = 
Common.Signature
-        
.getDescriptor().findFieldByNumber(Common.Signature.CURSOR_FACTORY_FIELD_NUMBER);
-
-    public final List<ColumnMetaData> columns;
-    public final String sql;
-    public final List<AvaticaParameter> parameters;
-    public final transient Map<String, Object> internalParameters;
-    public final CursorFactory cursorFactory;
-
-    public final Meta.StatementType statementType;
-
-    /** Creates a Signature. */
-    public Signature(List<ColumnMetaData> columns,
-        String sql,
-        List<AvaticaParameter> parameters,
-        Map<String, Object> internalParameters,
-        CursorFactory cursorFactory,
-        Meta.StatementType statementType) {
-      this.columns = columns;
-      this.sql = sql;
-      this.parameters = parameters;
-      this.internalParameters = internalParameters;
-      this.cursorFactory = cursorFactory;
-      this.statementType = statementType;
-    }
-
-    /** Used by Jackson to create a Signature by de-serializing JSON. */
-    @JsonCreator
-    public static Signature create(
-        @JsonProperty("columns") List<ColumnMetaData> columns,
-        @JsonProperty("sql") String sql,
-        @JsonProperty("parameters") List<AvaticaParameter> parameters,
-        @JsonProperty("cursorFactory") CursorFactory cursorFactory,
-        @JsonProperty("statementType") Meta.StatementType statementType) {
-      return new Signature(columns, sql, parameters,
-          Collections.<String, Object>emptyMap(), cursorFactory, 
statementType);
-    }
-
-    /** Returns a copy of this Signature, substituting given CursorFactory. */
-    public Signature setCursorFactory(CursorFactory cursorFactory) {
-      return new Signature(columns, sql, parameters, internalParameters,
-          cursorFactory, statementType);
-    }
-
-    /** Creates a copy of this Signature with null lists and maps converted to
-     * empty. */
-    public Signature sanitize() {
-      if (columns == null || parameters == null || internalParameters == null
-          || statementType == null) {
-        return new Signature(sanitize(columns), sql, sanitize(parameters),
-            sanitize(internalParameters), cursorFactory,
-            Meta.StatementType.SELECT);
-      }
-      return this;
-    }
-
-    private <E> List<E> sanitize(List<E> list) {
-      return list == null ? Collections.<E>emptyList() : list;
-    }
-
-    private <K, V> Map<K, V> sanitize(Map<K, V> map) {
-      return map == null ? Collections.<K, V>emptyMap() : map;
-    }
-
-    public Common.Signature toProto() {
-      Common.Signature.Builder builder = Common.Signature.newBuilder();
-
-      if (null != sql) {
-        builder.setSql(sql);
-      }
-
-      if (null != cursorFactory) {
-        builder.setCursorFactory(cursorFactory.toProto());
-      }
-
-      if (null != columns) {
-        for (ColumnMetaData column : columns) {
-          builder.addColumns(column.toProto());
-        }
-      }
-
-      if (null != parameters) {
-        for (AvaticaParameter parameter : parameters) {
-          builder.addParameters(parameter.toProto());
-        }
-      }
-
-      return builder.build();
-    }
-
-    public static Signature fromProto(Common.Signature protoSignature) {
-      List<ColumnMetaData> metadata = new 
ArrayList<>(protoSignature.getColumnsCount());
-      for (Common.ColumnMetaData protoMetadata : 
protoSignature.getColumnsList()) {
-        metadata.add(ColumnMetaData.fromProto(protoMetadata));
-      }
-
-      List<AvaticaParameter> parameters = new 
ArrayList<>(protoSignature.getParametersCount());
-      for (Common.AvaticaParameter protoParam : 
protoSignature.getParametersList()) {
-        parameters.add(AvaticaParameter.fromProto(protoParam));
-      }
-
-      String sql = null;
-      if (protoSignature.hasField(SQL_DESCRIPTOR)) {
-        sql = protoSignature.getSql();
-      }
-
-      CursorFactory cursorFactory = null;
-      if (protoSignature.hasField(CURSOR_FACTORY_DESCRIPTOR)) {
-        cursorFactory = 
CursorFactory.fromProto(protoSignature.getCursorFactory());
-      }
-      final Meta.StatementType statementType =
-          Meta.StatementType.fromProto(protoSignature.getStatementType());
-
-      return Signature.create(metadata, sql, parameters, cursorFactory, 
statementType);
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(columns, cursorFactory, parameters, sql);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof Signature
-          && Objects.equals(columns, ((Signature) o).columns)
-          && Objects.equals(cursorFactory, ((Signature) o).cursorFactory)
-          && Objects.equals(parameters, ((Signature) o).parameters)
-          && Objects.equals(sql, ((Signature) o).sql);
-    }
-  }
-
-  /** A collection of rows. */
-  class Frame {
-    private static final FieldDescriptor HAS_ARRAY_VALUE_DESCRIPTOR = 
Common.ColumnValue
-        
.getDescriptor().findFieldByNumber(Common.ColumnValue.HAS_ARRAY_VALUE_FIELD_NUMBER);
-    private static final FieldDescriptor SCALAR_VALUE_DESCRIPTOR = 
Common.ColumnValue
-        
.getDescriptor().findFieldByNumber(Common.ColumnValue.SCALAR_VALUE_FIELD_NUMBER);
-    /** Frame that has zero rows and is the last frame. */
-    public static final Frame EMPTY =
-        new Frame(0, true, Collections.emptyList());
-
-    /** Frame that has zero rows but may have another frame. */
-    public static final Frame MORE =
-        new Frame(0, false, Collections.emptyList());
-
-    /** Zero-based offset of first row. */
-    public final long offset;
-    /** Whether this is definitely the last frame of rows.
-     * If true, there are no more rows.
-     * If false, there may or may not be more rows. */
-    public final boolean done;
-    /** The rows. */
-    public final Iterable<Object> rows;
-
-    public Frame(long offset, boolean done, Iterable<Object> rows) {
-      this.offset = offset;
-      this.done = done;
-      this.rows = rows;
-    }
-
-    @JsonCreator
-    public static Frame create(@JsonProperty("offset") long offset,
-        @JsonProperty("done") boolean done,
-        @JsonProperty("rows") List<Object> rows) {
-      if (offset == 0 && done && rows.isEmpty()) {
-        return EMPTY;
-      }
-      return new Frame(offset, done, rows);
-    }
-
-    public Common.Frame toProto() {
-      Common.Frame.Builder builder = Common.Frame.newBuilder();
-
-      builder.setDone(done).setOffset(offset);
-
-      for (Object row : this.rows) {
-        if (null == row) {
-          // Does this need to be persisted for some reason?
-          continue;
-        }
-
-        if (row instanceof Object[]) {
-          final Common.Row.Builder rowBuilder = Common.Row.newBuilder();
-
-          for (Object element : (Object[]) row) {
-            final Common.ColumnValue.Builder columnBuilder = 
Common.ColumnValue.newBuilder();
-
-            if (element instanceof List) {
-              columnBuilder.setHasArrayValue(true);
-              List<?> list = (List<?>) element;
-              // Add each element in the list/array to the column's value
-              for (Object listItem : list) {
-                final Common.TypedValue scalarListItem = 
serializeScalar(listItem);
-                columnBuilder.addArrayValue(scalarListItem);
-                // Add the deprecated 'value' repeated attribute for backwards 
compat
-                columnBuilder.addValue(scalarListItem);
-              }
-            } else {
-              // The default value, but still explicit.
-              columnBuilder.setHasArrayValue(false);
-              // Only one value for this column, a scalar.
-              final Common.TypedValue scalarVal = serializeScalar(element);
-              columnBuilder.setScalarValue(scalarVal);
-              // Add the deprecated 'value' repeated attribute for backwards 
compat
-              columnBuilder.addValue(scalarVal);
-            }
-
-            // Add value to row
-            rowBuilder.addValue(columnBuilder.build());
-          }
-
-          // Collect all rows
-          builder.addRows(rowBuilder.build());
-        } else {
-          // Can a "row" be a primitive? A struct? Only an Array?
-          throw new RuntimeException("Only arrays are supported");
-        }
-      }
-
-      return builder.build();
-    }
-
-    static Common.TypedValue serializeScalar(Object element) {
-      final Common.TypedValue.Builder valueBuilder = 
Common.TypedValue.newBuilder();
-
-      // Let TypedValue handle the serialization for us.
-      TypedValue.toProto(valueBuilder, element);
-
-      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.ColumnValue protoColumn : protoRow.getValueList()) {
-          final Object value;
-          if (!isNewStyleColumn(protoColumn)) {
-            // Backward compatibility
-            value = parseOldStyleColumn(protoColumn);
-          } else {
-            // Current style parsing (separate scalar and array values)
-            value = parseColumn(protoColumn);
-          }
-
-          row.add(value);
-        }
-
-        parsedRows.add(row);
-      }
-
-      return new Frame(proto.getOffset(), proto.getDone(), parsedRows);
-    }
-
-    /**
-     * Determines whether this message contains the new attributes in the
-     * message. We can't directly test for the negative because our
-     * {@code hasField} trick does not work on repeated fields.
-     *
-     * @param column The protobuf column object
-     * @return True if the message is the new style, false otherwise.
-     */
-    static boolean isNewStyleColumn(Common.ColumnValue column) {
-      return column.hasField(HAS_ARRAY_VALUE_DESCRIPTOR)
-          || column.hasField(SCALAR_VALUE_DESCRIPTOR);
-    }
-
-    /**
-     * For Calcite 1.5, we made the mistake of using array length to determine 
when the value for a
-     * column is a scalar or an array. This method performs the old parsing 
for backwards
-     * compatibility.
-     *
-     * @param column The protobuf ColumnValue object
-     * @return The parsed value for this column
-     */
-    static Object parseOldStyleColumn(Common.ColumnValue column) {
-      if (column.getValueCount() > 1) {
-        List<Object> array = new ArrayList<>(column.getValueCount());
-        for (Common.TypedValue columnValue : column.getValueList()) {
-          array.add(deserializeScalarValue(columnValue));
-        }
-        return array;
-      } else {
-        return deserializeScalarValue(column.getValue(0));
-      }
-    }
-
-    /**
-     * Parses the value for a ColumnValue using the separated array and scalar 
attributes.
-     *
-     * @param column The protobuf ColumnValue object
-     * @return The parse value for this column
-     */
-    static Object parseColumn(Common.ColumnValue column) {
-      // Verify that we have one or the other (scalar or array)
-      validateColumnValue(column);
-
-      if (!column.hasField(SCALAR_VALUE_DESCRIPTOR)) {
-        // Array
-        List<Object> array = new ArrayList<>(column.getArrayValueCount());
-        for (Common.TypedValue arrayValue : column.getArrayValueList()) {
-          array.add(deserializeScalarValue(arrayValue));
-        }
-        return array;
-      } else {
-        // Scalar
-        return deserializeScalarValue(column.getScalarValue());
-      }
-    }
-
-    /**
-     * Verifies that a ColumnValue has only a scalar or array value, not both 
and not neither.
-     *
-     * @param column The protobuf ColumnValue object
-     * @throws IllegalArgumentException When the above condition is not met
-     */
-    static void validateColumnValue(Common.ColumnValue column) {
-      final boolean hasScalar = column.hasField(SCALAR_VALUE_DESCRIPTOR);
-      final boolean hasArrayValue = column.getHasArrayValue();
-
-      // These should always be different
-      if (hasScalar == hasArrayValue) {
-        throw new IllegalArgumentException("A column must have a scalar or 
array value, not "
-            + (hasScalar ? "both" : "neither"));
-      }
-    }
-
-    static Object deserializeScalarValue(Common.TypedValue protoElement) {
-      // ByteString is a single case where TypedValue is representing the data 
differently
-      // (in its "local" form) than Frame does. We need to unwrap the Base64 
encoding.
-      if (Common.Rep.BYTE_STRING == protoElement.getType()) {
-        // Protobuf is sending native bytes (not b64) across the wire. B64 
bytes is only for
-        // TypedValue's benefit
-        return protoElement.getBytesValue().toByteArray();
-      }
-      // Again, let TypedValue deserialize things for us.
-      return TypedValue.fromProto(protoElement).value;
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(done, offset, rows);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof Frame
-          && equalRows(rows, ((Frame) o).rows)
-          && offset == ((Frame) o).offset
-          && done == ((Frame) o).done;
-    }
-
-    private static boolean equalRows(Iterable<Object> rows, Iterable<Object> 
otherRows) {
-      if (null == rows) {
-        if (null != otherRows) {
-          return false;
-        }
-      } else {
-        Iterator<Object> iter1 = rows.iterator();
-        Iterator<Object> iter2 = otherRows.iterator();
-        while (iter1.hasNext() && iter2.hasNext()) {
-          Object obj1 = iter1.next();
-          Object obj2 = iter2.next();
-
-          // Can't just call equals on an array
-          if (obj1 instanceof Object[]) {
-            if (obj2 instanceof Object[]) {
-              // Compare array and array
-              if (!Arrays.equals((Object[]) obj1, (Object[]) obj2)) {
-                return false;
-              }
-            } else if (obj2 instanceof List) {
-              // compare array and list
-              @SuppressWarnings("unchecked")
-              List<Object> obj2List = (List<Object>) obj2;
-              if (!Arrays.equals((Object[]) obj1, obj2List.toArray())) {
-                return false;
-              }
-            } else {
-              // compare array and something that isn't an array will always 
fail
-              return false;
-            }
-          } else if (obj1 instanceof List) {
-            if (obj2 instanceof Object[]) {
-              // Compare list and array
-              @SuppressWarnings("unchecked")
-              List<Object> obj1List = (List<Object>) obj1;
-              if (!Arrays.equals(obj1List.toArray(), (Object[]) obj2)) {
-                return false;
-              }
-            } else if (!obj1.equals(obj2)) {
-              // compare list and something else, let it fall to equals()
-              return false;
-            }
-          } else if (!obj1.equals(obj2)) {
-            // Not an array, leave it to equals()
-            return false;
-          }
-        }
-
-        // More elements in one of the iterables
-        if (iter1.hasNext() || iter2.hasNext()) {
-          return false;
-        }
-      }
-
-      return true;
-    }
-  }
-
-  /** Connection handle. */
-  public class ConnectionHandle {
-    public final String id;
-
-    @Override public String toString() {
-      return id;
-    }
-
-    @JsonCreator
-    public ConnectionHandle(@JsonProperty("id") String id) {
-      this.id = id;
-    }
-  }
-
-  /** Statement handle. */
-  // Visible for testing
-  public class StatementHandle {
-    private static final FieldDescriptor SIGNATURE_DESCRIPTOR = 
Common.StatementHandle
-        
.getDescriptor().findFieldByNumber(Common.StatementHandle.SIGNATURE_FIELD_NUMBER);
-    public final String connectionId;
-    public final int id;
-
-    // not final because LocalService#apply(PrepareRequest)
-    /** Only present for PreparedStatement handles, null otherwise. */
-    public Signature signature;
-
-    @Override public String toString() {
-      return connectionId + "::" + Integer.toString(id);
-    }
-
-    @JsonCreator
-    public StatementHandle(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("id") int id,
-        @JsonProperty("signature") Signature signature) {
-      this.connectionId = connectionId;
-      this.id = id;
-      this.signature = signature;
-    }
-
-    public Common.StatementHandle toProto() {
-      Common.StatementHandle.Builder builder = 
Common.StatementHandle.newBuilder()
-          .setConnectionId(connectionId).setId(id);
-      if (null != signature) {
-        builder.setSignature(signature.toProto());
-      }
-      return builder.build();
-    }
-
-    public static StatementHandle fromProto(Common.StatementHandle 
protoHandle) {
-      // Signature is optional in the update path for executes.
-      Signature signature = null;
-      if (protoHandle.hasField(SIGNATURE_DESCRIPTOR)) {
-        signature = Signature.fromProto(protoHandle.getSignature());
-      }
-      return new StatementHandle(protoHandle.getConnectionId(), 
protoHandle.getId(), signature);
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(connectionId, id, signature);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof StatementHandle
-          && Objects.equals(connectionId, ((StatementHandle) o).connectionId)
-          && Objects.equals(signature, ((StatementHandle) o).signature)
-          && id == ((StatementHandle) o).id;
-    }
-  }
-
-  /** A pojo containing various client-settable {@link java.sql.Connection} 
properties.
-   *
-   * <p>{@code java.lang} types are used here so that {@code null} can be used 
to indicate
-   * a value has no been set.</p>
-   *
-   * <p>Note: this interface is considered "experimental" and may undergo 
further changes as this
-   * functionality is extended to other aspects of state management for
-   * {@link java.sql.Connection}, {@link java.sql.Statement}, and {@link 
java.sql.ResultSet}.</p>
-   */
-  @JsonTypeInfo(
-      use = JsonTypeInfo.Id.NAME,
-      property = "connProps",
-      defaultImpl = ConnectionPropertiesImpl.class)
-  @JsonSubTypes({
-      @JsonSubTypes.Type(value = ConnectionPropertiesImpl.class, name = 
"connPropsImpl")
-  })
-  interface ConnectionProperties {
-
-    /** Overwrite fields in {@code this} with any non-null fields in {@code 
that}
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties merge(ConnectionProperties that);
-
-    /** @return {@code true} when no properies have been set, {@code false} 
otherwise. */
-    @JsonIgnore
-    boolean isEmpty();
-
-    /** Set {@code autoCommit} status.
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties setAutoCommit(boolean val);
-
-    Boolean isAutoCommit();
-
-    /** Set {@code readOnly} status.
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties setReadOnly(boolean val);
-
-    Boolean isReadOnly();
-
-    /** Set {@code transactionIsolation} status.
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties setTransactionIsolation(int val);
-
-    Integer getTransactionIsolation();
-
-    /** Set {@code catalog}.
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties setCatalog(String val);
-
-    String getCatalog();
-
-    /** Set {@code schema}.
-     *
-     * @return {@code this}
-     */
-    ConnectionProperties setSchema(String val);
-
-    String getSchema();
-
-    Common.ConnectionProperties toProto();
-  }
-
-  /** API to put a result set into a statement, being careful to enforce
-   * thread-safety and not to overwrite existing open result sets. */
-  interface PrepareCallback {
-    Object getMonitor();
-    void clear() throws SQLException;
-    void assign(Signature signature, Frame firstFrame, long updateCount)
-        throws SQLException;
-    void execute() throws SQLException;
-  }
-
-  /** Type of statement. */
-  enum StatementType {
-    SELECT, INSERT, UPDATE, DELETE, UPSERT, MERGE, OTHER_DML, IS_DML,
-    CREATE, DROP, ALTER, OTHER_DDL, CALL;
-
-    public boolean canUpdate() {
-      switch(this) {
-      case INSERT:
-        return true;
-      case IS_DML:
-        return true;
-      default:
-        return false;
-      }
-    }
-
-    public Common.StatementType toProto() {
-      return Common.StatementType.valueOf(name());
-    }
-
-    public static StatementType fromProto(Common.StatementType proto) {
-      return StatementType.valueOf(proto.name());
-    }
-  }
-}
-
-// End Meta.java

Reply via email to