You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2016/03/07 19:27:39 UTC

[01/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Repository: calcite
Updated Branches:
  refs/heads/master 5464f3329 -> 749b236c0


http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/protobuf/common.proto
----------------------------------------------------------------------
diff --git a/avatica/src/main/protobuf/common.proto b/avatica/src/main/protobuf/common.proto
deleted file mode 100644
index bd116c3..0000000
--- a/avatica/src/main/protobuf/common.proto
+++ /dev/null
@@ -1,275 +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.
- */
-
-syntax = "proto3";
-
-option java_package = "org.apache.calcite.avatica.proto";
-
-// Details about a connection
-message ConnectionProperties {
-  bool is_dirty = 1;
-  bool auto_commit = 2;
-  bool has_auto_commit = 7; // field is a Boolean, need to discern null and default value
-  bool read_only = 3;
-  bool has_read_only = 8; // field is a Boolean, need to discern null and default value
-  uint32 transaction_isolation = 4;
-  string catalog = 5;
-  string schema = 6;
-}
-
-// Statement handle
-message StatementHandle {
-  string connection_id = 1;
-  uint32 id = 2;
-  Signature signature = 3;
-}
-
-// Results of preparing a statement
-message Signature {
-  repeated ColumnMetaData columns = 1;
-  string sql = 2;
-  repeated AvaticaParameter parameters = 3;
-  CursorFactory cursor_factory = 4;
-  StatementType statementType = 5;
-}
-
-// Has to be consistent with Meta.StatementType
-enum StatementType {
-  SELECT = 0;
-  INSERT = 1;
-  UPDATE = 2;
-  DELETE = 3;
-  UPSERT = 4;
-  MERGE = 5;
-  OTHER_DML = 6;
-  CREATE = 7;
-  DROP = 8;
-  ALTER = 9;
-  OTHER_DDL = 10;
-  CALL = 11;
-}
-
-message ColumnMetaData {
-  uint32 ordinal = 1;
-  bool auto_increment = 2;
-  bool case_sensitive = 3;
-  bool searchable = 4;
-  bool currency = 5;
-  uint32 nullable = 6;
-  bool signed = 7;
-  uint32 display_size = 8;
-  string label = 9;
-  string column_name = 10;
-  string schema_name = 11;
-  uint32 precision = 12;
-  uint32 scale = 13;
-  string table_name = 14;
-  string catalog_name = 15;
-  bool read_only = 16;
-  bool writable = 17;
-  bool definitely_writable = 18;
-  string column_class_name = 19;
-  AvaticaType type = 20;
-}
-
-enum Rep {
-  PRIMITIVE_BOOLEAN = 0;
-  PRIMITIVE_BYTE = 1;
-  PRIMITIVE_CHAR = 2;
-  PRIMITIVE_SHORT = 3;
-  PRIMITIVE_INT = 4;
-  PRIMITIVE_LONG = 5;
-  PRIMITIVE_FLOAT = 6;
-  PRIMITIVE_DOUBLE = 7;
-  BOOLEAN = 8;
-  BYTE = 9;
-  CHARACTER = 10;
-  SHORT = 11;
-  INTEGER = 12;
-  LONG = 13;
-  FLOAT = 14;
-  DOUBLE = 15;
-  BIG_INTEGER = 25;
-  BIG_DECIMAL = 26;
-  JAVA_SQL_TIME = 16;
-  JAVA_SQL_TIMESTAMP = 17;
-  JAVA_SQL_DATE = 18;
-  JAVA_UTIL_DATE = 19;
-  BYTE_STRING = 20;
-  STRING = 21;
-  NUMBER = 22;
-  OBJECT = 23;
-  NULL = 24;
-  ARRAY = 27;
-  STRUCT = 28;
-  MULTISET = 29;
-}
-
-// Base class for a column type
-message AvaticaType {
-  uint32 id = 1;
-  string name = 2;
-  Rep rep = 3;
-
-  repeated ColumnMetaData columns = 4; // Only present when name = STRUCT
-  AvaticaType component = 5; // Only present when name = ARRAY
-}
-
-// Metadata for a parameter
-message AvaticaParameter {
-  bool signed = 1;
-  uint32 precision = 2;
-  uint32 scale = 3;
-  uint32 parameter_type = 4;
-  string type_name = 5;
-  string class_name = 6;
-  string name = 7;
-}
-
-// Information necessary to convert an Iterable into a Calcite Cursor
-message CursorFactory {
-  enum Style {
-    OBJECT = 0;
-    RECORD = 1;
-    RECORD_PROJECTION = 2;
-    ARRAY = 3;
-    LIST = 4;
-    MAP = 5;
-  }
-
-  Style style = 1;
-  string class_name = 2;
-  repeated string field_names = 3;
-}
-
-// A collection of rows
-message Frame {
-  uint64 offset = 1;
-  bool done = 2;
-  repeated Row rows = 3;
-}
-
-// A row is a collection of values
-message Row {
-  repeated ColumnValue value = 1;
-}
-
-// Database property, list of functions the database provides for a certain operation
-message DatabaseProperty {
-  string name = 1;
-  repeated string functions = 2;
-}
-
-// Message which encapsulates another message to support a single RPC endpoint
-message WireMessage {
-  string name = 1;
-  bytes wrapped_message = 2;
-}
-
-// A value might be a TypedValue or an Array of TypedValue's
-message ColumnValue {
-  repeated TypedValue value = 1; // deprecated, use array_value or scalar_value
-  repeated TypedValue array_value = 2;
-  bool has_array_value = 3; // Is an array value set?
-  TypedValue scalar_value = 4;
-}
-
-// 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
-
-  bool bool_value = 2; // boolean
-  string string_value = 3; // char/varchar
-  sint64 number_value = 4; // var-len encoding lets us shove anything from byte to long
-                           // includes numeric types and date/time types.
-  bytes bytes_values = 5; // binary/varbinary
-  double double_value = 6; // big numbers
-  bool null = 7; // a null object
-}
-
-// The severity of some unexpected outcome to an operation.
-// Protobuf enum values must be unique across all other enums
-enum Severity {
-  UNKNOWN_SEVERITY = 0;
-  FATAL_SEVERITY = 1;
-  ERROR_SEVERITY = 2;
-  WARNING_SEVERITY = 3;
-}
-
-// Enumeration corresponding to DatabaseMetaData operations
-enum MetaDataOperation {
-  GET_ATTRIBUTES = 0;
-  GET_BEST_ROW_IDENTIFIER = 1;
-  GET_CATALOGS = 2;
-  GET_CLIENT_INFO_PROPERTIES = 3;
-  GET_COLUMN_PRIVILEGES = 4;
-  GET_COLUMNS = 5;
-  GET_CROSS_REFERENCE = 6;
-  GET_EXPORTED_KEYS = 7;
-  GET_FUNCTION_COLUMNS = 8;
-  GET_FUNCTIONS = 9;
-  GET_IMPORTED_KEYS = 10;
-  GET_INDEX_INFO = 11;
-  GET_PRIMARY_KEYS = 12;
-  GET_PROCEDURE_COLUMNS = 13;
-  GET_PROCEDURES = 14;
-  GET_PSEUDO_COLUMNS = 15;
-  GET_SCHEMAS = 16;
-  GET_SCHEMAS_WITH_ARGS = 17;
-  GET_SUPER_TABLES = 18;
-  GET_SUPER_TYPES = 19;
-  GET_TABLE_PRIVILEGES = 20;
-  GET_TABLES = 21;
-  GET_TABLE_TYPES = 22;
-  GET_TYPE_INFO = 23;
-  GET_UDTS = 24;
-  GET_VERSION_COLUMNS = 25;
-}
-
-// Represents the breadth of arguments to DatabaseMetaData functions
-message MetaDataOperationArgument {
-  enum ArgumentType {
-    STRING = 0;
-    BOOL = 1;
-    INT = 2;
-    REPEATED_STRING = 3;
-    REPEATED_INT = 4;
-    NULL = 5;
-  }
-    
-  string string_value = 1;
-  bool bool_value = 2;
-  sint32 int_value = 3;
-  repeated string string_array_values = 4;
-  repeated sint32 int_array_values = 5;
-  ArgumentType type = 6;
-}
-
-enum StateType {
-  SQL = 0;
-  METADATA = 1;
-}
-
-message QueryState {
-  StateType type = 1;
-  string sql = 2;
-  MetaDataOperation op = 3;
-  repeated MetaDataOperationArgument args = 4;
-  bool has_args = 5;
-  bool has_sql = 6;
-  bool has_op = 7;
-}


[55/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/index.md b/avatica/site/_docs/index.md
index f0c4afd..da4fd2d 100644
--- a/avatica/site/_docs/index.md
+++ b/avatica/site/_docs/index.md
@@ -22,124 +22,107 @@ limitations under the License.
 {% endcomment %}
 -->
 
-Apache Calcite is a dynamic data management framework.
+Avatica is a framework for building JDBC and ODBC drivers for databases,
+and an RPC wire protocol.
 
-It contains many of the pieces that comprise a typical database
-management system, but omits some key functions: storage of data,
-algorithms to process data, and a repository for storing metadata.
+![Avatica Architecture](https://raw.githubusercontent.com/julianhyde/share/master/slides/avatica-architecture.png)
 
-Calcite intentionally stays out of the business of storing and
-processing data. As we shall see, this makes it an excellent choice
-for mediating between applications and one or more data storage
-locations and data processing engines. It is also a perfect foundation
-for building a database: just add data.
+Avatica's Java binding has very few dependencies.
+Even though it is part of Apache Calcite it does not depend on other parts of
+Calcite. It depends only on JDK 1.7+ and Jackson.
 
-To illustrate, let's create an empty instance of Calcite and then
-point it at some data.
+Avatica's wire protocol is JSON over HTTP.
+The Java implementation uses Jackson to convert request/response command
+objects to/from JSON.
 
-{% highlight java %}
-public static class HrSchema {
-  public final Employee[] emps = 0;
-  public final Department[] depts = 0;
-}
-Class.forName("org.apache.calcite.jdbc.Driver");
-Properties info = new Properties();
-info.setProperty("lex", "JAVA");
-Connection connection = DriverManager.getConnection("jdbc:calcite:", info);
-CalciteConnection calciteConnection =
-    connection.unwrap(CalciteConnection.class);
-ReflectiveSchema.create(calciteConnection,
-    calciteConnection.getRootSchema(), "hr", new HrSchema());
-Statement statement = calciteConnection.createStatement();
-ResultSet resultSet = statement.executeQuery(
-    "select d.deptno, min(e.empid)\n"
-    + "from hr.emps as e\n"
-    + "join hr.depts as d\n"
-    + "  on e.deptno = d.deptno\n"
-    + "group by d.deptno\n"
-    + "having count(*) > 1");
-print(resultSet);
-resultSet.close();
-statement.close();
-connection.close();
-{% endhighlight %}
+Avatica-Server is a Java implementation of Avatica RPC.
 
-Where is the database? There is no database. The connection is
-completely empty until `ReflectiveSchema.create` registers a Java
-object as a schema and its collection fields `emps` and `depts` as
-tables.
+Core concepts:
 
-Calcite does not want to own data; it does not even have favorite data
-format. This example used in-memory data sets, and processed them
-using operators such as `groupBy` and `join` from the linq4j
-library. But Calcite can also process data in other data formats, such
-as JDBC. In the first example, replace
+* Meta is a local API sufficient to implement any Avatica provider
+* Factory creates implementations of the JDBC classes (Driver, Connection,
+  Statement, ResultSet) on top of a Meta
+* Service is an interface that implements the functions of Meta in terms
+  of request and response command objects
 
-{% highlight java %}
-ReflectiveSchema.create(calciteConnection,
-    calciteConnection.getRootSchema(), "hr", new HrSchema());
-{% endhighlight %}
+## JDBC
 
-with
+Avatica implements JDBC by means of Factory.
+Factory creates implementations of the JDBC classes (Driver, Connection,
+Statement, PreparedStatement, ResultSet) on top of a Meta.
 
-{% highlight java %}
-Class.forName("com.mysql.jdbc.Driver");
-BasicDataSource dataSource = new BasicDataSource();
-dataSource.setUrl("jdbc:mysql://localhost");
-dataSource.setUsername("username");
-dataSource.setPassword("password");
-JdbcSchema.create(calciteConnection.getRootSchema(), "name", dataSource,
-    null, "hr");
-{% endhighlight %}
+## ODBC
 
-and Calcite will execute the same query in JDBC. To the application,
-the data and API are the same, but behind the scenes the
-implementation is very different. Calcite uses optimizer rules to push
-the `JOIN` and `GROUP BY` operations to the source database.
+Work has not started on Avatica ODBC.
 
-In-memory and JDBC are just two familiar examples. Calcite can handle
-any data source and data format. To add a data source, you need to
-write an adapter that tells Calcite what collections in the data
-source it should consider "tables".
+Avatica ODBC would use the same wire protocol and could use the same server
+implementation in Java. The ODBC client would be written in C or C++.
 
-For more advanced integration, you can write optimizer
-rules. Optimizer rules allow Calcite to access data of a new format,
-allow you to register new operators (such as a better join algorithm),
-and allow Calcite to optimize how queries are translated to
-operators. Calcite will combine your rules and operators with built-in
-rules and operators, apply cost-based optimization, and generate an
-efficient plan.
+Since the Avatica protocol abstracts many of the differences between providers,
+the same ODBC client could be used for different databases.
 
-### Writing an adapter
+## HTTP Server
 
-The subproject under example/csv provides a CSV adapter, which is
-fully functional for use in applications but is also simple enough to
-serve as a good template if you are writing your own adapter.
+Avatica-server embeds the Jetty HTTP server, providing a class
+[HttpServer]({{ site.apiRoot }}/org/apache/calcite/avatica/server/HttpServer.html)
+that implements the Avatica RPC protocol
+and can be run as a standalone Java application.
 
-See the <a href="{{ site.baseurl }}/docs/tutorial.html">tutorial</a> for information on using
-the CSV adapter and writing other adapters.
+Connectors in HTTP server can be configured if needed by extending
+`HttpServer` class and overriding its `configureConnector()` method.
+For example, user can set `requestHeaderSize` to 64K bytes as follows:
 
-See the <a href="howto.html">HOWTO</a> for more information about
-using other adapters, and about using Calcite in general.
+{% highlight java %}
+HttpServer server = new HttpServer(handler) {
+  @Override
+  protected ServerConnector configureConnector(
+      ServerConnector connector, int port) {
+    HttpConnectionFactory factory = (HttpConnectionFactory)
+        connector.getDefaultConnectionFactory();
+    factory.getHttpConfiguration().setRequestHeaderSize(64 << 10);
+    return super.configureConnector(connector, port);
+  }
+};
+server.start();
+{% endhighlight %}
 
-## Status
+## Project structure
+
+We know that it is important that client libraries have minimal dependencies.
 
-The following features are complete.
-
-* Query parser, validator and optimizer
-* Support for reading models in JSON format
-* Many standard functions and aggregate functions
-* JDBC queries against Linq4j and JDBC back-ends
-* Linq4j front-end
-* SQL features: SELECT, FROM (including JOIN syntax), WHERE, GROUP BY
-  (including GROUPING SETS), aggregate functions (including
-  COUNT(DISTINCT ...) and FILTER), HAVING, ORDER BY (including NULLS
-  FIRST/LAST), set operations (UNION, INTERSECT, MINUS), sub-queries
-  (including correlated sub-queries), windowed aggregates, LIMIT
-  (syntax as <a
-  href="http://www.postgresql.org/docs/8.4/static/sql-select.html#SQL-LIMIT">Postgres</a>);
-  more details in the [SQL reference](reference.html)
-* Local and remote JDBC drivers; see [Avatica](avatica_overview.html)
-* Several [adapters](adapter.html)
+Avatica is currently part of Apache Calcite.
+It does not depend upon any other part of Calcite.
+At some point Avatica could become a separate project.
 
+Packages:
+
+* [org.apache.calcite.avatica]({{ site.apiRoot }}/org/apache/calcite/avatica/package-summary.html) Core framework
+* [org.apache.calcite.avatica.remote]({{ site.apiRoot }}/org/apache/calcite/avatica/remote/package-summary.html) JDBC driver that uses remote procedure calls
+* [org.apache.calcite.avatica.server]({{ site.apiRoot }}/org/apache/calcite/avatica/server/package-summary.html) HTTP server
+* [org.apache.calcite.avatica.util]({{ site.apiRoot }}/org/apache/calcite/avatica/util/package-summary.html) Utilities
+
+## Status
 
+### Implemented
+
+* Create connection, create statement, metadata, prepare, bind, execute, fetch
+* RPC using JSON over HTTP
+* Local implementation
+* Implementation over an existing JDBC driver
+* Composite RPCs (combining several requests into one round trip)
+  * Execute-Fetch
+  * Metadata-Fetch (metadata calls such as getTables return all rows)
+
+### Not implemented
+
+* ODBC
+* RPCs
+  * CloseStatement
+  * CloseConnection
+* Composite RPCs
+  * CreateStatement-Prepare
+  * CloseStatement-CloseConnection
+  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
+* Remove statements from statement table
+* DML (INSERT, UPDATE, DELETE)
+* Statement.execute applied to SELECT statement

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/json_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/json_reference.md b/avatica/site/_docs/json_reference.md
new file mode 100644
index 0000000..85db8f5
--- /dev/null
+++ b/avatica/site/_docs/json_reference.md
@@ -0,0 +1,1086 @@
+---
+layout: docs
+title: JSON Reference
+sidebar_title: JSON Reference
+permalink: /docs/json_reference.html
+requests:
+  - { name: "CatalogsRequest" }
+  - { name: "CloseConnectionRequest" }
+  - { name: "CloseStatementRequest" }
+  - { name: "ColumnsRequest" }
+  - { name: "CommitRequest" }
+  - { name: "ConnectionSyncRequest" }
+  - { name: "CreateStatementRequest" }
+  - { name: "DatabasePropertyRequest" }
+  - { name: "ExecuteRequest" }
+  - { name: "FetchRequest" }
+  - { name: "OpenConnectionRequest" }
+  - { name: "PrepareAndExecuteRequest" }
+  - { name: "PrepareRequest" }
+  - { name: "RollbackRequest" }
+  - { name: "SchemasRequest" }
+  - { name: "SyncResultsRequest" }
+  - { name: "TableTypesRequest" }
+  - { name: "TablesRequest" }
+  - { name: "TypeInfoRequest" }
+miscellaneous:
+  - { name: "AvaticaParameter" }
+  - { name: "AvaticaSeverity" }
+  - { name: "AvaticaType" }
+  - { name: "ColumnMetaData" }
+  - { name: "ConnectionProperties" }
+  - { name: "CursorFactory" }
+  - { name: "DatabaseProperty" }
+  - { name: "Frame" }
+  - { name: "QueryState" }
+  - { name: "Rep" }
+  - { name: "RpcMetadata" }
+  - { name: "Signature" }
+  - { name: "StateType" }
+  - { name: "StatementHandle" }
+  - { name: "StatementType" }
+  - { name: "Style" }
+  - { name: "TypedValue" }
+responses:
+  - { name: "CloseConnectionResponse" }
+  - { name: "CloseStatementResponse" }
+  - { name: "CommitResponse" }
+  - { name: "ConnectionSyncResponse" }
+  - { name: "CreateStatementResponse" }
+  - { name: "DatabasePropertyResponse" }
+  - { name: "ErrorResponse" }
+  - { name: "ExecuteResponse" }
+  - { name: "FetchResponse" }
+  - { name: "OpenConnectionResponse" }
+  - { name: "PrepareResponse" }
+  - { name: "ResultSetResponse" }
+  - { name: "RollbackResponse" }
+  - { name: "SyncResultsResponse" }
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+As Avatica uses JSON to serialize messages sent over an HTTP transport,
+the RPC layer is agnostic of the language used by a client. While the Avatica
+server is written in Java, this enables clients to interact with the server
+using any language instead of being limited to Java.
+
+A specification of the JSON request and response objects are documented
+below. Programmatic bindings for these JSON objects are only available
+in Java. For support outside of Java, see the Protocol Buffer
+[bindings]({{ site.baseurl }}/docs/avatica_protobuf_reference.html)
+
+## Index
+
+### Requests
+<ul>
+  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Responses
+<ul>
+  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Miscellaneous
+<ul>
+  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+
+## Requests
+
+The collection of all JSON objects accepted as requests to Avatica. All Requests include a `request` attribute
+which uniquely identifies the concrete Request from all other Requests.
+
+### CatalogsRequest
+
+This request is used to fetch the available catalog names in the database.
+
+{% highlight json %}
+{
+  "request": "getCatalogs",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use.
+
+### CloseConnectionRequest
+
+This request is used to close the Connection object in the Avatica server identified by the given IDs.
+
+{% highlight json %}
+{
+  "request": "closeConnection",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to close.
+
+### CloseStatementRequest
+
+This request is used to close the Statement object in the Avatica server identified by the given IDs.
+
+{% highlight json %}
+{
+  "request": "closeStatement",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to which the statement belongs.
+
+`statementId` (required integer) The identifier of the statement to close.
+
+### ColumnsRequest
+
+This request is used to fetch columns in the database given some optional filtering criteria.
+
+{% highlight json %}
+{
+  "request": "getColumns",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "catalog",
+  "schemaPattern": "schema_pattern.*",
+  "tableNamePattern": "table_pattern.*",
+  "columnNamePattern": "column_pattern.*"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection on which to fetch the columns.
+
+`catalog` (optional string) The name of a catalog to limit returned columns.
+
+`schemaPattern` (optional string) A Java Pattern against schemas to limit returned columns.
+
+`tableNamePattern` (optional string) A Java Pattern against table names to limit returned columns.
+
+`columnNamePattern` (optional string) A Java Pattern against column names to limit returned columns.
+
+### CommitRequest
+
+This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight json %}
+{
+  "request": "commit",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection on which to invoke commit.
+
+### ConnectionSyncRequest
+
+This request is used to ensure that the client and server have a consistent view of the database properties.
+
+{% highlight json %}
+{
+  "request": "connectionSync",
+  "connectionId": "000000-0000-0000-00000000",
+  "connProps": ConnectionProperties
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to synchronize.
+
+`connProps` (optional nested object) A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
+
+### CreateStatementRequest
+
+This request is used to create a new Statement in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "createStatement",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use in creating a statement.
+
+### DatabasePropertyRequest
+
+This request is used to fetch all <a href="#databaseproperty">database properties</a>.
+
+{% highlight json %}
+{
+  "request": "databaseProperties",
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use when fetching the database properties.
+
+### ExecuteRequest
+
+This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
+
+{% highlight json %}
+{
+  "request": "execute",
+  "statementHandle": StatementHandle,
+  "parameterValues": [TypedValue, TypedValue, ... ],
+  "maxRowCount": 100
+}
+{% endhighlight %}
+
+`statementHandle` (required object) A <a href="#statementhandle">StatementHandle</a> object.
+
+`parameterValues` (optional array of nested objects) The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### FetchRequest
+
+This request is used to fetch a batch of rows from a Statement previously created.
+
+{% highlight json %}
+{
+  "request": "fetch",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "offset": 0,
+  "fetchMaxRowCount": 100
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use.
+
+`statementId` (required integer) The identifier of the statement created using the above connection.
+
+`offset` (required integer) The positional offset into a result set to fetch.
+
+`fetchMatchRowCount` (required integer) The maximum number of rows to return in the response to this request.
+
+### OpenConnectionRequest
+
+This request is used to open a new Connection in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "openConnection",
+  "connectionId": "000000-0000-0000-00000000",
+  "info": {"key":"value", ...}
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to open in the server.
+
+`info` (optional string-to-string map) A Map containing properties to include when creating the Connection.
+
+### PrepareAndExecuteRequest
+
+This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
+
+{% highlight json %}
+{
+  "request": "prepareAndExecute",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "sql": "SELECT * FROM table",
+  "maxRowCount": 100,
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`statementId` (required integer) The identifier for the statement created by the above connection to use.
+
+`sql` (required string) A SQL statement
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### PrepareRequest
+
+This request is used to create create a new Statement with the given query in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "prepare",
+  "connectionId": "000000-0000-0000-00000000",
+  "sql": "SELECT * FROM table",
+  "maxRowCount": 100,
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`sql` (required string) A SQL statement
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### SyncResultsRequest
+
+This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "syncResults",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "state": QueryState,
+  "offset": 200
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`statementId` (required integer) The identifier for the statement to use.
+
+`state` (required object) The <a href="#querystate">QueryState</a> object.
+
+`offset` (required long) The offset into the ResultSet to seek to.
+
+### RollbackRequest
+
+This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight json %}
+{
+  "request": "rollback",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection on which to invoke rollback.
+
+### SchemasRequest
+
+This request is used to fetch the schemas matching the provided criteria in the database.
+
+{% highlight json %}
+{
+  "request": "getSchemas",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "name",
+  "schemaPattern": "pattern.*"
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to fetch schemas from.
+
+`catalog` (required string) The name of the catalog to fetch the schema from.
+
+`schemaPattern` (required string) A Java pattern of schemas to fetch.
+
+### TableTypesRequest
+
+This request is used to fetch the table types available in this database.
+
+{% highlight json %}
+{
+  "request": "getTableTypes",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to fetch the table types from.
+
+### TablesRequest
+
+This request is used to fetch the tables available in this database filtered by the provided criteria.
+
+{% highlight json %}
+{
+  "request": "getTables",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "catalog_name",
+  "schemaPattern": "schema_pattern.*",
+  "tableNamePattern": "table_name_pattern.*",
+  "typeList": [ "TABLE", "VIEW", ... ]
+}
+{% endhighlight %}
+
+`catalog` (optional string) The name of a catalog to restrict fetched tables.
+
+`connectionId` The identifier of the connection to fetch the tables from.
+
+`schemaPattern` (optional string) A Java Pattern representing schemas to include in fetched tables.
+
+`tableNamePattern` (optional string) A Java Pattern representing table names to include in fetched tables.
+
+`typeList` (optional array of string) A list of table types used to restrict fetched tables.
+
+### TypeInfoRequest
+
+This request is used to fetch the types available in this database.
+
+{% highlight json %}
+{
+  "request": "getTypeInfo",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to fetch the types from.
+
+## Responses
+
+The collection of all JSON objects returned as responses from Avatica. All Responses include a `response` attribute
+which uniquely identifies the concrete Response from all other Responses.
+
+### CloseConnectionResponse
+
+A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
+
+{% highlight json %}
+{
+  "response": "closeConnection",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CloseStatementResponse
+
+A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
+
+{% highlight json %}
+{
+  "response": "closeStatement",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CommitResponse
+
+A response to the <a href="#commitrequest">CommitRequest</a>.
+
+{% highlight json %}
+{
+  "response": "commit"
+}
+{% endhighlight %}
+
+There are no extra attributes on this Response.
+
+### ConnectionSyncResponse
+
+A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
+response are those of the Connection in the Avatica server.
+
+{% highlight json %}
+{
+  "response": "connectionSync",
+  "connProps": ConnectionProperties,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connProps` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CreateStatementResponse
+
+A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
+that was created is included in the response. Clients will use this `statementId` in subsequent calls.
+
+{% highlight json %}
+{
+  "response": "createStatement",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connectionId` The identifier for the connection used to create the statement.
+
+`statementId` The identifier for the created statement.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### DatabasePropertyResponse
+
+A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
+for information on the available property keys.
+
+{% highlight json %}
+{
+  "response": "databaseProperties",
+  "map": { DatabaseProperty: Object, DatabaseProperty: Object, ... },
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`map` A map of <a href="#databaseproperty">DatabaseProperty</a> to value of that property. The value may be some
+primitive type or an array of primitive types.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ErrorResponse
+
+A response when an error was caught executing a request. Any request may return this response.
+
+{% highlight json %}
+{
+  "response": "error",
+  "exceptions": [ "stacktrace", "stacktrace", ... ],
+  "errorMessage": "The error message",
+  "errorCode": 42,
+  "sqlState": "ABC12",
+  "severity": AvaticaSeverity,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`exceptions` A list of stringified Java StackTraces.
+
+`errorMessage` A human-readable error message.
+
+`errorCode` A numeric code for this error.
+
+`sqlState` A five character alphanumeric code for this error.
+
+`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ExecuteResponse
+
+A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
+
+{% highlight json %}
+{
+  "response": "executeResults",
+  "resultSets": [ ResultSetResponse, ResultSetResponse, ... ],
+  "missingStatement": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`resultSets` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
+
+`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### FetchResponse
+
+A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
+
+{% highlight json %}
+{
+  "response": "fetch",
+  "frame": Frame,
+  "missingStatement": false,
+  "missingResults": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
+
+`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
+
+`missingResults` A boolean which denotes if the request failed due to a missing ResultSet.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### OpenConnectionResponse
+
+A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
+the client should use in subsequent calls was provided by the client in the request.
+
+{% highlight json %}
+{
+  "response": "openConnection",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### PrepareResponse
+
+A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
+which clients must use to fetch the results from the Statement.
+
+{% highlight json %}
+{
+  "response": "prepare",
+  "statement": StatementHandle,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`statement` A <a href="#statementhandle">StatementHandle</a> object.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ResultSetResponse
+
+A response which contains the results and type details from a query.
+
+{% highlight json %}
+{
+  "response": "resultSet",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "ownStatement": true,
+  "signature": Signature,
+  "firstFrame": Frame,
+  "updateCount": 10,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connectionId` The identifier for the connection used to generate this response.
+
+`statementId` The identifier for the statement used to generate this response.
+
+`ownStatement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
+statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
+
+`signature` A non-optional nested object <a href="#signature">Signature</a>
+
+`firstFrame` A optional nested object <a href="#frame">Frame</a>
+
+`updateCount` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
+that only contains this count and no additional data.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### RollbackResponse
+
+A response to the <a href="#rollbackrequest">RollBackRequest</a>.
+
+{% highlight json %}
+{
+  "response": "rollback"
+}
+{% endhighlight %}
+
+There are no extra attributes on this Response.
+
+### SyncResultsResponse
+
+A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
+should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
+or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
+
+{% highlight json %}
+{
+  "response": "syncResults",
+  "moreResults": true,
+  "missingStatement": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`moreResults` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
+
+`missingStatement` A boolean which denotes if the statement for the ResultSet still exists.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+## Miscellaneous
+
+### AvaticaParameter
+
+This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
+complex types such as arrays.
+
+{% highlight json %}
+{
+  "signed": true,
+  "precision": 10,
+  "scale": 2,
+  "parameterType": 8,
+  "typeName": "integer",
+  "className": "java.lang.Integer",
+  "name": "number"
+}
+{% endhighlight %}
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`parameterType` An integer corresponding to the JDBC Types class denoting the column's type.
+
+`typeName` The JDBC type name for this column.
+
+`className` The Java class backing the JDBC type for this column.
+
+`name` The name of the column.
+
+### AvaticaSeverity
+
+This enumeration describes the various levels of concern for an error in the Avatica server.
+
+One of:
+
+* `UNKNOWN`
+* `FATAL`
+* `ERROR`
+* `WARNING`
+
+### AvaticaType
+
+This object describes a simple or complex type for a column. Complex types will contain
+additional information in the `component` or `columns` attribute which describe the nested
+types of the complex parent type.
+
+{% highlight json %}
+{
+  "type": "scalar",
+  "id": "identifier",
+  "name": "column",
+  "rep": Rep,
+  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
+  "component": AvaticaType
+}
+{% endhighlight %}
+
+`type` One of: `scalar`, `array`, `struct`.
+
+`id` A numeric value corresponding to the type of the object per the JDBC Types class.
+
+`name` The readable name of the JDBC type.
+
+`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
+
+`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
+
+`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
+
+### ColumnMetaData
+
+This object represents the JDBC ResultSetMetaData for a column.
+
+{% highlight json %}
+{
+  "ordinal": 0,
+  "autoIncrement": true,
+  "caseSensitive": true,
+  "searchable": false,
+  "currency": false,
+  "nullable": 0,
+  "signed": true,
+  "displaySize": 20,
+  "label": "Description",
+  "columnName": "col1",
+  "schemaName": "schema",
+  "precision": 10,
+  "scale": 2,
+  "tableName": "table",
+  "catalogName": "catalog",
+  "type": AvaticaType,
+  "readOnly": false,
+  "writable": true,
+  "definitelyWritable": true,
+  "columnClassName": "java.lang.String"
+}
+{% endhighlight %}
+
+`ordinal` A positional offset number.
+
+`autoIncrement` A boolean denoting whether the column is automatically incremented.
+
+`caseSensitive` A boolean denoting whether the column is case sensitive.
+
+`searchable` A boolean denoting whether this column supports all WHERE search clauses.
+
+`currency` A boolean denoting whether this column represents currency.
+
+`nullable` A number denoting whether this column supports null values.
+
+* 0 = No null values are allowed
+* 1 = Null values are allowed
+* 2 = It is unknown if null values are allowed
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`displaySize` The character width of the column.
+
+`label` A description for this column.
+
+`columnName` The name of the column.
+
+`schemaName` The schema to which this column belongs.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`tableName` The name of the table to which this column belongs.
+
+`catalogName` The name of the catalog to which this column belongs.
+
+`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
+
+`readOnly` A boolean denoting whether the column is read-only.
+
+`writable` A boolean denoting whether the column is possible to be updated.
+
+`definitelyWritable` A boolean denoting whether the column definitely can be updated.
+
+`columnClassName` The name of the Java class backing the column's type.
+
+### ConnectionProperties
+
+This object represents the properties for a given JDBC Connection.
+
+{% highlight json %}
+{
+  "connProps": "connPropsImpl",
+  "autoCommit": true,
+  "readOnly": true,
+  "transactionIsolation": 0,
+  "catalog": "catalog",
+  "schema": "schema"
+}
+{% endhighlight %}
+
+`autoCommit` (optional boolean) A boolean denoting if autoCommit is enabled for transactions.
+
+`readOnly` (optional boolean) A boolean denoting if a JDBC connection is read-only.
+
+`transactionIsolation` (optional integer) An integer which denotes the level of transactions isolation per the JDBC
+specification. This value is analogous to the values defined in `java.sql.Connection`.
+
+* 0 = Transactions are not supported
+* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
+* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
+* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
+* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
+
+`catalog` (optional string) The name of the catalog to include when fetching connection properties.
+
+`schema` (optional string) The name of the schema to include when fetching connection properties.
+
+### CursorFactory
+
+This object represents the information required to cast untyped objects into the necessary type for some results.
+
+{% highlight json %}
+{
+  "style": Style,
+  "clazz": "java.lang.String",
+  "fieldNames": [ "column1", "column2", ... ]
+}
+{% endhighlight %}
+
+`style` A string denoting the <a href="#style">Style</a> of the contained objects.
+
+### DatabaseProperty
+
+This object represents the exposed database properties for a Connection through the Avatica server.
+
+One of:
+
+* `GET_STRING_FUNCTIONS`
+* `GET_NUMERIC_FUNCTIONS`
+* `GET_SYSTEM_FUNCTIONS`
+* `GET_TIME_DATE_FUNCTIONS`
+* `GET_S_Q_L_KEYWORDS`
+* `GET_DEFAULT_TRANSACTION_ISOLATION`
+
+### Frame
+
+This object represents a batch of results, tracking the offset into the results and whether more results still exist
+to be fetched in the Avatica server.
+
+{% highlight json %}
+{
+  "offset": 100,
+  "done": true,
+  "rows": [ [ val1, val2, ... ], ... ]
+}
+{% endhighlight %}
+
+`offset` The starting position of these `rows` in the encompassing result set.
+
+`done` A boolean denoting whether more results exist for this result set.
+
+`rows` An array of arrays corresponding to the rows and columns for the result set.
+
+### QueryState
+
+This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
+SQL or by a DatabaseMetaData operation with arguments on that operation.
+
+{% highlight json %}
+{
+  "type": StateType,
+  "sql": "SELECT * FROM table",
+  "metaDataOperation": MetaDataOperation,
+  "operationArgs": ["arg0", "arg1", ... ]
+}
+{% endhighlight %}
+
+`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
+
+`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
+
+`metaDataOperation` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
+
+`operationArgs` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
+
+### Rep
+
+This enumeration represents the concrete Java type for some value.
+
+One of:
+
+* `PRIMITIVE_BOOLEAN`
+* `PRIMITIVE_BYTE`
+* `PRIMITIVE_CHAR`
+* `PRIMITIVE_SHORT`
+* `PRIMITIVE_INT`
+* `PRIMITIVE_LONG`
+* `PRIMITIVE_FLOAT`
+* `PRIMITIVE_DOUBLE`
+* `BOOLEAN`
+* `BYTE`
+* `CHARACTER`
+* `SHORT`
+* `INTEGER`
+* `LONG`
+* `FLOAT`
+* `DOUBLE`
+* `JAVA_SQL_TIME`
+* `JAVA_SQL_TIMESTAMP`
+* `JAVA_SQL_DATE`
+* `JAVA_UTIL_DATE`
+* `BYTE_STRING`
+* `STRING`
+* `NUMBER`
+* `OBJECT`
+
+### RpcMetadata
+
+This object contains assorted per-call/contextual metadata returned by the Avatica server.
+
+{% highlight json %}
+{
+  "serverAddress": "localhost:8765"
+}
+{% endhighlight %}
+
+`serverAddress` The `host:port` of the server which created this object.
+
+### Signature
+
+This object represents the result of preparing a Statement in the Avatica server.
+
+{% highlight json %}
+{
+  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
+  "sql": "SELECT * FROM table",
+  "parameters": [ AvaticaParameter, AvaticaParameter, ... ],
+  "cursorFactory": CursorFactory,
+  "statementType": StatementType
+}
+{% endhighlight %}
+
+`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
+
+`sql` The SQL executed.
+
+`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
+
+`cursorFactory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
+
+`statementType` An <a href="#statementtype">StatementType</a> object representing the type of Statement.
+
+### StateType
+
+This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
+
+One of:
+
+* `SQL`
+* `METADATA`
+
+### StatementHandle
+
+This object encapsulates all of the information of a Statement created in the Avatica server.
+
+{% highlight json %}
+{
+  "connectionId": "000000-0000-0000-00000000",
+  "id": 12345,
+  "signature": Signature
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to which this statement belongs.
+
+`id` The identifier of the statement.
+
+`signature` A <a href="#signature">Signature</a> object for the statement.
+
+### StatementType
+
+This enumeration represents what kind the Statement is.
+
+One of:
+
+* `SELECT`
+* `INSERT`
+* `UPDATE`
+* `DELETE`
+* `UPSERT`
+* `MERGE`
+* `OTHER_DML`
+* `CREATE`
+* `DROP`
+* `ALTER`
+* `OTHER_DDL`
+* `CALL`
+
+### Style
+
+This enumeration represents the generic "class" of type for a value.
+
+One of:
+
+* `OBJECT`
+* `RECORD`
+* `RECORD_PROJECTION`
+* `ARRAY`
+* `LIST`
+* `MAP`
+
+### TypedValue
+
+This object encapsulates the type and value for a column in a row.
+
+{% highlight json %}
+{
+  "type": "type_name",
+  "value": object
+}
+{% endhighlight %}
+
+`type` A name referring to the type of the object stored in `value`.
+
+`value` A JSON representation of a JDBC type.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/lattice.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/lattice.md b/avatica/site/_docs/lattice.md
deleted file mode 100644
index 918261c..0000000
--- a/avatica/site/_docs/lattice.md
+++ /dev/null
@@ -1,136 +0,0 @@
----
-layout: docs
-title: Lattices
-permalink: /docs/lattice.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-A lattice is a framework for creating and populating materialized views,
-and for recognizing that a materialized view can be used to solve a
-particular query.
-
-A lattice represents a star (or snowflake) schema, not a general
-schema. In particular, all relationships must be many-to-one, heading
-from a fact table at the center of the star.
-
-The name derives from the mathematics: a
-<a href="http://en.wikipedia.org/wiki/Lattice_(order)">lattice</a>
-is a
-<a href="http://en.wikipedia.org/wiki/Partially_ordered_set">partially
-ordered set</a> where any two elements have a unique greatest lower
-bound and least upper bound.
-
-[<a href="#ref-hru96">HRU96</a>] observed that the set of possible
-materializations of a data cube forms a lattice, and presented an
-algorithm to choose a good set of materializations. Calcite's
-recommendation algorithm is derived from this.
-
-The lattice definition uses a SQL statement to represent the star. SQL
-is a useful short-hand to represent several tables joined together,
-and assigning aliases to the column names (it more convenient than
-inventing a new language to represent relationships, join conditions
-and cardinalities).
-
-Unlike regular SQL, order is important. If you put A before B in the
-FROM clause, and make a join between A and B, you are saying that
-there is a many-to-one foreign key relationship from A to B. (E.g. in
-the example lattice, the Sales fact table occurs before the Time
-dimension table, and before the Product dimension table. The Product
-dimension table occurs before the ProductClass outer dimension table,
-further down an arm of a snowflake.)
-
-A lattice implies constraints. In the A to B relationship, there is a
-foreign key on A (i.e. every value of A's foreign key has a
-corresponding value in B's key), and a unique key on B (i.e. no key
-value occurs more than once). These constraints are really important,
-because it allows the planner to remove joins to tables whose columns
-are not being used, and know that the query results will not change.
-
-Calcite does not check these constraints. If they are violated,
-Calcite will return wrong results.
-
-A lattice is a big, virtual join view. It is not materialized (it
-would be several times larger than the star schema, because of
-denormalization) and you probably wouldn't want to query it (far too
-many columns). So what is it useful for? As we said above, (a) the
-lattice declares some very useful primary and foreign key constraints,
-(b) it helps the query planner map user queries onto
-filter-join-aggregate materialized views (the most useful kind of
-materialized view for DW queries), (c) gives Calcite a framework
-within which to gather stats about data volumes and user queries, (d)
-allows Calcite to automatically design and populate materialized
-views.
-
-Most star schema models force you to choose whether a column is a
-dimension or a measure. In a lattice, every column is a dimension
-column. (That is, it can become one of the columns in the GROUP BY clause
-to query the star schema at a particular dimensionality). Any column
-can also be used in a measure; you define measures by giving the
-column and an aggregate function.
-
-If "unit_sales" tends to be used much more often as a measure rather
-than a dimension, that's fine. Calcite's algorithm should notice that
-it is rarely aggregated, and not be inclined to create tiles that
-aggregate on it. (By "should" I mean "could and one day will". The
-algorithm does not currently take query history into account when
-designing tiles.)
-
-But someone might want to know whether orders with fewer than 5 items
-were more or less profitable than orders with more than 100. All of a
-sudden, "unit_sales" has become a dimension. If there's virtually zero
-cost to declaring a column a dimension column, I figured let's make
-them all dimension columns.
-
-The model allows for a particular table to be used more than once,
-with a different table alias. You could use this to model say
-OrderDate and ShipDate, with two uses to the Time dimension table.
-
-Most SQL systems require that the column names in a view are unique.
-This is hard to achieve in a lattice, because you often include
-primary and foreign key columns in a join. So Calcite lets you refer
-to columns in two ways. If the column is unique, you can use its name,
-["unit_sales"]. Whether or not it is unique in the lattice, it will be
-unique in its table, so you can use it qualified by its table alias.
-Examples:
-
-* ["sales", "unit_sales"]
-* ["ship_date", "time_id"]
-* ["order_date", "time_id"]
-
-A "tile" is a materialized table in a lattice, with a particular
-dimensionality. (What Kylin calls a "cuboid".) The "tiles" attribute
-of the <a href="{{ site.baseurl }}/docs/model.html#lattice">lattice JSON element</a>
-defines an initial set of tiles to materialize.
-
-If you run the algorithm, you can omit the tiles attribute. Calcite
-will choose an initial set. If you include the tiles attribute, the
-algorithm will start with that list and then start finding other tiles
-that are complementary (i.e. "fill in the gaps" left by the initial
-tiles).
-
-### References
-
-<ul>
-<li>[<a name="ref-hru96">HRU96</a>] V. Harinarayan, A. Rajaraman and J. Ullman.
-    <a href="http://web.eecs.umich.edu/~jag/eecs584/papers/implementing_data_cube.pdf">Implementing
-    data cubes efficiently</a>.
-    In <i>Proc. ACM SIGMOD Conf.</i>, Montreal, 1996.</li>
-</ul>
-

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/model.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/model.md b/avatica/site/_docs/model.md
deleted file mode 100644
index 2675453..0000000
--- a/avatica/site/_docs/model.md
+++ /dev/null
@@ -1,517 +0,0 @@
----
-layout: docs
-title: JSON models
-permalink: /docs/model.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Calcite models can be represented as JSON files.
-This page describes the structure of those files.
-
-Models can also be built programmatically using the `Schema` SPI.
-
-## Elements
-
-### Root
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'mongo',
-  schemas: [ Schema... ]
-}
-{% endhighlight %}
-
-`version` (required string) must have value `1.0`.
-
-`defaultSchema` (optional string). If specified, it is
-the name (case-sensitive) of a schema defined in this model, and will
-become the default schema for connections to Calcite that use this model.
-
-`schemas` (optional list of <a href="#schema">Schema</a> elements).
-
-### Schema
-
-Occurs within `root.schemas`.
-
-{% highlight json %}
-{
-  name: 'foodmart',
-  path: ['lib'],
-  cache: true,
-  materializations: [ Materialization... ]
-}
-{% endhighlight %}
-
-`name` (required string) is the name of the schema.
-
-`type` (optional string, default `map`) indicates sub-type. Values are:
-
-* `map` for <a href="#map-schema">Map Schema</a>
-* `custom` for <a href="#custom-schema">Custom Schema</a>
-* `jdbc` for <a href="#jdbc-schema">JDBC Schema</a>
-
-`path` (optional list) is the SQL path that is used to
-resolve functions used in this schema. If specified it must be a list,
-and each element of the list must be either a string or a list of
-strings. For example,
-
-{% highlight json %}
-  path: [ ['usr', 'lib'], 'lib' ]
-{% endhighlight %}
-
-declares a path with two elements: the schema '/usr/lib' and the
-schema '/lib'. Most schemas are at the top level, and for these you can use a
-string.
-
-`materializations` (optional list of
-<a href="#materialization">Materialization</a>) defines the tables
-in this schema that are materializations of queries.
-
-`cache` (optional boolean, default true) tells Calcite whether to
-cache metadata (tables, functions and sub-schemas) generated
-by this schema.
-
-* If `false`, Calcite will go back to the schema each time it needs
-  metadata, for example, each time it needs a list of tables in order to
-  validate a query against the schema.
-
-* If `true`, Calcite will cache the metadata the first time it reads
-  it. This can lead to better performance, especially if name-matching is
-  case-insensitive.
-
-However, it also leads to the problem of cache staleness.
-A particular schema implementation can override the
-`Schema.contentsHaveChangedSince` method to tell Calcite
-when it should consider its cache to be out of date.
-
-Tables, functions and sub-schemas explicitly created in a schema are
-not affected by this caching mechanism. They always appear in the schema
-immediately, and are never flushed.
-
-### Map Schema
-
-Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
-
-{% highlight json %}
-{
-  name: 'foodmart',
-  type: 'map',
-  tables: [ Table... ],
-  functions: [ Function... ]
-}
-{% endhighlight %}
-
-`name`, `type`, `path`, `cache`, `materializations` inherited from
-<a href="#schema">Schema</a>.
-
-`tables` (optional list of <a href="#table">Table</a> elements)
-defines the tables in this schema.
-
-`functions` (optional list of <a href="#function">Function</a> elements)
-defines the functions in this schema.
-
-### Custom Schema
-
-Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
-
-{% highlight json %}
-{
-  name: 'mongo',
-  type: 'custom',
-  factory: 'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',
-  operand: {
-    host: 'localhost',
-    database: 'test'
-  }
-}
-{% endhighlight %}
-
-`name`, `type`, `path`, `cache`, `materializations` inherited from
-<a href="#schema">Schema</a>.
-
-`factory` (required string) is the name of the factory class for this
-schema. Must implement interface
-[org.apache.calcite.schema.SchemaFactory]({{ site.apiRoot }}/org/apache/calcite/schema/SchemaFactory.html)
-and have a public default constructor.
-
-`operand` (optional map) contains attributes to be passed to the
-factory.
-
-### JDBC Schema
-
-Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
-
-{% highlight json %}
-{
-  name: 'foodmart',
-  type: 'jdbc',
-  jdbcDriver: TODO,
-  jdbcUrl: TODO,
-  jdbcUser: TODO,
-  jdbcPassword: TODO,
-  jdbcCatalog: TODO,
-  jdbcSchema: TODO
-}
-{% endhighlight %}
-
-`name`, `type`, `path`, `cache`, `materializations` inherited from
-<a href="#schema">Schema</a>.
-
-`jdbcDriver` (optional string) is the name of the JDBC driver class. If not
-specified, uses whichever class the JDBC DriverManager chooses.
-
-`jdbcUrl` (optional string) is the JDBC connect string, for example
-"jdbc:mysql://localhost/foodmart".
-
-`jdbcUser` (optional string) is the JDBC user name.
-
-`jdbcPassword` (optional string) is the JDBC password.
-
-`jdbcCatalog` (optional string) is the name of the initial catalog in the JDBC
-data source.
-
-`jdbcSchema` (optional string) is the name of the initial schema in the JDBC
-data source.
-
-### Materialization
-
-Occurs within `root.schemas.materializations`.
-
-{% highlight json %}
-{
-  view: 'V',
-  table: 'T',
-  sql: 'select deptno, count(*) as c, sum(sal) as s from emp group by deptno'
-}
-{% endhighlight %}
-
-`view` (optional string) is the name of the view; null means that the table
-already exists and is populated with the correct data.
-
-`table` (required string) is the name of the table that materializes the data in
-the query. If `view` is not null, the table might not exist, and if it does not,
-Calcite will create and populate an in-memory table.
-
-`sql` (optional string, or list of strings that will be concatenated as a
- multi-line string) is the SQL definition of the materialization.
-
-### Table
-
-Occurs within `root.schemas.tables`.
-
-{% highlight json %}
-{
-  name: 'sales_fact',
-  columns: [ Column... ]
-}
-{% endhighlight %}
-
-`name` (required string) is the name of this table. Must be unique within the schema.
-
-`type` (optional string, default `custom`) indicates sub-type. Values are:
-
-* `custom` for <a href="#custom-table">Custom Table</a>
-* `view` for <a href="#view">View</a>
-
-`columns` (list of <a href="#column">Column</a> elements, required for
-some kinds of table, optional for others such as View)
-
-### View
-
-Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
-
-{% highlight json %}
-{
-  name: 'female_emps',
-  type: 'view',
-  sql: "select * from emps where gender = 'F'",
-  modifiable: true
-}
-{% endhighlight %}
-
-`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
-
-`sql` (required string, or list of strings that will be concatenated as a
- multi-line string) is the SQL definition of the view.
-
-`path` (optional list) is the SQL path to resolve the query. If not
-specified, defaults to the current schema.
-
-`modifiable` (optional boolean) is whether the view is modifiable.
-If null or not specified, Calcite deduces whether the view is modifiable.
-
-A view is modifiable if contains only SELECT, FROM, WHERE (no JOIN, aggregation
-or sub-queries) and every column:
-
-* is specified once in the SELECT clause; or
-* occurs in the WHERE clause with a `column = literal` predicate; or
-* is nullable.
-
-The second clause allows Calcite to automatically provide the correct value for
-hidden columns. It is useful in multi-tenant environments, where the `tenantId`
-column is hidden, mandatory (NOT NULL), and has a constant value for a
-particular view.
-
-Errors regarding modifiable views:
-
-* If a view is marked `modifiable: true` and is not modifiable, Calcite throws
-  an error while reading the schema.
-* If you submit an INSERT, UPDATE or UPSERT command to a non-modifiable view,
-  Calcite throws an error when validating the statement.
-* If a DML statement creates a row that would not appear in the view
-  (for example, a row in `female_emps`, above, with `gender = 'M'`),
-  Calcite throws an error when executing the statement.
-
-### Custom Table
-
-Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
-
-{% highlight json %}
-{
-  name: 'female_emps',
-  type: 'custom',
-  factory: 'TODO',
-  operand: {
-    todo: 'TODO'
-  }
-}
-{% endhighlight %}
-
-`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
-
-`factory` (required string) is the name of the factory class for this
-table. Must implement interface
-[org.apache.calcite.schema.TableFactory]({{ site.apiRoot }}/org/apache/calcite/schema/TableFactory.html)
-and have a public default constructor.
-
-`operand` (optional map) contains attributes to be passed to the
-factory.
-
-### Stream
-
-Information about whether a table allows streaming.
-
-Occurs within `root.schemas.tables.stream`.
-
-{% highlight json %}
-{
-  stream: true,
-  history: false
-}
-{% endhighlight %}
-
-`stream` (optional; default true) is whether the table allows streaming.
-
-`history` (optional; default false) is whether the history of the stream is
-available.
-
-### Column
-
-Occurs within `root.schemas.tables.columns`.
-
-{% highlight json %}
-{
-  name: 'empno'
-}
-{% endhighlight %}
-
-`name` (required string) is the name of this column.
-
-### Function
-
-Occurs within `root.schemas.functions`.
-
-{% highlight json %}
-{
-  name: 'MY_PLUS',
-  className: 'com.example.functions.MyPlusFunction',
-  methodName: 'apply',
-  path: []
-}
-{% endhighlight %}
-
-`name` (required string) is the name of this function.
-
-`className` (required string) is the name of the class that implements this
-function.
-
-`methodName` (optional string) is the name of the method that implements this
-function.
-
-If `methodName` is specified, the method must exist (case-sensitive) and Calcite
-will create a scalar function. The method may be static or non-static, but
-if non-static, the class must have a public constructor with no parameters.
-
-If `methodName` is "*", Calcite creates a function for every method
-in the class.
-
-If `methodName` is not specified, Calcite looks for a method called "eval", and
-if found, creates a a table macro or scalar function.
-It also looks for methods "init", "add", "merge", "result", and
-if found, creates an aggregate function.
-
-`path` (optional list of string) is the path for resolving this function.
-
-### Lattice
-
-Occurs within `root.schemas.lattices`.
-
-{% highlight json %}
-{
-  name: 'star',
-  sql: [
-    'select 1 from "foodmart"."sales_fact_1997" as "s"',
-    'join "foodmart"."product" as "p" using ("product_id")',
-    'join "foodmart"."time_by_day" as "t" using ("time_id")',
-    'join "foodmart"."product_class" as "pc" on "p"."product_class_id" = "pc"."product_class_id"'
-  ],
-  auto: false,
-  algorithm: true,
-  algorithmMaxMillis: 10000,
-  rowCountEstimate: 86837,
-  defaultMeasures: [ {
-    agg: 'count'
-  } ],
-  tiles: [ {
-    dimensions: [ 'the_year', ['t', 'quarter'] ],
-    measures: [ {
-      agg: 'sum',
-      args: 'unit_sales'
-    }, {
-      agg: 'sum',
-      args: 'store_sales'
-    }, {
-      agg: 'count'
-    } ]
-  } ]
-}
-{% endhighlight %}
-
-`name` (required string) is the name of this lattice.
-
-`sql` (required string, or list of strings that will be concatenated as a
-multi-line string) is the SQL statement that defines the fact table, dimension
-tables, and join paths for this lattice.
-
-`auto` (optional boolean, default true) is whether to materialize tiles on need
-as queries are executed.
-
-`algorithm` (optional boolean, default false) is whether to use an optimization
-algorithm to suggest and populate an initial set of tiles.
-
-`algorithmMaxMillis` (optional long, default -1, meaning no limit) is the
-maximum number of milliseconds for which to run the algorithm. After this point,
-takes the best result the algorithm has come up with so far.
-
-`rowCountEstimate` (optional double, default 1000.0) estimated number of rows in
-the lattice
-
-`tiles` (optional list of <a href="#tile">Tile</a> elements) is a list of
-materialized aggregates to create up front.
-
-`defaultMeasures`  (optional list of <a href="#measure">Measure</a> elements)
-is a list of measures that a tile should have by default.
-Any tile defined in `tiles` can still define its own measures, including
-measures not on this list. If not specified, the default list of measures is
-just 'count(*)':
-
-{% highlight json %}
-[ { name: 'count' } ]
-{% endhighlight %}
-
-`statisticProvider` (optional name of a class that implements
-[org.apache.calcite.materialize.LatticeStatisticProvider]({{ site.apiRoot }}/org/apache/calcite/materialize/LatticeStatisticProvider.html))
-provides estimates of the number of distinct values in each column.
-
-You can use a class name, or a class plus a static field. Example:
-
-{% highlight json %}
-  "statisticProvider": "org.apache.calcite.materialize.Lattices#CACHING_SQL_STATISTIC_PROVIDER"
-{% endhighlight %}
-
-If not set, Calcite will generate and execute a SQL query to find the real
-value, and cache the results.
-
-See also: <a href="{{ site.baseurl }}/docs/lattice.html">Lattices</a>.
-
-### Tile
-
-Occurs within `root.schemas.lattices.tiles`.
-
-{% highlight json %}
-{
-  dimensions: [ 'the_year', ['t', 'quarter'] ],
-  measures: [ {
-    agg: 'sum',
-    args: 'unit_sales'
-  }, {
-    agg: 'sum',
-    args: 'store_sales'
-  }, {
-    agg: 'count'
-  } ]
-}
-{% endhighlight %}
-
-`dimensions` (list of strings or string lists, required, but may be empty)
-defines the dimensionality of this tile.
-Each dimension is a column from the lattice, like a `GROUP BY` clause.
-Each element can be either a string
-(the unique label of the column within the lattice)
-or a string list (a pair consisting of a table alias and a column name).
-
-`measures` (optional list of <a href="#measure">Measure</a> elements) is a list
-of aggregate functions applied to arguments. If not specified, uses the
-lattice's default measure list.
-
-### Measure
-
-Occurs within `root.schemas.lattices.defaultMeasures`
-and `root.schemas.lattices.tiles.measures`.
-
-{% highlight json %}
-{
-  agg: 'sum',
-  args: [ 'unit_sales' ]
-}
-{% endhighlight %}
-
-`agg` is the name of an aggregate function (usually 'count', 'sum', 'min',
-'max').
-
-`args` (optional) is a column label (string), or list of zero or more column
-labels
-
-Valid values are:
-
-* Not specified: no arguments
-* null: no arguments
-* Empty list: no arguments
-* String: single argument, the name of a lattice column
-* List: multiple arguments, each a column label
-
-Unlike lattice dimensions, measures can not be specified in qualified
-format, {@code ["table", "column"]}. When you define a lattice, make sure
-that each column you intend to use as a measure has a unique label within
-the lattice (using "{@code AS label}" if necessary), and use that label
-when you want to pass the column as a measure argument.
-
-<!-- End model.md -->


[28/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
new file mode 100644
index 0000000..6870717
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
@@ -0,0 +1,256 @@
+/*
+ * 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.noop;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * A {@link Connection} implementation which does nothing.
+ */
+public class AvaticaNoopConnection implements Connection {
+
+  private static final AvaticaNoopConnection INSTANCE = new AvaticaNoopConnection();
+
+  public static AvaticaNoopConnection getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopConnection() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Statement createStatement() throws SQLException {
+    return AvaticaNoopStatement.getInstance();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql) throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public CallableStatement prepareCall(String sql) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String nativeSQL(String sql) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setAutoCommit(boolean autoCommit) throws SQLException {}
+
+  @Override public boolean getAutoCommit() throws SQLException {
+    return false;
+  }
+
+  @Override public void commit() throws SQLException {}
+
+  @Override public void rollback() throws SQLException {}
+
+  @Override public void close() throws SQLException {}
+
+  @Override public boolean isClosed() throws SQLException {
+    return true;
+  }
+
+  @Override public DatabaseMetaData getMetaData() throws SQLException {
+    return AvaticaNoopDatabaseMetaData.getInstance();
+  }
+
+  @Override public void setReadOnly(boolean readOnly) throws SQLException {}
+
+  @Override public boolean isReadOnly() throws SQLException {
+    return false;
+  }
+
+  @Override public void setCatalog(String catalog) throws SQLException {}
+
+  @Override public String getCatalog() throws SQLException {
+    return null;
+  }
+
+  @Override public void setTransactionIsolation(int level) throws SQLException {}
+
+  @Override public int getTransactionIsolation() throws SQLException {
+    return 0;
+  }
+
+  @Override public SQLWarning getWarnings() throws SQLException {
+    return null;
+  }
+
+  @Override public void clearWarnings() throws SQLException {}
+
+  @Override public Statement createStatement(int resultSetType, int resultSetConcurrency)
+      throws SQLException {
+    return AvaticaNoopStatement.getInstance();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql, int resultSetType,
+      int resultSetConcurrency) throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public CallableStatement prepareCall(String sql, int resultSetType,
+      int resultSetConcurrency) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Map<String, Class<?>> getTypeMap() throws SQLException {
+    return Collections.emptyMap();
+  }
+
+  @Override public void setTypeMap(Map<String, Class<?>> map) throws SQLException {}
+
+  @Override public void setHoldability(int holdability) throws SQLException {}
+
+  @Override public int getHoldability() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Savepoint setSavepoint() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Savepoint setSavepoint(String name) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void rollback(Savepoint savepoint) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Statement createStatement(int resultSetType, int resultSetConcurrency,
+      int resultSetHoldability) throws SQLException {
+    return AvaticaNoopStatement.getInstance();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql, int resultSetType,
+      int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public CallableStatement prepareCall(String sql, int resultSetType,
+      int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+      throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+      throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public PreparedStatement prepareStatement(String sql, String[] columnNames)
+      throws SQLException {
+    return AvaticaNoopPreparedStatement.getInstance();
+  }
+
+  @Override public Clob createClob() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Blob createBlob() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public NClob createNClob() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public SQLXML createSQLXML() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isValid(int timeout) throws SQLException {
+    return true;
+  }
+
+  @Override public void setClientInfo(String name, String value) throws SQLClientInfoException {}
+
+  @Override public void setClientInfo(Properties properties) throws SQLClientInfoException {}
+
+  @Override public String getClientInfo(String name) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Properties getClientInfo() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setSchema(String schema) throws SQLException {}
+
+  @Override public String getSchema() throws SQLException {
+    return null;
+  }
+
+  @Override public void abort(Executor executor) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setNetworkTimeout(Executor executor, int milliseconds)
+      throws SQLException {}
+
+  @Override public int getNetworkTimeout() throws SQLException {
+    throw unsupported();
+  }
+
+}
+
+// End AvaticaNoopConnection.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
new file mode 100644
index 0000000..2b58590
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
@@ -0,0 +1,770 @@
+/*
+ * 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.noop;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+
+/**
+ * A {@link DatabaseMetaData} implementation which does nothing.
+ */
+public class AvaticaNoopDatabaseMetaData implements DatabaseMetaData {
+
+  private static final AvaticaNoopDatabaseMetaData INSTANCE = new AvaticaNoopDatabaseMetaData();
+
+  public static AvaticaNoopDatabaseMetaData getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopDatabaseMetaData() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean allProceduresAreCallable() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean allTablesAreSelectable() throws SQLException {
+    return false;
+  }
+
+  @Override public String getURL() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getUserName() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isReadOnly() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean nullsAreSortedHigh() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean nullsAreSortedLow() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean nullsAreSortedAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean nullsAreSortedAtEnd() throws SQLException {
+    return false;
+  }
+
+  @Override public String getDatabaseProductName() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getDatabaseProductVersion() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getDriverName() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getDriverVersion() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getDriverMajorVersion() {
+    return 0;
+  }
+
+  @Override public int getDriverMinorVersion() {
+    return 0;
+  }
+
+  @Override public boolean usesLocalFiles() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean usesLocalFilePerTable() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesUpperCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override public String getIdentifierQuoteString() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getSQLKeywords() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getNumericFunctions() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getStringFunctions() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getSystemFunctions() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getTimeDateFunctions() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getSearchStringEscape() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getExtraNameCharacters() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsColumnAliasing() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean nullPlusNonNullIsNull() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsConvert() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsConvert(int fromType, int toType) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsExpressionsInOrderBy() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOrderByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsGroupBy() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsGroupByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsGroupByBeyondSelect() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsLikeEscapeClause() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMultipleResultSets() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMultipleTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsNonNullableColumns() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMinimumSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCoreSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsExtendedSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsANSI92FullSQL() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsFullOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsLimitedOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override public String getSchemaTerm() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getProcedureTerm() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getCatalogTerm() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isCatalogAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override public String getCatalogSeparator() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean supportsSchemasInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsPositionedDelete() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsPositionedUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSelectForUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsStoredProcedures() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSubqueriesInComparisons() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSubqueriesInExists() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSubqueriesInIns() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsCorrelatedSubqueries() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsUnion() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsUnionAll() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override public int getMaxBinaryLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxCharLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnsInGroupBy() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnsInIndex() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnsInOrderBy() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnsInSelect() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxColumnsInTable() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxConnections() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxCursorNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxIndexLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxSchemaNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxProcedureNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxCatalogNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxRowSize() throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+    return false;
+  }
+
+  @Override public int getMaxStatementLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxStatements() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxTableNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxTablesInSelect() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getMaxUserNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getDefaultTransactionIsolation() throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean supportsTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsDataDefinitionAndDataManipulationTransactions()
+      throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getProcedures(String catalog, String schemaPattern,
+      String procedureNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+      String procedureNamePattern, String columnNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getTables(String catalog, String schemaPattern,
+      String tableNamePattern, String[] types) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getSchemas() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getCatalogs() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getTableTypes() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getColumns(String catalog, String schemaPattern,
+      String tableNamePattern, String columnNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table,
+      String columnNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern,
+      String tableNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table,
+      int scope, boolean nullable) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getVersionColumns(String catalog, String schema, String table)
+      throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+      throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getImportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getExportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema,
+      String parentTable, String foreignCatalog, String foreignSchema,
+      String foreignTable) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getTypeInfo() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getIndexInfo(String catalog, String schema, String table,
+      boolean unique, boolean approximate) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public boolean supportsResultSetType(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsResultSetConcurrency(int type, int concurrency)
+      throws SQLException {
+    return false;
+  }
+
+  @Override public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean ownDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean ownInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean othersDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean othersInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean updatesAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean deletesAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean insertsAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsBatchUpdates() throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern,
+      int[] types) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Connection getConnection() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean supportsSavepoints() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsNamedParameters() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsMultipleOpenResults() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsGetGeneratedKeys() throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getSuperTypes(String catalog, String schemaPattern,
+      String typeNamePattern) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSet getSuperTables(String catalog, String schemaPattern,
+      String tableNamePattern) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSet getAttributes(String catalog, String schemaPattern,
+      String typeNamePattern, String attributeNamePattern) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+    return false;
+  }
+
+  @Override public int getResultSetHoldability() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getDatabaseMajorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getDatabaseMinorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getJDBCMajorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getJDBCMinorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override public int getSQLStateType() throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean locatorsUpdateCopy() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean supportsStatementPooling() throws SQLException {
+    return false;
+  }
+
+  @Override public RowIdLifetime getRowIdLifetime() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+    return false;
+  }
+
+  @Override public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getClientInfoProperties() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getFunctions(String catalog, String schemaPattern,
+      String functionNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getFunctionColumns(String catalog, String schemaPattern,
+      String functionNamePattern, String columnNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public ResultSet getPseudoColumns(String catalog, String schemaPattern,
+      String tableNamePattern, String columnNamePattern) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public boolean generatedKeyAlwaysReturned() throws SQLException {
+    return false;
+  }
+}
+
+// End AvaticaNoopDatabaseMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
new file mode 100644
index 0000000..76f5356
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
@@ -0,0 +1,74 @@
+/*
+ * 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.noop;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/**
+ * A Noop JDBC Driver.
+ */
+public class AvaticaNoopDriver implements Driver {
+
+  private static final AvaticaNoopDriver INSTANCE = new AvaticaNoopDriver();
+
+  static {
+    try {
+      DriverManager.registerDriver(INSTANCE);
+    } catch (Exception e) {
+      System.err.println("Failed to register driver");
+      e.printStackTrace(System.err);
+    }
+  }
+
+  @Override public Connection connect(String url, Properties info) throws SQLException {
+    return AvaticaNoopConnection.getInstance();
+  }
+
+  @Override public boolean acceptsURL(String url) throws SQLException {
+    return url.startsWith("jdbc:avatica:noop");
+  }
+
+  @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
+      throws SQLException {
+    return new DriverPropertyInfo[0];
+  }
+
+  @Override public int getMajorVersion() {
+    return 1;
+  }
+
+  @Override public int getMinorVersion() {
+    return 7;
+  }
+
+  @Override public boolean jdbcCompliant() {
+    return true;
+  }
+
+  @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+    return Logger.getLogger("");
+  }
+}
+
+// End AvaticaNoopDriver.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
new file mode 100644
index 0000000..f7117e9
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
@@ -0,0 +1,85 @@
+/*
+ * 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.noop;
+
+import java.sql.ParameterMetaData;
+import java.sql.SQLException;
+
+/**
+ * An implementation of {@link ParameterMetaData} which does nothing.
+ */
+public class AvaticaNoopParameterMetaData implements ParameterMetaData {
+
+  private static final AvaticaNoopParameterMetaData INSTANCE = new AvaticaNoopParameterMetaData();
+
+  public static AvaticaNoopParameterMetaData getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopParameterMetaData() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return false;
+  }
+
+  @Override public int getParameterCount() throws SQLException {
+    return 0;
+  }
+
+  @Override public int isNullable(int param) throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean isSigned(int param) throws SQLException {
+    return false;
+  }
+
+  @Override public int getPrecision(int param) throws SQLException {
+    return 0;
+  }
+
+  @Override public int getScale(int param) throws SQLException {
+    return 0;
+  }
+
+  @Override public int getParameterType(int param) throws SQLException {
+    return 0;
+  }
+
+  @Override public String getParameterTypeName(int param) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getParameterClassName(int param) throws SQLException {
+    return "java.lang.Object";
+  }
+
+  @Override public int getParameterMode(int param) throws SQLException {
+    return 0;
+  }
+
+}
+
+// End AvaticaNoopParameterMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
new file mode 100644
index 0000000..b8ad8cc
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
@@ -0,0 +1,344 @@
+/*
+ * 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.noop;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+/**
+ * A {@link PreparedStatement} instance which does nothing.
+ */
+public class AvaticaNoopPreparedStatement implements PreparedStatement {
+
+  private static final AvaticaNoopPreparedStatement INSTANCE = new AvaticaNoopPreparedStatement();
+
+  public static AvaticaNoopPreparedStatement getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopPreparedStatement() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public ResultSet executeQuery(String sql) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public int executeUpdate(String sql) throws SQLException {
+    return 1;
+  }
+
+  @Override public void close() throws SQLException {}
+
+  @Override public int getMaxFieldSize() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setMaxFieldSize(int max) throws SQLException {}
+
+  @Override public int getMaxRows() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setMaxRows(int max) throws SQLException {}
+
+  @Override public void setEscapeProcessing(boolean enable) throws SQLException {}
+
+  @Override public int getQueryTimeout() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setQueryTimeout(int seconds) throws SQLException {}
+
+  @Override public void cancel() throws SQLException {}
+
+  @Override public SQLWarning getWarnings() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void clearWarnings() throws SQLException {}
+
+  @Override public void setCursorName(String name) throws SQLException {}
+
+  @Override public boolean execute(String sql) throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getResultSet() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public int getUpdateCount() throws SQLException {
+    return 1;
+  }
+
+  @Override public boolean getMoreResults() throws SQLException {
+    return false;
+  }
+
+  @Override public void setFetchDirection(int direction) throws SQLException {}
+
+  @Override public int getFetchDirection() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setFetchSize(int rows) throws SQLException {}
+
+  @Override public int getFetchSize() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getResultSetConcurrency() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getResultSetType() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void addBatch(String sql) throws SQLException {}
+
+  @Override public void clearBatch() throws SQLException {}
+
+  @Override public int[] executeBatch() throws SQLException {
+    return new int[0];
+  }
+
+  @Override public Connection getConnection() throws SQLException {
+    return AvaticaNoopConnection.getInstance();
+  }
+
+  @Override public boolean getMoreResults(int current) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSet getGeneratedKeys() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    return 1;
+  }
+
+  @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    return 1;
+  }
+
+  @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+    return 1;
+  }
+
+  @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    return true;
+  }
+
+  @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    return true;
+  }
+
+  @Override public boolean execute(String sql, String[] columnNames) throws SQLException {
+    return true;
+  }
+
+  @Override public int getResultSetHoldability() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isClosed() throws SQLException {
+    return false;
+  }
+
+  @Override public void setPoolable(boolean poolable) throws SQLException {}
+
+  @Override public boolean isPoolable() throws SQLException {
+    return true;
+  }
+
+  @Override public void closeOnCompletion() throws SQLException {}
+
+  @Override public boolean isCloseOnCompletion() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet executeQuery() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public int executeUpdate() throws SQLException {
+    return 1;
+  }
+
+  @Override public void setNull(int parameterIndex, int sqlType) throws SQLException {}
+
+  @Override public void setBoolean(int parameterIndex, boolean x) throws SQLException {}
+
+  @Override public void setByte(int parameterIndex, byte x) throws SQLException {}
+
+  @Override public void setShort(int parameterIndex, short x) throws SQLException {}
+
+  @Override public void setInt(int parameterIndex, int x) throws SQLException {}
+
+  @Override public void setLong(int parameterIndex, long x) throws SQLException {}
+
+  @Override public void setFloat(int parameterIndex, float x) throws SQLException {}
+
+  @Override public void setDouble(int parameterIndex, double x) throws SQLException {}
+
+  @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {}
+
+  @Override public void setString(int parameterIndex, String x) throws SQLException {}
+
+  @Override public void setBytes(int parameterIndex, byte[] x) throws SQLException {}
+
+  @Override public void setDate(int parameterIndex, Date x) throws SQLException {}
+
+  @Override public void setTime(int parameterIndex, Time x) throws SQLException {}
+
+  @Override public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {}
+
+  @Override public void setAsciiStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void setBinaryStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void clearParameters() throws SQLException {}
+
+  @Override public void setObject(int parameterIndex, Object x, int targetSqlType)
+      throws SQLException {}
+
+  @Override public void setObject(int parameterIndex, Object x) throws SQLException {}
+
+  @Override public boolean execute() throws SQLException {
+    return false;
+  }
+
+  @Override public void addBatch() throws SQLException {}
+
+  @Override public void setCharacterStream(int parameterIndex, Reader reader, int length)
+      throws SQLException {}
+
+  @Override public void setRef(int parameterIndex, Ref x) throws SQLException {}
+
+  @Override public void setBlob(int parameterIndex, Blob x) throws SQLException {}
+
+  @Override public void setClob(int parameterIndex, Clob x) throws SQLException {}
+
+  @Override public void setArray(int parameterIndex, Array x) throws SQLException {}
+
+  @Override public ResultSetMetaData getMetaData() throws SQLException {
+    return AvaticaNoopResultSetMetaData.getInstance();
+  }
+
+  @Override public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {}
+
+  @Override public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {}
+
+  @Override public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+      throws SQLException {}
+
+  @Override public void setNull(int parameterIndex, int sqlType, String typeName)
+      throws SQLException {}
+
+  @Override public void setURL(int parameterIndex, URL x) throws SQLException {}
+
+  @Override public ParameterMetaData getParameterMetaData() throws SQLException {
+    return AvaticaNoopParameterMetaData.getInstance();
+  }
+
+  @Override public void setRowId(int parameterIndex, RowId x) throws SQLException {}
+
+  @Override public void setNString(int parameterIndex, String value) throws SQLException {}
+
+  @Override public void setNCharacterStream(int parameterIndex, Reader value, long length)
+      throws SQLException {}
+
+  @Override public void setNClob(int parameterIndex, NClob value) throws SQLException {}
+
+  @Override public void setClob(int parameterIndex, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void setBlob(int parameterIndex, InputStream inputStream, long length)
+      throws SQLException {}
+
+  @Override public void setNClob(int parameterIndex, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {}
+
+  @Override public void setObject(int parameterIndex, Object x, int targetSqlType,
+      int scaleOrLength)
+      throws SQLException {}
+
+  @Override public void setAsciiStream(int parameterIndex, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void setBinaryStream(int parameterIndex, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void setCharacterStream(int parameterIndex, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {}
+
+  @Override public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {}
+
+  @Override public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {}
+
+  @Override public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {}
+
+  @Override public void setClob(int parameterIndex, Reader reader) throws SQLException {}
+
+  @Override public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {}
+
+  @Override public void setNClob(int parameterIndex, Reader reader) throws SQLException {}
+}
+
+// End AvaticaNoopPreparedStatement.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
new file mode 100644
index 0000000..2d71184
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
@@ -0,0 +1,661 @@
+/*
+ * 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.noop;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+/**
+ * A {@link ResultSet} implementation which does nothing.
+ */
+public class AvaticaNoopResultSet implements ResultSet {
+
+  private static final AvaticaNoopResultSet INSTANCE = new AvaticaNoopResultSet();
+
+  public static AvaticaNoopResultSet getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopResultSet() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("unsupported");
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean next() throws SQLException {
+    return false;
+  }
+
+  @Override public void close() throws SQLException {}
+
+  @Override public boolean wasNull() throws SQLException {
+    return false;
+  }
+
+  @Override public String getString(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean getBoolean(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public byte getByte(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public short getShort(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getInt(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public long getLong(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public float getFloat(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public double getDouble(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public byte[] getBytes(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Date getDate(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Time getTime(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Timestamp getTimestamp(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getAsciiStream(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getBinaryStream(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getString(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean getBoolean(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public byte getByte(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public short getShort(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getInt(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public long getLong(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public float getFloat(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public double getDouble(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public byte[] getBytes(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Date getDate(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Time getTime(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Timestamp getTimestamp(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getAsciiStream(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public InputStream getBinaryStream(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public SQLWarning getWarnings() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void clearWarnings() throws SQLException {}
+
+  @Override public String getCursorName() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSetMetaData getMetaData() throws SQLException {
+    return AvaticaNoopResultSetMetaData.getInstance();
+  }
+
+  @Override public Object getObject(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Object getObject(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int findColumn(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Reader getCharacterStream(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Reader getCharacterStream(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isBeforeFirst() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isAfterLast() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isFirst() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isLast() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void beforeFirst() throws SQLException {}
+
+  @Override public void afterLast() throws SQLException {}
+
+  @Override public boolean first() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean last() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getRow() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean absolute(int row) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean relative(int rows) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean previous() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setFetchDirection(int direction) throws SQLException {}
+
+  @Override public int getFetchDirection() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setFetchSize(int rows) throws SQLException {}
+
+  @Override public int getFetchSize() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getType() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getConcurrency() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean rowUpdated() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean rowInserted() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean rowDeleted() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void updateNull(int columnIndex) throws SQLException {}
+
+  @Override public void updateBoolean(int columnIndex, boolean x) throws SQLException {}
+
+  @Override public void updateByte(int columnIndex, byte x) throws SQLException {}
+
+  @Override public void updateShort(int columnIndex, short x) throws SQLException {}
+
+  @Override public void updateInt(int columnIndex, int x) throws SQLException {}
+
+  @Override public void updateLong(int columnIndex, long x) throws SQLException {}
+
+  @Override public void updateFloat(int columnIndex, float x) throws SQLException {}
+
+  @Override public void updateDouble(int columnIndex, double x) throws SQLException {}
+
+  @Override public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {}
+
+  @Override public void updateString(int columnIndex, String x) throws SQLException {}
+
+  @Override public void updateBytes(int columnIndex, byte[] x) throws SQLException {}
+
+  @Override public void updateDate(int columnIndex, Date x) throws SQLException {}
+
+  @Override public void updateTime(int columnIndex, Time x) throws SQLException {}
+
+  @Override public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {}
+
+  @Override public void updateAsciiStream(int columnIndex, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void updateBinaryStream(int columnIndex, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void updateCharacterStream(int columnIndex, Reader x, int length)
+      throws SQLException {}
+
+  @Override public void updateObject(int columnIndex, Object x, int scaleOrLength)
+      throws SQLException {}
+
+  @Override public void updateObject(int columnIndex, Object x) throws SQLException {}
+
+  @Override public void updateNull(String columnLabel) throws SQLException {}
+
+  @Override public void updateBoolean(String columnLabel, boolean x) throws SQLException {}
+
+  @Override public void updateByte(String columnLabel, byte x) throws SQLException {}
+
+  @Override public void updateShort(String columnLabel, short x) throws SQLException {}
+
+  @Override public void updateInt(String columnLabel, int x) throws SQLException {}
+
+  @Override public void updateLong(String columnLabel, long x) throws SQLException {}
+
+  @Override public void updateFloat(String columnLabel, float x) throws SQLException {}
+
+  @Override public void updateDouble(String columnLabel, double x) throws SQLException {}
+
+  @Override public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {}
+
+  @Override public void updateString(String columnLabel, String x) throws SQLException {}
+
+  @Override public void updateBytes(String columnLabel, byte[] x) throws SQLException {}
+
+  @Override public void updateDate(String columnLabel, Date x) throws SQLException {}
+
+  @Override public void updateTime(String columnLabel, Time x) throws SQLException {}
+
+  @Override public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {}
+
+  @Override public void updateAsciiStream(String columnLabel, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void updateBinaryStream(String columnLabel, InputStream x, int length)
+      throws SQLException {}
+
+  @Override public void updateCharacterStream(String columnLabel, Reader reader, int length)
+      throws SQLException {}
+
+  @Override public void updateObject(String columnLabel, Object x, int scaleOrLength)
+      throws SQLException {}
+
+  @Override public void updateObject(String columnLabel, Object x) throws SQLException {}
+
+  @Override public void insertRow() throws SQLException {}
+
+  @Override public void updateRow() throws SQLException {}
+
+  @Override public void deleteRow() throws SQLException {}
+
+  @Override public void refreshRow() throws SQLException {}
+
+  @Override public void cancelRowUpdates() throws SQLException {}
+
+  @Override public void moveToInsertRow() throws SQLException {}
+
+  @Override public void moveToCurrentRow() throws SQLException {}
+
+  @Override public Statement getStatement() throws SQLException {
+    return AvaticaNoopStatement.getInstance();
+  }
+
+  @Override public Object getObject(int columnIndex, Map<String, Class<?>> map)
+      throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Ref getRef(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Blob getBlob(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Clob getClob(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Array getArray(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Object getObject(String columnLabel, Map<String, Class<?>> map)
+      throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Ref getRef(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Blob getBlob(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Clob getClob(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Array getArray(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public URL getURL(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public URL getURL(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void updateRef(int columnIndex, Ref x) throws SQLException {}
+
+  @Override public void updateRef(String columnLabel, Ref x) throws SQLException {}
+
+  @Override public void updateBlob(int columnIndex, Blob x) throws SQLException {}
+
+  @Override public void updateBlob(String columnLabel, Blob x) throws SQLException {}
+
+  @Override public void updateClob(int columnIndex, Clob x) throws SQLException {}
+
+  @Override public void updateClob(String columnLabel, Clob x) throws SQLException {}
+
+  @Override public void updateArray(int columnIndex, Array x) throws SQLException {}
+
+  @Override public void updateArray(String columnLabel, Array x) throws SQLException {}
+
+  @Override public RowId getRowId(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public RowId getRowId(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void updateRowId(int columnIndex, RowId x) throws SQLException {}
+
+  @Override public void updateRowId(String columnLabel, RowId x) throws SQLException {}
+
+  @Override public int getHoldability() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isClosed() throws SQLException {
+    return false;
+  }
+
+  @Override public void updateNString(int columnIndex, String nString) throws SQLException {}
+
+  @Override public void updateNString(String columnLabel, String nString) throws SQLException {}
+
+  @Override public void updateNClob(int columnIndex, NClob nClob) throws SQLException {}
+
+  @Override public void updateNClob(String columnLabel, NClob nClob) throws SQLException {}
+
+  @Override public NClob getNClob(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public NClob getNClob(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public SQLXML getSQLXML(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public SQLXML getSQLXML(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {}
+
+  @Override public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {}
+
+  @Override public String getNString(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getNString(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Reader getNCharacterStream(int columnIndex) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public Reader getNCharacterStream(String columnLabel) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void updateNCharacterStream(int columnIndex, Reader x, long length)
+      throws SQLException {}
+
+  @Override public void updateNCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateAsciiStream(int columnIndex, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void updateBinaryStream(int columnIndex, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void updateCharacterStream(int columnIndex, Reader x, long length)
+      throws SQLException {}
+
+  @Override public void updateAsciiStream(String columnLabel, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void updateBinaryStream(String columnLabel, InputStream x, long length)
+      throws SQLException {}
+
+  @Override public void updateCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateBlob(int columnIndex, InputStream inputStream, long length)
+      throws SQLException {}
+
+  @Override public void updateBlob(String columnLabel, InputStream inputStream, long length)
+      throws SQLException {}
+
+  @Override public void updateClob(int columnIndex, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateClob(String columnLabel, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateNClob(int columnIndex, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateNClob(String columnLabel, Reader reader, long length)
+      throws SQLException {}
+
+  @Override public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {}
+
+  @Override public void updateNCharacterStream(String columnLabel, Reader reader)
+      throws SQLException {}
+
+  @Override public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {}
+
+  @Override public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {}
+
+  @Override public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {}
+
+  @Override public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {}
+
+  @Override public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {}
+
+  @Override public void updateCharacterStream(String columnLabel, Reader reader)
+      throws SQLException {}
+
+  @Override public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {}
+
+  @Override public void updateBlob(String columnLabel, InputStream inputStream)
+      throws SQLException {}
+
+  @Override public void updateClob(int columnIndex, Reader reader) throws SQLException {}
+
+  @Override public void updateClob(String columnLabel, Reader reader) throws SQLException {}
+
+  @Override public void updateNClob(int columnIndex, Reader reader) throws SQLException {}
+
+  @Override public void updateNClob(String columnLabel, Reader reader) throws SQLException {}
+
+  @Override public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
+    throw unsupported();
+  }
+
+}
+
+// End AvaticaNoopResultSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
new file mode 100644
index 0000000..ddc8c3b
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
@@ -0,0 +1,133 @@
+/*
+ * 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.noop;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+/**
+ * A {@link ResultSetMetaData} implementation which does nothing.
+ */
+public class AvaticaNoopResultSetMetaData implements ResultSetMetaData {
+
+  private static final AvaticaNoopResultSetMetaData INSTANCE = new AvaticaNoopResultSetMetaData();
+
+  public static AvaticaNoopResultSetMetaData getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopResultSetMetaData() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getColumnCount() throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean isAutoIncrement(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean isCaseSensitive(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean isSearchable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean isCurrency(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public int isNullable(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override public boolean isSigned(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public int getColumnDisplaySize(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override public String getColumnLabel(int column) throws SQLException {
+    return "";
+  }
+
+  @Override public String getColumnName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getSchemaName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getPrecision(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override public int getScale(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override public String getTableName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public String getCatalogName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getColumnType(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override public String getColumnTypeName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isReadOnly(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean isWritable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public boolean isDefinitelyWritable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override public String getColumnClassName(int column) throws SQLException {
+    throw unsupported();
+  }
+
+}
+
+// End AvaticaNoopResultSetMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
new file mode 100644
index 0000000..079cea4
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
@@ -0,0 +1,191 @@
+/*
+ * 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.noop;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+
+/**
+ * A {@link Statement} implementation which does nothing.
+ */
+public class AvaticaNoopStatement implements Statement {
+
+  private static final AvaticaNoopStatement INSTANCE = new AvaticaNoopStatement();
+
+  public static AvaticaNoopStatement getInstance() {
+    return INSTANCE;
+  }
+
+  private AvaticaNoopStatement() {}
+
+  private UnsupportedOperationException unsupported() {
+    return new UnsupportedOperationException("Unsupported");
+  }
+
+  @Override public ResultSet executeQuery(String sql) throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public int executeUpdate(String sql) throws SQLException {
+    return 1;
+  }
+
+  @Override public void close() throws SQLException {}
+
+  @Override public int getMaxFieldSize() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setMaxFieldSize(int max) throws SQLException {}
+
+  @Override public int getMaxRows() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setMaxRows(int max) throws SQLException {}
+
+  @Override public void setEscapeProcessing(boolean enable) throws SQLException {}
+
+  @Override public int getQueryTimeout() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setQueryTimeout(int seconds) throws SQLException {}
+
+  @Override public void cancel() throws SQLException {}
+
+  @Override public SQLWarning getWarnings() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void clearWarnings() throws SQLException {}
+
+  @Override public void setCursorName(String name) throws SQLException {}
+
+  @Override public boolean execute(String sql) throws SQLException {
+    return false;
+  }
+
+  @Override public ResultSet getResultSet() throws SQLException {
+    return AvaticaNoopResultSet.getInstance();
+  }
+
+  @Override public int getUpdateCount() throws SQLException {
+    return 1;
+  }
+
+  @Override public boolean getMoreResults() throws SQLException {
+    return false;
+  }
+
+  @Override public void setFetchDirection(int direction) throws SQLException {}
+
+  @Override public int getFetchDirection() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void setFetchSize(int rows) throws SQLException {}
+
+  @Override public int getFetchSize() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getResultSetConcurrency() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int getResultSetType() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public void addBatch(String sql) throws SQLException {}
+
+  @Override public void clearBatch() throws SQLException {}
+
+  @Override public int[] executeBatch() throws SQLException {
+    return new int[0];
+  }
+
+  @Override public Connection getConnection() throws SQLException {
+    return AvaticaNoopConnection.getInstance();
+  }
+
+  @Override public boolean getMoreResults(int current) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public ResultSet getGeneratedKeys() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    return 1;
+  }
+
+  @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    return 1;
+  }
+
+  @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+    return 1;
+  }
+
+  @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    return true;
+  }
+
+  @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    return true;
+  }
+
+  @Override public boolean execute(String sql, String[] columnNames) throws SQLException {
+    return true;
+  }
+
+  @Override public int getResultSetHoldability() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isClosed() throws SQLException {
+    return false;
+  }
+
+  @Override public void setPoolable(boolean poolable) throws SQLException {}
+
+  @Override public boolean isPoolable() throws SQLException {
+    return true;
+  }
+
+  @Override public void closeOnCompletion() throws SQLException {}
+
+  @Override public boolean isCloseOnCompletion() throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw unsupported();
+  }
+
+  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw unsupported();
+  }
+}
+
+// End AvaticaNoopStatement.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
new file mode 100644
index 0000000..6ae1905
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
@@ -0,0 +1,37 @@
+/*
+ * 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.noop;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is a dummy annotation that forces javac to produce output for
+ * otherwise empty package-info.java.
+ *
+ * <p>The result is maven-compiler-plugin can properly identify the scope of
+ * changed files
+ *
+ * <p>See more details in
+ * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
+ *   maven-compiler-plugin: incremental compilation broken</a>
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface PackageMarker {
+}
+
+// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/package-info.java b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/package-info.java
new file mode 100644
index 0000000..da1c5c4
--- /dev/null
+++ b/avatica/noop-driver/src/main/java/org/apache/calcite/avatica/noop/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * A no-operation implementation of a JDBC driver built for testing Avatica.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.noop;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/src/main/resources/META-INF/services/java.sql.Driver
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/src/main/resources/META-INF/services/java.sql.Driver b/avatica/noop-driver/src/main/resources/META-INF/services/java.sql.Driver
new file mode 100644
index 0000000..24845b0
--- /dev/null
+++ b/avatica/noop-driver/src/main/resources/META-INF/services/java.sql.Driver
@@ -0,0 +1 @@
+org.apache.calcite.avatica.noop.AvaticaNoopDriver


[59/59] calcite git commit: [CALCITE-1123] Get Travis working with a separated Avatica build

Posted by el...@apache.org.
[CALCITE-1123] Get Travis working with a separated Avatica build


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

Branch: refs/heads/master
Commit: 749b236c0ec72b02439403e44b29427e837e6704
Parents: 65f2afa
Author: Josh Elser <el...@apache.org>
Authored: Fri Mar 4 00:55:24 2016 -0500
Committer: Josh Elser <el...@apache.org>
Committed: Mon Mar 7 13:12:03 2016 -0500

----------------------------------------------------------------------
 .travis.yml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/749b236c/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index a88afc2..b63f468 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,8 +27,12 @@ branches:
     - javadoc
     - /^branch-.*$/
     - /^[0-9]+-.*$/
+install:
+  - cd avatica && mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V && cd ..
+  - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
 script:
-  mvn -Dsurefire.useFile=false javadoc:javadoc test
+  - cd avatica && mvn -Dsurefire.useFile=false javadoc:javadoc test && cd ..
+  - mvn -Dsurefire.useFile=false javadoc:javadoc test
 git:
   depth: 10000
 sudo: false


[42/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
new file mode 100644
index 0000000..a5a3852
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/InternalProperty.java
@@ -0,0 +1,109 @@
+/*
+ * 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/blob/5cee486f/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
new file mode 100644
index 0000000..4cc460c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -0,0 +1,1272 @@
+/*
+ * 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 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.ByteString;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+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
+   */
+  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
+      long maxRowCount, PrepareCallback callback) 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
+   */
+  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+      long maxRowCount) 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. */
+  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-set 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. Analogy 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. Analogy to
+   * {@link Connection#rollback()};
+   *
+   * @param ch A reference to the real JDBC Connection.
+   */
+  void rollback(ConnectionHandle ch);
+
+  /** Sync 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);
+
+    public final Class<?> type;
+    public final Object defaultValue;
+    public final Method method;
+
+    <T> DatabaseProperty(T defaultValue) {
+      this.defaultValue = defaultValue;
+      final String methodName = AvaticaUtils.toCamelCase(name());
+      try {
+        this.method = DatabaseMetaData.class.getMethod(methodName);
+      } catch (NoSuchMethodException e) {
+        throw new RuntimeException(e);
+      }
+      this.type = AvaticaUtils.box(method.getReturnType());
+      assert 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;
+    }
+  }
+
+  /** 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") int 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) {
+                columnBuilder.addArrayValue(serializeScalar(listItem));
+              }
+            } else {
+              // The default value, but still explicit.
+              columnBuilder.setHasArrayValue(false);
+              // Only one value for this column, a scalar.
+              columnBuilder.setScalarValue(serializeScalar(element));
+            }
+
+            // 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();
+
+      // 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);
+      } 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(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.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(getScalarValue(columnValue));
+        }
+        return array;
+      } else {
+        return getScalarValue(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(getScalarValue(arrayValue));
+        }
+        return array;
+      } else {
+        // Scalar
+        return getScalarValue(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 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 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() {
+      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. */
+  class ConnectionHandle {
+    public final String id;
+
+    @Override public String toString() {
+      return id;
+    }
+
+    @JsonCreator
+    public ConnectionHandle(@JsonProperty("id") String id) {
+      this.id = id;
+    }
+  }
+
+  /** Statement handle. */
+  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

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
new file mode 100644
index 0000000..7bb99fc
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
@@ -0,0 +1,961 @@
+/*
+ * 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.remote.TypedValue;
+import org.apache.calcite.avatica.util.ArrayIteratorCursor;
+import org.apache.calcite.avatica.util.Cursor;
+import org.apache.calcite.avatica.util.IteratorCursor;
+import org.apache.calcite.avatica.util.ListIteratorCursor;
+import org.apache.calcite.avatica.util.MapIteratorCursor;
+import org.apache.calcite.avatica.util.RecordIteratorCursor;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Basic implementation of {@link Meta}.
+ *
+ * <p>Each sub-class must implement the two remaining abstract methods,
+ * {@link #prepare} and
+ * {@link #prepareAndExecute}.
+ * It should also override metadata methods such as {@link #getCatalogs(Meta.ConnectionHandle)} and
+ * {@link #getTables} for the element types for which it has instances; the
+ * default metadata methods return empty collections.
+ */
+public abstract class MetaImpl implements Meta {
+  /** The {@link AvaticaConnection} backing {@code this}. */
+  protected final AvaticaConnection connection;
+  /** Represents the various states specific to {@link #connection}.
+   *
+   * <p>Note: this instance is used recursively with {@link #connection}'s getter and setter
+   * methods.</p>
+   */
+  protected final ConnectionPropertiesImpl connProps;
+
+  public MetaImpl(AvaticaConnection connection) {
+    this.connection = connection;
+    this.connProps = new ConnectionPropertiesImpl();
+  }
+
+  /** Uses a {@link org.apache.calcite.avatica.Meta.CursorFactory} to convert
+   * an {@link Iterable} into a
+   * {@link org.apache.calcite.avatica.util.Cursor}. */
+  public static Cursor createCursor(CursorFactory cursorFactory,
+      Iterable<Object> iterable) {
+    switch (cursorFactory.style) {
+    case OBJECT:
+      return new IteratorCursor<Object>(iterable.iterator()) {
+        protected Getter createGetter(int ordinal) {
+          return new ObjectGetter(ordinal);
+        }
+      };
+    case ARRAY:
+      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
+          (Iterable<Object[]>) (Iterable) iterable;
+      return new ArrayIteratorCursor(iterable1.iterator());
+    case RECORD:
+      @SuppressWarnings("unchecked") final Class<Object> clazz =
+          cursorFactory.clazz;
+      return new RecordIteratorCursor<Object>(iterable.iterator(), clazz);
+    case RECORD_PROJECTION:
+      @SuppressWarnings("unchecked") final Class<Object> clazz2 =
+          cursorFactory.clazz;
+      return new RecordIteratorCursor<Object>(iterable.iterator(), clazz2,
+          cursorFactory.fields);
+    case LIST:
+      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
+          (Iterable<List<Object>>) (Iterable) iterable;
+      return new ListIteratorCursor(iterable2.iterator());
+    case MAP:
+      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
+          iterable3 =
+          (Iterable<Map<String, Object>>) (Iterable) iterable;
+      return new MapIteratorCursor(iterable3.iterator(),
+          cursorFactory.fieldNames);
+    default:
+      throw new AssertionError("unknown style: " + cursorFactory.style);
+    }
+  }
+
+  public static List<List<Object>> collect(CursorFactory cursorFactory,
+      final Iterator<Object> iterator, List<List<Object>> list) {
+    final Iterable<Object> iterable = new Iterable<Object>() {
+      public Iterator<Object> iterator() {
+        return iterator;
+      }
+    };
+    return collect(cursorFactory, iterable, list);
+  }
+
+  public static List<List<Object>> collect(CursorFactory cursorFactory,
+      Iterable<Object> iterable, final List<List<Object>> list) {
+    switch (cursorFactory.style) {
+    case OBJECT:
+      for (Object o : iterable) {
+        list.add(Collections.singletonList(o));
+      }
+      return list;
+    case ARRAY:
+      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
+          (Iterable<Object[]>) (Iterable) iterable;
+      for (Object[] objects : iterable1) {
+        list.add(Arrays.asList(objects));
+      }
+      return list;
+    case RECORD:
+    case RECORD_PROJECTION:
+      final Field[] fields;
+      switch (cursorFactory.style) {
+      case RECORD:
+        fields = cursorFactory.clazz.getFields();
+        break;
+      default:
+        fields = cursorFactory.fields.toArray(
+            new Field[cursorFactory.fields.size()]);
+      }
+      for (Object o : iterable) {
+        final Object[] objects = new Object[fields.length];
+        for (int i = 0; i < fields.length; i++) {
+          Field field = fields[i];
+          try {
+            objects[i] = field.get(o);
+          } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+          }
+        }
+        list.add(Arrays.asList(objects));
+      }
+      return list;
+    case LIST:
+      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
+          (Iterable<List<Object>>) (Iterable) iterable;
+      for (List<Object> objects : iterable2) {
+        list.add(objects);
+      }
+      return list;
+    case MAP:
+      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
+          iterable3 =
+          (Iterable<Map<String, Object>>) (Iterable) iterable;
+      for (Map<String, Object> map : iterable3) {
+        final List<Object> objects = new ArrayList<Object>();
+        for (String fieldName : cursorFactory.fieldNames) {
+          objects.add(map.get(fieldName));
+        }
+        list.add(objects);
+      }
+      return list;
+    default:
+      throw new AssertionError("unknown style: " + cursorFactory.style);
+    }
+  }
+
+  @Override public void openConnection(ConnectionHandle ch, Map<String, String> info) {
+    // dummy implementation, connection is already created at this point
+  }
+
+  @Override public void closeConnection(ConnectionHandle ch) {
+    // TODO: implement
+    //
+    // lots of Calcite tests break with this simple implementation,
+    // requires investigation
+
+//    try {
+//      connection.close();
+//    } catch (SQLException e) {
+//      throw new RuntimeException(e);
+//    }
+  }
+
+  @Override public ConnectionProperties connectionSync(ConnectionHandle ch,
+      ConnectionProperties connProps) {
+    this.connProps.merge(connProps);
+    this.connProps.setDirty(false);
+    return this.connProps;
+  }
+
+  public StatementHandle createStatement(ConnectionHandle ch) {
+    return new StatementHandle(ch.id, connection.statementCount++, null);
+  }
+
+  /** Creates an empty result set. Useful for JDBC metadata methods that are
+   * not implemented or which query entities that are not supported (e.g.
+   * triggers in Lingual). */
+  protected <E> MetaResultSet createEmptyResultSet(final Class<E> clazz) {
+    return createResultSet(Collections.<String, Object>emptyMap(),
+        fieldMetaData(clazz).columns,
+        CursorFactory.deduce(fieldMetaData(clazz).columns, null),
+        Frame.EMPTY);
+  }
+
+  public static ColumnMetaData columnMetaData(String name, int index,
+      Class<?> type) {
+    TypeInfo pair = TypeInfo.m.get(type);
+    ColumnMetaData.Rep rep =
+        ColumnMetaData.Rep.VALUE_MAP.get(type);
+    ColumnMetaData.AvaticaType scalarType =
+        ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
+    return new ColumnMetaData(
+        index, false, true, false, false,
+        pair.primitive
+            ? DatabaseMetaData.columnNullable
+            : DatabaseMetaData.columnNoNulls,
+        true, -1, name, name, null,
+        0, 0, null, null, scalarType, true, false, false,
+        scalarType.columnClassName());
+  }
+
+  protected static ColumnMetaData.StructType fieldMetaData(Class clazz) {
+    final List<ColumnMetaData> list = new ArrayList<ColumnMetaData>();
+    for (Field field : clazz.getFields()) {
+      if (Modifier.isPublic(field.getModifiers())
+          && !Modifier.isStatic(field.getModifiers())) {
+        list.add(
+            columnMetaData(
+                AvaticaUtils.camelToUpper(field.getName()),
+                list.size() + 1, field.getType()));
+      }
+    }
+    return ColumnMetaData.struct(list);
+  }
+
+  protected MetaResultSet createResultSet(
+      Map<String, Object> internalParameters, List<ColumnMetaData> columns,
+      CursorFactory cursorFactory, Frame firstFrame) {
+    try {
+      final AvaticaStatement statement = connection.createStatement();
+      final Signature signature =
+          new Signature(columns, "", Collections.<AvaticaParameter>emptyList(),
+              internalParameters, cursorFactory, Meta.StatementType.SELECT);
+      return MetaResultSet.create(connection.id, statement.getId(), true,
+          signature, firstFrame);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /** An object that has a name. */
+  public interface Named {
+    @JsonIgnore String getName();
+  }
+
+  /** Metadata describing a column. */
+  public static class MetaColumn implements Named {
+    public final String tableCat;
+    public final String tableSchem;
+    public final String tableName;
+    public final String columnName;
+    public final int dataType;
+    public final String typeName;
+    public final int columnSize;
+    public final String bufferLength = null;
+    public final Integer decimalDigits;
+    public final int numPrecRadix;
+    public final int nullable;
+    public final String remarks = null;
+    public final String columnDef = null;
+    public final String sqlDataType = null;
+    public final String sqlDatetimeSub = null;
+    public final int charOctetLength;
+    public final int ordinalPosition;
+    public final String isNullable;
+    public final String scopeCatalog = null;
+    public final String scopeSchema = null;
+    public final String scopeTable = null;
+    public final String sourceDataType = null;
+    public final String isAutoincrement = null;
+    public final String isGeneratedcolumn = null;
+
+    public MetaColumn(
+        String tableCat,
+        String tableSchem,
+        String tableName,
+        String columnName,
+        int dataType,
+        String typeName,
+        int columnSize,
+        Integer decimalDigits,
+        int numPrecRadix,
+        int nullable,
+        int charOctetLength,
+        int ordinalPosition,
+        String isNullable) {
+      this.tableCat = tableCat;
+      this.tableSchem = tableSchem;
+      this.tableName = tableName;
+      this.columnName = columnName;
+      this.dataType = dataType;
+      this.typeName = typeName;
+      this.columnSize = columnSize;
+      this.decimalDigits = decimalDigits;
+      this.numPrecRadix = numPrecRadix;
+      this.nullable = nullable;
+      this.charOctetLength = charOctetLength;
+      this.ordinalPosition = ordinalPosition;
+      this.isNullable = isNullable;
+    }
+
+    public String getName() {
+      return columnName;
+    }
+  }
+
+  /** Metadata describing a TypeInfo. */
+
+  /** Metadata describing a table. */
+  public static class MetaTable implements Named {
+    public final String tableCat;
+    public final String tableSchem;
+    public final String tableName;
+    public final String tableType;
+    public final String remarks = null;
+    public final String typeCat = null;
+    public final String typeSchem = null;
+    public final String typeName = null;
+    public final String selfReferencingColName = null;
+    public final String refGeneration = null;
+
+    public MetaTable(String tableCat,
+        String tableSchem,
+        String tableName,
+        String tableType) {
+      this.tableCat = tableCat;
+      this.tableSchem = tableSchem;
+      this.tableName = tableName;
+      this.tableType = tableType;
+    }
+
+    public String getName() {
+      return tableName;
+    }
+  }
+
+  /** Metadata describing a schema. */
+  public static class MetaSchema implements Named {
+    public final String tableCatalog;
+    public final String tableSchem;
+
+    public MetaSchema(
+        String tableCatalog,
+        String tableSchem) {
+      this.tableCatalog = tableCatalog;
+      this.tableSchem = tableSchem;
+    }
+
+    public String getName() {
+      return tableSchem;
+    }
+  }
+
+  /** Metadata describing a catalog. */
+  public static class MetaCatalog implements Named {
+    public final String tableCat;
+
+    public MetaCatalog(
+        String tableCatalog) {
+      this.tableCat = tableCatalog;
+    }
+
+    public String getName() {
+      return tableCat;
+    }
+  }
+
+  /** Metadata describing a table type. */
+  public static class MetaTableType {
+    public final String tableType;
+
+    public MetaTableType(String tableType) {
+      this.tableType = tableType;
+    }
+  }
+
+  /** Metadata describing a procedure. */
+  public static class MetaProcedure {
+  }
+
+  /** Metadata describing a procedure column. */
+  public static class MetaProcedureColumn {
+  }
+
+  /** Metadata describing a column privilege. */
+  public static class MetaColumnPrivilege {
+  }
+
+  /** Metadata describing a table privilege. */
+  public static class MetaTablePrivilege {
+  }
+
+  /** Metadata describing the best identifier for a row. */
+  public static class MetaBestRowIdentifier {
+  }
+
+  /** Metadata describing a version column. */
+  public static class MetaVersionColumn {
+    public final short scope;
+    public final String columnName;
+    public final int dataType;
+    public final String typeName;
+    public final int columnSize;
+    public final int bufferLength;
+    public final short decimalDigits;
+    public final short pseudoColumn;
+
+    MetaVersionColumn(short scope, String columnName, int dataType,
+        String typeName, int columnSize, int bufferLength, short decimalDigits,
+        short pseudoColumn) {
+      this.scope = scope;
+      this.columnName = columnName;
+      this.dataType = dataType;
+      this.typeName = typeName;
+      this.columnSize = columnSize;
+      this.bufferLength = bufferLength;
+      this.decimalDigits = decimalDigits;
+      this.pseudoColumn = pseudoColumn;
+    }
+  }
+
+  /** Metadata describing a primary key. */
+  public static class MetaPrimaryKey {
+    public final String tableCat;
+    public final String tableSchem;
+    public final String tableName;
+    public final String columnName;
+    public final short keySeq;
+    public final String pkName;
+
+    MetaPrimaryKey(String tableCat, String tableSchem, String tableName,
+        String columnName, short keySeq, String pkName) {
+      this.tableCat = tableCat;
+      this.tableSchem = tableSchem;
+      this.tableName = tableName;
+      this.columnName = columnName;
+      this.keySeq = keySeq;
+      this.pkName = pkName;
+    }
+  }
+
+  /** Metadata describing an imported key. */
+  public static class MetaImportedKey {
+  }
+
+  /** Metadata describing an exported key. */
+  public static class MetaExportedKey {
+  }
+
+  /** Metadata describing a cross reference. */
+  public static class MetaCrossReference {
+  }
+
+  /** Metadata describing type info. */
+  public static class MetaTypeInfo implements Named {
+    public final String typeName;
+    public final int dataType;
+    public final int precision;
+    public final String literalPrefix;
+    public final String literalSuffix;
+    //TODO: Add create parameter for type on DDL
+    public final String createParams = null;
+    public final int nullable;
+    public final boolean caseSensitive;
+    public final int searchable;
+    public final boolean unsignedAttribute;
+    public final boolean fixedPrecScale;
+    public final boolean autoIncrement;
+    public final String localTypeName;
+    public final int minimumScale;
+    public final int maximumScale;
+    public final int sqlDataType = 0;
+    public final int sqlDatetimeSub = 0;
+    public final Integer numPrecRadix; //nullable int
+
+    public MetaTypeInfo(
+        String typeName,
+        int dataType,
+        int precision,
+        String literalPrefix,
+        String literalSuffix,
+        int nullable,
+        boolean caseSensitive,
+        int searchable,
+        boolean unsignedAttribute,
+        boolean fixedPrecScale,
+        boolean autoIncrement,
+        int minimumScale,
+        int maximumScale,
+        int numPrecRadix) {
+      this.typeName = typeName;
+      this.dataType = dataType;
+      this.precision = precision;
+      this.literalPrefix = literalPrefix;
+      this.literalSuffix = literalSuffix;
+      this.nullable = nullable;
+      this.caseSensitive = caseSensitive;
+      this.searchable = searchable;
+      this.unsignedAttribute = unsignedAttribute;
+      this.fixedPrecScale = fixedPrecScale;
+      this.autoIncrement = autoIncrement;
+      this.localTypeName = typeName;
+      // Make min to be 0 instead of -1
+      this.minimumScale = minimumScale == -1 ? 0 : minimumScale;
+      this.maximumScale = maximumScale == -1 ? 0 : maximumScale;
+      this.numPrecRadix = numPrecRadix == 0 ? null : numPrecRadix;
+    }
+
+    public String getName() {
+      return typeName;
+    }
+  }
+
+  /** Metadata describing index info. */
+  public static class MetaIndexInfo {
+  }
+
+  /** Metadata describing a user-defined type. */
+  public static class MetaUdt {
+  }
+
+  /** Metadata describing a super-type. */
+  public static class MetaSuperType {
+  }
+
+  /** Metadata describing an attribute. */
+  public static class MetaAttribute {
+  }
+
+  /** Metadata describing a client info property. */
+  public static class MetaClientInfoProperty {
+  }
+
+  /** Metadata describing a function. */
+  public static class MetaFunction {
+  }
+
+  /** Metadata describing a function column. */
+  public static class MetaFunctionColumn {
+  }
+
+  /** Metadata describing a pseudo column. */
+  public static class MetaPseudoColumn {
+  }
+
+  /** Metadata describing a super-table. */
+  public static class MetaSuperTable {
+  }
+
+  public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
+    return Collections.emptyMap();
+  }
+
+  public MetaResultSet getTables(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat tableNamePattern,
+      List<String> typeList) {
+    return createEmptyResultSet(MetaTable.class);
+  }
+
+  public MetaResultSet getColumns(ConnectionHandle ch, String catalog,
+      Pat schemaPattern,
+      Pat tableNamePattern,
+      Pat columnNamePattern) {
+    return createEmptyResultSet(MetaColumn.class);
+  }
+
+  public MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat schemaPattern) {
+    return createEmptyResultSet(MetaSchema.class);
+  }
+
+  public MetaResultSet getCatalogs(ConnectionHandle ch) {
+    return createEmptyResultSet(MetaCatalog.class);
+  }
+
+  public MetaResultSet getTableTypes(ConnectionHandle ch) {
+    return createEmptyResultSet(MetaTableType.class);
+  }
+
+  public MetaResultSet getProcedures(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat procedureNamePattern) {
+    return createEmptyResultSet(MetaProcedure.class);
+  }
+
+  public MetaResultSet getProcedureColumns(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat procedureNamePattern,
+      Pat columnNamePattern) {
+    return createEmptyResultSet(MetaProcedureColumn.class);
+  }
+
+  public MetaResultSet getColumnPrivileges(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table,
+      Pat columnNamePattern) {
+    return createEmptyResultSet(MetaColumnPrivilege.class);
+  }
+
+  public MetaResultSet getTablePrivileges(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat tableNamePattern) {
+    return createEmptyResultSet(MetaTablePrivilege.class);
+  }
+
+  public MetaResultSet getBestRowIdentifier(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table,
+      int scope,
+      boolean nullable) {
+    return createEmptyResultSet(MetaBestRowIdentifier.class);
+  }
+
+  public MetaResultSet getVersionColumns(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table) {
+    return createEmptyResultSet(MetaVersionColumn.class);
+  }
+
+  public MetaResultSet getPrimaryKeys(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table) {
+    return createEmptyResultSet(MetaPrimaryKey.class);
+  }
+
+  public MetaResultSet getImportedKeys(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table) {
+    return createEmptyResultSet(MetaImportedKey.class);
+  }
+
+  public MetaResultSet getExportedKeys(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table) {
+    return createEmptyResultSet(MetaExportedKey.class);
+  }
+
+  public MetaResultSet getCrossReference(ConnectionHandle ch,
+      String parentCatalog,
+      String parentSchema,
+      String parentTable,
+      String foreignCatalog,
+      String foreignSchema,
+      String foreignTable) {
+    return createEmptyResultSet(MetaCrossReference.class);
+  }
+
+  public MetaResultSet getTypeInfo(ConnectionHandle ch) {
+    return createEmptyResultSet(MetaTypeInfo.class);
+  }
+
+  public MetaResultSet getIndexInfo(ConnectionHandle ch,
+      String catalog,
+      String schema,
+      String table,
+      boolean unique,
+      boolean approximate) {
+    return createEmptyResultSet(MetaIndexInfo.class);
+  }
+
+  public MetaResultSet getUDTs(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat typeNamePattern,
+      int[] types) {
+    return createEmptyResultSet(MetaUdt.class);
+  }
+
+  public MetaResultSet getSuperTypes(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat typeNamePattern) {
+    return createEmptyResultSet(MetaSuperType.class);
+  }
+
+  public MetaResultSet getSuperTables(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat tableNamePattern) {
+    return createEmptyResultSet(MetaSuperTable.class);
+  }
+
+  public MetaResultSet getAttributes(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat typeNamePattern,
+      Pat attributeNamePattern) {
+    return createEmptyResultSet(MetaAttribute.class);
+  }
+
+  public MetaResultSet getClientInfoProperties(ConnectionHandle ch) {
+    return createEmptyResultSet(MetaClientInfoProperty.class);
+  }
+
+  public MetaResultSet getFunctions(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat functionNamePattern) {
+    return createEmptyResultSet(MetaFunction.class);
+  }
+
+  public MetaResultSet getFunctionColumns(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat functionNamePattern,
+      Pat columnNamePattern) {
+    return createEmptyResultSet(MetaFunctionColumn.class);
+  }
+
+  public MetaResultSet getPseudoColumns(ConnectionHandle ch,
+      String catalog,
+      Pat schemaPattern,
+      Pat tableNamePattern,
+      Pat columnNamePattern) {
+    return createEmptyResultSet(MetaPseudoColumn.class);
+  }
+
+  @Override public Iterable<Object> createIterable(StatementHandle handle, QueryState state,
+      Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
+    if (firstFrame != null && firstFrame.done) {
+      return firstFrame.rows;
+    }
+    AvaticaStatement stmt;
+    try {
+      stmt = connection.lookupStatement(handle);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+    return new FetchIterable(stmt, state,
+        firstFrame, parameterValues);
+  }
+
+  public Frame fetch(AvaticaStatement stmt, List<TypedValue> parameterValues,
+      long offset, int fetchMaxRowCount) throws NoSuchStatementException, MissingResultsException {
+    return null;
+  }
+
+  /** Information about a type. */
+  private static class TypeInfo {
+    private static Map<Class<?>, TypeInfo> m =
+        new HashMap<Class<?>, TypeInfo>();
+    static {
+      put(boolean.class, true, Types.BOOLEAN, "BOOLEAN");
+      put(Boolean.class, false, Types.BOOLEAN, "BOOLEAN");
+      put(byte.class, true, Types.TINYINT, "TINYINT");
+      put(Byte.class, false, Types.TINYINT, "TINYINT");
+      put(short.class, true, Types.SMALLINT, "SMALLINT");
+      put(Short.class, false, Types.SMALLINT, "SMALLINT");
+      put(int.class, true, Types.INTEGER, "INTEGER");
+      put(Integer.class, false, Types.INTEGER, "INTEGER");
+      put(long.class, true, Types.BIGINT, "BIGINT");
+      put(Long.class, false, Types.BIGINT, "BIGINT");
+      put(float.class, true, Types.FLOAT, "FLOAT");
+      put(Float.class, false, Types.FLOAT, "FLOAT");
+      put(double.class, true, Types.DOUBLE, "DOUBLE");
+      put(Double.class, false, Types.DOUBLE, "DOUBLE");
+      put(String.class, false, Types.VARCHAR, "VARCHAR");
+      put(java.sql.Date.class, false, Types.DATE, "DATE");
+      put(Time.class, false, Types.TIME, "TIME");
+      put(Timestamp.class, false, Types.TIMESTAMP, "TIMESTAMP");
+    }
+
+    private final boolean primitive;
+    private final int sqlType;
+    private final String sqlTypeName;
+
+    public TypeInfo(boolean primitive, int sqlType, String sqlTypeName) {
+      this.primitive = primitive;
+      this.sqlType = sqlType;
+      this.sqlTypeName = sqlTypeName;
+    }
+
+    static void put(Class clazz, boolean primitive, int sqlType,
+        String sqlTypeName) {
+      m.put(clazz, new TypeInfo(primitive, sqlType, sqlTypeName));
+    }
+  }
+
+  /** Iterator that never returns any elements. */
+  private static class EmptyIterator implements Iterator<Object> {
+    public static final Iterator<Object> INSTANCE = new EmptyIterator();
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+
+    public boolean hasNext() {
+      return false;
+    }
+
+    public Object next() {
+      throw new NoSuchElementException();
+    }
+  }
+
+  /** Iterable that yields an iterator over rows coming from a sequence of
+   * {@link Meta.Frame}s. */
+  private class FetchIterable implements Iterable<Object> {
+    private final AvaticaStatement stmt;
+    private final QueryState state;
+    private final Frame firstFrame;
+    private final List<TypedValue> parameterValues;
+
+    public FetchIterable(AvaticaStatement stmt, QueryState state, Frame firstFrame,
+        List<TypedValue> parameterValues) {
+      this.stmt = stmt;
+      this.state = state;
+      this.firstFrame = firstFrame;
+      this.parameterValues = parameterValues;
+    }
+
+    public Iterator<Object> iterator() {
+      return new FetchIterator(stmt, state, firstFrame, parameterValues);
+    }
+  }
+
+  /** Iterator over rows coming from a sequence of {@link Meta.Frame}s. */
+  private class FetchIterator implements Iterator<Object> {
+    private final AvaticaStatement stmt;
+    private final QueryState state;
+    private Frame frame;
+    private Iterator<Object> rows;
+    private List<TypedValue> parameterValues;
+    private List<TypedValue> originalParameterValues;
+    private long currentOffset = 0;
+
+    public FetchIterator(AvaticaStatement stmt, QueryState state, Frame firstFrame,
+        List<TypedValue> parameterValues) {
+      this.stmt = stmt;
+      this.state = state;
+      this.parameterValues = parameterValues;
+      this.originalParameterValues = parameterValues;
+      if (firstFrame == null) {
+        frame = Frame.MORE;
+        rows = EmptyIterator.INSTANCE;
+      } else {
+        frame = firstFrame;
+        rows = firstFrame.rows.iterator();
+      }
+      moveNext();
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException("remove");
+    }
+
+    public boolean hasNext() {
+      return rows != null;
+    }
+
+    public Object next() {
+      if (rows == null) {
+        throw new NoSuchElementException();
+      }
+      final Object o = rows.next();
+      currentOffset++;
+      moveNext();
+      return o;
+    }
+
+    private void moveNext() {
+      for (;;) {
+        if (rows.hasNext()) {
+          break;
+        }
+        if (frame.done) {
+          rows = null;
+          break;
+        }
+        try {
+          // currentOffset updated after element is read from `rows` iterator
+          frame = fetch(stmt.handle, currentOffset, AvaticaStatement.DEFAULT_FETCH_SIZE);
+        } catch (NoSuchStatementException e) {
+          resetStatement();
+          // re-fetch the batch where we left off
+          continue;
+        } catch (MissingResultsException e) {
+          try {
+            // We saw the statement, but it didnt' have a resultset initialized. So, reset it.
+            if (!stmt.syncResults(state, currentOffset)) {
+              // This returned false, so there aren't actually any more results to iterate over
+              frame = null;
+              rows = null;
+              break;
+            }
+            // syncResults returning true means we need to fetch those results
+          } catch (NoSuchStatementException e1) {
+            // Tried to reset the result set, but lost the statement, save a loop before retrying.
+            resetStatement();
+            // Will just loop back around to a MissingResultsException, but w/e recursion
+          }
+          // Kick back to the top to try to fetch again (in both branches)
+          continue;
+        }
+        parameterValues = null; // don't execute next time
+        if (frame == null) {
+          rows = null;
+          break;
+        }
+        // It is valid for rows to be empty, so we go around the loop again to
+        // check
+        rows = frame.rows.iterator();
+      }
+    }
+
+    private void resetStatement() {
+      // If we have to reset the statement, we need to reset the parameterValues too
+      parameterValues = originalParameterValues;
+      // Defer to the statement to reset itself
+      stmt.resetStatement();
+    }
+  }
+
+  /** Returns whether a list of parameter values has any null elements. */
+  public static boolean checkParameterValueHasNull(List<TypedValue> parameterValues) {
+    for (TypedValue x : parameterValues) {
+      if (x == null) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+// End MetaImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/MissingResultsException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
new file mode 100644
index 0000000..7746769
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.Meta.StatementHandle;
+
+import java.sql.ResultSet;
+
+/**
+ * An Exception which denotes that a cached Statement is present but has no {@link ResultSet}.
+ */
+public class MissingResultsException extends Exception {
+
+  private static final long serialVersionUID = 1L;
+
+  private final StatementHandle handle;
+
+  public MissingResultsException(StatementHandle handle) {
+    this.handle = handle;
+  }
+
+  public StatementHandle getHandle() {
+    return handle;
+  }
+}
+
+// End MissingResultsException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
new file mode 100644
index 0000000..b5a940d
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * An Exception that denotes that the given Connection is not cached.
+ */
+public class NoSuchConnectionException extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+  private final String connectionId;
+
+  public NoSuchConnectionException(String connectionId) {
+    this.connectionId = connectionId;
+  }
+
+  public String getConnectionId() {
+    return connectionId;
+  }
+}
+
+// End NoSuchConnectionException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
new file mode 100644
index 0000000..321011b
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.Meta.StatementHandle;
+
+/**
+ * An Exception that denotes that the given Statement is not cached.
+ */
+public class NoSuchStatementException extends Exception {
+
+  private static final long serialVersionUID = 1L;
+
+  private final StatementHandle stmtHandle;
+
+  public NoSuchStatementException(StatementHandle stmtHandle) {
+    this.stmtHandle = stmtHandle;
+  }
+
+  public StatementHandle getStatementHandle() {
+    return stmtHandle;
+  }
+}
+
+// End NoSuchStatementException.java


[18/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_gridism.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_gridism.scss b/avatica/site/_sass/_gridism.scss
new file mode 100644
index 0000000..40d2163
--- /dev/null
+++ b/avatica/site/_sass/_gridism.scss
@@ -0,0 +1,124 @@
+/*
+ * Gridism
+ * A simple, responsive, and handy CSS grid by @cobyism
+ * https://github.com/cobyism/gridism
+ */
+
+/* Preserve some sanity */
+.grid,
+.unit {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+/* Set up some rules to govern the grid */
+.grid {
+  display: block;
+  clear: both;
+}
+.grid .unit {
+  float: left;
+  width: 100%;
+  padding: 10px;
+}
+
+/* This ensures the outer gutters are equal to the (doubled) inner gutters. */
+.grid .unit:first-child { padding-left: 20px; }
+.grid .unit:last-child { padding-right: 20px; }
+
+/* Nested grids already have padding though, so let’s nuke it */
+.unit .unit:first-child { padding-left: 0; }
+.unit .unit:last-child { padding-right: 0; }
+.unit .grid:first-child > .unit { padding-top: 0; }
+.unit .grid:last-child > .unit { padding-bottom: 0; }
+
+/* Let people nuke the gutters/padding completely in a couple of ways */
+.no-gutters .unit,
+.unit.no-gutters {
+  padding: 0 !important;
+}
+
+/* Wrapping at a maximum width is optional */
+.wrap .grid,
+.grid.wrap {
+  max-width: 978px;
+  margin: 0 auto;
+}
+
+/* Width classes also have shorthand versions numbered as fractions
+ * For example: for a grid unit 1/3 (one third) of the parent width,
+ * simply apply class="w-1-3" to the element. */
+.grid .whole,          .grid .w-1-1 { width: 100%; }
+.grid .half,           .grid .w-1-2 { width: 50%; }
+.grid .one-third,      .grid .w-1-3 { width: 33.3332%; }
+.grid .two-thirds,     .grid .w-2-3 { width: 66.6665%; }
+.grid .one-quarter,
+.grid .one-fourth,     .grid .w-1-4 { width: 25%; }
+.grid .three-quarters,
+.grid .three-fourths,  .grid .w-3-4 { width: 75%; }
+.grid .one-fifth,      .grid .w-1-5 { width: 20%; }
+.grid .two-fifths,     .grid .w-2-5 { width: 40%; }
+.grid .three-fifths,   .grid .w-3-5 { width: 60%; }
+.grid .four-fifths,    .grid .w-4-5 { width: 80%; }
+.grid .golden-small,   .grid .w-g-s { width: 38.2716%; } /* Golden section: smaller piece */
+.grid .golden-large,   .grid .w-g-l { width: 61.7283%; } /* Golden section: larger piece */
+
+/* Clearfix after every .grid */
+.grid {
+  *zoom: 1;
+}
+.grid:before, .grid:after {
+  display: table;
+  content: "";
+  line-height: 0;
+}
+.grid:after {
+  clear: both;
+}
+
+/* Utility classes */
+.align-center { text-align: center; }
+.align-left   { text-align: left; }
+.align-right  { text-align: right; }
+.pull-left    { float: left; }
+.pull-right   { float: right; }
+
+/* A property for a better rendering of images in units: in
+   this way bigger pictures are just resized if the unit
+   becomes smaller */
+.unit img {
+  max-width: 100%;
+}
+
+/* Responsive Stuff */
+@media screen and (max-width: 568px) {
+  /* Stack anything that isn’t full-width on smaller screens
+     and doesn't provide the no-stacking-on-mobiles class */
+  .grid:not(.no-stacking-on-mobiles) > .unit {
+    width: 100% !important;
+    padding-left: 20px;
+    padding-right: 20px;
+  }
+  .unit .grid .unit {
+    padding-left: 0px;
+    padding-right: 0px;
+  }
+
+  /* Sometimes, you just want to be different on small screens */
+  .center-on-mobiles {
+    text-align: center !important;
+  }
+  .hide-on-mobiles {
+    display: none !important;
+  }
+}
+
+/* Expand the wrap a bit further on larger screens */
+@media screen and (min-width: 1180px) {
+  .wider .grid,
+  .grid.wider {
+    max-width: 1180px;
+    margin: 0 auto;
+  }
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_mixins.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_mixins.scss b/avatica/site/_sass/_mixins.scss
new file mode 100644
index 0000000..5b9bb43
--- /dev/null
+++ b/avatica/site/_sass/_mixins.scss
@@ -0,0 +1,38 @@
+@mixin box-shadow($shadow...) {
+  -webkit-box-shadow: $shadow;
+     -moz-box-shadow: $shadow;
+          box-shadow: $shadow;
+}
+
+@mixin border-radius($radius...) {
+  -webkit-border-radius: $radius;
+     -moz-border-radius: $radius;
+          border-radius: $radius;
+}
+
+@mixin border-top-left-radius($radius...) {
+  -webkit-border-top-left-radius: $radius;
+     -moz-border-radius-topleft:  $radius;
+          border-top-left-radius: $radius;
+}
+
+@mixin border-top-right-radius($radius...) {
+  -webkit-border-top-right-radius: $radius;
+     -moz-border-radius-topright:  $radius;
+          border-top-right-radius: $radius;
+}
+
+@mixin transition($transition...) {
+  -webkit-transition: $transition;
+     -moz-transition: $transition;
+       -o-transition: $transition;
+          transition: $transition;
+}
+
+@mixin user-select($select...) {
+  -webkit-user-select: $select;    /* Chrome all / Safari all */
+     -moz-user-select: $select;    /* Firefox all */
+      -ms-user-select: $select;    /* IE 10+ */
+       -o-user-select: $select;
+          user-select: $select;
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_normalize.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_normalize.scss b/avatica/site/_sass/_normalize.scss
new file mode 100644
index 0000000..f6e0b65
--- /dev/null
+++ b/avatica/site/_sass/_normalize.scss
@@ -0,0 +1 @@
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{
 color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_pygments.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_pygments.scss b/avatica/site/_sass/_pygments.scss
new file mode 100644
index 0000000..2858bcd
--- /dev/null
+++ b/avatica/site/_sass/_pygments.scss
@@ -0,0 +1,78 @@
+.highlight {
+  .hll { background-color: #ffffcc }
+  .c { color: #87ceeb} /* Comment */
+  .err { color: #ffffff} /* Error */
+  .g { color: #ffffff} /* Generic */
+  .k { color: #f0e68c} /* Keyword */
+  .l { color: #ffffff} /* Literal */
+  .n { color: #ffffff} /* Name */
+  .o { color: #ffffff} /* Operator */
+  .x { color: #ffffff} /* Other */
+  .p { color: #ffffff} /* Punctuation */
+  .cm { color: #87ceeb} /* Comment.Multiline */
+  .cp { color: #cd5c5c} /* Comment.Preproc */
+  .c1 { color: #87ceeb} /* Comment.Single */
+  .cs { color: #87ceeb} /* Comment.Special */
+  .gd { color: #0000c0; font-weight: bold; background-color: #008080 } /* Generic.Deleted */
+  .ge { color: #c000c0; text-decoration: underline} /* Generic.Emph */
+  .gr { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Error */
+  .gh { color: #cd5c5c} /* Generic.Heading */
+  .gi { color: #ffffff; background-color: #0000c0 } /* Generic.Inserted */
+  span.go { color: #add8e6; font-weight: bold; background-color: #4d4d4d } /* Generic.Output, qualified with span to prevent applying this style to the Go language, see #1153. */
+  .gp { color: #ffffff} /* Generic.Prompt */
+  .gs { color: #ffffff} /* Generic.Strong */
+  .gu { color: #cd5c5c} /* Generic.Subheading */
+  .gt { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Traceback */
+  .kc { color: #f0e68c} /* Keyword.Constant */
+  .kd { color: #f0e68c} /* Keyword.Declaration */
+  .kn { color: #f0e68c} /* Keyword.Namespace */
+  .kp { color: #f0e68c} /* Keyword.Pseudo */
+  .kr { color: #f0e68c} /* Keyword.Reserved */
+  .kt { color: #bdb76b} /* Keyword.Type */
+  .ld { color: #ffffff} /* Literal.Date */
+  .m { color: #ffffff} /* Literal.Number */
+  .s { color: #ffffff} /* Literal.String */
+  .na { color: #ffffff} /* Name.Attribute */
+  .nb { color: #ffffff} /* Name.Builtin */
+  .nc { color: #ffffff} /* Name.Class */
+  .no { color: #ffa0a0} /* Name.Constant */
+  .nd { color: #ffffff} /* Name.Decorator */
+  .ni { color: #ffdead} /* Name.Entity */
+  .ne { color: #ffffff} /* Name.Exception */
+  .nf { color: #ffffff} /* Name.Function */
+  .nl { color: #ffffff} /* Name.Label */
+  .nn { color: #ffffff} /* Name.Namespace */
+  .nx { color: #ffffff} /* Name.Other */
+  .py { color: #ffffff} /* Name.Property */
+  .nt { color: #f0e68c} /* Name.Tag */
+  .nv { color: #98fb98} /* Name.Variable */
+  .ow { color: #ffffff} /* Operator.Word */
+  .w { color: #ffffff} /* Text.Whitespace */
+  .mf { color: #ffffff} /* Literal.Number.Float */
+  .mh { color: #ffffff} /* Literal.Number.Hex */
+  .mi { color: #ffffff} /* Literal.Number.Integer */
+  .mo { color: #ffffff} /* Literal.Number.Oct */
+  .sb { color: #ffffff} /* Literal.String.Backtick */
+  .sc { color: #ffffff} /* Literal.String.Char */
+  .sd { color: #ffffff} /* Literal.String.Doc */
+  .s2 { color: #ffffff} /* Literal.String.Double */
+  .se { color: #ffffff} /* Literal.String.Escape */
+  .sh { color: #ffffff} /* Literal.String.Heredoc */
+  .si { color: #ffffff} /* Literal.String.Interpol */
+  .sx { color: #ffffff} /* Literal.String.Other */
+  .sr { color: #ffffff} /* Literal.String.Regex */
+  .s1 { color: #ffffff} /* Literal.String.Single */
+  .ss { color: #ffffff} /* Literal.String.Symbol */
+  .bp { color: #ffffff} /* Name.Builtin.Pseudo */
+  .vc { color: #98fb98} /* Name.Variable.Class */
+  .vg { color: #98fb98} /* Name.Variable.Global */
+  .vi { color: #98fb98} /* Name.Variable.Instance */
+  .il { color: #ffffff} /* Literal.Number.Integer.Long */
+  .bash .nv {
+    -webkit-user-select: none;
+       -moz-user-select: none;
+        -ms-user-select: none;
+         -o-user-select: none;
+            user-select: none;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_style.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_style.scss b/avatica/site/_sass/_style.scss
new file mode 100644
index 0000000..14d9723
--- /dev/null
+++ b/avatica/site/_sass/_style.scss
@@ -0,0 +1,989 @@
+/* Base */
+
+* {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+body {
+  font: 300 21px Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  color: #ddd;
+  background-color: #333;
+  border-top: 5px solid #33adff;
+  @include box-shadow(inset 0 3px 30px rgba(0,0,0,.3));
+  text-shadow: 0 1px 3px rgba(0,0,0,.5);
+  -webkit-font-feature-settings: "kern" 1;
+  -moz-font-feature-settings: "kern" 1;
+  -o-font-feature-settings: "kern" 1;
+  font-feature-settings: "kern" 1;
+  font-kerning: normal;
+}
+
+.clear {
+  display: block;
+}
+
+.clear:after {
+  content: " ";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+/* Sections */
+
+header,
+section,
+footer {
+  float: left;
+  width: 100%;
+  clear: both;
+}
+
+/* Header */
+
+header {
+
+  h1,
+  nav { display: inline-block; }
+
+}
+
+nav {
+
+  ul {
+    padding: 0;
+    margin: 0;
+  }
+
+  li { display: inline-block; }
+}
+
+.main-nav {
+  margin-top: 52px;
+
+  li {
+    margin-right: 10px;
+
+    a {
+      @include border-radius(5px);
+      font-weight: 900;
+      font-size: 14px;
+      padding: 0.5em 1em;
+      text-shadow: none;
+      text-transform: uppercase;
+      @include transition(all .25s);
+
+      &:hover {
+        background-color: #252525;
+        @include box-shadow(inset 0 1px 3px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.1));
+        text-shadow: 0 1px 3px rgba(0,0,0,.5);
+      }
+    }
+
+    &.current {
+
+      a {
+        background-color: #33adff;
+        color: #222;
+        @include box-shadow(inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5));
+        text-shadow: 0 1px 0 rgba(255,255,255,.3);
+      }
+    }
+  }
+}
+
+.mobile-nav {
+
+  ul {
+    overflow: hidden;
+    width: 100%;
+    display: table;
+  }
+
+  a {
+    float: left;
+    width: 100%;
+    background-color: #333;
+    color: #33adff;
+    text-align: center;
+    text-transform: uppercase;
+    font-size: 14px;
+    font-weight: 900;
+    padding: 5px;
+    @include border-radius(5px);
+  }
+
+  li {
+    display: table-cell;
+    width: 20%;
+    padding: 8px 2px;
+  }
+
+  .current {
+
+    a {
+      background-color: #33adff;
+      color: #222;
+      @include box-shadow(inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5));
+      text-shadow: 0 1px 0 rgba(255,255,255,.3);
+    }
+  }
+}
+
+/*
+ * This code is courtesy Ben Balter, modified by Parker Moore.
+ * http://ben.balter.com/2014/03/13/pages-anchor-links/
+ */
+.header-link {
+  position: relative;
+  left: 0.5em;
+  opacity: 0;
+  font-size: 0.8em;
+  @include transition(opacity 0.2s ease-in-out 0.1s);
+}
+h2:hover .header-link,
+h3:hover .header-link,
+h4:hover .header-link,
+h5:hover .header-link,
+h6:hover .header-link {
+  opacity: 1;
+}
+
+@media (max-width: 768px) {
+  .main-nav ul {
+    text-align: right;
+  }
+}
+@media (max-width: 830px) {
+  .main-nav {
+    .show-on-mobiles { display: inline; }
+    .hide-on-mobiles { display: none; }
+  }
+}
+
+/* Footer */
+
+footer {
+  background-color: #212121;
+  font-size: 16px;
+  padding-bottom: 5px;
+  padding-left: 5px;
+  padding-right: 5px;
+  color: #c0c0c0;
+  margin-top: 40px;
+
+  a {
+    color: #fff;
+
+    &:hover {
+
+      img { opacity: 1; }
+    }
+  }
+
+  .align-right {
+
+    p { display: inline-block; }
+  }
+
+  img {
+    display: inline-block;
+    position: relative;
+    top: 8px;
+    margin-left: 5px;
+    opacity: .8;
+    padding: 1px;
+    @include transition(opacity .2s);
+  }
+}
+
+@media (max-width: 568px) {
+  footer {
+    .one-third p { margin-bottom: 0; }
+    .two-thirds p { margin-top: -20px; }
+  }
+}
+
+/* Intro */
+
+.intro {
+
+  .unit { padding: 10px 0 40px; }
+
+  p {
+    font-size: 1.75em;
+    line-height: 1em;
+    margin: 0;
+  }
+}
+
+@media (min-width: 569px) {
+  .intro p { font-size: 3.2em; }
+}
+
+/* Quickstart */
+
+.quickstart {
+  background-color: #3F1F1F;
+  color: #fff;
+  margin: 60px 0;
+  @include box-shadow(inset 0 3px 10px rgba(0,0,0,.4));
+
+  .content { padding: 0; }
+
+  h3 {
+    font-size: 24px;
+    line-height: 24px;
+    margin-top: 20px;
+    text-shadow: 0 1px 3px rgba(0,0,0,.8);
+  }
+
+  .code {
+    font-size: 12px;
+    display: block;
+    margin: 0 0 -30px;
+  }
+}
+
+@media (min-width: 768px) {
+  .quickstart {
+
+    .code {
+      font-size: 18px;
+      margin: -30px 0;
+      float: right;
+    }
+
+    h3 {
+      margin: 50px 0 0;
+      text-align: center;
+    }
+  }
+}
+
+/* Code */
+
+.quickstart {
+
+  .code {
+    display: block;
+    padding: 0;
+    font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
+    line-height: 1.3em;
+
+    .title {
+      display: block;
+      text-align: center;
+      margin: 0 20px;
+      padding: 5px 0;
+      @include border-radius(5px 5px 0 0);
+      @include box-shadow(0 3px 10px rgba(0,0,0,.5));
+      font: 400 16px/24px 'Helvetica Neue', Helvetica, Arial, sans-serif;
+      color: #444;
+      text-shadow: 0 1px 0 rgba(255,255,255,.5);
+      background-color: #f7f7f7;
+      background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y3ZjdmNyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjY2ZjZmNmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
+      background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), color-stop(7%, #cfcfcf), to(#aaaaaa));
+      background-image: -webkit-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%);
+      background-image: -moz-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%);
+      background-image: -o-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%);
+      background-image: linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
+      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#aaaaaa',GradientType=0 );
+      border-bottom: 1px solid #111;
+    }
+
+    .shell {
+      padding: 20px;
+      text-shadow: none;
+      margin: 0 20px;
+      background-color: #171717;
+      @include border-radius(0 0 5px 5px);
+      @include box-shadow(0 5px 30px rgba(0,0,0,.3));
+    }
+
+    .line {
+      display: block;
+      margin: 0;
+      padding: 0;
+
+      span { display: inline-block; }
+    }
+
+    .path {
+      color: #87ceeb;
+      @include user-select(none);
+    }
+
+    .prompt {
+      color: #cd5c5c;
+      -webkit-user-select: none;  /* Chrome all / Safari all */
+      -moz-user-select: none;     /* Firefox all */
+      -ms-user-select: none;      /* IE 10+ */
+      -o-user-select: none;
+      user-select: none;
+    }
+
+    .command { color: #f0e68c; }
+
+    .output { color: #888; }
+  }
+}
+
+@media (min-width: 768px) {
+  .free-hosting {
+
+    img {
+      float: left;
+      margin: -20px -30px -30px -50px;
+      width: 300px;
+      height: 251px;
+    }
+
+    .pane-content {
+      margin-top: 35px;
+      padding-right: 30px;
+    }
+
+    p,
+    a { font-size: 18px; }
+
+    .pane:after {
+      content: " ";
+      float: right;
+      background: url(../img/footer-arrow.png) top left no-repeat;
+      width: 73px;
+      height: 186px;
+      position: absolute;
+      right: 0;
+      bottom: -30px;
+    }
+  }
+}
+
+/* Article - Used for both docs and news */
+
+
+article {
+  background-color: #444;
+  @include border-radius(10px);
+  padding: 20px;
+  margin: 0 10px;
+  @include box-shadow(0 3px 10px rgba(0,0,0,.1));
+  font-size: 16px;
+}
+
+@media (max-width: 480px) {
+  article ul { padding-left: 20px; }
+}
+
+@media (max-width: 568px) {
+  article { margin: 0; }
+}
+
+@media (min-width: 768px) {
+  article {
+    padding: 40px 40px 30px;
+    font-size: 21px;
+  }
+}
+
+/* Right-side nav - used by both docs and news */
+
+aside {
+  padding-top: 30px;
+
+  h4 {
+    text-transform: uppercase;
+    font-size: 14px;
+    font-weight: 700;
+    padding: 0 0 10px 30px;
+    margin-left: -30px;
+    display: inline-block;
+    border-bottom: 1px solid #ff0;
+  }
+
+  ul {
+    padding-left: 0;
+
+    &:first-child { margin-top: 0; }
+  }
+
+  li {
+    list-style-type: none;
+
+    a {
+      font-size: 16px;
+      position: relative
+    }
+
+    &.current a:before {
+      content: "";
+      border-color: transparent transparent transparent #444;
+      border-style: solid;
+      border-width: 10px;
+      width: 0;
+      height: 0;
+      position: absolute;
+      top: 0;
+      left: -30px;
+    }
+  }
+}
+
+/* Documentation */
+
+.docs {
+
+  article { min-height: 800px; }
+
+  .content { padding: 0; }
+}
+
+.section-nav {
+  text-align: center;
+  padding-top: 40px;
+  position: relative;
+  background: url(../img/article-footer.png) top center no-repeat;
+  margin: 40px -20px 10px;
+
+  > div { width: 49.5%; }
+
+  a,
+  span {
+    color: #fff;
+    font-size: 16px;
+    text-transform: uppercase;
+    font-weight: 700;
+    padding: 8px 12px 10px;
+    @include border-radius(5px);
+    /*border: 1px solid #333;*/
+    @include box-shadow(0 1px 3px rgba(0,0,0,.3), inset 0 1px 1px rgba(255,255,255,.5));
+    background-color: #767676;
+  }
+
+  a:hover {
+    color: #fff;
+    background-color: #888;
+  }
+
+  .next,
+  .prev { position: relative; }
+
+  .next:after,
+  .prev:before {
+    font-size: 36px;
+    color: #222;
+    font-weight: 900;
+    text-shadow: 0 1px 0 rgba(255,255,255,.4);
+    position: absolute;
+    top: -7px;
+  }
+
+  .next:after {
+    content: '\203A';
+    right: 10px;
+  }
+
+  .prev:before {
+    content: '\2039';
+    left: 10px;
+  }
+
+  .prev,
+  .prev:hover { padding-left: 30px; }
+
+  .next,
+  .next:hover { padding-right: 30px; }
+
+  .disabled {
+    opacity: .5;
+    cursor: default;
+  }
+}
+
+.improve {
+  padding-top: 25px;
+  font-size: 16px;
+  a {
+    color: #999;
+  }
+}
+
+.docs-nav-mobile select {
+  color: #000;
+  width: 100%;
+}
+
+/* News */
+
+article h2:first-child { margin-top: 0; }
+
+.post-category,
+.post-meta {
+  display: inline-block;
+  vertical-align: middle;
+  font-size: .8em;
+}
+
+.post-category {
+  display: inline-block;
+  margin-left: -30px;
+  padding: 6px 10px 8px;
+  padding-left: 50px;
+  @include border-radius(0 5px 5px 0);
+  position: relative;
+  @include box-shadow(0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3));
+  background-color: #9e2812;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2ZjBkMGQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9e2812), to(#6f0d0d));
+  background-image: -webkit-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: -o-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 );
+
+  &:before {
+    content: "";
+    position: absolute;
+    top: -10px;
+    left: 0;
+    border-color: transparent #6f0d0d #6f0d0d transparent;
+    border-style: solid;
+    border-width: 5px;
+    width: 0;
+    height: 0;
+  }
+}
+
+.post-content img { max-width: 100% }
+
+.label {
+  float: left;
+  text-transform: uppercase;
+  font-weight: 700;
+  text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+@media (max-width: 568px) {
+  .post-category { padding-left: 30px; }
+}
+
+@media (min-width: 768px) {
+  .post-category { margin-left: -50px; }
+}
+
+.avatar {
+  @include border-radius(3px);
+  display: inline-block;
+  vertical-align: middle;
+}
+
+.post-meta {
+  padding: 5px 0;
+  color: #c0c0c0;
+  font-weight: 600;
+  text-shadow: 0 -1px 0 #000;
+}
+
+.post-date,
+.post-author { margin-left: 10px; }
+
+.news article + article {
+  margin-top: -10px;
+  @include border-radius(0 0 10px 10px);
+  border-top: 1px solid #555;
+  @include box-shadow(0 -1px 0 #2f2f2f);
+}
+
+/* Code Highlighting */
+
+
+pre,
+code {
+  white-space: pre;
+  display: inline-block;
+  margin: 0;
+  font: 14px/1.8em Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
+  padding: 0 0.5em;
+}
+
+@media (min-width: 768px) {
+  pre, code { font-size: 16px; }
+}
+
+.highlight,
+p > pre,
+p > code,
+p > nobr > code,
+li > code,
+h5 > code,
+.note > code {
+  background-color: #2b2b2b;
+  color: #fff;
+  @include border-radius(5px);
+  @include box-shadow(inset 0 1px 10px rgba(0,0,0,.3),
+    0 1px 0 rgba(255,255,255,.1),
+    0 -1px 0 rgba(0,0,0,.5));
+}
+
+.note code {
+  background-color: #333;
+  background-color: rgba(0,0,0,0.2);
+  margin-left: 2.5px;
+  margin-right: 2.5px;
+  font-size: 0.8em;
+}
+
+.highlight {
+  margin: 1em 0;
+  padding: 10px 0;
+  width: 100%;
+  overflow: auto;
+}
+
+/* HTML Elements */
+
+h1, h2, h3, h4, h5, h6 { margin: 0; }
+
+a {
+  color: #33adff;
+  text-decoration: none;
+  @include transition(all .25s);
+
+  &:hover { color: #33adff; }
+}
+
+strong { font-weight: 700; }
+
+p { line-height: 1.5em; }
+
+.left { float: left; }
+.right { float: right; }
+.align-right { text-align: right; }
+.align-left { text-align: left; }
+.align-center { text-align: center; }
+
+/* Article HTML */
+
+article {
+
+  h2, h3, h4, h5, h6 { margin: 1em 0; }
+
+  h4 { color: #fff; }
+
+  ul li {
+
+    p { margin: 0; }
+
+    blockquote { margin: 10px 0; }
+  }
+
+  ul li,
+  ol li {
+    line-height: 1.5em;
+    margin-bottom: 0.5em;
+  }
+
+}
+
+h5, h6 {
+  font-size: 1em;
+  font-style: italic;
+}
+
+blockquote {
+  border-left: 2px solid #777;
+  padding-left: 20px;
+  font-style: italic;
+  font-size: 18px;
+  font-weight: 500;
+}
+
+
+/* Tables */
+
+table {
+  width: 100%;
+  background-color: #555;
+  margin: .5em 0;
+  @include border-radius(5px);
+  @include box-shadow(0 1px 3px rgba(0,0,0,.3));
+}
+
+thead {
+  @include border-top-left-radius(5px);
+  @include border-top-right-radius(5px);
+  color: #fff;
+  background-color: #3a3a3a;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzNhM2EzYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxZTFlMWUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#3a3a3a), to(#1e1e1e));
+  background-image: -webkit-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%);
+  background-image: -moz-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%);
+  background-image: -o-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%);
+  background-image: linear-gradient(to bottom, #3a3a3a 0%,#1e1e1e 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a3a3a', endColorstr='#1e1e1e',GradientType=0 );
+
+  th {
+    position: relative;
+    @include box-shadow(inset 0 1px 0 rgba(255,255,255,.1));
+
+    &:first-child {
+      @include border-top-left-radius(5px);
+    }
+
+    &:last-child {
+      @include border-top-right-radius(5px);
+    }
+  }
+}
+
+td { padding: .5em .75em; }
+
+td p { margin: 0; }
+
+th {
+  text-transform: uppercase;
+  font-size: 16px;
+  padding: .5em .75em;
+  text-shadow: 0 -1px 0 rgba(0,0,0,.9);
+  color: #888;
+}
+
+tbody td {
+  border-top: 1px solid #747474;
+  border-top: 1px solid rgba(0,0,0,.1);
+  @include box-shadow(inset 0 1px 0 rgba(255,255,255,.1));
+  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0.1)), to(rgba(255,255,255,0)));
+  background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
+  background-image: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
+  background-image: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
+  background-image: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1affffff', endColorstr='#00ffffff',GradientType=0 );
+
+  p {
+    font-size: 16px;
+
+    code { font-size: 14px; }
+  }
+}
+
+code.option,
+th .option,
+code.filter,
+th .filter {
+  color: #50B600;
+}
+
+code.flag,
+th .flag,
+code.output,
+th .output {
+  color: #049DCE;
+}
+
+code.option,
+code.flag,
+code.filter,
+code.output {
+  margin-bottom: 2px;
+}
+
+/* Note types */
+
+.note {
+  margin: 30px 0;
+  margin-left: -30px;
+  padding: 20px 20px 24px;
+  padding-left: 50px;
+  @include border-radius(0 5px 5px 0);
+  position: relative;
+  @include box-shadow(0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3));
+  background-color: #7e6d42;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdlNmQ0MiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM1YzRlMzUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7e6d42), to(#5c4e35));
+  background-image: -webkit-linear-gradient(top, #7e6d42 0%, #5c4e35 100%);
+  background-image: -moz-linear-gradient(top, #7e6d42 0%, #5c4e35 100%);
+  background-image: -o-linear-gradient(top, #7e6d42 0%, #5c4e35 100%);
+  background-image: linear-gradient(to bottom, #7e6d42 0%,#5c4e35 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7e6d42', endColorstr='#5c4e35',GradientType=0 );
+}
+
+@media (max-width: 568px) {
+  .note { margin-right: -30px; }
+}
+
+@media (min-width: 768px) {
+  .note { margin-left: -50px; }
+}
+
+.configtable {
+    font-size: 14px;
+}
+
+.note {
+  &:before {
+    content: "";
+    position: absolute;
+    top: -10px;
+    left: 0;
+    border-color: transparent #222 #222 transparent;
+    border-style: solid;
+    border-width: 5px;
+    width: 0;
+    height: 0;
+  }
+
+  h5,
+  p {
+    margin: 0;
+    color: #fff;
+  }
+
+  h5 {
+    line-height: 1.5em;
+    font-weight: 900;
+    font-style: normal;
+  }
+
+  p {
+    font-weight: 400;
+    font-size: .75em;
+  }
+
+  &:after {
+    content: '\2605';
+    color: #33adff;
+    position: absolute;
+    top: 14px;
+    left: 14px;
+    font-size: 28px;
+    font-weight: 700;
+    text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+  }
+}
+
+.info {
+  background-color: #0389aa;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAzODlhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDYxN2YiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#0389aa), to(#00617f));
+  background-image: -webkit-linear-gradient(top, #0389aa 0%, #00617f 100%);
+  background-image: -moz-linear-gradient(top, #0389aa 0%, #00617f 100%);
+  background-image: -o-linear-gradient(top, #0389aa 0%, #00617f 100%);
+  background-image: linear-gradient(to bottom, #0389aa 0%,#00617f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0389aa', endColorstr='#00617f',GradientType=0 );
+}
+
+.warning {
+  background-color: #9e2812;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2ZjBkMGQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9e2812), to(#6f0d0d));
+  background-image: -webkit-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: -o-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+  background-image: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 );
+}
+
+.unreleased {
+  background-color: #cd9239;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2NkOTIzOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNhMjc1MjgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(205,146,57,1)), to(rgba(162,117,40,1)));
+  background-image: -webkit-linear-gradient(top, rgba(205,146,57,1) 0%, rgba(162,117,40,1) 100%);
+  background-image: -moz-linear-gradient(top, rgba(205,146,57,1) 0%, rgba(162,117,40,1) 100%);
+  background-image: -o-linear-gradient(top, rgba(205,146,57,1) 0%, rgba(162,117,40,1) 100%);
+  background-image: linear-gradient(to bottom, rgba(205,146,57,1) 0%,rgba(162,117,40,1) 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cd9239', endColorstr='#a27528',GradientType=0 );
+}
+
+.info:before { border-color: transparent #00617f #00617f transparent; }
+
+.warning:before { border-color: transparent #6f0d0d #6f0d0d transparent; }
+
+.unreleased:before { border-color: transparent #664719 #664719 transparent; }
+
+.info:after {
+  content: '\24D8';
+  color: #fff;
+  position: absolute;
+  top: 15px;
+  left: 15px;
+  font-size: 28px;
+  font-weight: 700;
+  text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+.warning:after {
+  content: '\203C';
+  color: #33adff;
+  position: absolute;
+  top: 15px;
+  left: 15px;
+  font-size: 32px;
+  font-weight: 700;
+  text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+.unreleased:after {
+  content: '\2692';
+  color: #2b2a12;
+  position: absolute;
+  top: 8px;
+  left: 15px;
+  font-size: 38px;
+  font-weight: 700;
+  text-shadow: 0 1px 0 rgba(255,255,255,.25);
+}
+
+/* Responsive tables */
+
+@media (max-width: 768px) {
+  .mobile-side-scroller {
+    overflow-x: scroll;
+    margin: 0 -40px;
+    padding: 0 10px;
+  }
+}
+
+
+.show-on-mobiles {
+  display: none;
+}
+
+@media screen and (max-width: 568px) {
+  .show-on-mobiles {
+    display: block !important;
+  }
+  a .show-on-mobiles {
+    display: inline !important;
+  }
+}
+
+
+/* Helper class taken from Bootstrap.
+   Hides an element to all devices except screen readers.
+*/
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  border: 0;
+}
+
+#poweredby {
+  float: right;
+  text-align: right;
+  width: 200px;
+  height: 87px;
+}
+
+#resources {
+  background-color: #000;
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/community/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/community/index.md b/avatica/site/community/index.md
new file mode 100644
index 0000000..b0c9fdb
--- /dev/null
+++ b/avatica/site/community/index.md
@@ -0,0 +1,116 @@
+---
+layout: page
+title: Community
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+* TOC
+{:toc}
+
+# Project Members
+
+Name (Apache ID) | Github | Org | Role
+:--------------- | :----- | :-- | :---
+{% for c in site.data.contributors %}  {{ c.name }} (<a href="http://people.apache.org/committer-index#{{ c.apacheId }}">{{ c.apacheId }}</a>) | <a href="http://github.com/{{ c.githubId }}"><img width="64" src="{% unless c.avatar %}http://github.com/{{ c.githubId }}.png{% else %}{{ c.avatar }}{% endunless %}"></a> | {{ c.org }} | {{ c.role }}
+{% endfor %}
+
+# Mailing Lists
+
+There are several development mailing lists for Calcite:
+
+* [dev@calcite.apache.org](mailto:dev@calcite.apache.org) - Development discussions
+  [[archive](https://mail-archives.apache.org/mod_mbox/calcite-dev/)]
+* [issues@calcite.apache.org](mailto:issues@calcite.apache.org) - Bug tracking
+  [[archive](https://mail-archives.apache.org/mod_mbox/calcite-issues/)]
+* [commits@calcite.apache.org](mailto:commits@calcite.apache.org) - Git tracking
+  [[archive](https://mail-archives.apache.org/mod_mbox/calcite-commits/)]
+
+You can subscribe to the lists by sending email to
+*list*-subscribe@calcite.apache.org and unsubscribe by sending email to
+*list*-unsubscribe@calcite.apache.org.
+
+# Help
+
+Need help with Calcite? Try these resources:
+
+* **Mailing Lists**.
+  The best option is to send email to the developers list
+  [dev@calcite.apache.org](mailto:dev@calcite.apache.org). All
+  of the historic traffic is available in the
+  [archive](http://mail-archives.apache.org/mod_mbox/calcite-dev/). To
+  subscribe to the user list, please send email to
+  [dev-subscribe@calcite.apache.org](mailto:dev-subscribe@calcite.apache.org).
+* **Bug Reports**.
+  Please file any issues you encounter or fixes you'd like on the
+  [Calcite Jira](https://issues.apache.org/jira/browse/CALCITE). We welcome
+  patches!
+* **StackOverflow**.
+  [StackOverflow](http://stackoverflow.com) is a wonderful resource for
+  any developer. Take a look over there to see if someone has answered
+  your question.
+* **Browse the code**.
+  One of the advantages of open source software is that you can browse the code.
+  The code is available on [github](https://github.com/apache/calcite/tree/master).
+
+# Talks
+
+Want to learn more about Calcite?
+
+Watch some presentations and read through some slide decks about Calcite.
+
+## Apache Calcite: One planner fits all
+
+Voted [Best Lightning Talk at XLDB-2015](http://www.xldb.org/archives/2015/05/best-lightning-talks-selected/);
+[[video](https://www.youtube.com/watch?v=5_MyORYjq3w)],
+[[slides](http://www.slideshare.net/julianhyde/apache-calcite-one-planner-fits-all)].
+
+{% oembed https://www.youtube.com/watch?v=5_MyORYjq3w %}
+
+## Why you care about relational algebra (even though you didn't know it)
+
+Washington DC, April 2015;
+[[slides](http://www.slideshare.net/julianhyde/calcite-algebraedw2015)].
+
+<iframe src="//www.slideshare.net/slideshow/embed_code/key/vfVDu6y1mAM5Dl" width="629" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
+
+## Apache Calcite overview
+
+Apache Kylin meetup, 2014;
+[[slides](http://www.slideshare.net/julianhyde/apache-calcite-overview)].
+
+<iframe src="//www.slideshare.net/slideshow/embed_code/key/fCGsAedsQiq53V" width="629" height="354" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
+
+## Streaming SQL
+
+At Samza meetup, Mountain View, CA, 2016
+[[video](http://www.ustream.tv/recorded/83322450#to00:55:48)],
+[[slides](http://www.slideshare.net/julianhyde/streaming-sql)].
+
+<iframe src="//www.slideshare.net/slideshow/embed_code/key/rzaptOy3H8K6Gz" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
+
+## More talks
+
+* <a href="https://github.com/julianhyde/share/blob/master/slides/hive-cbo-seattle-2014.pdf?raw=true">Cost-based optimization in Hive 0.14</a> (Seattle, 2014)
+* <a href="https://github.com/julianhyde/share/blob/master/slides/dmmq-summit-2014.pdf?raw=true">Discardable, in-memory materialized query for Hadoop</a> (<a href="https://www.youtube.com/watch?v=CziGOa8GXqI">video</a>) (Hadoop Summit, 2014)
+* <a href="https://github.com/julianhyde/share/blob/master/slides/hive-cbo-summit-2014.pdf?raw=true">Cost-based optimization in Hive</a> (<a href="https://www.youtube.com/watch?v=vpG5noIbEFs">video</a>) (Hadoop Summit, 2014)
+* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-nosql-now-2013.pdf?raw=true">SQL Now!</a> (NoSQL Now! conference, 2013)
+* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-richrelevance-2013.pdf?raw=true">SQL on Big Data using Optiq</a> (2013)
+* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-drill-user-group-2013.pdf?raw=true">Drill / SQL / Optiq</a> (2013)
+* <a href="http://www.slideshare.net/julianhyde/how-to-integrate-splunk-with-any-data-solution">How to integrate Splunk with any data solution</a> (Splunk User Conference, 2012)

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/css/screen.scss
----------------------------------------------------------------------
diff --git a/avatica/site/css/screen.scss b/avatica/site/css/screen.scss
new file mode 100644
index 0000000..2eff7f8
--- /dev/null
+++ b/avatica/site/css/screen.scss
@@ -0,0 +1,9 @@
+---
+---
+
+@import "mixins";
+@import "normalize";
+@import "gridism";
+@import "pygments";
+@import "font-awesome";
+@import "style";

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/develop/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/develop/index.md b/avatica/site/develop/index.md
new file mode 100644
index 0000000..c2b11f3
--- /dev/null
+++ b/avatica/site/develop/index.md
@@ -0,0 +1,117 @@
+---
+layout: page
+title: Developing Calcite
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Want to help add a feature or fix a bug?
+
+* TOC
+{:toc}
+
+## Source code
+
+You can get the source code by
+[downloading a release]({{ site.baseurl }}/downloads)
+or from source control.
+
+Calcite uses git for version control.  The canonical source is in
+[Apache](https://git-wip-us.apache.org/repos/asf/calcite.git),
+but most people find the
+[Github mirror](https://github.com/apache/calcite) more
+user-friendly.
+
+## Download source, build, and run tests
+
+Prerequisites are git, maven (3.2.1 or later) and Java (JDK 1.7 or
+later, 1.8 preferred) on your path.
+
+Create a local copy of the git repository, `cd` to its root directory,
+then build using maven:
+
+{% highlight bash %}
+$ git clone git://github.com/apache/calcite.git
+$ cd calcite
+$ mvn install
+{% endhighlight %}
+
+The HOWTO describes how to
+[build from a source distribution]({{ site.baseurl }}/docs/howto.html#building-from-a-source-distribution),
+[run more or fewer tests]({{ site.baseurl }}/docs/howto.html#running-tests) and
+[run integration tests]({{ site.baseurl }}/docs/howto.html#running-integration-tests).
+
+## Contributing
+
+We welcome contributions.
+
+If you are planning to make a large contribution, talk to us first! It
+helps to agree on the general approach. Log a
+[JIRA case](https://issues.apache.org/jira/browse/CALCITE) for your
+proposed feature or start a discussion on the dev list.
+
+Fork the github repository, and create a branch for your feature.
+
+Develop your feature and test cases, and make sure that
+`mvn install` succeeds. (Run extra tests if your change warrants it.)
+
+Commit your change to your branch, and use a comment that starts with
+the JIRA case number, like this:
+
+{% highlight text %}
+[CALCITE-345] AssertionError in RexToLixTranslator comparing to date literal
+{% endhighlight %}
+
+If your change had multiple commits, use `git rebase -i master` to
+squash them into a single commit, and to bring your code up to date
+with the latest on the main line.
+
+Then push your commit(s) to github, and create a pull request from
+your branch to the calcite master branch. Update the JIRA case
+to reference your pull request, and a committer will review your
+changes.
+
+## Continuous Integration Testing
+
+Calcite has a collection of Jenkins jobs on ASF-hosted infrastructure.
+They are all organized in a single view and available at
+[https://builds.apache.org/view/A-D/view/Calcite/](https://builds.apache.org/view/A-D/view/Calcite/).
+
+## Getting started
+
+Calcite is a community, so the first step to joining the project is to introduce yourself.
+Join the [developers list](http://mail-archives.apache.org/mod_mbox/calcite-dev/)
+and send an email.
+
+If you have the chance to attend a [meetup](http://www.meetup.com/Apache-Calcite/),
+or meet [members of the community](http://calcite.apache.org/develop/#project-members)
+at a conference, that's also great.
+
+Choose an initial task to work on. It should be something really simple,
+such as a bug fix or a [Jira task that we have labeled
+"newbie"](https://issues.apache.org/jira/issues/?jql=labels%20%3D%20newbie%20%26%20project%20%3D%20Calcite%20%26%20status%20%3D%20Open).
+Follow the [contributing guidelines](#contributing) to get your change committed.
+
+After you have made several useful contributions we may
+[invite you to become a committer](https://community.apache.org/contributors/).
+We value all contributions that help to build a vibrant community, not just code.
+You can contribute by testing the code, helping verify a release,
+writing documentation or the web site,
+or just by answering questions on the list.
+

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/doap_calcite.rdf
----------------------------------------------------------------------
diff --git a/avatica/site/doap_calcite.rdf b/avatica/site/doap_calcite.rdf
new file mode 100644
index 0000000..46204e9
--- /dev/null
+++ b/avatica/site/doap_calcite.rdf
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl"?>
+<rdf:RDF xml:lang="en"
+         xmlns="http://usefulinc.com/ns/doap#"
+         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:asfext="http://projects.apache.org/ns/asfext#"
+         xmlns:foaf="http://xmlns.com/foaf/0.1/">
+<!--
+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.
+-->
+  <Project rdf:about="https://calcite.apache.org">
+    <created>2015-05-27</created>
+    <license rdf:resource="http://spdx.org/licenses/Apache-2.0" />
+    <name>Apache Calcite</name>
+    <homepage rdf:resource="https://calcite.apache.org" />
+    <asfext:pmc rdf:resource="https://calcite.apache.org" />
+    <shortdesc>A dynamic data management framework.</shortdesc>
+    <description>Calcite is a framework for writing data management
+      systems.  It converts queries, represented in relational algebra,
+      into an efficient executable form using pluggable query
+      transformation rules. There is an optional SQL parser and JDBC
+      driver. Calcite does not store data or have a preferred execution
+      engine. Data formats, execution algorithms, planning rules,
+      operator types, metadata, and cost model are added at runtime as
+      plugins.</description>
+    <bug-database rdf:resource="https://issues.apache.org/jira/browse/CALCITE" />
+    <mailing-list rdf:resource="https://calcite.apache.org/develop" />
+    <download-page rdf:resource="https://calcite.apache.org/downloads" />
+    <programming-language>Java</programming-language>
+    <category rdf:resource="http://projects.apache.org/category/big-data" />
+    <category rdf:resource="http://projects.apache.org/category/hadoop" />
+    <category rdf:resource="http://projects.apache.org/category/sql" />
+    <repository>
+      <GitRepository>
+        <location rdf:resource="https://git-wip-us.apache.org/repos/asf/calcite.git"/>
+        <browse rdf:resource="https://github.com/apache/calcite"/>
+      </GitRepository>
+    </repository>
+    <maintainer>
+      <foaf:Person>
+        <foaf:name>Julian Hyde</foaf:name>
+          <foaf:mbox rdf:resource="mailto:jhyde@apache.org"/>
+      </foaf:Person>
+    </maintainer>
+  </Project>
+</rdf:RDF>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/downloads/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/downloads/index.md b/avatica/site/downloads/index.md
new file mode 100644
index 0000000..7faead0
--- /dev/null
+++ b/avatica/site/downloads/index.md
@@ -0,0 +1,100 @@
+---
+layout: page
+title: Downloads
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Calcite is released as a source artifact, and also through Maven.
+
+# Source releases
+
+Release          | Date       | Commit   | Download
+:--------------- | :--------- | :------- | :-------
+{% for post in site.categories.release %}{% comment %}
+{% endcomment %}{% if post.fullVersion %}{% comment %}
+{% endcomment %}{% assign v = post.fullVersion %}{% comment %}
+{% endcomment %}{% else %}{% comment %}
+{% endcomment %}{% capture v %}apache-calcite-{{ post.version }}{% endcapture %}{% comment %}
+{% endcomment %}{% endif %}{% comment %}
+{% endcomment %}{% if forloop.index0 < 1 %}{% comment %}
+{% endcomment %}{% capture p %}http://www.apache.org/dyn/closer.lua?filename=calcite/{{ v }}{% endcapture %}{% comment %}
+{% endcomment %}{% assign q = "&action=download" %}{% comment %}
+{% endcomment %}{% assign d = "https://www.apache.org/dist" %}{% comment %}
+{% endcomment %}{% elsif forloop.rindex < 8 %}{% comment %}
+{% endcomment %}{% capture p %}http://archive.apache.org/dist/incubator/calcite/{{ v }}{% endcapture %}{% comment %}
+{% endcomment %}{% assign q = "" %}{% comment %}
+{% endcomment %}{% assign d = "https://archive.apache.org/dist/incubator" %}{% comment %}
+{% endcomment %}{% else %}{% comment %}
+{% endcomment %}{% capture p %}http://archive.apache.org/dist/calcite/{{ v }}{% endcapture %}{% comment %}
+{% endcomment %}{% assign q = "" %}{% comment %}
+{% endcomment %}{% assign d = "https://archive.apache.org/dist" %}{% comment %}
+{% endcomment %}{% endif %}{% comment %}
+{% endcomment %}<a href="{{ site.baseurl }}/docs/history.html#{{ post.tag }}">{{ post.version }}</a>{% comment %}
+{% endcomment %} | {{ post.date | date_to_string }}{% comment %}
+{% endcomment %} | <a href="https://github.com/apache/calcite/commit/{{ post.sha }}">{{ post.sha }}</a>{% comment %}
+{% endcomment %} | <a href="{{ p }}/{{ v }}-src.tar.gz{{ q }}">tar</a>{% comment %}
+{% endcomment %} (<a href="{{ d }}/calcite/{{ v }}/{{ v }}-src.tar.gz.md5">md5</a>{% comment %}
+{% endcomment %} <a href="{{ d }}/calcite/{{ v }}/{{ v }}-src.tar.gz.asc">pgp</a>){% comment %}
+{% endcomment %} {% raw %}<br>{% endraw %}{% comment %}
+{% endcomment %} <a href="{{ p }}/{{ v }}-src.zip{{ q }}">zip</a>{% comment %}
+{% endcomment %} (<a href="{{ d }}/calcite/{{ v }}/{{ v }}-src.zip.md5">md5</a>{% comment %}
+{% endcomment %} <a href="{{ d }}/calcite/{{ v }}/{{ v }}-src.zip.asc">pgp</a>){% comment %}
+{% endcomment %}
+{% endfor %}
+
+Choose a source distribution in either *tar* or *zip* format,
+and [verify](http://www.apache.org/dyn/closer.cgi#verify)
+using the corresponding *pgp* signature (using the committer file in
+[KEYS](http://www.apache.org/dist/calcite/KEYS)).
+If you cannot do that, the *md5* hash file may be used to check that the
+download has completed OK.
+
+For fast downloads, current source distributions are hosted on mirror servers;
+older source distributions are in the
+[archive](http://archive.apache.org/dist/calcite/)
+or [incubator archive](http://archive.apache.org/dist/incubator/calcite/).
+If a download from a mirror fails, retry, and the second download will likely
+succeed.
+
+For security, hash and signature files are always hosted at
+[Apache](https://www.apache.org/dist).
+
+# Maven artifacts
+
+Add the following to the dependencies section of your `pom.xml` file:
+
+{% for post in site.categories.release limit:1 %}
+{% assign current_release = post %}
+{% endfor %}
+
+{% highlight xml %}
+<dependencies>
+  <dependency>
+    <groupId>org.apache.calcite</groupId>
+    <artifactId>calcite-core</artifactId>
+    <version>{{ current_release.version }}</version>
+  </dependency>
+</dependencies>
+{% endhighlight %}
+
+Also include `<dependency>` elements for any extension modules you
+need: `calcite-mongodb`, `calcite-spark`, `calcite-splunk`, and so
+forth.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/favicon.ico
----------------------------------------------------------------------
diff --git a/avatica/site/favicon.ico b/avatica/site/favicon.ico
new file mode 100644
index 0000000..47d4618
Binary files /dev/null and b/avatica/site/favicon.ico differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/avatica/site/fonts/fontawesome-webfont.eot b/avatica/site/fonts/fontawesome-webfont.eot
new file mode 100755
index 0000000..84677bc
Binary files /dev/null and b/avatica/site/fonts/fontawesome-webfont.eot differ


[35/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
new file mode 100644
index 0000000..5790848
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -0,0 +1,2771 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaClientRuntimeException;
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.BuiltInConnectionProperty;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.QueryState;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.proto.Responses;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.HBaseZeroCopyByteString;
+import com.google.protobuf.Message;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Properties;
+
+/**
+ * API for request-response calls to an Avatica server.
+ */
+public interface Service {
+  ResultSetResponse apply(CatalogsRequest request);
+  ResultSetResponse apply(SchemasRequest request);
+  ResultSetResponse apply(TablesRequest request);
+  ResultSetResponse apply(TableTypesRequest request);
+  ResultSetResponse apply(TypeInfoRequest request);
+  ResultSetResponse apply(ColumnsRequest request);
+  PrepareResponse apply(PrepareRequest request);
+  ExecuteResponse apply(ExecuteRequest request);
+  ExecuteResponse apply(PrepareAndExecuteRequest request);
+  SyncResultsResponse apply(SyncResultsRequest request);
+  FetchResponse apply(FetchRequest request);
+  CreateStatementResponse apply(CreateStatementRequest request);
+  CloseStatementResponse apply(CloseStatementRequest request);
+  OpenConnectionResponse apply(OpenConnectionRequest request);
+  CloseConnectionResponse apply(CloseConnectionRequest request);
+  ConnectionSyncResponse apply(ConnectionSyncRequest request);
+  DatabasePropertyResponse apply(DatabasePropertyRequest request);
+  CommitResponse apply(CommitRequest request);
+  RollbackResponse apply(RollbackRequest request);
+
+  /**
+   * Sets server-level metadata for RPCs. This includes information that is static across all RPCs.
+   *
+   * @param metadata The server-level metadata.
+   */
+  void setRpcMetadata(RpcMetadataResponse metadata);
+
+  /** Factory that creates a {@code Service}. */
+  interface Factory {
+    Service create(AvaticaConnection connection);
+  }
+
+  /** Base class for request and response. */
+  abstract class Base {
+    static final int PRIME = 31;
+
+    protected static int p(int result, Object o) {
+      return PRIME * result + ((o == null) ? 0 : o.hashCode());
+    }
+
+    protected static int p(int result, boolean v) {
+      return PRIME * result + (v ? 1231 : 1237);
+    }
+
+    protected static int p(int result, int v) {
+      return PRIME * result + v;
+    }
+
+    protected static int p(int result, long v) {
+      return PRIME * result + (int) (v ^ (v >>> 32));
+    }
+  }
+
+  /** Base class for all service request messages. */
+  @JsonTypeInfo(
+      use = JsonTypeInfo.Id.NAME,
+      property = "request",
+      defaultImpl = SchemasRequest.class)
+  @JsonSubTypes({
+      @JsonSubTypes.Type(value = CatalogsRequest.class, name = "getCatalogs"),
+      @JsonSubTypes.Type(value = SchemasRequest.class, name = "getSchemas"),
+      @JsonSubTypes.Type(value = TablesRequest.class, name = "getTables"),
+      @JsonSubTypes.Type(value = TableTypesRequest.class, name = "getTableTypes"),
+      @JsonSubTypes.Type(value = TypeInfoRequest.class, name = "getTypeInfo"),
+      @JsonSubTypes.Type(value = ColumnsRequest.class, name = "getColumns"),
+      @JsonSubTypes.Type(value = ExecuteRequest.class, name = "execute"),
+      @JsonSubTypes.Type(value = PrepareRequest.class, name = "prepare"),
+      @JsonSubTypes.Type(value = PrepareAndExecuteRequest.class,
+          name = "prepareAndExecute"),
+      @JsonSubTypes.Type(value = FetchRequest.class, name = "fetch"),
+      @JsonSubTypes.Type(value = CreateStatementRequest.class,
+          name = "createStatement"),
+      @JsonSubTypes.Type(value = CloseStatementRequest.class,
+          name = "closeStatement"),
+      @JsonSubTypes.Type(value = OpenConnectionRequest.class,
+          name = "openConnection"),
+      @JsonSubTypes.Type(value = CloseConnectionRequest.class,
+          name = "closeConnection"),
+      @JsonSubTypes.Type(value = ConnectionSyncRequest.class, name = "connectionSync"),
+      @JsonSubTypes.Type(value = DatabasePropertyRequest.class, name = "databaseProperties"),
+      @JsonSubTypes.Type(value = SyncResultsRequest.class, name = "syncResults"),
+      @JsonSubTypes.Type(value = CommitRequest.class, name = "commit"),
+      @JsonSubTypes.Type(value = RollbackRequest.class, name = "rollback") })
+  abstract class Request extends Base {
+    abstract Response accept(Service service);
+    abstract Request deserialize(Message genericMsg);
+    abstract Message serialize();
+  }
+
+  /** Base class for all service response messages. */
+  @JsonTypeInfo(
+      use = JsonTypeInfo.Id.NAME,
+      property = "response",
+      defaultImpl = ResultSetResponse.class)
+  @JsonSubTypes({
+      @JsonSubTypes.Type(value = OpenConnectionResponse.class, name = "openConnection"),
+      @JsonSubTypes.Type(value = ResultSetResponse.class, name = "resultSet"),
+      @JsonSubTypes.Type(value = PrepareResponse.class, name = "prepare"),
+      @JsonSubTypes.Type(value = FetchResponse.class, name = "fetch"),
+      @JsonSubTypes.Type(value = CreateStatementResponse.class,
+          name = "createStatement"),
+      @JsonSubTypes.Type(value = CloseStatementResponse.class,
+          name = "closeStatement"),
+      @JsonSubTypes.Type(value = CloseConnectionResponse.class,
+          name = "closeConnection"),
+      @JsonSubTypes.Type(value = ConnectionSyncResponse.class, name = "connectionSync"),
+      @JsonSubTypes.Type(value = DatabasePropertyResponse.class, name = "databaseProperties"),
+      @JsonSubTypes.Type(value = ExecuteResponse.class, name = "executeResults"),
+      @JsonSubTypes.Type(value = ErrorResponse.class, name = "error"),
+      @JsonSubTypes.Type(value = SyncResultsResponse.class, name = "syncResults"),
+      @JsonSubTypes.Type(value = RpcMetadataResponse.class, name = "rpcMetadata"),
+      @JsonSubTypes.Type(value = CommitResponse.class, name = "commit"),
+      @JsonSubTypes.Type(value = RollbackResponse.class, name = "rollback") })
+  abstract class Response extends Base {
+    abstract Response deserialize(Message genericMsg);
+    abstract Message serialize();
+  }
+
+  /** Request for
+   * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)}. */
+  class CatalogsRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CatalogsRequest.
+        getDescriptor().findFieldByNumber(Requests.CatalogsRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+
+    public CatalogsRequest() {
+      connectionId = null;
+    }
+
+    @JsonCreator
+    public CatalogsRequest(@JsonProperty("connectionId") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override CatalogsRequest deserialize(Message genericMsg) {
+      final Requests.CatalogsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.CatalogsRequest.class);
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new CatalogsRequest(connectionId);
+    }
+
+    @Override Requests.CatalogsRequest serialize() {
+      Requests.CatalogsRequest.Builder builder = Requests.CatalogsRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CatalogsRequest
+          && Objects.equals(connectionId, ((CatalogsRequest) o).connectionId);
+    }
+  }
+
+  /** Request for
+   * {@link org.apache.calcite.avatica.Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */
+  class DatabasePropertyRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR =
+        Requests.DatabasePropertyRequest.getDescriptor().
+        findFieldByNumber(Requests.DatabasePropertyRequest.CONNECTION_ID_FIELD_NUMBER);
+
+    public final String connectionId;
+
+    public DatabasePropertyRequest() {
+      connectionId = null;
+    }
+
+    @JsonCreator
+    public DatabasePropertyRequest(@JsonProperty("connectionId") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    DatabasePropertyResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override DatabasePropertyRequest deserialize(Message genericMsg) {
+      final Requests.DatabasePropertyRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.DatabasePropertyRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new DatabasePropertyRequest(connectionId);
+    }
+
+    @Override Requests.DatabasePropertyRequest serialize() {
+      Requests.DatabasePropertyRequest.Builder builder =
+          Requests.DatabasePropertyRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof DatabasePropertyRequest
+          && Objects.equals(connectionId, ((DatabasePropertyRequest) o).connectionId);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#getSchemas(Meta.ConnectionHandle, String, Meta.Pat)}. */
+  class SchemasRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SchemasRequest.
+        getDescriptor().findFieldByNumber(Requests.SchemasRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.SchemasRequest.
+        getDescriptor().findFieldByNumber(Requests.SchemasRequest.CATALOG_FIELD_NUMBER);
+    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.SchemasRequest.
+        getDescriptor().findFieldByNumber(Requests.SchemasRequest.SCHEMA_PATTERN_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final String catalog;
+    public final String schemaPattern;
+
+    SchemasRequest() {
+      connectionId = null;
+      catalog = null;
+      schemaPattern = null;
+    }
+
+    @JsonCreator
+    public SchemasRequest(@JsonProperty("connectionId") String connectionId,
+        @JsonProperty("catalog") String catalog,
+        @JsonProperty("schemaPattern") String schemaPattern) {
+      this.connectionId = connectionId;
+      this.catalog = catalog;
+      this.schemaPattern = schemaPattern;
+    }
+
+    ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override SchemasRequest deserialize(Message genericMsg) {
+      final Requests.SchemasRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.SchemasRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      String catalog = null;
+      if (msg.hasField(CATALOG_DESCRIPTOR)) {
+        catalog = msg.getCatalog();
+      }
+
+      String schemaPattern = null;
+      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
+        schemaPattern = msg.getSchemaPattern();
+      }
+
+      return new SchemasRequest(connectionId, catalog, schemaPattern);
+    }
+
+    @Override Requests.SchemasRequest serialize() {
+      Requests.SchemasRequest.Builder builder = Requests.SchemasRequest.newBuilder();
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+      if (null != catalog) {
+        builder.setCatalog(catalog);
+      }
+      if (null != schemaPattern) {
+        builder.setSchemaPattern(schemaPattern);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, catalog);
+      result = p(result, schemaPattern);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof SchemasRequest
+          && Objects.equals(connectionId, ((SchemasRequest) o).connectionId)
+          && Objects.equals(catalog, ((SchemasRequest) o).catalog)
+          && Objects.equals(schemaPattern, ((SchemasRequest) o).schemaPattern);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#getTables(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, java.util.List)}
+   */
+  class TablesRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TablesRequest.
+        getDescriptor().findFieldByNumber(Requests.TablesRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.TablesRequest.
+        getDescriptor().findFieldByNumber(Requests.TablesRequest.CATALOG_FIELD_NUMBER);
+    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.TablesRequest.
+        getDescriptor().findFieldByNumber(Requests.TablesRequest.SCHEMA_PATTERN_FIELD_NUMBER);
+    private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.TablesRequest.
+        getDescriptor().findFieldByNumber(Requests.TablesRequest.TABLE_NAME_PATTERN_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final String catalog;
+    public final String schemaPattern;
+    public final String tableNamePattern;
+    public final List<String> typeList;
+
+    TablesRequest() {
+      connectionId = null;
+      catalog = null;
+      schemaPattern = null;
+      tableNamePattern = null;
+      typeList = null;
+    }
+
+    @JsonCreator
+    public TablesRequest(@JsonProperty("connectionId") String connectionId,
+        @JsonProperty("catalog") String catalog,
+        @JsonProperty("schemaPattern") String schemaPattern,
+        @JsonProperty("tableNamePattern") String tableNamePattern,
+        @JsonProperty("typeList") List<String> typeList) {
+      this.connectionId = connectionId;
+      this.catalog = catalog;
+      this.schemaPattern = schemaPattern;
+      this.tableNamePattern = tableNamePattern;
+      this.typeList = typeList;
+    }
+
+    @Override Response accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override Request deserialize(Message genericMsg) {
+      final Requests.TablesRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.TablesRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      String catalog = null;
+      if (msg.hasField(CATALOG_DESCRIPTOR)) {
+        catalog = msg.getCatalog();
+      }
+
+      String schemaPattern = null;
+      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
+        schemaPattern = msg.getSchemaPattern();
+      }
+
+      String tableNamePattern = null;
+      if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) {
+        tableNamePattern = msg.getTableNamePattern();
+      }
+
+      // Cannot determine if a value was set for a repeated field. Must use an extra boolean
+      // parameter to distinguish an empty and null typeList.
+      List<String> typeList = null;
+      if (msg.getHasTypeList()) {
+        typeList = msg.getTypeListList();
+      }
+
+      return new TablesRequest(connectionId, catalog, schemaPattern, tableNamePattern, typeList);
+    }
+
+    @Override Requests.TablesRequest serialize() {
+      Requests.TablesRequest.Builder builder = Requests.TablesRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+      if (null != catalog) {
+        builder.setCatalog(catalog);
+      }
+      if (null != schemaPattern) {
+        builder.setSchemaPattern(schemaPattern);
+      }
+      if (null != tableNamePattern) {
+        builder.setTableNamePattern(tableNamePattern);
+      }
+      if (null != typeList) {
+        builder.setHasTypeList(true);
+        builder.addAllTypeList(typeList);
+      } else {
+        builder.setHasTypeList(false);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, catalog);
+      result = p(result, schemaPattern);
+      result = p(result, tableNamePattern);
+      result = p(result, typeList);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof TablesRequest
+          && Objects.equals(connectionId, ((TablesRequest) o).connectionId)
+          && Objects.equals(catalog, ((TablesRequest) o).catalog)
+          && Objects.equals(schemaPattern, ((TablesRequest) o).schemaPattern)
+          && Objects.equals(tableNamePattern, ((TablesRequest) o).tableNamePattern)
+          && Objects.equals(typeList, ((TablesRequest) o).typeList);
+    }
+  }
+
+  /**
+   * Request for {@link Meta#getTableTypes(Meta.ConnectionHandle)}.
+   */
+  class TableTypesRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TableTypesRequest.
+        getDescriptor().findFieldByNumber(Requests.TableTypesRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+
+    public TableTypesRequest() {
+      this.connectionId = null;
+    }
+
+    @JsonCreator
+    public TableTypesRequest(@JsonProperty("connectionId") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    @Override ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override TableTypesRequest deserialize(Message genericMsg) {
+      final Requests.TableTypesRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.TableTypesRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new TableTypesRequest(connectionId);
+    }
+
+    @Override Requests.TableTypesRequest serialize() {
+      Requests.TableTypesRequest.Builder builder = Requests.TableTypesRequest.newBuilder();
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof TableTypesRequest
+          && Objects.equals(connectionId, ((TableTypesRequest) o).connectionId);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#getColumns(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat)}.
+   */
+  class ColumnsRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ColumnsRequest.
+        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.ColumnsRequest.
+        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CATALOG_FIELD_NUMBER);
+    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
+        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.SCHEMA_PATTERN_FIELD_NUMBER);
+    private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
+        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.TABLE_NAME_PATTERN_FIELD_NUMBER);
+    private static final FieldDescriptor COLUMN_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
+        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.COLUMN_NAME_PATTERN_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final String catalog;
+    public final String schemaPattern;
+    public final String tableNamePattern;
+    public final String columnNamePattern;
+
+    ColumnsRequest() {
+      connectionId = null;
+      catalog = null;
+      schemaPattern = null;
+      tableNamePattern = null;
+      columnNamePattern = null;
+    }
+
+    @JsonCreator
+    public ColumnsRequest(@JsonProperty("connectionId") String connectionId,
+        @JsonProperty("catalog") String catalog,
+        @JsonProperty("schemaPattern") String schemaPattern,
+        @JsonProperty("tableNamePattern") String tableNamePattern,
+        @JsonProperty("columnNamePattern") String columnNamePattern) {
+      this.connectionId = connectionId;
+      this.catalog = catalog;
+      this.schemaPattern = schemaPattern;
+      this.tableNamePattern = tableNamePattern;
+      this.columnNamePattern = columnNamePattern;
+    }
+
+    ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override ColumnsRequest deserialize(Message genericMsg) {
+      final Requests.ColumnsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.ColumnsRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      String catalog = null;
+      if (msg.hasField(CATALOG_DESCRIPTOR)) {
+        catalog = msg.getCatalog();
+      }
+
+      String schemaPattern = null;
+      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
+        schemaPattern = msg.getSchemaPattern();
+      }
+
+      String tableNamePattern = null;
+      if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) {
+        tableNamePattern = msg.getTableNamePattern();
+      }
+
+      String columnNamePattern = null;
+      if (msg.hasField(COLUMN_NAME_PATTERN_DESCRIPTOR)) {
+        columnNamePattern = msg.getColumnNamePattern();
+      }
+
+      return new ColumnsRequest(connectionId, catalog, schemaPattern, tableNamePattern,
+          columnNamePattern);
+    }
+
+    @Override Requests.ColumnsRequest serialize() {
+      Requests.ColumnsRequest.Builder builder = Requests.ColumnsRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+      if (null != catalog) {
+        builder.setCatalog(catalog);
+      }
+      if (null != schemaPattern) {
+        builder.setSchemaPattern(schemaPattern);
+      }
+      if (null != tableNamePattern) {
+        builder.setTableNamePattern(tableNamePattern);
+      }
+      if (null != columnNamePattern) {
+        builder.setColumnNamePattern(columnNamePattern);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, catalog);
+      result = p(result, columnNamePattern);
+      result = p(result, schemaPattern);
+      result = p(result, tableNamePattern);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ColumnsRequest
+          && Objects.equals(connectionId, ((ColumnsRequest) o).connectionId)
+          && Objects.equals(catalog, ((ColumnsRequest) o).catalog)
+          && Objects.equals(schemaPattern, ((ColumnsRequest) o).schemaPattern)
+          && Objects.equals(tableNamePattern, ((ColumnsRequest) o).tableNamePattern)
+          && Objects.equals(columnNamePattern, ((ColumnsRequest) o).columnNamePattern);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#getTypeInfo(Meta.ConnectionHandle)}. */
+  class TypeInfoRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TypeInfoRequest.
+        getDescriptor().findFieldByNumber(Requests.TypeInfoRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+
+    public TypeInfoRequest() {
+      connectionId = null;
+    }
+
+    @JsonCreator
+    public TypeInfoRequest(@JsonProperty("connectionId") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    @Override ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override TypeInfoRequest deserialize(Message genericMsg) {
+      final Requests.TypeInfoRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.TypeInfoRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new TypeInfoRequest(connectionId);
+    }
+
+    @Override Requests.TypeInfoRequest serialize() {
+      Requests.TypeInfoRequest.Builder builder = Requests.TypeInfoRequest.newBuilder();
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof TypeInfoRequest
+          && Objects.equals(connectionId, ((TypeInfoRequest) o).connectionId);
+    }
+  }
+
+  /** Response that contains a result set.
+   *
+   * <p>Regular result sets have {@code updateCount} -1;
+   * any other value means a dummy result set that is just a count, and has
+   * no signature and no other data.
+   *
+   * <p>Several types of request, including
+   * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)} and
+   * {@link org.apache.calcite.avatica.Meta#getSchemas(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat)}
+   * {@link Meta#getTables(Meta.ConnectionHandle, String, Meta.Pat, Meta.Pat, List)}
+   * {@link Meta#getTableTypes(Meta.ConnectionHandle)}
+   * return this response. */
+  class ResultSetResponse extends Response {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.ResultSetResponse.
+        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor SIGNATURE_DESCRIPTOR = Responses.ResultSetResponse.
+        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.SIGNATURE_FIELD_NUMBER);
+    private static final FieldDescriptor FIRST_FRAME_DESCRIPTOR = Responses.ResultSetResponse.
+        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.FIRST_FRAME_FIELD_NUMBER);
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ResultSetResponse.
+        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.METADATA_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final int statementId;
+    public final boolean ownStatement;
+    public final Meta.Signature signature;
+    public final Meta.Frame firstFrame;
+    public final long updateCount;
+    public final RpcMetadataResponse rpcMetadata;
+
+    ResultSetResponse() {
+      connectionId = null;
+      statementId = 0;
+      ownStatement = false;
+      signature = null;
+      firstFrame = null;
+      updateCount = 0;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public ResultSetResponse(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId,
+        @JsonProperty("ownStatement") boolean ownStatement,
+        @JsonProperty("signature") Meta.Signature signature,
+        @JsonProperty("firstFrame") Meta.Frame firstFrame,
+        @JsonProperty("updateCount") long updateCount,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+      this.ownStatement = ownStatement;
+      this.signature = signature;
+      this.firstFrame = firstFrame;
+      this.updateCount = updateCount;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override ResultSetResponse deserialize(Message genericMsg) {
+      final Responses.ResultSetResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.ResultSetResponse.class);
+
+      return fromProto(msg);
+    }
+
+    static ResultSetResponse fromProto(Responses.ResultSetResponse msg) {
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      Meta.Signature signature = null;
+      if (msg.hasField(SIGNATURE_DESCRIPTOR)) {
+        signature = Meta.Signature.fromProto(msg.getSignature());
+      }
+
+      Meta.Frame frame = null;
+      if (msg.hasField(FIRST_FRAME_DESCRIPTOR)) {
+        frame = Meta.Frame.fromProto(msg.getFirstFrame());
+      }
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new ResultSetResponse(connectionId, msg.getStatementId(), msg.getOwnStatement(),
+          signature, frame, msg.getUpdateCount(), metadata);
+    }
+
+    @Override Responses.ResultSetResponse serialize() {
+      Responses.ResultSetResponse.Builder builder = Responses.ResultSetResponse.newBuilder();
+
+      builder.setStatementId(statementId).setOwnStatement(ownStatement).setUpdateCount(updateCount);
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      if (null != signature) {
+        builder.setSignature(signature.toProto());
+      }
+
+      if (null != firstFrame) {
+        builder.setFirstFrame(firstFrame.toProto());
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, firstFrame);
+      result = p(result, ownStatement);
+      result = p(result, signature);
+      result = p(result, statementId);
+      result = p(result, updateCount);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ResultSetResponse
+          && statementId == ((ResultSetResponse) o).statementId
+          && ownStatement == ((ResultSetResponse) o).ownStatement
+          && updateCount == ((ResultSetResponse) o).updateCount
+          && Objects.equals(connectionId, ((ResultSetResponse) o).connectionId)
+          && Objects.equals(firstFrame, ((ResultSetResponse) o).firstFrame)
+          && Objects.equals(signature, ((ResultSetResponse) o).signature)
+          && Objects.equals(rpcMetadata, ((ResultSetResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)}. */
+  class PrepareAndExecuteRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.
+        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
+            Requests.PrepareAndExecuteRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor SQL_DESCRIPTOR = Requests.
+        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
+            Requests.PrepareAndExecuteRequest.SQL_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final String sql;
+    public final long maxRowCount;
+    public final int statementId;
+
+    PrepareAndExecuteRequest() {
+      connectionId = null;
+      sql = null;
+      maxRowCount = 0;
+      statementId = 0;
+    }
+
+    @JsonCreator
+    public PrepareAndExecuteRequest(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId,
+        @JsonProperty("sql") String sql,
+        @JsonProperty("maxRowCount") long maxRowCount) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+      this.sql = sql;
+      this.maxRowCount = maxRowCount;
+    }
+
+    @Override ExecuteResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override PrepareAndExecuteRequest deserialize(Message genericMsg) {
+      final Requests.PrepareAndExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.PrepareAndExecuteRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      String sql = null;
+      if (msg.hasField(SQL_DESCRIPTOR)) {
+        sql = msg.getSql();
+      }
+
+      return new PrepareAndExecuteRequest(connectionId, msg.getStatementId(), sql,
+          msg.getMaxRowCount());
+    }
+
+    @Override Requests.PrepareAndExecuteRequest serialize() {
+      Requests.PrepareAndExecuteRequest.Builder builder = Requests.PrepareAndExecuteRequest
+          .newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+      if (null != sql) {
+        builder.setSql(sql);
+      }
+      builder.setStatementId(statementId);
+      builder.setMaxRowCount(maxRowCount);
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, maxRowCount);
+      result = p(result, sql);
+      result = p(result, statementId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof PrepareAndExecuteRequest
+          && statementId == ((PrepareAndExecuteRequest) o).statementId
+          && maxRowCount == ((PrepareAndExecuteRequest) o).maxRowCount
+          && Objects.equals(connectionId, ((PrepareAndExecuteRequest) o).connectionId)
+          && Objects.equals(sql, ((PrepareAndExecuteRequest) o).sql);
+    }
+  }
+
+  /** Request for
+   * {@link org.apache.calcite.avatica.Meta#execute}. */
+  class ExecuteRequest extends Request {
+    private static final FieldDescriptor STATEMENT_HANDLE_DESCRIPTOR = Requests.ExecuteRequest.
+        getDescriptor().findFieldByNumber(Requests.ExecuteRequest.STATEMENTHANDLE_FIELD_NUMBER);
+    public final Meta.StatementHandle statementHandle;
+    public final List<TypedValue> parameterValues;
+    public final long maxRowCount;
+
+    ExecuteRequest() {
+      statementHandle = null;
+      parameterValues = null;
+      maxRowCount = 0;
+    }
+
+    @JsonCreator
+    public ExecuteRequest(
+        @JsonProperty("statementHandle") Meta.StatementHandle statementHandle,
+        @JsonProperty("parameterValues") List<TypedValue> parameterValues,
+        @JsonProperty("maxRowCount") long maxRowCount) {
+      this.statementHandle = statementHandle;
+      this.parameterValues = parameterValues;
+      this.maxRowCount = maxRowCount;
+    }
+
+    @Override ExecuteResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override ExecuteRequest deserialize(Message genericMsg) {
+      final Requests.ExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.ExecuteRequest.class);
+
+      Meta.StatementHandle statemetnHandle = null;
+      if (msg.hasField(STATEMENT_HANDLE_DESCRIPTOR)) {
+        statemetnHandle = Meta.StatementHandle.fromProto(msg.getStatementHandle());
+      }
+
+      List<TypedValue> values = null;
+      if (msg.getHasParameterValues()) {
+        values = new ArrayList<>(msg.getParameterValuesCount());
+        for (Common.TypedValue valueProto : msg.getParameterValuesList()) {
+          values.add(TypedValue.fromProto(valueProto));
+        }
+      }
+
+      return new ExecuteRequest(statemetnHandle, values, msg.getMaxRowCount());
+    }
+
+    @Override Requests.ExecuteRequest serialize() {
+      Requests.ExecuteRequest.Builder builder = Requests.ExecuteRequest.newBuilder();
+
+      if (null != statementHandle) {
+        builder.setStatementHandle(statementHandle.toProto());
+      }
+
+      if (null != parameterValues) {
+        builder.setHasParameterValues(true);
+        for (TypedValue paramValue : parameterValues) {
+          if (paramValue == null) {
+            builder.addParameterValues(TypedValue.NULL.toProto());
+          } else {
+            builder.addParameterValues(paramValue.toProto());
+          }
+        }
+      } else {
+        builder.setHasParameterValues(false);
+      }
+
+      builder.setMaxRowCount(maxRowCount);
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, statementHandle);
+      result = p(result, parameterValues);
+      result = p(result, maxRowCount);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ExecuteRequest
+          && maxRowCount == ((ExecuteRequest) o).maxRowCount
+          && Objects.equals(statementHandle, ((ExecuteRequest) o).statementHandle)
+          && Objects.equals(parameterValues, ((ExecuteRequest) o).parameterValues);
+    }
+  }
+
+  /** Response to a
+   * {@link org.apache.calcite.avatica.remote.Service.PrepareAndExecuteRequest}. */
+  class ExecuteResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ExecuteResponse.
+        getDescriptor().findFieldByNumber(Responses.ExecuteResponse.METADATA_FIELD_NUMBER);
+    public final List<ResultSetResponse> results;
+    public boolean missingStatement = false;
+    public final RpcMetadataResponse rpcMetadata;
+
+    ExecuteResponse() {
+      results = null;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public ExecuteResponse(@JsonProperty("resultSets") List<ResultSetResponse> results,
+        @JsonProperty("missingStatement") boolean missingStatement,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.results = results;
+      this.missingStatement = missingStatement;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override ExecuteResponse deserialize(Message genericMsg) {
+      final Responses.ExecuteResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.ExecuteResponse.class);
+
+      List<Responses.ResultSetResponse> msgResults = msg.getResultsList();
+      List<ResultSetResponse> copiedResults = new ArrayList<>(msgResults.size());
+
+      for (Responses.ResultSetResponse msgResult : msgResults) {
+        copiedResults.add(ResultSetResponse.fromProto(msgResult));
+      }
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new ExecuteResponse(copiedResults, msg.getMissingStatement(), metadata);
+    }
+
+    @Override Responses.ExecuteResponse serialize() {
+      Responses.ExecuteResponse.Builder builder = Responses.ExecuteResponse.newBuilder();
+
+      if (null != results) {
+        for (ResultSetResponse result : results) {
+          builder.addResults(result.serialize());
+        }
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.setMissingStatement(missingStatement).build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, results);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ExecuteResponse
+          && Objects.equals(results, ((ExecuteResponse) o).results)
+          && Objects.equals(rpcMetadata, ((ExecuteResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#prepare(Meta.ConnectionHandle, String, long)}. */
+  class PrepareRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.PrepareRequest.
+        getDescriptor().findFieldByNumber(Requests.PrepareRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor SQL_DESCRIPTOR = Requests.PrepareRequest.
+        getDescriptor().findFieldByNumber(Requests.PrepareRequest.SQL_FIELD_NUMBER);
+    public final String connectionId;
+    public final String sql;
+    public final long maxRowCount;
+
+    PrepareRequest() {
+      connectionId = null;
+      sql = null;
+      maxRowCount = 0;
+    }
+
+    @JsonCreator
+    public PrepareRequest(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("sql") String sql,
+        @JsonProperty("maxRowCount") long maxRowCount) {
+      this.connectionId = connectionId;
+      this.sql = sql;
+      this.maxRowCount = maxRowCount;
+    }
+
+    @Override PrepareResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override PrepareRequest deserialize(Message genericMsg) {
+      final Requests.PrepareRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.PrepareRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      String sql = null;
+      if (msg.hasField(SQL_DESCRIPTOR)) {
+        sql = msg.getSql();
+      }
+
+      return new PrepareRequest(connectionId, sql, msg.getMaxRowCount());
+    }
+
+    @Override Requests.PrepareRequest serialize() {
+      Requests.PrepareRequest.Builder builder = Requests.PrepareRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      if (null != sql) {
+        builder.setSql(sql);
+      }
+
+      return builder.setMaxRowCount(maxRowCount).build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, maxRowCount);
+      result = p(result, sql);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof PrepareRequest
+          && maxRowCount == ((PrepareRequest) o).maxRowCount
+          && Objects.equals(connectionId, ((PrepareRequest) o).connectionId)
+          && Objects.equals(sql, ((PrepareRequest) o).sql);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.PrepareRequest}. */
+  class PrepareResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.PrepareResponse.
+        getDescriptor().findFieldByNumber(Responses.PrepareResponse.METADATA_FIELD_NUMBER);
+    public final Meta.StatementHandle statement;
+    public final RpcMetadataResponse rpcMetadata;
+
+    PrepareResponse() {
+      statement = null;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public PrepareResponse(
+        @JsonProperty("statement") Meta.StatementHandle statement,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.statement = statement;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override PrepareResponse deserialize(Message genericMsg) {
+      final Responses.PrepareResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.PrepareResponse.class);
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new PrepareResponse(Meta.StatementHandle.fromProto(msg.getStatement()), metadata);
+    }
+
+    @Override Responses.PrepareResponse serialize() {
+      Responses.PrepareResponse.Builder builder = Responses.PrepareResponse.newBuilder();
+
+      if (null != statement) {
+        builder.setStatement(statement.toProto());
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, statement);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof PrepareResponse
+          && Objects.equals(statement, ((PrepareResponse) o).statement)
+          && Objects.equals(rpcMetadata, ((PrepareResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#fetch}. */
+  class FetchRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.FetchRequest.
+        getDescriptor().findFieldByNumber(Requests.FetchRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+    public final int statementId;
+    public final long offset;
+    /** Maximum number of rows to be returned in the frame. Negative means no
+     * limit. */
+    public final int fetchMaxRowCount;
+
+    FetchRequest() {
+      connectionId = null;
+      statementId = 0;
+      offset = 0;
+      fetchMaxRowCount = 0;
+    }
+
+    @JsonCreator
+    public FetchRequest(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId,
+        @JsonProperty("offset") long offset,
+        @JsonProperty("fetchMaxRowCount") int fetchMaxRowCount) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+      this.offset = offset;
+      this.fetchMaxRowCount = fetchMaxRowCount;
+    }
+
+    @Override FetchResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override FetchRequest deserialize(Message genericMsg) {
+      final Requests.FetchRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.FetchRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new FetchRequest(connectionId, msg.getStatementId(), msg.getOffset(),
+          msg.getFetchMaxRowCount());
+    }
+
+    @Override Requests.FetchRequest serialize() {
+      Requests.FetchRequest.Builder builder = Requests.FetchRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      builder.setStatementId(statementId);
+      builder.setOffset(offset);
+      builder.setFetchMaxRowCount(fetchMaxRowCount);
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, fetchMaxRowCount);
+      result = p(result, offset);
+      result = p(result, statementId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof FetchRequest
+          && statementId == ((FetchRequest) o).statementId
+          && offset == ((FetchRequest) o).offset
+          && fetchMaxRowCount == ((FetchRequest) o).fetchMaxRowCount
+          && Objects.equals(connectionId, ((FetchRequest) o).connectionId);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.FetchRequest}. */
+  class FetchResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.FetchResponse.
+        getDescriptor().findFieldByNumber(Responses.FetchResponse.METADATA_FIELD_NUMBER);
+    public final Meta.Frame frame;
+    public boolean missingStatement = false;
+    public boolean missingResults = false;
+    public final RpcMetadataResponse rpcMetadata;
+
+    FetchResponse() {
+      frame = null;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public FetchResponse(@JsonProperty("frame") Meta.Frame frame,
+        @JsonProperty("missingStatement") boolean missingStatement,
+        @JsonProperty("missingResults") boolean missingResults,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.frame = frame;
+      this.missingStatement = missingStatement;
+      this.missingResults = missingResults;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override FetchResponse deserialize(Message genericMsg) {
+      final Responses.FetchResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.FetchResponse.class);
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new FetchResponse(Meta.Frame.fromProto(msg.getFrame()), msg.getMissingStatement(),
+          msg.getMissingResults(), metadata);
+    }
+
+    @Override Responses.FetchResponse serialize() {
+      Responses.FetchResponse.Builder builder = Responses.FetchResponse.newBuilder();
+
+      if (null != frame) {
+        builder.setFrame(frame.toProto());
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.setMissingStatement(missingStatement)
+          .setMissingResults(missingResults).build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, frame);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof FetchResponse
+          && Objects.equals(frame, ((FetchResponse) o).frame)
+          && Objects.equals(rpcMetadata, ((FetchResponse) o).rpcMetadata)
+          && missingStatement == ((FetchResponse) o).missingStatement;
+    }
+  }
+
+  /** Request for
+   * {@link org.apache.calcite.avatica.Meta#createStatement(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */
+  class CreateStatementRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CreateStatementRequest.
+        getDescriptor().findFieldByNumber(
+            Requests.CreateStatementRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+
+    CreateStatementRequest() {
+      connectionId = null;
+    }
+
+    @JsonCreator
+    public CreateStatementRequest(
+        @JsonProperty("signature") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    @Override CreateStatementResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override CreateStatementRequest deserialize(Message genericMsg) {
+      final Requests.CreateStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.CreateStatementRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new CreateStatementRequest(connectionId);
+    }
+
+    @Override Requests.CreateStatementRequest serialize() {
+      Requests.CreateStatementRequest.Builder builder = Requests.CreateStatementRequest
+          .newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CreateStatementRequest
+          && Objects.equals(connectionId, ((CreateStatementRequest) o).connectionId);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.CreateStatementRequest}. */
+  class CreateStatementResponse extends Response {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.
+        CreateStatementResponse.getDescriptor().findFieldByNumber(
+            Responses.CreateStatementResponse.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.
+        CreateStatementResponse.getDescriptor().findFieldByNumber(
+            Responses.CreateStatementResponse.METADATA_FIELD_NUMBER);
+    public final String connectionId;
+    public final int statementId;
+    public final RpcMetadataResponse rpcMetadata;
+
+    CreateStatementResponse() {
+      connectionId = null;
+      statementId = 0;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public CreateStatementResponse(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override CreateStatementResponse deserialize(Message genericMsg) {
+      final Responses.CreateStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.CreateStatementResponse.class);
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new CreateStatementResponse(connectionId, msg.getStatementId(), metadata);
+    }
+
+    @Override Responses.CreateStatementResponse serialize() {
+      Responses.CreateStatementResponse.Builder builder = Responses.CreateStatementResponse
+          .newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      builder.setStatementId(statementId);
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, statementId);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CreateStatementResponse
+          && statementId == ((CreateStatementResponse) o).statementId
+          && Objects.equals(connectionId, ((CreateStatementResponse) o).connectionId)
+          && Objects.equals(rpcMetadata, ((CreateStatementResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link org.apache.calcite.avatica.Meta#closeStatement(org.apache.calcite.avatica.Meta.StatementHandle)}. */
+  class CloseStatementRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseStatementRequest.
+        getDescriptor().findFieldByNumber(
+            Requests.CloseStatementRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+    public final int statementId;
+
+    CloseStatementRequest() {
+      connectionId = null;
+      statementId = 0;
+    }
+
+    @JsonCreator
+    public CloseStatementRequest(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+    }
+
+    @Override CloseStatementResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override CloseStatementRequest deserialize(Message genericMsg) {
+      final Requests.CloseStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.CloseStatementRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new CloseStatementRequest(connectionId, msg.getStatementId());
+    }
+
+    @Override Requests.CloseStatementRequest serialize() {
+      Requests.CloseStatementRequest.Builder builder = Requests.CloseStatementRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.setStatementId(statementId).build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, statementId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CloseStatementRequest
+          && statementId == ((CloseStatementRequest) o).statementId
+          && Objects.equals(connectionId, ((CloseStatementRequest) o).connectionId);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.CloseStatementRequest}. */
+  class CloseStatementResponse extends Response {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.
+        CloseStatementResponse.getDescriptor().findFieldByNumber(
+            Responses.CloseStatementResponse.METADATA_FIELD_NUMBER);
+
+    public final RpcMetadataResponse rpcMetadata;
+
+    public CloseStatementResponse() {
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public CloseStatementResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override CloseStatementResponse deserialize(Message genericMsg) {
+      final Responses.CloseStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.CloseStatementResponse.class);
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new CloseStatementResponse(metadata);
+    }
+
+    @Override Responses.CloseStatementResponse serialize() {
+      Responses.CloseStatementResponse.Builder builder =
+          Responses.CloseStatementResponse.newBuilder();
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CloseStatementResponse
+          && Objects.equals(rpcMetadata, ((CloseStatementResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#openConnection}. */
+  class OpenConnectionRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.OpenConnectionRequest
+        .getDescriptor().findFieldByNumber(
+            Requests.OpenConnectionRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+    public final Map<String, String> info;
+
+    public OpenConnectionRequest() {
+      connectionId = null;
+      info = null;
+    }
+
+    @JsonCreator
+    public OpenConnectionRequest(@JsonProperty("connectionId") String connectionId,
+        @JsonProperty("info") Map<String, String> info) {
+      this.connectionId = connectionId;
+      this.info = info;
+    }
+
+    @Override OpenConnectionResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    /**
+     * Serializes the necessary properties into a Map.
+     *
+     * @param props The properties to serialize.
+     * @return A representation of the Properties as a Map.
+     */
+    public static Map<String, String> serializeProperties(Properties props) {
+      Map<String, String> infoAsString = new HashMap<>();
+      for (Map.Entry<Object, Object> entry : props.entrySet()) {
+        // Determine if this is a property we want to forward to the server
+        boolean localProperty = false;
+        for (BuiltInConnectionProperty prop : BuiltInConnectionProperty.values()) {
+          if (prop.camelName().equals(entry.getKey())) {
+            localProperty = true;
+            break;
+          }
+        }
+
+        if (!localProperty) {
+          infoAsString.put(entry.getKey().toString(), entry.getValue().toString());
+        }
+      }
+      return infoAsString;
+    }
+
+    @Override Request deserialize(Message genericMsg) {
+      final Requests.OpenConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.OpenConnectionRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      Map<String, String> info = msg.getInfo();
+      if (info.isEmpty()) {
+        info = null;
+      }
+
+      return new OpenConnectionRequest(connectionId, info);
+    }
+
+    @Override Message serialize() {
+      Requests.OpenConnectionRequest.Builder builder = Requests.OpenConnectionRequest.newBuilder();
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+      if (null != info) {
+        builder.getMutableInfo().putAll(info);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      result = p(result, info);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof OpenConnectionRequest
+          && Objects.equals(connectionId, ((OpenConnectionRequest) o).connectionId)
+          && Objects.equals(info, ((OpenConnectionRequest) o).info);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.OpenConnectionRequest}. */
+  class OpenConnectionResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.OpenConnectionResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.OpenConnectionResponse.METADATA_FIELD_NUMBER);
+    public final RpcMetadataResponse rpcMetadata;
+
+    public OpenConnectionResponse() {
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public OpenConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override OpenConnectionResponse deserialize(Message genericMsg) {
+      final Responses.OpenConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.OpenConnectionResponse.class);
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new OpenConnectionResponse(metadata);
+    }
+
+    @Override Responses.OpenConnectionResponse serialize() {
+      Responses.OpenConnectionResponse.Builder builder =
+          Responses.OpenConnectionResponse.newBuilder();
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof OpenConnectionResponse
+          && Objects.equals(rpcMetadata, ((OpenConnectionResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for
+   * {@link Meta#closeConnection(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */
+  class CloseConnectionRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseConnectionRequest
+        .getDescriptor().findFieldByNumber(
+            Requests.CloseConnectionRequest.CONNECTION_ID_FIELD_NUMBER);
+    public final String connectionId;
+
+    CloseConnectionRequest() {
+      connectionId = null;
+    }
+
+    @JsonCreator
+    public CloseConnectionRequest(
+        @JsonProperty("connectionId") String connectionId) {
+      this.connectionId = connectionId;
+    }
+
+    @Override CloseConnectionResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override CloseConnectionRequest deserialize(Message genericMsg) {
+      final Requests.CloseConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.CloseConnectionRequest.class);
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      return new CloseConnectionRequest(connectionId);
+    }
+
+    @Override Requests.CloseConnectionRequest serialize() {
+      Requests.CloseConnectionRequest.Builder builder = Requests.CloseConnectionRequest
+          .newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CloseConnectionRequest
+          && Objects.equals(connectionId, ((CloseConnectionRequest) o).connectionId);
+    }
+  }
+
+  /** Response from
+   * {@link org.apache.calcite.avatica.remote.Service.CloseConnectionRequest}. */
+  class CloseConnectionResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.CloseConnectionResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.CloseConnectionResponse.METADATA_FIELD_NUMBER);
+
+    public final RpcMetadataResponse rpcMetadata;
+
+    public CloseConnectionResponse() {
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public CloseConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override CloseConnectionResponse deserialize(Message genericMsg) {
+      final Responses.CloseConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.CloseConnectionResponse.class);
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new CloseConnectionResponse(metadata);
+    }
+
+    @Override Responses.CloseConnectionResponse serialize() {
+      Responses.CloseConnectionResponse.Builder builder =
+          Responses.CloseConnectionResponse.newBuilder();
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof CloseConnectionResponse
+          && Objects.equals(rpcMetadata, ((CloseConnectionResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Request for {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */
+  class ConnectionSyncRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ConnectionSyncRequest
+        .getDescriptor().findFieldByNumber(
+            Requests.ConnectionSyncRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor CONN_PROPS_DESCRIPTOR = Requests.ConnectionSyncRequest
+        .getDescriptor().findFieldByNumber(Requests.ConnectionSyncRequest.CONN_PROPS_FIELD_NUMBER);
+
+    public final String connectionId;
+    public final Meta.ConnectionProperties connProps;
+
+    ConnectionSyncRequest() {
+      connectionId = null;
+      connProps = null;
+    }
+
+    @JsonCreator
+    public ConnectionSyncRequest(
+        @JsonProperty("connectionId") String connectionId,
+        @JsonProperty("connProps") Meta.ConnectionProperties connProps) {
+      this.connectionId = connectionId;
+      this.connProps = connProps;
+    }
+
+    @Override ConnectionSyncResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    @Override ConnectionSyncRequest deserialize(Message genericMsg) {
+      final Requests.ConnectionSyncRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.ConnectionSyncRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      Meta.ConnectionProperties connProps = null;
+      if (msg.hasField(CONN_PROPS_DESCRIPTOR)) {
+        connProps = ConnectionPropertiesImpl.fromProto(msg.getConnProps());
+      }
+
+      return new ConnectionSyncRequest(connectionId, connProps);
+    }
+
+    @Override Requests.ConnectionSyncRequest serialize() {
+      Requests.ConnectionSyncRequest.Builder builder = Requests.ConnectionSyncRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      if (null != connProps) {
+        builder.setConnProps(connProps.toProto());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connProps);
+      result = p(result, connectionId);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ConnectionSyncRequest
+          && Objects.equals(connectionId, ((ConnectionSyncRequest) o).connectionId)
+          && Objects.equals(connProps, ((ConnectionSyncRequest) o).connProps);
+    }
+  }
+
+  /** Response for
+   * {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */
+  class ConnectionSyncResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ConnectionSyncResponse
+        .getDescriptor().findFieldByNumber(Responses.ConnectionSyncResponse.METADATA_FIELD_NUMBER);
+    public final Meta.ConnectionProperties connProps;
+    public final RpcMetadataResponse rpcMetadata;
+
+    ConnectionSyncResponse() {
+      connProps = null;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public ConnectionSyncResponse(@JsonProperty("connProps") Meta.ConnectionProperties connProps,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.connProps = connProps;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override ConnectionSyncResponse deserialize(Message genericMsg) {
+      final Responses.ConnectionSyncResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.ConnectionSyncResponse.class);
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new ConnectionSyncResponse(ConnectionPropertiesImpl.fromProto(msg.getConnProps()),
+          metadata);
+    }
+
+    @Override Responses.ConnectionSyncResponse serialize() {
+      Responses.ConnectionSyncResponse.Builder builder = Responses.ConnectionSyncResponse
+          .newBuilder();
+
+      if (null != connProps) {
+        builder.setConnProps(connProps.toProto());
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, connProps);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ConnectionSyncResponse
+          && Objects.equals(connProps, ((ConnectionSyncResponse) o).connProps)
+          && Objects.equals(rpcMetadata, ((ConnectionSyncResponse) o).rpcMetadata);
+    }
+  }
+
+  /** Response for
+   * {@link Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */
+  class DatabasePropertyResponse extends Response {
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.DatabasePropertyResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.DatabasePropertyResponse.METADATA_FIELD_NUMBER);
+    public final Map<Meta.DatabaseProperty, Object> map;
+    public final RpcMetadataResponse rpcMetadata;
+
+    DatabasePropertyResponse() {
+      map = null;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public DatabasePropertyResponse(@JsonProperty("map") Map<Meta.DatabaseProperty, Object> map,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.map = map;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    @Override DatabasePropertyResponse deserialize(Message genericMsg) {
+      final Responses.DatabasePropertyResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.DatabasePropertyResponse.class);
+      HashMap<Meta.DatabaseProperty, Object> properties = new HashMap<>();
+      for (Responses.DatabasePropertyElement property : msg.getPropsList()) {
+        final Meta.DatabaseProperty dbProp = Meta.DatabaseProperty.fromProto(property.getKey());
+        final Common.TypedValue value = property.getValue();
+
+        Object obj;
+        switch (dbProp) {
+        // Just need to keep parity with the exposed values on DatabaseProperty
+        case GET_NUMERIC_FUNCTIONS:
+        case GET_STRING_FUNCTIONS:
+        case GET_SYSTEM_FUNCTIONS:
+        case GET_TIME_DATE_FUNCTIONS:
+        case GET_S_Q_L_KEYWORDS:
+          // String
+          if (Common.Rep.STRING != value.getType()) {
+            throw new IllegalArgumentException("Expected STRING, but got " + value.getType());
+          }
+
+          obj = value.getStringValue();
+          break;
+        case GET_DEFAULT_TRANSACTION_ISOLATION:
+          // int
+          if (Common.Rep.INTEGER != value.getType()) {
+            throw new IllegalArgumentException("Expected INTEGER, but got " + value.getType());
+          }
+
+          obj = (int) value.getNumberValue();
+          break;
+        default:
+          throw new RuntimeException("Unhandled DatabaseProperty");
+        }
+
+        properties.put(dbProp, obj);
+      }
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new DatabasePropertyResponse(properties, metadata);
+    }
+
+    @Override Responses.DatabasePropertyResponse serialize() {
+      Responses.DatabasePropertyResponse.Builder builder = Responses.DatabasePropertyResponse
+          .newBuilder();
+
+      if (null != map) {
+        for (Entry<Meta.DatabaseProperty, Object> entry : map.entrySet()) {
+          Object obj = entry.getValue();
+
+          Common.TypedValue.Builder valueBuilder = Common.TypedValue.newBuilder();
+          switch (entry.getKey()) {
+          // Just need to keep parity with the exposed values on DatabaseProperty
+          case GET_NUMERIC_FUNCTIONS:
+          case GET_STRING_FUNCTIONS:
+          case GET_SYSTEM_FUNCTIONS:
+          case GET_TIME_DATE_FUNCTIONS:
+          case GET_S_Q_L_KEYWORDS:
+            // String
+            if (!(obj instanceof String)) {
+              throw new RuntimeException("Expected a String, but got " + obj.getClass());
+            }
+
+            valueBuilder.setType(Common.Rep.STRING).setStringValue((String) obj);
+            break;
+          case GET_DEFAULT_TRANSACTION_ISOLATION:
+            // int
+            if (!(obj instanceof Integer)) {
+              throw new RuntimeException("Expected an Integer, but got " + obj.getClass());
+            }
+
+            valueBuilder.setType(Common.Rep.INTEGER).setNumberValue(((Integer) obj).longValue());
+            break;
+          default:
+            throw new RuntimeException("Unhandled DatabaseProperty");
+          }
+
+          builder.addProps(Responses.DatabasePropertyElement.newBuilder()
+              .setKey(entry.getKey().toProto()).setValue(valueBuilder.build()));
+        }
+      }
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, map);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof DatabasePropertyResponse
+          && Objects.equals(map, ((DatabasePropertyResponse) o).map)
+          && Objects.equals(rpcMetadata, ((DatabasePropertyResponse) o).rpcMetadata);
+    }
+  }
+
+  /**
+   * Response for any request that the server failed to successfully perform.
+   * It is used internally by the transport layers to format errors for
+   * transport over the wire. Thus, {@link Service#apply} will never return
+   * an ErrorResponse.
+   */
+  public class ErrorResponse extends Response {
+    private static final FieldDescriptor ERROR_MESSAGE_DESCRIPTOR = Responses.ErrorResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.ErrorResponse.ERROR_MESSAGE_FIELD_NUMBER);
+    private static final FieldDescriptor SQL_DESCRIPTOR = Responses.ErrorResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.ErrorResponse.SQL_STATE_FIELD_NUMBER);
+    private static final FieldDescriptor SEVERITY_DESCRIPTOR = Responses.ErrorResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.ErrorResponse.SEVERITY_FIELD_NUMBER);
+    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ErrorResponse
+        .getDescriptor().findFieldByNumber(
+            Responses.ErrorResponse.METADATA_FIELD_NUMBER);
+
+    public static final int UNKNOWN_ERROR_CODE = -1;
+    public static final int MISSING_CONNECTION_ERROR_CODE = 1;
+
+    public static final String UNKNOWN_SQL_STATE = "00000";
+
+    public final List<String> exceptions;
+    public final String errorMessage;
+    public final int errorCode;
+    public final String sqlState;
+    public final AvaticaSeverity severity;
+    public final RpcMetadataResponse rpcMetadata;
+
+    ErrorResponse() {
+      exceptions = Collections.singletonList("Unhandled exception");
+      errorMessage = "Unknown message";
+      errorCode = -1;
+      sqlState = UNKNOWN_SQL_STATE;
+      severity = AvaticaSeverity.UNKNOWN;
+      rpcMetadata = null;
+    }
+
+    @JsonCreator
+    public ErrorResponse(@JsonProperty("exceptions") List<String> exceptions,
+        @JsonProperty("errorMessage") String errorMessage,
+        @JsonProperty("errorCode") int errorCode,
+        @JsonProperty("sqlState") String sqlState,
+        @JsonProperty("severity") AvaticaSeverity severity,
+        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+      this.exceptions = exceptions;
+      this.errorMessage = errorMessage;
+      this.errorCode = errorCode;
+      this.sqlState = sqlState;
+      this.severity = severity;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    protected ErrorResponse(Exception e, String errorMessage, int code, String sqlState,
+        AvaticaSeverity severity, RpcMetadataResponse rpcMetadata) {
+      this(errorMessage, code, sqlState, severity, toStackTraces(e), rpcMetadata);
+    }
+
+    protected ErrorResponse(String errorMessage, int code, String sqlState,
+        AvaticaSeverity severity, List<String> exceptions, RpcMetadataResponse rpcMetadata) {
+      this.exceptions = exceptions;
+      this.errorMessage = errorMessage;
+      this.errorCode = code;
+      this.sqlState = sqlState;
+      this.severity = severity;
+      this.rpcMetadata = rpcMetadata;
+    }
+
+    static List<String> toStackTraces(Exception e) {
+      List<String> stackTraces = new ArrayList<>();
+      stackTraces.add(toString(e));
+      if (e instanceof SQLException) {
+        SQLException next = ((SQLException) e).getNextException();
+        while (null != next) {
+          stackTraces.add(toString(next));
+          next = next.getNextException();
+        }
+      }
+      return stackTraces;
+    }
+
+    static String toString(Exception e) {
+      //noinspection ThrowableResultOfMethodCallIgnored
+      Objects.requireNonNull(e);
+      StringWriter sw = new StringWriter();
+      e.printStackTrace(new PrintWriter(sw));
+      return sw.toString();
+    }
+
+    @Override ErrorResponse deserialize(Message genericMsg) {
+      final Responses.ErrorResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+          Responses.ErrorResponse.class);
+      List<String> exceptions = null;
+      if (msg.getHasExceptions()) {
+        exceptions = msg.getExceptionsList();
+      }
+
+      String errorMessage = null;
+      if (msg.hasField(ERROR_MESSAGE_DESCRIPTOR)) {
+        errorMessage = msg.getErrorMessage();
+      }
+
+      String sqlState = null;
+      if (msg.hasField(SQL_DESCRIPTOR)) {
+        sqlState = msg.getSqlState();
+      }
+
+      AvaticaSeverity severity = null;
+      if (msg.hasField(SEVERITY_DESCRIPTOR)) {
+        severity = AvaticaSeverity.fromProto(msg.getSeverity());
+      }
+
+      RpcMetadataResponse metadata = null;
+      if (msg.hasField(METADATA_DESCRIPTOR)) {
+        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+      }
+
+      return new ErrorResponse(exceptions, errorMessage, msg.getErrorCode(), sqlState, severity,
+          metadata);
+    }
+
+    @Override Responses.ErrorResponse serialize() {
+      Responses.ErrorResponse.Builder builder = Responses.ErrorResponse.newBuilder();
+
+      if (null != rpcMetadata) {
+        builder.setMetadata(rpcMetadata.serialize());
+      }
+
+      if (null != exceptions) {
+        builder.setHasExceptions(true);
+        builder.addAllExceptions(exceptions);
+      } else {
+        builder.setHasExceptions(false);
+      }
+
+      if (null != errorMessage) {
+        builder.setErrorMessage(errorMessage);
+      }
+
+      if (null != sqlState) {
+        builder.setSqlState(sqlState);
+      }
+
+      if (null != severity) {
+        builder.setSeverity(severity.toProto());
+      }
+
+      return builder.setErrorCode(errorCode).build();
+    }
+
+    @Override public String toString() {
+      StringBuilder sb = new StringBuilder(32);
+      sb.append("ErrorResponse[errorCode=").append(errorCode)
+          .append(", sqlState=").append(sqlState)
+          .append(", severity=").append(severity)
+          .append(", errorMessage=").append(errorMessage)
+          .append(", exceptions=").append(exceptions);
+      return sb.toString();
+    }
+
+    @Override public int hashCode() {
+      int result = 1;
+      result = p(result, exceptions);
+      result = p(result, errorMessage);
+      result = p(result, errorCode);
+      result = p(result, sqlState);
+      result = p(result, severity);
+      result = p(result, rpcMetadata);
+      return result;
+    }
+
+    @Override public boolean equals(Object o) {
+      return this == o
+          || o instanceof ErrorResponse
+          && errorCode == ((ErrorResponse) o).errorCode
+          && severity == ((ErrorResponse) o).severity
+          && Objects.equals(exceptions, ((ErrorResponse) o).exceptions)
+          && Objects.equals(errorMessage, ((ErrorResponse) o).errorMessage)
+          && Objects.equals(sqlState, ((ErrorResponse) o).sqlState)
+          && Objects.equals(rpcMetadata, ((ErrorResponse) o).rpcMetadata);
+    }
+
+    public AvaticaClientRuntimeException toException() {
+      return new AvaticaClientRuntimeException("Remote driver error: " + errorMessage, errorCode,
+          sqlState, severity, exceptions, rpcMetadata);
+    }
+  }
+
+  /**
+   * Request for {@link Service#apply(SyncResultsRequest)}
+   */
+  class SyncResultsRequest extends Request {
+    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SyncResultsRequest
+        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor STATEMENT_ID_DESCRIPTOR = Requests.SyncResultsRequest
+        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATEMENT_ID_FIELD_NUMBER);
+    private static final FieldDescriptor STATE_DESCRIPTOR = Requests.SyncResultsRequest
+        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATE_FIELD_NUMBER);
+    private static final FieldDescriptor OFFSET_DESCRIPTOR = Requests.SyncResultsRequest
+        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.OFFSET_FIELD_NUMBER);
+    public final String connectionId;
+    public final int statementId;
+    public final QueryState state;
+    public final long offset;
+
+    SyncResultsRequest() {
+      this.connectionId = null;
+      this.statementId = 0;
+      this.state = null;
+      this.offset = 0L;
+    }
+
+    public SyncResultsRequest(@JsonProperty("connectionId") String connectionId,
+        @JsonProperty("statementId") int statementId, @JsonProperty("state") QueryState state,
+        @JsonProperty("offset") long offset) {
+      this.connectionId = connectionId;
+      this.statementId = statementId;
+      this.state = state;
+      this.offset = offset;
+    }
+
+    SyncResultsResponse accept(Service service) {
+      return service.apply(this);
+    }
+
+    Request deserialize(Message genericMsg) {
+      final Requests.SyncResultsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+          Requests.SyncResultsRequest.class);
+
+      String connectionId = null;
+      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
+        connectionId = msg.getConnectionId();
+      }
+
+      int statementId = 0;
+      if (msg.hasField(STATEMENT_ID_DESCRIPTOR)) {
+        statementId = msg.getStatementId();
+      }
+
+      Common.QueryState state = null;
+      if (msg.hasField(STATE_DESCRIPTOR)) {
+        state = msg.getState();
+      }
+
+      long offset = 0;
+      if (msg.hasField(OFFSET_DESCRIPTOR)) {
+        offset = msg.getOffset();
+      }
+
+      return new SyncResultsRequest(connectionId, statementId,
+          null == state ? null : QueryState.fromProto(msg.getState()), offset);
+    }
+
+    Requests.SyncResultsRequest serialize() {
+      Requests.SyncResultsRequest.Builder builder = Requests.SyncResultsRequest.newBuilder();
+
+      if (null != connectionId) {
+        builder.setConnectionId(connectionId);
+      }
+
+      if (null != state) {
+        builder.setState(state.toProto());
+      }

<TRUNCATED>

[07/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
deleted file mode 100644
index 1968fcd..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
+++ /dev/null
@@ -1,154 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaSeverity;
-import org.apache.calcite.avatica.NoSuchConnectionException;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-import org.apache.calcite.avatica.remote.Service.Request;
-import org.apache.calcite.avatica.remote.Service.Response;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import java.io.IOException;
-
-/**
- * Abstract base class for {@link Handler}s to extend to inherit functionality common across
- * serialization strategies.
- *
- * @param <T> The format Requests/Responses are serialized as.
- */
-public abstract class AbstractHandler<T> implements Handler<T> {
-  private static final String NULL_EXCEPTION_MESSAGE = "(null exception message)";
-  protected final Service service;
-  private RpcMetadataResponse metadata = null;
-
-  public AbstractHandler(Service service) {
-    this.service = service;
-  }
-
-  abstract Request decode(T serializedRequest) throws IOException;
-
-  /**
-   * Serialize the given {@link Response} per the concrete {@link Handler} implementation.
-   *
-   * @param response The {@link Response} to serialize.
-   * @return A serialized representation of the {@link Response}.
-   * @throws IOException
-   */
-  abstract T encode(Response response) throws IOException;
-
-  /**
-   * Unwrap Avatica-specific context about a given exception.
-   *
-   * @param e A caught exception throw by Avatica implementation.
-   * @return An {@link ErrorResponse}.
-   */
-  ErrorResponse unwrapException(Exception e) {
-    // By default, we know nothing extra.
-    int errorCode = ErrorResponse.UNKNOWN_ERROR_CODE;
-    String sqlState = ErrorResponse.UNKNOWN_SQL_STATE;
-    AvaticaSeverity severity = AvaticaSeverity.UNKNOWN;
-    String errorMsg = null;
-
-    // Extract the contextual information if we have it. We may not.
-    if (e instanceof AvaticaRuntimeException) {
-      AvaticaRuntimeException rte = (AvaticaRuntimeException) e;
-      errorCode = rte.getErrorCode();
-      sqlState = rte.getSqlState();
-      severity = rte.getSeverity();
-      errorMsg = rte.getErrorMessage();
-    } else if (e instanceof NoSuchConnectionException) {
-      errorCode = ErrorResponse.MISSING_CONNECTION_ERROR_CODE;
-      severity = AvaticaSeverity.ERROR;
-      errorMsg = e.getMessage();
-    } else {
-      // Try to construct a meaningful error message when the server impl doesn't provide one.
-      errorMsg = getCausalChain(e);
-    }
-
-    return new ErrorResponse(e, errorMsg, errorCode, sqlState, severity, metadata);
-  }
-
-  /**
-   * Compute a response for the given request, handling errors generated by that computation.
-   *
-   * @param serializedRequest The caller's request.
-   * @return A {@link Response} with additional context about that response.
-   */
-  public HandlerResponse<T> apply(T serializedRequest) {
-    final Service.Request request;
-    try {
-      request = decode(serializedRequest);
-    } catch (IOException e) {
-      // TODO provide a canned ErrorResponse.
-      throw new RuntimeException(e);
-    }
-
-    try {
-      final Service.Response response = request.accept(service);
-      return new HandlerResponse<>(encode(response), HTTP_OK);
-    } catch (Exception e) {
-      ErrorResponse errorResp = unwrapException(e);
-
-      try {
-        return new HandlerResponse<>(encode(errorResp), HTTP_INTERNAL_SERVER_ERROR);
-      } catch (IOException e1) {
-        // TODO provide a canned ErrorResponse
-
-        // If we can't serialize error message to JSON, can't give a meaningful error to caller.
-        // Just try to not unnecessarily create more exceptions.
-        if (e instanceof RuntimeException) {
-          throw (RuntimeException) e;
-        }
-
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  /**
-   * Constructs a message for the summary of an Exception.
-   *
-   * @param e The Exception to summarize.
-   * @return A summary message for the Exception.
-   */
-  private String getCausalChain(Exception e) {
-    StringBuilder sb = new StringBuilder(16);
-    Throwable curr = e;
-    // Could use Guava, but that would increase dependency set unnecessarily.
-    while (null != curr) {
-      if (sb.length() > 0) {
-        sb.append(" -> ");
-      }
-      String message = curr.getMessage();
-      sb.append(curr.getClass().getSimpleName()).append(": ");
-      sb.append(null == message ? NULL_EXCEPTION_MESSAGE : message);
-      curr = curr.getCause();
-    }
-    if (sb.length() == 0) {
-      // Catch the case where we have no error message.
-      return "Unknown error message";
-    }
-    return sb.toString();
-  }
-
-  @Override public void setRpcMetadata(RpcMetadataResponse metadata) {
-    this.metadata = metadata;
-  }
-}
-
-// End AbstractHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
deleted file mode 100644
index ffaa360..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
+++ /dev/null
@@ -1,159 +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.remote;
-
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.Meta;
-
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A common base class for {@link Service} implementations that implement
- * modifications made to response objects.
- */
-public abstract class AbstractService implements Service {
-
-  private RpcMetadataResponse rpcMetadata = null;
-
-  /**
-   * Represents the serialization of the data over a transport.
-   */
-  enum SerializationType {
-    JSON,
-    PROTOBUF
-  }
-
-  /**
-   * @return The manner in which the data is serialized.
-   */
-  abstract SerializationType getSerializationType();
-
-  /** Modifies a signature, changing the representation of numeric columns
-   * within it. This deals with the fact that JSON transmits a small long value,
-   * or a float which is a whole number, as an integer. Thus the accessors need
-   * be prepared to accept any numeric type. */
-  Meta.Signature finagle(Meta.Signature signature) {
-    final List<ColumnMetaData> columns = new ArrayList<>();
-    for (ColumnMetaData column : signature.columns) {
-      columns.add(finagle(column));
-    }
-    if (columns.equals(signature.columns)) {
-      return signature;
-    }
-    return new Meta.Signature(columns, signature.sql,
-        signature.parameters, signature.internalParameters,
-        signature.cursorFactory, signature.statementType);
-  }
-
-  ColumnMetaData finagle(ColumnMetaData column) {
-    switch (column.type.rep) {
-    case BYTE:
-    case PRIMITIVE_BYTE:
-    case DOUBLE:
-    case PRIMITIVE_DOUBLE:
-    case FLOAT:
-    case PRIMITIVE_FLOAT:
-    case INTEGER:
-    case PRIMITIVE_INT:
-    case SHORT:
-    case PRIMITIVE_SHORT:
-    case LONG:
-    case PRIMITIVE_LONG:
-      return column.setRep(ColumnMetaData.Rep.NUMBER);
-    default:
-      // continue
-      break;
-    }
-    switch (column.type.id) {
-    case Types.VARBINARY:
-    case Types.BINARY:
-      switch (getSerializationType()) {
-      case JSON:
-        return column.setRep(ColumnMetaData.Rep.STRING);
-      case PROTOBUF:
-        return column;
-      default:
-        throw new IllegalStateException("Unhadled case statement");
-      }
-    case Types.DECIMAL:
-    case Types.NUMERIC:
-      return column.setRep(ColumnMetaData.Rep.NUMBER);
-    default:
-      return column;
-    }
-  }
-
-  PrepareResponse finagle(PrepareResponse response) {
-    final Meta.StatementHandle statement = finagle(response.statement);
-    if (statement == response.statement) {
-      return response;
-    }
-    return new PrepareResponse(statement, rpcMetadata);
-  }
-
-  Meta.StatementHandle finagle(Meta.StatementHandle h) {
-    final Meta.Signature signature = finagle(h.signature);
-    if (signature == h.signature) {
-      return h;
-    }
-    return new Meta.StatementHandle(h.connectionId, h.id, signature);
-  }
-
-  ResultSetResponse finagle(ResultSetResponse r) {
-    if (r.updateCount != -1) {
-      assert r.signature == null;
-      return r;
-    }
-    if (r.signature == null) {
-      return r;
-    }
-    final Meta.Signature signature = finagle(r.signature);
-    if (signature == r.signature) {
-      return r;
-    }
-    return new ResultSetResponse(r.connectionId, r.statementId, r.ownStatement,
-        signature, r.firstFrame, r.updateCount, rpcMetadata);
-  }
-
-  ExecuteResponse finagle(ExecuteResponse r) {
-    if (r.missingStatement) {
-      return r;
-    }
-    final List<ResultSetResponse> results = new ArrayList<>();
-    int changeCount = 0;
-    for (ResultSetResponse result : r.results) {
-      ResultSetResponse result2 = finagle(result);
-      if (result2 != result) {
-        ++changeCount;
-      }
-      results.add(result2);
-    }
-    if (changeCount == 0) {
-      return r;
-    }
-    return new ExecuteResponse(results, r.missingStatement, rpcMetadata);
-  }
-
-  @Override public void setRpcMetadata(RpcMetadataResponse metadata) {
-    // OK if this is null
-    this.rpcMetadata = metadata;
-  }
-}
-
-// End AbstractService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
deleted file mode 100644
index 3bda248..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
+++ /dev/null
@@ -1,133 +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.remote;
-
-import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.protocol.RequestExpectContinue;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.pool.BasicConnFactory;
-import org.apache.http.impl.pool.BasicConnPool;
-import org.apache.http.impl.pool.BasicPoolEntry;
-import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.protocol.HttpCoreContext;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.HttpProcessorBuilder;
-import org.apache.http.protocol.HttpRequestExecutor;
-import org.apache.http.protocol.RequestConnControl;
-import org.apache.http.protocol.RequestContent;
-import org.apache.http.protocol.RequestTargetHost;
-import org.apache.http.util.EntityUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.concurrent.Future;
-
-/**
- * A common class to invoke HTTP requests against the Avatica server agnostic of the data being
- * sent and received across the wire.
- */
-public class AvaticaCommonsHttpClientImpl implements AvaticaHttpClient {
-  private static final Logger LOG = LoggerFactory.getLogger(AvaticaCommonsHttpClientImpl.class);
-  private static final ConnectionReuseStrategy REUSE = DefaultConnectionReuseStrategy.INSTANCE;
-
-  // Some basic exposed configurations
-  private static final String MAX_POOLED_CONNECTION_PER_ROUTE_KEY =
-      "avatica.pooled.connections.per.route";
-  private static final String MAX_POOLED_CONNECTION_PER_ROUTE_DEFAULT = "4";
-  private static final String MAX_POOLED_CONNECTIONS_KEY = "avatica.pooled.connections.max";
-  private static final String MAX_POOLED_CONNECTIONS_DEFAULT = "16";
-
-  protected final HttpHost host;
-  protected final HttpProcessor httpProcessor;
-  protected final HttpRequestExecutor httpExecutor;
-  protected final BasicConnPool httpPool;
-
-  public AvaticaCommonsHttpClientImpl(URL url) {
-    this.host = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
-
-    this.httpProcessor = HttpProcessorBuilder.create()
-        .add(new RequestContent())
-        .add(new RequestTargetHost())
-        .add(new RequestConnControl())
-        .add(new RequestExpectContinue()).build();
-
-    this.httpExecutor = new HttpRequestExecutor();
-
-    this.httpPool = new BasicConnPool(new BasicConnFactory());
-    int maxPerRoute = Integer.parseInt(
-        System.getProperty(MAX_POOLED_CONNECTION_PER_ROUTE_KEY,
-            MAX_POOLED_CONNECTION_PER_ROUTE_DEFAULT));
-    int maxTotal = Integer.parseInt(
-        System.getProperty(MAX_POOLED_CONNECTIONS_KEY,
-            MAX_POOLED_CONNECTIONS_DEFAULT));
-    httpPool.setDefaultMaxPerRoute(maxPerRoute);
-    httpPool.setMaxTotal(maxTotal);
-  }
-
-  public byte[] send(byte[] request) {
-    while (true) {
-      boolean reusable = false;
-      // Get a connection from the pool
-      Future<BasicPoolEntry> future = this.httpPool.lease(host, null);
-      BasicPoolEntry entry = null;
-      try {
-        entry = future.get();
-        HttpCoreContext coreContext = HttpCoreContext.create();
-        coreContext.setTargetHost(host);
-
-        HttpClientConnection conn = entry.getConnection();
-
-        ByteArrayEntity entity = new ByteArrayEntity(request, ContentType.APPLICATION_OCTET_STREAM);
-
-        BasicHttpEntityEnclosingRequest postRequest =
-            new BasicHttpEntityEnclosingRequest("POST", "/");
-        postRequest.setEntity(entity);
-
-        httpExecutor.preProcess(postRequest, httpProcessor, coreContext);
-        HttpResponse response = httpExecutor.execute(postRequest, conn, coreContext);
-        httpExecutor.postProcess(response, httpProcessor, coreContext);
-
-        // Should the connection be kept alive?
-        reusable = REUSE.keepAlive(response, coreContext);
-
-        final int statusCode = response.getStatusLine().getStatusCode();
-        if (HttpURLConnection.HTTP_UNAVAILABLE == statusCode) {
-          // Could be sitting behind a load-balancer, try again.
-          continue;
-        }
-
-        return EntityUtils.toByteArray(response.getEntity());
-      } catch (Exception e) {
-        LOG.debug("Failed to execute HTTP request", e);
-        throw new RuntimeException(e);
-      } finally {
-        // Release the connection back to the pool, marking if it's good to reuse or not.
-        httpPool.release(entry, reusable);
-      }
-    }
-  }
-}
-
-// End AvaticaCommonsHttpClientImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
deleted file mode 100644
index eac1b74..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
+++ /dev/null
@@ -1,34 +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.remote;
-
-/**
- * An interface which defines how requests are sent to the Avatica server.
- */
-public interface AvaticaHttpClient {
-
-  /**
-   * Sends a serialized request to the Avatica server.
-   *
-   * @param request The serialized request.
-   * @return The serialized response.
-   */
-  byte[] send(byte[] request);
-
-}
-
-// End AvaticaHttpClient.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
deleted file mode 100644
index b5d213a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
+++ /dev/null
@@ -1,39 +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.remote;
-
-import org.apache.calcite.avatica.ConnectionConfig;
-
-import java.net.URL;
-
-/**
- * A factory for constructing {@link AvaticaHttpClient}'s.
- */
-public interface AvaticaHttpClientFactory {
-
-  /**
-   * Construct the appropriate implementation of {@link AvaticaHttpClient}.
-   *
-   * @param url URL that the client is for.
-   * @param config Configuration to use when constructing the implementation.
-   * @return An instance of {@link AvaticaHttpClient}.
-   */
-  AvaticaHttpClient getClient(URL url, ConnectionConfig config);
-
-}
-
-// End AvaticaHttpClientFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
deleted file mode 100644
index cd6cbce..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
+++ /dev/null
@@ -1,66 +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.remote;
-
-import org.apache.calcite.avatica.ConnectionConfig;
-
-import java.lang.reflect.Constructor;
-import java.net.URL;
-import java.util.Objects;
-
-/**
- * Default implementation of {@link AvaticaHttpClientFactory} which chooses an implementation
- * from a property.
- */
-public class AvaticaHttpClientFactoryImpl implements AvaticaHttpClientFactory {
-  public static final String HTTP_CLIENT_IMPL_DEFAULT =
-      AvaticaCommonsHttpClientImpl.class.getName();
-
-  // Public for Type.PLUGIN
-  public static final AvaticaHttpClientFactoryImpl INSTANCE = new AvaticaHttpClientFactoryImpl();
-
-  // Public for Type.PLUGIN
-  public AvaticaHttpClientFactoryImpl() {}
-
-  /**
-   * Returns a singleton instance of {@link AvaticaHttpClientFactoryImpl}.
-   *
-   * @return A singleton instance.
-   */
-  public static AvaticaHttpClientFactoryImpl getInstance() {
-    return INSTANCE;
-  }
-
-  @Override public AvaticaHttpClient getClient(URL url, ConnectionConfig config) {
-    String className = config.httpClientClass();
-    if (null == className) {
-      className = HTTP_CLIENT_IMPL_DEFAULT;
-    }
-
-    try {
-      Class<?> clz = Class.forName(className);
-      Constructor<?> constructor = clz.getConstructor(URL.class);
-      Object instance = constructor.newInstance(Objects.requireNonNull(url));
-      return AvaticaHttpClient.class.cast(instance);
-    } catch (Exception e) {
-      throw new RuntimeException("Failed to construct AvaticaHttpClient implementation "
-          + className, e);
-    }
-  }
-}
-
-// End AvaticaHttpClientFactoryImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
deleted file mode 100644
index c100eec..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
+++ /dev/null
@@ -1,73 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-/**
- * A common class to invoke HTTP requests against the Avatica server agnostic of the data being
- * sent and received across the wire.
- */
-public class AvaticaHttpClientImpl implements AvaticaHttpClient {
-  protected final URL url;
-
-  public AvaticaHttpClientImpl(URL url) {
-    this.url = url;
-  }
-
-  public byte[] send(byte[] request) {
-    // TODO back-off policy?
-    while (true) {
-      try {
-        final HttpURLConnection connection = openConnection();
-        connection.setRequestMethod("POST");
-        connection.setDoInput(true);
-        connection.setDoOutput(true);
-        try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
-          wr.write(request);
-          wr.flush();
-          wr.close();
-        }
-        final int responseCode = connection.getResponseCode();
-        final InputStream inputStream;
-        if (responseCode == HttpURLConnection.HTTP_UNAVAILABLE) {
-          // Could be sitting behind a load-balancer, try again.
-          continue;
-        } else if (responseCode != HttpURLConnection.HTTP_OK) {
-          inputStream = connection.getErrorStream();
-        } else {
-          inputStream = connection.getInputStream();
-        }
-        return AvaticaUtils.readFullyToBytes(inputStream);
-      } catch (IOException e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  HttpURLConnection openConnection() throws IOException {
-    return (HttpURLConnection) url.openConnection();
-  }
-}
-
-// End AvaticaHttpClientImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
deleted file mode 100644
index d5ae9b1..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
+++ /dev/null
@@ -1,36 +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.remote;
-
-import org.apache.calcite.avatica.ConnectionConfigImpl;
-
-import java.util.Properties;
-
-/** Implementation of {@link org.apache.calcite.avatica.ConnectionConfig}
- * with extra properties specific to Remote Driver. */
-public class AvaticaRemoteConnectionConfigImpl extends ConnectionConfigImpl {
-  public AvaticaRemoteConnectionConfigImpl(Properties properties) {
-    super(properties);
-  }
-
-  public Service.Factory factory() {
-    return AvaticaRemoteConnectionProperty.FACTORY.wrap(properties)
-        .getPlugin(Service.Factory.class, null);
-  }
-}
-
-// End AvaticaRemoteConnectionConfigImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
deleted file mode 100644
index 5e755f8..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
+++ /dev/null
@@ -1,80 +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.remote;
-
-import org.apache.calcite.avatica.ConnectionProperty;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import static org.apache.calcite.avatica.ConnectionConfigImpl.PropEnv;
-import static org.apache.calcite.avatica.ConnectionConfigImpl.parse;
-
-/**
- * Enumeration of Avatica remote driver's built-in connection properties.
- */
-public enum AvaticaRemoteConnectionProperty implements ConnectionProperty {
-  /** Factory. */
-  FACTORY("factory", Type.STRING, null);
-
-  private final String camelName;
-  private final Type type;
-  private final Object defaultValue;
-
-  private static final Map<String, AvaticaRemoteConnectionProperty> NAME_TO_PROPS;
-
-  static {
-    NAME_TO_PROPS = new HashMap<String, AvaticaRemoteConnectionProperty>();
-    for (AvaticaRemoteConnectionProperty p
-        : AvaticaRemoteConnectionProperty.values()) {
-      NAME_TO_PROPS.put(p.camelName.toUpperCase(), p);
-      NAME_TO_PROPS.put(p.name(), p);
-    }
-  }
-
-  AvaticaRemoteConnectionProperty(String camelName,
-      Type type,
-      Object defaultValue) {
-    this.camelName = camelName;
-    this.type = type;
-    this.defaultValue = defaultValue;
-    assert defaultValue == null || type.valid(defaultValue);
-  }
-
-  public String camelName() {
-    return camelName;
-  }
-
-  public Object defaultValue() {
-    return defaultValue;
-  }
-
-  public Type type() {
-    return type;
-  }
-
-  public PropEnv wrap(Properties properties) {
-    return new PropEnv(parse(properties, NAME_TO_PROPS), this);
-  }
-
-  public boolean required() {
-    return false;
-  }
-}
-
-// End AvaticaRemoteConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
deleted file mode 100644
index 2f9a1cd..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
+++ /dev/null
@@ -1,102 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaSeverity;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-
-import java.util.Objects;
-
-/**
- * A {@link RuntimeException} thrown by Avatica with additional contextual information about
- * what happened to cause the Exception.
- */
-public class AvaticaRuntimeException extends RuntimeException {
-  private static final long serialVersionUID = 1L;
-  private final String errorMessage;
-  private final int errorCode;
-  private final String sqlState;
-  private final AvaticaSeverity severity;
-
-  /**
-   * Constructs an {@code AvaticaRuntimeException} with no additional information.
-   *
-   * <p>It is strongly preferred that the caller invoke
-   * {@link #AvaticaRuntimeException(String, int, String, AvaticaSeverity)}
-   * with proper contextual information.
-   */
-  public AvaticaRuntimeException() {
-    this("No additional context on exception", ErrorResponse.UNKNOWN_ERROR_CODE,
-        ErrorResponse.UNKNOWN_SQL_STATE, AvaticaSeverity.UNKNOWN);
-  }
-
-  /**
-   * Constructs an {@code AvaticaRuntimeException} with the given
-   * contextual information surrounding the error.
-   *
-   * @param errorMessage A human-readable explanation about what happened
-   * @param errorCode Numeric identifier for error
-   * @param sqlState 5-character identifier for error
-   * @param severity Severity
-   */
-  public AvaticaRuntimeException(String errorMessage, int errorCode, String sqlState,
-      AvaticaSeverity severity) {
-    this.errorMessage = Objects.requireNonNull(errorMessage);
-    this.errorCode = errorCode;
-    this.sqlState = Objects.requireNonNull(sqlState);
-    this.severity = Objects.requireNonNull(severity);
-  }
-
-  /**
-   * Returns a human-readable error message.
-   */
-  public String getErrorMessage() {
-    return errorMessage;
-  }
-
-  /**
-   * Returns a numeric code for this error.
-   */
-  public int getErrorCode() {
-    return errorCode;
-  }
-
-  /**
-   * Returns the five-character identifier for this error.
-   */
-  public String getSqlState() {
-    return sqlState;
-  }
-
-  /**
-   * Returns the severity at which this exception is thrown.
-   */
-  public AvaticaSeverity getSeverity() {
-    return severity;
-  }
-
-  @Override public String toString() {
-    StringBuilder sb = new StringBuilder(64);
-    return sb.append("AvaticaRuntimeException: [")
-        .append("Messsage: '").append(errorMessage).append("', ")
-        .append("Error code: '").append(errorCode).append("', ")
-        .append("SQL State: '").append(sqlState).append("', ")
-        .append("Severity: '").append(severity).append("']").toString();
-  }
-}
-
-// End AvaticaRuntimeException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
deleted file mode 100644
index e98c486..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
+++ /dev/null
@@ -1,178 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.BuiltInConnectionProperty;
-import org.apache.calcite.avatica.ConnectionConfig;
-import org.apache.calcite.avatica.ConnectionProperty;
-import org.apache.calcite.avatica.DriverVersion;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.UnregisteredDriver;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Avatica Remote JDBC driver.
- */
-public class Driver extends UnregisteredDriver {
-  private static final Logger LOG = LoggerFactory.getLogger(Driver.class);
-  public static final String CONNECT_STRING_PREFIX = "jdbc:avatica:remote:";
-
-  static {
-    new Driver().register();
-  }
-
-  public Driver() {
-    super();
-  }
-
-  /**
-   * Defines the method of message serialization used by the Driver
-   */
-  public static enum Serialization {
-    JSON,
-    PROTOBUF;
-  }
-
-  @Override protected String getConnectStringPrefix() {
-    return CONNECT_STRING_PREFIX;
-  }
-
-  protected DriverVersion createDriverVersion() {
-    return DriverVersion.load(
-        Driver.class,
-        "org-apache-calcite-jdbc.properties",
-        "Avatica Remote JDBC Driver",
-        "unknown version",
-        "Avatica",
-        "unknown version");
-  }
-
-  @Override protected Collection<ConnectionProperty> getConnectionProperties() {
-    final List<ConnectionProperty> list = new ArrayList<ConnectionProperty>();
-    Collections.addAll(list, BuiltInConnectionProperty.values());
-    Collections.addAll(list, AvaticaRemoteConnectionProperty.values());
-    return list;
-  }
-
-  @Override public Meta createMeta(AvaticaConnection connection) {
-    final ConnectionConfig config = connection.config();
-    final Service service = createService(connection, config);
-    return new RemoteMeta(connection, service);
-  }
-
-  /**
-   * Creates a {@link Service} with the given {@link AvaticaConnection} and configuration.
-   *
-   * @param connection The {@link AvaticaConnection} to use.
-   * @param config Configuration properties
-   * @return A Service implementation.
-   */
-  Service createService(AvaticaConnection connection, ConnectionConfig config) {
-    final Service.Factory metaFactory = config.factory();
-    final Service service;
-    if (metaFactory != null) {
-      service = metaFactory.create(connection);
-    } else if (config.url() != null) {
-      final AvaticaHttpClient httpClient = getHttpClient(connection, config);
-      final Serialization serializationType = getSerialization(config);
-
-      LOG.debug("Instantiating {} service", serializationType);
-      switch (serializationType) {
-      case JSON:
-        service = new RemoteService(httpClient);
-        break;
-      case PROTOBUF:
-        service = new RemoteProtobufService(httpClient, new ProtobufTranslationImpl());
-        break;
-      default:
-        throw new IllegalArgumentException("Unhandled serialization type: " + serializationType);
-      }
-    } else {
-      service = new MockJsonService(Collections.<String, String>emptyMap());
-    }
-    return service;
-  }
-
-  /**
-   * Creates the HTTP client that communicates with the Avatica server.
-   *
-   * @param connection The {@link AvaticaConnection}.
-   * @param config The configuration.
-   * @return An {@link AvaticaHttpClient} implementation.
-   */
-  AvaticaHttpClient getHttpClient(AvaticaConnection connection, ConnectionConfig config) {
-    URL url;
-    try {
-      url = new URL(config.url());
-    } catch (MalformedURLException e) {
-      throw new RuntimeException(e);
-    }
-
-    AvaticaHttpClientFactory httpClientFactory = config.httpClientFactory();
-
-    return httpClientFactory.getClient(url, config);
-  }
-
-  @Override public Connection connect(String url, Properties info)
-      throws SQLException {
-    AvaticaConnection conn = (AvaticaConnection) super.connect(url, info);
-    if (conn == null) {
-      // It's not an url for our driver
-      return null;
-    }
-
-    // Create the corresponding remote connection
-    ConnectionConfig config = conn.config();
-    Service service = createService(conn, config);
-
-    service.apply(
-        new Service.OpenConnectionRequest(conn.id,
-            Service.OpenConnectionRequest.serializeProperties(info)));
-
-    return conn;
-  }
-
-  Serialization getSerialization(ConnectionConfig config) {
-    final String serializationStr = config.serialization();
-    Serialization serializationType = Serialization.JSON;
-    if (null != serializationStr) {
-      try {
-        serializationType = Serialization.valueOf(serializationStr.toUpperCase());
-      } catch (Exception e) {
-        // Log a warning instead of failing harshly? Intentionally no loggers available?
-        throw new RuntimeException(e);
-      }
-    }
-
-    return serializationType;
-  }
-}
-
-// End Driver.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/Handler.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Handler.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Handler.java
deleted file mode 100644
index 30d026c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Handler.java
+++ /dev/null
@@ -1,68 +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.remote;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import java.util.Objects;
-
-/**
- * API for text request-response calls to an Avatica server.
- *
- * @param <T> The type this handler accepts and returns
- */
-public interface Handler<T> {
-  int HTTP_OK = 200;
-  int HTTP_INTERNAL_SERVER_ERROR = 500;
-  String HANDLER_SERIALIZATION_METRICS_NAME = "Handler.Serialization";
-
-  /**
-   * Struct that encapsulates the context of the result of a request to Avatica.
-   */
-  public class HandlerResponse<T> {
-    private final T response;
-    private final int statusCode;
-
-    public HandlerResponse(T response, int statusCode) {
-      this.response = Objects.requireNonNull(response);
-      this.statusCode = statusCode;
-    }
-
-    public T getResponse() {
-      return response;
-    }
-
-    public int getStatusCode() {
-      return statusCode;
-    }
-
-    @Override public String toString() {
-      return "Response: " + response + ", Status:" + statusCode;
-    }
-  }
-
-  HandlerResponse<T> apply(T request);
-
-  /**
-   * Sets some general server information to return to the client in all responses.
-   *
-   * @param metadata Server-wide information
-   */
-  void setRpcMetadata(RpcMetadataResponse metadata);
-}
-
-// End Handler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
deleted file mode 100644
index fd57078..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.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.remote;
-
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.remote.Service.Request;
-import org.apache.calcite.avatica.remote.Service.Response;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.remote.Handler}
- * that decodes JSON requests, sends them to a {@link Service},
- * and encodes the responses into JSON.
- *
- * @see org.apache.calcite.avatica.remote.JsonService
- */
-public class JsonHandler extends AbstractHandler<String> {
-
-  protected static final ObjectMapper MAPPER = JsonService.MAPPER;
-
-  final MetricsSystem metrics;
-  final Timer serializationTimer;
-
-  public JsonHandler(Service service, MetricsSystem metrics) {
-    super(service);
-    this.metrics = metrics;
-    this.serializationTimer = this.metrics.getTimer(
-        MetricsHelper.concat(JsonHandler.class, HANDLER_SERIALIZATION_METRICS_NAME));
-  }
-
-  public HandlerResponse<String> apply(String jsonRequest) {
-    return super.apply(jsonRequest);
-  }
-
-  @Override Request decode(String request) throws IOException {
-    try (final Context ctx = serializationTimer.start()) {
-      return MAPPER.readValue(request, Service.Request.class);
-    }
-  }
-
-  /**
-   * Serializes the provided object as JSON.
-   *
-   * @param response The object to serialize.
-   * @return A JSON string.
-   */
-  @Override String encode(Response response) throws IOException {
-    try (final Context ctx = serializationTimer.start()) {
-      final StringWriter w = new StringWriter();
-      MAPPER.writeValue(w, response);
-      return w.toString();
-    }
-  }
-}
-
-// End JsonHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
deleted file mode 100644
index 668b3be..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
+++ /dev/null
@@ -1,227 +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.remote;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.remote.Service}
- * that encodes requests and responses as JSON.
- */
-public abstract class JsonService extends AbstractService {
-  public static final ObjectMapper MAPPER;
-  static {
-    MAPPER = new ObjectMapper();
-    MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
-    MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
-    MAPPER.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
-  }
-
-  public JsonService() {
-  }
-
-  /** Derived class should implement this method to transport requests and
-   * responses to and from the peer service. */
-  public abstract String apply(String request);
-
-  @Override SerializationType getSerializationType() {
-    return SerializationType.JSON;
-  }
-
-  //@VisibleForTesting
-  protected static <T> T decode(String response, Class<T> expectedType)
-      throws IOException {
-    Response resp = MAPPER.readValue(response, Response.class);
-    if (resp instanceof ErrorResponse) {
-      throw ((ErrorResponse) resp).toException();
-    } else if (!expectedType.isAssignableFrom(resp.getClass())) {
-      throw new ClassCastException("Cannot cast " + resp.getClass() + " into " + expectedType);
-    }
-
-    return expectedType.cast(resp);
-  }
-
-  //@VisibleForTesting
-  protected static <T> String encode(T request) throws IOException {
-    final StringWriter w = new StringWriter();
-    MAPPER.writeValue(w, request);
-    return w.toString();
-  }
-
-  protected RuntimeException handle(IOException e) {
-    return new RuntimeException(e);
-  }
-
-  public ResultSetResponse apply(CatalogsRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ResultSetResponse apply(SchemasRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ResultSetResponse apply(TablesRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ResultSetResponse apply(TableTypesRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ResultSetResponse apply(TypeInfoRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ResultSetResponse apply(ColumnsRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public PrepareResponse apply(PrepareRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), PrepareResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ExecuteResponse apply(PrepareAndExecuteRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ExecuteResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public FetchResponse apply(FetchRequest request) {
-    try {
-      return decode(apply(encode(request)), FetchResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ExecuteResponse apply(ExecuteRequest request) {
-    try {
-      return finagle(decode(apply(encode(request)), ExecuteResponse.class));
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public CreateStatementResponse apply(CreateStatementRequest request) {
-    try {
-      return decode(apply(encode(request)), CreateStatementResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public CloseStatementResponse apply(CloseStatementRequest request) {
-    try {
-      return decode(apply(encode(request)), CloseStatementResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public OpenConnectionResponse apply(OpenConnectionRequest request) {
-    try {
-      return decode(apply(encode(request)), OpenConnectionResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public CloseConnectionResponse apply(CloseConnectionRequest request) {
-    try {
-      return decode(apply(encode(request)), CloseConnectionResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
-    try {
-      return decode(apply(encode(request)), ConnectionSyncResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
-    try {
-      return decode(apply(encode(request)), DatabasePropertyResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public SyncResultsResponse apply(SyncResultsRequest request) {
-    try {
-      return decode(apply(encode(request)), SyncResultsResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public CommitResponse apply(CommitRequest request) {
-    try {
-      return decode(apply(encode(request)), CommitResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-
-  public RollbackResponse apply(RollbackRequest request) {
-    try {
-      return decode(apply(encode(request)), RollbackResponse.class);
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-}
-
-// End JsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
deleted file mode 100644
index 0af6300..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
+++ /dev/null
@@ -1,46 +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.remote;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.remote.Service}
- * that goes to an in-process instance of {@code Service}.
- */
-public class LocalJsonService extends JsonService {
-  private final Service service;
-
-  public LocalJsonService(Service service) {
-    this.service = service;
-  }
-
-  @Override public String apply(String request) {
-    try {
-      Request request2 = MAPPER.readValue(request, Request.class);
-      Response response2 = request2.accept(service);
-      final StringWriter w = new StringWriter();
-      MAPPER.writeValue(w, response2);
-      return w.toString();
-    } catch (IOException e) {
-      throw handle(e);
-    }
-  }
-}
-
-// End LocalJsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
deleted file mode 100644
index 76e2392..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
+++ /dev/null
@@ -1,58 +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.remote;
-
-import java.io.IOException;
-
-/**
- * A Service implementation that performs protocol buffer serialization on request and responses
- * on either side of computing a response from a request to mimic some transport to a server which
- * would normally perform such computation.
- */
-public class LocalProtobufService extends ProtobufService {
-  private final Service service;
-  private final ProtobufTranslation translation;
-
-  public LocalProtobufService(Service service, ProtobufTranslation translation) {
-    this.service = service;
-    this.translation = translation;
-  }
-
-  @Override public Response _apply(Request request) {
-    try {
-      // Serialize the request to "send to the server"
-      byte[] serializedRequest = translation.serializeRequest(request);
-
-      // *some transport would normally happen here*
-
-      // Fake deserializing that request somewhere else
-      Request request2 = translation.parseRequest(serializedRequest);
-
-      // Serialize the response from the service to "send to the client"
-      byte[] serializedResponse = translation.serializeResponse(request2.accept(service));
-
-      // *some transport would normally happen here*
-
-      // Deserialize the response on "the client"
-      return translation.parseResponse(serializedResponse);
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-}
-
-// End LocalProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
deleted file mode 100644
index c070ec0..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
+++ /dev/null
@@ -1,358 +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.remote;
-
-import org.apache.calcite.avatica.Meta;
-
-import org.apache.calcite.avatica.MetaImpl;
-import org.apache.calcite.avatica.MissingResultsException;
-import org.apache.calcite.avatica.NoSuchStatementException;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
-
-/**
- * Implementation of {@link Service} that talks to a local {@link Meta}.
- */
-public class LocalService implements Service {
-  final Meta meta;
-  final MetricsSystem metrics;
-
-  private final Timer executeTimer;
-  private final Timer commitTimer;
-  private final Timer prepareTimer;
-  private final Timer prepareAndExecuteTimer;
-  private final Timer connectionSyncTimer;
-
-  private RpcMetadataResponse serverLevelRpcMetadata;
-
-  public LocalService(Meta meta) {
-    this(meta, NoopMetricsSystem.getInstance());
-  }
-
-  public LocalService(Meta meta, MetricsSystem metrics) {
-    this.meta = meta;
-    this.metrics = Objects.requireNonNull(metrics);
-
-    this.executeTimer = this.metrics.getTimer(name("Execute"));
-    this.commitTimer = this.metrics.getTimer(name("Commit"));
-    this.prepareTimer = this.metrics.getTimer(name("Prepare"));
-    this.prepareAndExecuteTimer = this.metrics.getTimer(name("PrepareAndExecute"));
-    this.connectionSyncTimer = this.metrics.getTimer(name("ConnectionSync"));
-  }
-
-  private static String name(String timer) {
-    return concat(LocalService.class, timer);
-  }
-
-  @Override public void setRpcMetadata(RpcMetadataResponse serverLevelRpcMetadata) {
-    this.serverLevelRpcMetadata = Objects.requireNonNull(serverLevelRpcMetadata);
-  }
-
-  private static <E> List<E> list(Iterable<E> iterable) {
-    if (iterable instanceof List) {
-      return (List<E>) iterable;
-    }
-    final List<E> rowList = new ArrayList<>();
-    for (E row : iterable) {
-      rowList.add(row);
-    }
-    return rowList;
-  }
-
-  /** Converts a result set (not serializable) into a serializable response. */
-  public ResultSetResponse toResponse(Meta.MetaResultSet resultSet) {
-    if (resultSet.updateCount != -1) {
-      return new ResultSetResponse(resultSet.connectionId,
-          resultSet.statementId, resultSet.ownStatement, null, null,
-          resultSet.updateCount, serverLevelRpcMetadata);
-    }
-
-    Meta.Signature signature = resultSet.signature;
-    Meta.CursorFactory cursorFactory = resultSet.signature.cursorFactory;
-    Meta.Frame frame = null;
-    int updateCount = -1;
-    final List<Object> list;
-
-    if (resultSet.firstFrame != null) {
-      list = list(resultSet.firstFrame.rows);
-      switch (cursorFactory.style) {
-      case ARRAY:
-        cursorFactory = Meta.CursorFactory.LIST;
-        break;
-      case MAP:
-      case LIST:
-        break;
-      case RECORD:
-        cursorFactory = Meta.CursorFactory.LIST;
-        break;
-      default:
-        cursorFactory = Meta.CursorFactory.map(cursorFactory.fieldNames);
-      }
-
-      final boolean done = resultSet.firstFrame.done;
-
-      frame = new Meta.Frame(0, done, list);
-      updateCount = -1;
-
-      if (signature.statementType != null) {
-        if (signature.statementType.canUpdate()) {
-          frame = null;
-          updateCount = ((Number) ((List) list.get(0)).get(0)).intValue();
-        }
-      }
-    } else {
-      //noinspection unchecked
-      list = (List<Object>) (List) list2(resultSet);
-      cursorFactory = Meta.CursorFactory.LIST;
-    }
-
-    if (cursorFactory != resultSet.signature.cursorFactory) {
-      signature = signature.setCursorFactory(cursorFactory);
-    }
-
-    return new ResultSetResponse(resultSet.connectionId, resultSet.statementId,
-        resultSet.ownStatement, signature, frame, updateCount, serverLevelRpcMetadata);
-  }
-
-  private List<List<Object>> list2(Meta.MetaResultSet resultSet) {
-    final Meta.StatementHandle h = new Meta.StatementHandle(
-        resultSet.connectionId, resultSet.statementId, null);
-    final List<TypedValue> parameterValues = Collections.emptyList();
-    final Iterable<Object> iterable = meta.createIterable(h, null,
-        resultSet.signature, parameterValues, resultSet.firstFrame);
-    final List<List<Object>> list = new ArrayList<>();
-    return MetaImpl.collect(resultSet.signature.cursorFactory, iterable, list);
-  }
-
-  public ResultSetResponse apply(CatalogsRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet = meta.getCatalogs(ch);
-    return toResponse(resultSet);
-  }
-
-  public ResultSetResponse apply(SchemasRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet =
-        meta.getSchemas(ch, request.catalog, Meta.Pat.of(request.schemaPattern));
-    return toResponse(resultSet);
-  }
-
-  public ResultSetResponse apply(TablesRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet =
-        meta.getTables(ch,
-            request.catalog,
-            Meta.Pat.of(request.schemaPattern),
-            Meta.Pat.of(request.tableNamePattern),
-            request.typeList);
-    return toResponse(resultSet);
-  }
-
-  public ResultSetResponse apply(TableTypesRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet = meta.getTableTypes(ch);
-    return toResponse(resultSet);
-  }
-
-  public ResultSetResponse apply(TypeInfoRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet = meta.getTypeInfo(ch);
-    return toResponse(resultSet);
-  }
-
-  public ResultSetResponse apply(ColumnsRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.MetaResultSet resultSet =
-        meta.getColumns(ch,
-            request.catalog,
-            Meta.Pat.of(request.schemaPattern),
-            Meta.Pat.of(request.tableNamePattern),
-            Meta.Pat.of(request.columnNamePattern));
-    return toResponse(resultSet);
-  }
-
-  public PrepareResponse apply(PrepareRequest request) {
-    try (final Context ctx = prepareTimer.start()) {
-      final Meta.ConnectionHandle ch =
-          new Meta.ConnectionHandle(request.connectionId);
-      final Meta.StatementHandle h =
-          meta.prepare(ch, request.sql, request.maxRowCount);
-      return new PrepareResponse(h, serverLevelRpcMetadata);
-    }
-  }
-
-  public ExecuteResponse apply(PrepareAndExecuteRequest request) {
-    try (final Context ctx = prepareAndExecuteTimer.start()) {
-      final Meta.StatementHandle sh =
-          new Meta.StatementHandle(request.connectionId, request.statementId, null);
-      try {
-        final Meta.ExecuteResult executeResult =
-            meta.prepareAndExecute(sh, request.sql, request.maxRowCount,
-                new Meta.PrepareCallback() {
-                  @Override public Object getMonitor() {
-                    return LocalService.class;
-                  }
-
-                  @Override public void clear() {
-                  }
-
-                  @Override public void assign(Meta.Signature signature,
-                      Meta.Frame firstFrame, long updateCount) {
-                  }
-
-                  @Override public void execute() {
-                  }
-                });
-        final List<ResultSetResponse> results = new ArrayList<>();
-        for (Meta.MetaResultSet metaResultSet : executeResult.resultSets) {
-          results.add(toResponse(metaResultSet));
-        }
-        return new ExecuteResponse(results, false, serverLevelRpcMetadata);
-      } catch (NoSuchStatementException e) {
-        // The Statement doesn't exist anymore, bubble up this information
-        return new ExecuteResponse(null, true, serverLevelRpcMetadata);
-      }
-    }
-  }
-
-  public FetchResponse apply(FetchRequest request) {
-    final Meta.StatementHandle h = new Meta.StatementHandle(
-        request.connectionId, request.statementId, null);
-    try {
-      final Meta.Frame frame =
-          meta.fetch(h,
-              request.offset,
-              request.fetchMaxRowCount);
-      return new FetchResponse(frame, false, false, serverLevelRpcMetadata);
-    } catch (NullPointerException | NoSuchStatementException e) {
-      // The Statement doesn't exist anymore, bubble up this information
-      return new FetchResponse(null, true, true, serverLevelRpcMetadata);
-    } catch (MissingResultsException e) {
-      return new FetchResponse(null, false, true, serverLevelRpcMetadata);
-    }
-  }
-
-  public ExecuteResponse apply(ExecuteRequest request) {
-    try (final Context ctx = executeTimer.start()) {
-      try {
-        final Meta.ExecuteResult executeResult = meta.execute(request.statementHandle,
-            request.parameterValues, request.maxRowCount);
-
-        final List<ResultSetResponse> results = new ArrayList<>(executeResult.resultSets.size());
-        for (Meta.MetaResultSet metaResultSet : executeResult.resultSets) {
-          results.add(toResponse(metaResultSet));
-        }
-        return new ExecuteResponse(results, false, serverLevelRpcMetadata);
-      } catch (NoSuchStatementException e) {
-        return new ExecuteResponse(null, true, serverLevelRpcMetadata);
-      }
-    }
-  }
-
-  public CreateStatementResponse apply(CreateStatementRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    final Meta.StatementHandle h = meta.createStatement(ch);
-    return new CreateStatementResponse(h.connectionId, h.id, serverLevelRpcMetadata);
-  }
-
-  public CloseStatementResponse apply(CloseStatementRequest request) {
-    final Meta.StatementHandle h = new Meta.StatementHandle(
-        request.connectionId, request.statementId, null);
-    meta.closeStatement(h);
-    return new CloseStatementResponse(serverLevelRpcMetadata);
-  }
-
-  public OpenConnectionResponse apply(OpenConnectionRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    meta.openConnection(ch, request.info);
-    return new OpenConnectionResponse(serverLevelRpcMetadata);
-  }
-
-  public CloseConnectionResponse apply(CloseConnectionRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    meta.closeConnection(ch);
-    return new CloseConnectionResponse(serverLevelRpcMetadata);
-  }
-
-  public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
-    try (final Context ctx = connectionSyncTimer.start()) {
-      final Meta.ConnectionHandle ch =
-          new Meta.ConnectionHandle(request.connectionId);
-      final Meta.ConnectionProperties connProps =
-          meta.connectionSync(ch, request.connProps);
-      return new ConnectionSyncResponse(connProps, serverLevelRpcMetadata);
-    }
-  }
-
-  public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
-    final Meta.ConnectionHandle ch =
-        new Meta.ConnectionHandle(request.connectionId);
-    return new DatabasePropertyResponse(meta.getDatabaseProperties(ch), serverLevelRpcMetadata);
-  }
-
-  public SyncResultsResponse apply(SyncResultsRequest request) {
-    final Meta.StatementHandle h = new Meta.StatementHandle(
-        request.connectionId, request.statementId, null);
-    SyncResultsResponse response;
-    try {
-      // Set success on the cached statement
-      response = new SyncResultsResponse(meta.syncResults(h, request.state, request.offset), false,
-          serverLevelRpcMetadata);
-    } catch (NoSuchStatementException e) {
-      // Tried to sync results on a statement which wasn't cached
-      response = new SyncResultsResponse(false, true, serverLevelRpcMetadata);
-    }
-
-    return response;
-  }
-
-  public CommitResponse apply(CommitRequest request) {
-    try (final Context ctx = commitTimer.start()) {
-      meta.commit(new Meta.ConnectionHandle(request.connectionId));
-
-      // If commit() errors, let the ErrorResponse be sent back via an uncaught Exception.
-      return new CommitResponse();
-    }
-  }
-
-  public RollbackResponse apply(RollbackRequest request) {
-    meta.rollback(new Meta.ConnectionHandle(request.connectionId));
-
-    // If rollback() errors, let the ErrorResponse be sent back via an uncaught Exception.
-    return new RollbackResponse();
-  }
-}
-
-// End LocalService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
deleted file mode 100644
index 12a5b59..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
+++ /dev/null
@@ -1,181 +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.remote;
-
-import org.apache.calcite.avatica.proto.Common;
-
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-
-/**
- * Identifies an operation from {@link DatabaseMetaData} which returns a {@link ResultSet}. This
- * enum is used to allow clients to request the server to re-instantiate a {@link ResultSet} for
- * these operations which do not have a SQL string associated with them as a normal query does.
- */
-public enum MetaDataOperation {
-  GET_ATTRIBUTES,
-  GET_BEST_ROW_IDENTIFIER,
-  GET_CATALOGS,
-  GET_CLIENT_INFO_PROPERTIES,
-  GET_COLUMN_PRIVILEGES,
-  GET_COLUMNS,
-  GET_CROSS_REFERENCE,
-  GET_EXPORTED_KEYS,
-  GET_FUNCTION_COLUMNS,
-  GET_FUNCTIONS,
-  GET_IMPORTED_KEYS,
-  GET_INDEX_INFO,
-  GET_PRIMARY_KEYS,
-  GET_PROCEDURE_COLUMNS,
-  GET_PROCEDURES,
-  GET_PSEUDO_COLUMNS,
-  GET_SCHEMAS,
-  GET_SCHEMAS_WITH_ARGS,
-  GET_SUPER_TABLES,
-  GET_SUPER_TYPES,
-  GET_TABLE_PRIVILEGES,
-  GET_TABLES,
-  GET_TABLE_TYPES,
-  GET_TYPE_INFO,
-  GET_UDTS,
-  GET_VERSION_COLUMNS;
-
-  public Common.MetaDataOperation toProto() {
-    switch (this) {
-    case GET_ATTRIBUTES:
-      return Common.MetaDataOperation.GET_ATTRIBUTES;
-    case GET_BEST_ROW_IDENTIFIER:
-      return Common.MetaDataOperation.GET_BEST_ROW_IDENTIFIER;
-    case GET_CATALOGS:
-      return Common.MetaDataOperation.GET_CATALOGS;
-    case GET_CLIENT_INFO_PROPERTIES:
-      return Common.MetaDataOperation.GET_CLIENT_INFO_PROPERTIES;
-    case GET_COLUMNS:
-      return Common.MetaDataOperation.GET_COLUMNS;
-    case GET_COLUMN_PRIVILEGES:
-      return Common.MetaDataOperation.GET_COLUMN_PRIVILEGES;
-    case GET_CROSS_REFERENCE:
-      return Common.MetaDataOperation.GET_CROSS_REFERENCE;
-    case GET_EXPORTED_KEYS:
-      return Common.MetaDataOperation.GET_EXPORTED_KEYS;
-    case GET_FUNCTIONS:
-      return Common.MetaDataOperation.GET_FUNCTIONS;
-    case GET_FUNCTION_COLUMNS:
-      return Common.MetaDataOperation.GET_FUNCTION_COLUMNS;
-    case GET_IMPORTED_KEYS:
-      return Common.MetaDataOperation.GET_IMPORTED_KEYS;
-    case GET_INDEX_INFO:
-      return Common.MetaDataOperation.GET_INDEX_INFO;
-    case GET_PRIMARY_KEYS:
-      return Common.MetaDataOperation.GET_PRIMARY_KEYS;
-    case GET_PROCEDURES:
-      return Common.MetaDataOperation.GET_PROCEDURES;
-    case GET_PROCEDURE_COLUMNS:
-      return Common.MetaDataOperation.GET_PROCEDURE_COLUMNS;
-    case GET_PSEUDO_COLUMNS:
-      return Common.MetaDataOperation.GET_PSEUDO_COLUMNS;
-    case GET_SCHEMAS:
-      return Common.MetaDataOperation.GET_SCHEMAS;
-    case GET_SCHEMAS_WITH_ARGS:
-      return Common.MetaDataOperation.GET_SCHEMAS_WITH_ARGS;
-    case GET_SUPER_TABLES:
-      return Common.MetaDataOperation.GET_SUPER_TABLES;
-    case GET_SUPER_TYPES:
-      return Common.MetaDataOperation.GET_SUPER_TYPES;
-    case GET_TABLES:
-      return Common.MetaDataOperation.GET_TABLES;
-    case GET_TABLE_PRIVILEGES:
-      return Common.MetaDataOperation.GET_TABLE_PRIVILEGES;
-    case GET_TABLE_TYPES:
-      return Common.MetaDataOperation.GET_TABLE_TYPES;
-    case GET_TYPE_INFO:
-      return Common.MetaDataOperation.GET_TYPE_INFO;
-    case GET_UDTS:
-      return Common.MetaDataOperation.GET_UDTS;
-    case GET_VERSION_COLUMNS:
-      return Common.MetaDataOperation.GET_VERSION_COLUMNS;
-    default:
-      throw new RuntimeException("Unknown type: " + this);
-    }
-  }
-
-  public static MetaDataOperation fromProto(Common.MetaDataOperation protoOp) {
-    // Null is acceptable
-    if (null == protoOp) {
-      return null;
-    }
-
-    switch (protoOp) {
-    case GET_ATTRIBUTES:
-      return MetaDataOperation.GET_ATTRIBUTES;
-    case GET_BEST_ROW_IDENTIFIER:
-      return MetaDataOperation.GET_BEST_ROW_IDENTIFIER;
-    case GET_CATALOGS:
-      return MetaDataOperation.GET_CATALOGS;
-    case GET_CLIENT_INFO_PROPERTIES:
-      return MetaDataOperation.GET_CLIENT_INFO_PROPERTIES;
-    case GET_COLUMNS:
-      return MetaDataOperation.GET_COLUMNS;
-    case GET_COLUMN_PRIVILEGES:
-      return MetaDataOperation.GET_COLUMN_PRIVILEGES;
-    case GET_CROSS_REFERENCE:
-      return MetaDataOperation.GET_CROSS_REFERENCE;
-    case GET_EXPORTED_KEYS:
-      return MetaDataOperation.GET_EXPORTED_KEYS;
-    case GET_FUNCTIONS:
-      return MetaDataOperation.GET_FUNCTIONS;
-    case GET_FUNCTION_COLUMNS:
-      return MetaDataOperation.GET_FUNCTION_COLUMNS;
-    case GET_IMPORTED_KEYS:
-      return MetaDataOperation.GET_IMPORTED_KEYS;
-    case GET_INDEX_INFO:
-      return MetaDataOperation.GET_INDEX_INFO;
-    case GET_PRIMARY_KEYS:
-      return MetaDataOperation.GET_PRIMARY_KEYS;
-    case GET_PROCEDURES:
-      return MetaDataOperation.GET_PROCEDURES;
-    case GET_PROCEDURE_COLUMNS:
-      return MetaDataOperation.GET_PROCEDURE_COLUMNS;
-    case GET_PSEUDO_COLUMNS:
-      return MetaDataOperation.GET_PSEUDO_COLUMNS;
-    case GET_SCHEMAS:
-      return MetaDataOperation.GET_SCHEMAS;
-    case GET_SCHEMAS_WITH_ARGS:
-      return MetaDataOperation.GET_SCHEMAS_WITH_ARGS;
-    case GET_SUPER_TABLES:
-      return MetaDataOperation.GET_SUPER_TABLES;
-    case GET_SUPER_TYPES:
-      return MetaDataOperation.GET_SUPER_TYPES;
-    case GET_TABLES:
-      return MetaDataOperation.GET_TABLES;
-    case GET_TABLE_PRIVILEGES:
-      return MetaDataOperation.GET_TABLE_PRIVILEGES;
-    case GET_TABLE_TYPES:
-      return MetaDataOperation.GET_TABLE_TYPES;
-    case GET_TYPE_INFO:
-      return MetaDataOperation.GET_TYPE_INFO;
-    case GET_UDTS:
-      return MetaDataOperation.GET_UDTS;
-    case GET_VERSION_COLUMNS:
-      return MetaDataOperation.GET_VERSION_COLUMNS;
-    default:
-      throw new RuntimeException("Unknown type: " + protoOp);
-    }
-  }
-}
-
-// End MetaDataOperation.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
deleted file mode 100644
index 2561b29..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
+++ /dev/null
@@ -1,36 +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.remote;
-
-/**
- * A utility class to encapsulate common logic in use of metrics implementation.
- */
-public class MetricsHelper {
-
-  private static final String PERIOD = ".";
-
-  private MetricsHelper() {}
-
-  public static String concat(Class<?> clz, String name) {
-    StringBuilder sb = new StringBuilder();
-    sb.append(clz.getName());
-    return sb.append(PERIOD).append(name).toString();
-  }
-
-}
-
-// End MetricsHelper.java


[34/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
new file mode 100644
index 0000000..d96293b
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
@@ -0,0 +1,533 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.util.ByteString;
+import org.apache.calcite.avatica.util.DateTimeUtils;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.protobuf.HBaseZeroCopyByteString;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/** Value and type.
+ *
+ * <p>There are 3 representations:
+ * <ul>
+ *   <li>JDBC - the representation used by JDBC get and set methods
+ *   <li>Serial - suitable for serializing using JSON
+ *   <li>Local - used by Calcite for efficient computation
+ * </ul>
+ *
+ * <p>The following table shows the Java type(s) that may represent each SQL
+ * type in each representation.
+ *
+ * <table>
+ *   <caption>SQL types and their representations</caption>
+ *   <tr>
+ *     <th>Type</th> <th>JDBC</th> <th>Serial</th> <th>Local</th>
+ *   </tr>
+ *   <tr>
+ *     <td>BOOLEAN</td> <td>boolean</td> <td>boolean</td> <td>boolean</td>
+ *   </tr>
+ *   <tr>
+ *     <td>BINARY, VARBINARY</td> <td>byte[]</td>
+ *                    <td>String (base64)</td> <td>{@link ByteString}</td>
+ *   </tr>
+ *   <tr>
+ *     <td>DATE</td> <td>{@link java.sql.Date}</td>
+ *                                   <td>int</td> <td>int</td>
+ *   </tr>
+ *   <tr>
+ *     <td>TIME</td> <td>{@link java.sql.Time}</td>
+ *                                   <td>int</td> <td>int</td>
+ *   </tr>
+ *   <tr>
+ *     <td>DATE</td> <td>{@link java.sql.Timestamp}</td>
+ *                                   <td>long</td> <td>long</td>
+ *   </tr>
+ *   <tr>
+ *     <td>CHAR, VARCHAR</td>
+ *                   <td>String</td> <td>String</td> <td>String</td>
+ *   </tr>
+ *   <tr>
+ *     <td>TINYINT</td> <td>byte</td> <td>Number</td> <td>byte</td>
+ *   </tr>
+ *   <tr>
+ *     <td>SMALLINT</td> <td>short</td> <td>Number</td> <td>short</td>
+ *   </tr>
+ *   <tr>
+ *     <td>INTEGER</td> <td>int</td> <td>Number</td> <td>int</td>
+ *   </tr>
+ *   <tr>
+ *     <td>BIGINT</td> <td>long</td> <td>Number</td> <td>long</td>
+ *   </tr>
+ *   <tr>
+ *     <td>REAL</td> <td>float</td> <td>Number</td> <td>float</td>
+ *   </tr>
+ *   <tr>
+ *     <td>FLOAT, DOUBLE</td>
+ *                   <td>double</td> <td>Number</td> <td>double</td>
+ *   </tr>
+ *   <tr>
+ *     <td>DECIMAL</td>
+ *                   <td>BigDecimal</td> <td>Number</td> <td>BigDecimal</td>
+ *   </tr>
+ * </table>
+ *
+ * Note:
+ * <ul>
+ *   <li>The various numeric types (TINYINT, SMALLINT, INTEGER, BIGINT, REAL,
+ *   FLOAT, DOUBLE) are represented by {@link Number} in serial format because
+ *   JSON numbers are not strongly typed. A {@code float} value {@code 3.0} is
+ *   transmitted as {@code 3}, and is therefore decoded as an {@code int}.
+ *
+ *   <li>The date-time types (DATE, TIME, TIMESTAMP) are represented in JDBC as
+ *   {@link java.sql.Date}, {@link java.sql.Time}, {@link java.sql.Timestamp},
+ *   all sub-classes of {@link java.util.Date}. When they are passed to and
+ *   from the server, they are interpreted in terms of a time zone, by default
+ *   the current connection's time zone. Their serial and local representations
+ *   as {@code int} (days since 1970-01-01 for DATE, milliseconds since
+ *   00:00:00.000 for TIME), and long (milliseconds since 1970-01-01
+ *   00:00:00.000 for TIMESTAMP) are easier to work with, because it is clear
+ *   that time zone is not involved.
+ *
+ *   <li>BINARY and VARBINARY values are represented as base64-encoded strings
+ *   for serialization over JSON.
+ * </ul>
+ */
+public class TypedValue {
+  public static final TypedValue NULL =
+      new TypedValue(ColumnMetaData.Rep.OBJECT, null);
+
+  /** Type of the value. */
+  public final ColumnMetaData.Rep type;
+
+  /** Value.
+   *
+   * <p>Always in a form that can be serialized to JSON by Jackson.
+   * For example, byte arrays are represented as String. */
+  public final Object value;
+
+  private TypedValue(ColumnMetaData.Rep rep, Object value) {
+    this.type = rep;
+    this.value = value;
+    assert isSerial(rep, value) : "rep: " + rep + ", value: " + value;
+  }
+
+  private boolean isSerial(ColumnMetaData.Rep rep, Object value) {
+    if (value == null) {
+      return true;
+    }
+    switch (rep) {
+    case BYTE_STRING:
+      return value instanceof String;
+    case JAVA_SQL_DATE:
+    case JAVA_SQL_TIME:
+      return value instanceof Integer;
+    case JAVA_SQL_TIMESTAMP:
+    case JAVA_UTIL_DATE:
+      return value instanceof Long;
+    default:
+      return true;
+    }
+  }
+
+  @JsonCreator
+  public static TypedValue create(@JsonProperty("type") String type,
+      @JsonProperty("value") Object value) {
+    if (value == null) {
+      return NULL;
+    }
+    ColumnMetaData.Rep rep = ColumnMetaData.Rep.valueOf(type);
+    return ofLocal(rep, serialToLocal(rep, value));
+  }
+
+  /** Creates a TypedValue from a value in local representation. */
+  public static TypedValue ofLocal(ColumnMetaData.Rep rep, Object value) {
+    return new TypedValue(rep, localToSerial(rep, value));
+  }
+
+  /** Creates a TypedValue from a value in serial representation. */
+  public static TypedValue ofSerial(ColumnMetaData.Rep rep, Object value) {
+    return new TypedValue(rep, value);
+  }
+
+  /** Creates a TypedValue from a value in JDBC representation. */
+  public static TypedValue ofJdbc(ColumnMetaData.Rep rep, Object value,
+      Calendar calendar) {
+    if (value == null) {
+      return NULL;
+    }
+    return new TypedValue(rep, jdbcToSerial(rep, value, calendar));
+  }
+
+  /** Creates a TypedValue from a value in JDBC representation,
+   * deducing its type. */
+  public static TypedValue ofJdbc(Object value, Calendar calendar) {
+    if (value == null) {
+      return NULL;
+    }
+    final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(value.getClass());
+    return new TypedValue(rep, jdbcToSerial(rep, value, calendar));
+  }
+
+  /** Converts the value into the local representation.
+   *
+   * <p>For example, a byte string is represented as a {@link ByteString};
+   * a long is represented as a {@link Long} (not just some {@link Number}).
+   */
+  public Object toLocal() {
+    if (value == null) {
+      return null;
+    }
+    return serialToLocal(type, value);
+  }
+
+  /** Converts a value to the exact type required for the given
+   * representation. */
+  private static Object serialToLocal(ColumnMetaData.Rep rep, Object value) {
+    assert value != null;
+    if (value.getClass() == rep.clazz) {
+      return value;
+    }
+    switch (rep) {
+    case BYTE:
+      return ((Number) value).byteValue();
+    case SHORT:
+      return ((Number) value).shortValue();
+    case INTEGER:
+    case JAVA_SQL_DATE:
+    case JAVA_SQL_TIME:
+      return ((Number) value).intValue();
+    case LONG:
+    case JAVA_UTIL_DATE:
+    case JAVA_SQL_TIMESTAMP:
+      return ((Number) value).longValue();
+    case FLOAT:
+      return ((Number) value).floatValue();
+    case DOUBLE:
+      return ((Number) value).doubleValue();
+    case NUMBER:
+      return value instanceof BigDecimal ? value
+          : value instanceof BigInteger ? new BigDecimal((BigInteger) value)
+          : value instanceof Double ? new BigDecimal((Double) value)
+          : value instanceof Float ? new BigDecimal((Float) value)
+          : new BigDecimal(((Number) value).longValue());
+    case BYTE_STRING:
+      return ByteString.ofBase64((String) value);
+    default:
+      throw new IllegalArgumentException("cannot convert " + value + " ("
+          + value.getClass() + ") to " + rep);
+    }
+  }
+
+  /** Converts the value into the JDBC representation.
+   *
+   * <p>For example, a byte string is represented as a {@link ByteString};
+   * a long is represented as a {@link Long} (not just some {@link Number}).
+   */
+  public Object toJdbc(Calendar calendar) {
+    if (value == null) {
+      return null;
+    }
+    return serialToJdbc(type, value, calendar);
+  }
+
+  private static Object serialToJdbc(ColumnMetaData.Rep type, Object value,
+      Calendar calendar) {
+    switch (type) {
+    case BYTE_STRING:
+      return ByteString.ofBase64((String) value).getBytes();
+    case JAVA_UTIL_DATE:
+      return new java.util.Date(adjust((Number) value, calendar));
+    case JAVA_SQL_DATE:
+      return new java.sql.Date(
+          adjust(((Number) value).longValue() * DateTimeUtils.MILLIS_PER_DAY,
+              calendar));
+    case JAVA_SQL_TIME:
+      return new java.sql.Time(adjust((Number) value, calendar));
+    case JAVA_SQL_TIMESTAMP:
+      return new java.sql.Timestamp(adjust((Number) value, calendar));
+    default:
+      return serialToLocal(type, value);
+    }
+  }
+
+  private static long adjust(Number number, Calendar calendar) {
+    long t = number.longValue();
+    if (calendar != null) {
+      t -= calendar.getTimeZone().getOffset(t);
+    }
+    return t;
+  }
+
+  /** Converts a value from JDBC format to a type that can be serialized as
+   * JSON. */
+  private static Object jdbcToSerial(ColumnMetaData.Rep rep, Object value,
+      Calendar calendar) {
+    switch (rep) {
+    case BYTE_STRING:
+      return new ByteString((byte[]) value).toBase64String();
+    case JAVA_UTIL_DATE:
+    case JAVA_SQL_TIMESTAMP:
+    case JAVA_SQL_DATE:
+    case JAVA_SQL_TIME:
+      long t = ((Date) value).getTime();
+      if (calendar != null) {
+        t += calendar.getTimeZone().getOffset(t);
+      }
+      switch (rep) {
+      case JAVA_SQL_DATE:
+        return (int) DateTimeUtils.floorDiv(t, DateTimeUtils.MILLIS_PER_DAY);
+      case JAVA_SQL_TIME:
+        return (int) DateTimeUtils.floorMod(t, DateTimeUtils.MILLIS_PER_DAY);
+      default:
+        return t;
+      }
+    default:
+      return value;
+    }
+  }
+
+  /** Converts a value from internal format to a type that can be serialized
+   * as JSON. */
+  private static Object localToSerial(ColumnMetaData.Rep rep, Object value) {
+    switch (rep) {
+    case BYTE_STRING:
+      return ((ByteString) value).toBase64String();
+    default:
+      return value;
+    }
+  }
+
+  /** Converts a list of {@code TypedValue} to a list of values. */
+  public static List<Object> values(List<TypedValue> typedValues) {
+    final List<Object> list = new ArrayList<>();
+    for (TypedValue typedValue : typedValues) {
+      list.add(typedValue.toLocal());
+    }
+    return list;
+  }
+
+  public Common.TypedValue toProto() {
+    final Common.TypedValue.Builder builder = Common.TypedValue.newBuilder();
+
+    Common.Rep protoRep = type.toProto();
+    builder.setType(protoRep);
+
+    // Serialize the type into the protobuf
+    switch (protoRep) {
+    case BOOLEAN:
+    case PRIMITIVE_BOOLEAN:
+      builder.setBoolValue((boolean) value);
+      break;
+    case BYTE_STRING:
+    case STRING:
+      builder.setStringValueBytes(HBaseZeroCopyByteString.wrap(((String) value).getBytes()));
+      break;
+    case PRIMITIVE_CHAR:
+    case CHARACTER:
+      builder.setStringValue(Character.toString((char) value));
+      break;
+    case BYTE:
+    case PRIMITIVE_BYTE:
+      builder.setNumberValue(Byte.valueOf((byte) value).longValue());
+      break;
+    case DOUBLE:
+    case PRIMITIVE_DOUBLE:
+      builder.setDoubleValue((double) value);
+      break;
+    case FLOAT:
+    case PRIMITIVE_FLOAT:
+      builder.setNumberValue(Float.floatToIntBits((float) value));
+      break;
+    case INTEGER:
+    case PRIMITIVE_INT:
+      builder.setNumberValue(Integer.valueOf((int) value).longValue());
+      break;
+    case PRIMITIVE_SHORT:
+    case SHORT:
+      builder.setNumberValue(Short.valueOf((short) value).longValue());
+      break;
+    case LONG:
+    case PRIMITIVE_LONG:
+      builder.setNumberValue((long) value);
+      break;
+    case JAVA_SQL_DATE:
+    case JAVA_SQL_TIME:
+      // Persisted as integers
+      builder.setNumberValue(Integer.valueOf((int) value).longValue());
+      break;
+    case JAVA_SQL_TIMESTAMP:
+    case JAVA_UTIL_DATE:
+      // Persisted as longs
+      builder.setNumberValue((long) value);
+      break;
+    case BIG_INTEGER:
+      byte[] bytes = ((BigInteger) value).toByteArray();
+      builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bytes));
+      break;
+    case BIG_DECIMAL:
+      final BigDecimal bigDecimal = (BigDecimal) value;
+      final int scale = bigDecimal.scale();
+      final BigInteger bigInt = bigDecimal.toBigInteger();
+      builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bigInt.toByteArray()))
+        .setNumberValue(scale);
+      break;
+    case NUMBER:
+      builder.setNumberValue(((Number) value).longValue());
+      break;
+    case OBJECT:
+      if (null == value) {
+        // We can persist a null value through easily
+        builder.setNull(true);
+        break;
+      }
+      // Intentional fall-through to RTE because we can't serialize something we have no type
+      // insight into.
+    case UNRECOGNIZED:
+      // Fail?
+      throw new RuntimeException("Unhandled value: " + protoRep + " " + value.getClass());
+    default:
+      // Fail?
+      throw new RuntimeException("Unknown serialized type: " + protoRep);
+    }
+
+    return builder.build();
+  }
+
+  public static TypedValue fromProto(Common.TypedValue proto) {
+    ColumnMetaData.Rep rep = ColumnMetaData.Rep.fromProto(proto.getType());
+
+    Object value = null;
+
+    // Deserialize the value again
+    switch (proto.getType()) {
+    case BOOLEAN:
+    case PRIMITIVE_BOOLEAN:
+      value = proto.getBoolValue();
+      break;
+    case BYTE_STRING:
+    case STRING:
+      value = proto.getStringValue();
+      break;
+    case PRIMITIVE_CHAR:
+    case CHARACTER:
+      value = proto.getStringValue().charAt(0);
+      break;
+    case BYTE:
+    case PRIMITIVE_BYTE:
+      value = Long.valueOf(proto.getNumberValue()).byteValue();
+      break;
+    case DOUBLE:
+    case PRIMITIVE_DOUBLE:
+      value = proto.getDoubleValue();
+      break;
+    case FLOAT:
+    case PRIMITIVE_FLOAT:
+      value = Float.intBitsToFloat((int) proto.getNumberValue());
+      break;
+    case INTEGER:
+    case PRIMITIVE_INT:
+      value = Long.valueOf(proto.getNumberValue()).intValue();
+      break;
+    case PRIMITIVE_SHORT:
+    case SHORT:
+      value = Long.valueOf(proto.getNumberValue()).shortValue();
+      break;
+    case LONG:
+    case PRIMITIVE_LONG:
+      value = Long.valueOf(proto.getNumberValue());
+      break;
+    case JAVA_SQL_DATE:
+    case JAVA_SQL_TIME:
+      value = Long.valueOf(proto.getNumberValue()).intValue();
+      break;
+    case JAVA_SQL_TIMESTAMP:
+    case JAVA_UTIL_DATE:
+      value = proto.getNumberValue();
+      break;
+    case BIG_INTEGER:
+      value = new BigInteger(proto.getBytesValues().toByteArray());
+      break;
+    case BIG_DECIMAL:
+      BigInteger bigInt = new BigInteger(proto.getBytesValues().toByteArray());
+      value = new BigDecimal(bigInt, (int) proto.getNumberValue());
+      break;
+    case NUMBER:
+      value = Long.valueOf(proto.getNumberValue());
+      break;
+    case OBJECT:
+      if (proto.getNull()) {
+        value = null;
+        break;
+      }
+      // Intentional fall through to RTE. If we sent an object over the wire, it could only
+      // possibly be null (at this point). Anything else has to be an error.
+    case UNRECOGNIZED:
+      // Fail?
+      throw new RuntimeException("Unhandled type: " + proto.getType());
+    default:
+      // Fail?
+      throw new RuntimeException("Unknown type: " + proto.getType());
+    }
+
+    return new TypedValue(rep, value);
+  }
+
+  @Override public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((type == null) ? 0 : type.hashCode());
+    result = prime * result + ((value == null) ? 0 : value.hashCode());
+    return result;
+  }
+
+  @Override public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (o instanceof TypedValue) {
+      TypedValue other = (TypedValue) o;
+
+      if (type != other.type) {
+        return false;
+      }
+
+      if (null == value) {
+        if (null != other.value) {
+          return false;
+        }
+      }
+
+      return value.equals(other.value);
+    }
+
+    return false;
+  }
+}
+
+// End TypedValue.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/package-info.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/package-info.java
new file mode 100644
index 0000000..1cf3e14
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDBC driver that uses remote procedure calls.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.remote;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
new file mode 100644
index 0000000..70f87a7
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
@@ -0,0 +1,1377 @@
+/*
+ * 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.util;
+
+import org.apache.calcite.avatica.AvaticaSite;
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.ColumnMetaData;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+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.Map;
+
+/**
+ * Base class for implementing a cursor.
+ *
+ * <p>Derived class needs to provide {@link Getter} and can override
+ * {@link org.apache.calcite.avatica.util.Cursor.Accessor} implementations if it
+ * wishes.</p>
+ */
+public abstract class AbstractCursor implements Cursor {
+  /**
+   * Slot into which each accessor should write whether the
+   * value returned was null.
+   */
+  protected final boolean[] wasNull = {false};
+
+  protected AbstractCursor() {
+  }
+
+  public boolean wasNull() {
+    return wasNull[0];
+  }
+
+  public List<Accessor> createAccessors(List<ColumnMetaData> types,
+      Calendar localCalendar, ArrayImpl.Factory factory) {
+    List<Accessor> accessors = new ArrayList<>();
+    for (ColumnMetaData type : types) {
+      accessors.add(
+          createAccessor(type, accessors.size(), localCalendar, factory));
+    }
+    return accessors;
+  }
+
+  protected Accessor createAccessor(ColumnMetaData columnMetaData, int ordinal,
+      Calendar localCalendar, ArrayImpl.Factory factory) {
+    // Create an accessor appropriate to the underlying type; the accessor
+    // can convert to any type in the same family.
+    Getter getter = createGetter(ordinal);
+    return createAccessor(columnMetaData, getter, localCalendar, factory);
+  }
+
+  protected Accessor createAccessor(ColumnMetaData columnMetaData,
+      Getter getter, Calendar localCalendar, ArrayImpl.Factory factory) {
+    switch (columnMetaData.type.rep) {
+    case NUMBER:
+      switch (columnMetaData.type.id) {
+      case Types.TINYINT:
+      case Types.SMALLINT:
+      case Types.INTEGER:
+      case Types.BIGINT:
+      case Types.REAL:
+      case Types.FLOAT:
+      case Types.DOUBLE:
+      case Types.NUMERIC:
+      case Types.DECIMAL:
+        return new NumberAccessor(getter, columnMetaData.scale);
+      }
+    }
+    switch (columnMetaData.type.id) {
+    case Types.TINYINT:
+      return new ByteAccessor(getter);
+    case Types.SMALLINT:
+      return new ShortAccessor(getter);
+    case Types.INTEGER:
+      return new IntAccessor(getter);
+    case Types.BIGINT:
+      return new LongAccessor(getter);
+    case Types.BOOLEAN:
+      return new BooleanAccessor(getter);
+    case Types.REAL:
+      return new FloatAccessor(getter);
+    case Types.FLOAT:
+    case Types.DOUBLE:
+      return new DoubleAccessor(getter);
+    case Types.DECIMAL:
+      return new BigDecimalAccessor(getter);
+    case Types.CHAR:
+      switch (columnMetaData.type.rep) {
+      case PRIMITIVE_CHAR:
+      case CHARACTER:
+        return new StringFromCharAccessor(getter, columnMetaData.displaySize);
+      default:
+        return new FixedStringAccessor(getter, columnMetaData.displaySize);
+      }
+    case Types.VARCHAR:
+      return new StringAccessor(getter);
+    case Types.BINARY:
+    case Types.VARBINARY:
+      switch (columnMetaData.type.rep) {
+      case STRING:
+        return new BinaryFromStringAccessor(getter);
+      default:
+        return new BinaryAccessor(getter);
+      }
+    case Types.DATE:
+      switch (columnMetaData.type.rep) {
+      case PRIMITIVE_INT:
+      case INTEGER:
+      case NUMBER:
+        return new DateFromNumberAccessor(getter, localCalendar);
+      case JAVA_SQL_DATE:
+        return new DateAccessor(getter);
+      default:
+        throw new AssertionError("bad " + columnMetaData.type.rep);
+      }
+    case Types.TIME:
+      switch (columnMetaData.type.rep) {
+      case PRIMITIVE_INT:
+      case INTEGER:
+      case NUMBER:
+        return new TimeFromNumberAccessor(getter, localCalendar);
+      case JAVA_SQL_TIME:
+        return new TimeAccessor(getter);
+      default:
+        throw new AssertionError("bad " + columnMetaData.type.rep);
+      }
+    case Types.TIMESTAMP:
+      switch (columnMetaData.type.rep) {
+      case PRIMITIVE_LONG:
+      case LONG:
+      case NUMBER:
+        return new TimestampFromNumberAccessor(getter, localCalendar);
+      case JAVA_SQL_TIMESTAMP:
+        return new TimestampAccessor(getter);
+      case JAVA_UTIL_DATE:
+        return new TimestampFromUtilDateAccessor(getter, localCalendar);
+      default:
+        throw new AssertionError("bad " + columnMetaData.type.rep);
+      }
+    case Types.ARRAY:
+      final ColumnMetaData.ArrayType arrayType =
+          (ColumnMetaData.ArrayType) columnMetaData.type;
+      final SlotGetter componentGetter = new SlotGetter();
+      final Accessor componentAccessor =
+          createAccessor(ColumnMetaData.dummy(arrayType.component, true),
+              componentGetter, localCalendar, factory);
+      return new ArrayAccessor(getter, arrayType.component, componentAccessor,
+          componentGetter, factory);
+    case Types.STRUCT:
+      switch (columnMetaData.type.rep) {
+      case OBJECT:
+        final ColumnMetaData.StructType structType =
+            (ColumnMetaData.StructType) columnMetaData.type;
+        List<Accessor> accessors = new ArrayList<>();
+        for (ColumnMetaData column : structType.columns) {
+          final Getter fieldGetter =
+              structType.columns.size() == 1
+                  ? getter
+                  : new StructGetter(getter, column);
+          accessors.add(
+              createAccessor(column, fieldGetter, localCalendar, factory));
+        }
+        return new StructAccessor(getter, accessors);
+      default:
+        throw new AssertionError("bad " + columnMetaData.type.rep);
+      }
+    case Types.JAVA_OBJECT:
+    case Types.OTHER: // e.g. map
+      if (columnMetaData.type.name.startsWith("INTERVAL_")) {
+        int end = columnMetaData.type.name.indexOf("(");
+        if (end < 0) {
+          end = columnMetaData.type.name.length();
+        }
+        TimeUnitRange range =
+            TimeUnitRange.valueOf(
+                columnMetaData.type.name.substring("INTERVAL_".length(), end));
+        if (range.monthly()) {
+          return new IntervalYearMonthAccessor(getter, range);
+        } else {
+          return new IntervalDayTimeAccessor(getter, range,
+              columnMetaData.scale);
+        }
+      }
+      return new ObjectAccessor(getter);
+    default:
+      throw new RuntimeException("unknown type " + columnMetaData.type.id);
+    }
+  }
+
+  protected abstract Getter createGetter(int ordinal);
+
+  public abstract boolean next();
+
+  /** Accesses a timestamp value as a string.
+   * The timestamp is in SQL format (e.g. "2013-09-22 22:30:32"),
+   * not Java format ("2013-09-22 22:30:32.123"). */
+  private static String timestampAsString(long v, Calendar calendar) {
+    if (calendar != null) {
+      v -= calendar.getTimeZone().getOffset(v);
+    }
+    return DateTimeUtils.unixTimestampToString(v);
+  }
+
+  /** Accesses a date value as a string, e.g. "2013-09-22". */
+  private static String dateAsString(int v, Calendar calendar) {
+    AvaticaUtils.discard(calendar); // time zone shift doesn't make sense
+    return DateTimeUtils.unixDateToString(v);
+  }
+
+  /** Accesses a time value as a string, e.g. "22:30:32". */
+  private static String timeAsString(int v, Calendar calendar) {
+    if (calendar != null) {
+      v -= calendar.getTimeZone().getOffset(v);
+    }
+    return DateTimeUtils.unixTimeToString(v);
+  }
+
+  private static Date longToDate(long v, Calendar calendar) {
+    if (calendar != null) {
+      v -= calendar.getTimeZone().getOffset(v);
+    }
+    return new Date(v);
+  }
+
+  static Time intToTime(int v, Calendar calendar) {
+    if (calendar != null) {
+      v -= calendar.getTimeZone().getOffset(v);
+    }
+    return new Time(v);
+  }
+
+  static Timestamp longToTimestamp(long v, Calendar calendar) {
+    if (calendar != null) {
+      v -= calendar.getTimeZone().getOffset(v);
+    }
+    return new Timestamp(v);
+  }
+
+  /** Implementation of {@link Cursor.Accessor}. */
+  static class AccessorImpl implements Accessor {
+    protected final Getter getter;
+
+    public AccessorImpl(Getter getter) {
+      assert getter != null;
+      this.getter = getter;
+    }
+
+    public boolean wasNull() {
+      return getter.wasNull();
+    }
+
+    public String getString() {
+      final Object o = getObject();
+      return o == null ? null : o.toString();
+    }
+
+    public boolean getBoolean() {
+      return getLong() != 0L;
+    }
+
+    public byte getByte() {
+      return (byte) getLong();
+    }
+
+    public short getShort() {
+      return (short) getLong();
+    }
+
+    public int getInt() {
+      return (int) getLong();
+    }
+
+    public long getLong() {
+      throw cannotConvert("long");
+    }
+
+    public float getFloat() {
+      return (float) getDouble();
+    }
+
+    public double getDouble() {
+      throw cannotConvert("double");
+    }
+
+    public BigDecimal getBigDecimal() {
+      throw cannotConvert("BigDecimal");
+    }
+
+    public BigDecimal getBigDecimal(int scale) {
+      throw cannotConvert("BigDecimal with scale");
+    }
+
+    public byte[] getBytes() {
+      throw cannotConvert("byte[]");
+    }
+
+    public InputStream getAsciiStream() {
+      throw cannotConvert("InputStream (ascii)");
+    }
+
+    public InputStream getUnicodeStream() {
+      throw cannotConvert("InputStream (unicode)");
+    }
+
+    public InputStream getBinaryStream() {
+      throw cannotConvert("InputStream (binary)");
+    }
+
+    public Object getObject() {
+      return getter.getObject();
+    }
+
+    public Reader getCharacterStream() {
+      throw cannotConvert("Reader");
+    }
+
+    private RuntimeException cannotConvert(String targetType) {
+      return new RuntimeException("cannot convert to " + targetType + " ("
+          + this + ")");
+    }
+
+    public Object getObject(Map<String, Class<?>> map) {
+      throw cannotConvert("Object (with map)");
+    }
+
+    public Ref getRef() {
+      throw cannotConvert("Ref");
+    }
+
+    public Blob getBlob() {
+      throw cannotConvert("Blob");
+    }
+
+    public Clob getClob() {
+      throw cannotConvert("Clob");
+    }
+
+    public Array getArray() {
+      throw cannotConvert("Array");
+    }
+
+    public Struct getStruct() {
+      throw cannotConvert("Struct");
+    }
+
+    public Date getDate(Calendar calendar) {
+      throw cannotConvert("Date");
+    }
+
+    public Time getTime(Calendar calendar) {
+      throw cannotConvert("Time");
+    }
+
+    public Timestamp getTimestamp(Calendar calendar) {
+      throw cannotConvert("Timestamp");
+    }
+
+    public URL getURL() {
+      throw cannotConvert("URL");
+    }
+
+    public NClob getNClob() {
+      throw cannotConvert("NClob");
+    }
+
+    public SQLXML getSQLXML() {
+      throw cannotConvert("SQLXML");
+    }
+
+    public String getNString() {
+      throw cannotConvert("NString");
+    }
+
+    public Reader getNCharacterStream() {
+      throw cannotConvert("NCharacterStream");
+    }
+
+    public <T> T getObject(Class<T> type) {
+      throw cannotConvert("Object (with type)");
+    }
+  }
+
+  /**
+   * Accessor of exact numeric values. The subclass must implement the
+   * {@link #getLong()} method.
+   */
+  private abstract static class ExactNumericAccessor extends AccessorImpl {
+    public ExactNumericAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public BigDecimal getBigDecimal(int scale) {
+      final long v = getLong();
+      if (v == 0 && getter.wasNull()) {
+        return null;
+      }
+      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
+    }
+
+    public BigDecimal getBigDecimal() {
+      final long val = getLong();
+      if (val == 0 && getter.wasNull()) {
+        return null;
+      }
+      return BigDecimal.valueOf(val);
+    }
+
+    public double getDouble() {
+      return getLong();
+    }
+
+    public float getFloat() {
+      return getLong();
+    }
+
+    public abstract long getLong();
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Boolean};
+   * corresponds to {@link java.sql.Types#BOOLEAN}.
+   */
+  private static class BooleanAccessor extends ExactNumericAccessor {
+    public BooleanAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public boolean getBoolean() {
+      Boolean o = (Boolean) getObject();
+      return o != null && o;
+    }
+
+    public long getLong() {
+      return getBoolean() ? 1 : 0;
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Byte};
+   * corresponds to {@link java.sql.Types#TINYINT}.
+   */
+  private static class ByteAccessor extends ExactNumericAccessor {
+    public ByteAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public byte getByte() {
+      Byte o = (Byte) getObject();
+      return o == null ? 0 : o;
+    }
+
+    public long getLong() {
+      return getByte();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Short};
+   * corresponds to {@link java.sql.Types#SMALLINT}.
+   */
+  private static class ShortAccessor extends ExactNumericAccessor {
+    public ShortAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public short getShort() {
+      Short o = (Short) getObject();
+      return o == null ? 0 : o;
+    }
+
+    public long getLong() {
+      return getShort();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is an {@link Integer};
+   * corresponds to {@link java.sql.Types#INTEGER}.
+   */
+  private static class IntAccessor extends ExactNumericAccessor {
+    public IntAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public int getInt() {
+      Integer o = (Integer) super.getObject();
+      return o == null ? 0 : o;
+    }
+
+    public long getLong() {
+      return getInt();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Long};
+   * corresponds to {@link java.sql.Types#BIGINT}.
+   */
+  private static class LongAccessor extends ExactNumericAccessor {
+    public LongAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public long getLong() {
+      Long o = (Long) super.getObject();
+      return o == null ? 0 : o;
+    }
+  }
+
+  /**
+   * Accessor of values that are {@link Double} or null.
+   */
+  private abstract static class ApproximateNumericAccessor
+      extends AccessorImpl {
+    public ApproximateNumericAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public BigDecimal getBigDecimal(int scale) {
+      final double v = getDouble();
+      if (v == 0d && getter.wasNull()) {
+        return null;
+      }
+      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
+    }
+
+    public BigDecimal getBigDecimal() {
+      final double v = getDouble();
+      if (v == 0 && getter.wasNull()) {
+        return null;
+      }
+      return BigDecimal.valueOf(v);
+    }
+
+    public abstract double getDouble();
+
+    public long getLong() {
+      return (long) getDouble();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Float};
+   * corresponds to {@link java.sql.Types#FLOAT}.
+   */
+  private static class FloatAccessor extends ApproximateNumericAccessor {
+    public FloatAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public float getFloat() {
+      Float o = (Float) getObject();
+      return o == null ? 0f : o;
+    }
+
+    public double getDouble() {
+      return getFloat();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Double};
+   * corresponds to {@link java.sql.Types#DOUBLE}.
+   */
+  private static class DoubleAccessor extends ApproximateNumericAccessor {
+    public DoubleAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public double getDouble() {
+      Double o = (Double) getObject();
+      return o == null ? 0d : o;
+    }
+  }
+
+  /**
+   * Accessor of exact numeric values. The subclass must implement the
+   * {@link #getLong()} method.
+   */
+  private abstract static class BigNumberAccessor extends AccessorImpl {
+    public BigNumberAccessor(Getter getter) {
+      super(getter);
+    }
+
+    protected abstract Number getNumber();
+
+    public double getDouble() {
+      Number number = getNumber();
+      return number == null ? 0d : number.doubleValue();
+    }
+
+    public float getFloat() {
+      Number number = getNumber();
+      return number == null ? 0f : number.floatValue();
+    }
+
+    public long getLong() {
+      Number number = getNumber();
+      return number == null ? 0L : number.longValue();
+    }
+
+    public int getInt() {
+      Number number = getNumber();
+      return number == null ? 0 : number.intValue();
+    }
+
+    public short getShort() {
+      Number number = getNumber();
+      return number == null ? 0 : number.shortValue();
+    }
+
+    public byte getByte() {
+      Number number = getNumber();
+      return number == null ? 0 : number.byteValue();
+    }
+
+    public boolean getBoolean() {
+      Number number = getNumber();
+      return number != null && number.doubleValue() != 0;
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link BigDecimal};
+   * corresponds to {@link java.sql.Types#DECIMAL}.
+   */
+  private static class BigDecimalAccessor extends BigNumberAccessor {
+    public BigDecimalAccessor(Getter getter) {
+      super(getter);
+    }
+
+    protected Number getNumber() {
+      return (Number) getObject();
+    }
+
+    public BigDecimal getBigDecimal(int scale) {
+      return (BigDecimal) getObject();
+    }
+
+    public BigDecimal getBigDecimal() {
+      return (BigDecimal) getObject();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link Number};
+   * corresponds to {@link java.sql.Types#NUMERIC}.
+   *
+   * <p>This is useful when numbers have been translated over JSON. JSON
+   * converts a 0L (0 long) value to the string "0" and back to 0 (0 int).
+   * So you cannot be sure that the source and target type are the same.
+   */
+  static class NumberAccessor extends BigNumberAccessor {
+    private final int scale;
+
+    public NumberAccessor(Getter getter, int scale) {
+      super(getter);
+      this.scale = scale;
+    }
+
+    protected Number getNumber() {
+      return (Number) super.getObject();
+    }
+
+    public BigDecimal getBigDecimal(int scale) {
+      Number n = getNumber();
+      if (n == null) {
+        return null;
+      }
+      BigDecimal decimal = AvaticaSite.toBigDecimal(n);
+      if (0 != scale) {
+        return decimal.setScale(scale, BigDecimal.ROUND_UNNECESSARY);
+      }
+      return decimal;
+    }
+
+    public BigDecimal getBigDecimal() {
+      return getBigDecimal(scale);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link String};
+   * corresponds to {@link java.sql.Types#CHAR}
+   * and {@link java.sql.Types#VARCHAR}.
+   */
+  private static class StringAccessor extends AccessorImpl {
+    public StringAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public String getString() {
+      return (String) getObject();
+    }
+
+    @Override public byte[] getBytes() {
+      return super.getBytes();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link String};
+   * corresponds to {@link java.sql.Types#CHAR}.
+   */
+  private static class FixedStringAccessor extends StringAccessor {
+    protected final Spacer spacer;
+
+    public FixedStringAccessor(Getter getter, int length) {
+      super(getter);
+      this.spacer = new Spacer(length);
+    }
+
+    public String getString() {
+      String s = super.getString();
+      if (s == null) {
+        return null;
+      }
+      return spacer.padRight(s);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link String};
+   * corresponds to {@link java.sql.Types#CHAR}.
+   */
+  private static class StringFromCharAccessor extends FixedStringAccessor {
+    public StringFromCharAccessor(Getter getter, int length) {
+      super(getter, length);
+    }
+
+    public String getString() {
+      Character s = (Character) super.getObject();
+      if (s == null) {
+        return null;
+      }
+      return spacer.padRight(s.toString());
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is an array of
+   * {@link org.apache.calcite.avatica.util.ByteString} values;
+   * corresponds to {@link java.sql.Types#BINARY}
+   * and {@link java.sql.Types#VARBINARY}.
+   */
+  private static class BinaryAccessor extends AccessorImpl {
+    public BinaryAccessor(Getter getter) {
+      super(getter);
+    }
+
+    //FIXME: Protobuf gets byte[]
+    @Override public byte[] getBytes() {
+      Object obj = getObject();
+      try {
+        final ByteString o = (ByteString) obj;
+        return o == null ? null : o.getBytes();
+      } catch (Exception ex) {
+        return obj == null ? null : (byte[]) obj;
+      }
+    }
+
+    @Override public String getString() {
+      Object o = getObject();
+      if (null == o) {
+        return null;
+      }
+      if (o instanceof byte[]) {
+        return new String((byte[]) o, StandardCharsets.UTF_8);
+      } else if (o instanceof ByteString) {
+        return ((ByteString) o).toString();
+      }
+      throw new IllegalStateException("Unhandled value type: " + o.getClass());
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@link String},
+   * encoding {@link java.sql.Types#BINARY}
+   * and {@link java.sql.Types#VARBINARY} values in Base64 format.
+   */
+  private static class BinaryFromStringAccessor extends StringAccessor {
+    public BinaryFromStringAccessor(Getter getter) {
+      super(getter);
+    }
+
+    @Override public Object getObject() {
+      return super.getObject();
+    }
+
+    @Override public byte[] getBytes() {
+      // JSON sends this as a base64-enc string, protobuf can do binary.
+      Object obj = getObject();
+
+      if (obj instanceof byte[]) {
+        // If we already have bytes, just send them back.
+        return (byte[]) obj;
+      }
+
+      return getBase64Decoded();
+    }
+
+    private byte[] getBase64Decoded() {
+      final String string = super.getString();
+      if (null == string) {
+        return null;
+      }
+      // Need to base64 decode the string.
+      return ByteString.parseBase64(string);
+    }
+
+    @Override public String getString() {
+      final byte[] bytes = getBase64Decoded();
+      if (null == bytes) {
+        return null;
+      }
+      // Need to base64 decode the string.
+      return new String(bytes, StandardCharsets.UTF_8);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a DATE,
+   * in its default representation {@code int};
+   * corresponds to {@link java.sql.Types#DATE}.
+   */
+  private static class DateFromNumberAccessor extends NumberAccessor {
+    private final Calendar localCalendar;
+
+    public DateFromNumberAccessor(Getter getter, Calendar localCalendar) {
+      super(getter, 0);
+      this.localCalendar = localCalendar;
+    }
+
+    @Override public Object getObject() {
+      return getDate(localCalendar);
+    }
+
+    @Override public Date getDate(Calendar calendar) {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return longToDate(v.longValue() * DateTimeUtils.MILLIS_PER_DAY, calendar);
+    }
+
+    @Override public Timestamp getTimestamp(Calendar calendar) {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return longToTimestamp(v.longValue() * DateTimeUtils.MILLIS_PER_DAY,
+          calendar);
+    }
+
+    @Override public String getString() {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return dateAsString(v.intValue(), null);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a Time,
+   * in its default representation {@code int};
+   * corresponds to {@link java.sql.Types#TIME}.
+   */
+  private static class TimeFromNumberAccessor extends NumberAccessor {
+    private final Calendar localCalendar;
+
+    public TimeFromNumberAccessor(Getter getter, Calendar localCalendar) {
+      super(getter, 0);
+      this.localCalendar = localCalendar;
+    }
+
+    @Override public Object getObject() {
+      return getTime(localCalendar);
+    }
+
+    @Override public Time getTime(Calendar calendar) {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return intToTime(v.intValue(), calendar);
+    }
+
+    @Override public Timestamp getTimestamp(Calendar calendar) {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return longToTimestamp(v.longValue(), calendar);
+    }
+
+    @Override public String getString() {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return timeAsString(v.intValue(), null);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a TIMESTAMP,
+   * in its default representation {@code long};
+   * corresponds to {@link java.sql.Types#TIMESTAMP}.
+   */
+  private static class TimestampFromNumberAccessor extends NumberAccessor {
+    private final Calendar localCalendar;
+
+    public TimestampFromNumberAccessor(Getter getter, Calendar localCalendar) {
+      super(getter, 0);
+      this.localCalendar = localCalendar;
+    }
+
+    @Override public Object getObject() {
+      return getTimestamp(localCalendar);
+    }
+
+    @Override public Timestamp getTimestamp(Calendar calendar) {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return longToTimestamp(v.longValue(), calendar);
+    }
+
+    @Override public Date getDate(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Date(timestamp.getTime());
+    }
+
+    @Override public Time getTime(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Time(
+          DateTimeUtils.floorMod(timestamp.getTime(),
+              DateTimeUtils.MILLIS_PER_DAY));
+    }
+
+    @Override public String getString() {
+      final Number v = getNumber();
+      if (v == null) {
+        return null;
+      }
+      return timestampAsString(v.longValue(), null);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a DATE,
+   * represented as a java.sql.Date;
+   * corresponds to {@link java.sql.Types#DATE}.
+   */
+  private static class DateAccessor extends ObjectAccessor {
+    public DateAccessor(Getter getter) {
+      super(getter);
+    }
+
+    @Override public Date getDate(Calendar calendar) {
+      java.sql.Date date = (Date) getObject();
+      if (date == null) {
+        return null;
+      }
+      if (calendar != null) {
+        long v = date.getTime();
+        v -= calendar.getTimeZone().getOffset(v);
+        date = new Date(v);
+      }
+      return date;
+    }
+
+    @Override public String getString() {
+      final int v = getInt();
+      if (v == 0 && wasNull()) {
+        return null;
+      }
+      return dateAsString(v, null);
+    }
+
+    @Override public long getLong() {
+      Date date = getDate(null);
+      return date == null
+          ? 0L
+          : (date.getTime() / DateTimeUtils.MILLIS_PER_DAY);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a TIME,
+   * represented as a java.sql.Time;
+   * corresponds to {@link java.sql.Types#TIME}.
+   */
+  private static class TimeAccessor extends ObjectAccessor {
+    public TimeAccessor(Getter getter) {
+      super(getter);
+    }
+
+    @Override public Time getTime(Calendar calendar) {
+      Time date  = (Time) getObject();
+      if (date == null) {
+        return null;
+      }
+      if (calendar != null) {
+        long v = date.getTime();
+        v -= calendar.getTimeZone().getOffset(v);
+        date = new Time(v);
+      }
+      return date;
+    }
+
+    @Override public String getString() {
+      final int v = getInt();
+      if (v == 0 && wasNull()) {
+        return null;
+      }
+      return timeAsString(v, null);
+    }
+
+    @Override public long getLong() {
+      Time time = getTime(null);
+      return time == null ? 0L
+          : (time.getTime() % DateTimeUtils.MILLIS_PER_DAY);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a TIMESTAMP,
+   * represented as a java.sql.Timestamp;
+   * corresponds to {@link java.sql.Types#TIMESTAMP}.
+   */
+  private static class TimestampAccessor extends ObjectAccessor {
+    public TimestampAccessor(Getter getter) {
+      super(getter);
+    }
+
+    @Override public Timestamp getTimestamp(Calendar calendar) {
+      Timestamp timestamp  = (Timestamp) getObject();
+      if (timestamp == null) {
+        return null;
+      }
+      if (calendar != null) {
+        long v = timestamp.getTime();
+        v -= calendar.getTimeZone().getOffset(v);
+        timestamp = new Timestamp(v);
+      }
+      return timestamp;
+    }
+
+    @Override public Date getDate(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Date(timestamp.getTime());
+    }
+
+    @Override public Time getTime(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Time(
+          DateTimeUtils.floorMod(timestamp.getTime(),
+              DateTimeUtils.MILLIS_PER_DAY));
+    }
+
+    @Override public String getString() {
+      final long v = getLong();
+      if (v == 0 && wasNull()) {
+        return null;
+      }
+      return timestampAsString(v, null);
+    }
+
+    @Override public long getLong() {
+      Timestamp timestamp = getTimestamp(null);
+      return timestamp == null ? 0 : timestamp.getTime();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a TIMESTAMP,
+   * represented as a java.util.Date;
+   * corresponds to {@link java.sql.Types#TIMESTAMP}.
+   */
+  private static class TimestampFromUtilDateAccessor extends ObjectAccessor {
+    private final Calendar localCalendar;
+
+    public TimestampFromUtilDateAccessor(Getter getter,
+        Calendar localCalendar) {
+      super(getter);
+      this.localCalendar = localCalendar;
+    }
+
+    @Override public Timestamp getTimestamp(Calendar calendar) {
+      java.util.Date date  = (java.util.Date) getObject();
+      if (date == null) {
+        return null;
+      }
+      long v = date.getTime();
+      if (calendar != null) {
+        v -= calendar.getTimeZone().getOffset(v);
+      }
+      return new Timestamp(v);
+    }
+
+    @Override public Date getDate(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Date(timestamp.getTime());
+    }
+
+    @Override public Time getTime(Calendar calendar) {
+      final Timestamp timestamp  = getTimestamp(calendar);
+      if (timestamp == null) {
+        return null;
+      }
+      return new Time(
+          DateTimeUtils.floorMod(timestamp.getTime(),
+              DateTimeUtils.MILLIS_PER_DAY));
+    }
+
+    @Override public String getString() {
+      java.util.Date date  = (java.util.Date) getObject();
+      if (date == null) {
+        return null;
+      }
+      return timestampAsString(date.getTime(), null);
+    }
+
+    @Override public long getLong() {
+      Timestamp timestamp = getTimestamp(localCalendar);
+      return timestamp == null ? 0 : timestamp.getTime();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@code int};
+   * corresponds to {@link java.sql.Types#OTHER}.
+   */
+  private static class IntervalYearMonthAccessor extends IntAccessor {
+    private final TimeUnitRange range;
+
+    public IntervalYearMonthAccessor(Getter getter, TimeUnitRange range) {
+      super(getter);
+      this.range = range;
+    }
+
+    @Override public String getString() {
+      final int v = getInt();
+      if (v == 0 && wasNull()) {
+        return null;
+      }
+      return DateTimeUtils.intervalYearMonthToString(v, range);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a {@code long};
+   * corresponds to {@link java.sql.Types#OTHER}.
+   */
+  private static class IntervalDayTimeAccessor extends LongAccessor {
+    private final TimeUnitRange range;
+    private final int scale;
+
+    public IntervalDayTimeAccessor(Getter getter, TimeUnitRange range,
+        int scale) {
+      super(getter);
+      this.range = range;
+      this.scale = scale;
+    }
+
+    @Override public String getString() {
+      final long v = getLong();
+      if (v == 0 && wasNull()) {
+        return null;
+      }
+      return DateTimeUtils.intervalDayTimeToString(v, range, scale);
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is an ARRAY;
+   * corresponds to {@link java.sql.Types#ARRAY}.
+   */
+  static class ArrayAccessor extends AccessorImpl {
+    final ColumnMetaData.AvaticaType componentType;
+    final Accessor componentAccessor;
+    final SlotGetter componentSlotGetter;
+    final ArrayImpl.Factory factory;
+
+    public ArrayAccessor(Getter getter,
+        ColumnMetaData.AvaticaType componentType, Accessor componentAccessor,
+        SlotGetter componentSlotGetter, ArrayImpl.Factory factory) {
+      super(getter);
+      this.componentType = componentType;
+      this.componentAccessor = componentAccessor;
+      this.componentSlotGetter = componentSlotGetter;
+      this.factory = factory;
+    }
+
+    @Override public Object getObject() {
+      final Object object = super.getObject();
+      if (object == null || object instanceof List) {
+        return object;
+      }
+      // The object can be java array in case of user-provided class for row
+      // storage.
+      return AvaticaUtils.primitiveList(object);
+    }
+
+    @Override public Array getArray() {
+      final List list = (List) getObject();
+      if (list == null) {
+        return null;
+      }
+      return new ArrayImpl(list, this);
+    }
+
+    @Override public String getString() {
+      final Array array = getArray();
+      return array == null ? null : array.toString();
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is a STRUCT;
+   * corresponds to {@link java.sql.Types#STRUCT}.
+   */
+  private static class StructAccessor extends AccessorImpl {
+    private final List<Accessor> fieldAccessors;
+
+    public StructAccessor(Getter getter, List<Accessor> fieldAccessors) {
+      super(getter);
+      this.fieldAccessors = fieldAccessors;
+    }
+
+    @Override public Object getObject() {
+      return getStruct();
+    }
+
+    @Override public Struct getStruct() {
+      final Object o = super.getObject();
+      if (o == null) {
+        return null;
+      } else if (o instanceof List) {
+        return new StructImpl((List) o);
+      } else {
+        final List<Object> list = new ArrayList<>();
+        for (Accessor fieldAccessor : fieldAccessors) {
+          try {
+            list.add(fieldAccessor.getObject());
+          } catch (SQLException e) {
+            throw new RuntimeException(e);
+          }
+        }
+        return new StructImpl(list);
+      }
+    }
+  }
+
+  /**
+   * Accessor that assumes that the underlying value is an OBJECT;
+   * corresponds to {@link java.sql.Types#JAVA_OBJECT}.
+   */
+  private static class ObjectAccessor extends AccessorImpl {
+    public ObjectAccessor(Getter getter) {
+      super(getter);
+    }
+  }
+
+  /** Gets a value from a particular field of the current record of this
+   * cursor. */
+  protected interface Getter {
+    Object getObject();
+
+    boolean wasNull();
+  }
+
+  /** Abstract implementation of {@link Getter}. */
+  protected abstract class AbstractGetter implements Getter {
+    public boolean wasNull() {
+      return wasNull[0];
+    }
+  }
+
+  /** Implementation of {@link Getter} that returns the current contents of
+   * a mutable slot. */
+  public class SlotGetter implements Getter {
+    public Object slot;
+
+    public Object getObject() {
+      return slot;
+    }
+
+    public boolean wasNull() {
+      return slot == null;
+    }
+  }
+
+  /** Implementation of {@link Getter} that returns the value of a given field
+   * of the current contents of another getter. */
+  public class StructGetter implements Getter {
+    public final Getter getter;
+    private final ColumnMetaData columnMetaData;
+
+    public StructGetter(Getter getter, ColumnMetaData columnMetaData) {
+      this.getter = getter;
+      this.columnMetaData = columnMetaData;
+    }
+
+    public Object getObject() {
+      final Object o = getter.getObject();
+      if (o instanceof Object[]) {
+        Object[] objects = (Object[]) o;
+        return objects[columnMetaData.ordinal];
+      }
+      try {
+        final Field field = o.getClass().getField(columnMetaData.label);
+        return field.get(getter.getObject());
+      } catch (IllegalAccessException | NoSuchFieldException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    public boolean wasNull() {
+      return getObject() == null;
+    }
+  }
+}
+
+// End AbstractCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
new file mode 100644
index 0000000..b2d5ae9
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
@@ -0,0 +1,204 @@
+/*
+ * 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.util;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.ColumnMetaData;
+
+import java.sql.Array;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/** Implementation of JDBC {@link Array}. */
+public class ArrayImpl implements Array {
+  private final List list;
+  private final AbstractCursor.ArrayAccessor accessor;
+
+  public ArrayImpl(List list, AbstractCursor.ArrayAccessor accessor) {
+    this.list = list;
+    this.accessor = accessor;
+  }
+
+  public String getBaseTypeName() throws SQLException {
+    return accessor.componentType.name;
+  }
+
+  public int getBaseType() throws SQLException {
+    return accessor.componentType.id;
+  }
+
+  public Object getArray() throws SQLException {
+    return getArray(list);
+  }
+
+  @Override public String toString() {
+    final Iterator iterator = list.iterator();
+    if (!iterator.hasNext()) {
+      return "[]";
+    }
+    final StringBuilder buf = new StringBuilder("[");
+    for (;;) {
+      accessor.componentSlotGetter.slot = iterator.next();
+      try {
+        append(buf, accessor.componentAccessor.getString());
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+      accessor.componentSlotGetter.slot = null;
+      if (!iterator.hasNext()) {
+        return buf.append("]").toString();
+      }
+      buf.append(", ");
+    }
+  }
+
+  private void append(StringBuilder buf, Object o) {
+    if (o == null) {
+      buf.append("null");
+    } else if (o.getClass().isArray()) {
+      append(buf, AvaticaUtils.primitiveList(o));
+    } else {
+      buf.append(o);
+    }
+  }
+
+  /**
+   * Converts a list into an array.
+   *
+   * <p>If the elements of the list are primitives, converts to an array of
+   * primitives (e.g. {@code boolean[]}.</p>
+   *
+   * @param list List of objects
+   *
+   * @return array
+   * @throws ClassCastException   if any element is not of the box type
+   * @throws NullPointerException if any element is null
+   */
+  @SuppressWarnings("unchecked")
+  protected Object getArray(List list) throws SQLException {
+    int i = 0;
+    switch (accessor.componentType.rep) {
+    case PRIMITIVE_DOUBLE:
+      final double[] doubles = new double[list.size()];
+      for (double v : (List<Double>) list) {
+        doubles[i++] = v;
+      }
+      return doubles;
+    case PRIMITIVE_FLOAT:
+      final float[] floats = new float[list.size()];
+      for (float v : (List<Float>) list) {
+        floats[i++] = v;
+      }
+      return floats;
+    case PRIMITIVE_INT:
+      final int[] ints = new int[list.size()];
+      for (int v : (List<Integer>) list) {
+        ints[i++] = v;
+      }
+      return ints;
+    case PRIMITIVE_LONG:
+      final long[] longs = new long[list.size()];
+      for (long v : (List<Long>) list) {
+        longs[i++] = v;
+      }
+      return longs;
+    case PRIMITIVE_SHORT:
+      final short[] shorts = new short[list.size()];
+      for (short v : (List<Short>) list) {
+        shorts[i++] = v;
+      }
+      return shorts;
+    case PRIMITIVE_BOOLEAN:
+      final boolean[] booleans = new boolean[list.size()];
+      for (boolean v : (List<Boolean>) list) {
+        booleans[i++] = v;
+      }
+      return booleans;
+    case PRIMITIVE_BYTE:
+      final byte[] bytes = new byte[list.size()];
+      for (byte v : (List<Byte>) list) {
+        bytes[i++] = v;
+      }
+      return bytes;
+    case PRIMITIVE_CHAR:
+      final char[] chars = new char[list.size()];
+      for (char v : (List<Character>) list) {
+        chars[i++] = v;
+      }
+      return chars;
+    default:
+      // fall through
+    }
+    final Object[] objects = list.toArray();
+    switch (accessor.componentType.id) {
+    case Types.ARRAY:
+      final AbstractCursor.ArrayAccessor componentAccessor =
+          (AbstractCursor.ArrayAccessor) accessor.componentAccessor;
+      for (i = 0; i < objects.length; i++) {
+        objects[i] = new ArrayImpl((List) objects[i], componentAccessor);
+      }
+    }
+    return objects;
+  }
+
+  public Object getArray(Map<String, Class<?>> map) throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  public Object getArray(long index, int count) throws SQLException {
+    return getArray(list.subList((int) index, count));
+  }
+
+  public Object getArray(long index, int count, Map<String, Class<?>> map)
+      throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  public ResultSet getResultSet() throws SQLException {
+    return accessor.factory.create(accessor.componentType, list);
+  }
+
+  public ResultSet getResultSet(Map<String, Class<?>> map)
+      throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  public ResultSet getResultSet(long index, int count) throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  public ResultSet getResultSet(long index, int count,
+      Map<String, Class<?>> map) throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  public void free() throws SQLException {
+    // nothing to do
+  }
+
+  /** Factory that can create a result set based on a list of values. */
+  public interface Factory {
+    ResultSet create(ColumnMetaData.AvaticaType elementType,
+        Iterable<Object> iterable);
+  }
+}
+
+// End ArrayImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
new file mode 100644
index 0000000..0477984
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
@@ -0,0 +1,41 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+
+/**
+ * Implementation of {@link Cursor} on top of an
+ * {@link java.util.Iterator} that
+ * returns an array of {@link Object} for each row.
+ */
+public class ArrayIteratorCursor extends IteratorCursor<Object[]> {
+  /**
+   * Creates an ArrayEnumeratorCursor.
+   *
+   * @param iterator Iterator
+   */
+  public ArrayIteratorCursor(Iterator<Object[]> iterator) {
+    super(iterator);
+  }
+
+  protected Getter createGetter(int ordinal) {
+    return new ArrayGetter(ordinal);
+  }
+}
+
+// End ArrayIteratorCursor.java


[51/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
[CALCITE-1078] Detach avatica from the core calcite Maven project

The "calcite-avatica" module is still called "calcite-avatica"
but is contained in the directory "avatica/core", since avatica
is now the parent directory for all of avatica.

The present contents of the LICENSE file was incorrect, stating
that all artifacts (notably the source tarball) bundled protobuf.
This is incorrect. Protobuf was only included in the avatica (client)
jar. As such, only that artifact should have the LICENSE file with
the appropriate notice in it.


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

Branch: refs/heads/master
Commit: 5cee486f3ad878275ffe67e67cd8593d6bcfd62d
Parents: 5464f33
Author: Josh Elser <el...@apache.org>
Authored: Thu Mar 3 19:03:27 2016 -0500
Committer: Josh Elser <el...@apache.org>
Committed: Mon Mar 7 10:49:44 2016 -0500

----------------------------------------------------------------------
 LICENSE                                         |    42 -
 avatica-metrics-dropwizardmetrics3/pom.xml      |   119 -
 .../metrics/dropwizard3/DropwizardCounter.java  |    51 -
 .../metrics/dropwizard3/DropwizardGauge.java    |    39 -
 .../dropwizard3/DropwizardHistogram.java        |    43 -
 .../metrics/dropwizard3/DropwizardMeter.java    |    43 -
 .../dropwizard3/DropwizardMetricsSystem.java    |    62 -
 .../DropwizardMetricsSystemConfiguration.java   |    42 -
 .../DropwizardMetricsSystemFactory.java         |    42 -
 .../metrics/dropwizard3/DropwizardTimer.java    |    54 -
 .../metrics/dropwizard3/package-info.java       |    26 -
 ...calcite.avatica.metrics.MetricsSystemFactory |     2 -
 .../dropwizard3/DropwizardCounterTest.java      |    61 -
 .../dropwizard3/DropwizardGaugeTest.java        |    60 -
 .../dropwizard3/DropwizardHistogramTest.java    |    49 -
 .../dropwizard3/DropwizardMeterTest.java        |    50 -
 .../DropwizardMetricsSystemFactoryTest.java     |    54 -
 .../DropwizardMetricsSystemTest.java            |   161 -
 .../dropwizard3/DropwizardTimerTest.java        |    56 -
 avatica-metrics/pom.xml                         |   138 -
 .../apache/calcite/avatica/metrics/Counter.java |    49 -
 .../apache/calcite/avatica/metrics/Gauge.java   |    30 -
 .../calcite/avatica/metrics/Histogram.java      |    40 -
 .../apache/calcite/avatica/metrics/Meter.java   |    38 -
 .../apache/calcite/avatica/metrics/Metric.java  |    26 -
 .../calcite/avatica/metrics/MetricsSystem.java  |    68 -
 .../metrics/MetricsSystemConfiguration.java     |    33 -
 .../avatica/metrics/MetricsSystemFactory.java   |    32 -
 .../avatica/metrics/MetricsSystemLoader.java    |    87 -
 .../calcite/avatica/metrics/PackageMarker.java  |    37 -
 .../apache/calcite/avatica/metrics/Timer.java   |    37 -
 .../avatica/metrics/noop/NoopCounter.java       |    36 -
 .../avatica/metrics/noop/NoopHistogram.java     |    32 -
 .../calcite/avatica/metrics/noop/NoopMeter.java |    32 -
 .../avatica/metrics/noop/NoopMetricsSystem.java |    69 -
 .../noop/NoopMetricsSystemConfiguration.java    |    40 -
 .../metrics/noop/NoopMetricsSystemFactory.java  |    35 -
 .../calcite/avatica/metrics/noop/NoopTimer.java |    43 -
 .../avatica/metrics/noop/package-info.java      |    26 -
 .../calcite/avatica/metrics/package-info.java   |    24 -
 .../metrics/MetricsSystemLoaderTest.java        |   114 -
 .../noop/NoopMetricsSystemFactoryTest.java      |    37 -
 .../metrics/noop/NoopMetricsSystemTest.java     |    73 -
 .../src/test/resources/log4j.properties         |    24 -
 avatica-noop/pom.xml                            |   110 -
 .../avatica/noop/AvaticaNoopConnection.java     |   256 -
 .../noop/AvaticaNoopDatabaseMetaData.java       |   770 -
 .../calcite/avatica/noop/AvaticaNoopDriver.java |    74 -
 .../noop/AvaticaNoopParameterMetaData.java      |    85 -
 .../noop/AvaticaNoopPreparedStatement.java      |   344 -
 .../avatica/noop/AvaticaNoopResultSet.java      |   661 -
 .../noop/AvaticaNoopResultSetMetaData.java      |   133 -
 .../avatica/noop/AvaticaNoopStatement.java      |   191 -
 .../calcite/avatica/noop/PackageMarker.java     |    37 -
 .../calcite/avatica/noop/package-info.java      |    24 -
 .../resources/META-INF/services/java.sql.Driver |     1 -
 avatica-server/pom.xml                          |   196 -
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |   976 -
 .../calcite/avatica/jdbc/JdbcResultSet.java     |   215 -
 .../calcite/avatica/jdbc/StatementInfo.java     |   170 -
 .../calcite/avatica/jdbc/package-info.java      |    22 -
 .../calcite/avatica/server/AvaticaHandler.java  |    32 -
 .../avatica/server/AvaticaJsonHandler.java      |   127 -
 .../avatica/server/AvaticaProtobufHandler.java  |   121 -
 .../server/DelegatingAvaticaHandler.java        |   116 -
 .../calcite/avatica/server/HandlerFactory.java  |   115 -
 .../calcite/avatica/server/HttpServer.java      |   168 -
 .../org/apache/calcite/avatica/server/Main.java |   100 -
 .../server/MetricsAwareAvaticaHandler.java      |    43 -
 .../calcite/avatica/server/package-info.java    |    26 -
 .../apache/calcite/avatica/ConnectionSpec.java  |    55 -
 .../calcite/avatica/RemoteDriverMockTest.java   |   219 -
 .../calcite/avatica/RemoteDriverTest.java       |  1320 --
 .../calcite/avatica/jdbc/JdbcMetaTest.java      |    46 -
 .../calcite/avatica/jdbc/StatementInfoTest.java |   138 -
 .../remote/AlternatingRemoteMetaTest.java       |   396 -
 .../calcite/avatica/remote/RemoteMetaTest.java  |   626 -
 .../avatica/server/HandlerFactoryTest.java      |    58 -
 .../calcite/avatica/test/AvaticaSuite.java      |    37 -
 .../src/test/resources/log4j.properties         |    24 -
 avatica/LICENSE                                 |   268 +
 avatica/NOTICE                                  |    10 +
 avatica/core/pom.xml                            |   224 +
 .../protobuf/HBaseZeroCopyByteString.java       |    77 +
 .../java/com/google/protobuf/package-info.java  |    26 +
 .../avatica/AvaticaClientRuntimeException.java  |    94 +
 .../calcite/avatica/AvaticaConnection.java      |   696 +
 .../avatica/AvaticaDatabaseMetaData.java        |  1416 ++
 .../apache/calcite/avatica/AvaticaFactory.java  |    83 +
 .../calcite/avatica/AvaticaJdbc41Factory.java   |   256 +
 .../calcite/avatica/AvaticaParameter.java       |   135 +
 .../avatica/AvaticaPreparedStatement.java       |   343 +
 .../calcite/avatica/AvaticaResultSet.java       |  1046 +
 .../avatica/AvaticaResultSetMetaData.java       |   145 +
 .../apache/calcite/avatica/AvaticaSeverity.java |    90 +
 .../org/apache/calcite/avatica/AvaticaSite.java |   587 +
 .../calcite/avatica/AvaticaSqlException.java    |   138 +
 .../calcite/avatica/AvaticaStatement.java       |   527 +
 .../apache/calcite/avatica/AvaticaUtils.java    |   329 +
 .../avatica/BuiltInConnectionProperty.java      |   103 +
 .../apache/calcite/avatica/ColumnMetaData.java  |   593 +
 .../calcite/avatica/ConnectStringParser.java    |   391 +
 .../calcite/avatica/ConnectionConfig.java       |    40 +
 .../calcite/avatica/ConnectionConfigImpl.java   |   239 +
 .../avatica/ConnectionPropertiesImpl.java       |   279 +
 .../calcite/avatica/ConnectionProperty.java     |    69 +
 .../apache/calcite/avatica/DriverVersion.java   |   149 +
 .../org/apache/calcite/avatica/Handler.java     |    87 +
 .../org/apache/calcite/avatica/HandlerImpl.java |    47 +
 .../java/org/apache/calcite/avatica/Helper.java |    76 +
 .../calcite/avatica/InternalProperty.java       |   109 +
 .../java/org/apache/calcite/avatica/Meta.java   |  1272 ++
 .../org/apache/calcite/avatica/MetaImpl.java    |   961 +
 .../avatica/MissingResultsException.java        |    41 +
 .../avatica/NoSuchConnectionException.java      |    37 +
 .../avatica/NoSuchStatementException.java       |    39 +
 .../org/apache/calcite/avatica/QueryState.java  |   466 +
 .../org/apache/calcite/avatica/SqlType.java     |   559 +
 .../calcite/avatica/UnregisteredDriver.java     |   255 +
 .../apache/calcite/avatica/package-info.java    |    26 +
 .../apache/calcite/avatica/proto/Common.java    | 17128 +++++++++++++++++
 .../apache/calcite/avatica/proto/Requests.java  | 12327 ++++++++++++
 .../apache/calcite/avatica/proto/Responses.java | 11853 ++++++++++++
 .../calcite/avatica/remote/AbstractHandler.java |   154 +
 .../calcite/avatica/remote/AbstractService.java |   159 +
 .../remote/AvaticaCommonsHttpClientImpl.java    |   133 +
 .../avatica/remote/AvaticaHttpClient.java       |    34 +
 .../remote/AvaticaHttpClientFactory.java        |    39 +
 .../remote/AvaticaHttpClientFactoryImpl.java    |    66 +
 .../avatica/remote/AvaticaHttpClientImpl.java   |    73 +
 .../AvaticaRemoteConnectionConfigImpl.java      |    36 +
 .../remote/AvaticaRemoteConnectionProperty.java |    80 +
 .../avatica/remote/AvaticaRuntimeException.java |   102 +
 .../apache/calcite/avatica/remote/Driver.java   |   178 +
 .../apache/calcite/avatica/remote/Handler.java  |    68 +
 .../calcite/avatica/remote/JsonHandler.java     |    76 +
 .../calcite/avatica/remote/JsonService.java     |   227 +
 .../avatica/remote/LocalJsonService.java        |    46 +
 .../avatica/remote/LocalProtobufService.java    |    58 +
 .../calcite/avatica/remote/LocalService.java    |   358 +
 .../avatica/remote/MetaDataOperation.java       |   181 +
 .../calcite/avatica/remote/MetricsHelper.java   |    36 +
 .../calcite/avatica/remote/MockJsonService.java |   118 +
 .../avatica/remote/MockProtobufService.java     |   144 +
 .../calcite/avatica/remote/ProtobufHandler.java |    62 +
 .../calcite/avatica/remote/ProtobufService.java |   132 +
 .../avatica/remote/ProtobufTranslation.java     |    64 +
 .../avatica/remote/ProtobufTranslationImpl.java |   354 +
 .../calcite/avatica/remote/RemoteMeta.java      |   395 +
 .../avatica/remote/RemoteProtobufService.java   |    53 +
 .../calcite/avatica/remote/RemoteService.java   |    39 +
 .../avatica/remote/RequestTranslator.java       |    45 +
 .../avatica/remote/ResponseTranslator.java      |    44 +
 .../apache/calcite/avatica/remote/Service.java  |  2771 +++
 .../calcite/avatica/remote/TypedValue.java      |   533 +
 .../calcite/avatica/remote/package-info.java    |    26 +
 .../calcite/avatica/util/AbstractCursor.java    |  1377 ++
 .../apache/calcite/avatica/util/ArrayImpl.java  |   204 +
 .../avatica/util/ArrayIteratorCursor.java       |    41 +
 .../org/apache/calcite/avatica/util/Base64.java |  2087 ++
 .../apache/calcite/avatica/util/ByteString.java |   347 +
 .../org/apache/calcite/avatica/util/Casing.java |    35 +
 .../org/apache/calcite/avatica/util/Cursor.java |   145 +
 .../calcite/avatica/util/DateTimeUtils.java     |   842 +
 .../calcite/avatica/util/IteratorCursor.java    |    85 +
 .../avatica/util/ListIteratorCursor.java        |    43 +
 .../calcite/avatica/util/MapIteratorCursor.java |    51 +
 .../calcite/avatica/util/PackageMarker.java     |    37 +
 .../calcite/avatica/util/PositionedCursor.java  |   134 +
 .../apache/calcite/avatica/util/Quoting.java    |    37 +
 .../avatica/util/RecordIteratorCursor.java      |    63 +
 .../org/apache/calcite/avatica/util/Spacer.java |    80 +
 .../org/apache/calcite/avatica/util/Spaces.java |   185 +
 .../apache/calcite/avatica/util/StructImpl.java |    79 +
 .../apache/calcite/avatica/util/TimeUnit.java   |    75 +
 .../calcite/avatica/util/TimeUnitRange.java     |   107 +
 .../avatica/util/UnsynchronizedBuffer.java      |   152 +
 .../calcite/avatica/util/package-info.java      |    24 +
 avatica/core/src/main/protobuf/common.proto     |   275 +
 avatica/core/src/main/protobuf/requests.proto   |   145 +
 avatica/core/src/main/protobuf/responses.proto  |   126 +
 .../core/src/main/resources/META-INF/LICENSE    |   257 +
 .../resources/META-INF/services/java.sql.Driver |     1 +
 .../core/src/main/scripts/generate-protobuf.sh  |    99 +
 .../calcite/avatica/AvaticaConnectionTest.java  |    60 +
 .../org/apache/calcite/avatica/FrameTest.java   |   165 +
 .../apache/calcite/avatica/QueryStateTest.java  |   513 +
 .../avatica/metrics/MetricsHelperTest.java      |    42 +
 .../avatica/remote/AbstractHandlerTest.java     |   165 +
 .../remote/AvaticaHttpClientFactoryTest.java    |    60 +
 .../avatica/remote/AvaticaHttpClientTest.java   |    93 +
 .../avatica/remote/ErrorResponseTest.java       |    68 +
 .../avatica/remote/MetaDataOperationTest.java   |    37 +
 .../avatica/remote/ProtobufHandlerTest.java     |   138 +
 .../remote/ProtobufSerializationTest.java       |    75 +
 .../avatica/remote/ProtobufServiceTest.java     |    58 +
 .../remote/ProtobufTranslationImplTest.java     |   376 +
 .../calcite/avatica/remote/TypedValueTest.java  |   126 +
 .../test/AvaticaClientRuntimeExceptionTest.java |    53 +
 .../avatica/test/AvaticaSeverityTest.java       |    39 +
 .../avatica/test/AvaticaSqlExceptionTest.java   |    52 +
 .../calcite/avatica/test/AvaticaUtilsTest.java  |    86 +
 .../avatica/test/ConnectStringParserTest.java   |   255 +
 .../calcite/avatica/test/JsonHandlerTest.java   |   187 +
 .../calcite/avatica/test/package-info.java      |    26 +
 .../avatica/util/NumberAccessorTest.java        |    54 +
 .../avatica/util/UnsynchronizedBufferTest.java  |    41 +
 avatica/metrics-dropwizardmetrics3/pom.xml      |   119 +
 .../metrics/dropwizard3/DropwizardCounter.java  |    51 +
 .../metrics/dropwizard3/DropwizardGauge.java    |    39 +
 .../dropwizard3/DropwizardHistogram.java        |    43 +
 .../metrics/dropwizard3/DropwizardMeter.java    |    43 +
 .../dropwizard3/DropwizardMetricsSystem.java    |    62 +
 .../DropwizardMetricsSystemConfiguration.java   |    42 +
 .../DropwizardMetricsSystemFactory.java         |    42 +
 .../metrics/dropwizard3/DropwizardTimer.java    |    54 +
 .../metrics/dropwizard3/package-info.java       |    26 +
 ...calcite.avatica.metrics.MetricsSystemFactory |     2 +
 .../dropwizard3/DropwizardCounterTest.java      |    61 +
 .../dropwizard3/DropwizardGaugeTest.java        |    60 +
 .../dropwizard3/DropwizardHistogramTest.java    |    49 +
 .../dropwizard3/DropwizardMeterTest.java        |    50 +
 .../DropwizardMetricsSystemFactoryTest.java     |    54 +
 .../DropwizardMetricsSystemTest.java            |   161 +
 .../dropwizard3/DropwizardTimerTest.java        |    56 +
 avatica/metrics/pom.xml                         |   138 +
 .../apache/calcite/avatica/metrics/Counter.java |    49 +
 .../apache/calcite/avatica/metrics/Gauge.java   |    30 +
 .../calcite/avatica/metrics/Histogram.java      |    40 +
 .../apache/calcite/avatica/metrics/Meter.java   |    38 +
 .../apache/calcite/avatica/metrics/Metric.java  |    26 +
 .../calcite/avatica/metrics/MetricsSystem.java  |    68 +
 .../metrics/MetricsSystemConfiguration.java     |    33 +
 .../avatica/metrics/MetricsSystemFactory.java   |    32 +
 .../avatica/metrics/MetricsSystemLoader.java    |    87 +
 .../calcite/avatica/metrics/PackageMarker.java  |    37 +
 .../apache/calcite/avatica/metrics/Timer.java   |    37 +
 .../avatica/metrics/noop/NoopCounter.java       |    36 +
 .../avatica/metrics/noop/NoopHistogram.java     |    32 +
 .../calcite/avatica/metrics/noop/NoopMeter.java |    32 +
 .../avatica/metrics/noop/NoopMetricsSystem.java |    69 +
 .../noop/NoopMetricsSystemConfiguration.java    |    40 +
 .../metrics/noop/NoopMetricsSystemFactory.java  |    35 +
 .../calcite/avatica/metrics/noop/NoopTimer.java |    43 +
 .../avatica/metrics/noop/package-info.java      |    26 +
 .../calcite/avatica/metrics/package-info.java   |    24 +
 .../metrics/MetricsSystemLoaderTest.java        |   114 +
 .../noop/NoopMetricsSystemFactoryTest.java      |    37 +
 .../metrics/noop/NoopMetricsSystemTest.java     |    73 +
 .../metrics/src/test/resources/log4j.properties |    24 +
 avatica/noop-driver/pom.xml                     |   110 +
 .../avatica/noop/AvaticaNoopConnection.java     |   256 +
 .../noop/AvaticaNoopDatabaseMetaData.java       |   770 +
 .../calcite/avatica/noop/AvaticaNoopDriver.java |    74 +
 .../noop/AvaticaNoopParameterMetaData.java      |    85 +
 .../noop/AvaticaNoopPreparedStatement.java      |   344 +
 .../avatica/noop/AvaticaNoopResultSet.java      |   661 +
 .../noop/AvaticaNoopResultSetMetaData.java      |   133 +
 .../avatica/noop/AvaticaNoopStatement.java      |   191 +
 .../calcite/avatica/noop/PackageMarker.java     |    37 +
 .../calcite/avatica/noop/package-info.java      |    24 +
 .../resources/META-INF/services/java.sql.Driver |     1 +
 avatica/pom.xml                                 |   849 +-
 avatica/server/pom.xml                          |   196 +
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |   976 +
 .../calcite/avatica/jdbc/JdbcResultSet.java     |   215 +
 .../calcite/avatica/jdbc/StatementInfo.java     |   170 +
 .../calcite/avatica/jdbc/package-info.java      |    22 +
 .../calcite/avatica/server/AvaticaHandler.java  |    32 +
 .../avatica/server/AvaticaJsonHandler.java      |   127 +
 .../avatica/server/AvaticaProtobufHandler.java  |   121 +
 .../server/DelegatingAvaticaHandler.java        |   116 +
 .../calcite/avatica/server/HandlerFactory.java  |   115 +
 .../calcite/avatica/server/HttpServer.java      |   168 +
 .../org/apache/calcite/avatica/server/Main.java |   100 +
 .../server/MetricsAwareAvaticaHandler.java      |    43 +
 .../calcite/avatica/server/package-info.java    |    26 +
 .../apache/calcite/avatica/ConnectionSpec.java  |    55 +
 .../calcite/avatica/RemoteDriverMockTest.java   |   219 +
 .../calcite/avatica/RemoteDriverTest.java       |  1320 ++
 .../calcite/avatica/jdbc/JdbcMetaTest.java      |    46 +
 .../calcite/avatica/jdbc/StatementInfoTest.java |   138 +
 .../remote/AlternatingRemoteMetaTest.java       |   396 +
 .../calcite/avatica/remote/RemoteMetaTest.java  |   626 +
 .../avatica/server/HandlerFactoryTest.java      |    58 +
 .../calcite/avatica/test/AvaticaSuite.java      |    37 +
 .../server/src/test/resources/log4j.properties  |    24 +
 avatica/site/.gitignore                         |     2 +
 avatica/site/Gemfile                            |    20 +
 avatica/site/README.md                          |    57 +
 avatica/site/_config.yml                        |    43 +
 avatica/site/_data/contributors.yml             |    96 +
 avatica/site/_data/docs.yml                     |    48 +
 avatica/site/_docs/adapter.md                   |    38 +
 avatica/site/_docs/algebra.md                   |   369 +
 avatica/site/_docs/api.md                       |    28 +
 avatica/site/_docs/avatica_json_reference.md    |  1086 ++
 avatica/site/_docs/avatica_overview.md          |   130 +
 .../site/_docs/avatica_protobuf_reference.md    |  1181 ++
 avatica/site/_docs/avatica_roadmap.md           |    51 +
 avatica/site/_docs/history.md                   |  2343 +++
 avatica/site/_docs/howto.md                     |   775 +
 avatica/site/_docs/index.md                     |   145 +
 avatica/site/_docs/lattice.md                   |   136 +
 avatica/site/_docs/model.md                     |   517 +
 avatica/site/_docs/reference.md                 |  1248 ++
 avatica/site/_docs/stream.md                    |  1023 +
 avatica/site/_docs/testapi.md                   |    28 +
 avatica/site/_docs/tutorial.md                  |   760 +
 avatica/site/_includes/anchor_links.html        |    33 +
 avatica/site/_includes/docs_contents.html       |     8 +
 .../site/_includes/docs_contents_mobile.html    |    10 +
 avatica/site/_includes/docs_option.html         |    11 +
 avatica/site/_includes/docs_ul.html             |    29 +
 avatica/site/_includes/footer.html              |    15 +
 avatica/site/_includes/header.html              |    18 +
 avatica/site/_includes/news_contents.html       |    30 +
 .../site/_includes/news_contents_mobile.html    |    11 +
 avatica/site/_includes/news_item.html           |    62 +
 avatica/site/_includes/primary-nav-items.html   |    20 +
 avatica/site/_includes/section_nav.html         |    39 +
 avatica/site/_includes/top.html                 |    15 +
 avatica/site/_layouts/default.html              |    12 +
 avatica/site/_layouts/docs.html                 |    23 +
 avatica/site/_layouts/external.html             |     9 +
 avatica/site/_layouts/news.html                 |    19 +
 avatica/site/_layouts/news_item.html            |    49 +
 avatica/site/_layouts/page.html                 |    18 +
 avatica/site/_plugins/bundler.rb                |    20 +
 .../2014-06-27-release-0.8.0-incubating.md      |    31 +
 .../2014-08-19-release-0.9.0-incubating.md      |    30 +
 .../2014-10-02-release-0.9.1-incubating.md      |    29 +
 .../2014-11-05-release-0.9.2-incubating.md      |    32 +
 .../2015-01-31-release-1.0.0-incubating.md      |    42 +
 .../2015-03-13-release-1.1.0-incubating.md      |    41 +
 .../2015-04-07-release-1.2.0-incubating.md      |    41 +
 .../site/_posts/2015-04-24-new-committers.md    |    34 +
 .../2015-05-30-release-1.3.0-incubating.md      |    33 +
 .../site/_posts/2015-06-05-algebra-builder.md   |    87 +
 .../2015-07-31-xldb-best-lightning-talk.md      |    41 +
 .../2015-09-02-release-1.4.0-incubating.md      |    39 +
 .../site/_posts/2015-10-22-calcite-graduates.md |    63 +
 .../site/_posts/2015-11-08-new-committers.md    |    31 +
 avatica/site/_posts/2015-11-10-release-1.5.0.md |    33 +
 avatica/site/_posts/2016-01-22-release-1.6.0.md |    59 +
 avatica/site/_posts/2016-02-17-elser-pmc.md     |    33 +
 .../_posts/2016-02-17-streaming-sql-talk.md     |    40 +
 avatica/site/_sass/_font-awesome.scss           |    25 +
 avatica/site/_sass/_gridism.scss                |   124 +
 avatica/site/_sass/_mixins.scss                 |    38 +
 avatica/site/_sass/_normalize.scss              |     1 +
 avatica/site/_sass/_pygments.scss               |    78 +
 avatica/site/_sass/_style.scss                  |   989 +
 avatica/site/community/index.md                 |   116 +
 avatica/site/css/screen.scss                    |     9 +
 avatica/site/develop/index.md                   |   117 +
 avatica/site/doap_calcite.rdf                   |    59 +
 avatica/site/downloads/index.md                 |   100 +
 avatica/site/favicon.ico                        |   Bin 0 -> 5683 bytes
 avatica/site/fonts/fontawesome-webfont.eot      |   Bin 0 -> 56006 bytes
 avatica/site/fonts/fontawesome-webfont.svg      |   520 +
 avatica/site/fonts/fontawesome-webfont.ttf      |   Bin 0 -> 112160 bytes
 avatica/site/fonts/fontawesome-webfont.woff     |   Bin 0 -> 65452 bytes
 avatica/site/img/cake.jpg                       |   Bin 0 -> 58990 bytes
 avatica/site/img/feather.png                    |   Bin 0 -> 12607 bytes
 avatica/site/img/logo.png                       |   Bin 0 -> 69304 bytes
 avatica/site/img/pie-chart.png                  |   Bin 0 -> 13257 bytes
 avatica/site/img/window-types.png               |   Bin 0 -> 19177 bytes
 avatica/site/index.html                         |    75 +
 avatica/site/js/html5shiv.min.js                |     4 +
 avatica/site/js/respond.min.js                  |     5 +
 avatica/site/news/index.html                    |    35 +
 avatica/site/news/releases/index.html           |    26 +
 .../main/config/assemblies/source-assembly.xml  |   103 +
 avatica/src/main/config/checkstyle/checker.xml  |   279 +
 avatica/src/main/config/checkstyle/header.txt   |    16 +
 .../src/main/config/checkstyle/suppressions.xml |    48 +
 .../protobuf/HBaseZeroCopyByteString.java       |    77 -
 .../java/com/google/protobuf/package-info.java  |    26 -
 .../avatica/AvaticaClientRuntimeException.java  |    94 -
 .../calcite/avatica/AvaticaConnection.java      |   696 -
 .../avatica/AvaticaDatabaseMetaData.java        |  1416 --
 .../apache/calcite/avatica/AvaticaFactory.java  |    83 -
 .../calcite/avatica/AvaticaJdbc41Factory.java   |   256 -
 .../calcite/avatica/AvaticaParameter.java       |   135 -
 .../avatica/AvaticaPreparedStatement.java       |   343 -
 .../calcite/avatica/AvaticaResultSet.java       |  1046 -
 .../avatica/AvaticaResultSetMetaData.java       |   145 -
 .../apache/calcite/avatica/AvaticaSeverity.java |    90 -
 .../org/apache/calcite/avatica/AvaticaSite.java |   587 -
 .../calcite/avatica/AvaticaSqlException.java    |   138 -
 .../calcite/avatica/AvaticaStatement.java       |   527 -
 .../apache/calcite/avatica/AvaticaUtils.java    |   329 -
 .../avatica/BuiltInConnectionProperty.java      |   103 -
 .../apache/calcite/avatica/ColumnMetaData.java  |   593 -
 .../calcite/avatica/ConnectStringParser.java    |   391 -
 .../calcite/avatica/ConnectionConfig.java       |    40 -
 .../calcite/avatica/ConnectionConfigImpl.java   |   239 -
 .../avatica/ConnectionPropertiesImpl.java       |   279 -
 .../calcite/avatica/ConnectionProperty.java     |    69 -
 .../apache/calcite/avatica/DriverVersion.java   |   149 -
 .../org/apache/calcite/avatica/Handler.java     |    87 -
 .../org/apache/calcite/avatica/HandlerImpl.java |    47 -
 .../java/org/apache/calcite/avatica/Helper.java |    76 -
 .../calcite/avatica/InternalProperty.java       |   109 -
 .../java/org/apache/calcite/avatica/Meta.java   |  1272 --
 .../org/apache/calcite/avatica/MetaImpl.java    |   961 -
 .../avatica/MissingResultsException.java        |    41 -
 .../avatica/NoSuchConnectionException.java      |    37 -
 .../avatica/NoSuchStatementException.java       |    39 -
 .../org/apache/calcite/avatica/QueryState.java  |   466 -
 .../org/apache/calcite/avatica/SqlType.java     |   559 -
 .../calcite/avatica/UnregisteredDriver.java     |   255 -
 .../apache/calcite/avatica/package-info.java    |    26 -
 .../apache/calcite/avatica/proto/Common.java    | 17128 -----------------
 .../apache/calcite/avatica/proto/Requests.java  | 12327 ------------
 .../apache/calcite/avatica/proto/Responses.java | 11853 ------------
 .../calcite/avatica/remote/AbstractHandler.java |   154 -
 .../calcite/avatica/remote/AbstractService.java |   159 -
 .../remote/AvaticaCommonsHttpClientImpl.java    |   133 -
 .../avatica/remote/AvaticaHttpClient.java       |    34 -
 .../remote/AvaticaHttpClientFactory.java        |    39 -
 .../remote/AvaticaHttpClientFactoryImpl.java    |    66 -
 .../avatica/remote/AvaticaHttpClientImpl.java   |    73 -
 .../AvaticaRemoteConnectionConfigImpl.java      |    36 -
 .../remote/AvaticaRemoteConnectionProperty.java |    80 -
 .../avatica/remote/AvaticaRuntimeException.java |   102 -
 .../apache/calcite/avatica/remote/Driver.java   |   178 -
 .../apache/calcite/avatica/remote/Handler.java  |    68 -
 .../calcite/avatica/remote/JsonHandler.java     |    76 -
 .../calcite/avatica/remote/JsonService.java     |   227 -
 .../avatica/remote/LocalJsonService.java        |    46 -
 .../avatica/remote/LocalProtobufService.java    |    58 -
 .../calcite/avatica/remote/LocalService.java    |   358 -
 .../avatica/remote/MetaDataOperation.java       |   181 -
 .../calcite/avatica/remote/MetricsHelper.java   |    36 -
 .../calcite/avatica/remote/MockJsonService.java |   118 -
 .../avatica/remote/MockProtobufService.java     |   144 -
 .../calcite/avatica/remote/ProtobufHandler.java |    62 -
 .../calcite/avatica/remote/ProtobufService.java |   132 -
 .../avatica/remote/ProtobufTranslation.java     |    64 -
 .../avatica/remote/ProtobufTranslationImpl.java |   354 -
 .../calcite/avatica/remote/RemoteMeta.java      |   395 -
 .../avatica/remote/RemoteProtobufService.java   |    53 -
 .../calcite/avatica/remote/RemoteService.java   |    39 -
 .../avatica/remote/RequestTranslator.java       |    45 -
 .../avatica/remote/ResponseTranslator.java      |    44 -
 .../apache/calcite/avatica/remote/Service.java  |  2771 ---
 .../calcite/avatica/remote/TypedValue.java      |   533 -
 .../calcite/avatica/remote/package-info.java    |    26 -
 .../calcite/avatica/util/AbstractCursor.java    |  1377 --
 .../apache/calcite/avatica/util/ArrayImpl.java  |   204 -
 .../avatica/util/ArrayIteratorCursor.java       |    41 -
 .../org/apache/calcite/avatica/util/Base64.java |  2087 --
 .../apache/calcite/avatica/util/ByteString.java |   347 -
 .../org/apache/calcite/avatica/util/Casing.java |    35 -
 .../org/apache/calcite/avatica/util/Cursor.java |   145 -
 .../calcite/avatica/util/DateTimeUtils.java     |   842 -
 .../calcite/avatica/util/IteratorCursor.java    |    85 -
 .../avatica/util/ListIteratorCursor.java        |    43 -
 .../calcite/avatica/util/MapIteratorCursor.java |    51 -
 .../calcite/avatica/util/PackageMarker.java     |    37 -
 .../calcite/avatica/util/PositionedCursor.java  |   134 -
 .../apache/calcite/avatica/util/Quoting.java    |    37 -
 .../avatica/util/RecordIteratorCursor.java      |    63 -
 .../org/apache/calcite/avatica/util/Spacer.java |    80 -
 .../org/apache/calcite/avatica/util/Spaces.java |   185 -
 .../apache/calcite/avatica/util/StructImpl.java |    79 -
 .../apache/calcite/avatica/util/TimeUnit.java   |    75 -
 .../calcite/avatica/util/TimeUnitRange.java     |   107 -
 .../avatica/util/UnsynchronizedBuffer.java      |   152 -
 .../calcite/avatica/util/package-info.java      |    24 -
 avatica/src/main/protobuf/common.proto          |   275 -
 avatica/src/main/protobuf/requests.proto        |   145 -
 avatica/src/main/protobuf/responses.proto       |   126 -
 .../resources/META-INF/services/java.sql.Driver |     1 -
 avatica/src/main/scripts/generate-protobuf.sh   |    99 -
 .../calcite/avatica/AvaticaConnectionTest.java  |    60 -
 .../org/apache/calcite/avatica/FrameTest.java   |   165 -
 .../apache/calcite/avatica/QueryStateTest.java  |   513 -
 .../avatica/metrics/MetricsHelperTest.java      |    42 -
 .../avatica/remote/AbstractHandlerTest.java     |   165 -
 .../remote/AvaticaHttpClientFactoryTest.java    |    60 -
 .../avatica/remote/AvaticaHttpClientTest.java   |    93 -
 .../avatica/remote/ErrorResponseTest.java       |    68 -
 .../avatica/remote/MetaDataOperationTest.java   |    37 -
 .../avatica/remote/ProtobufHandlerTest.java     |   138 -
 .../remote/ProtobufSerializationTest.java       |    75 -
 .../avatica/remote/ProtobufServiceTest.java     |    58 -
 .../remote/ProtobufTranslationImplTest.java     |   376 -
 .../calcite/avatica/remote/TypedValueTest.java  |   126 -
 .../test/AvaticaClientRuntimeExceptionTest.java |    53 -
 .../avatica/test/AvaticaSeverityTest.java       |    39 -
 .../avatica/test/AvaticaSqlExceptionTest.java   |    52 -
 .../calcite/avatica/test/AvaticaUtilsTest.java  |    86 -
 .../avatica/test/ConnectStringParserTest.java   |   255 -
 .../calcite/avatica/test/JsonHandlerTest.java   |   187 -
 .../calcite/avatica/test/package-info.java      |    26 -
 .../avatica/util/NumberAccessorTest.java        |    54 -
 .../avatica/util/UnsynchronizedBufferTest.java  |    41 -
 pom.xml                                         |     5 -
 src/main/config/checkstyle/suppressions.xml     |     1 -
 502 files changed, 95461 insertions(+), 80094 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 0f5c755..f7b9863 100644
--- a/LICENSE
+++ b/LICENSE
@@ -266,45 +266,3 @@ SIL Open Font License (OFL) - http://scripts.sil.org/OFL/
 
 - site/fonts/fontawesome-webfont.*
    Font-awesome font files v4.0.3 (http://fortawesome.github.io/Font-Awesome/)
-
------------------------------------------------------------------------
- 3-clause BSD license
------------------------------------------------------------------------
-
-The Apache Calcite project bundles Protocol Buffers, which is available
-under the following "3-clause BSD" license:
-
-    Copyright 2014, Google Inc. All rights reserved.
-
-    Redistribution and use in source and binary forms, with or
-    without modification, are permitted provided that the following
-    conditions are met:
-
-    Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-    Redistributions in binary form must reproduce the above
-    copyright notice, this list of conditions and the following disclaimer
-    in the documentation and/or other materials provided with the
-    distribution.
-
-    Neither the name of Google Inc. nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    Code generated by the Protocol Buffer compiler is owned by the owner
-    of the input file used when generating it. This code is not
-    standalone and requires a support library to be linked with it. This
-    support library is itself covered by the above license.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/pom.xml
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/pom.xml b/avatica-metrics-dropwizardmetrics3/pom.xml
deleted file mode 100644
index f0e6fc1..0000000
--- a/avatica-metrics-dropwizardmetrics3/pom.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>calcite-avatica-metrics-dropwizardmetrics3</artifactId>
-  <packaging>jar</packaging>
-  <name>Calcite Avatica Dropwizard Metrics 3</name>
-  <description>An implementation of Avatica Metrics using Dropwizard Metrics.</description>
-
-  <properties>
-    <top.dir>${project.basedir}/..</top.dir>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.calcite</groupId>
-      <artifactId>calcite-avatica-metrics</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.dropwizard.metrics</groupId>
-      <artifactId>metrics-core</artifactId>
-      <!-- Avoid specifying version in dependencyManagement in support of other avatica-metrics impls -->
-      <version>${dropwizard-metrics3.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <versionRange>[2.12.1,)</versionRange>
-                    <goals>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <!-- Parent module has the same plugin and does the work of
-           generating -sources.jar for each project. But without the
-           plugin declared here, IDEs don't know the sources are
-           available. -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-source-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-sources</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>jar-no-fork</goal>
-              <goal>test-jar-no-fork</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-remote-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>non-root-resources</id>
-            <goals>
-              <goal>process</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
deleted file mode 100644
index 4204ebf..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
+++ /dev/null
@@ -1,51 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Counter;
-
-import java.util.Objects;
-
-/**
- * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Counter}.
- */
-public class DropwizardCounter implements org.apache.calcite.avatica.metrics.Counter {
-
-  private final Counter counter;
-
-  public DropwizardCounter(Counter counter) {
-    this.counter = Objects.requireNonNull(counter);
-  }
-
-  @Override public void increment() {
-    this.counter.inc();
-  }
-
-  @Override public void increment(long n) {
-    this.counter.inc(n);
-  }
-
-  @Override public void decrement() {
-    this.counter.dec();
-  }
-
-  @Override public void decrement(long n) {
-    this.counter.dec(n);
-  }
-}
-
-// End DropwizardCounter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
deleted file mode 100644
index 5f4b776..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
+++ /dev/null
@@ -1,39 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Gauge;
-
-/**
- * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Gauge}.
- *
- * @param <T> The value the gauge returns.
- */
-public class DropwizardGauge<T> implements Gauge<T> {
-
-  private final org.apache.calcite.avatica.metrics.Gauge<T> gauge;
-
-  public DropwizardGauge(org.apache.calcite.avatica.metrics.Gauge<T> gauge) {
-    this.gauge = gauge;
-  }
-
-  @Override public T getValue() {
-    return gauge.getValue();
-  }
-}
-
-// End DropwizardGauge.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
deleted file mode 100644
index 266f130..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
+++ /dev/null
@@ -1,43 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Histogram;
-
-import java.util.Objects;
-
-/**
- * Dropwizard metrics implementation of {@link org.apache.calcite.avatica.metrics.Histogram}.
- */
-public class DropwizardHistogram implements org.apache.calcite.avatica.metrics.Histogram {
-
-  private final Histogram histogram;
-
-  public DropwizardHistogram(Histogram histogram) {
-    this.histogram = Objects.requireNonNull(histogram);
-  }
-
-  @Override public void update(int value) {
-    histogram.update(value);
-  }
-
-  @Override public void update(long value) {
-    histogram.update(value);
-  }
-}
-
-// End DropwizardHistogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
deleted file mode 100644
index ab8fafc..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
+++ /dev/null
@@ -1,43 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Meter;
-
-import java.util.Objects;
-
-/**
- * Dropwizard metrics implementation of {@link org.apache.calcite.avatica.metrics.Meter}.
- */
-public class DropwizardMeter implements org.apache.calcite.avatica.metrics.Meter {
-
-  private final Meter meter;
-
-  public DropwizardMeter(Meter meter) {
-    this.meter = Objects.requireNonNull(meter);
-  }
-
-  @Override public void mark() {
-    this.meter.mark();
-  }
-
-  @Override public void mark(long count) {
-    this.meter.mark(count);
-  }
-}
-
-// End DropwizardMeter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
deleted file mode 100644
index 6aa71b9..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
+++ /dev/null
@@ -1,62 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.Counter;
-import org.apache.calcite.avatica.metrics.Gauge;
-import org.apache.calcite.avatica.metrics.Histogram;
-import org.apache.calcite.avatica.metrics.Meter;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-
-import com.codahale.metrics.MetricRegistry;
-
-import java.util.Objects;
-
-/**
- * Dropwizard Metrics implementation of {@link MetricsSystem}.
- */
-public class DropwizardMetricsSystem implements MetricsSystem {
-
-  private final MetricRegistry registry;
-
-  public DropwizardMetricsSystem(MetricRegistry registry) {
-    this.registry = Objects.requireNonNull(registry);
-  }
-
-  @Override public Timer getTimer(String name) {
-    return new DropwizardTimer(registry.timer(name));
-  }
-
-  @Override public Histogram getHistogram(String name) {
-    return new DropwizardHistogram(registry.histogram(name));
-  }
-
-  @Override public Meter getMeter(String name) {
-    return new DropwizardMeter(registry.meter(name));
-  }
-
-  @Override public Counter getCounter(String name) {
-    return new DropwizardCounter(registry.counter(name));
-  }
-
-  @Override public <T> void register(String name, Gauge<T> gauge) {
-    registry.register(name, new DropwizardGauge<T>(gauge));
-  }
-}
-
-// End DropwizardMetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
deleted file mode 100644
index f4c9234..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
+++ /dev/null
@@ -1,42 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-
-import com.codahale.metrics.MetricRegistry;
-
-import java.util.Objects;
-
-/**
- * A container which provides a {@link MetricRegistry} to a {@link DropwizardMetricsSystem}.
- */
-public class DropwizardMetricsSystemConfiguration implements
-    MetricsSystemConfiguration<MetricRegistry> {
-
-  private final MetricRegistry registry;
-
-  public DropwizardMetricsSystemConfiguration(MetricRegistry registry) {
-    this.registry = Objects.requireNonNull(registry);
-  }
-
-  @Override public MetricRegistry get() {
-    return registry;
-  }
-}
-
-// End DropwizardMetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
deleted file mode 100644
index 1480db6..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
+++ /dev/null
@@ -1,42 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
-
-/**
- * A {@link MetricsSystemFactory} for {@link DropwizardMetricsSystem}.
- */
-public class DropwizardMetricsSystemFactory implements MetricsSystemFactory {
-
-  @Override public DropwizardMetricsSystem create(MetricsSystemConfiguration<?> config) {
-    // Verify we got configuration this factory can use
-    if (config instanceof DropwizardMetricsSystemConfiguration) {
-      DropwizardMetricsSystemConfiguration typedConfig =
-          (DropwizardMetricsSystemConfiguration) config;
-
-      return new DropwizardMetricsSystem(typedConfig.get());
-    }
-
-    throw new IllegalStateException("Expected instance of "
-        + DropwizardMetricsSystemConfiguration.class.getName() + " but got "
-        + (null == config ? "null" : config.getClass().getName()));
-  }
-}
-
-// End DropwizardMetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
deleted file mode 100644
index 850f9a6..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
+++ /dev/null
@@ -1,54 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Timer;
-
-import java.util.Objects;
-
-/**
- * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Timer}.
- */
-public class DropwizardTimer implements org.apache.calcite.avatica.metrics.Timer {
-
-  private final Timer timer;
-
-  public DropwizardTimer(Timer timer) {
-    this.timer = Objects.requireNonNull(timer);
-  }
-
-  @Override public DropwizardContext start() {
-    return new DropwizardContext(timer.time());
-  }
-
-  /**
-   * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Timer.Context}
-   */
-  public class DropwizardContext implements org.apache.calcite.avatica.metrics.Timer.Context {
-    private final com.codahale.metrics.Timer.Context context;
-
-    public DropwizardContext(com.codahale.metrics.Timer.Context context) {
-      this.context = Objects.requireNonNull(context);
-    }
-
-    @Override public void close() {
-      this.context.stop();
-    }
-  }
-}
-
-// End DropwizardTimer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java b/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
deleted file mode 100644
index f88df93..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * Dropwizard-Metrics (v3) implementation of the Avatica Metrics framework.
- */
-@PackageMarker
-package org.apache.calcite.avatica.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.PackageMarker;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory b/avatica-metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
deleted file mode 100644
index 25b64a8..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.calcite.avatica.metrics.dropwizard3.DropwizardMetricsSystemFactory
-

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
deleted file mode 100644
index b037196..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
+++ /dev/null
@@ -1,61 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Counter;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test class for {@link DropwizardCounter}.
- */
-public class DropwizardCounterTest {
-
-  private Counter counter;
-
-  @Before public void setup() {
-    this.counter = new Counter();
-  }
-
-  @Test public void testCounting() {
-    DropwizardCounter dwCounter = new DropwizardCounter(counter);
-
-    dwCounter.increment();
-    assertEquals(1L, counter.getCount());
-    dwCounter.increment();
-    assertEquals(2L, counter.getCount());
-    dwCounter.increment(2L);
-    assertEquals(4L, counter.getCount());
-    dwCounter.increment(-1L);
-    assertEquals(3L, counter.getCount());
-
-    dwCounter.decrement();
-    assertEquals(2L, counter.getCount());
-    dwCounter.decrement();
-    assertEquals(1L, counter.getCount());
-    dwCounter.decrement(4L);
-    assertEquals(-3L, counter.getCount());
-    dwCounter.decrement(-3L);
-    assertEquals(0L, counter.getCount());
-  }
-
-}
-
-// End DropwizardCounterTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
deleted file mode 100644
index ed78a58..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
+++ /dev/null
@@ -1,60 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.Gauge;
-
-import org.junit.Test;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test class for {@link DropwizardGauge}.
- */
-public class DropwizardGaugeTest {
-
-  @Test public void test() {
-    SimpleGauge gauge = new SimpleGauge();
-    DropwizardGauge<Long> dwGauge = new DropwizardGauge<>(gauge);
-
-    assertEquals(gauge.getValue(), dwGauge.getValue());
-
-    gauge.setValue(1000L);
-
-    assertEquals(gauge.getValue(), dwGauge.getValue());
-  }
-
-  /**
-   * Gauge implementation with a setter.
-   */
-  private static class SimpleGauge implements Gauge<Long> {
-
-    private final AtomicLong value = new AtomicLong(0L);
-
-    @Override public Long getValue() {
-      return this.value.get();
-    }
-
-    public void setValue(long value) {
-      this.value.set(value);
-    }
-  }
-}
-
-// End DropwizardGaugeTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
deleted file mode 100644
index 25ec5c0..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
+++ /dev/null
@@ -1,49 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Histogram;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Test class for {@link DropwizardHistogram}.
- */
-public class DropwizardHistogramTest {
-
-  private Histogram histogram;
-
-  @Before public void setup() {
-    this.histogram = Mockito.mock(Histogram.class);
-  }
-
-  @Test public void test() {
-    DropwizardHistogram dwHistogram = new DropwizardHistogram(histogram);
-
-    dwHistogram.update(10);
-
-    dwHistogram.update(100L);
-
-    Mockito.verify(histogram).update(10);
-    Mockito.verify(histogram).update(100L);
-  }
-
-}
-
-// End DropwizardHistogramTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
deleted file mode 100644
index c76c7e0..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
+++ /dev/null
@@ -1,50 +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.metrics.dropwizard3;
-
-import com.codahale.metrics.Meter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Test class for {@link DropwizardMeter}.
- */
-public class DropwizardMeterTest {
-
-  private Meter meter;
-
-  @Before public void setup() {
-    this.meter = Mockito.mock(Meter.class);
-  }
-
-  @Test public void test() {
-    DropwizardMeter dwMeter = new DropwizardMeter(this.meter);
-
-    dwMeter.mark();
-    dwMeter.mark(10L);
-    dwMeter.mark();
-    dwMeter.mark();
-
-    Mockito.verify(meter, Mockito.times(3)).mark();
-    Mockito.verify(meter).mark(10L);
-  }
-
-}
-
-// End DropwizardMeterTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
deleted file mode 100644
index 332c6e0..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
+++ /dev/null
@@ -1,54 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
-
-import com.codahale.metrics.MetricRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Test class for {@link DropwizardMetricsSystemFactory}.
- */
-public class DropwizardMetricsSystemFactoryTest {
-
-  private DropwizardMetricsSystemFactory factory;
-
-  @Before public void setup() {
-    factory = new DropwizardMetricsSystemFactory();
-  }
-
-  @Test(expected = IllegalStateException.class) public void testNullConfigurationFails() {
-    factory.create(null);
-  }
-
-  @Test(expected = IllegalStateException.class) public void testUnhandledConfigurationType() {
-    factory.create(NoopMetricsSystemConfiguration.getInstance());
-  }
-
-  @Test public void testHandledConfigurationType() {
-    DropwizardMetricsSystem metrics =
-        factory.create(new DropwizardMetricsSystemConfiguration(new MetricRegistry()));
-    assertNotNull("Expected DropwizardMetricsSystem to be non-null", metrics);
-  }
-}
-
-// End DropwizardMetricsSystemFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
deleted file mode 100644
index 7eeec3b..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
+++ /dev/null
@@ -1,161 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.Counter;
-import org.apache.calcite.avatica.metrics.Gauge;
-import org.apache.calcite.avatica.metrics.Histogram;
-import org.apache.calcite.avatica.metrics.Meter;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-
-import com.codahale.metrics.MetricRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Tests for {@link DropwizardMetricsSystem}.
- */
-public class DropwizardMetricsSystemTest {
-
-  private MetricRegistry mockRegistry;
-  private DropwizardMetricsSystem metrics;
-
-  @Before public void setup() {
-    mockRegistry = mock(MetricRegistry.class);
-    metrics = new DropwizardMetricsSystem(mockRegistry);
-  }
-
-  @Test public void testGauge() {
-    final long gaugeValue = 42L;
-    final String name = "gauge";
-    metrics.register(name, new Gauge<Long>() {
-      @Override public Long getValue() {
-        return gaugeValue;
-      }
-    });
-
-    verify(mockRegistry, times(1)).register(eq(name), any(com.codahale.metrics.Gauge.class));
-  }
-
-  @Test public void testMeter() {
-    final String name = "meter";
-    final com.codahale.metrics.Meter mockMeter = mock(com.codahale.metrics.Meter.class);
-
-    when(mockRegistry.meter(name)).thenReturn(mockMeter);
-
-    Meter meter = metrics.getMeter(name);
-
-    final long count = 5;
-    meter.mark(count);
-
-    verify(mockMeter, times(1)).mark(count);
-
-    meter.mark();
-
-    verify(mockMeter, times(1)).mark();
-  }
-
-  @Test public void testHistogram() {
-    final String name = "histogram";
-    final com.codahale.metrics.Histogram mockHistogram = mock(com.codahale.metrics.Histogram.class);
-
-    when(mockRegistry.histogram(name)).thenReturn(mockHistogram);
-
-    Histogram histogram = metrics.getHistogram(name);
-
-    long[] long_values = new long[] {1L, 5L, 15L, 30L, 60L};
-    for (long value : long_values) {
-      histogram.update(value);
-    }
-
-    for (long value : long_values) {
-      verify(mockHistogram).update(value);
-    }
-
-    int[] int_values = new int[] {2, 6, 16, 31, 61};
-    for (int value : int_values) {
-      histogram.update(value);
-    }
-
-    for (int value : int_values) {
-      verify(mockHistogram).update(value);
-    }
-  }
-
-  @Test public void testCounter() {
-    final String name = "counter";
-    final com.codahale.metrics.Counter mockCounter = mock(com.codahale.metrics.Counter.class);
-
-    when(mockRegistry.counter(name)).thenReturn(mockCounter);
-
-    Counter counter = metrics.getCounter(name);
-
-    long[] updates = new long[] {1L, 5L, -2L, 4L, -8L, 0};
-    for (long update : updates) {
-      if (update < 0) {
-        counter.decrement(Math.abs(update));
-      } else {
-        counter.increment(update);
-      }
-    }
-
-    for (long update : updates) {
-      if (update < 0) {
-        verify(mockCounter).dec(Math.abs(update));
-      } else {
-        verify(mockCounter).inc(update);
-      }
-    }
-
-    int numSingleUpdates = 3;
-    for (int i = 0; i < numSingleUpdates; i++) {
-      counter.increment();
-      counter.decrement();
-    }
-
-    verify(mockCounter, times(numSingleUpdates)).inc();
-    verify(mockCounter, times(numSingleUpdates)).dec();
-  }
-
-  @Test public void testTimer() {
-    final String name = "timer";
-    final com.codahale.metrics.Timer mockTimer = mock(com.codahale.metrics.Timer.class);
-    final com.codahale.metrics.Timer.Context mockContext =
-        mock(com.codahale.metrics.Timer.Context.class);
-
-    when(mockRegistry.timer(name)).thenReturn(mockTimer);
-    when(mockTimer.time()).thenReturn(mockContext);
-
-    Timer timer = metrics.getTimer(name);
-    Context context = timer.start();
-    context.close();
-
-    verify(mockTimer).time();
-    verify(mockContext).stop();
-  }
-}
-
-// End DropwizardMetricsSystemTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java b/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
deleted file mode 100644
index 536d935..0000000
--- a/avatica-metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
+++ /dev/null
@@ -1,56 +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.metrics.dropwizard3;
-
-import org.apache.calcite.avatica.metrics.dropwizard3.DropwizardTimer.DropwizardContext;
-
-import com.codahale.metrics.Timer;
-import com.codahale.metrics.Timer.Context;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Test class for {@link DropwizardTimer}
- */
-public class DropwizardTimerTest {
-
-  private Timer timer;
-  private Context context;
-
-  @Before public void setup() {
-    this.timer = Mockito.mock(Timer.class);
-    this.context = Mockito.mock(Context.class);
-  }
-
-  @Test public void test() {
-    DropwizardTimer dwTimer = new DropwizardTimer(timer);
-
-    Mockito.when(timer.time()).thenReturn(context);
-
-    DropwizardContext dwContext = dwTimer.start();
-
-    dwContext.close();
-
-    Mockito.verify(timer).time();
-    Mockito.verify(context).stop();
-  }
-
-}
-
-// End DropwizardTimerTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/pom.xml
----------------------------------------------------------------------
diff --git a/avatica-metrics/pom.xml b/avatica-metrics/pom.xml
deleted file mode 100644
index cb7da6e..0000000
--- a/avatica-metrics/pom.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>calcite-avatica-metrics</artifactId>
-  <packaging>jar</packaging>
-  <name>Calcite Avatica Metrics</name>
-  <description>A library designed to abstract away any required dependency on a metrics library</description>
-
-  <properties>
-    <top.dir>${project.basedir}/..</top.dir>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <versionRange>[2.12.1,)</versionRange>
-                    <goals>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <!-- configurations do not cascade, so all of the definition from
-             ../pom.xml:build:plugin-management:plugins:plugin must be repeated in child poms -->
-        <executions>
-          <execution>
-            <id>analyze</id>
-            <goals>
-              <goal>analyze-only</goal>
-            </goals>
-            <configuration>
-              <failOnWarning>true</failOnWarning>
-              <!-- ignore "unused but declared" warnings -->
-              <ignoredUnusedDeclaredDependencies>
-                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
-              </ignoredUnusedDeclaredDependencies>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <!-- Parent module has the same plugin and does the work of
-           generating -sources.jar for each project. But without the
-           plugin declared here, IDEs don't know the sources are
-           available. -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-source-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-sources</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>jar-no-fork</goal>
-              <goal>test-jar-no-fork</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-remote-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>non-root-resources</id>
-            <goals>
-              <goal>process</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
deleted file mode 100644
index 87aec1b..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
+++ /dev/null
@@ -1,49 +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.metrics;
-
-/**
- * A mutable number.
- */
-public interface Counter {
-
-  /**
-   * Increment {@code this} by 1.
-   */
-  void increment();
-
-  /**
-   * Increment {@code this} by {@code n}.
-   *
-   * @param n The amount to increment.
-   */
-  void increment(long n);
-
-  /**
-   * Decrement {@code this} by 1.
-   */
-  void decrement();
-
-  /**
-   * Decrement {@code this} by {@code n}.
-   *
-   * @param n The amount to decrement.
-   */
-  void decrement(long n);
-}
-
-// End Counter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
deleted file mode 100644
index 6313a9a..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
+++ /dev/null
@@ -1,30 +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.metrics;
-
-/**
- * A metrics which measures a discrete value.
- *
- * @param <T> The value of the Gauge.
- */
-public interface Gauge<T> extends Metric {
-
-  T getValue();
-
-}
-
-// End Gauge.java


[36/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
new file mode 100644
index 0000000..11a6104
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
@@ -0,0 +1,118 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Mock implementation of {@link Service}
+ * that encodes its requests and responses as JSON
+ * and looks up responses from a pre-defined map.
+ */
+public class MockJsonService extends JsonService {
+  private final Map<String, String> map;
+
+  public MockJsonService(Map<String, String> map) {
+    this.map = map;
+  }
+
+  @Override public String apply(String request) {
+    String response = map.get(request);
+    if (response == null) {
+      throw new RuntimeException("No response for " + request);
+    }
+    return response;
+  }
+
+  /** Factory that creates a {@code MockJsonService}. */
+  public static class Factory implements Service.Factory {
+    public Service create(AvaticaConnection connection) {
+      final String connectionId = connection.id;
+      final Map<String, String> map1 = new HashMap<>();
+      try {
+        map1.put(
+            "{\"request\":\"openConnection\",\"connectionId\":\"" + connectionId + "\",\"info\":{}}",
+            "{\"response\":\"openConnection\"}");
+        map1.put(
+            "{\"request\":\"closeConnection\",\"connectionId\":\"" + connectionId + "\"}",
+            "{\"response\":\"closeConnection\"}");
+        map1.put(
+            "{\"request\":\"getSchemas\",\"catalog\":null,\"schemaPattern\":{\"s\":null}}",
+            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
+        map1.put(
+            JsonService.encode(new SchemasRequest(connectionId, null, null)),
+            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
+        map1.put(
+            JsonService.encode(
+                new TablesRequest(connectionId, null, null, null, Arrays.<String>asList())),
+            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
+        map1.put(
+            "{\"request\":\"createStatement\",\"connectionId\":\"" + connectionId + "\"}",
+            "{\"response\":\"createStatement\",\"id\":0}");
+        map1.put(
+            "{\"request\":\"prepareAndExecute\",\"statementId\":0,"
+                + "\"sql\":\"select * from (\\n  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)\",\"maxRowCount\":-1}",
+            "{\"response\":\"resultSet\", updateCount: -1, \"signature\": {\n"
+                + " \"columns\": [\n"
+                + "   {\"columnName\": \"C1\", \"type\": {type: \"scalar\", id: 4, rep: \"INTEGER\"}},\n"
+                + "   {\"columnName\": \"C2\", \"type\": {type: \"scalar\", id: 12, rep: \"STRING\"}}\n"
+                + " ], \"cursorFactory\": {\"style\": \"ARRAY\"}\n"
+                + "}, \"rows\": [[1, \"a\"], [null, \"b\"], [3, \"c\"]]}");
+        map1.put(
+            "{\"request\":\"prepare\",\"statementId\":0,"
+                + "\"sql\":\"select * from (\\n  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)\",\"maxRowCount\":-1}",
+            "{\"response\":\"prepare\",\"signature\": {\n"
+                + " \"columns\": [\n"
+                + "   {\"columnName\": \"C1\", \"type\": {type: \"scalar\", id: 4, rep: \"INTEGER\"}},\n"
+                + "   {\"columnName\": \"C2\", \"type\": {type: \"scalar\", id: 12, rep: \"STRING\"}}\n"
+                + " ],\n"
+                + " \"parameters\": [],\n"
+                + " \"cursorFactory\": {\"style\": \"ARRAY\"}\n"
+                + "}}");
+        map1.put(
+            "{\"request\":\"getColumns\",\"connectionId\":\"" + connectionId + "\",\"catalog\":null,\"schemaPattern\":null,"
+                + "\"tableNamePattern\":\"my_table\",\"columnNamePattern\":null}",
+            "{\"response\":\"resultSet\",\"connectionId\":\"00000000-0000-0000-0000-000000000000\",\"statementId\":-1,\"ownStatement\":true,"
+                + "\"signature\":{\"columns\":["
+                  + "{\"ordinal\":0,\"autoIncrement\":false,\"caseSensitive\":false,\"searchable\":true,\"currency\":false,\"nullable\":1,\"signed\":false,"
+                    + "\"displaySize\":40,\"label\":\"TABLE_NAME\",\"columnName\":\"TABLE_NAME\",\"schemaName\":\"\",\"precision\":0,\"scale\":0,\"tableName\":\"SYSTEM.TABLE\","
+                    + "\"catalogName\":\"\",\"type\":{\"type\":\"scalar\",\"id\":12,\"name\":\"VARCHAR\",\"rep\":\"STRING\"},\"readOnly\":true,\"writable\":false,"
+                    + "\"definitelyWritable\":false,\"columnClassName\":\"java.lang.String\"},"
+                  + "{\"ordinal\":1,\"autoIncrement\":false,\"caseSensitive\":false,\"searchable\":true,\"currency\":false,\"nullable\":1,\"signed\":true,"
+                    + "\"displaySize\":40,\"label\":\"ORDINAL_POSITION\",\"columnName\":\"ORDINAL_POSITION\",\"schemaName\":\"\",\"precision\":0,\"scale\":0,"
+                    + "\"tableName\":\"SYSTEM.TABLE\",\"catalogName\":\"\",\"type\":{\"type\":\"scalar\",\"id\":-5,\"name\":\"BIGINT\",\"rep\":\"PRIMITIVE_LONG\"},"
+                    + "\"readOnly\":true,\"writable\":false,\"definitelyWritable\":false,\"columnClassName\":\"java.lang.Long\"}"
+                + "],\"sql\":null,"
+                + "\"parameters\":[],"
+                + "\"cursorFactory\":{\"style\":\"LIST\",\"clazz\":null,\"fieldNames\":null},\"statementType\":null},"
+                + "\"firstFrame\":{\"offset\":0,\"done\":true,"
+                + "\"rows\":[[\"my_table\",10]]"
+                + "},\"updateCount\":-1}");
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+      return new MockJsonService(map1);
+    }
+  }
+}
+
+// End MockJsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
new file mode 100644
index 0000000..2fcb19a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
@@ -0,0 +1,144 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.MetaImpl;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A mock implementation of ProtobufService for testing.
+ *
+ * <p>It performs no serialization of requests and responses.
+ */
+public class MockProtobufService extends ProtobufService {
+
+  private final String connectionId;
+  private final Map<Request, Response> mapping;
+
+  public MockProtobufService(String connectionId) {
+    this.connectionId = connectionId;
+    this.mapping = createMapping();
+  }
+
+  private Map<Request, Response> createMapping() {
+    HashMap<Request, Response> mappings = new HashMap<>();
+
+    // Add in mappings
+
+    mappings.put(
+        new OpenConnectionRequest(connectionId, new HashMap<String, String>()),
+        new OpenConnectionResponse());
+
+    // Get the schema, no.. schema..?
+    mappings.put(
+        new SchemasRequest(connectionId, null, null),
+        // ownStatement=false just to avoid the extra close statement call.
+        new ResultSetResponse(null, 1, false, null, Meta.Frame.EMPTY, -1, null));
+
+    // Get the tables, no tables exist
+    mappings.put(new TablesRequest(connectionId, null, null, null, Collections.<String>emptyList()),
+        // ownStatement=false just to avoid the extra close statement call.
+        new ResultSetResponse(null, 150, false, null, Meta.Frame.EMPTY, -1, null));
+
+    // Create a statement, get back an id
+    mappings.put(new CreateStatementRequest("0"), new CreateStatementResponse("0", 1, null));
+
+    // Prepare and execute a query. Values and schema are returned
+    mappings.put(
+        new PrepareAndExecuteRequest(connectionId, 1,
+            "select * from (\\n values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)", -1),
+        new ResultSetResponse("0", 1, true,
+            Meta.Signature.create(
+                Arrays.<ColumnMetaData>asList(
+                    MetaImpl.columnMetaData("C1", 0, Integer.class),
+                    MetaImpl.columnMetaData("C2", 1, String.class)),
+                null, null, Meta.CursorFactory.ARRAY, Meta.StatementType.SELECT),
+            Meta.Frame.create(0, true,
+                Arrays.<Object>asList(new Object[] {1, "a"},
+                    new Object[] {null, "b"}, new Object[] {3, "c"})), -1, null));
+
+    // Prepare a query. Schema for results are returned, but no values
+    mappings.put(
+        new PrepareRequest(connectionId,
+            "select * from (\\n values(1, 'a'), (null, 'b'), (3, 'c')), as t (c1, c2)", -1),
+        new ResultSetResponse("0", 1, true,
+            Meta.Signature.create(
+                Arrays.<ColumnMetaData>asList(
+                    MetaImpl.columnMetaData("C1", 0, Integer.class),
+                    MetaImpl.columnMetaData("C2", 1, String.class)),
+                null, Collections.<AvaticaParameter>emptyList(),
+                Meta.CursorFactory.ARRAY, Meta.StatementType.SELECT),
+            null, -1, null));
+
+    mappings.put(
+        new ColumnsRequest(connectionId, null, null, "my_table", null),
+        new ResultSetResponse("00000000-0000-0000-0000-000000000000", -1, true,
+            Meta.Signature.create(
+                Arrays.<ColumnMetaData>asList(
+                    MetaImpl.columnMetaData("TABLE_NAME", 0, String.class),
+                    MetaImpl.columnMetaData("ORDINAL_POSITION", 1, Long.class)), null,
+                Collections.<AvaticaParameter>emptyList(), Meta.CursorFactory.ARRAY, null),
+            Meta.Frame.create(0, true,
+                Arrays.<Object>asList(new Object[] {new Object[]{"my_table", 10}})), -1, null));
+
+    return Collections.unmodifiableMap(mappings);
+  }
+
+  @Override public Response _apply(Request request) {
+    if (request instanceof CloseConnectionRequest) {
+      return new CloseConnectionResponse();
+    }
+
+    return dispatch(request);
+  }
+
+  /**
+   * Fetches the static response for the given request.
+   *
+   * @param request the client's request
+   * @return the appropriate response
+   * @throws RuntimeException if no mapping is found for the request
+   */
+  private Response dispatch(Request request) {
+    Response response = mapping.get(request);
+
+    if (null == response) {
+      throw new RuntimeException("Had no response mapping for " + request);
+    }
+
+    return response;
+  }
+
+  /**
+   * A factory that instantiates the mock protobuf service.
+   */
+  public static class MockProtobufServiceFactory implements Service.Factory {
+    @Override public Service create(AvaticaConnection connection) {
+      return new MockProtobufService(connection.id);
+    }
+  }
+}
+
+// End MockProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
new file mode 100644
index 0000000..89e380e
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
@@ -0,0 +1,62 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+import org.apache.calcite.avatica.remote.Service.Response;
+
+import java.io.IOException;
+
+/**
+ * Dispatches serialized protocol buffer messages to the provided {@link Service}
+ * by converting them to the POJO Request. Returns back the serialized protocol
+ * buffer response.
+ */
+public class ProtobufHandler extends AbstractHandler<byte[]> {
+
+  private final ProtobufTranslation translation;
+  private final MetricsSystem metrics;
+  private final Timer serializationTimer;
+
+  public ProtobufHandler(Service service, ProtobufTranslation translation, MetricsSystem metrics) {
+    super(service);
+    this.translation = translation;
+    this.metrics = metrics;
+    this.serializationTimer = this.metrics.getTimer(
+        MetricsHelper.concat(ProtobufHandler.class, HANDLER_SERIALIZATION_METRICS_NAME));
+  }
+
+  @Override public HandlerResponse<byte[]> apply(byte[] requestBytes) {
+    return super.apply(requestBytes);
+  }
+
+  @Override Service.Request decode(byte[] serializedRequest) throws IOException {
+    try (final Context ctx = serializationTimer.start()) {
+      return translation.parseRequest(serializedRequest);
+    }
+  }
+
+  @Override byte[] encode(Response response) throws IOException {
+    try (final Context ctx = serializationTimer.start()) {
+      return translation.serializeResponse(response);
+    }
+  }
+}
+
+// End ProtobufHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
new file mode 100644
index 0000000..56ba125
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
@@ -0,0 +1,132 @@
+/*
+ * 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.remote;
+
+import com.google.protobuf.Message;
+
+/**
+ * Service implementation that encodes requests and responses as protocol buffers.
+ */
+public abstract class ProtobufService extends AbstractService {
+
+  /**
+   * Derived class should implement this method to transport requests and
+   * responses to and from the peer service.
+   */
+  public abstract Response _apply(Request request);
+
+  @Override SerializationType getSerializationType() {
+    return SerializationType.PROTOBUF;
+  }
+
+  @Override public ResultSetResponse apply(CatalogsRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public ResultSetResponse apply(SchemasRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public ResultSetResponse apply(TablesRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public ResultSetResponse apply(TableTypesRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public ResultSetResponse apply(TypeInfoRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public ResultSetResponse apply(ColumnsRequest request) {
+    return finagle((ResultSetResponse) _apply(request));
+  }
+
+  @Override public PrepareResponse apply(PrepareRequest request) {
+    return finagle((PrepareResponse) _apply(request));
+  }
+
+  @Override public ExecuteResponse apply(PrepareAndExecuteRequest request) {
+    return finagle((ExecuteResponse) _apply(request));
+  }
+
+  @Override public FetchResponse apply(FetchRequest request) {
+    return (FetchResponse) _apply(request);
+  }
+
+  @Override public CreateStatementResponse apply(CreateStatementRequest request) {
+    return (CreateStatementResponse) _apply(request);
+  }
+
+  @Override public CloseStatementResponse apply(CloseStatementRequest request) {
+    return (CloseStatementResponse) _apply(request);
+  }
+
+  @Override public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    return (OpenConnectionResponse) _apply(request);
+  }
+
+  @Override public CloseConnectionResponse apply(CloseConnectionRequest request) {
+    return (CloseConnectionResponse) _apply(request);
+  }
+
+  @Override public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
+    return (ConnectionSyncResponse) _apply(request);
+  }
+
+  @Override public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
+    return (DatabasePropertyResponse) _apply(request);
+  }
+
+  @Override public ExecuteResponse apply(ExecuteRequest request) {
+    return finagle((ExecuteResponse) _apply(request));
+  }
+
+  @Override public SyncResultsResponse apply(SyncResultsRequest request) {
+    return (SyncResultsResponse) _apply(request);
+  }
+
+  @Override public CommitResponse apply(CommitRequest request) {
+    return (CommitResponse) _apply(request);
+  }
+
+  @Override public RollbackResponse apply(RollbackRequest request) {
+    return (RollbackResponse) _apply(request);
+  }
+
+  /**
+   * Checks if the provided {@link Message} is an instance of the Class given by
+   * <code>expectedType</code>. Throws an IllegalArgumentException if the message is not of the
+   * expected type, otherwise, it returns the message cast as the expected type.
+   *
+   * @param msg A Protocol Buffer message.
+   * @param expectedType The expected type of the Protocol Buffer message.
+   * @return The msg cast to the concrete Message type.
+   * @throws IllegalArgumentException If the type of the message is not the expectedType.
+   */
+  public static <T extends Message> T castProtobufMessage(Message msg, Class<T> expectedType) {
+    if (!expectedType.isInstance(msg)) {
+      throw new IllegalArgumentException("Expected instance of " + expectedType.getName()
+          + ", but got " + msg.getClass().getName());
+    }
+
+    return expectedType.cast(msg);
+  }
+}
+
+// End ProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
new file mode 100644
index 0000000..7142d59
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
@@ -0,0 +1,64 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+
+import java.io.IOException;
+
+/**
+ * Generic interface to support parsing of serialized protocol buffers between client and server.
+ */
+public interface ProtobufTranslation {
+
+  /**
+   * Serializes a {@link Response} as a protocol buffer.
+   *
+   * @param response The response to serialize
+   * @throws IOException If there are errors during serialization
+   */
+  byte[] serializeResponse(Response response) throws IOException;
+
+  /**
+   * Serializes a {@link Request} as a protocol buffer.
+   *
+   * @param request The request to serialize
+   * @throws IOException If there are errors during serialization
+   */
+  byte[] serializeRequest(Request request) throws IOException;
+
+  /**
+   * Parses a serialized protocol buffer request into a {@link Request}.
+   *
+   * @param bytes Serialized protocol buffer request from client
+   * @return A Request object for the given bytes
+   * @throws IOException If the protocol buffer cannot be deserialized
+   */
+  Request parseRequest(byte[] bytes) throws IOException;
+
+  /**
+   * Parses a serialized protocol buffer response into a {@link Response}.
+   *
+   * @param bytes Serialized protocol buffer request from server
+   * @return The Response object for the given bytes
+   * @throws IOException If the protocol buffer cannot be deserialized
+   */
+  Response parseResponse(byte[] bytes) throws IOException;
+}
+
+// End ProtobufTranslation.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
new file mode 100644
index 0000000..80d2b22
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
@@ -0,0 +1,354 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.proto.Common.WireMessage;
+import org.apache.calcite.avatica.proto.Requests.CatalogsRequest;
+import org.apache.calcite.avatica.proto.Requests.CloseConnectionRequest;
+import org.apache.calcite.avatica.proto.Requests.CloseStatementRequest;
+import org.apache.calcite.avatica.proto.Requests.ColumnsRequest;
+import org.apache.calcite.avatica.proto.Requests.CommitRequest;
+import org.apache.calcite.avatica.proto.Requests.ConnectionSyncRequest;
+import org.apache.calcite.avatica.proto.Requests.CreateStatementRequest;
+import org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest;
+import org.apache.calcite.avatica.proto.Requests.ExecuteRequest;
+import org.apache.calcite.avatica.proto.Requests.FetchRequest;
+import org.apache.calcite.avatica.proto.Requests.OpenConnectionRequest;
+import org.apache.calcite.avatica.proto.Requests.PrepareAndExecuteRequest;
+import org.apache.calcite.avatica.proto.Requests.PrepareRequest;
+import org.apache.calcite.avatica.proto.Requests.RollbackRequest;
+import org.apache.calcite.avatica.proto.Requests.SchemasRequest;
+import org.apache.calcite.avatica.proto.Requests.SyncResultsRequest;
+import org.apache.calcite.avatica.proto.Requests.TableTypesRequest;
+import org.apache.calcite.avatica.proto.Requests.TablesRequest;
+import org.apache.calcite.avatica.proto.Requests.TypeInfoRequest;
+import org.apache.calcite.avatica.proto.Responses.CloseConnectionResponse;
+import org.apache.calcite.avatica.proto.Responses.CloseStatementResponse;
+import org.apache.calcite.avatica.proto.Responses.CommitResponse;
+import org.apache.calcite.avatica.proto.Responses.ConnectionSyncResponse;
+import org.apache.calcite.avatica.proto.Responses.CreateStatementResponse;
+import org.apache.calcite.avatica.proto.Responses.DatabasePropertyResponse;
+import org.apache.calcite.avatica.proto.Responses.ErrorResponse;
+import org.apache.calcite.avatica.proto.Responses.ExecuteResponse;
+import org.apache.calcite.avatica.proto.Responses.FetchResponse;
+import org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse;
+import org.apache.calcite.avatica.proto.Responses.PrepareResponse;
+import org.apache.calcite.avatica.proto.Responses.ResultSetResponse;
+import org.apache.calcite.avatica.proto.Responses.RollbackResponse;
+import org.apache.calcite.avatica.proto.Responses.RpcMetadata;
+import org.apache.calcite.avatica.proto.Responses.SyncResultsResponse;
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.HBaseZeroCopyByteString;
+import com.google.protobuf.Message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Implementation of {@link ProtobufTranslationImpl} that translates
+ * protobuf requests to POJO requests.
+ */
+public class ProtobufTranslationImpl implements ProtobufTranslation {
+
+  // Extremely ugly mapping of PB class name into a means to convert it to the POJO
+  private static final Map<String, RequestTranslator> REQUEST_PARSERS;
+  private static final Map<String, ResponseTranslator> RESPONSE_PARSERS;
+  private static final Map<Class<?>, ByteString> MESSAGE_CLASSES;
+
+  static {
+    Map<String, RequestTranslator> reqParsers = new ConcurrentHashMap<>();
+    reqParsers.put(CatalogsRequest.class.getName(),
+        new RequestTranslator(CatalogsRequest.parser(), new Service.CatalogsRequest()));
+    reqParsers.put(OpenConnectionRequest.class.getName(),
+        new RequestTranslator(OpenConnectionRequest.parser(), new Service.OpenConnectionRequest()));
+    reqParsers.put(CloseConnectionRequest.class.getName(),
+        new RequestTranslator(CloseConnectionRequest.parser(),
+          new Service.CloseConnectionRequest()));
+    reqParsers.put(CloseStatementRequest.class.getName(),
+        new RequestTranslator(CloseStatementRequest.parser(), new Service.CloseStatementRequest()));
+    reqParsers.put(ColumnsRequest.class.getName(),
+        new RequestTranslator(ColumnsRequest.parser(), new Service.ColumnsRequest()));
+    reqParsers.put(ConnectionSyncRequest.class.getName(),
+        new RequestTranslator(ConnectionSyncRequest.parser(), new Service.ConnectionSyncRequest()));
+    reqParsers.put(CreateStatementRequest.class.getName(),
+        new RequestTranslator(CreateStatementRequest.parser(),
+          new Service.CreateStatementRequest()));
+    reqParsers.put(DatabasePropertyRequest.class.getName(),
+        new RequestTranslator(DatabasePropertyRequest.parser(),
+            new Service.DatabasePropertyRequest()));
+    reqParsers.put(FetchRequest.class.getName(),
+        new RequestTranslator(FetchRequest.parser(), new Service.FetchRequest()));
+    reqParsers.put(PrepareAndExecuteRequest.class.getName(),
+        new RequestTranslator(PrepareAndExecuteRequest.parser(),
+            new Service.PrepareAndExecuteRequest()));
+    reqParsers.put(PrepareRequest.class.getName(),
+        new RequestTranslator(PrepareRequest.parser(), new Service.PrepareRequest()));
+    reqParsers.put(SchemasRequest.class.getName(),
+        new RequestTranslator(SchemasRequest.parser(), new Service.SchemasRequest()));
+    reqParsers.put(TablesRequest.class.getName(),
+        new RequestTranslator(TablesRequest.parser(), new Service.TablesRequest()));
+    reqParsers.put(TableTypesRequest.class.getName(),
+        new RequestTranslator(TableTypesRequest.parser(), new Service.TableTypesRequest()));
+    reqParsers.put(TypeInfoRequest.class.getName(),
+        new RequestTranslator(TypeInfoRequest.parser(), new Service.TypeInfoRequest()));
+    reqParsers.put(ExecuteRequest.class.getName(),
+        new RequestTranslator(ExecuteRequest.parser(), new Service.ExecuteRequest()));
+    reqParsers.put(SyncResultsRequest.class.getName(),
+        new RequestTranslator(SyncResultsRequest.parser(), new Service.SyncResultsRequest()));
+    reqParsers.put(CommitRequest.class.getName(),
+        new RequestTranslator(CommitRequest.parser(), new Service.CommitRequest()));
+    reqParsers.put(RollbackRequest.class.getName(),
+        new RequestTranslator(RollbackRequest.parser(), new Service.RollbackRequest()));
+
+    REQUEST_PARSERS = Collections.unmodifiableMap(reqParsers);
+
+    Map<String, ResponseTranslator> respParsers = new ConcurrentHashMap<>();
+    respParsers.put(OpenConnectionResponse.class.getName(),
+        new ResponseTranslator(OpenConnectionResponse.parser(),
+            new Service.OpenConnectionResponse()));
+    respParsers.put(CloseConnectionResponse.class.getName(),
+        new ResponseTranslator(CloseConnectionResponse.parser(),
+            new Service.CloseConnectionResponse()));
+    respParsers.put(CloseStatementResponse.class.getName(),
+        new ResponseTranslator(CloseStatementResponse.parser(),
+            new Service.CloseStatementResponse()));
+    respParsers.put(ConnectionSyncResponse.class.getName(),
+        new ResponseTranslator(ConnectionSyncResponse.parser(),
+            new Service.ConnectionSyncResponse()));
+    respParsers.put(CreateStatementResponse.class.getName(),
+        new ResponseTranslator(CreateStatementResponse.parser(),
+            new Service.CreateStatementResponse()));
+    respParsers.put(DatabasePropertyResponse.class.getName(),
+        new ResponseTranslator(DatabasePropertyResponse.parser(),
+            new Service.DatabasePropertyResponse()));
+    respParsers.put(ExecuteResponse.class.getName(),
+        new ResponseTranslator(ExecuteResponse.parser(), new Service.ExecuteResponse()));
+    respParsers.put(FetchResponse.class.getName(),
+        new ResponseTranslator(FetchResponse.parser(), new Service.FetchResponse()));
+    respParsers.put(PrepareResponse.class.getName(),
+        new ResponseTranslator(PrepareResponse.parser(), new Service.PrepareResponse()));
+    respParsers.put(ResultSetResponse.class.getName(),
+        new ResponseTranslator(ResultSetResponse.parser(), new Service.ResultSetResponse()));
+    respParsers.put(ErrorResponse.class.getName(),
+        new ResponseTranslator(ErrorResponse.parser(), new Service.ErrorResponse()));
+    respParsers.put(SyncResultsResponse.class.getName(),
+        new ResponseTranslator(SyncResultsResponse.parser(), new Service.SyncResultsResponse()));
+    respParsers.put(RpcMetadata.class.getName(),
+        new ResponseTranslator(RpcMetadata.parser(), new RpcMetadataResponse()));
+    respParsers.put(CommitResponse.class.getName(),
+        new ResponseTranslator(CommitResponse.parser(), new Service.CommitResponse()));
+    respParsers.put(RollbackResponse.class.getName(),
+        new ResponseTranslator(RollbackResponse.parser(), new Service.RollbackResponse()));
+
+    RESPONSE_PARSERS = Collections.unmodifiableMap(respParsers);
+
+    Map<Class<?>, ByteString> messageClassNames = new ConcurrentHashMap<>();
+    for (Class<?> msgClz : getAllMessageClasses()) {
+      messageClassNames.put(msgClz, wrapClassName(msgClz));
+    }
+    MESSAGE_CLASSES = Collections.unmodifiableMap(messageClassNames);
+  }
+
+  private static List<Class<?>> getAllMessageClasses() {
+    List<Class<?>> messageClasses = new ArrayList<>();
+    messageClasses.add(CatalogsRequest.class);
+    messageClasses.add(CloseConnectionRequest.class);
+    messageClasses.add(CloseStatementRequest.class);
+    messageClasses.add(ColumnsRequest.class);
+    messageClasses.add(CommitRequest.class);
+    messageClasses.add(ConnectionSyncRequest.class);
+    messageClasses.add(CreateStatementRequest.class);
+    messageClasses.add(DatabasePropertyRequest.class);
+    messageClasses.add(ExecuteRequest.class);
+    messageClasses.add(FetchRequest.class);
+    messageClasses.add(OpenConnectionRequest.class);
+    messageClasses.add(PrepareAndExecuteRequest.class);
+    messageClasses.add(PrepareRequest.class);
+    messageClasses.add(RollbackRequest.class);
+    messageClasses.add(SchemasRequest.class);
+    messageClasses.add(SyncResultsRequest.class);
+    messageClasses.add(TableTypesRequest.class);
+    messageClasses.add(TablesRequest.class);
+    messageClasses.add(TypeInfoRequest.class);
+    messageClasses.add(CloseConnectionResponse.class);
+    messageClasses.add(CloseStatementResponse.class);
+    messageClasses.add(CommitResponse.class);
+    messageClasses.add(ConnectionSyncResponse.class);
+    messageClasses.add(CreateStatementResponse.class);
+    messageClasses.add(DatabasePropertyResponse.class);
+    messageClasses.add(ErrorResponse.class);
+    messageClasses.add(ExecuteResponse.class);
+    messageClasses.add(FetchResponse.class);
+    messageClasses.add(OpenConnectionResponse.class);
+    messageClasses.add(PrepareResponse.class);
+    messageClasses.add(ResultSetResponse.class);
+    messageClasses.add(RollbackResponse.class);
+    messageClasses.add(RpcMetadata.class);
+    messageClasses.add(SyncResultsResponse.class);
+
+    return messageClasses;
+  }
+
+  private static ByteString wrapClassName(Class<?> clz) {
+    return HBaseZeroCopyByteString.wrap(clz.getName().getBytes(UTF_8));
+  }
+
+  private final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer =
+      new ThreadLocal<UnsynchronizedBuffer>() {
+        @Override protected UnsynchronizedBuffer initialValue() {
+          return new UnsynchronizedBuffer();
+        }
+      };
+
+  /**
+   * Fetches the concrete message's Parser implementation.
+   *
+   * @param className The protocol buffer class name
+   * @return The Parser for the class
+   * @throws IllegalArgumentException If the argument is null or if a Parser for the given
+   *     class name is not found.
+   */
+  public static RequestTranslator getParserForRequest(String className) {
+    if (null == className) {
+      throw new IllegalArgumentException("Cannot fetch parser for null class name");
+    }
+
+    RequestTranslator translator = REQUEST_PARSERS.get(className);
+    if (null == translator) {
+      throw new IllegalArgumentException("Cannot find parser for " + className);
+    }
+
+    return translator;
+  }
+
+  /**
+   * Fetches the concrete message's Parser implementation.
+   *
+   * @param className The protocol buffer class name
+   * @return The Parser for the class
+   * @throws IllegalArgumentException If the argument is null or if a Parser for the given
+   *     class name is not found.
+   */
+  public static ResponseTranslator getParserForResponse(String className) {
+    if (null == className) {
+      throw new IllegalArgumentException("Cannot fetch parser for null class name");
+    }
+
+    ResponseTranslator translator = RESPONSE_PARSERS.get(className);
+    if (null == translator) {
+      throw new IllegalArgumentException("Cannot find parser for " + className);
+    }
+
+    return translator;
+  }
+
+  @Override public byte[] serializeResponse(Response response) throws IOException {
+    // Avoid BAOS for its synchronized write methods, we don't need that concurrency control
+    UnsynchronizedBuffer out = threadLocalBuffer.get();
+    try {
+      Message responseMsg = response.serialize();
+      serializeMessage(out, responseMsg);
+      return out.toArray();
+    } finally {
+      out.reset();
+    }
+  }
+
+  @Override public byte[] serializeRequest(Request request) throws IOException {
+    // Avoid BAOS for its synchronized write methods, we don't need that concurrency control
+    UnsynchronizedBuffer out = threadLocalBuffer.get();
+    try {
+      Message requestMsg = request.serialize();
+      serializeMessage(out, requestMsg);
+      return out.toArray();
+    } finally {
+      out.reset();
+    }
+  }
+
+  void serializeMessage(OutputStream out, Message msg) throws IOException {
+    // Serialize the protobuf message
+    UnsynchronizedBuffer buffer = threadLocalBuffer.get();
+    ByteString serializedMsg;
+    try {
+      msg.writeTo(buffer);
+      // Make a bytestring from it
+      serializedMsg = HBaseZeroCopyByteString.wrap(buffer.toArray());
+    } finally {
+      buffer.reset();
+    }
+
+    // Wrap the serialized message in a WireMessage
+    WireMessage wireMsg = WireMessage.newBuilder().setNameBytes(getClassNameBytes(msg.getClass()))
+        .setWrappedMessage(serializedMsg).build();
+
+    // Write the WireMessage to the provided OutputStream
+    wireMsg.writeTo(out);
+  }
+
+  ByteString getClassNameBytes(Class<?> clz) {
+    ByteString byteString = MESSAGE_CLASSES.get(clz);
+    if (null == byteString) {
+      throw new IllegalArgumentException("Missing ByteString for " + clz.getName());
+    }
+    return byteString;
+  }
+
+  @Override public Request parseRequest(byte[] bytes) throws IOException {
+    ByteString byteString = HBaseZeroCopyByteString.wrap(bytes);
+    CodedInputStream inputStream = byteString.newCodedInput();
+    // Enable aliasing to avoid an extra copy to get at the serialized Request inside of the
+    // WireMessage.
+    inputStream.enableAliasing(true);
+    WireMessage wireMsg = WireMessage.parseFrom(inputStream);
+
+    String serializedMessageClassName = wireMsg.getName();
+    RequestTranslator translator = getParserForRequest(serializedMessageClassName);
+
+    // The ByteString should be logical offsets into the original byte array
+    return translator.transform(wireMsg.getWrappedMessage());
+  }
+
+  @Override public Response parseResponse(byte[] bytes) throws IOException {
+    ByteString byteString = HBaseZeroCopyByteString.wrap(bytes);
+    CodedInputStream inputStream = byteString.newCodedInput();
+    // Enable aliasing to avoid an extra copy to get at the serialized Response inside of the
+    // WireMessage.
+    inputStream.enableAliasing(true);
+    WireMessage wireMsg = WireMessage.parseFrom(inputStream);
+
+    String serializedMessageClassName = wireMsg.getName();
+    ResponseTranslator translator = getParserForResponse(serializedMessageClassName);
+
+    return translator.transform(wireMsg.getWrappedMessage());
+  }
+}
+
+// End ProtobufTranslationImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
new file mode 100644
index 0000000..463985a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -0,0 +1,395 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaConnection.CallableWithoutException;
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.MetaImpl;
+import org.apache.calcite.avatica.MissingResultsException;
+import org.apache.calcite.avatica.NoSuchStatementException;
+import org.apache.calcite.avatica.QueryState;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.Meta} for the remote
+ * driver.
+ */
+class RemoteMeta extends MetaImpl {
+  final Service service;
+  final Map<String, ConnectionPropertiesImpl> propsMap = new HashMap<>();
+  private Map<DatabaseProperty, Object> databaseProperties;
+
+  public RemoteMeta(AvaticaConnection connection, Service service) {
+    super(connection);
+    this.service = service;
+  }
+
+  private MetaResultSet toResultSet(Class clazz,
+      Service.ResultSetResponse response) {
+    if (response.updateCount != -1) {
+      return MetaResultSet.count(response.connectionId, response.statementId,
+          response.updateCount);
+    }
+    Signature signature0 = response.signature;
+    if (signature0 == null) {
+      final List<ColumnMetaData> columns =
+          clazz == null
+              ? Collections.<ColumnMetaData>emptyList()
+              : fieldMetaData(clazz).columns;
+      signature0 = Signature.create(columns,
+          "?", Collections.<AvaticaParameter>emptyList(), CursorFactory.ARRAY,
+          Meta.StatementType.SELECT);
+    }
+    return MetaResultSet.create(response.connectionId, response.statementId,
+        response.ownStatement, signature0, response.firstFrame);
+  }
+
+  @Override public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
+    synchronized (this) {
+      // Compute map on first use, and cache
+      if (databaseProperties == null) {
+        databaseProperties =
+            service.apply(new Service.DatabasePropertyRequest(ch.id)).map;
+      }
+      return databaseProperties;
+    }
+  }
+
+  @Override public StatementHandle createStatement(final ConnectionHandle ch) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<StatementHandle>() {
+          public StatementHandle call() {
+            // sync connection state if necessary
+            connectionSync(ch, new ConnectionPropertiesImpl());
+            final Service.CreateStatementResponse response =
+                service.apply(new Service.CreateStatementRequest(ch.id));
+            return new StatementHandle(response.connectionId, response.statementId, null);
+          }
+        });
+  }
+
+  @Override public void closeStatement(final StatementHandle h) {
+    connection.invokeWithRetries(
+        new CallableWithoutException<Void>() {
+          public Void call() {
+            final Service.CloseStatementResponse response =
+                service.apply(
+                    new Service.CloseStatementRequest(h.connectionId, h.id));
+            return null;
+          }
+        });
+  }
+
+  @Override public void openConnection(final ConnectionHandle ch, final Map<String, String> info) {
+    connection.invokeWithRetries(
+        new CallableWithoutException<Void>() {
+          public Void call() {
+            final Service.OpenConnectionResponse response =
+                service.apply(new Service.OpenConnectionRequest(ch.id, info));
+            return null;
+          }
+        });
+  }
+
+  @Override public void closeConnection(final ConnectionHandle ch) {
+    connection.invokeWithRetries(
+        new CallableWithoutException<Void>() {
+          public Void call() {
+            final Service.CloseConnectionResponse response =
+                service.apply(new Service.CloseConnectionRequest(ch.id));
+            propsMap.remove(ch.id);
+            return null;
+          }
+        });
+  }
+
+  @Override public ConnectionProperties connectionSync(final ConnectionHandle ch,
+      final ConnectionProperties connProps) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<ConnectionProperties>() {
+          public ConnectionProperties call() {
+            ConnectionPropertiesImpl localProps = propsMap.get(ch.id);
+            if (localProps == null) {
+              localProps = new ConnectionPropertiesImpl();
+              localProps.setDirty(true);
+              propsMap.put(ch.id, localProps);
+            }
+
+            // Only make an RPC if necessary. RPC is necessary when we have local changes that need
+            // flushed to the server (be sure to introduce any new changes from connProps before
+            // checking AND when connProps.isEmpty() (meaning, this was a request for a value, not
+            // overriding a value). Otherwise, accumulate the change locally and return immediately.
+            if (localProps.merge(connProps).isDirty() && connProps.isEmpty()) {
+              final Service.ConnectionSyncResponse response = service.apply(
+                  new Service.ConnectionSyncRequest(ch.id, localProps));
+              propsMap.put(ch.id, (ConnectionPropertiesImpl) response.connProps);
+              return response.connProps;
+            } else {
+              return localProps;
+            }
+          }
+        });
+  }
+
+  @Override public MetaResultSet getCatalogs(final ConnectionHandle ch) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(new Service.CatalogsRequest(ch.id));
+            return toResultSet(MetaCatalog.class, response);
+          }
+        });
+  }
+
+  @Override public MetaResultSet getSchemas(final ConnectionHandle ch, final String catalog,
+      final Pat schemaPattern) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(
+                    new Service.SchemasRequest(ch.id, catalog, schemaPattern.s));
+            return toResultSet(MetaSchema.class, response);
+          }
+        });
+  }
+
+  @Override public MetaResultSet getTables(final ConnectionHandle ch, final String catalog,
+      final Pat schemaPattern, final Pat tableNamePattern, final List<String> typeList) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(
+                    new Service.TablesRequest(ch.id, catalog, schemaPattern.s,
+                        tableNamePattern.s, typeList));
+            return toResultSet(MetaTable.class, response);
+          }
+        });
+  }
+
+  @Override public MetaResultSet getTableTypes(final ConnectionHandle ch) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(new Service.TableTypesRequest(ch.id));
+            return toResultSet(MetaTableType.class, response);
+          }
+        });
+  }
+
+  @Override public MetaResultSet getTypeInfo(final ConnectionHandle ch) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(new Service.TypeInfoRequest(ch.id));
+            return toResultSet(MetaTypeInfo.class, response);
+          }
+        });
+  }
+
+  @Override public MetaResultSet getColumns(final ConnectionHandle ch, final String catalog,
+      final Pat schemaPattern, final Pat tableNamePattern, final Pat columnNamePattern) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<MetaResultSet>() {
+          public MetaResultSet call() {
+            final Service.ResultSetResponse response =
+                service.apply(
+                    new Service.ColumnsRequest(ch.id, catalog, schemaPattern.s,
+                        tableNamePattern.s, columnNamePattern.s));
+            return toResultSet(MetaColumn.class, response);
+          }
+        });
+  }
+
+  @Override public StatementHandle prepare(final ConnectionHandle ch, final String sql,
+      final long maxRowCount) {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<StatementHandle>() {
+          public StatementHandle call() {
+            connectionSync(ch,
+                new ConnectionPropertiesImpl()); // sync connection state if necessary
+            final Service.PrepareResponse response = service.apply(
+                new Service.PrepareRequest(ch.id, sql, maxRowCount));
+            return response.statement;
+          }
+        });
+  }
+
+  @Override public ExecuteResult prepareAndExecute(final StatementHandle h, final String sql,
+      final long maxRowCount, final PrepareCallback callback) throws NoSuchStatementException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ExecuteResult>() {
+            public ExecuteResult call() {
+              // sync connection state if necessary
+              connectionSync(new ConnectionHandle(h.connectionId), new ConnectionPropertiesImpl());
+              final Service.ExecuteResponse response;
+              try {
+                synchronized (callback.getMonitor()) {
+                  callback.clear();
+                  response = service.apply(
+                      new Service.PrepareAndExecuteRequest(h.connectionId,
+                          h.id, sql, maxRowCount));
+                  if (response.missingStatement) {
+                    throw new RuntimeException(new NoSuchStatementException(h));
+                  }
+                  if (response.results.size() > 0) {
+                    final Service.ResultSetResponse result = response.results.get(0);
+                    callback.assign(result.signature, result.firstFrame,
+                        result.updateCount);
+                  }
+                }
+                callback.execute();
+                List<MetaResultSet> metaResultSets = new ArrayList<>();
+                for (Service.ResultSetResponse result : response.results) {
+                  metaResultSets.add(toResultSet(null, result));
+                }
+                return new ExecuteResult(metaResultSets);
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof NoSuchStatementException) {
+        throw (NoSuchStatementException) cause;
+      }
+      throw e;
+    }
+  }
+
+  @Override public Frame fetch(final StatementHandle h, final long offset,
+      final int fetchMaxRowCount) throws NoSuchStatementException, MissingResultsException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<Frame>() {
+            public Frame call() {
+              final Service.FetchResponse response =
+                  service.apply(
+                      new Service.FetchRequest(h.connectionId, h.id, offset, fetchMaxRowCount));
+              if (response.missingStatement) {
+                throw new RuntimeException(new NoSuchStatementException(h));
+              }
+              if (response.missingResults) {
+                throw new RuntimeException(new MissingResultsException(h));
+              }
+              return response.frame;
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof NoSuchStatementException) {
+        throw (NoSuchStatementException) cause;
+      } else if (cause instanceof MissingResultsException) {
+        throw (MissingResultsException) cause;
+      }
+      throw e;
+    }
+  }
+
+  @Override public ExecuteResult execute(final StatementHandle h,
+      final List<TypedValue> parameterValues, final long maxRowCount)
+      throws NoSuchStatementException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ExecuteResult>() {
+            public ExecuteResult call() {
+              final Service.ExecuteResponse response = service.apply(
+                  new Service.ExecuteRequest(h, parameterValues, maxRowCount));
+
+              if (response.missingStatement) {
+                throw new RuntimeException(new NoSuchStatementException(h));
+              }
+
+              List<MetaResultSet> metaResultSets = new ArrayList<>();
+              for (Service.ResultSetResponse result : response.results) {
+                metaResultSets.add(toResultSet(null, result));
+              }
+
+              return new ExecuteResult(metaResultSets);
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof NoSuchStatementException) {
+        throw (NoSuchStatementException) cause;
+      }
+      throw e;
+    }
+  }
+
+  @Override public boolean syncResults(final StatementHandle h, final QueryState state,
+      final long offset) throws NoSuchStatementException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<Boolean>() {
+            public Boolean call() {
+              final Service.SyncResultsResponse response =
+                  service.apply(
+                      new Service.SyncResultsRequest(h.connectionId, h.id, state, offset));
+              if (response.missingStatement) {
+                throw new RuntimeException(new NoSuchStatementException(h));
+              }
+              return response.moreResults;
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof NoSuchStatementException) {
+        throw (NoSuchStatementException) cause;
+      }
+      throw e;
+    }
+  }
+
+  @Override public void commit(final ConnectionHandle ch) {
+    connection.invokeWithRetries(new CallableWithoutException<Void>() {
+      public Void call() {
+        final Service.CommitResponse response =
+            service.apply(new Service.CommitRequest(ch.id));
+        return null;
+      }
+    });
+  }
+
+  @Override public void rollback(final ConnectionHandle ch) {
+    connection.invokeWithRetries(new CallableWithoutException<Void>() {
+      public Void call() {
+        final Service.RollbackResponse response =
+            service.apply(new Service.RollbackRequest(ch.id));
+        return null;
+      }
+    });
+  }
+}
+
+// End RemoteMeta.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
new file mode 100644
index 0000000..828513a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
@@ -0,0 +1,53 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+
+/**
+ * ProtobufService implementation that queries against a remote implementation, using
+ * protocol buffers as the serialized form.
+ */
+public class RemoteProtobufService extends ProtobufService {
+  private final AvaticaHttpClient client;
+  private final ProtobufTranslation translation;
+
+  public RemoteProtobufService(AvaticaHttpClient client, ProtobufTranslation translation) {
+    this.client = client;
+    this.translation = translation;
+  }
+
+  @Override public Response _apply(Request request) {
+    final Response resp;
+    try {
+      byte[] response = client.send(translation.serializeRequest(request));
+      resp = translation.parseResponse(response);
+    } catch (IOException e) {
+      // Not a protobuf that we could parse.
+      throw new RuntimeException(e);
+    }
+
+    // The server had an error, throw an Exception for that.
+    if (resp instanceof ErrorResponse) {
+      throw ((ErrorResponse) resp).toException();
+    }
+
+    return resp;
+  }
+}
+
+// End RemoteProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
new file mode 100644
index 0000000..d4828b5
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
@@ -0,0 +1,39 @@
+/*
+ * 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.remote;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.remote.Service}
+ * that translates requests into JSON and sends them to a remote server,
+ * usually an HTTP server.
+ */
+public class RemoteService extends JsonService {
+  private final AvaticaHttpClient client;
+
+  public RemoteService(AvaticaHttpClient client) {
+    this.client = client;
+  }
+
+  @Override public String apply(String request) {
+    byte[] response = client.send(request.getBytes(StandardCharsets.UTF_8));
+    return new String(response, StandardCharsets.UTF_8);
+  }
+}
+
+// End RemoteService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
new file mode 100644
index 0000000..417c6ed
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.remote;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+import com.google.protobuf.Parser;
+
+/**
+ * Encapsulate the logic of transforming a protobuf Request message into the Avatica POJO request.
+ */
+public class RequestTranslator {
+
+  private final Parser<? extends Message> parser;
+  private final Service.Request impl;
+
+  public RequestTranslator(Parser<? extends Message> parser, Service.Request impl) {
+    this.parser = parser;
+    this.impl = impl;
+  }
+
+  public Service.Request transform(ByteString serializedMessage) throws
+      InvalidProtocolBufferException {
+    // This should already be an aliased CodedInputStream from the WireMessage parsing.
+    Message msg = parser.parseFrom(serializedMessage.newCodedInput());
+    return impl.deserialize(msg);
+  }
+}
+
+// End RequestTranslator.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
new file mode 100644
index 0000000..0311e13
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.remote;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+import com.google.protobuf.Parser;
+
+/**
+ * Encapsulate the logic of transforming a protobuf Response message into the Avatica POJO Response.
+ */
+public class ResponseTranslator {
+
+  private final Parser<? extends Message> parser;
+  private final Service.Response impl;
+
+  public ResponseTranslator(Parser<? extends Message> parser, Service.Response impl) {
+    this.parser = parser;
+    this.impl = impl;
+  }
+
+  public Service.Response transform(ByteString serializedMessage) throws
+      InvalidProtocolBufferException {
+    Message msg = parser.parseFrom(serializedMessage);
+    return impl.deserialize(msg);
+  }
+}
+
+// End ResponseTranslator.java


[24/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
new file mode 100644
index 0000000..ff95a45
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
@@ -0,0 +1,626 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaSqlException;
+import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.ConnectionSpec;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.jdbc.JdbcMeta;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.Response;
+import org.apache.calcite.avatica.server.AvaticaJsonHandler;
+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.base.Throwables;
+import com.google.common.cache.Cache;
+
+import org.junit.AfterClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.Array;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+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.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/** Tests covering {@link RemoteMeta}. */
+@RunWith(Parameterized.class)
+public class RemoteMetaTest {
+  private static final Random RANDOM = new Random();
+  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
+
+  // Keep a reference to the servers we start to clean them up after
+  private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
+
+  private final HttpServer server;
+  private final String url;
+  private final int port;
+  private final Driver.Serialization serialization;
+
+  @Parameters
+  public static List<Object[]> parameters() throws Exception {
+    List<Object[]> params = new ArrayList<>();
+
+    final String[] mainArgs = { FullyRemoteJdbcMetaFactory.class.getName() };
+
+    // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
+
+    final HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
+      @Override public AvaticaJsonHandler createHandler(Service service) {
+        return new AvaticaJsonHandler(service);
+      }
+    });
+    params.add(new Object[] {jsonServer, Driver.Serialization.JSON});
+    ACTIVE_SERVERS.add(jsonServer);
+
+    final HttpServer protobufServer = Main.start(mainArgs, 0, new HandlerFactory() {
+      @Override public AvaticaProtobufHandler createHandler(Service service) {
+        return new AvaticaProtobufHandler(service);
+      }
+    });
+    params.add(new Object[] {protobufServer, Driver.Serialization.PROTOBUF});
+
+    ACTIVE_SERVERS.add(protobufServer);
+
+    return params;
+  }
+
+  public RemoteMetaTest(HttpServer server, Driver.Serialization serialization) {
+    this.server = server;
+    this.port = this.server.getPort();
+    this.serialization = serialization;
+    url = "jdbc:avatica:remote:url=http://localhost:" + port + ";serialization="
+        + serialization.name();
+  }
+
+  @AfterClass public static void afterClass() throws Exception {
+    for (HttpServer server : ACTIVE_SERVERS) {
+      if (server != null) {
+        server.stop();
+      }
+    }
+  }
+
+  private static Meta getMeta(AvaticaConnection conn) throws Exception {
+    Field f = AvaticaConnection.class.getDeclaredField("meta");
+    f.setAccessible(true);
+    return (Meta) f.get(conn);
+  }
+
+  private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
+    final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
+    Method m =
+        AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
+            AvaticaStatement.class, String.class, long.class);
+    m.setAccessible(true);
+    return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
+  }
+
+  private static Connection getConnection(JdbcMeta m, String id) throws Exception {
+    Field f = JdbcMeta.class.getDeclaredField("connectionCache");
+    f.setAccessible(true);
+    //noinspection unchecked
+    Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
+    return connectionCache.getIfPresent(id);
+  }
+
+  @Test public void testRemoteExecuteMaxRowCount() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      final AvaticaStatement statement = conn.createStatement();
+      prepareAndExecuteInternal(conn, statement,
+        "select * from (values ('a', 1), ('b', 2))", 0);
+      ResultSet rs = statement.getResultSet();
+      int count = 0;
+      while (rs.next()) {
+        count++;
+      }
+      assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
+      assertEquals("Check result set meta is still there",
+        rs.getMetaData().getColumnCount(), 2);
+      rs.close();
+      statement.close();
+      conn.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
+   * HTTP error 413 when sending a long string to the Avatica server</a>. */
+  @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      // Before the bug was fixed, a value over 7998 caused an HTTP 413.
+      // 16K bytes, I guess.
+      checkLargeQuery(8);
+      checkLargeQuery(240);
+      checkLargeQuery(8000);
+      checkLargeQuery(240000);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkLargeQuery(int n) throws Exception {
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      final AvaticaStatement statement = conn.createStatement();
+      final String frenchDisko = "It said human existence is pointless\n"
+          + "As acts of rebellious solidarity\n"
+          + "Can bring sense in this world\n"
+          + "La resistance!\n";
+      final String sql = "select '"
+          + longString(frenchDisko, n)
+          + "' as s from (values 'x')";
+      prepareAndExecuteInternal(conn, statement, sql, -1);
+      ResultSet rs = statement.getResultSet();
+      int count = 0;
+      while (rs.next()) {
+        count++;
+      }
+      assertThat(count, is(1));
+      rs.close();
+      statement.close();
+      conn.close();
+    }
+  }
+
+  /** Creates a string of exactly {@code length} characters by concatenating
+   * {@code fragment}. */
+  private static String longString(String fragment, int length) {
+    assert fragment.length() > 0;
+    final StringBuilder buf = new StringBuilder();
+    while (buf.length() < length) {
+      buf.append(fragment);
+    }
+    buf.setLength(length);
+    return buf.toString();
+  }
+
+  @Test public void testRemoteConnectionProperties() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      String id = conn.id;
+      final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
+      assertFalse("remote connection map should start ignorant", m.containsKey(id));
+      // force creating a connection object on the remote side.
+      try (final Statement stmt = conn.createStatement()) {
+        assertTrue("creating a statement starts a local object.", m.containsKey(id));
+        assertTrue(stmt.execute("select count(1) from EMP"));
+      }
+      Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
+      final boolean defaultRO = remoteConn.isReadOnly();
+      final boolean defaultAutoCommit = remoteConn.getAutoCommit();
+      final String defaultCatalog = remoteConn.getCatalog();
+      final String defaultSchema = remoteConn.getSchema();
+      conn.setReadOnly(!defaultRO);
+      assertTrue("local changes dirty local state", m.get(id).isDirty());
+      assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
+      conn.setAutoCommit(!defaultAutoCommit);
+      assertEquals("remote connection has not been touched",
+          defaultAutoCommit, remoteConn.getAutoCommit());
+
+      // further interaction with the connection will force a sync
+      try (final Statement stmt = conn.createStatement()) {
+        assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
+        assertFalse("local values should be clean", m.get(id).isDirty());
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testRemoteStatementInsert() throws Exception {
+    final String t = AvaticaUtils.unique("TEST_TABLE2");
+    AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+    Statement statement = conn.createStatement();
+    final String create =
+        String.format("create table if not exists %s ("
+            + "  id int not null, msg varchar(255) not null)", t);
+    int status = statement.executeUpdate(create);
+    assertEquals(status, 0);
+
+    statement = conn.createStatement();
+    final String update = String.format("insert into %s values ('%d', '%s')",
+        t, RANDOM.nextInt(Integer.MAX_VALUE), UUID.randomUUID());
+    status = statement.executeUpdate(update);
+    assertEquals(status, 1);
+  }
+
+  @Test public void testBigints() throws Exception {
+    final String table = "TESTBIGINTS";
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+        Statement stmt = conn.createStatement()) {
+      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + table));
+      assertFalse(stmt.execute("CREATE TABLE " + table + " (id BIGINT)"));
+      assertFalse(stmt.execute("INSERT INTO " + table + " values(10)"));
+      ResultSet results = conn.getMetaData().getColumns(null, null, table, null);
+      assertTrue(results.next());
+      assertEquals(table, results.getString(3));
+      // ordinal position
+      assertEquals(1L, results.getLong(17));
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testOpenConnectionWithProperties() throws Exception {
+    // This tests that username and password are used for creating a connection on the
+    // server. If this was not the case, it would succeed.
+    try {
+      DriverManager.getConnection(url, "john", "doe");
+      fail("expected exception");
+    } catch (RuntimeException e) {
+      assertEquals("Remote driver error: RuntimeException: "
+          + "java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification"
+          + " - not found: john"
+          + " -> SQLInvalidAuthorizationSpecException: invalid authorization specification - "
+          + "not found: john"
+          + " -> HsqlException: invalid authorization specification - not found: john",
+          e.getMessage());
+    }
+  }
+
+  @Test public void testRemoteConnectionsAreDifferent() throws SQLException {
+    Connection conn1 = DriverManager.getConnection(url);
+    Statement stmt = conn1.createStatement();
+    stmt.execute("DECLARE LOCAL TEMPORARY TABLE"
+        + " buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100))");
+    stmt.execute("insert into buffer(id, textdata) values(1, 'abc')");
+    stmt.executeQuery("select * from buffer");
+
+    // The local temporary table is local to the connection above, and should
+    // not be visible on another connection
+    Connection conn2 = DriverManager.getConnection(url);
+    Statement stmt2 = conn2.createStatement();
+    try {
+      stmt2.executeQuery("select * from buffer");
+      fail("expected exception");
+    } catch (Exception e) {
+      assertEquals("Error -1 (00000) : Error while executing SQL \"select * from buffer\": "
+          + "Remote driver error: RuntimeException: java.sql.SQLSyntaxErrorException: "
+          + "user lacks privilege or object not found: BUFFER -> "
+          + "SQLSyntaxErrorException: user lacks privilege or object not found: BUFFER -> "
+          + "HsqlException: user lacks privilege or object not found: BUFFER",
+          e.getMessage());
+    }
+  }
+
+  @Ignore("[CALCITE-942] AvaticaConnection should fail-fast when closed.")
+  @Test public void testRemoteConnectionClosing() throws Exception {
+    AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+    // Verify connection is usable
+    conn.createStatement();
+    conn.close();
+
+    // After closing the connection, it should not be usable anymore
+    try {
+      conn.createStatement();
+      fail("expected exception");
+    } catch (SQLException e) {
+      assertThat(e.getMessage(),
+          containsString("Connection is closed"));
+    }
+  }
+
+  @Test public void testExceptionPropagation() throws Exception {
+    final String sql = "SELECT * from EMP LIMIT FOOBARBAZ";
+    ConnectionSpec.getDatabaseLock().lock();
+    try (final AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+        final Statement stmt = conn.createStatement()) {
+      try {
+        // invalid SQL
+        stmt.execute(sql);
+        fail("Expected an AvaticaSqlException");
+      } catch (AvaticaSqlException e) {
+        assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, e.getErrorCode());
+        assertEquals(ErrorResponse.UNKNOWN_SQL_STATE, e.getSQLState());
+        assertTrue("Message should contain original SQL, was '" + e.getMessage() + "'",
+            e.getMessage().contains(sql));
+        assertEquals(1, e.getStackTraces().size());
+        final String stacktrace = e.getStackTraces().get(0);
+        final String substring = "unexpected token: FOOBARBAZ";
+        assertTrue("Message should contain '" + substring + "', was '" + e.getMessage() + ",",
+            stacktrace.contains(substring));
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testRemoteColumnsMeta() throws Exception {
+    // Verify all columns are retrieved, thus that frame-based fetching works correctly for columns
+    int rowCount = 0;
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      ResultSet rs = conn.getMetaData().getColumns(null, null, null, null);
+      while (rs.next()) {
+        rowCount++;
+      }
+      rs.close();
+
+      // The implicitly created statement should have been closed
+      assertTrue(rs.getStatement().isClosed());
+    }
+    // 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();
+    }
+  }
+
+  @Test public void testBinaryAndStrings() throws Exception {
+    final String tableName = "testbinaryandstrs";
+    final byte[] data = "asdf".getBytes(StandardCharsets.UTF_8);
+    ConnectionSpec.getDatabaseLock().lock();
+    try (final Connection conn = DriverManager.getConnection(url);
+        final Statement stmt = conn.createStatement()) {
+      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+      assertFalse(stmt.execute("CREATE TABLE " + tableName + "(id int, bin BINARY(4))"));
+      try (final PreparedStatement prepStmt = conn.prepareStatement(
+          "INSERT INTO " + tableName + " values(1, ?)")) {
+        prepStmt.setBytes(1, data);
+        assertFalse(prepStmt.execute());
+      }
+      try (ResultSet results = stmt.executeQuery("SELECT id, bin from " + tableName)) {
+        assertTrue(results.next());
+        assertEquals(1, results.getInt(1));
+        // byte comparison should work
+        assertArrayEquals("Bytes were " + Arrays.toString(results.getBytes(2)),
+            data, results.getBytes(2));
+        // as should string
+        assertEquals(new String(data, StandardCharsets.UTF_8), results.getString(2));
+        assertFalse(results.next());
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testLocalStackTraceHasServerStackTrace() {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      Statement statement = DriverManager.getConnection(url).createStatement();
+      statement.executeQuery("SELECT * FROM BOGUS_TABLE_DEF_DOESNT_EXIST");
+    } catch (SQLException e) {
+      // Verify that we got the expected exception
+      assertThat(e, instanceOf(AvaticaSqlException.class));
+
+      // Attempt to verify that we got a "server-side" class in the stack.
+      assertThat(Throwables.getStackTraceAsString(e),
+          containsString(JdbcMeta.class.getName()));
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testServerAddressInResponse() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      URL url = new URL("http://localhost:" + this.port);
+      AvaticaHttpClient httpClient = new AvaticaHttpClientImpl(url);
+      byte[] request;
+
+      Service.OpenConnectionRequest jsonReq = new Service.OpenConnectionRequest(
+          UUID.randomUUID().toString(), Collections.<String, String>emptyMap());
+      switch (this.serialization) {
+      case JSON:
+        request = JsonService.MAPPER.writeValueAsBytes(jsonReq);
+        break;
+      case PROTOBUF:
+        ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
+        request = pbTranslation.serializeRequest(jsonReq);
+        break;
+      default:
+        throw new IllegalStateException("Should not reach here");
+      }
+
+      byte[] response = httpClient.send(request);
+      Service.OpenConnectionResponse openCnxnResp;
+      switch (this.serialization) {
+      case JSON:
+        openCnxnResp = JsonService.MAPPER.readValue(response,
+            Service.OpenConnectionResponse.class);
+        break;
+      case PROTOBUF:
+        ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
+        Response genericResp = pbTranslation.parseResponse(response);
+        assertTrue("Expected an OpenConnnectionResponse, but got " + genericResp.getClass(),
+            genericResp instanceof Service.OpenConnectionResponse);
+        openCnxnResp = (Service.OpenConnectionResponse) genericResp;
+        break;
+      default:
+        throw new IllegalStateException("Should not reach here");
+      }
+
+      String hostname = InetAddress.getLocalHost().getHostName();
+
+      assertNotNull(openCnxnResp.rpcMetadata);
+      assertEquals(hostname + ":" + this.port, openCnxnResp.rpcMetadata.serverAddress);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testCommitRollback() throws Exception {
+    final String productTable = "commitrollback_products";
+    final String salesTable = "commitrollback_sales";
+    ConnectionSpec.getDatabaseLock().lock();
+    try (final Connection conn = DriverManager.getConnection(url);
+        final Statement stmt = conn.createStatement()) {
+      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + productTable));
+      assertFalse(
+          stmt.execute(
+              String.format("CREATE TABLE %s(id integer, stock integer)", productTable)));
+      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + salesTable));
+      assertFalse(
+          stmt.execute(
+              String.format("CREATE TABLE %s(id integer, units_sold integer)", salesTable)));
+
+      final int productId = 1;
+      // No products and no sales
+      assertFalse(
+          stmt.execute(
+              String.format("INSERT INTO %s VALUES(%d, 0)", productTable, productId)));
+      assertFalse(
+          stmt.execute(
+              String.format("INSERT INTO %s VALUES(%d, 0)", salesTable, productId)));
+
+      conn.setAutoCommit(false);
+      PreparedStatement productStmt = conn.prepareStatement(
+          String.format("UPDATE %s SET stock = stock + ? WHERE id = ?", productTable));
+      PreparedStatement salesStmt = conn.prepareStatement(
+          String.format("UPDATE %s SET units_sold = units_sold + ? WHERE id = ?", salesTable));
+
+      // No stock
+      assertEquals(0, getInventory(conn, productTable, productId));
+
+      // Set a stock of 10 for product 1
+      productStmt.setInt(1, 10);
+      productStmt.setInt(2, productId);
+      productStmt.executeUpdate();
+
+      conn.commit();
+      assertEquals(10, getInventory(conn, productTable, productId));
+
+      // Sold 5 items (5 in stock, 5 sold)
+      productStmt.setInt(1, -5);
+      productStmt.setInt(2, productId);
+      productStmt.executeUpdate();
+      salesStmt.setInt(1, 5);
+      salesStmt.setInt(2, productId);
+      salesStmt.executeUpdate();
+
+      conn.commit();
+      // We will definitely see the updated values
+      assertEquals(5, getInventory(conn, productTable, productId));
+      assertEquals(5, getSales(conn, salesTable, productId));
+
+      // Update some "bad" values
+      productStmt.setInt(1, -10);
+      productStmt.setInt(2, productId);
+      productStmt.executeUpdate();
+      salesStmt.setInt(1, 10);
+      salesStmt.setInt(2, productId);
+      salesStmt.executeUpdate();
+
+      // We just went negative, nonsense. Better rollback.
+      conn.rollback();
+
+      // Should still have 5 and 5
+      assertEquals(5, getInventory(conn, productTable, productId));
+      assertEquals(5, getSales(conn, salesTable, productId));
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private int getInventory(Connection conn, String productTable, int productId) throws Exception {
+    try (Statement stmt = conn.createStatement()) {
+      ResultSet results = stmt.executeQuery(
+          String.format("SELECT stock FROM %s WHERE id = %d", productTable, productId));
+      assertTrue(results.next());
+      return results.getInt(1);
+    }
+  }
+
+  private int getSales(Connection conn, String salesTable, int productId) throws Exception {
+    try (Statement stmt = conn.createStatement()) {
+      ResultSet results = stmt.executeQuery(
+          String.format("SELECT units_sold FROM %s WHERE id = %d", salesTable, productId));
+      assertTrue(results.next());
+      return results.getInt(1);
+    }
+  }
+
+  /** Factory that provides a {@link JdbcMeta}. */
+  public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
+
+    private static JdbcMeta instance = null;
+
+    private static JdbcMeta getInstance() {
+      if (instance == null) {
+        try {
+          instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
+              CONNECTION_SPEC.password);
+        } catch (SQLException e) {
+          throw new RuntimeException(e);
+        }
+      }
+      return instance;
+    }
+
+    @Override public Meta create(List<String> args) {
+      return getInstance();
+    }
+  }
+}
+
+// End RemoteMetaTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
new file mode 100644
index 0000000..3504e02
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.remote.Driver.Serialization;
+import org.apache.calcite.avatica.remote.Service;
+
+import org.eclipse.jetty.server.Handler;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the {@link HandlerFactory} implementation.
+ */
+public class HandlerFactoryTest {
+
+  private HandlerFactory factory;
+  private Service service;
+
+  @Before
+  public void setup() {
+    this.factory = new HandlerFactory();
+    this.service = Mockito.mock(Service.class);
+  }
+
+  @Test
+  public void testJson() {
+    Handler handler = factory.getHandler(service, Serialization.JSON);
+    assertTrue("Expected an implementation of the AvaticaHandler, "
+        + "but got " + handler.getClass(), handler instanceof AvaticaJsonHandler);
+  }
+
+  @Test
+  public void testProtobuf() {
+    Handler handler = factory.getHandler(service, Serialization.PROTOBUF);
+    assertTrue("Expected an implementation of the AvaticaProtobufHandler, "
+        + "but got " + handler.getClass(), handler instanceof AvaticaProtobufHandler);
+  }
+}
+
+// End HandlerFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java b/avatica/server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
new file mode 100644
index 0000000..4a0c26c
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
@@ -0,0 +1,37 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.RemoteDriverTest;
+
+import org.junit.runner.RunWith;
+
+import org.junit.runners.Suite;
+
+/**
+ * Avatica test suite.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    AvaticaUtilsTest.class,
+    ConnectStringParserTest.class,
+    RemoteDriverTest.class
+})
+public class AvaticaSuite {
+}
+
+// End AvaticaSuite.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/resources/log4j.properties b/avatica/server/src/test/resources/log4j.properties
new file mode 100644
index 0000000..834e2db
--- /dev/null
+++ b/avatica/server/src/test/resources/log4j.properties
@@ -0,0 +1,24 @@
+# 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.
+
+# Root logger is configured at INFO and is sent to A1
+log4j.rootLogger=INFO, A1
+
+# A1 goes to the console
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# Set the pattern for each log message
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p - %m%n

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/.gitignore
----------------------------------------------------------------------
diff --git a/avatica/site/.gitignore b/avatica/site/.gitignore
new file mode 100644
index 0000000..09c86a2
--- /dev/null
+++ b/avatica/site/.gitignore
@@ -0,0 +1,2 @@
+.sass-cache
+Gemfile.lock

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/Gemfile
----------------------------------------------------------------------
diff --git a/avatica/site/Gemfile b/avatica/site/Gemfile
new file mode 100644
index 0000000..c13c470
--- /dev/null
+++ b/avatica/site/Gemfile
@@ -0,0 +1,20 @@
+# 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.
+#
+source 'https://rubygems.org'
+gem 'github-pages'
+gem 'rouge'
+gem 'jekyll-oembed', :require => 'jekyll_oembed'
+# End Gemfile

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/README.md
----------------------------------------------------------------------
diff --git a/avatica/site/README.md b/avatica/site/README.md
new file mode 100644
index 0000000..ea3f212
--- /dev/null
+++ b/avatica/site/README.md
@@ -0,0 +1,57 @@
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+# Apache Calcite docs site
+
+This directory contains the code for the Apache Calcite web site,
+[calcite.apache.org](https://calcite.apache.org/).
+
+## Setup
+
+1. `cd site`
+2. `svn co https://svn.apache.org/repos/asf/calcite/site target`
+3. `sudo apt-get install rubygems ruby2.1-dev zlib1g-dev` (linux)
+4. `sudo gem install bundler github-pages jekyll jekyll-oembed`
+5. `bundle install`
+
+## Add javadoc
+
+1. `cd ..`
+2. `mvn -DskipTests site`
+3. `rm -rf site/target/apidocs site/target/testapidocs`
+4. `mv target/site/apidocs target/site/testapidocs site/target`
+
+## Running locally
+
+Before opening a pull request, you can preview your contributions by
+running from within the directory:
+
+1. `bundle exec jekyll serve`
+2. Open [http://localhost:4000](http://localhost:4000)
+
+## Pushing to site
+
+1. `cd site/target`
+2. `svn status`
+3. You'll need to `svn add` any new files
+4. `svn ci`
+
+Within a few minutes, svnpubsub should kick in and you'll be able to
+see the results at
+[calcite.apache.org](https://calcite.apache.org/).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_config.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_config.yml b/avatica/site/_config.yml
new file mode 100644
index 0000000..9b8de85
--- /dev/null
+++ b/avatica/site/_config.yml
@@ -0,0 +1,43 @@
+# 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.
+#
+markdown: kramdown
+permalink: /news/:year/:month/:day/:title/
+excerpt_separator: ""
+
+repository: https://github.com/apache/calcite
+destination: target
+exclude: [README.md,Gemfile*]
+keep_files: [".git", ".svn", "apidocs", "testapidocs"]
+
+collections:
+  docs:
+    output: true
+
+# The URL where the code can be found
+sourceRoot: https://github.com/apache/calcite/blob/master
+
+# The URL where Javadocs are located
+apiRoot: /apidocs
+# apiRoot: http://calcite.apache.org/apidocs
+
+# The URL where Test Javadocs are located
+testApiRoot: /testapidocs
+# testApiRoot: http://calcite.apache.org/testapidocs
+
+# The base path where the website is deployed
+baseurl:
+
+# End _config.yml

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_data/contributors.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_data/contributors.yml b/avatica/site/_data/contributors.yml
new file mode 100644
index 0000000..98f8bf9
--- /dev/null
+++ b/avatica/site/_data/contributors.yml
@@ -0,0 +1,96 @@
+# 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.
+#
+# Database of contributors to Apache Calcite.
+# Pages such as developer.md use this data.
+#
+- name: Alan Gates
+  apacheId: gates
+  githubId: alanfgates
+  org: Hortonworks
+  role: PMC
+- name: Aman Sinha
+  apacheId: amansinha
+  githubId: amansinha100
+  org: MapR
+  role: PMC
+- name: Ashutosh Chauhan
+  apacheId: hashutosh
+  githubId: ashutoshc
+  org: Hortonworks
+  role: PMC
+- name: James R. Taylor
+  apacheId: jamestaylor
+  githubId: JamesRTaylor
+  org: Salesforce
+  role: PMC
+- name: Jacques Nadeau
+  apacheId: jacques
+  githubId: jacques-n
+  org: Dremio
+  role: PMC
+- name: Jesús Camacho Rodríguez
+  apacheId: jcamacho
+  githubId: jcamachor
+  org: Hortonworks
+  role: PMC
+- name: Jinfeng Ni
+  apacheId: jni
+  githubId: jinfengni
+  org: MapR
+  role: PMC
+- name: John Pullokkaran
+  apacheId: jpullokk
+  githubId: jpullokkaran
+  org: Hortonworks
+  role: PMC
+- name: Josh Elser
+  apacheId: elserj
+  githubId: joshelser
+  org: Hortonworks
+  role: PMC
+- name: Julian Hyde
+  apacheId: jhyde
+  githubId: julianhyde
+  org: Hortonworks
+  role: PMC Chair
+  homepage: http://people.apache.org/~jhyde
+- name: Maryann Xue
+  apacheId: maryannxue
+  githubId: maryannxue
+  org: Intel
+  role: Committer
+- name: Nick Dimiduk
+  apacheId: ndimiduk
+  githubId: ndimiduk
+  org: Hortonworks
+  role: PMC
+- name: Steven Noels
+  apacheId: stevenn
+  githubId: stevenn
+  org: NGData
+  role: PMC
+- name: Ted Dunning
+  apacheId: tdunning
+  githubId: tdunning
+  org: MapR
+  role: PMC
+  avatar: https://www.mapr.com/sites/default/files/otherpageimages/ted-circle-80.png
+- name: Vladimir Sitnikov
+  apacheId: vladimirsitnikov
+  githubId: vlsi
+  org: NetCracker
+  role: PMC
+# End contributors.yml

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_data/docs.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_data/docs.yml b/avatica/site/_data/docs.yml
new file mode 100644
index 0000000..a996097
--- /dev/null
+++ b/avatica/site/_data/docs.yml
@@ -0,0 +1,48 @@
+# 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.
+#
+# Data that defines menu structure
+#
+- title: Overview
+  docs:
+  - index
+  - tutorial
+  - algebra
+
+- title: Advanced
+  docs:
+  - adapter
+  - stream
+  - lattice
+
+- title: Avatica
+  docs:
+  - avatica_overview
+  - avatica_roadmap
+  - avatica_json_reference
+  - avatica_protobuf_reference
+
+- title: Reference
+  docs:
+  - reference
+  - model
+  - howto
+
+- title: Meta
+  docs:
+  - history
+  - api
+  - testapi
+# End docs.yml

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/adapter.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/adapter.md b/avatica/site/_docs/adapter.md
new file mode 100644
index 0000000..fa8eb21
--- /dev/null
+++ b/avatica/site/_docs/adapter.md
@@ -0,0 +1,38 @@
+---
+layout: docs
+title: Adapters
+permalink: /docs/adapter.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+* <a href="https://github.com/apache/drill">Apache Drill adapter</a>
+* Cascading adapter (<a href="https://github.com/Cascading/lingual">Lingual</a>)
+* Cassandra adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/cassandra/package-summary.html">calcite-cassandra</a>)
+* CSV adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/csv/package-summary.html">example/csv</a>)
+* JDBC adapter (part of <a href="{{ site.apiRoot }}/org/apache/calcite/adapter/jdbc/package-summary.html">calcite-core</a>)
+* MongoDB adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/mongodb/package-summary.html">calcite-mongodb</a>)
+* Spark adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/spark/package-summary.html">calcite-spark</a>)
+* Splunk adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/splunk/package-summary.html">calcite-splunk</a>)
+* Eclipse Memory Analyzer (MAT) adapter (<a href="https://github.com/vlsi/mat-calcite-plugin">mat-calcite-plugin</a>)
+
+## Drivers
+
+* <a href="{{ site.apiRoot }}/org/apache/calcite/jdbc/package-summary.html">JDBC driver</a>
+

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/algebra.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/algebra.md b/avatica/site/_docs/algebra.md
new file mode 100644
index 0000000..e651dd0
--- /dev/null
+++ b/avatica/site/_docs/algebra.md
@@ -0,0 +1,369 @@
+---
+layout: docs
+title: Algebra
+permalink: /docs/algebra.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Relational algebra is at the heart of Calcite. Every query is
+represented as a tree of relational operators. You can translate from
+SQL to relational algebra, or you can build the tree directly.
+
+Planner rules transform expression trees using mathematical identities
+that preserve semantics. For example, it is valid to push a filter
+into an input of an inner join if the filter does not reference
+columns from the other input.
+
+Calcite optimizes queries by repeatedly applying planner rules to a
+relational expression. A cost model guides the process, and the
+planner engine generates an alternative expression that has the same
+semantics as the original but a lower cost.
+
+The planning process is extensible. You can add your own relational
+operators, planner rules, cost model, and statistics.
+
+## Algebra builder
+
+The simplest way to build a relational expression is to use the algebra builder,
+[RelBuilder]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html).
+Here is an example:
+
+### TableScan
+
+{% highlight java %}
+final FrameworkConfig config;
+final RelBuilder builder = RelBuilder.create(config);
+final RelNode node = builder
+  .scan("EMP")
+  .build();
+System.out.println(RelOptUtil.toString(node));
+{% endhighlight %}
+
+(You can find the full code for this and other examples in
+[RelBuilderExample.java]({{ site.sourceRoot }}/core/src/test/java/org/apache/calcite/examples/RelBuilderExample.java).)
+
+The code prints
+
+{% highlight text %}
+LogicalTableScan(table=[[scott, EMP]])
+{% endhighlight %}
+
+It has created a scan of the `EMP` table; equivalent to the SQL
+
+{% highlight sql %}
+SELECT *
+FROM scott.EMP;
+{% endhighlight %}
+
+### Adding a Project
+
+Now, let's add a Project, the equivalent of
+
+{% highlight sql %}
+SELECT ename, deptno
+FROM scott.EMP;
+{% endhighlight %}
+
+We just add a call to the `project` method before calling
+`build`:
+
+{% highlight java %}
+final RelNode node = builder
+  .scan("EMP")
+  .project(builder.field("DEPTNO"), builder.field("ENAME"))
+  .build();
+System.out.println(RelOptUtil.toString(node));
+{% endhighlight %}
+
+and the output is
+
+{% highlight text %}
+LogicalProject(DEPTNO=[$7], ENAME=[$1])
+  LogicalTableScan(table=[[scott, EMP]])
+{% endhighlight %}
+
+The two calls to `builder.field` create simple expressions
+that return the fields from the input relational expression,
+namely the TableScan created by the `scan` call.
+
+Calcite has converted them to field references by ordinal,
+`$7` and `$1`.
+
+### Adding a Filter and Aggregate
+
+A query with an Aggregate, and a Filter:
+
+{% highlight java %}
+final RelNode node = builder
+  .scan("EMP")
+  .aggregate(builder.groupKey("DEPTNO"),
+      builder.count(false, "C"),
+      builder.sum(false, "S", builder.field("SAL")))
+  .filter(
+      builder.call(SqlStdOperatorTable.GREATER_THAN,
+          builder.field("C"),
+          builder.literal(10)))
+  .build();
+System.out.println(RelOptUtil.toString(node));
+{% endhighlight %}
+
+is equivalent to SQL
+
+{% highlight sql %}
+SELECT deptno, count(*) AS c, sum(sal) AS s
+FROM emp
+GROUP BY deptno
+HAVING count(*) > 10
+{% endhighlight %}
+
+and produces
+
+{% highlight text %}
+LogicalFilter(condition=[>($1, 10)])
+  LogicalAggregate(group=[{7}], C=[COUNT()], S=[SUM($5)])
+    LogicalTableScan(table=[[scott, EMP]])
+{% endhighlight %}
+
+### Push and pop
+
+The builder uses a stack to store the relational expression produced by
+one step and pass it as an input to the next step. This allows the
+methods that produce relational expressions to produce a builder.
+
+Most of the time, the only stack method you will use is `build()`, to get the
+last relational expression, namely the root of the tree.
+
+Sometimes the stack becomes so deeply nested it gets confusing. To keep things
+straight, you can remove expressions from the stack. For example, here we are
+building a bushy join:
+
+{% highlight text %}
+.
+               join
+             /      \
+        join          join
+      /      \      /      \
+CUSTOMERS ORDERS LINE_ITEMS PRODUCTS
+{% endhighlight %}
+
+We build it in three stages. Store the intermediate results in variables
+`left` and `right`, and use `push()` to put them back on the stack when it is
+time to create the final `Join`:
+
+{% highlight java %}
+final RelNode left = builder
+  .scan("CUSTOMERS")
+  .scan("ORDERS")
+  .join(JoinRelType.INNER, "ORDER_ID")
+  .build();
+
+final RelNode right = builder
+  .scan("LINE_ITEMS")
+  .scan("PRODUCTS")
+  .join(JoinRelType.INNER, "PRODUCT_ID")
+  .build();
+
+final RelNode result = builder
+  .push(left)
+  .push(right)
+  .join(JoinRelType.INNER, "ORDER_ID")
+  .build();
+{% endhighlight %}
+
+### Field names and ordinals
+
+You can reference a field by name or ordinal.
+
+Ordinals are zero-based. Each operator guarantees the order in which its output
+fields occur. For example, `Project` returns the fields in the generated by
+each of the scalar expressions.
+
+The field names of an operator are guaranteed to be unique, but sometimes that
+means that the names are not exactly what you expect. For example, when you
+join EMP to DEPT, one of the output fields will be called DEPTNO and another
+will be called something like DEPTNO_1.
+
+Some relational expression methods give you more control over field names:
+
+* `project` lets you wrap expressions using `alias(expr, fieldName)`. It
+  removes the wrapper but keeps the suggested name (as long as it is unique).
+* `values(String[] fieldNames, Object... values)` accepts an array of field
+  names. If any element of the array is null, the builder will generate a unique
+  name.
+
+If an expression projects an input field, or a cast of an input field, it will
+use the name of that input field.
+
+Once the unique field names have been assigned, the names are immutable.
+If you have a particular `RelNode` instance, you can rely on the field names not
+changing. In fact, the whole relational expression is immutable.
+
+But if a relational expression has passed through several rewrite rules (see
+([RelOptRule]({{ site.apiRoot }}/org/apache/calcite/plan/RelOptRule.html)), the field
+names of the resulting expression might not look much like the originals.
+At that point it is better to reference fields by ordinal.
+
+When you are building a relational expression that accepts multiple inputs,
+you need to build field references that take that into account. This occurs
+most often when building join conditions.
+
+Suppose you are building a join on EMP,
+which has 8 fields [EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO]
+and DEPT,
+which has 3 fields [DEPTNO, DNAME, LOC].
+Internally, Calcite represents those fields as offsets into
+a combined input row with 11 fields: the first field of the left input is
+field #0 (0-based, remember), and the first field of the right input is
+field #8.
+
+But through the builder API, you specify which field of which input.
+To reference "SAL", internal field #5,
+write `builder.field(2, 0, "SAL")`
+or `builder.field(2, 0, 5)`.
+This means "the field #5 of input #0 of two inputs".
+(Why does it need to know that there are two inputs? Because they are stored on
+the stack; input #1 is at the top of the stack, and input #0 is below it.
+If we did not tell the builder that were two inputs, it would not know how deep
+to go for input #0.)
+
+Similarly, to reference "DNAME", internal field #9 (8 + 1),
+write `builder.field(2, 1, "DNAME")`
+or `builder.field(2, 1, 1)`.
+
+### API summary
+
+#### Relational operators
+
+The following methods create a relational expression
+([RelNode]({{ site.apiRoot }}/org/apache/calcite/rel/RelNode.html)),
+push it onto the stack, and
+return the `RelBuilder`.
+
+| Method              | Description
+|:------------------- |:-----------
+| `scan(tableName)` | Creates a [TableScan]({{ site.apiRoot }}/org/apache/calcite/rel/core/TableScan.html).
+| `values(fieldNames, value...)`<br/>`values(rowType, tupleList)` | Creates a [Values]({{ site.apiRoot }}/org/apache/calcite/rel/core/Values.html).
+| `filter(expr...)`<br/>`filter(exprList)` | Creates a [Filter]({{ site.apiRoot }}/org/apache/calcite/rel/core/Filter.html) over the AND of the given predicates.
+| `project(expr...)`<br/>`project(exprList [, fieldNames])` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html). To override the default name, wrap expressions using `alias`, or specify the `fieldNames` argument.
+| `permute(mapping)` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html) that permutes the fields using `mapping`.
+| `convert(rowType [, rename])` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html) that converts the fields to the given types, optionally also renaming them.
+| `aggregate(groupKey, aggCall...)`<br/>`aggregate(groupKey, aggCallList)` | Creates an [Aggregate]({{ site.apiRoot }}/org/apache/calcite/rel/core/Aggregate.html).
+| `distinct()` | Creates an [Aggregate]({{ site.apiRoot }}/org/apache/calcite/rel/core/Aggregate.html) that eliminates duplicate records.
+| `sort(fieldOrdinal...)`<br/>`sort(expr...)`<br/>`sort(exprList)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html).<br/><br/>In the first form, field ordinals are 0-based, and a negative ordinal indicates descending; for example, -2 means field 1 descending.<br/><br/>In the other forms, you can wrap expressions in `as`, `nullsFirst` or `nullsLast`.
+| `sortLimit(offset, fetch, expr...)`<br/>`sortLimit(offset, fetch, exprList)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html) with offset and limit.
+| `limit(offset, fetch)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html) that does not sort, only applies with offset and limit.
+| `join(joinType, expr...)`<br/>`join(joinType, exprList)`<br/>`join(joinType, fieldName...)` | Creates a [Join]({{ site.apiRoot }}/org/apache/calcite/rel/core/Join.html) of the two most recent relational expressions.<br/><br/>The first form joins on a boolean expression (multiple conditions are combined using AND).<br/><br/>The last form joins on named fields; each side must have a field of each name.
+| `semiJoin(expr)` | Creates a [SemiJoin]({{ site.apiRoot }}/org/apache/calcite/rel/core/SemiJoin.html) of the two most recent relational expressions.
+| `union(all [, n])` | Creates a [Union]({{ site.apiRoot }}/org/apache/calcite/rel/core/Union.html) of the `n` (default two) most recent relational expressions.
+| `intersect(all [, n])` | Creates an [Intersect]({{ site.apiRoot }}/org/apache/calcite/rel/core/Intersect.html) of the `n` (default two) most recent relational expressions.
+| `minus(all)` | Creates a [Minus]({{ site.apiRoot }}/org/apache/calcite/rel/core/Minus.html) of the two most recent relational expressions.
+
+Argument types:
+
+* `expr`  [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `expr...` Array of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `exprList` Iterable of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `fieldOrdinal` Ordinal of a field within its row (starting from 0)
+* `fieldName` Name of a field, unique within its row
+* `fieldName...` Array of String
+* `fieldNames` Iterable of String
+* `rowType` [RelDataType]({{ site.apiRoot }}/org/apache/calcite/rel/type/RelDataType.html)
+* `groupKey` [RelBuilder.GroupKey]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.GroupKey.html)
+* `aggCall...` Array of [RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html)
+* `aggCallList` Iterable of [RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html)
+* `value...` Array of Object
+* `value` Object
+* `tupleList` Iterable of List of [RexLiteral]({{ site.apiRoot }}/org/apache/calcite/rex/RexLiteral.html)
+* `all` boolean
+* `distinct` boolean
+* `alias` String
+
+The builder methods perform various optimizations, including:
+* `project` returns its input if asked to project all columns in order
+* `filter` flattens the condition (so an `AND` and `OR` may have more than 2 children),
+  simplifies (converting say `x = 1 AND TRUE` to `x = 1`)
+* If you apply `sort` then `limit`, the effect is as if you had called `sortLimit`
+
+### Stack methods
+
+
+| Method              | Description
+|:------------------- |:-----------
+| `build()`           | Pops the most recently created relational expression off the stack
+| `push(rel)`         | Pushes a relational expression onto the stack. Relational methods such as `scan`, above, call this method, but user code generally does not
+| `pushAll(collection)` | Pushes a collection of relational expressions onto the stack
+| `peek()`            | Returns the relational expression most recently put onto the stack, but does not remove it
+
+#### Scalar expression methods
+
+The following methods return a scalar expression
+([RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)).
+
+Many of them use the contents of the stack. For example, `field("DEPTNO")`
+returns a reference to the "DEPTNO" field of the relational expression just
+added to the stack.
+
+| Method              | Description
+|:------------------- |:-----------
+| `literal(value)` | Constant
+| `field(fieldName)` | Reference, by name, to a field of the top-most relational expression
+| `field(fieldOrdinal)` | Reference, by ordinal, to a field of the top-most relational expression
+| `field(inputCount, inputOrdinal, fieldName)` | Reference, by name, to a field of the (`inputCount` - `inputOrdinal`)th relational expression
+| `field(inputCount, inputOrdinal, fieldOrdinal)` | Reference, by ordinal, to a field of the (`inputCount` - `inputOrdinal`)th relational expression
+| `fields(fieldOrdinalList)` | List of expressions referencing input fields by ordinal
+| `fields(mapping)` | List of expressions referencing input fields by a given mapping
+| `fields(collation)` | List of expressions, `exprList`, such that `sort(exprList)` would replicate collation
+| `call(op, expr...)`<br/>`call(op, exprList)` | Call to a function or operator
+| `and(expr...)`<br/>`and(exprList)` | Logical AND. Flattens nested ANDs, and optimizes cases involving TRUE and FALSE.
+| `or(expr...)`<br/>`or(exprList)` | Logical OR. Flattens nested ORs, and optimizes cases involving TRUE and FALSE.
+| `not(expr)` | Logical NOT
+| `equals(expr, expr)` | Equals
+| `isNull(expr)` | Checks whether an expression is null
+| `isNotNull(expr)` | Checks whether an expression is not null
+| `alias(expr, fieldName)` | Renames an expression (only valid as an argument to `project`)
+| `cast(expr, typeName)`<br/>`cast(expr, typeName, precision)`<br/>`cast(expr, typeName, precision, scale)`<br/> | Converts an expression to a given type
+| `desc(expr)` | Changes sort direction to descending (only valid as an argument to `sort` or `sortLimit`)
+| `nullsFirst(expr)` | Changes sort order to nulls first (only valid as an argument to `sort` or `sortLimit`)
+| `nullsLast(expr)` | Changes sort order to nulls last (only valid as an argument to `sort` or `sortLimit`)
+
+### Group key methods
+
+The following methods return a
+[RelBuilder.GroupKey]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.GroupKey.html).
+
+| Method              | Description
+|:------------------- |:-----------
+| `groupKey(fieldName...)`<br/>`groupKey(fieldOrdinal...)`<br/>`groupKey(expr...)`<br/>`groupKey(exprList)` | Creates a group key of the given expressions
+| `groupKey(exprList, exprListList)` | Creates a group key of the given expressions with grouping sets
+| `groupKey(bitSet, bitSets)` | Creates a group key of the given input columns with grouping sets
+
+### Aggregate call methods
+
+The following methods return an
+[RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html).
+
+| Method              | Description
+|:------------------- |:-----------
+| `aggregateCall(op, distinct, filter, alias, expr...)`<br/>`aggregateCall(op, distinct, filter, alias, exprList)` | Creates a call to a given aggregate function, with an optional filter expression
+| `count(distinct, alias, expr...)` | Creates a call to the COUNT aggregate function
+| `countStar(alias)` | Creates a call to the COUNT(*) aggregate function
+| `sum(distinct, alias, expr)` | Creates a call to the SUM aggregate function
+| `min(alias, expr)` | Creates a call to the MIN aggregate function
+| `max(alias, expr)` | Creates a call to the MAX aggregate function

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/api.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/api.md b/avatica/site/_docs/api.md
new file mode 100644
index 0000000..49f456b
--- /dev/null
+++ b/avatica/site/_docs/api.md
@@ -0,0 +1,28 @@
+---
+title: API
+layout: external
+external_url: http://calcite.apache.org/apidocs
+---
+{% comment %}
+Ideally, we want to use {{ site.apiRoot }} instead of hardcoding
+the above external_url value, but I don't believe there's a way to do that
+{% endcomment %}
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->


[44/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
new file mode 100644
index 0000000..478723f
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
@@ -0,0 +1,1046 @@
+/*
+ * 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.remote.TypedValue;
+import org.apache.calcite.avatica.util.ArrayImpl;
+import org.apache.calcite.avatica.util.Cursor;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * Implementation of {@link java.sql.ResultSet}
+ * for the Avatica engine.
+ */
+public class AvaticaResultSet implements ResultSet, ArrayImpl.Factory {
+  protected final AvaticaStatement statement;
+  protected final QueryState state;
+  protected final Meta.Signature signature;
+  protected final Meta.Frame firstFrame;
+  protected final List<ColumnMetaData> columnMetaDataList;
+  protected final ResultSetMetaData resultSetMetaData;
+  protected final Calendar localCalendar;
+
+  protected Cursor cursor;
+  protected List<Cursor.Accessor> accessorList;
+  private int row;
+  private boolean afterLast;
+  private int fetchDirection;
+  private int fetchSize;
+  private int type;
+  private int concurrency;
+  private int holdability;
+  private boolean closed;
+  private long timeoutMillis;
+  private Cursor timeoutCursor;
+
+  public AvaticaResultSet(AvaticaStatement statement,
+      QueryState state,
+      Meta.Signature signature,
+      ResultSetMetaData resultSetMetaData,
+      TimeZone timeZone,
+      Meta.Frame firstFrame) {
+    this.statement = statement;
+    this.state = state;
+    this.signature = signature;
+    this.firstFrame = firstFrame;
+    this.columnMetaDataList = signature.columns;
+    this.type = statement.resultSetType;
+    this.concurrency = statement.resultSetConcurrency;
+    this.holdability = statement.resultSetHoldability;
+    this.fetchSize = statement.getFetchSize();
+    this.fetchDirection = statement.getFetchDirection();
+    this.resultSetMetaData = resultSetMetaData;
+    this.localCalendar = Calendar.getInstance(timeZone);
+  }
+
+  private int findColumn0(String columnLabel) throws SQLException {
+    for (ColumnMetaData columnMetaData : columnMetaDataList) {
+      // Per JDBC 3.0 specification, match is case-insensitive and if there is
+      // more than one column with a particular name, take the first.
+      if (columnMetaData.label.equalsIgnoreCase(columnLabel)) {
+        return columnMetaData.ordinal; // 0-based
+      }
+    }
+    throw new SQLException("column '" + columnLabel + "' not found");
+  }
+
+  /**
+   * Returns the accessor for column with a given index.
+   *
+   * @param columnIndex 1-based column index
+   * @return Accessor
+   * @throws SQLException if index is not valid
+   */
+  private Cursor.Accessor getAccessor(int columnIndex) throws SQLException {
+    try {
+      return accessorList.get(columnIndex - 1);
+    } catch (IndexOutOfBoundsException e) {
+      throw new SQLException("invalid column ordinal: " + columnIndex);
+    }
+  }
+
+  /**
+   * Returns the accessor for column with a given label.
+   *
+   * @param columnLabel Column label
+   * @return Accessor
+   * @throws SQLException if there is no column with that label
+   */
+  private Cursor.Accessor getAccessor(String columnLabel) throws SQLException {
+    return accessorList.get(findColumn0(columnLabel));
+  }
+
+  public void close() {
+    closed = true;
+    final Cursor cursor = this.cursor;
+    if (cursor != null) {
+      this.cursor = null;
+      cursor.close();
+    }
+    statement.onResultSetClose(this);
+    // TODO: for timeout, see IteratorResultSet.close
+/*
+        if (timeoutCursor != null) {
+            final long noTimeout = 0;
+            timeoutCursor.close(noTimeout);
+            timeoutCursor = null;
+        }
+*/
+  }
+
+  /**
+   * Sets the timeout that this result set will wait for a row from the
+   * underlying iterator.
+   *
+   * <p>Not a JDBC method.</p>
+   *
+   * @param timeoutMillis Timeout in milliseconds. Must be greater than zero.
+   */
+  void setTimeout(long timeoutMillis) {
+    assert timeoutMillis > 0;
+    assert this.timeoutMillis == 0;
+    this.timeoutMillis = timeoutMillis;
+    assert timeoutCursor == null;
+    timeoutCursor = cursor;
+
+    // TODO: for timeout, see IteratorResultSet.setTimeout
+/*
+        timeoutCursor = new TimeoutCursor(timeoutMillis);
+        timeoutCursor.start();
+*/
+  }
+
+  // not JDBC
+  protected void cancel() {
+    throw new UnsupportedOperationException(); // TODO:
+  }
+
+  /**
+   * Executes this result set. (Not a JDBC method.)
+   *
+   * <p>Note that execute cannot occur in the constructor, because the
+   * constructor occurs while the statement is locked, to make sure that
+   * execute/cancel don't happen at the same time.</p>
+   *
+   * @see org.apache.calcite.avatica.AvaticaConnection.Trojan#execute(AvaticaResultSet)
+   *
+   * @throws SQLException if execute fails for some reason.
+   */
+  protected AvaticaResultSet execute() throws SQLException {
+    final List<TypedValue> parameterValues = statement.getBoundParameterValues();
+    final Iterable<Object> iterable1 =
+        statement.connection.meta.createIterable(statement.handle, state, signature,
+            parameterValues, firstFrame);
+    this.cursor = MetaImpl.createCursor(signature.cursorFactory, iterable1);
+    this.accessorList =
+        cursor.createAccessors(columnMetaDataList, localCalendar, this);
+    this.row = -1;
+    this.afterLast = false;
+    return this;
+  }
+
+  protected AvaticaResultSet execute2(Cursor cursor,
+      List<ColumnMetaData> columnMetaDataList) {
+    this.cursor = cursor;
+    this.accessorList =
+        cursor.createAccessors(columnMetaDataList, localCalendar, this);
+    this.row = -1;
+    this.afterLast = false;
+    return this;
+  }
+
+  public ResultSet create(ColumnMetaData.AvaticaType elementType,
+      Iterable<Object> iterable) {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean next() throws SQLException {
+    // TODO: for timeout, see IteratorResultSet.next
+    if (isClosed()) {
+      throw new SQLException("next() called on closed cursor");
+    }
+    if (cursor.next()) {
+      ++row;
+      return true;
+    } else {
+      afterLast = true;
+      return false;
+    }
+  }
+
+  public int findColumn(String columnLabel) throws SQLException {
+    return findColumn0(columnLabel) + 1;
+  }
+
+  public boolean wasNull() throws SQLException {
+    return cursor.wasNull();
+  }
+
+  public String getString(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getString();
+  }
+
+  public boolean getBoolean(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getBoolean();
+  }
+
+  public byte getByte(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getByte();
+  }
+
+  public short getShort(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getShort();
+  }
+
+  public int getInt(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getInt();
+  }
+
+  public long getLong(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getLong();
+  }
+
+  public float getFloat(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getFloat();
+  }
+
+  public double getDouble(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getDouble();
+  }
+
+  public BigDecimal getBigDecimal(
+      int columnIndex, int scale) throws SQLException {
+    return getAccessor(columnIndex).getBigDecimal(scale);
+  }
+
+  public byte[] getBytes(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getBytes();
+  }
+
+  public Date getDate(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getDate(localCalendar);
+  }
+
+  public Time getTime(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getTime(localCalendar);
+  }
+
+  public Timestamp getTimestamp(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getTimestamp(localCalendar);
+  }
+
+  public InputStream getAsciiStream(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getAsciiStream();
+  }
+
+  public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getUnicodeStream();
+  }
+
+  public InputStream getBinaryStream(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getBinaryStream();
+  }
+
+  public String getString(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getString();
+  }
+
+  public boolean getBoolean(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getBoolean();
+  }
+
+  public byte getByte(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getByte();
+  }
+
+  public short getShort(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getShort();
+  }
+
+  public int getInt(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getInt();
+  }
+
+  public long getLong(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getLong();
+  }
+
+  public float getFloat(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getFloat();
+  }
+
+  public double getDouble(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getDouble();
+  }
+
+  public BigDecimal getBigDecimal(
+      String columnLabel, int scale) throws SQLException {
+    return getAccessor(columnLabel).getBigDecimal(scale);
+  }
+
+  public byte[] getBytes(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getBytes();
+  }
+
+  public Date getDate(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getDate(localCalendar);
+  }
+
+  public Time getTime(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getTime(localCalendar);
+  }
+
+  public Timestamp getTimestamp(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getTimestamp(localCalendar);
+  }
+
+  public InputStream getAsciiStream(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getAsciiStream();
+  }
+
+  public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getUnicodeStream();
+  }
+
+  public InputStream getBinaryStream(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getBinaryStream();
+  }
+
+  public SQLWarning getWarnings() throws SQLException {
+    return null; // no warnings, since warnings are not supported
+  }
+
+  public void clearWarnings() throws SQLException {
+    // no-op since warnings are not supported
+  }
+
+  public String getCursorName() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public ResultSetMetaData getMetaData() throws SQLException {
+    return resultSetMetaData;
+  }
+
+  public Object getObject(int columnIndex) throws SQLException {
+    final Cursor.Accessor accessor = getAccessor(columnIndex);
+    final ColumnMetaData metaData = columnMetaDataList.get(columnIndex - 1);
+    return AvaticaSite.get(accessor, metaData.type.id, localCalendar);
+  }
+
+  public Object getObject(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getObject();
+  }
+
+  public Reader getCharacterStream(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getCharacterStream();
+  }
+
+  public Reader getCharacterStream(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getCharacterStream();
+  }
+
+  public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getBigDecimal();
+  }
+
+  public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getBigDecimal();
+  }
+
+  public boolean isBeforeFirst() throws SQLException {
+    return row < 0;
+  }
+
+  public boolean isAfterLast() throws SQLException {
+    return afterLast;
+  }
+
+  public boolean isFirst() throws SQLException {
+    return row == 0;
+  }
+
+  public boolean isLast() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void beforeFirst() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void afterLast() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean first() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean last() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public int getRow() throws SQLException {
+    return row;
+  }
+
+  public boolean absolute(int row) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean relative(int rows) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public boolean previous() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void setFetchDirection(int direction) throws SQLException {
+    this.fetchDirection = direction;
+  }
+
+  public int getFetchDirection() throws SQLException {
+    return fetchDirection;
+  }
+
+  public void setFetchSize(int fetchSize) throws SQLException {
+    this.fetchSize = fetchSize;
+  }
+
+  public int getFetchSize() throws SQLException {
+    return fetchSize;
+  }
+
+  public int getType() throws SQLException {
+    return type;
+  }
+
+  public int getConcurrency() throws SQLException {
+    return concurrency;
+  }
+
+  public boolean rowUpdated() throws SQLException {
+    return false;
+  }
+
+  public boolean rowInserted() throws SQLException {
+    return false;
+  }
+
+  public boolean rowDeleted() throws SQLException {
+    return false;
+  }
+
+  public void updateNull(int columnIndex) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateByte(int columnIndex, byte x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateShort(int columnIndex, short x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateInt(int columnIndex, int x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateLong(int columnIndex, long x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateFloat(int columnIndex, float x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateDouble(int columnIndex, double x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBigDecimal(
+      int columnIndex, BigDecimal x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateString(int columnIndex, String x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateDate(int columnIndex, Date x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateTime(int columnIndex, Time x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateTimestamp(
+      int columnIndex, Timestamp x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      int columnIndex, InputStream x, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      int columnIndex, InputStream x, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      int columnIndex, Reader x, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateObject(
+      int columnIndex, Object x, int scaleOrLength) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateObject(int columnIndex, Object x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNull(String columnLabel) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBoolean(
+      String columnLabel, boolean x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateByte(String columnLabel, byte x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateShort(String columnLabel, short x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateInt(String columnLabel, int x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateLong(String columnLabel, long x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateFloat(String columnLabel, float x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateDouble(String columnLabel, double x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBigDecimal(
+      String columnLabel, BigDecimal x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateString(String columnLabel, String x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateDate(String columnLabel, Date x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateTime(String columnLabel, Time x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateTimestamp(
+      String columnLabel, Timestamp x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      String columnLabel, InputStream x, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      String columnLabel, InputStream x, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      String columnLabel, Reader reader, int length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateObject(
+      String columnLabel, Object x, int scaleOrLength) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateObject(String columnLabel, Object x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void insertRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void deleteRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void refreshRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void cancelRowUpdates() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void moveToInsertRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void moveToCurrentRow() throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public AvaticaStatement getStatement() {
+    return statement;
+  }
+
+  public Object getObject(
+      int columnIndex, Map<String, Class<?>> map) throws SQLException {
+    return getAccessor(columnIndex).getObject(map);
+  }
+
+  public Ref getRef(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getRef();
+  }
+
+  public Blob getBlob(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getBlob();
+  }
+
+  public Clob getClob(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getClob();
+  }
+
+  public Array getArray(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getArray();
+  }
+
+  public Object getObject(
+      String columnLabel, Map<String, Class<?>> map) throws SQLException {
+    return getAccessor(columnLabel).getObject(map);
+  }
+
+  public Ref getRef(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getRef();
+  }
+
+  public Blob getBlob(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getBlob();
+  }
+
+  public Clob getClob(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getClob();
+  }
+
+  public Array getArray(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getArray();
+  }
+
+  public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+    return getAccessor(columnIndex).getDate(cal);
+  }
+
+  public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+    return getAccessor(columnLabel).getDate(cal);
+  }
+
+  public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+    return getAccessor(columnIndex).getTime(cal);
+  }
+
+  public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+    return getAccessor(columnLabel).getTime(cal);
+  }
+
+  public Timestamp getTimestamp(
+      int columnIndex, Calendar cal) throws SQLException {
+    return getAccessor(columnIndex).getTimestamp(cal);
+  }
+
+  public Timestamp getTimestamp(
+      String columnLabel, Calendar cal) throws SQLException {
+    return getAccessor(columnLabel).getTimestamp(cal);
+  }
+
+  public URL getURL(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getURL();
+  }
+
+  public URL getURL(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getURL();
+  }
+
+  public void updateRef(int columnIndex, Ref x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateRef(String columnLabel, Ref x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(int columnIndex, Blob x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(String columnLabel, Blob x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(int columnIndex, Clob x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(String columnLabel, Clob x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateArray(int columnIndex, Array x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateArray(String columnLabel, Array x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public RowId getRowId(int columnIndex) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public RowId getRowId(String columnLabel) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateRowId(int columnIndex, RowId x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateRowId(String columnLabel, RowId x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public int getHoldability() throws SQLException {
+    return holdability;
+  }
+
+  public boolean isClosed() throws SQLException {
+    return closed;
+  }
+
+  public void updateNString(
+      int columnIndex, String nString) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNString(
+      String columnLabel, String nString) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(
+      String columnLabel, NClob nClob) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public NClob getNClob(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getNClob();
+  }
+
+  public NClob getNClob(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getNClob();
+  }
+
+  public SQLXML getSQLXML(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getSQLXML();
+  }
+
+  public SQLXML getSQLXML(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getSQLXML();
+  }
+
+  public void updateSQLXML(
+      int columnIndex, SQLXML xmlObject) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateSQLXML(
+      String columnLabel, SQLXML xmlObject) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public String getNString(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getNString();
+  }
+
+  public String getNString(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getNString();
+  }
+
+  public Reader getNCharacterStream(int columnIndex) throws SQLException {
+    return getAccessor(columnIndex).getNCharacterStream();
+  }
+
+  public Reader getNCharacterStream(String columnLabel) throws SQLException {
+    return getAccessor(columnLabel).getNCharacterStream();
+  }
+
+  public void updateNCharacterStream(
+      int columnIndex, Reader x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNCharacterStream(
+      String columnLabel, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      int columnIndex, InputStream x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      int columnIndex, InputStream x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      int columnIndex, Reader x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      String columnLabel, InputStream x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      String columnLabel, InputStream x, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      String columnLabel, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(
+      int columnIndex,
+      InputStream inputStream,
+      long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(
+      String columnLabel,
+      InputStream inputStream,
+      long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(
+      int columnIndex, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(
+      String columnLabel, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(
+      int columnIndex, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(
+      String columnLabel, Reader reader, long length) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNCharacterStream(
+      int columnIndex, Reader x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNCharacterStream(
+      String columnLabel, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      int columnIndex, InputStream x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      int columnIndex, InputStream x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      int columnIndex, Reader x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAsciiStream(
+      String columnLabel, InputStream x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBinaryStream(
+      String columnLabel, InputStream x) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateCharacterStream(
+      String columnLabel, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(
+      int columnIndex, InputStream inputStream) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateBlob(
+      String columnLabel, InputStream inputStream) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(int columnIndex, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateClob(
+      String columnLabel, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(
+      int columnIndex, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateNClob(
+      String columnLabel, Reader reader) throws SQLException {
+    throw new UnsupportedOperationException();
+  }
+
+  public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+    return getAccessor(columnIndex).getObject(type);
+  }
+
+  public <T> T getObject(
+      String columnLabel, Class<T> type) throws SQLException {
+    return getAccessor(columnLabel).getObject(type);
+  }
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (iface.isInstance(this)) {
+      return iface.cast(this);
+    }
+    throw statement.connection.helper.createException(
+        "does not implement '" + iface + "'");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return iface.isInstance(this);
+  }
+}
+
+// End AvaticaResultSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
new file mode 100644
index 0000000..b4e8892
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
@@ -0,0 +1,145 @@
+/*
+ * 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.ResultSetMetaData;
+import java.sql.SQLException;
+
+/**
+ * Implementation of {@link ResultSetMetaData}
+ * for the Avatica framework.
+ */
+public class AvaticaResultSetMetaData implements ResultSetMetaData {
+  final AvaticaStatement statement;
+  final Object query; // reserved for future use
+  final Meta.Signature signature;
+
+  public AvaticaResultSetMetaData(
+      AvaticaStatement statement,
+      Object query,
+      Meta.Signature signature) {
+    this.statement = statement;
+    this.query = query;
+    this.signature = signature;
+  }
+
+  private ColumnMetaData getColumnMetaData(int column) {
+    return signature.columns.get(column - 1);
+  }
+
+  // implement ResultSetMetaData
+
+  public int getColumnCount() throws SQLException {
+    return signature.columns.size();
+  }
+
+  public boolean isAutoIncrement(int column) throws SQLException {
+    return getColumnMetaData(column).autoIncrement;
+  }
+
+  public boolean isCaseSensitive(int column) throws SQLException {
+    return getColumnMetaData(column).caseSensitive;
+  }
+
+  public boolean isSearchable(int column) throws SQLException {
+    return getColumnMetaData(column).searchable;
+  }
+
+  public boolean isCurrency(int column) throws SQLException {
+    return getColumnMetaData(column).currency;
+  }
+
+  public int isNullable(int column) throws SQLException {
+    return getColumnMetaData(column).nullable;
+  }
+
+  public boolean isSigned(int column) throws SQLException {
+    return getColumnMetaData(column).signed;
+  }
+
+  public int getColumnDisplaySize(int column) throws SQLException {
+    return getColumnMetaData(column).displaySize;
+  }
+
+  public String getColumnLabel(int column) throws SQLException {
+    return getColumnMetaData(column).label;
+  }
+
+  public String getColumnName(int column) throws SQLException {
+    return getColumnMetaData(column).columnName;
+  }
+
+  public String getSchemaName(int column) throws SQLException {
+    return getColumnMetaData(column).schemaName;
+  }
+
+  public int getPrecision(int column) throws SQLException {
+    return getColumnMetaData(column).precision;
+  }
+
+  public int getScale(int column) throws SQLException {
+    return getColumnMetaData(column).scale;
+  }
+
+  public String getTableName(int column) throws SQLException {
+    return getColumnMetaData(column).tableName;
+  }
+
+  public String getCatalogName(int column) throws SQLException {
+    return getColumnMetaData(column).catalogName;
+  }
+
+  public int getColumnType(int column) throws SQLException {
+    return getColumnMetaData(column).type.id;
+  }
+
+  public String getColumnTypeName(int column) throws SQLException {
+    return getColumnMetaData(column).type.name;
+  }
+
+  public boolean isReadOnly(int column) throws SQLException {
+    return getColumnMetaData(column).readOnly;
+  }
+
+  public boolean isWritable(int column) throws SQLException {
+    return getColumnMetaData(column).writable;
+  }
+
+  public boolean isDefinitelyWritable(int column) throws SQLException {
+    return getColumnMetaData(column).definitelyWritable;
+  }
+
+  public String getColumnClassName(int column) throws SQLException {
+    return getColumnMetaData(column).columnClassName;
+  }
+
+  // implement Wrapper
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (iface.isInstance(this)) {
+      return iface.cast(this);
+    }
+    throw statement.connection.helper.createException(
+        "does not implement '" + iface + "'");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return iface.isInstance(this);
+  }
+}
+
+// End AvaticaResultSetMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
new file mode 100644
index 0000000..675c8af
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
@@ -0,0 +1,90 @@
+/*
+ * 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 java.util.Objects;
+
+/**
+ * An enumeration that denotes the severity of a given unexpected state.
+ */
+public enum AvaticaSeverity {
+  /**
+   * The severity of the outcome of some unexpected state is unknown.
+   */
+  UNKNOWN(0),
+
+  /**
+   * The system has been left in an unrecoverable state as a result of an operation.
+   */
+  FATAL(1),
+
+  /**
+   * The result of an action resulted in an error which the current operation cannot recover
+   * from. Clients can attempt to execute the operation again.
+   */
+  ERROR(2),
+
+  /**
+   * The operation completed successfully but a message was generated to warn the client about
+   * some unexpected state or action.
+   */
+  WARNING(3);
+
+  private final int value;
+
+  AvaticaSeverity(int value) {
+    this.value = value;
+  }
+
+  public int getValue() {
+    return value;
+  }
+
+  public Common.Severity toProto() {
+    switch (this) {
+    case UNKNOWN:
+      return Common.Severity.UNKNOWN_SEVERITY;
+    case FATAL:
+      return Common.Severity.FATAL_SEVERITY;
+    case ERROR:
+      return Common.Severity.ERROR_SEVERITY;
+    case WARNING:
+      return Common.Severity.WARNING_SEVERITY;
+    default:
+      throw new RuntimeException("Unhandled Severity level: " + this);
+    }
+  }
+
+  public static AvaticaSeverity fromProto(Common.Severity proto) {
+    switch (Objects.requireNonNull(proto)) {
+    case UNKNOWN_SEVERITY:
+      return AvaticaSeverity.UNKNOWN;
+    case FATAL_SEVERITY:
+      return AvaticaSeverity.FATAL;
+    case ERROR_SEVERITY:
+      return AvaticaSeverity.ERROR;
+    case WARNING_SEVERITY:
+      return AvaticaSeverity.WARNING;
+    default:
+      throw new RuntimeException("Unhandled protobuf Severity level: " + proto);
+    }
+  }
+}
+
+// End AvaticaSeverity.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
new file mode 100644
index 0000000..7fd6947
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
@@ -0,0 +1,587 @@
+/*
+ * 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.remote.TypedValue;
+import org.apache.calcite.avatica.util.Cursor;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+
+/**
+ * A location that a value can be written to or read from.
+ */
+public class AvaticaSite {
+  final AvaticaParameter parameter;
+
+  /** Calendar is not thread-safe. But calendar is only used from within one
+   * thread, and we have to trust that clients are not modifying calendars
+   * that they pass to us in a method such as
+   * {@link java.sql.PreparedStatement#setTime(int, Time, Calendar)}, so we do
+   * not need to synchronize access. */
+  final Calendar calendar;
+  private final int index;
+  final TypedValue[] slots;
+
+  /** Value that means the parameter has been set to null.
+   * If value is null, parameter has not been set. */
+  public static final Object DUMMY_VALUE = Dummy.INSTANCE;
+
+  public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,
+      TypedValue[] slots) {
+    assert calendar != null;
+    assert parameter != null;
+    assert slots != null;
+    this.parameter = parameter;
+    this.calendar = calendar;
+    this.index = index;
+    this.slots = slots;
+  }
+
+  private TypedValue wrap(ColumnMetaData.Rep rep, Object o,
+      Calendar calendar) {
+    return TypedValue.ofJdbc(rep, o, calendar);
+  }
+
+  private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {
+    return TypedValue.ofJdbc(rep, o, calendar);
+  }
+
+  public boolean isSet(int index) {
+    return slots[index] != null;
+  }
+
+  public void setByte(byte o) {
+    slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);
+  }
+
+  public void setChar(char o) {
+    slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);
+  }
+
+  public void setShort(short o) {
+    slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);
+  }
+
+  public void setInt(int o) {
+    slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);
+  }
+
+  public void setLong(long o) {
+    slots[index] = wrap(ColumnMetaData.Rep.LONG, o);
+  }
+
+  public void setBoolean(boolean o) {
+    slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);
+  }
+
+  public void setRowId(RowId x) {
+    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);
+  }
+
+  public void setNString(String o) {
+    slots[index] = wrap(ColumnMetaData.Rep.STRING, o);
+  }
+
+  public void setNCharacterStream(Reader value, long length) {
+  }
+
+  public void setNClob(NClob value) {
+    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);
+  }
+
+  public void setClob(Reader reader, long length) {
+  }
+
+  public void setBlob(InputStream inputStream, long length) {
+  }
+
+  public void setNClob(Reader reader, long length) {
+  }
+
+  public void setSQLXML(SQLXML xmlObject) {
+    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);
+  }
+
+  public void setAsciiStream(InputStream x, long length) {
+  }
+
+  public void setBinaryStream(InputStream x, long length) {
+  }
+
+  public void setCharacterStream(Reader reader, long length) {
+  }
+
+  public void setAsciiStream(InputStream x) {
+  }
+
+  public void setBinaryStream(InputStream x) {
+  }
+
+  public void setCharacterStream(Reader reader) {
+  }
+
+  public void setNCharacterStream(Reader value) {
+  }
+
+  public void setClob(Reader reader) {
+  }
+
+  public void setBlob(InputStream inputStream) {
+  }
+
+  public void setNClob(Reader reader) {
+  }
+
+  public void setUnicodeStream(InputStream x, int length) {
+  }
+
+  public void setFloat(float x) {
+    slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);
+  }
+
+  public void setDouble(double x) {
+    slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);
+  }
+
+  public void setBigDecimal(BigDecimal x) {
+    slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);
+  }
+
+  public void setString(String x) {
+    slots[index] = wrap(ColumnMetaData.Rep.STRING, x);
+  }
+
+  public void setBytes(byte[] x) {
+    slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);
+  }
+
+  public void setTimestamp(Timestamp x, Calendar calendar) {
+    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);
+  }
+
+  public void setTime(Time x, Calendar calendar) {
+    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);
+  }
+
+  public void setDate(Date x, Calendar cal) {
+    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);
+  }
+
+  public void setObject(Object x, int targetSqlType) {
+    if (x == null || Types.NULL == targetSqlType) {
+      setNull(targetSqlType);
+      return;
+    }
+    switch (targetSqlType) {
+    case Types.CLOB:
+    case Types.DATALINK:
+    case Types.NCLOB:
+    case Types.OTHER:
+    case Types.REF:
+    case Types.SQLXML:
+    case Types.STRUCT:
+      throw notImplemented();
+    case Types.ARRAY:
+      setArray(toArray(x));
+      break;
+    case Types.BIGINT:
+      setLong(toLong(x));
+      break;
+    case Types.BINARY:
+    case Types.LONGVARBINARY:
+    case Types.VARBINARY:
+      setBytes(toBytes(x));
+      break;
+    case Types.BIT:
+    case Types.BOOLEAN:
+      setBoolean(toBoolean(x));
+      break;
+    case Types.BLOB:
+      if (x instanceof Blob) {
+        setBlob((Blob) x);
+        break;
+      } else if (x instanceof InputStream) {
+        setBlob((InputStream) x);
+      }
+      throw unsupportedCast(x.getClass(), Blob.class);
+    case Types.DATE:
+      setDate(toDate(x), calendar);
+      break;
+    case Types.DECIMAL:
+    case Types.NUMERIC:
+      setBigDecimal(toBigDecimal(x));
+      break;
+    case Types.DISTINCT:
+      throw notImplemented();
+    case Types.DOUBLE:
+    case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+      setDouble(toDouble(x));
+      break;
+    case Types.INTEGER:
+      setInt(toInt(x));
+      break;
+    case Types.JAVA_OBJECT:
+      setObject(x);
+      break;
+    case Types.LONGNVARCHAR:
+    case Types.LONGVARCHAR:
+    case Types.NVARCHAR:
+    case Types.VARCHAR:
+    case Types.CHAR:
+    case Types.NCHAR:
+      setString(toString(x));
+      break;
+    case Types.REAL:
+      setFloat(toFloat(x));
+      break;
+    case Types.ROWID:
+      if (x instanceof RowId) {
+        setRowId((RowId) x);
+        break;
+      }
+      throw unsupportedCast(x.getClass(), RowId.class);
+    case Types.SMALLINT:
+      setShort(toShort(x));
+      break;
+    case Types.TIME:
+      setTime(toTime(x), calendar);
+      break;
+    case Types.TIMESTAMP:
+      setTimestamp(toTimestamp(x), calendar);
+      break;
+    case Types.TINYINT:
+      setByte(toByte(x));
+      break;
+    default:
+      throw notImplemented();
+    }
+  }
+
+  /** Similar logic to {@link #setObject}. */
+  public static Object get(Cursor.Accessor accessor, int targetSqlType,
+      Calendar localCalendar) throws SQLException {
+    switch (targetSqlType) {
+    case Types.CLOB:
+    case Types.DATALINK:
+    case Types.NCLOB:
+    case Types.REF:
+    case Types.SQLXML:
+    case Types.STRUCT:
+      throw notImplemented();
+    case Types.ARRAY:
+      return accessor.getArray();
+    case Types.BIGINT:
+      final long aLong = accessor.getLong();
+      if (aLong == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return aLong;
+    case Types.BINARY:
+    case Types.LONGVARBINARY:
+    case Types.VARBINARY:
+      return accessor.getBytes();
+    case Types.BIT:
+    case Types.BOOLEAN:
+      final boolean aBoolean = accessor.getBoolean();
+      if (!aBoolean && accessor.wasNull()) {
+        return null;
+      }
+      return aBoolean;
+    case Types.BLOB:
+      return accessor.getBlob();
+    case Types.DATE:
+      return accessor.getDate(localCalendar);
+    case Types.DECIMAL:
+    case Types.NUMERIC:
+      return accessor.getBigDecimal();
+    case Types.DISTINCT:
+      throw notImplemented();
+    case Types.DOUBLE:
+    case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+      final double aDouble = accessor.getDouble();
+      if (aDouble == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return aDouble;
+    case Types.INTEGER:
+      final int anInt = accessor.getInt();
+      if (anInt == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return anInt;
+    case Types.JAVA_OBJECT:
+    case Types.OTHER:
+      return accessor.getObject();
+    case Types.LONGNVARCHAR:
+    case Types.LONGVARCHAR:
+    case Types.NVARCHAR:
+    case Types.VARCHAR:
+    case Types.CHAR:
+    case Types.NCHAR:
+      return accessor.getString();
+    case Types.REAL:
+      final float aFloat = accessor.getFloat();
+      if (aFloat == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return aFloat;
+    case Types.ROWID:
+      throw notImplemented();
+    case Types.SMALLINT:
+      final short aShort = accessor.getShort();
+      if (aShort == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return aShort;
+    case Types.TIME:
+      return accessor.getTime(localCalendar);
+    case Types.TIMESTAMP:
+      return accessor.getTimestamp(localCalendar);
+    case Types.TINYINT:
+      final byte aByte = accessor.getByte();
+      if (aByte == 0 && accessor.wasNull()) {
+        return null;
+      }
+      return aByte;
+    default:
+      throw notImplemented();
+    }
+  }
+
+  public void setObject(Object x) {
+    slots[index] = TypedValue.ofJdbc(x, calendar);
+  }
+
+  public void setNull(int sqlType) {
+    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);
+  }
+
+  public void setRef(Ref x) {
+  }
+
+  public void setBlob(Blob x) {
+  }
+
+  public void setClob(Clob x) {
+  }
+
+  public void setArray(Array x) {
+  }
+
+  public void setNull(int sqlType, String typeName) {
+  }
+
+  public void setURL(URL x) {
+  }
+
+  public void setObject(Object x, int targetSqlType,
+      int scaleOrLength) {
+  }
+
+  private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
+    return new UnsupportedOperationException("Cannot convert from "
+        + from.getCanonicalName() + " to " + to.getCanonicalName());
+  }
+
+  private static RuntimeException notImplemented() {
+    return new RuntimeException("not implemented");
+  }
+
+  private static Array toArray(Object x) {
+    if (x instanceof Array) {
+      return (Array) x;
+    }
+    throw unsupportedCast(x.getClass(), Array.class);
+  }
+
+  public static BigDecimal toBigDecimal(Object x) {
+    if (x instanceof BigDecimal) {
+      return (BigDecimal) x;
+    } else if (x instanceof BigInteger) {
+      return new BigDecimal((BigInteger) x);
+    } else if (x instanceof Number) {
+      if (x instanceof Double || x instanceof Float) {
+        return new BigDecimal(((Number) x).doubleValue());
+      } else {
+        return new BigDecimal(((Number) x).longValue());
+      }
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
+    } else if (x instanceof String) {
+      return new BigDecimal((String) x);
+    }
+    throw unsupportedCast(x.getClass(), BigDecimal.class);
+  }
+
+  private static boolean toBoolean(Object x) {
+    if (x instanceof Boolean) {
+      return (Boolean) x;
+    } else if (x instanceof Number) {
+      return ((Number) x).intValue() != 0;
+    } else if (x instanceof String) {
+      String s = (String) x;
+      if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
+        return true;
+      } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
+        return false;
+      }
+    }
+    throw unsupportedCast(x.getClass(), Boolean.TYPE);
+  }
+
+  private static byte toByte(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).byteValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? (byte) 1 : (byte) 0;
+    } else if (x instanceof String) {
+      return Byte.parseByte((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Byte.TYPE);
+    }
+  }
+
+  private static byte[] toBytes(Object x) {
+    if (x instanceof byte[]) {
+      return (byte[]) x;
+    }
+    if (x instanceof String) {
+      return ((String) x).getBytes();
+    }
+    throw unsupportedCast(x.getClass(), byte[].class);
+  }
+
+  private static Date toDate(Object x) {
+    if (x instanceof String) {
+      return Date.valueOf((String) x);
+    }
+    return new Date(toLong(x));
+  }
+
+  private static Time toTime(Object x) {
+    if (x instanceof String) {
+      return Time.valueOf((String) x);
+    }
+    return new Time(toLong(x));
+  }
+
+  private static Timestamp toTimestamp(Object x) {
+    if (x instanceof String) {
+      return Timestamp.valueOf((String) x);
+    }
+    return new Timestamp(toLong(x));
+  }
+
+  private static double toDouble(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).doubleValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? 1D : 0D;
+    } else if (x instanceof String) {
+      return Double.parseDouble((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Double.TYPE);
+    }
+  }
+
+  private static float toFloat(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).floatValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? 1F : 0F;
+    } else if (x instanceof String) {
+      return Float.parseFloat((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Float.TYPE);
+    }
+  }
+
+  private static int toInt(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).intValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? 1 : 0;
+    } else if (x instanceof String) {
+      return Integer.parseInt((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Integer.TYPE);
+    }
+  }
+
+  private static long toLong(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).longValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? 1L : 0L;
+    } else if (x instanceof String) {
+      return Long.parseLong((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Long.TYPE);
+    }
+  }
+
+  private static short toShort(Object x) {
+    if (x instanceof Number) {
+      return ((Number) x).shortValue();
+    } else if (x instanceof Boolean) {
+      return (Boolean) x ? (short) 1 : (short) 0;
+    } else if (x instanceof String) {
+      return Short.parseShort((String) x);
+    } else {
+      throw unsupportedCast(x.getClass(), Short.TYPE);
+    }
+  }
+
+  private static String toString(Object x) {
+    if (x instanceof String) {
+      return (String) x;
+    } else if (x instanceof Character
+        || x instanceof Boolean) {
+      return x.toString();
+    }
+    throw unsupportedCast(x.getClass(), String.class);
+  }
+
+  /** Singleton value to denote parameters that have been set to null (as
+   * opposed to not set).
+   *
+   * <p>Not a valid value for a parameter.
+   *
+   * <p>As an enum, it is serializable by Jackson. */
+  private enum Dummy {
+    INSTANCE
+  }
+}
+
+// End AvaticaSite.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
new file mode 100644
index 0000000..9408a7b
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
@@ -0,0 +1,138 @@
+/*
+ * 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.PrintStream;
+import java.io.PrintWriter;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A client-facing {@link SQLException} which encapsulates errors from the remote Avatica server.
+ */
+public class AvaticaSqlException extends SQLException {
+
+  private static final long serialVersionUID = 1L;
+
+  private final String errorMessage;
+  private final List<String> stackTraces;
+  private final String remoteServer;
+
+  /**
+   * Construct the Exception with information from the server.
+   *
+   * @param errorMessage A human-readable error message.
+   * @param errorCode An integer corresponding to a known error.
+   * @param stackTraces Server-side stacktrace.
+   * @param remoteServer The host:port where the Avatica server is located
+   */
+  public AvaticaSqlException(String errorMessage, String sqlState, int errorCode,
+      List<String> stackTraces, String remoteServer) {
+    super("Error " + errorCode + " (" + sqlState + ") : " + errorMessage, sqlState, errorCode);
+    this.errorMessage = errorMessage;
+    this.stackTraces = Objects.requireNonNull(stackTraces);
+    this.remoteServer = remoteServer;
+  }
+
+  public String getErrorMessage() {
+    return errorMessage;
+  }
+
+  /**
+   * @return The stacktraces for exceptions thrown on the Avatica server.
+   */
+  public List<String> getStackTraces() {
+    return stackTraces;
+  }
+
+  /**
+   * @return The host:port for the remote Avatica server. May be null.
+   */
+  public String getRemoteServer() {
+    return remoteServer;
+  }
+
+  // printStackTrace() will get redirected to printStackTrace(PrintStream), don't need to override.
+
+  @Override public void printStackTrace(PrintStream stream) {
+    super.printStackTrace(stream);
+    stream.flush();
+    printServerStackTrace(new PrintStreamOrWriter(stream));
+  }
+
+  @Override public void printStackTrace(PrintWriter writer) {
+    super.printStackTrace(writer);
+    writer.flush();
+    printServerStackTrace(new PrintStreamOrWriter(writer));
+  }
+
+  void printServerStackTrace(PrintStreamOrWriter streamOrWriter) {
+    for (String serverStackTrace : this.stackTraces) {
+      streamOrWriter.println(serverStackTrace);
+    }
+  }
+
+  /**
+   * A class that encapsulates either a PrintStream or a PrintWriter.
+   */
+  private static class PrintStreamOrWriter {
+    /**
+     * Enumeration to differentiate between a PrintStream and a PrintWriter.
+     */
+    private enum Type {
+      STREAM,
+      WRITER
+    }
+
+    private PrintStream stream;
+    private PrintWriter writer;
+    private final Type type;
+
+    public PrintStreamOrWriter(PrintStream stream) {
+      this.stream = stream;
+      type = Type.STREAM;
+    }
+
+    public PrintStreamOrWriter(PrintWriter writer) {
+      this.writer = writer;
+      type = Type.WRITER;
+    }
+
+    /**
+     * Prints the given string to the the provided stream or writer.
+     *
+     * @param string The string to print
+     */
+    public void println(String string) {
+      switch (type) {
+      case STREAM:
+        stream.println(string);
+        stream.flush();
+        return;
+      case WRITER:
+        writer.println(string);
+        writer.flush();
+        return;
+      default:
+        throw new IllegalStateException();
+      }
+    }
+  }
+}
+
+// End AvaticaSqlException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
new file mode 100644
index 0000000..cfd1d45
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
@@ -0,0 +1,527 @@
+/*
+ * 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.remote.TypedValue;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Implementation of {@link java.sql.Statement}
+ * for the Avatica engine.
+ */
+public abstract class AvaticaStatement
+    implements Statement {
+  /** The default value for {@link Statement#getFetchSize()}. */
+  public static final int DEFAULT_FETCH_SIZE = 100;
+
+  public final AvaticaConnection connection;
+  /** Statement id; unique within connection. */
+  public Meta.StatementHandle handle;
+  protected boolean closed;
+
+  /**
+   * Support for {@link #closeOnCompletion()} method.
+   */
+  protected boolean closeOnCompletion;
+
+  /**
+   * Current result set, or null if the statement is not executing anything.
+   * Any method which modifies this member must synchronize
+   * on the AvaticaStatement.
+   */
+  protected AvaticaResultSet openResultSet;
+
+  /** Current update count. Same lifecycle as {@link #openResultSet}. */
+  protected long updateCount;
+
+  private int queryTimeoutMillis;
+  final int resultSetType;
+  final int resultSetConcurrency;
+  final int resultSetHoldability;
+  private int fetchSize = DEFAULT_FETCH_SIZE;
+  private int fetchDirection;
+  protected long maxRowCount = 0;
+
+  private Meta.Signature signature;
+
+  protected void setSignature(Meta.Signature signature) {
+    this.signature = signature;
+  }
+
+  protected Meta.Signature getSignature() {
+    return signature;
+  }
+
+  public Meta.StatementType getStatementType() {
+    return signature.statementType;
+  }
+
+  /**
+   * Creates an AvaticaStatement.
+   *
+   * @param connection Connection
+   * @param h Statement handle
+   * @param resultSetType Result set type
+   * @param resultSetConcurrency Result set concurrency
+   * @param resultSetHoldability Result set holdability
+   */
+  protected AvaticaStatement(AvaticaConnection connection,
+      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
+      int resultSetHoldability) {
+    this(connection, h, resultSetType, resultSetConcurrency, resultSetHoldability, null);
+  }
+
+  protected AvaticaStatement(AvaticaConnection connection,
+      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
+      int resultSetHoldability, Meta.Signature signature) {
+    this.connection = Objects.requireNonNull(connection);
+    this.resultSetType = resultSetType;
+    this.resultSetConcurrency = resultSetConcurrency;
+    this.resultSetHoldability = resultSetHoldability;
+    this.signature = signature;
+    this.closed = false;
+    if (h == null) {
+      final Meta.ConnectionHandle ch = connection.handle;
+      h = connection.meta.createStatement(ch);
+    }
+    connection.statementMap.put(h.id, this);
+    this.handle = h;
+  }
+
+  /** Returns the identifier of the statement, unique within its connection. */
+  public int getId() {
+    return handle.id;
+  }
+
+  private void checkNotPreparedOrCallable(String s) throws SQLException {
+    if (this instanceof PreparedStatement
+        || this instanceof CallableStatement) {
+      throw connection.helper.createException("Cannot call " + s
+          + " on prepared or callable statement");
+    }
+  }
+
+  protected void executeInternal(String sql) throws SQLException {
+    // reset previous state before moving forward.
+    this.updateCount = -1;
+    try {
+      // In JDBC, maxRowCount = 0 means no limit; in prepare it means LIMIT 0
+      final long maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
+      for (int i = 0; i < connection.maxRetriesPerExecute; i++) {
+        try {
+          Meta.ExecuteResult x =
+              connection.prepareAndExecuteInternal(this, sql, maxRowCount1);
+          return;
+        } catch (NoSuchStatementException e) {
+          resetStatement();
+        }
+      }
+    } catch (RuntimeException e) {
+      throw connection.helper.createException("Error while executing SQL \"" + sql + "\": "
+          + e.getMessage(), e);
+    }
+
+    throw new RuntimeException("Failed to successfully execute query after "
+        + connection.maxRetriesPerExecute + " attempts.");
+  }
+
+  protected void resetStatement() {
+    // Invalidate the old statement
+    connection.statementMap.remove(handle.id);
+    // Get a new one
+    final Meta.ConnectionHandle ch = new Meta.ConnectionHandle(connection.id);
+    Meta.StatementHandle h = connection.meta.createStatement(ch);
+    // Cache it in the connection
+    connection.statementMap.put(h.id, this);
+    // Update the local state and try again
+    this.handle = h;
+  }
+
+  /**
+   * Re-initialize the ResultSet on the server with the given state.
+   * @param state The ResultSet's state.
+   * @param offset Offset into the desired ResultSet
+   * @return True if the ResultSet has more results, false if there are no more results.
+   */
+  protected boolean syncResults(QueryState state, long offset) throws NoSuchStatementException {
+    return connection.meta.syncResults(handle, state, offset);
+  }
+
+  // implement Statement
+
+  public boolean execute(String sql) throws SQLException {
+    checkNotPreparedOrCallable("execute(String)");
+    executeInternal(sql);
+    // Result set is null for DML or DDL.
+    // Result set is closed if user cancelled the query.
+    return openResultSet != null && !openResultSet.isClosed();
+  }
+
+  public ResultSet executeQuery(String sql) throws SQLException {
+    checkNotPreparedOrCallable("executeQuery(String)");
+    try {
+      executeInternal(sql);
+      if (openResultSet == null) {
+        throw connection.helper.createException(
+            "Statement did not return a result set");
+      }
+      return openResultSet;
+    } catch (RuntimeException e) {
+      throw connection.helper.createException("Error while executing SQL \"" + sql + "\": "
+          + e.getMessage(), e);
+    }
+  }
+
+  public final int executeUpdate(String sql) throws SQLException {
+    return (int) executeLargeUpdate(sql);
+  }
+
+  public long executeLargeUpdate(String sql) throws SQLException {
+    checkNotPreparedOrCallable("executeUpdate(String)");
+    executeInternal(sql);
+    return updateCount;
+  }
+
+  public synchronized void close() throws SQLException {
+    try {
+      close_();
+    } catch (RuntimeException e) {
+      throw connection.helper.createException("While closing statement", e);
+    }
+  }
+
+  protected void close_() {
+    if (!closed) {
+      closed = true;
+      if (openResultSet != null) {
+        AvaticaResultSet c = openResultSet;
+        openResultSet = null;
+        c.close();
+      }
+      try {
+        // inform the server to close the resource
+        connection.meta.closeStatement(handle);
+      } finally {
+        // make sure we don't leak on our side
+        connection.statementMap.remove(handle.id);
+      }
+      // If onStatementClose throws, this method will throw an exception (later
+      // converted to SQLException), but this statement still gets closed.
+      connection.driver.handler.onStatementClose(this);
+    }
+  }
+
+  public int getMaxFieldSize() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public void setMaxFieldSize(int max) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public final int getMaxRows() {
+    return (int) getLargeMaxRows();
+  }
+
+  public long getLargeMaxRows() {
+    return maxRowCount;
+  }
+
+  public final void setMaxRows(int maxRowCount) throws SQLException {
+    setLargeMaxRows(maxRowCount);
+  }
+
+  public void setLargeMaxRows(long maxRowCount) throws SQLException {
+    if (maxRowCount < 0) {
+      throw connection.helper.createException(
+          "illegal maxRows value: " + maxRowCount);
+    }
+    this.maxRowCount = maxRowCount;
+  }
+
+  public void setEscapeProcessing(boolean enable) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int getQueryTimeout() throws SQLException {
+    long timeoutSeconds = getQueryTimeoutMillis() / 1000;
+    if (timeoutSeconds > Integer.MAX_VALUE) {
+      return Integer.MAX_VALUE;
+    }
+    if (timeoutSeconds == 0 && getQueryTimeoutMillis() > 0) {
+      // Don't return timeout=0 if e.g. timeoutMillis=500. 0 is special.
+      return 1;
+    }
+    return (int) timeoutSeconds;
+  }
+
+  int getQueryTimeoutMillis() {
+    return queryTimeoutMillis;
+  }
+
+  public void setQueryTimeout(int seconds) throws SQLException {
+    if (seconds < 0) {
+      throw connection.helper.createException(
+          "illegal timeout value " + seconds);
+    }
+    setQueryTimeoutMillis(seconds * 1000);
+  }
+
+  void setQueryTimeoutMillis(int millis) {
+    this.queryTimeoutMillis = millis;
+  }
+
+  public synchronized void cancel() throws SQLException {
+    if (openResultSet != null) {
+      openResultSet.cancel();
+    }
+  }
+
+  public SQLWarning getWarnings() throws SQLException {
+    return null; // no warnings, since warnings are not supported
+  }
+
+  public void clearWarnings() throws SQLException {
+    // no-op since warnings are not supported
+  }
+
+  public void setCursorName(String name) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public ResultSet getResultSet() throws SQLException {
+    // NOTE: result set becomes visible in this member while
+    // executeQueryInternal is still in progress, and before it has
+    // finished executing. Its internal state may not be ready for API
+    // calls. JDBC never claims to be thread-safe! (Except for calls to the
+    // cancel method.) It is not possible to synchronize, because it would
+    // block 'cancel'.
+    return openResultSet;
+  }
+
+  public int getUpdateCount() throws SQLException {
+    return (int) updateCount;
+  }
+
+  public long getLargeUpdateCount() throws SQLException {
+    return updateCount;
+  }
+
+  public boolean getMoreResults() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public void setFetchDirection(int direction) throws SQLException {
+    this.fetchDirection = direction;
+  }
+
+  public int getFetchDirection() {
+    return fetchDirection;
+  }
+
+  public void setFetchSize(int rows) throws SQLException {
+    this.fetchSize = rows;
+  }
+
+  public int getFetchSize() {
+    return fetchSize;
+  }
+
+  public int getResultSetConcurrency() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int getResultSetType() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public void addBatch(String sql) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public void clearBatch() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int[] executeBatch() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public AvaticaConnection getConnection() {
+    return connection;
+  }
+
+  public boolean getMoreResults(int current) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public ResultSet getGeneratedKeys() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int executeUpdate(
+      String sql, int autoGeneratedKeys) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int executeUpdate(
+      String sql, int[] columnIndexes) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int executeUpdate(
+      String sql, String[] columnNames) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public boolean execute(
+      String sql, int autoGeneratedKeys) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public boolean execute(
+      String sql, int[] columnIndexes) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public boolean execute(
+      String sql, String[] columnNames) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public int getResultSetHoldability() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public boolean isClosed() throws SQLException {
+    return closed;
+  }
+
+  public void setPoolable(boolean poolable) throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public boolean isPoolable() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  // implements java.sql.Statement.closeOnCompletion (added in JDK 1.7)
+  public void closeOnCompletion() throws SQLException {
+    closeOnCompletion = true;
+  }
+
+  // implements java.sql.Statement.isCloseOnCompletion (added in JDK 1.7)
+  public boolean isCloseOnCompletion() throws SQLException {
+    return closeOnCompletion;
+  }
+
+  // implement Wrapper
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (iface.isInstance(this)) {
+      return iface.cast(this);
+    }
+    throw connection.helper.createException(
+        "does not implement '" + iface + "'");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return iface.isInstance(this);
+  }
+
+  /**
+   * Executes a prepared statement.
+   *
+   * @param signature Parsed statement
+   * @param isUpdate if the execute is for an update
+   *
+   * @return as specified by {@link java.sql.Statement#execute(String)}
+   * @throws java.sql.SQLException if a database error occurs
+   */
+  protected boolean executeInternal(Meta.Signature signature, boolean isUpdate)
+      throws SQLException {
+    ResultSet resultSet = executeQueryInternal(signature, isUpdate);
+    // user may have cancelled the query
+    if (resultSet.isClosed()) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Executes a prepared query, closing any previously open result set.
+   *
+   * @param signature Parsed query
+   * @param isUpdate If the execute is for an update
+   * @return Result set
+   * @throws java.sql.SQLException if a database error occurs
+   */
+  protected ResultSet executeQueryInternal(Meta.Signature signature, boolean isUpdate)
+      throws SQLException {
+    return connection.executeQueryInternal(this, signature, null, null, isUpdate);
+  }
+
+  /**
+   * Called by each child result set when it is closed.
+   *
+   * @param resultSet Result set or cell set
+   */
+  void onResultSetClose(ResultSet resultSet) {
+    if (closeOnCompletion) {
+      close_();
+    }
+  }
+
+  /** Returns the list of values of this statement's parameters.
+   *
+   * <p>Called at execute time. Not a public API.</p>
+   *
+   * <p>The default implementation returns the empty list, because non-prepared
+   * statements have no parameters.</p>
+   *
+   * @see org.apache.calcite.avatica.AvaticaConnection.Trojan#getParameterValues(AvaticaStatement)
+   */
+  protected List<TypedValue> getParameterValues() {
+    return Collections.emptyList();
+  }
+
+  /** Returns a list of bound parameter values.
+   *
+   * <p>If any of the parameters have not been bound, throws.
+   * If parameters have been bound to null, the value in the list is null.
+   */
+  protected List<TypedValue> getBoundParameterValues() throws SQLException {
+    final List<TypedValue> parameterValues = getParameterValues();
+    for (Object parameterValue : parameterValues) {
+      if (parameterValue == null) {
+        throw new SQLException("unbound parameter");
+      }
+    }
+    return parameterValues;
+  }
+}
+
+// End AvaticaStatement.java


[03/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Base64.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Base64.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Base64.java
deleted file mode 100644
index f6af109..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Base64.java
+++ /dev/null
@@ -1,2087 +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.util;
-
-//CHECKSTYLE: OFF
-
-/**
- * <p>Encodes and decodes to and from Base64 notation.</p>
- * <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
- *
- * <p>Example:</p>
- *
- * <code>String encoded = Base64.encode( myByteArray );</code>
- * <br>
- * <code>byte[] myByteArray = Base64.decode( encoded );</code>
- *
- * <p>The <tt>options</tt> parameter, which appears in a few places, is used to pass 
- * several pieces of information to the encoder. In the "higher level" methods such as 
- * encodeBytes( bytes, options ) the options parameter can be used to indicate such 
- * things as first gzipping the bytes before encoding them, not inserting linefeeds,
- * and encoding using the URL-safe and Ordered dialects.</p>
- *
- * <p>Note, according to <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>,
- * Section 2.1, implementations should not add line feeds unless explicitly told
- * to do so. I've got Base64 set to this behavior now, although earlier versions
- * broke lines by default.</p>
- *
- * <p>The constants defined in Base64 can be OR-ed together to combine options, so you 
- * might make a call like this:</p>
- *
- * <code>String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES );</code>
- * <p>to compress the data before encoding it and then making the output have newline characters.</p>
- * <p>Also...</p>
- * <code>String encoded = Base64.encodeBytes( crazyString.getBytes() );</code>
- *
- *
- *
- * <p>
- * Change Log:
- * </p>
- * <ul>
- *  <li>v2.3.7 - Fixed subtle bug when base 64 input stream contained the
- *   value 01111111, which is an invalid base 64 character but should not
- *   throw an ArrayIndexOutOfBoundsException either. Led to discovery of
- *   mishandling (or potential for better handling) of other bad input
- *   characters. You should now get an IOException if you try decoding
- *   something that has bad characters in it.</li>
- *  <li>v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded
- *   string ended in the last column; the buffer was not properly shrunk and
- *   contained an extra (null) byte that made it into the string.</li>
- *  <li>v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size
- *   was wrong for files of size 31, 34, and 37 bytes.</li>
- *  <li>v2.3.4 - Fixed bug when working with gzipped streams whereby flushing
- *   the Base64.OutputStream closed the Base64 encoding (by padding with equals
- *   signs) too soon. Also added an option to suppress the automatic decoding
- *   of gzipped streams. Also added experimental support for specifying a
- *   class loader when using the
- *   {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)}
- *   method.</li>
- *  <li>v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java
- *   footprint with its CharEncoders and so forth. Fixed some javadocs that were
- *   inconsistent. Removed imports and specified things like java.io.IOException
- *   explicitly inline.</li>
- *  <li>v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the
- *   final encoded data will be so that the code doesn't have to create two output
- *   arrays: an oversized initial one and then a final, exact-sized one. Big win
- *   when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not
- *   using the gzip options which uses a different mechanism with streams and stuff).</li>
- *  <li>v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some
- *   similar helper methods to be more efficient with memory by not returning a
- *   String but just a byte array.</li>
- *  <li>v2.3 - <strong>This is not a drop-in replacement!</strong> This is two years of comments
- *   and bug fixes queued up and finally executed. Thanks to everyone who sent
- *   me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else.
- *   Much bad coding was cleaned up including throwing exceptions where necessary 
- *   instead of returning null values or something similar. Here are some changes
- *   that may affect you:
- *   <ul>
- *    <li><em>Does not break lines, by default.</em> This is to keep in compliance with
- *      <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>.</li>
- *    <li><em>Throws exceptions instead of returning null values.</em> Because some operations
- *      (especially those that may permit the GZIP option) use IO streams, there
- *      is a possiblity of an java.io.IOException being thrown. After some discussion and
- *      thought, I've changed the behavior of the methods to throw java.io.IOExceptions
- *      rather than return null if ever there's an error. I think this is more
- *      appropriate, though it will require some changes to your code. Sorry,
- *      it should have been done this way to begin with.</li>
- *    <li><em>Removed all references to System.out, System.err, and the like.</em>
- *      Shame on me. All I can say is sorry they were ever there.</li>
- *    <li><em>Throws NullPointerExceptions and IllegalArgumentExceptions</em> as needed
- *      such as when passed arrays are null or offsets are invalid.</li>
- *    <li>Cleaned up as much javadoc as I could to avoid any javadoc warnings.
- *      This was especially annoying before for people who were thorough in their
- *      own projects and then had gobs of javadoc warnings on this file.</li>
- *   </ul>
- *  <li>v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug
- *   when using very small files (~&lt; 40 bytes).</li>
- *  <li>v2.2 - Added some helper methods for encoding/decoding directly from
- *   one file to the next. Also added a main() method to support command line
- *   encoding/decoding from one file to the next. Also added these Base64 dialects:
- *   <ol>
- *   <li>The default is RFC3548 format.</li>
- *   <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
- *   URL and file name friendly format as described in Section 4 of RFC3548.
- *   http://www.faqs.org/rfcs/rfc3548.html</li>
- *   <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
- *   URL and file name friendly format that preserves lexical ordering as described
- *   in http://www.faqs.org/qa/rfcc-1940.html</li>
- *   </ol>
- *   Special thanks to Jim Kellerman at <a href="http://www.powerset.com/">http://www.powerset.com/</a>
- *   for contributing the new Base64 dialects.
- *  </li>
- *
- *  <li>v2.1 - Cleaned up javadoc comments and unused variables and methods. Added
- *   some convenience methods for reading and writing to and from files.</li>
- *  <li>v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems
- *   with other encodings (like EBCDIC).</li>
- *  <li>v2.0.1 - Fixed an error when decoding a single byte, that is, when the
- *   encoded data was a single byte.</li>
- *  <li>v2.0 - I got rid of methods that used booleans to set options. 
- *   Now everything is more consolidated and cleaner. The code now detects
- *   when data that's being decoded is gzip-compressed and will decompress it
- *   automatically. Generally things are cleaner. You'll probably have to
- *   change some method calls that you were making to support the new
- *   options format (<tt>int</tt>s that you "OR" together).</li>
- *  <li>v1.5.1 - Fixed bug when decompressing and decoding to a             
- *   byte[] using <tt>decode( String s, boolean gzipCompressed )</tt>.      
- *   Added the ability to "suspend" encoding in the Output Stream so        
- *   you can turn on and off the encoding if you need to embed base64       
- *   data in an otherwise "normal" stream (like an XML file).</li>  
- *  <li>v1.5 - Output stream pases on flush() command but doesn't do anything itself.
- *      This helps when using GZIP streams.
- *      Added the ability to GZip-compress objects before encoding them.</li>
- *  <li>v1.4 - Added helper methods to read/write files.</li>
- *  <li>v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.</li>
- *  <li>v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream
- *      where last buffer being read, if not completely full, was not returned.</li>
- *  <li>v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.</li>
- *  <li>v1.3.3 - Fixed I/O streams which were totally messed up.</li>
- * </ul>
- *
- * <p>
- * I am placing this code in the Public Domain. Do with it as you will.
- * This software comes with no guarantees or warranties but with
- * plenty of well-wishing instead!
- * Please visit <a href="http://iharder.net/base64">http://iharder.net/base64</a>
- * periodically to check for updates or to contribute improvements.
- * </p>
- *
- * @author Robert Harder
- * @author rob@iharder.net
- * @version 2.3.7
- */
-public class Base64
-{
-    
-/* ********  P U B L I C   F I E L D S  ******** */
-
-
-  /** No options specified. Value is zero. */
-  public final static int NO_OPTIONS = 0;
-
-  /** Specify encoding in first bit. Value is one. */
-  public final static int ENCODE = 1;
-
-
-  /** Specify decoding in first bit. Value is zero. */
-  public final static int DECODE = 0;
-
-
-  /** Specify that data should be gzip-compressed in second bit. Value is two. */
-  public final static int GZIP = 2;
-
-  /** Specify that gzipped data should <em>not</em> be automatically gunzipped. */
-  public final static int DONT_GUNZIP = 4;
-
-
-  /** Do break lines when encoding. Value is 8. */
-  public final static int DO_BREAK_LINES = 8;
-
-  /**
-   * Encode using Base64-like encoding that is URL- and Filename-safe as described
-   * in Section 4 of RFC3548:
-   * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
-   * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
-   * or at the very least should not be called Base64 without also specifying that is
-   * was encoded using the URL- and Filename-safe dialect.
-   */
-  public final static int URL_SAFE = 16;
-
-
-  /**
-   * Encode using the special "ordered" dialect of Base64 described here:
-   * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
-   */
-  public final static int ORDERED = 32;
-    
-    
-/* ********  P R I V A T E   F I E L D S  ******** */
-
-
-  /** Maximum line length (76) of Base64 output. */
-  private final static int MAX_LINE_LENGTH = 76;
-
-
-  /** The equals sign (=) as a byte. */
-  private final static byte EQUALS_SIGN = (byte)'=';
-
-
-  /** The new line character (\n) as a byte. */
-  private final static byte NEW_LINE = (byte)'\n';
-
-
-  /** Preferred encoding. */
-  private final static String PREFERRED_ENCODING = "US-ASCII";
-
-
-  private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
-  private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
-
-
-/* ********  S T A N D A R D   B A S E 6 4   A L P H A B E T  ******** */
-
-  /** The 64 valid Base64 values. */
-    /* Host platform me be something funny like EBCDIC, so we hardcode these values. */
-  private final static byte[] _STANDARD_ALPHABET = {
-      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
-      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
-      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
-  };
-
-
-  /**
-   * Translates a Base64 value to either its 6-bit reconstruction value
-   * or a negative number indicating some other meaning.
-   **/
-  private final static byte[] _STANDARD_DECODABET = {
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-      -5,-5,                                      // Whitespace: Tab and Linefeed
-      -9,-9,                                      // Decimal 11 - 12
-      -5,                                         // Whitespace: Carriage Return
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-      -5,                                         // Whitespace: Space
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-      62,                                         // Plus sign at decimal 43
-      -9,-9,-9,                                   // Decimal 44 - 46
-      63,                                         // Slash at decimal 47
-      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
-      -9,-9,-9,                                   // Decimal 58 - 60
-      -1,                                         // Equals sign at decimal 61
-      -9,-9,-9,                                      // Decimal 62 - 64
-      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
-      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
-      -9,-9,-9,-9,-9,-9,                          // Decimal 91 - 96
-      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
-      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
-      -9,-9,-9,-9,-9                              // Decimal 123 - 127
-      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,       // Decimal 128 - 139
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255
-  };
-
-
-/* ********  U R L   S A F E   B A S E 6 4   A L P H A B E T  ******** */
-
-  /**
-   * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
-   * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
-   * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
-   */
-  private final static byte[] _URL_SAFE_ALPHABET = {
-      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
-      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
-      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_'
-  };
-
-  /**
-   * Used in decoding URL- and Filename-safe dialects of Base64.
-   */
-  private final static byte[] _URL_SAFE_DECODABET = {
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-      -5,-5,                                      // Whitespace: Tab and Linefeed
-      -9,-9,                                      // Decimal 11 - 12
-      -5,                                         // Whitespace: Carriage Return
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-      -5,                                         // Whitespace: Space
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-      -9,                                         // Plus sign at decimal 43
-      -9,                                         // Decimal 44
-      62,                                         // Minus sign at decimal 45
-      -9,                                         // Decimal 46
-      -9,                                         // Slash at decimal 47
-      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
-      -9,-9,-9,                                   // Decimal 58 - 60
-      -1,                                         // Equals sign at decimal 61
-      -9,-9,-9,                                   // Decimal 62 - 64
-      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
-      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
-      -9,-9,-9,-9,                                // Decimal 91 - 94
-      63,                                         // Underscore at decimal 95
-      -9,                                         // Decimal 96
-      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
-      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
-      -9,-9,-9,-9,-9                              // Decimal 123 - 127
-      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 128 - 139
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 
-  };
-
-
-
-/* ********  O R D E R E D   B A S E 6 4   A L P H A B E T  ******** */
-
-  /**
-   * I don't get the point of this technique, but someone requested it,
-   * and it is described here:
-   * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
-   */
-  private final static byte[] _ORDERED_ALPHABET = {
-      (byte)'-',
-      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4',
-      (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9',
-      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-      (byte)'_',
-      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'
-  };
-
-  /**
-   * Used in decoding the "ordered" dialect of Base64.
-   */
-  private final static byte[] _ORDERED_DECODABET = {
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-      -5,-5,                                      // Whitespace: Tab and Linefeed
-      -9,-9,                                      // Decimal 11 - 12
-      -5,                                         // Whitespace: Carriage Return
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-      -5,                                         // Whitespace: Space
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-      -9,                                         // Plus sign at decimal 43
-      -9,                                         // Decimal 44
-      0,                                          // Minus sign at decimal 45
-      -9,                                         // Decimal 46
-      -9,                                         // Slash at decimal 47
-      1,2,3,4,5,6,7,8,9,10,                       // Numbers zero through nine
-      -9,-9,-9,                                   // Decimal 58 - 60
-      -1,                                         // Equals sign at decimal 61
-      -9,-9,-9,                                   // Decimal 62 - 64
-      11,12,13,14,15,16,17,18,19,20,21,22,23,     // Letters 'A' through 'M'
-      24,25,26,27,28,29,30,31,32,33,34,35,36,     // Letters 'N' through 'Z'
-      -9,-9,-9,-9,                                // Decimal 91 - 94
-      37,                                         // Underscore at decimal 95
-      -9,                                         // Decimal 96
-      38,39,40,41,42,43,44,45,46,47,48,49,50,     // Letters 'a' through 'm'
-      51,52,53,54,55,56,57,58,59,60,61,62,63,     // Letters 'n' through 'z'
-      -9,-9,-9,-9,-9                                 // Decimal 123 - 127
-      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 128 - 139
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255
-  };
-
-
-/* ********  D E T E R M I N E   W H I C H   A L H A B E T  ******** */
-
-
-  /**
-   * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
-   * the options specified.
-   * It's possible, though silly, to specify ORDERED <b>and</b> URLSAFE
-   * in which case one of them will be picked, though there is
-   * no guarantee as to which one will be picked.
-   */
-  private final static byte[] getAlphabet( int options ) {
-    if ((options & URL_SAFE) == URL_SAFE) {
-      return _URL_SAFE_ALPHABET;
-    } else if ((options & ORDERED) == ORDERED) {
-      return _ORDERED_ALPHABET;
-    } else {
-      return _STANDARD_ALPHABET;
-    }
-  } // end getAlphabet
-
-
-  /**
-   * Returns one of the _SOMETHING_DECODABET byte arrays depending on
-   * the options specified.
-   * It's possible, though silly, to specify ORDERED and URL_SAFE
-   * in which case one of them will be picked, though there is
-   * no guarantee as to which one will be picked.
-   */
-  private final static byte[] getDecodabet( int options ) {
-    if( (options & URL_SAFE) == URL_SAFE) {
-      return _URL_SAFE_DECODABET;
-    } else if ((options & ORDERED) == ORDERED) {
-      return _ORDERED_DECODABET;
-    } else {
-      return _STANDARD_DECODABET;
-    }
-  } // end getAlphabet
-
-
-
-  /** Defeats instantiation. */
-  private Base64(){}
-    
-
-    
-    
-/* ********  E N C O D I N G   M E T H O D S  ******** */
-
-
-  /**
-   * Encodes up to the first three bytes of array <var>threeBytes</var>
-   * and returns a four-byte array in Base64 notation.
-   * The actual number of significant bytes in your array is
-   * given by <var>numSigBytes</var>.
-   * The array <var>threeBytes</var> needs only be as big as
-   * <var>numSigBytes</var>.
-   * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
-   *
-   * @param b4 A reusable byte array to reduce array instantiation
-   * @param threeBytes the array to convert
-   * @param numSigBytes the number of significant bytes in your array
-   * @return four byte array in Base64 notation.
-   * @since 1.5.1
-   */
-  private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) {
-    encode3to4( threeBytes, 0, numSigBytes, b4, 0, options );
-    return b4;
-  }   // end encode3to4
-
-
-  /**
-   * <p>Encodes up to three bytes of the array <var>source</var>
-   * and writes the resulting four Base64 bytes to <var>destination</var>.
-   * The source and destination arrays can be manipulated
-   * anywhere along their length by specifying
-   * <var>srcOffset</var> and <var>destOffset</var>.
-   * This method does not check to make sure your arrays
-   * are large enough to accomodate <var>srcOffset</var> + 3 for
-   * the <var>source</var> array or <var>destOffset</var> + 4 for
-   * the <var>destination</var> array.
-   * The actual number of significant bytes in your array is
-   * given by <var>numSigBytes</var>.</p>
-   * <p>This is the lowest level of the encoding methods with
-   * all possible parameters.</p>
-   *
-   * @param source the array to convert
-   * @param srcOffset the index where conversion begins
-   * @param numSigBytes the number of significant bytes in your array
-   * @param destination the array to hold the conversion
-   * @param destOffset the index where output will be put
-   * @return the <var>destination</var> array
-   * @since 1.3
-   */
-  private static byte[] encode3to4(
-      byte[] source, int srcOffset, int numSigBytes,
-      byte[] destination, int destOffset, int options ) {
-
-    byte[] ALPHABET = getAlphabet( options );
-
-    //           1         2         3
-    // 01234567890123456789012345678901 Bit position
-    // --------000000001111111122222222 Array position from threeBytes
-    // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
-    //          >>18  >>12  >> 6  >> 0  Right shift necessary
-    //                0x3f  0x3f  0x3f  Additional AND
-
-    // Create buffer with zero-padding if there are only one or two
-    // significant bytes passed in the array.
-    // We have to shift left 24 in order to flush out the 1's that appear
-    // when Java treats a value as negative that is cast from a byte to an int.
-    int inBuff =   ( numSigBytes > 0 ? ((source[ srcOffset     ] << 24) >>>  8) : 0 )
-        | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
-        | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
-
-    switch( numSigBytes )
-    {
-    case 3:
-      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-      destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
-      destination[ destOffset + 3 ] = ALPHABET[ (inBuff       ) & 0x3f ];
-      return destination;
-
-    case 2:
-      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-      destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
-      destination[ destOffset + 3 ] = EQUALS_SIGN;
-      return destination;
-
-    case 1:
-      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-      destination[ destOffset + 2 ] = EQUALS_SIGN;
-      destination[ destOffset + 3 ] = EQUALS_SIGN;
-      return destination;
-
-    default:
-      return destination;
-    }   // end switch
-  }   // end encode3to4
-
-
-
-  /**
-   * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
-   * writing it to the <code>encoded</code> ByteBuffer.
-   * This is an experimental feature. Currently it does not
-   * pass along any options (such as {@link #DO_BREAK_LINES}
-   * or {@link #GZIP}.
-   *
-   * @param raw input buffer
-   * @param encoded output buffer
-   * @since 2.3
-   */
-  public static void encode( java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded ){
-    byte[] raw3 = new byte[3];
-    byte[] enc4 = new byte[4];
-
-    while( raw.hasRemaining() ){
-      int rem = Math.min(3,raw.remaining());
-      raw.get(raw3,0,rem);
-      Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
-      encoded.put(enc4);
-    }   // end input remaining
-  }
-
-
-  /**
-   * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
-   * writing it to the <code>encoded</code> CharBuffer.
-   * This is an experimental feature. Currently it does not
-   * pass along any options (such as {@link #DO_BREAK_LINES}
-   * or {@link #GZIP}.
-   *
-   * @param raw input buffer
-   * @param encoded output buffer
-   * @since 2.3
-   */
-  public static void encode( java.nio.ByteBuffer raw, java.nio.CharBuffer encoded ){
-    byte[] raw3 = new byte[3];
-    byte[] enc4 = new byte[4];
-
-    while( raw.hasRemaining() ){
-      int rem = Math.min(3,raw.remaining());
-      raw.get(raw3,0,rem);
-      Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
-      for( int i = 0; i < 4; i++ ){
-        encoded.put( (char)(enc4[i] & 0xFF) );
-      }
-    }   // end input remaining
-  }
-
-
-
-
-  /**
-   * Serializes an object and returns the Base64-encoded
-   * version of that serialized object.
-   *
-   * <p>As of v 2.3, if the object
-   * cannot be serialized or there is another error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned a null value, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * The object is not GZip-compressed before being encoded.
-   *
-   * @param serializableObject The object to encode
-   * @return The Base64-encoded object
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if serializedObject is null
-   * @since 1.4
-   */
-  public static String encodeObject( java.io.Serializable serializableObject )
-      throws java.io.IOException {
-    return encodeObject( serializableObject, NO_OPTIONS );
-  }   // end encodeObject
-
-
-
-  /**
-   * Serializes an object and returns the Base64-encoded
-   * version of that serialized object.
-   *
-   * <p>As of v 2.3, if the object
-   * cannot be serialized or there is another error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned a null value, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * The object is not GZip-compressed before being encoded.
-   * <p>
-   * Example options:<pre>
-   *   GZIP: gzip-compresses object before encoding it.
-   *   DO_BREAK_LINES: break lines at 76 characters
-   * </pre>
-   * <p>
-   * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
-   * <p>
-   * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
-   *
-   * @param serializableObject The object to encode
-   * @param options Specified options
-   * @return The Base64-encoded object
-   * @see Base64#GZIP
-   * @see Base64#DO_BREAK_LINES
-   * @throws java.io.IOException if there is an error
-   * @since 2.0
-   */
-  public static String encodeObject( java.io.Serializable serializableObject, int options )
-      throws java.io.IOException {
-
-    if( serializableObject == null ){
-      throw new NullPointerException( "Cannot serialize a null object." );
-    }   // end if: null
-
-    // Streams
-    java.io.ByteArrayOutputStream  baos  = null;
-    java.io.OutputStream           b64os = null;
-    java.util.zip.GZIPOutputStream gzos  = null;
-    java.io.ObjectOutputStream     oos   = null;
-
-
-    try {
-      // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
-      baos  = new java.io.ByteArrayOutputStream();
-      b64os = new Base64.OutputStream( baos, ENCODE | options );
-      if( (options & GZIP) != 0 ){
-        // Gzip
-        gzos = new java.util.zip.GZIPOutputStream(b64os);
-        oos = new java.io.ObjectOutputStream( gzos );
-      } else {
-        // Not gzipped
-        oos = new java.io.ObjectOutputStream( b64os );
-      }
-      oos.writeObject( serializableObject );
-    }   // end try
-    catch( java.io.IOException e ) {
-      // Catch it and then throw it immediately so that
-      // the finally{} block is called for cleanup.
-      throw e;
-    }   // end catch
-    finally {
-      try{ oos.close();   } catch( Exception e ){}
-      try{ gzos.close();  } catch( Exception e ){}
-      try{ b64os.close(); } catch( Exception e ){}
-      try{ baos.close();  } catch( Exception e ){}
-    }   // end finally
-
-    // Return value according to relevant encoding.
-    try {
-      return new String( baos.toByteArray(), PREFERRED_ENCODING );
-    }   // end try
-    catch (java.io.UnsupportedEncodingException uue){
-      // Fall back to some Java default
-      return new String( baos.toByteArray() );
-    }   // end catch
-
-  }   // end encode
-
-
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   * Does not GZip-compress data.
-   *
-   * @param source The data to convert
-   * @return The data in Base64-encoded form
-   * @throws NullPointerException if source array is null
-   * @since 1.4
-   */
-  public static String encodeBytes( byte[] source ) {
-    // Since we're not going to have the GZIP encoding turned on,
-    // we're not going to have an java.io.IOException thrown, so
-    // we should not force the user to have to catch it.
-    String encoded = null;
-    try {
-      encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
-    } catch (java.io.IOException ex) {
-      assert false : ex.getMessage();
-    }   // end catch
-    assert encoded != null;
-    return encoded;
-  }   // end encodeBytes
-
-
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   * <p>
-   * Example options:<pre>
-   *   GZIP: gzip-compresses object before encoding it.
-   *   DO_BREAK_LINES: break lines at 76 characters
-   *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-   * </pre>
-   * <p>
-   * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
-   * <p>
-   * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
-   *
-   *
-   * <p>As of v 2.3, if there is an error with the GZIP stream,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned a null value, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   *
-   * @param source The data to convert
-   * @param options Specified options
-   * @return The Base64-encoded data as a String
-   * @see Base64#GZIP
-   * @see Base64#DO_BREAK_LINES
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if source array is null
-   * @since 2.0
-   */
-  public static String encodeBytes( byte[] source, int options ) throws java.io.IOException {
-    return encodeBytes( source, 0, source.length, options );
-  }   // end encodeBytes
-
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   * Does not GZip-compress data.
-   *
-   * <p>As of v 2.3, if there is an error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned a null value, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   *
-   * @param source The data to convert
-   * @param off Offset in array where conversion should begin
-   * @param len Length of data to convert
-   * @return The Base64-encoded data as a String
-   * @throws NullPointerException if source array is null
-   * @throws IllegalArgumentException if source array, offset, or length are invalid
-   * @since 1.4
-   */
-  public static String encodeBytes( byte[] source, int off, int len ) {
-    // Since we're not going to have the GZIP encoding turned on,
-    // we're not going to have an java.io.IOException thrown, so
-    // we should not force the user to have to catch it.
-    String encoded = null;
-    try {
-      encoded = encodeBytes( source, off, len, NO_OPTIONS );
-    } catch (java.io.IOException ex) {
-      assert false : ex.getMessage();
-    }   // end catch
-    assert encoded != null;
-    return encoded;
-  }   // end encodeBytes
-
-
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   * <p>
-   * Example options:<pre>
-   *   GZIP: gzip-compresses object before encoding it.
-   *   DO_BREAK_LINES: break lines at 76 characters
-   *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-   * </pre>
-   * <p>
-   * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
-   * <p>
-   * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
-   *
-   *
-   * <p>As of v 2.3, if there is an error with the GZIP stream,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned a null value, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   *
-   * @param source The data to convert
-   * @param off Offset in array where conversion should begin
-   * @param len Length of data to convert
-   * @param options Specified options
-   * @return The Base64-encoded data as a String
-   * @see Base64#GZIP
-   * @see Base64#DO_BREAK_LINES
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if source array is null
-   * @throws IllegalArgumentException if source array, offset, or length are invalid
-   * @since 2.0
-   */
-  public static String encodeBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
-    byte[] encoded = encodeBytesToBytes( source, off, len, options );
-
-    // Return value according to relevant encoding.
-    try {
-      return new String( encoded, PREFERRED_ENCODING );
-    }   // end try
-    catch (java.io.UnsupportedEncodingException uue) {
-      return new String( encoded );
-    }   // end catch
-
-  }   // end encodeBytes
-
-
-
-
-  /**
-   * Similar to {@link #encodeBytes(byte[])} but returns
-   * a byte array instead of instantiating a String. This is more efficient
-   * if you're working with I/O streams and have large data sets to encode.
-   *
-   *
-   * @param source The data to convert
-   * @return The Base64-encoded data as a byte[] (of ASCII characters)
-   * @throws NullPointerException if source array is null
-   * @since 2.3.1
-   */
-  public static byte[] encodeBytesToBytes( byte[] source ) {
-    byte[] encoded = null;
-    try {
-      encoded = encodeBytesToBytes( source, 0, source.length, Base64.NO_OPTIONS );
-    } catch( java.io.IOException ex ) {
-      assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
-    }
-    return encoded;
-  }
-
-
-  /**
-   * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns
-   * a byte array instead of instantiating a String. This is more efficient
-   * if you're working with I/O streams and have large data sets to encode.
-   *
-   *
-   * @param source The data to convert
-   * @param off Offset in array where conversion should begin
-   * @param len Length of data to convert
-   * @param options Specified options
-   * @return The Base64-encoded data as a String
-   * @see Base64#GZIP
-   * @see Base64#DO_BREAK_LINES
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if source array is null
-   * @throws IllegalArgumentException if source array, offset, or length are invalid
-   * @since 2.3.1
-   */
-  public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
-
-    if( source == null ){
-      throw new NullPointerException( "Cannot serialize a null array." );
-    }   // end if: null
-
-    if( off < 0 ){
-      throw new IllegalArgumentException( "Cannot have negative offset: " + off );
-    }   // end if: off < 0
-
-    if( len < 0 ){
-      throw new IllegalArgumentException( "Cannot have length offset: " + len );
-    }   // end if: len < 0
-
-    if( off + len > source.length  ){
-      throw new IllegalArgumentException(
-          String.format( "Cannot have offset of %d and length of %d with array of length %d", off,len,source.length));
-    }   // end if: off < 0
-
-
-
-    // Compress?
-    if( (options & GZIP) != 0 ) {
-      java.io.ByteArrayOutputStream  baos  = null;
-      java.util.zip.GZIPOutputStream gzos  = null;
-      Base64.OutputStream            b64os = null;
-
-      try {
-        // GZip -> Base64 -> ByteArray
-        baos = new java.io.ByteArrayOutputStream();
-        b64os = new Base64.OutputStream( baos, ENCODE | options );
-        gzos  = new java.util.zip.GZIPOutputStream( b64os );
-
-        gzos.write( source, off, len );
-        gzos.close();
-      }   // end try
-      catch( java.io.IOException e ) {
-        // Catch it and then throw it immediately so that
-        // the finally{} block is called for cleanup.
-        throw e;
-      }   // end catch
-      finally {
-        try{ gzos.close();  } catch( Exception e ){}
-        try{ b64os.close(); } catch( Exception e ){}
-        try{ baos.close();  } catch( Exception e ){}
-      }   // end finally
-
-      return baos.toByteArray();
-    }   // end if: compress
-
-    // Else, don't compress. Better not to use streams at all then.
-    else {
-      boolean breakLines = (options & DO_BREAK_LINES) != 0;
-
-      //int    len43   = len * 4 / 3;
-      //byte[] outBuff = new byte[   ( len43 )                      // Main 4:3
-      //                           + ( (len % 3) > 0 ? 4 : 0 )      // Account for padding
-      //                           + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
-      // Try to determine more precisely how big the array needs to be.
-      // If we get it right, we don't have to do an array copy, and
-      // we save a bunch of memory.
-      int encLen = ( len / 3 ) * 4 + ( len % 3 > 0 ? 4 : 0 ); // Bytes needed for actual encoding
-      if( breakLines ){
-        encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
-      }
-      byte[] outBuff = new byte[ encLen ];
-
-
-      int d = 0;
-      int e = 0;
-      int len2 = len - 2;
-      int lineLength = 0;
-      for( ; d < len2; d+=3, e+=4 ) {
-        encode3to4( source, d+off, 3, outBuff, e, options );
-
-        lineLength += 4;
-        if( breakLines && lineLength >= MAX_LINE_LENGTH )
-        {
-          outBuff[e+4] = NEW_LINE;
-          e++;
-          lineLength = 0;
-        }   // end if: end of line
-      }   // en dfor: each piece of array
-
-      if( d < len ) {
-        encode3to4( source, d+off, len - d, outBuff, e, options );
-        e += 4;
-      }   // end if: some padding needed
-
-
-      // Only resize array if we didn't guess it right.
-      if( e <= outBuff.length - 1 ){
-        // If breaking lines and the last byte falls right at
-        // the line length (76 bytes per line), there will be
-        // one extra byte, and the array will need to be resized.
-        // Not too bad of an estimate on array size, I'd say.
-        byte[] finalOut = new byte[e];
-        System.arraycopy(outBuff,0, finalOut,0,e);
-        //System.err.println("Having to resize array from " + outBuff.length + " to " + e );
-        return finalOut;
-      } else {
-        //System.err.println("No need to resize array.");
-        return outBuff;
-      }
-
-    }   // end else: don't compress
-
-  }   // end encodeBytesToBytes
-    
-
-    
-    
-    
-/* ********  D E C O D I N G   M E T H O D S  ******** */
-
-
-  /**
-   * Decodes four bytes from array <var>source</var>
-   * and writes the resulting bytes (up to three of them)
-   * to <var>destination</var>.
-   * The source and destination arrays can be manipulated
-   * anywhere along their length by specifying
-   * <var>srcOffset</var> and <var>destOffset</var>.
-   * This method does not check to make sure your arrays
-   * are large enough to accomodate <var>srcOffset</var> + 4 for
-   * the <var>source</var> array or <var>destOffset</var> + 3 for
-   * the <var>destination</var> array.
-   * This method returns the actual number of bytes that
-   * were converted from the Base64 encoding.
-   * <p>This is the lowest level of the decoding methods with
-   * all possible parameters.</p>
-   *
-   *
-   * @param source the array to convert
-   * @param srcOffset the index where conversion begins
-   * @param destination the array to hold the conversion
-   * @param destOffset the index where output will be put
-   * @param options alphabet type is pulled from this (standard, url-safe, ordered)
-   * @return the number of decoded bytes converted
-   * @throws NullPointerException if source or destination arrays are null
-   * @throws IllegalArgumentException if srcOffset or destOffset are invalid
-   *         or there is not enough room in the array.
-   * @since 1.3
-   */
-  private static int decode4to3(
-      byte[] source, int srcOffset,
-      byte[] destination, int destOffset, int options ) {
-
-    // Lots of error checking and exception throwing
-    if( source == null ){
-      throw new NullPointerException( "Source array was null." );
-    }   // end if
-    if( destination == null ){
-      throw new NullPointerException( "Destination array was null." );
-    }   // end if
-    if( srcOffset < 0 || srcOffset + 3 >= source.length ){
-      throw new IllegalArgumentException( String.format(
-          "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset ) );
-    }   // end if
-    if( destOffset < 0 || destOffset +2 >= destination.length ){
-      throw new IllegalArgumentException( String.format(
-          "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset ) );
-    }   // end if
-
-
-    byte[] DECODABET = getDecodabet( options );
-
-    // Example: Dk==
-    if( source[ srcOffset + 2] == EQUALS_SIGN ) {
-      // Two ways to do the same thing. Don't know which way I like best.
-      //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )
-      //              | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
-      int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] & 0xFF ) << 18 )
-          | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 );
-
-      destination[ destOffset ] = (byte)( outBuff >>> 16 );
-      return 1;
-    }
-
-    // Example: DkL=
-    else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) {
-      // Two ways to do the same thing. Don't know which way I like best.
-      //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
-      //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
-      //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
-      int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
-          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
-          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6 );
-
-      destination[ destOffset     ] = (byte)( outBuff >>> 16 );
-      destination[ destOffset + 1 ] = (byte)( outBuff >>>  8 );
-      return 2;
-    }
-
-    // Example: DkLE
-    else {
-      // Two ways to do the same thing. Don't know which way I like best.
-      //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
-      //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
-      //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
-      //              | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
-      int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
-          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
-          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6)
-          | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF )      );
-
-
-      destination[ destOffset     ] = (byte)( outBuff >> 16 );
-      destination[ destOffset + 1 ] = (byte)( outBuff >>  8 );
-      destination[ destOffset + 2 ] = (byte)( outBuff       );
-
-      return 3;
-    }
-  }   // end decodeToBytes
-
-
-
-
-
-  /**
-   * Low-level access to decoding ASCII characters in
-   * the form of a byte array. <strong>Ignores GUNZIP option, if
-   * it's set.</strong> This is not generally a recommended method,
-   * although it is used internally as part of the decoding process.
-   * Special case: if len = 0, an empty array is returned. Still,
-   * if you need more speed and reduced memory footprint (and aren't
-   * gzipping), consider this method.
-   *
-   * @param source The Base64 encoded data
-   * @return decoded data
-   * @since 2.3.1
-   */
-  public static byte[] decode( byte[] source )
-      throws java.io.IOException {
-    byte[] decoded = null;
-//        try {
-    decoded = decode( source, 0, source.length, Base64.NO_OPTIONS );
-//        } catch( java.io.IOException ex ) {
-//            assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
-//        }
-    return decoded;
-  }
-
-
-
-  /**
-   * Low-level access to decoding ASCII characters in
-   * the form of a byte array. <strong>Ignores GUNZIP option, if
-   * it's set.</strong> This is not generally a recommended method,
-   * although it is used internally as part of the decoding process.
-   * Special case: if len = 0, an empty array is returned. Still,
-   * if you need more speed and reduced memory footprint (and aren't
-   * gzipping), consider this method.
-   *
-   * @param source The Base64 encoded data
-   * @param off    The offset of where to begin decoding
-   * @param len    The length of characters to decode
-   * @param options Can specify options such as alphabet type to use
-   * @return decoded data
-   * @throws java.io.IOException If bogus characters exist in source data
-   * @since 1.3
-   */
-  public static byte[] decode( byte[] source, int off, int len, int options )
-      throws java.io.IOException {
-
-    // Lots of error checking and exception throwing
-    if( source == null ){
-      throw new NullPointerException( "Cannot decode null source array." );
-    }   // end if
-    if( off < 0 || off + len > source.length ){
-      throw new IllegalArgumentException( String.format(
-          "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) );
-    }   // end if
-
-    if( len == 0 ){
-      return new byte[0];
-    }else if( len < 4 ){
-      throw new IllegalArgumentException(
-          "Base64-encoded string must have at least four characters, but length specified was " + len );
-    }   // end if
-
-    byte[] DECODABET = getDecodabet( options );
-
-    int    len34   = len * 3 / 4;       // Estimate on array size
-    byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output
-    int    outBuffPosn = 0;             // Keep track of where we're writing
-
-    byte[] b4        = new byte[4];     // Four byte buffer from source, eliminating white space
-    int    b4Posn    = 0;               // Keep track of four byte input buffer
-    int    i         = 0;               // Source array counter
-    byte   sbiDecode = 0;               // Special value from DECODABET
-
-    for( i = off; i < off+len; i++ ) {  // Loop through source
-
-      sbiDecode = DECODABET[ source[i]&0xFF ];
-
-      // White space, Equals sign, or legit Base64 character
-      // Note the values such as -5 and -9 in the
-      // DECODABETs at the top of the file.
-      if( sbiDecode >= WHITE_SPACE_ENC )  {
-        if( sbiDecode >= EQUALS_SIGN_ENC ) {
-          b4[ b4Posn++ ] = source[i];         // Save non-whitespace
-          if( b4Posn > 3 ) {                  // Time to decode?
-            outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options );
-            b4Posn = 0;
-
-            // If that was the equals sign, break out of 'for' loop
-            if( source[i] == EQUALS_SIGN ) {
-              break;
-            }   // end if: equals sign
-          }   // end if: quartet built
-        }   // end if: equals sign or better
-      }   // end if: white space, equals sign or better
-      else {
-        // There's a bad input character in the Base64 stream.
-        throw new java.io.IOException( String.format(
-            "Bad Base64 input character decimal %d in array position %d", ((int)source[i])&0xFF, i ) );
-      }   // end else:
-    }   // each input character
-
-    byte[] out = new byte[ outBuffPosn ];
-    System.arraycopy( outBuff, 0, out, 0, outBuffPosn );
-    return out;
-  }   // end decode
-
-
-
-
-  /**
-   * Decodes data from Base64 notation, automatically
-   * detecting gzip-compressed data and decompressing it.
-   *
-   * @param s the string to decode
-   * @return the decoded data
-   * @throws java.io.IOException If there is a problem
-   * @since 1.4
-   */
-  public static byte[] decode( String s ) throws java.io.IOException {
-    return decode( s, NO_OPTIONS );
-  }
-
-
-
-  /**
-   * Decodes data from Base64 notation, automatically
-   * detecting gzip-compressed data and decompressing it.
-   *
-   * @param s the string to decode
-   * @param options encode options such as URL_SAFE
-   * @return the decoded data
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if <tt>s</tt> is null
-   * @since 1.4
-   */
-  public static byte[] decode( String s, int options ) throws java.io.IOException {
-
-    if( s == null ){
-      throw new NullPointerException( "Input string was null." );
-    }   // end if
-
-    byte[] bytes;
-    try {
-      bytes = s.getBytes( PREFERRED_ENCODING );
-    }   // end try
-    catch( java.io.UnsupportedEncodingException uee ) {
-      bytes = s.getBytes();
-    }   // end catch
-    //</change>
-
-    // Decode
-    bytes = decode( bytes, 0, bytes.length, options );
-
-    // Check to see if it's gzip-compressed
-    // GZIP Magic Two-Byte Number: 0x8b1f (35615)
-    boolean dontGunzip = (options & DONT_GUNZIP) != 0;
-    if( (bytes != null) && (bytes.length >= 4) && (!dontGunzip) ) {
-
-      int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
-      if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head )  {
-        java.io.ByteArrayInputStream  bais = null;
-        java.util.zip.GZIPInputStream gzis = null;
-        java.io.ByteArrayOutputStream baos = null;
-        byte[] buffer = new byte[2048];
-        int    length = 0;
-
-        try {
-          baos = new java.io.ByteArrayOutputStream();
-          bais = new java.io.ByteArrayInputStream( bytes );
-          gzis = new java.util.zip.GZIPInputStream( bais );
-
-          while( ( length = gzis.read( buffer ) ) >= 0 ) {
-            baos.write(buffer,0,length);
-          }   // end while: reading input
-
-          // No error? Get new bytes.
-          bytes = baos.toByteArray();
-
-        }   // end try
-        catch( java.io.IOException e ) {
-          e.printStackTrace();
-          // Just return originally-decoded bytes
-        }   // end catch
-        finally {
-          try{ baos.close(); } catch( Exception e ){}
-          try{ gzis.close(); } catch( Exception e ){}
-          try{ bais.close(); } catch( Exception e ){}
-        }   // end finally
-
-      }   // end if: gzipped
-    }   // end if: bytes.length >= 2
-
-    return bytes;
-  }   // end decode
-
-
-
-  /**
-   * Attempts to decode Base64 data and deserialize a Java
-   * Object within. Returns <tt>null</tt> if there was an error.
-   *
-   * @param encodedObject The Base64 data to decode
-   * @return The decoded and deserialized object
-   * @throws NullPointerException if encodedObject is null
-   * @throws java.io.IOException if there is a general error
-   * @throws ClassNotFoundException if the decoded object is of a
-   *         class that cannot be found by the JVM
-   * @since 1.5
-   */
-  public static Object decodeToObject( String encodedObject )
-      throws java.io.IOException, java.lang.ClassNotFoundException {
-    return decodeToObject(encodedObject,NO_OPTIONS,null);
-  }
-
-
-  /**
-   * Attempts to decode Base64 data and deserialize a Java
-   * Object within. Returns <tt>null</tt> if there was an error.
-   * If <tt>loader</tt> is not null, it will be the class loader
-   * used when deserializing.
-   *
-   * @param encodedObject The Base64 data to decode
-   * @param options Various parameters related to decoding
-   * @param loader Optional class loader to use in deserializing classes.
-   * @return The decoded and deserialized object
-   * @throws NullPointerException if encodedObject is null
-   * @throws java.io.IOException if there is a general error
-   * @throws ClassNotFoundException if the decoded object is of a
-   *         class that cannot be found by the JVM
-   * @since 2.3.4
-   */
-  public static Object decodeToObject(
-      String encodedObject, int options, final ClassLoader loader )
-      throws java.io.IOException, java.lang.ClassNotFoundException {
-
-    // Decode and gunzip if necessary
-    byte[] objBytes = decode( encodedObject, options );
-
-    java.io.ByteArrayInputStream  bais = null;
-    java.io.ObjectInputStream     ois  = null;
-    Object obj = null;
-
-    try {
-      bais = new java.io.ByteArrayInputStream( objBytes );
-
-      // If no custom class loader is provided, use Java's builtin OIS.
-      if( loader == null ){
-        ois  = new java.io.ObjectInputStream( bais );
-      }   // end if: no loader provided
-
-      // Else make a customized object input stream that uses
-      // the provided class loader.
-      else {
-        ois = new java.io.ObjectInputStream(bais){
-          @Override
-          public Class<?> resolveClass(java.io.ObjectStreamClass streamClass)
-              throws java.io.IOException, ClassNotFoundException {
-            Class c = Class.forName(streamClass.getName(), false, loader);
-            if( c == null ){
-              return super.resolveClass(streamClass);
-            } else {
-              return c;   // Class loader knows of this class.
-            }   // end else: not null
-          }   // end resolveClass
-        };  // end ois
-      }   // end else: no custom class loader
-
-      obj = ois.readObject();
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e;    // Catch and throw in order to execute finally{}
-    }   // end catch
-    catch( java.lang.ClassNotFoundException e ) {
-      throw e;    // Catch and throw in order to execute finally{}
-    }   // end catch
-    finally {
-      try{ bais.close(); } catch( Exception e ){}
-      try{ ois.close();  } catch( Exception e ){}
-    }   // end finally
-
-    return obj;
-  }   // end decodeObject
-
-
-
-  /**
-   * Convenience method for encoding data to a file.
-   *
-   * <p>As of v 2.3, if there is a error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned false, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * @param dataToEncode byte array of data to encode in base64 form
-   * @param filename Filename for saving encoded data
-   * @throws java.io.IOException if there is an error
-   * @throws NullPointerException if dataToEncode is null
-   * @since 2.1
-   */
-  public static void encodeToFile( byte[] dataToEncode, String filename )
-      throws java.io.IOException {
-
-    if( dataToEncode == null ){
-      throw new NullPointerException( "Data to encode was null." );
-    }   // end iff
-
-    Base64.OutputStream bos = null;
-    try {
-      bos = new Base64.OutputStream(
-          new java.io.FileOutputStream( filename ), Base64.ENCODE );
-      bos.write( dataToEncode );
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and throw to execute finally{} block
-    }   // end catch: java.io.IOException
-    finally {
-      try{ bos.close(); } catch( Exception e ){}
-    }   // end finally
-
-  }   // end encodeToFile
-
-
-  /**
-   * Convenience method for decoding data to a file.
-   *
-   * <p>As of v 2.3, if there is a error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned false, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * @param dataToDecode Base64-encoded data as a string
-   * @param filename Filename for saving decoded data
-   * @throws java.io.IOException if there is an error
-   * @since 2.1
-   */
-  public static void decodeToFile( String dataToDecode, String filename )
-      throws java.io.IOException {
-
-    Base64.OutputStream bos = null;
-    try{
-      bos = new Base64.OutputStream(
-          new java.io.FileOutputStream( filename ), Base64.DECODE );
-      bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and throw to execute finally{} block
-    }   // end catch: java.io.IOException
-    finally {
-      try{ bos.close(); } catch( Exception e ){}
-    }   // end finally
-
-  }   // end decodeToFile
-
-
-
-
-  /**
-   * Convenience method for reading a base64-encoded
-   * file and decoding it.
-   *
-   * <p>As of v 2.3, if there is a error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned false, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * @param filename Filename for reading encoded data
-   * @return decoded byte array
-   * @throws java.io.IOException if there is an error
-   * @since 2.1
-   */
-  public static byte[] decodeFromFile( String filename )
-      throws java.io.IOException {
-
-    byte[] decodedData = null;
-    Base64.InputStream bis = null;
-    try
-    {
-      // Set up some useful variables
-      java.io.File file = new java.io.File( filename );
-      byte[] buffer = null;
-      int length   = 0;
-      int numBytes = 0;
-
-      // Check for size of file
-      if( file.length() > Integer.MAX_VALUE )
-      {
-        throw new java.io.IOException( "File is too big for this convenience method (" + file.length() + " bytes)." );
-      }   // end if: file too big for int index
-      buffer = new byte[ (int)file.length() ];
-
-      // Open a stream
-      bis = new Base64.InputStream(
-          new java.io.BufferedInputStream(
-              new java.io.FileInputStream( file ) ), Base64.DECODE );
-
-      // Read until done
-      while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
-        length += numBytes;
-      }   // end while
-
-      // Save in a variable to return
-      decodedData = new byte[ length ];
-      System.arraycopy( buffer, 0, decodedData, 0, length );
-
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and release to execute finally{}
-    }   // end catch: java.io.IOException
-    finally {
-      try{ bis.close(); } catch( Exception e) {}
-    }   // end finally
-
-    return decodedData;
-  }   // end decodeFromFile
-
-
-
-  /**
-   * Convenience method for reading a binary file
-   * and base64-encoding it.
-   *
-   * <p>As of v 2.3, if there is a error,
-   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
-   * In earlier versions, it just returned false, but
-   * in retrospect that's a pretty poor way to handle it.</p>
-   *
-   * @param filename Filename for reading binary data
-   * @return base64-encoded string
-   * @throws java.io.IOException if there is an error
-   * @since 2.1
-   */
-  public static String encodeFromFile( String filename )
-      throws java.io.IOException {
-
-    String encodedData = null;
-    Base64.InputStream bis = null;
-    try
-    {
-      // Set up some useful variables
-      java.io.File file = new java.io.File( filename );
-      byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4+1),40) ]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5)
-      int length   = 0;
-      int numBytes = 0;
-
-      // Open a stream
-      bis = new Base64.InputStream(
-          new java.io.BufferedInputStream(
-              new java.io.FileInputStream( file ) ), Base64.ENCODE );
-
-      // Read until done
-      while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
-        length += numBytes;
-      }   // end while
-
-      // Save in a variable to return
-      encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
-
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and release to execute finally{}
-    }   // end catch: java.io.IOException
-    finally {
-      try{ bis.close(); } catch( Exception e) {}
-    }   // end finally
-
-    return encodedData;
-  }   // end encodeFromFile
-
-  /**
-   * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
-   *
-   * @param infile Input file
-   * @param outfile Output file
-   * @throws java.io.IOException if there is an error
-   * @since 2.2
-   */
-  public static void encodeFileToFile( String infile, String outfile )
-      throws java.io.IOException {
-
-    String encoded = Base64.encodeFromFile( infile );
-    java.io.OutputStream out = null;
-    try{
-      out = new java.io.BufferedOutputStream(
-          new java.io.FileOutputStream( outfile ) );
-      out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and release to execute finally{}
-    }   // end catch
-    finally {
-      try { out.close(); }
-      catch( Exception ex ){}
-    }   // end finally
-  }   // end encodeFileToFile
-
-
-  /**
-   * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
-   *
-   * @param infile Input file
-   * @param outfile Output file
-   * @throws java.io.IOException if there is an error
-   * @since 2.2
-   */
-  public static void decodeFileToFile( String infile, String outfile )
-      throws java.io.IOException {
-
-    byte[] decoded = Base64.decodeFromFile( infile );
-    java.io.OutputStream out = null;
-    try{
-      out = new java.io.BufferedOutputStream(
-          new java.io.FileOutputStream( outfile ) );
-      out.write( decoded );
-    }   // end try
-    catch( java.io.IOException e ) {
-      throw e; // Catch and release to execute finally{}
-    }   // end catch
-    finally {
-      try { out.close(); }
-      catch( Exception ex ){}
-    }   // end finally
-  }   // end decodeFileToFile
-    
-    
-    /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
-
-
-
-  /**
-   * A {@link Base64.InputStream} will read data from another
-   * <tt>java.io.InputStream</tt>, given in the constructor,
-   * and encode/decode to/from Base64 notation on the fly.
-   *
-   * @see Base64
-   * @since 1.3
-   */
-  public static class InputStream extends java.io.FilterInputStream {
-
-    private boolean encode;         // Encoding or decoding
-    private int     position;       // Current position in the buffer
-    private byte[]  buffer;         // Small buffer holding converted data
-    private int     bufferLength;   // Length of buffer (3 or 4)
-    private int     numSigBytes;    // Number of meaningful bytes in the buffer
-    private int     lineLength;
-    private boolean breakLines;     // Break lines at less than 80 characters
-    private int     options;        // Record options used to create the stream.
-    private byte[]  decodabet;      // Local copies to avoid extra method calls
-
-
-    /**
-     * Constructs a {@link Base64.InputStream} in DECODE mode.
-     *
-     * @param in the <tt>java.io.InputStream</tt> from which to read data.
-     * @since 1.3
-     */
-    public InputStream( java.io.InputStream in ) {
-      this( in, DECODE );
-    }   // end constructor
-
-
-    /**
-     * Constructs a {@link Base64.InputStream} in
-     * either ENCODE or DECODE mode.
-     * <p>
-     * Valid options:<pre>
-     *   ENCODE or DECODE: Encode or Decode as data is read.
-     *   DO_BREAK_LINES: break lines at 76 characters
-     *     (only meaningful when encoding)
-     * </pre>
-     * <p>
-     * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
-     *
-     *
-     * @param in the <tt>java.io.InputStream</tt> from which to read data.
-     * @param options Specified options
-     * @see Base64#ENCODE
-     * @see Base64#DECODE
-     * @see Base64#DO_BREAK_LINES
-     * @since 2.0
-     */
-    public InputStream( java.io.InputStream in, int options ) {
-
-      super( in );
-      this.options      = options; // Record for later
-      this.breakLines   = (options & DO_BREAK_LINES) > 0;
-      this.encode       = (options & ENCODE) > 0;
-      this.bufferLength = encode ? 4 : 3;
-      this.buffer       = new byte[ bufferLength ];
-      this.position     = -1;
-      this.lineLength   = 0;
-      this.decodabet    = getDecodabet(options);
-    }   // end constructor
-
-    /**
-     * Reads enough of the input stream to convert
-     * to/from Base64 and returns the next byte.
-     *
-     * @return next byte
-     * @since 1.3
-     */
-    @Override
-    public int read() throws java.io.IOException  {
-
-      // Do we need to get data?
-      if( position < 0 ) {
-        if( encode ) {
-          byte[] b3 = new byte[3];
-          int numBinaryBytes = 0;
-          for( int i = 0; i < 3; i++ ) {
-            int b = in.read();
-
-            // If end of stream, b is -1.
-            if( b >= 0 ) {
-              b3[i] = (byte)b;
-              numBinaryBytes++;
-            } else {
-              break; // out of for loop
-            }   // end else: end of stream
-
-          }   // end for: each needed input byte
-
-          if( numBinaryBytes > 0 ) {
-            encode3to4( b3, 0, numBinaryBytes, buffer, 0, options );
-            position = 0;
-            numSigBytes = 4;
-          }   // end if: got data
-          else {
-            return -1;  // Must be end of stream
-          }   // end else
-        }   // end if: encoding
-
-        // Else decoding
-        else {
-          byte[] b4 = new byte[4];
-          int i = 0;
-          for( i = 0; i < 4; i++ ) {
-            // Read four "meaningful" bytes:
-            int b = 0;
-            do{ b = in.read(); }
-            while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC );
-
-            if( b < 0 ) {
-              break; // Reads a -1 if end of stream
-            }   // end if: end of stream
-
-            b4[i] = (byte)b;
-          }   // end for: each needed input byte
-
-          if( i == 4 ) {
-            numSigBytes = decode4to3( b4, 0, buffer, 0, options );
-            position = 0;
-          }   // end if: got four characters
-          else if( i == 0 ){
-            return -1;
-          }   // end else if: also padded correctly
-          else {
-            // Must have broken out from above.
-            throw new java.io.IOException( "Improperly padded Base64 input." );
-          }   // end
-
-        }   // end else: decode
-      }   // end else: get data
-
-      // Got data?
-      if( position >= 0 ) {
-        // End of relevant data?
-        if( /*!encode &&*/ position >= numSigBytes ){
-          return -1;
-        }   // end if: got data
-
-        if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) {
-          lineLength = 0;
-          return '\n';
-        }   // end if
-        else {
-          lineLength++;   // This isn't important when decoding
-          // but throwing an extra "if" seems
-          // just as wasteful.
-
-          int b = buffer[ position++ ];
-
-          if( position >= bufferLength ) {
-            position = -1;
-          }   // end if: end
-
-          return b & 0xFF; // This is how you "cast" a byte that's
-          // intended to be unsigned.
-        }   // end else
-      }   // end if: position >= 0
-
-      // Else error
-      else {
-        throw new java.io.IOException( "Error in Base64 code reading stream." );
-      }   // end else
-    }   // end read
-
-
-    /**
-     * Calls {@link #read()} repeatedly until the end of stream
-     * is reached or <var>len</var> bytes are read.
-     * Returns number of bytes read into array or -1 if
-     * end of stream is encountered.
-     *
-     * @param dest array to hold values
-     * @param off offset for array
-     * @param len max number of bytes to read into array
-     * @return bytes read into array or -1 if end of stream is encountered.
-     * @since 1.3
-     */
-    @Override
-    public int read( byte[] dest, int off, int len )
-        throws java.io.IOException {
-      int i;
-      int b;
-      for( i = 0; i < len; i++ ) {
-        b = read();
-
-        if( b >= 0 ) {
-          dest[off + i] = (byte) b;
-        }
-        else if( i == 0 ) {
-          return -1;
-        }
-        else {
-          break; // Out of 'for' loop
-        } // Out of 'for' loop
-      }   // end for: each byte read
-      return i;
-    }   // end read
-
-  }   // end inner class InputStream
-    
-    
-    
-    
-    
-    
-    /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
-
-
-
-  /**
-   * A {@link Base64.OutputStream} will write data to another
-   * <tt>java.io.OutputStream</tt>, given in the constructor,
-   * and encode/decode to/from Base64 notation on the fly.
-   *
-   * @see Base64
-   * @since 1.3
-   */
-  public static class OutputStream extends java.io.FilterOutputStream {
-
-    private boolean encode;
-    private int     position;
-    private byte[]  buffer;
-    private int     bufferLength;
-    private int     lineLength;
-    private boolean breakLines;
-    private byte[]  b4;         // Scratch used in a few places
-    private boolean suspendEncoding;
-    private int     options;    // Record for later
-    private byte[]  decodabet;  // Local copies to avoid extra method calls
-
-    /**
-     * Constructs a {@link Base64.OutputStream} in ENCODE mode.
-     *
-     * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
-     * @since 1.3
-     */
-    public OutputStream( java.io.OutputStream out ) {
-      this( out, ENCODE );
-    }   // end constructor
-
-
-    /**
-     * Constructs a {@link Base64.OutputStream} in
-     * either ENCODE or DECODE mode.
-     * <p>
-     * Valid options:<pre>
-     *   ENCODE or DECODE: Encode or Decode as data is read.
-     *   DO_BREAK_LINES: don't break lines at 76 characters
-     *     (only meaningful when encoding)
-     * </pre>
-     * <p>
-     * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
-     *
-     * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
-     * @param options Specified options.
-     * @see Base64#ENCODE
-     * @see Base64#DECODE
-     * @see Base64#DO_BREAK_LINES
-     * @since 1.3
-     */
-    public OutputStream( java.io.OutputStream out, int options ) {
-      super( out );
-      this.breakLines   = (options & DO_BREAK_LINES) != 0;
-      this.encode       = (options & ENCODE) != 0;
-      this.bufferLength = encode ? 3 : 4;
-      this.buffer       = new byte[ bufferLength ];
-      this.position     = 0;
-      this.lineLength   = 0;
-      this.suspendEncoding = false;
-      this.b4           = new byte[4];
-      this.options      = options;
-      this.decodabet    = getDecodabet(options);
-    }   // end constructor
-
-
-    /**
-     * Writes the byte to the output stream after
-     * converting to/from Base64 notation.
-     * When encoding, bytes are buffered three
-     * at a time before the output stream actually
-     * gets a write() call.
-     * When decoding, bytes are buffered four
-     * at a time.
-     *
-     * @param theByte the byte to write
-     * @since 1.3
-     */
-    @Override
-    public void write(int theByte)
-        throws java.io.IOException {
-      // Encoding suspended?
-      if( suspendEncoding ) {
-        this.out.write( theByte );
-        return;
-      }   // end if: supsended
-
-      // Encode?
-      if( encode ) {
-        buffer[ position++ ] = (byte)theByte;
-        if( position >= bufferLength ) { // Enough to encode.
-
-          this.out.write( encode3to4( b4, buffer, bufferLength, options ) );
-
-          lineLength += 4;
-          if( breakLines && lineLength >= MAX_LINE_LENGTH ) {
-            this.out.write( NEW_LINE );
-            lineLength = 0;
-          }   // end if: end of line
-
-          position = 0;
-        }   // end if: enough to output
-      }   // end if: encoding
-
-      // Else, Decoding
-      else {
-        // Meaningful Base64 character?
-        if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) {
-          buffer[ position++ ] = (byte)theByte;
-          if( position >= bufferLength ) { // Enough to output.
-
-            int len = Base64.decode4to3( buffer, 0, b4, 0, options );
-            out.write( b4, 0, len );
-            position = 0;
-          }   // end if: enough to output
-        }   // end if: meaningful base64 character
-        else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) {
-          throw new java.io.IOException( "Invalid character in Base64 data." );
-        }   // end else: not white space either
-      }   // end else: decoding
-    }   // end write
-
-
-
-    /**
-     * Calls {@link #write(int)} repeatedly until <var>len</var>
-     * bytes are written.
-     *
-     * @param theBytes array from which to read bytes
-     * @param off offset for array
-     * @param len max number of bytes to read into array
-     * @since 1.3
-     */
-    @Override
-    public void write( byte[] theBytes, int off, int len )
-        throws java.io.IOException {
-      // Encoding suspended?
-      if( suspendEncoding ) {
-        this.out.write( theBytes, off, len );
-        return;
-      }   // end if: supsended
-
-      for( int i = 0; i < len; i++ ) {
-        write( theBytes[ off + i ] );
-      }   // end for: each byte written
-
-    }   // end write
-
-
-
-    /**
-     * Method added by PHIL. [Thanks, PHIL. -Rob]
-     * This pads the buffer without closing the stream.
-     * @throws java.io.IOException  if there's an error.
-     */
-    public void flushBase64() throws java.io.IOException  {
-      if( position > 0 ) {
-        if( encode ) {
-          out.write( encode3to4( b4, buffer, position, options ) );
-          position = 0;
-        }   // end if: encoding
-        else {
-          throw new java.io.IOException( "Base64 input not properly padded." );
-        }   // end else: decoding
-      }   // end if: buffer partially full
-
-    }   // end flush
-
-
-    /**
-     * Flushes and closes (I think, in the superclass) the stream.
-     *
-     * @since 1.3
-     */
-    @Override
-    public void close() throws java.io.IOException {
-      // 1. Ensure that pending characters are written
-      flushBase64();
-
-      // 2. Actually close the stream
-      // Base class both flushes and closes.
-      super.close();
-
-      buffer = null;
-      out    = null;
-    }   // end close
-
-
-
-    /**
-     * Suspends encoding of the stream.
-     * May be helpful if you need to embed a piece of
-     * base64-encoded data in a stream.
-     *
-     * @throws java.io.IOException  if there's an error flushing
-     * @since 1.5.1
-     */
-    public void suspendEncoding() throws java.io.IOException  {
-      flushBase64();
-      this.suspendEncoding = true;
-    }   // end suspendEncoding
-
-
-    /**
-     * Resumes encoding of the stream.
-     * May be helpful if you need to embed a piece of
-     * base64-encoded data in a stream.
-     *
-     * @since 1.5.1
-     */
-    public void resumeEncoding() {
-      this.suspendEncoding = false;
-    }   // end resumeEncoding
-
-
-
-  }   // end inner class OutputStream
-
-
-}   // end class Base64
-
-//CHECKSTYLE: ON
-
-// End Base64.java


[57/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/avatica_protobuf_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_protobuf_reference.md b/avatica/site/_docs/avatica_protobuf_reference.md
deleted file mode 100644
index 02a8ab1..0000000
--- a/avatica/site/_docs/avatica_protobuf_reference.md
+++ /dev/null
@@ -1,1181 +0,0 @@
----
-layout: docs
-title: Avatica Protocol Buffers Reference
-sidebar_title: Protobuf Reference
-permalink: /docs/avatica_protobuf_reference.html
-requests:
-  - { name: "CatalogsRequest" }
-  - { name: "CloseConnectionRequest" }
-  - { name: "CloseStatementRequest" }
-  - { name: "ColumnsRequest" }
-  - { name: "CommitRequest" }
-  - { name: "ConnectionSyncRequest" }
-  - { name: "CreateStatementRequest" }
-  - { name: "DatabasePropertyRequest" }
-  - { name: "ExecuteRequest" }
-  - { name: "FetchRequest" }
-  - { name: "OpenConnectionRequest" }
-  - { name: "PrepareAndExecuteRequest" }
-  - { name: "PrepareRequest" }
-  - { name: "RollbackRequest" }
-  - { name: "SchemasRequest" }
-  - { name: "SyncResultsRequest" }
-  - { name: "TableTypesRequest" }
-  - { name: "TablesRequest" }
-  - { name: "TypeInfoRequest" }
-miscellaneous:
-  - { name: "AvaticaParameter" }
-  - { name: "AvaticaSeverity" }
-  - { name: "AvaticaType" }
-  - { name: "ColumnMetaData" }
-  - { name: "ColumnValue" }
-  - { name: "ConnectionProperties" }
-  - { name: "CursorFactory" }
-  - { name: "DatabaseProperty" }
-  - { name: "Frame" }
-  - { name: "QueryState" }
-  - { name: "Rep" }
-  - { name: "Row" }
-  - { name: "RpcMetadata" }
-  - { name: "Signature" }
-  - { name: "StateType" }
-  - { name: "StatementHandle" }
-  - { name: "StatementType" }
-  - { name: "Style" }
-  - { name: "TypedValue" }
-  - { name: "WireMessage" }
-responses:
-  - { name: "CloseConnectionResponse" }
-  - { name: "CloseStatementResponse" }
-  - { name: "CommitResponse" }
-  - { name: "ConnectionSyncResponse" }
-  - { name: "CreateStatementResponse" }
-  - { name: "DatabasePropertyResponse" }
-  - { name: "ErrorResponse" }
-  - { name: "ExecuteResponse" }
-  - { name: "FetchResponse" }
-  - { name: "OpenConnectionResponse" }
-  - { name: "PrepareResponse" }
-  - { name: "ResultSetResponse" }
-  - { name: "RollbackResponse" }
-  - { name: "SyncResultsResponse" }
----
-
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Avatica also supports [Protocol Buffers](https://developers.google.com/protocol-buffers/)
-as a message format since version 1.5.0. The Protocol Buffer, or protobuf for
-short, implementation is extremely similar to the JSON implementation. Some
-differences include protobuf's expanded type support (such as native byte arrays)
-and inability to differentiate between the default value for a field and the
-absence of a value for a field.
-
-Other notable structural differences to JSON include the addition of a
-`WireMessage` message which is used to identify the type of the wrapped message
-returned by the server (synonymous with `request` or `response` attribute on the
-JSON messages) and a change to `TypedValue` containing an `Object` value to
-a collection of optional strongly-typed values (as protobuf does not natively
-support an `Object` type that is unwrapped at runtime).
-
-Unless otherwise specified with use of the `required` modifier, all fields in
-all protocol buffer messages are `optional` by default.
-
-## Index
-
-### Requests
-<ul>
-  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-### Responses
-<ul>
-  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-### Miscellaneous
-<ul>
-  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-
-## Requests
-
-The collection of all protobuf objects accepted as requests to Avatica. All request
-objects should be wrapped in a `WireMessage` before being sent to Avatica.
-
-### CatalogsRequest
-
-This request is used to fetch the available catalog names in the database.
-
-{% highlight protobuf %}
-message CatalogsRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection to use.
-
-### CloseConnectionRequest
-
-This request is used to close the Connection object in the Avatica server identified by the given IDs.
-
-{% highlight protobuf %}
-message CloseConnectionRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to close.
-
-### CloseStatementRequest
-
-This request is used to close the Statement object in the Avatica server identified by the given IDs.
-
-{% highlight protobuf %}
-message CloseStatementRequest {
-  string connection_id = 1;
-  uint32 statement_id = 2;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to which the statement belongs.
-
-`statement_id` The identifier of the statement to close.
-
-### ColumnsRequest
-
-This request is used to fetch columns in the database given some optional filtering criteria.
-
-{% highlight protobuf %}
-message ColumnsRequest {
-  string catalog = 1;
-  string schema_pattern = 2;
-  string table_name_pattern = 3;
-  string column_name_pattern = 4;
-  string connection_id = 5;
-}
-{% endhighlight %}
-
-`catalog` The name of a catalog to limit returned columns.
-
-`schema_pattern` A Java Pattern against schemas to limit returned columns.
-
-`table_name_pattern` A Java Pattern against table names to limit returned columns.
-
-`column_name_pattern` A Java Pattern against column names to limit returned columns.
-
-`connection_id` The identifier of the connection which to use to fetch the columns.
-
-### CommitRequest
-
-This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
-
-{% highlight protobuf %}
-message CommitRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection on which to invoke commit.
-
-### ConnectionSyncRequest
-
-This request is used to ensure that the client and server have a consistent view of the database properties.
-
-{% highlight protobuf %}
-message ConnectionSyncRequest {
-  string connection_id = 1;
-  ConnectionProperties conn_props = 2;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to synchronize.
-
-`conn_props` A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
-
-### CreateStatementRequest
-
-This request is used to create a new Statement in the Avatica server.
-
-{% highlight protobuf %}
-message CreateStatementRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to use in creating a statement.
-
-### DatabasePropertyRequest
-
-This request is used to fetch all <a href="#databaseproperty">database properties</a>.
-
-{% highlight protobuf %}
-message DatabasePropertyRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to use when fetching the database properties.
-
-### ExecuteRequest
-
-This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
-
-{% highlight protobuf %}
-message ExecuteRequest {
-  StatementHandle statementHandle = 1;
-  repeated TypedValue parameter_values = 2;
-  uint64 max_row_count = 3;
-  bool has_parameter_values = 4;
-}
-{% endhighlight %}
-
-`statementHandle` A <a href="#statementhandle">StatementHandle</a> object.
-
-`parameter_values` The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
-
-`max_row_count` The maximum number of rows returned in the response.
-
-`has_parameter_values` A boolean which denotes if the user set a value for the `parameter_values` field.
-
-### FetchRequest
-
-This request is used to fetch a batch of rows from a Statement previously created.
-
-{% highlight protobuf %}
-message FetchRequest {
-  string connection_id = 1;
-  uint32 statement_id = 2;
-  uint64 offset = 3;
-  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to use.
-
-`statement_id` The identifier of the statement created using the above connection.
-
-`offset` The positional offset into a result set to fetch.
-
-`fetch_match_row_count` The maximum number of rows to return in the response to this request.
-
-### OpenConnectionRequest
-
-This request is used to open a new Connection in the Avatica server.
-
-{% highlight protobuf %}
-message OpenConnectionRequest {
-  string connection_id = 1;
-  map<string, string> info = 2;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to open in the server.
-
-`info` A Map containing properties to include when creating the Connection.
-
-### PrepareAndExecuteRequest
-
-This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
-
-{% highlight protobuf %}
-message PrepareAndExecuteRequest {
-  string connection_id = 1;
-  uint32 statement_id = 4;
-  string sql = 2;
-  uint64 max_row_count = 3;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection to use.
-
-`statement_id` The identifier for the statement created by the above connection to use.
-
-`sql` A SQL statement
-
-`max_row_count` The maximum number of rows returned in the response.
-
-### PrepareRequest
-
-This request is used to create create a new Statement with the given query in the Avatica server.
-
-{% highlight protobuf %}
-message PrepareRequest {
-  string connection_id = 1;
-  string sql = 2;
-  uint64 max_row_count = 3;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection to use.
-
-`sql` A SQL statement
-
-`max_row_count` The maximum number of rows returned in the response.
-
-### SyncResultsRequest
-
-This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
-
-{% highlight protobuf %}
-message SyncResultsRequest {
-  string connection_id = 1;
-  uint32 statement_id = 2;
-  QueryState state = 3;
-  uint64 offset = 4;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection to use.
-
-`statement_id` The identifier for the statement to use.
-
-`state` The <a href="#querystate">QueryState</a> object.
-
-`offset` The offset into the ResultSet to seek to.
-
-### RollbackRequest
-
-This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
-
-{% highlight protobuf %}
-message RollbackRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection on which to invoke rollback.
-
-### SchemasRequest
-
-This request is used to fetch the schemas matching the provided criteria in the database.
-
-{% highlight protobuf %}
-message SchemasRequest {
-  string catalog = 1;
-  string schema_pattern = 2;
-  string connection_id = 3;
-}
-{% endhighlight %}
-
-`catalog` The name of the catalog to fetch the schema from.
-
-`schema_pattern` A Java pattern of schemas to fetch.
-
-`connection_id` The identifier for the connection to fetch schemas from.
-
-### TableTypesRequest
-
-This request is used to fetch the table types available in this database.
-
-{% highlight protobuf %}
-message TableTypesRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to fetch the table types from.
-
-### TablesRequest
-
-This request is used to fetch the tables available in this database filtered by the provided criteria.
-
-{% highlight protobuf %}
-message TablesRequest {
-  string catalog = 1;
-  string schema_pattern = 2;
-  string table_name_pattern = 3;
-  repeated string type_list = 4;
-  bool has_type_list = 6;
-  string connection_id = 7;
-}
-{% endhighlight %}
-
-`catalog` The name of a catalog to restrict fetched tables.
-
-`schema_pattern` A Java Pattern representing schemas to include in fetched tables.
-
-`table_name_pattern` A Java Pattern representing table names to include in fetched tables.
-
-`type_list` A list of table types used to restrict fetched tables.
-
-`has_type_list` A boolean which denotes if the field `type_list` was provided.
-
-`connection_id` The identifier of the connection to fetch the tables from.
-
-### TypeInfoRequest
-
-This request is used to fetch the types available in this database.
-
-{% highlight protobuf %}
-message TypeInfoRequest {
-  string connection_id = 1;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to fetch the types from.
-
-## Responses
-
-The collection of all protobuf objects accepted as requests to Avatica. All response
-objects will be wrapped in a `WireMessage` before being returned from Avatica.
-
-### CloseConnectionResponse
-
-A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
-
-{% highlight protobuf %}
-message CloseConnectionResponse {
-  RpcMetadata metadata = 1;
-}
-{% endhighlight %}
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CloseStatementResponse
-
-A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
-
-{% highlight protobuf %}
-message CloseStatementResponse {
-  RpcMetadata metadata = 1;
-}
-{% endhighlight %}
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CommitResponse
-
-A response to the <a href="#commitrequest">CommitRequest</a>.
-
-{% highlight protobuf %}
-message CommitResponse {
-
-}
-{% endhighlight %}
-
-There are no attributes on this Response.
-
-### ConnectionSyncResponse
-
-A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
-response are those of the Connection in the Avatica server.
-
-{% highlight protobuf %}
-message ConnectionSyncResponse {
-  ConnectionProperties conn_props = 1;
-  RpcMetadata metadata = 2;
-}
-{% endhighlight %}
-
-`conn_props` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CreateStatementResponse
-
-A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
-that was created is included in the response. Clients will use this `statement_id` in subsequent calls.
-
-{% highlight protobuf %}
-message CreateStatementResponse {
-  string connection_id = 1;
-  uint32 statement_id = 2;
-  RpcMetadata metadata = 3;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection used to create the statement.
-
-`statement_id` The identifier for the created statement.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### DatabasePropertyResponse
-
-A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
-for information on the available property keys.
-
-{% highlight protobuf %}
-message DatabasePropertyResponse {
-  repeated DatabasePropertyElement props = 1;
-  RpcMetadata metadata = 2;
-}
-{% endhighlight %}
-
-`props` A collection of <a href="#databaseproperty">DatabaseProperty</a>'s.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ErrorResponse
-
-A response when an error was caught executing a request. Any request may return this response.
-
-{% highlight protobuf %}
-message ErrorResponse {
-  repeated string exceptions = 1;
-  bool has_exceptions = 7;
-  string error_message = 2;
-  Severity severity = 3;
-  uint32 error_code = 4;
-  string sql_state = 5;
-  RpcMetadata metadata = 6;
-}
-{% endhighlight %}
-
-`exceptions` A list of stringified Java StackTraces.
-
-`has_exceptions` A boolean which denotes the presence of `exceptions`.
-
-`error_message` A human-readable error message.
-
-`error_code` A numeric code for this error.
-
-`sql_state` A five character alphanumeric code for this error.
-
-`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ExecuteResponse
-
-A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
-
-{% highlight protobuf %}
-message ExecuteResponse {
-  repeated ResultSetResponse results = 1;
-  bool missing_statement = 2;
-  RpcMetadata metadata = 3;
-}
-{% endhighlight %}
-
-`results` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
-
-`missing_statement` A boolean which denotes if the request failed due to a missing statement.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### FetchResponse
-
-A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
-
-{% highlight protobuf %}
-message FetchResponse {
-  Frame frame = 1;
-  bool missing_statement = 2;
-  bool missing_results = 3;
-  RpcMetadata metadata = 4;
-}
-{% endhighlight %}
-
-`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
-
-`missing_statement` A boolean which denotes if the request failed due to a missing Statement.
-
-`missing_results` A boolean which denotes if the request failed due to a missing ResultSet.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### OpenConnectionResponse
-
-A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
-the client should use in subsequent calls was provided by the client in the request.
-
-{% highlight protobuf %}
-message OpenConnectionResponse {
-  RpcMetadata metadata = 1;
-}
-
-{% endhighlight %}
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### PrepareResponse
-
-A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
-which clients must use to fetch the results from the Statement.
-
-{% highlight protobuf %}
-message PrepareResponse {
-  StatementHandle statement = 1;
-  RpcMetadata metadata = 2;
-}
-{% endhighlight %}
-
-`statement` A <a href="#statementhandle">StatementHandle</a> object.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ResultSetResponse
-
-A response which contains the results and type details from a query.
-
-{% highlight protobuf %}
-message ResultSetResponse {
-  string connection_id = 1;
-  uint32 statement_id = 2;
-  bool own_statement = 3;
-  Signature signature = 4;
-  Frame first_frame = 5;
-  uint64 update_count = 6;
-  RpcMetadata metadata = 7;
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection used to generate this response.
-
-`statement_id` The identifier for the statement used to generate this response.
-
-`own_statement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
-statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
-
-`signature` A non-optional nested object <a href="#signature">Signature</a>
-
-`first_frame` A optional nested object <a href="#frame">Frame</a>
-
-`update_count` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
-that only contains this count and no additional data.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### RollbackResponse
-
-A response to the <a href="#rollbackrequest">RollBackRequest</a>.
-
-{% highlight protobuf %}
-message RollbackResponse {
-
-}
-{% endhighlight %}
-
-There are no attributes on this Response.
-
-### SyncResultsResponse
-
-A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
-should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
-or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
-
-{% highlight protobuf %}
-message SyncResultsResponse {
-  bool missing_statement = 1;
-  bool more_results = 2;
-  RpcMetadata metadata = 3;
-}
-{% endhighlight %}
-
-`more_results` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
-
-`missing_statement` A boolean which denotes if the statement for the ResultSet still exists.
-
-`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-## Miscellaneous
-
-### AvaticaParameter
-
-This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
-complex types such as arrays.
-
-{% highlight protobuf %}
-message AvaticaParameter {
-  bool signed = 1;
-  uint32 precision = 2;
-  uint32 scale = 3;
-  uint32 parameter_type = 4;
-  string class_name = 5;
-  string class_name = 6;
-  string name = 7;
-}
-{% endhighlight %}
-
-`signed` A boolean denoting whether the column is a signed numeric.
-
-`precision` The maximum numeric precision supported by this column.
-
-`scale` The maximum numeric scale supported by this column.
-
-`parameter_type` An integer corresponding to the JDBC Types class denoting the column's type.
-
-`type_name` The JDBC type name for this column.
-
-`class_name` The Java class backing the JDBC type for this column.
-
-`name` The name of the column.
-
-### AvaticaSeverity
-
-This enumeration describes the various levels of concern for an error in the Avatica server.
-
-{% highlight protobuf %}
-enum Severity {
-  UNKNOWN_SEVERITY = 0;
-  FATAL_SEVERITY = 1;
-  ERROR_SEVERITY = 2;
-  WARNING_SEVERITY = 3;
-}
-{% endhighlight %}
-
-### AvaticaType
-
-This object describes a simple or complex type for a column. Complex types will contain
-additional information in the `component` or `columns` attribute which describe the nested
-types of the complex parent type.
-
-{% highlight protobuf %}
-message AvaticaType {
-  uint32 id = 1;
-  string name = 2;
-  Rep rep = 3;
-  repeated ColumnMetaData columns = 4;
-  AvaticaType component = 5;
-}
-{% endhighlight %}
-
-`type` One of: `scalar`, `array`, `struct`.
-
-`id` A numeric value corresponding to the type of the object per the JDBC Types class.
-
-`name` The readable name of the JDBC type.
-
-`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
-
-`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
-
-`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
-
-### ColumnMetaData
-
-This object represents the JDBC ResultSetMetaData for a column.
-
-{% highlight protobuf %}
-message ColumnMetaData {
-  uint32 ordinal = 1;
-  bool auto_increment = 2;
-  bool case_sensitive = 3;
-  bool searchable = 4;
-  bool currency = 5;
-  uint32 nullable = 6;
-  bool signed = 7;
-  uint32 display_size = 8;
-  string label = 9;
-  string column_name = 10;
-  string schema_name = 11;
-  uint32 precision = 12;
-  uint32 scale = 13;
-  string table_name = 14;
-  string catalog_name = 15;
-  bool read_only = 16;
-  bool writable = 17;
-  bool definitely_writable = 18;
-  string column_class_name = 19;
-  AvaticaType type = 20;
-}
-{% endhighlight %}
-
-`ordinal` A positional offset number.
-
-`auto_increment` A boolean denoting whether the column is automatically incremented.
-
-`case_sensitive` A boolean denoting whether the column is case sensitive.
-
-`searchable` A boolean denoting whether this column supports all WHERE search clauses.
-
-`currency` A boolean denoting whether this column represents currency.
-
-`nullable` A number denoting whether this column supports null values.
-
-* 0 = No null values are allowed
-* 1 = Null values are allowed
-* 2 = It is unknown if null values are allowed
-
-`signed` A boolean denoting whether the column is a signed numeric.
-
-`display_size` The character width of the column.
-
-`label` A description for this column.
-
-`column_name` The name of the column.
-
-`schema_name` The schema to which this column belongs.
-
-`precision` The maximum numeric precision supported by this column.
-
-`scale` The maximum numeric scale supported by this column.
-
-`table_name` The name of the table to which this column belongs.
-
-`catalog_name` The name of the catalog to which this column belongs.
-
-`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
-
-`read_only` A boolean denoting whether the column is read-only.
-
-`writable` A boolean denoting whether the column is possible to be updated.
-
-`definitely_writable` A boolean denoting whether the column definitely can be updated.
-
-`column_class_name` The name of the Java class backing the column's type.
-
-### ConnectionProperties
-
-This object represents the properties for a given JDBC Connection.
-
-{% highlight protobuf %}
-message ConnectionProperties {
-  bool is_dirty = 1;
-  bool auto_commit = 2;
-  bool has_auto_commit = 7;
-  bool read_only = 3;
-  bool has_read_only = 8;
-  uint32 transaction_isolation = 4;
-  string catalog = 5;
-  string schema = 6;
-}
-{% endhighlight %}
-
-`is_dirty` A boolean denoting if the properties have been altered.
-
-`auto_commit` A boolean denoting if autoCommit is enabled for transactions.
-
-`has_auto_commit` A boolean denoting if `auto_commit` was set.
-
-`read_only` A boolean denoting if a JDBC connection is read-only.
-
-`has_read_only` A boolean denoting if `read_only` was set.
-
-`transaction_isolation` An integer which denotes the level of transactions isolation per the JDBC
-specification. This value is analogous to the values defined in `java.sql.Connection`.
-
-* 0 = Transactions are not supported
-* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
-* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
-* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
-* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
-
-`catalog` The name of a catalog to use when fetching connection properties.
-
-`schema` The name of the schema to use when fetching connection properties.
-
-### CursorFactory
-
-This object represents the information required to cast untyped objects into the necessary type for some results.
-
-{% highlight protobuf %}
-message CursorFactory {
-  enum Style {
-    OBJECT = 0;
-    RECORD = 1;
-    RECORD_PROJECTION = 2;
-    ARRAY = 3;
-    LIST = 4;
-    MAP = 5;
-  }
-
-  Style style = 1;
-  string class_name = 2;
-  repeated string field_names = 3;
-}
-{% endhighlight %}
-
-`style` A string denoting the <a href="#style">Style</a> of the contained objects.
-
-`class_name` The name of the for `RECORD` or `RECORD_PROJECTION`.
-
-### DatabaseProperty
-
-This object represents the exposed database properties for a Connection through the Avatica server.
-
-{% highlight protobuf %}
-message DatabaseProperty {
-  string name = 1;
-  repeated string functions = 2;
-}
-{% endhighlight %}
-
-`name` The name of the database property.
-
-`functions` A collection of values for the property.
-
-### Frame
-
-This object represents a batch of results, tracking the offset into the results and whether more results still exist
-to be fetched in the Avatica server.
-
-{% highlight protobuf %}
-message Frame {
-  uint64 offset = 1;
-  bool done = 2;
-  repeated Row rows = 3;
-}
-{% endhighlight %}
-
-`offset` The starting position of these `rows` in the encompassing result set.
-
-`done` A boolean denoting whether more results exist for this result set.
-
-`rows` A collection of <a href="#row">Row</a>s.
-
-### Row
-
-This object represents a row in a relational database table.
-
-{% highlight protobuf %}
-message Row {
-  repeated ColumnValue value = 1;
-}
-{% endhighlight %}
-
-`value` A collection of <a href="#columnvalue">ColumnValue</a>s, the columns in the row.
-
-### ColumnValue
-
-{% highlight protobuf %}
-message ColumnValue {
-  repeated TypedValue value = 1; // Deprecated!
-  repeated ColumnValue array_value = 2;
-  boolean has_array_value = 3;
-  TypedValue scalar_value = 4;
-}
-{% endhighlight %}
-
-`value` The pre Calcite-1.6 means of serializing <a href="#typedvalue">TypedValue</a>s. Not used anymore.
-
-`array_value` The value of this column if it is an array (not a scalar).
-
-`has_array_value` Should be set to true if `array_value` is set.
-
-`scalar_value` The value of this column if it is a scalar (not an array).
-
-### QueryState
-
-This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
-SQL or by a DatabaseMetaData operation with arguments on that operation.
-
-{% highlight protobuf %}
-message QueryState {
-  StateType type = 1;
-  string sql = 2;
-  MetaDataOperation op = 3;
-  repeated MetaDataOperationArgument args = 4;
-  bool has_args = 5;
-  bool has_sql = 6;
-  bool has_op = 7;
-}
-{% endhighlight %}
-
-`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
-
-`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
-
-`op` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
-
-`args` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
-
-`has_args` A boolean which denotes if the field `args` is provided.
-
-`has_sql` A boolean which denotes if the field `sql` is provided.
-
-`has_op` A boolean which denotes if the field `op` is provided.
-
-### Rep
-
-This enumeration represents the concrete Java type for some value.
-
-{% highlight protobuf %}
-enum Rep {
-  PRIMITIVE_BOOLEAN = 0;
-  PRIMITIVE_BYTE = 1;
-  PRIMITIVE_CHAR = 2;
-  PRIMITIVE_SHORT = 3;
-  PRIMITIVE_INT = 4;
-  PRIMITIVE_LONG = 5;
-  PRIMITIVE_FLOAT = 6;
-  PRIMITIVE_DOUBLE = 7;
-  BOOLEAN = 8;
-  BYTE = 9;
-  CHARACTER = 10;
-  SHORT = 11;
-  INTEGER = 12;
-  LONG = 13;
-  FLOAT = 14;
-  DOUBLE = 15;
-  BIG_INTEGER = 25;
-  BIG_DECIMAL = 26;
-  JAVA_SQL_TIME = 16;
-  JAVA_SQL_TIMESTAMP = 17;
-  JAVA_SQL_DATE = 18;
-  JAVA_UTIL_DATE = 19;
-  BYTE_STRING = 20;
-  STRING = 21;
-  NUMBER = 22;
-  OBJECT = 23;
-  NULL = 24;
-  ARRAY = 27;
-  STRUCT = 28;
-  MULTISET = 29;
-}
-{% endhighlight %}
-
-### RpcMetadata
-
-This object contains assorted per-call/contextual metadata returned by the Avatica server.
-
-{% highlight protobuf %}
-message RpcMetadata {
-  string server_address = 1;
-}
-{% endhighlight %}
-
-`serverAddress` The `host:port` of the server which created this object.
-
-### Signature
-
-This object represents the result of preparing a Statement in the Avatica server.
-
-{% highlight protobuf %}
-message Signature {
-  repeated ColumnMetaData columns = 1;
-  string sql = 2;
-  repeated AvaticaParameter parameters = 3;
-  CursorFactory cursor_factory = 4;
-  StatementType statementType = 5;
-}
-{% endhighlight %}
-
-`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
-
-`sql` The SQL executed.
-
-`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
-
-`cursor_factory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
-
-`statementType` The type of the statement.
-
-### StateType
-
-This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
-
-{% highlight protobuf %}
-enum StateType {
-  SQL = 0;
-  METADATA = 1;
-}
-{% endhighlight %}
-
-### StatementHandle
-
-This object encapsulates all of the information of a Statement created in the Avatica server.
-
-{% highlight protobuf %}
-message StatementHandle {
-  string connection_id = 1;
-  uint32 id = 2;
-  Signature signature = 3;
-}
-{% endhighlight %}
-
-`connection_id` The identifier of the connection to which this statement belongs.
-
-`id` The identifier of the statement.
-
-`signature` A <a href="#signature">Signature</a> object for the statement.
-
-### StatementType
-
-This message represents what kind the Statement is.
-
-{% highlight protobuf %}
-enum StatementType {
-  SELECT = 0;
-  INSERT = 1;
-  UPDATE = 2;
-  DELETE = 3;
-  UPSERT = 4;
-  MERGE = 5;
-  OTHER_DML = 6;
-  CREATE = 7;
-  DROP = 8;
-  ALTER = 9;
-  OTHER_DDL = 10;
-  CALL = 11;
-}
-{% endhighlight %}
-
-### Style
-
-This enumeration represents the generic "class" of type for a value. Defined within <a href="#cursorfactory">CursorFactory</a>.
-
-{% highlight protobuf %}
-enum Style {
-  OBJECT = 0;
-  RECORD = 1;
-  RECORD_PROJECTION = 2;
-  ARRAY = 3;
-  LIST = 4;
-  MAP = 5;
-}
-{% endhighlight %}
-
-### TypedValue
-
-This object encapsulates the type and value for a column in a row.
-
-{% highlight protobuf %}
-message TypedValue {
-  Rep type = 1;
-  bool bool_value = 2;
-  string string_value = 3;
-  sint64 number_value = 4;
-  bytes bytes_values = 5;
-  double double_value = 6;
-  bool null = 7;
-}
-{% endhighlight %}
-
-`type` A name referring to which attribute is populated with the column's value.
-
-`bool_value` A boolean value.
-
-`string_value` A character/string value.
-
-`number_value` A numeric value (non-`double`).
-
-`bytes_value` A byte-array value.
-
-`double_value` A `double` value.
-
-`null` A boolean which denotes if the value was null.
-
-### WireMessage
-
-This message wraps all `Request`s and `Response`s.
-
-{% highlight protobuf %}
-message WireMessage {
-  string name = 1;
-  bytes wrapped_message = 2;
-}
-{% endhighlight %}
-
-`name` The Java class name of the wrapped message.
-
-`wrapped_message` A serialized representation of the wrapped message of the same type specified by `name`.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/avatica_roadmap.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_roadmap.md b/avatica/site/_docs/avatica_roadmap.md
deleted file mode 100644
index 4caebd4..0000000
--- a/avatica/site/_docs/avatica_roadmap.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-layout: docs
-title: Avatica Roadmap
-sidebar_title: Roadmap
-permalink: /docs/avatica_roadmap.html
----
-
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-## Status
-
-### Implemented
-
-* Create connection, create statement, metadata, prepare, bind, execute, fetch
-* RPC using JSON over HTTP
-* Local implementation
-* Implementation over an existing JDBC driver
-* Composite RPCs (combining several requests into one round trip)
-  * Execute-Fetch
-  * Metadata-Fetch (metadata calls such as getTables return all rows)
-
-### Not implemented
-
-* ODBC
-* RPCs
-  * CloseStatement
-  * CloseConnection
-* Composite RPCs
-  * CreateStatement-Prepare
-  * CloseStatement-CloseConnection
-  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
-* Remove statements from statement table
-* DML (INSERT, UPDATE, DELETE)
-* Statement.execute applied to SELECT statement


[06/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
deleted file mode 100644
index 11a6104..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
+++ /dev/null
@@ -1,118 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Mock implementation of {@link Service}
- * that encodes its requests and responses as JSON
- * and looks up responses from a pre-defined map.
- */
-public class MockJsonService extends JsonService {
-  private final Map<String, String> map;
-
-  public MockJsonService(Map<String, String> map) {
-    this.map = map;
-  }
-
-  @Override public String apply(String request) {
-    String response = map.get(request);
-    if (response == null) {
-      throw new RuntimeException("No response for " + request);
-    }
-    return response;
-  }
-
-  /** Factory that creates a {@code MockJsonService}. */
-  public static class Factory implements Service.Factory {
-    public Service create(AvaticaConnection connection) {
-      final String connectionId = connection.id;
-      final Map<String, String> map1 = new HashMap<>();
-      try {
-        map1.put(
-            "{\"request\":\"openConnection\",\"connectionId\":\"" + connectionId + "\",\"info\":{}}",
-            "{\"response\":\"openConnection\"}");
-        map1.put(
-            "{\"request\":\"closeConnection\",\"connectionId\":\"" + connectionId + "\"}",
-            "{\"response\":\"closeConnection\"}");
-        map1.put(
-            "{\"request\":\"getSchemas\",\"catalog\":null,\"schemaPattern\":{\"s\":null}}",
-            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
-        map1.put(
-            JsonService.encode(new SchemasRequest(connectionId, null, null)),
-            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
-        map1.put(
-            JsonService.encode(
-                new TablesRequest(connectionId, null, null, null, Arrays.<String>asList())),
-            "{\"response\":\"resultSet\", updateCount: -1, firstFrame: {offset: 0, done: true, rows: []}}");
-        map1.put(
-            "{\"request\":\"createStatement\",\"connectionId\":\"" + connectionId + "\"}",
-            "{\"response\":\"createStatement\",\"id\":0}");
-        map1.put(
-            "{\"request\":\"prepareAndExecute\",\"statementId\":0,"
-                + "\"sql\":\"select * from (\\n  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)\",\"maxRowCount\":-1}",
-            "{\"response\":\"resultSet\", updateCount: -1, \"signature\": {\n"
-                + " \"columns\": [\n"
-                + "   {\"columnName\": \"C1\", \"type\": {type: \"scalar\", id: 4, rep: \"INTEGER\"}},\n"
-                + "   {\"columnName\": \"C2\", \"type\": {type: \"scalar\", id: 12, rep: \"STRING\"}}\n"
-                + " ], \"cursorFactory\": {\"style\": \"ARRAY\"}\n"
-                + "}, \"rows\": [[1, \"a\"], [null, \"b\"], [3, \"c\"]]}");
-        map1.put(
-            "{\"request\":\"prepare\",\"statementId\":0,"
-                + "\"sql\":\"select * from (\\n  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)\",\"maxRowCount\":-1}",
-            "{\"response\":\"prepare\",\"signature\": {\n"
-                + " \"columns\": [\n"
-                + "   {\"columnName\": \"C1\", \"type\": {type: \"scalar\", id: 4, rep: \"INTEGER\"}},\n"
-                + "   {\"columnName\": \"C2\", \"type\": {type: \"scalar\", id: 12, rep: \"STRING\"}}\n"
-                + " ],\n"
-                + " \"parameters\": [],\n"
-                + " \"cursorFactory\": {\"style\": \"ARRAY\"}\n"
-                + "}}");
-        map1.put(
-            "{\"request\":\"getColumns\",\"connectionId\":\"" + connectionId + "\",\"catalog\":null,\"schemaPattern\":null,"
-                + "\"tableNamePattern\":\"my_table\",\"columnNamePattern\":null}",
-            "{\"response\":\"resultSet\",\"connectionId\":\"00000000-0000-0000-0000-000000000000\",\"statementId\":-1,\"ownStatement\":true,"
-                + "\"signature\":{\"columns\":["
-                  + "{\"ordinal\":0,\"autoIncrement\":false,\"caseSensitive\":false,\"searchable\":true,\"currency\":false,\"nullable\":1,\"signed\":false,"
-                    + "\"displaySize\":40,\"label\":\"TABLE_NAME\",\"columnName\":\"TABLE_NAME\",\"schemaName\":\"\",\"precision\":0,\"scale\":0,\"tableName\":\"SYSTEM.TABLE\","
-                    + "\"catalogName\":\"\",\"type\":{\"type\":\"scalar\",\"id\":12,\"name\":\"VARCHAR\",\"rep\":\"STRING\"},\"readOnly\":true,\"writable\":false,"
-                    + "\"definitelyWritable\":false,\"columnClassName\":\"java.lang.String\"},"
-                  + "{\"ordinal\":1,\"autoIncrement\":false,\"caseSensitive\":false,\"searchable\":true,\"currency\":false,\"nullable\":1,\"signed\":true,"
-                    + "\"displaySize\":40,\"label\":\"ORDINAL_POSITION\",\"columnName\":\"ORDINAL_POSITION\",\"schemaName\":\"\",\"precision\":0,\"scale\":0,"
-                    + "\"tableName\":\"SYSTEM.TABLE\",\"catalogName\":\"\",\"type\":{\"type\":\"scalar\",\"id\":-5,\"name\":\"BIGINT\",\"rep\":\"PRIMITIVE_LONG\"},"
-                    + "\"readOnly\":true,\"writable\":false,\"definitelyWritable\":false,\"columnClassName\":\"java.lang.Long\"}"
-                + "],\"sql\":null,"
-                + "\"parameters\":[],"
-                + "\"cursorFactory\":{\"style\":\"LIST\",\"clazz\":null,\"fieldNames\":null},\"statementType\":null},"
-                + "\"firstFrame\":{\"offset\":0,\"done\":true,"
-                + "\"rows\":[[\"my_table\",10]]"
-                + "},\"updateCount\":-1}");
-      } catch (IOException e) {
-        throw new RuntimeException(e);
-      }
-      return new MockJsonService(map1);
-    }
-  }
-}
-
-// End MockJsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index 2fcb19a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
+++ /dev/null
@@ -1,144 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaParameter;
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.MetaImpl;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A mock implementation of ProtobufService for testing.
- *
- * <p>It performs no serialization of requests and responses.
- */
-public class MockProtobufService extends ProtobufService {
-
-  private final String connectionId;
-  private final Map<Request, Response> mapping;
-
-  public MockProtobufService(String connectionId) {
-    this.connectionId = connectionId;
-    this.mapping = createMapping();
-  }
-
-  private Map<Request, Response> createMapping() {
-    HashMap<Request, Response> mappings = new HashMap<>();
-
-    // Add in mappings
-
-    mappings.put(
-        new OpenConnectionRequest(connectionId, new HashMap<String, String>()),
-        new OpenConnectionResponse());
-
-    // Get the schema, no.. schema..?
-    mappings.put(
-        new SchemasRequest(connectionId, null, null),
-        // ownStatement=false just to avoid the extra close statement call.
-        new ResultSetResponse(null, 1, false, null, Meta.Frame.EMPTY, -1, null));
-
-    // Get the tables, no tables exist
-    mappings.put(new TablesRequest(connectionId, null, null, null, Collections.<String>emptyList()),
-        // ownStatement=false just to avoid the extra close statement call.
-        new ResultSetResponse(null, 150, false, null, Meta.Frame.EMPTY, -1, null));
-
-    // Create a statement, get back an id
-    mappings.put(new CreateStatementRequest("0"), new CreateStatementResponse("0", 1, null));
-
-    // Prepare and execute a query. Values and schema are returned
-    mappings.put(
-        new PrepareAndExecuteRequest(connectionId, 1,
-            "select * from (\\n values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)", -1),
-        new ResultSetResponse("0", 1, true,
-            Meta.Signature.create(
-                Arrays.<ColumnMetaData>asList(
-                    MetaImpl.columnMetaData("C1", 0, Integer.class),
-                    MetaImpl.columnMetaData("C2", 1, String.class)),
-                null, null, Meta.CursorFactory.ARRAY, Meta.StatementType.SELECT),
-            Meta.Frame.create(0, true,
-                Arrays.<Object>asList(new Object[] {1, "a"},
-                    new Object[] {null, "b"}, new Object[] {3, "c"})), -1, null));
-
-    // Prepare a query. Schema for results are returned, but no values
-    mappings.put(
-        new PrepareRequest(connectionId,
-            "select * from (\\n values(1, 'a'), (null, 'b'), (3, 'c')), as t (c1, c2)", -1),
-        new ResultSetResponse("0", 1, true,
-            Meta.Signature.create(
-                Arrays.<ColumnMetaData>asList(
-                    MetaImpl.columnMetaData("C1", 0, Integer.class),
-                    MetaImpl.columnMetaData("C2", 1, String.class)),
-                null, Collections.<AvaticaParameter>emptyList(),
-                Meta.CursorFactory.ARRAY, Meta.StatementType.SELECT),
-            null, -1, null));
-
-    mappings.put(
-        new ColumnsRequest(connectionId, null, null, "my_table", null),
-        new ResultSetResponse("00000000-0000-0000-0000-000000000000", -1, true,
-            Meta.Signature.create(
-                Arrays.<ColumnMetaData>asList(
-                    MetaImpl.columnMetaData("TABLE_NAME", 0, String.class),
-                    MetaImpl.columnMetaData("ORDINAL_POSITION", 1, Long.class)), null,
-                Collections.<AvaticaParameter>emptyList(), Meta.CursorFactory.ARRAY, null),
-            Meta.Frame.create(0, true,
-                Arrays.<Object>asList(new Object[] {new Object[]{"my_table", 10}})), -1, null));
-
-    return Collections.unmodifiableMap(mappings);
-  }
-
-  @Override public Response _apply(Request request) {
-    if (request instanceof CloseConnectionRequest) {
-      return new CloseConnectionResponse();
-    }
-
-    return dispatch(request);
-  }
-
-  /**
-   * Fetches the static response for the given request.
-   *
-   * @param request the client's request
-   * @return the appropriate response
-   * @throws RuntimeException if no mapping is found for the request
-   */
-  private Response dispatch(Request request) {
-    Response response = mapping.get(request);
-
-    if (null == response) {
-      throw new RuntimeException("Had no response mapping for " + request);
-    }
-
-    return response;
-  }
-
-  /**
-   * A factory that instantiates the mock protobuf service.
-   */
-  public static class MockProtobufServiceFactory implements Service.Factory {
-    @Override public Service create(AvaticaConnection connection) {
-      return new MockProtobufService(connection.id);
-    }
-  }
-}
-
-// End MockProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
deleted file mode 100644
index 89e380e..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufHandler.java
+++ /dev/null
@@ -1,62 +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.remote;
-
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.remote.Service.Response;
-
-import java.io.IOException;
-
-/**
- * Dispatches serialized protocol buffer messages to the provided {@link Service}
- * by converting them to the POJO Request. Returns back the serialized protocol
- * buffer response.
- */
-public class ProtobufHandler extends AbstractHandler<byte[]> {
-
-  private final ProtobufTranslation translation;
-  private final MetricsSystem metrics;
-  private final Timer serializationTimer;
-
-  public ProtobufHandler(Service service, ProtobufTranslation translation, MetricsSystem metrics) {
-    super(service);
-    this.translation = translation;
-    this.metrics = metrics;
-    this.serializationTimer = this.metrics.getTimer(
-        MetricsHelper.concat(ProtobufHandler.class, HANDLER_SERIALIZATION_METRICS_NAME));
-  }
-
-  @Override public HandlerResponse<byte[]> apply(byte[] requestBytes) {
-    return super.apply(requestBytes);
-  }
-
-  @Override Service.Request decode(byte[] serializedRequest) throws IOException {
-    try (final Context ctx = serializationTimer.start()) {
-      return translation.parseRequest(serializedRequest);
-    }
-  }
-
-  @Override byte[] encode(Response response) throws IOException {
-    try (final Context ctx = serializationTimer.start()) {
-      return translation.serializeResponse(response);
-    }
-  }
-}
-
-// End ProtobufHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
deleted file mode 100644
index 56ba125..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
+++ /dev/null
@@ -1,132 +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.remote;
-
-import com.google.protobuf.Message;
-
-/**
- * Service implementation that encodes requests and responses as protocol buffers.
- */
-public abstract class ProtobufService extends AbstractService {
-
-  /**
-   * Derived class should implement this method to transport requests and
-   * responses to and from the peer service.
-   */
-  public abstract Response _apply(Request request);
-
-  @Override SerializationType getSerializationType() {
-    return SerializationType.PROTOBUF;
-  }
-
-  @Override public ResultSetResponse apply(CatalogsRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public ResultSetResponse apply(SchemasRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public ResultSetResponse apply(TablesRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public ResultSetResponse apply(TableTypesRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public ResultSetResponse apply(TypeInfoRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public ResultSetResponse apply(ColumnsRequest request) {
-    return finagle((ResultSetResponse) _apply(request));
-  }
-
-  @Override public PrepareResponse apply(PrepareRequest request) {
-    return finagle((PrepareResponse) _apply(request));
-  }
-
-  @Override public ExecuteResponse apply(PrepareAndExecuteRequest request) {
-    return finagle((ExecuteResponse) _apply(request));
-  }
-
-  @Override public FetchResponse apply(FetchRequest request) {
-    return (FetchResponse) _apply(request);
-  }
-
-  @Override public CreateStatementResponse apply(CreateStatementRequest request) {
-    return (CreateStatementResponse) _apply(request);
-  }
-
-  @Override public CloseStatementResponse apply(CloseStatementRequest request) {
-    return (CloseStatementResponse) _apply(request);
-  }
-
-  @Override public OpenConnectionResponse apply(OpenConnectionRequest request) {
-    return (OpenConnectionResponse) _apply(request);
-  }
-
-  @Override public CloseConnectionResponse apply(CloseConnectionRequest request) {
-    return (CloseConnectionResponse) _apply(request);
-  }
-
-  @Override public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
-    return (ConnectionSyncResponse) _apply(request);
-  }
-
-  @Override public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
-    return (DatabasePropertyResponse) _apply(request);
-  }
-
-  @Override public ExecuteResponse apply(ExecuteRequest request) {
-    return finagle((ExecuteResponse) _apply(request));
-  }
-
-  @Override public SyncResultsResponse apply(SyncResultsRequest request) {
-    return (SyncResultsResponse) _apply(request);
-  }
-
-  @Override public CommitResponse apply(CommitRequest request) {
-    return (CommitResponse) _apply(request);
-  }
-
-  @Override public RollbackResponse apply(RollbackRequest request) {
-    return (RollbackResponse) _apply(request);
-  }
-
-  /**
-   * Checks if the provided {@link Message} is an instance of the Class given by
-   * <code>expectedType</code>. Throws an IllegalArgumentException if the message is not of the
-   * expected type, otherwise, it returns the message cast as the expected type.
-   *
-   * @param msg A Protocol Buffer message.
-   * @param expectedType The expected type of the Protocol Buffer message.
-   * @return The msg cast to the concrete Message type.
-   * @throws IllegalArgumentException If the type of the message is not the expectedType.
-   */
-  public static <T extends Message> T castProtobufMessage(Message msg, Class<T> expectedType) {
-    if (!expectedType.isInstance(msg)) {
-      throw new IllegalArgumentException("Expected instance of " + expectedType.getName()
-          + ", but got " + msg.getClass().getName());
-    }
-
-    return expectedType.cast(msg);
-  }
-}
-
-// End ProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
deleted file mode 100644
index 7142d59..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslation.java
+++ /dev/null
@@ -1,64 +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.remote;
-
-import org.apache.calcite.avatica.remote.Service.Request;
-import org.apache.calcite.avatica.remote.Service.Response;
-
-import java.io.IOException;
-
-/**
- * Generic interface to support parsing of serialized protocol buffers between client and server.
- */
-public interface ProtobufTranslation {
-
-  /**
-   * Serializes a {@link Response} as a protocol buffer.
-   *
-   * @param response The response to serialize
-   * @throws IOException If there are errors during serialization
-   */
-  byte[] serializeResponse(Response response) throws IOException;
-
-  /**
-   * Serializes a {@link Request} as a protocol buffer.
-   *
-   * @param request The request to serialize
-   * @throws IOException If there are errors during serialization
-   */
-  byte[] serializeRequest(Request request) throws IOException;
-
-  /**
-   * Parses a serialized protocol buffer request into a {@link Request}.
-   *
-   * @param bytes Serialized protocol buffer request from client
-   * @return A Request object for the given bytes
-   * @throws IOException If the protocol buffer cannot be deserialized
-   */
-  Request parseRequest(byte[] bytes) throws IOException;
-
-  /**
-   * Parses a serialized protocol buffer response into a {@link Response}.
-   *
-   * @param bytes Serialized protocol buffer request from server
-   * @return The Response object for the given bytes
-   * @throws IOException If the protocol buffer cannot be deserialized
-   */
-  Response parseResponse(byte[] bytes) throws IOException;
-}
-
-// End ProtobufTranslation.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
deleted file mode 100644
index 80d2b22..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
+++ /dev/null
@@ -1,354 +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.remote;
-
-import org.apache.calcite.avatica.proto.Common.WireMessage;
-import org.apache.calcite.avatica.proto.Requests.CatalogsRequest;
-import org.apache.calcite.avatica.proto.Requests.CloseConnectionRequest;
-import org.apache.calcite.avatica.proto.Requests.CloseStatementRequest;
-import org.apache.calcite.avatica.proto.Requests.ColumnsRequest;
-import org.apache.calcite.avatica.proto.Requests.CommitRequest;
-import org.apache.calcite.avatica.proto.Requests.ConnectionSyncRequest;
-import org.apache.calcite.avatica.proto.Requests.CreateStatementRequest;
-import org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest;
-import org.apache.calcite.avatica.proto.Requests.ExecuteRequest;
-import org.apache.calcite.avatica.proto.Requests.FetchRequest;
-import org.apache.calcite.avatica.proto.Requests.OpenConnectionRequest;
-import org.apache.calcite.avatica.proto.Requests.PrepareAndExecuteRequest;
-import org.apache.calcite.avatica.proto.Requests.PrepareRequest;
-import org.apache.calcite.avatica.proto.Requests.RollbackRequest;
-import org.apache.calcite.avatica.proto.Requests.SchemasRequest;
-import org.apache.calcite.avatica.proto.Requests.SyncResultsRequest;
-import org.apache.calcite.avatica.proto.Requests.TableTypesRequest;
-import org.apache.calcite.avatica.proto.Requests.TablesRequest;
-import org.apache.calcite.avatica.proto.Requests.TypeInfoRequest;
-import org.apache.calcite.avatica.proto.Responses.CloseConnectionResponse;
-import org.apache.calcite.avatica.proto.Responses.CloseStatementResponse;
-import org.apache.calcite.avatica.proto.Responses.CommitResponse;
-import org.apache.calcite.avatica.proto.Responses.ConnectionSyncResponse;
-import org.apache.calcite.avatica.proto.Responses.CreateStatementResponse;
-import org.apache.calcite.avatica.proto.Responses.DatabasePropertyResponse;
-import org.apache.calcite.avatica.proto.Responses.ErrorResponse;
-import org.apache.calcite.avatica.proto.Responses.ExecuteResponse;
-import org.apache.calcite.avatica.proto.Responses.FetchResponse;
-import org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse;
-import org.apache.calcite.avatica.proto.Responses.PrepareResponse;
-import org.apache.calcite.avatica.proto.Responses.ResultSetResponse;
-import org.apache.calcite.avatica.proto.Responses.RollbackResponse;
-import org.apache.calcite.avatica.proto.Responses.RpcMetadata;
-import org.apache.calcite.avatica.proto.Responses.SyncResultsResponse;
-import org.apache.calcite.avatica.remote.Service.Request;
-import org.apache.calcite.avatica.remote.Service.Response;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.HBaseZeroCopyByteString;
-import com.google.protobuf.Message;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-/**
- * Implementation of {@link ProtobufTranslationImpl} that translates
- * protobuf requests to POJO requests.
- */
-public class ProtobufTranslationImpl implements ProtobufTranslation {
-
-  // Extremely ugly mapping of PB class name into a means to convert it to the POJO
-  private static final Map<String, RequestTranslator> REQUEST_PARSERS;
-  private static final Map<String, ResponseTranslator> RESPONSE_PARSERS;
-  private static final Map<Class<?>, ByteString> MESSAGE_CLASSES;
-
-  static {
-    Map<String, RequestTranslator> reqParsers = new ConcurrentHashMap<>();
-    reqParsers.put(CatalogsRequest.class.getName(),
-        new RequestTranslator(CatalogsRequest.parser(), new Service.CatalogsRequest()));
-    reqParsers.put(OpenConnectionRequest.class.getName(),
-        new RequestTranslator(OpenConnectionRequest.parser(), new Service.OpenConnectionRequest()));
-    reqParsers.put(CloseConnectionRequest.class.getName(),
-        new RequestTranslator(CloseConnectionRequest.parser(),
-          new Service.CloseConnectionRequest()));
-    reqParsers.put(CloseStatementRequest.class.getName(),
-        new RequestTranslator(CloseStatementRequest.parser(), new Service.CloseStatementRequest()));
-    reqParsers.put(ColumnsRequest.class.getName(),
-        new RequestTranslator(ColumnsRequest.parser(), new Service.ColumnsRequest()));
-    reqParsers.put(ConnectionSyncRequest.class.getName(),
-        new RequestTranslator(ConnectionSyncRequest.parser(), new Service.ConnectionSyncRequest()));
-    reqParsers.put(CreateStatementRequest.class.getName(),
-        new RequestTranslator(CreateStatementRequest.parser(),
-          new Service.CreateStatementRequest()));
-    reqParsers.put(DatabasePropertyRequest.class.getName(),
-        new RequestTranslator(DatabasePropertyRequest.parser(),
-            new Service.DatabasePropertyRequest()));
-    reqParsers.put(FetchRequest.class.getName(),
-        new RequestTranslator(FetchRequest.parser(), new Service.FetchRequest()));
-    reqParsers.put(PrepareAndExecuteRequest.class.getName(),
-        new RequestTranslator(PrepareAndExecuteRequest.parser(),
-            new Service.PrepareAndExecuteRequest()));
-    reqParsers.put(PrepareRequest.class.getName(),
-        new RequestTranslator(PrepareRequest.parser(), new Service.PrepareRequest()));
-    reqParsers.put(SchemasRequest.class.getName(),
-        new RequestTranslator(SchemasRequest.parser(), new Service.SchemasRequest()));
-    reqParsers.put(TablesRequest.class.getName(),
-        new RequestTranslator(TablesRequest.parser(), new Service.TablesRequest()));
-    reqParsers.put(TableTypesRequest.class.getName(),
-        new RequestTranslator(TableTypesRequest.parser(), new Service.TableTypesRequest()));
-    reqParsers.put(TypeInfoRequest.class.getName(),
-        new RequestTranslator(TypeInfoRequest.parser(), new Service.TypeInfoRequest()));
-    reqParsers.put(ExecuteRequest.class.getName(),
-        new RequestTranslator(ExecuteRequest.parser(), new Service.ExecuteRequest()));
-    reqParsers.put(SyncResultsRequest.class.getName(),
-        new RequestTranslator(SyncResultsRequest.parser(), new Service.SyncResultsRequest()));
-    reqParsers.put(CommitRequest.class.getName(),
-        new RequestTranslator(CommitRequest.parser(), new Service.CommitRequest()));
-    reqParsers.put(RollbackRequest.class.getName(),
-        new RequestTranslator(RollbackRequest.parser(), new Service.RollbackRequest()));
-
-    REQUEST_PARSERS = Collections.unmodifiableMap(reqParsers);
-
-    Map<String, ResponseTranslator> respParsers = new ConcurrentHashMap<>();
-    respParsers.put(OpenConnectionResponse.class.getName(),
-        new ResponseTranslator(OpenConnectionResponse.parser(),
-            new Service.OpenConnectionResponse()));
-    respParsers.put(CloseConnectionResponse.class.getName(),
-        new ResponseTranslator(CloseConnectionResponse.parser(),
-            new Service.CloseConnectionResponse()));
-    respParsers.put(CloseStatementResponse.class.getName(),
-        new ResponseTranslator(CloseStatementResponse.parser(),
-            new Service.CloseStatementResponse()));
-    respParsers.put(ConnectionSyncResponse.class.getName(),
-        new ResponseTranslator(ConnectionSyncResponse.parser(),
-            new Service.ConnectionSyncResponse()));
-    respParsers.put(CreateStatementResponse.class.getName(),
-        new ResponseTranslator(CreateStatementResponse.parser(),
-            new Service.CreateStatementResponse()));
-    respParsers.put(DatabasePropertyResponse.class.getName(),
-        new ResponseTranslator(DatabasePropertyResponse.parser(),
-            new Service.DatabasePropertyResponse()));
-    respParsers.put(ExecuteResponse.class.getName(),
-        new ResponseTranslator(ExecuteResponse.parser(), new Service.ExecuteResponse()));
-    respParsers.put(FetchResponse.class.getName(),
-        new ResponseTranslator(FetchResponse.parser(), new Service.FetchResponse()));
-    respParsers.put(PrepareResponse.class.getName(),
-        new ResponseTranslator(PrepareResponse.parser(), new Service.PrepareResponse()));
-    respParsers.put(ResultSetResponse.class.getName(),
-        new ResponseTranslator(ResultSetResponse.parser(), new Service.ResultSetResponse()));
-    respParsers.put(ErrorResponse.class.getName(),
-        new ResponseTranslator(ErrorResponse.parser(), new Service.ErrorResponse()));
-    respParsers.put(SyncResultsResponse.class.getName(),
-        new ResponseTranslator(SyncResultsResponse.parser(), new Service.SyncResultsResponse()));
-    respParsers.put(RpcMetadata.class.getName(),
-        new ResponseTranslator(RpcMetadata.parser(), new RpcMetadataResponse()));
-    respParsers.put(CommitResponse.class.getName(),
-        new ResponseTranslator(CommitResponse.parser(), new Service.CommitResponse()));
-    respParsers.put(RollbackResponse.class.getName(),
-        new ResponseTranslator(RollbackResponse.parser(), new Service.RollbackResponse()));
-
-    RESPONSE_PARSERS = Collections.unmodifiableMap(respParsers);
-
-    Map<Class<?>, ByteString> messageClassNames = new ConcurrentHashMap<>();
-    for (Class<?> msgClz : getAllMessageClasses()) {
-      messageClassNames.put(msgClz, wrapClassName(msgClz));
-    }
-    MESSAGE_CLASSES = Collections.unmodifiableMap(messageClassNames);
-  }
-
-  private static List<Class<?>> getAllMessageClasses() {
-    List<Class<?>> messageClasses = new ArrayList<>();
-    messageClasses.add(CatalogsRequest.class);
-    messageClasses.add(CloseConnectionRequest.class);
-    messageClasses.add(CloseStatementRequest.class);
-    messageClasses.add(ColumnsRequest.class);
-    messageClasses.add(CommitRequest.class);
-    messageClasses.add(ConnectionSyncRequest.class);
-    messageClasses.add(CreateStatementRequest.class);
-    messageClasses.add(DatabasePropertyRequest.class);
-    messageClasses.add(ExecuteRequest.class);
-    messageClasses.add(FetchRequest.class);
-    messageClasses.add(OpenConnectionRequest.class);
-    messageClasses.add(PrepareAndExecuteRequest.class);
-    messageClasses.add(PrepareRequest.class);
-    messageClasses.add(RollbackRequest.class);
-    messageClasses.add(SchemasRequest.class);
-    messageClasses.add(SyncResultsRequest.class);
-    messageClasses.add(TableTypesRequest.class);
-    messageClasses.add(TablesRequest.class);
-    messageClasses.add(TypeInfoRequest.class);
-    messageClasses.add(CloseConnectionResponse.class);
-    messageClasses.add(CloseStatementResponse.class);
-    messageClasses.add(CommitResponse.class);
-    messageClasses.add(ConnectionSyncResponse.class);
-    messageClasses.add(CreateStatementResponse.class);
-    messageClasses.add(DatabasePropertyResponse.class);
-    messageClasses.add(ErrorResponse.class);
-    messageClasses.add(ExecuteResponse.class);
-    messageClasses.add(FetchResponse.class);
-    messageClasses.add(OpenConnectionResponse.class);
-    messageClasses.add(PrepareResponse.class);
-    messageClasses.add(ResultSetResponse.class);
-    messageClasses.add(RollbackResponse.class);
-    messageClasses.add(RpcMetadata.class);
-    messageClasses.add(SyncResultsResponse.class);
-
-    return messageClasses;
-  }
-
-  private static ByteString wrapClassName(Class<?> clz) {
-    return HBaseZeroCopyByteString.wrap(clz.getName().getBytes(UTF_8));
-  }
-
-  private final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer =
-      new ThreadLocal<UnsynchronizedBuffer>() {
-        @Override protected UnsynchronizedBuffer initialValue() {
-          return new UnsynchronizedBuffer();
-        }
-      };
-
-  /**
-   * Fetches the concrete message's Parser implementation.
-   *
-   * @param className The protocol buffer class name
-   * @return The Parser for the class
-   * @throws IllegalArgumentException If the argument is null or if a Parser for the given
-   *     class name is not found.
-   */
-  public static RequestTranslator getParserForRequest(String className) {
-    if (null == className) {
-      throw new IllegalArgumentException("Cannot fetch parser for null class name");
-    }
-
-    RequestTranslator translator = REQUEST_PARSERS.get(className);
-    if (null == translator) {
-      throw new IllegalArgumentException("Cannot find parser for " + className);
-    }
-
-    return translator;
-  }
-
-  /**
-   * Fetches the concrete message's Parser implementation.
-   *
-   * @param className The protocol buffer class name
-   * @return The Parser for the class
-   * @throws IllegalArgumentException If the argument is null or if a Parser for the given
-   *     class name is not found.
-   */
-  public static ResponseTranslator getParserForResponse(String className) {
-    if (null == className) {
-      throw new IllegalArgumentException("Cannot fetch parser for null class name");
-    }
-
-    ResponseTranslator translator = RESPONSE_PARSERS.get(className);
-    if (null == translator) {
-      throw new IllegalArgumentException("Cannot find parser for " + className);
-    }
-
-    return translator;
-  }
-
-  @Override public byte[] serializeResponse(Response response) throws IOException {
-    // Avoid BAOS for its synchronized write methods, we don't need that concurrency control
-    UnsynchronizedBuffer out = threadLocalBuffer.get();
-    try {
-      Message responseMsg = response.serialize();
-      serializeMessage(out, responseMsg);
-      return out.toArray();
-    } finally {
-      out.reset();
-    }
-  }
-
-  @Override public byte[] serializeRequest(Request request) throws IOException {
-    // Avoid BAOS for its synchronized write methods, we don't need that concurrency control
-    UnsynchronizedBuffer out = threadLocalBuffer.get();
-    try {
-      Message requestMsg = request.serialize();
-      serializeMessage(out, requestMsg);
-      return out.toArray();
-    } finally {
-      out.reset();
-    }
-  }
-
-  void serializeMessage(OutputStream out, Message msg) throws IOException {
-    // Serialize the protobuf message
-    UnsynchronizedBuffer buffer = threadLocalBuffer.get();
-    ByteString serializedMsg;
-    try {
-      msg.writeTo(buffer);
-      // Make a bytestring from it
-      serializedMsg = HBaseZeroCopyByteString.wrap(buffer.toArray());
-    } finally {
-      buffer.reset();
-    }
-
-    // Wrap the serialized message in a WireMessage
-    WireMessage wireMsg = WireMessage.newBuilder().setNameBytes(getClassNameBytes(msg.getClass()))
-        .setWrappedMessage(serializedMsg).build();
-
-    // Write the WireMessage to the provided OutputStream
-    wireMsg.writeTo(out);
-  }
-
-  ByteString getClassNameBytes(Class<?> clz) {
-    ByteString byteString = MESSAGE_CLASSES.get(clz);
-    if (null == byteString) {
-      throw new IllegalArgumentException("Missing ByteString for " + clz.getName());
-    }
-    return byteString;
-  }
-
-  @Override public Request parseRequest(byte[] bytes) throws IOException {
-    ByteString byteString = HBaseZeroCopyByteString.wrap(bytes);
-    CodedInputStream inputStream = byteString.newCodedInput();
-    // Enable aliasing to avoid an extra copy to get at the serialized Request inside of the
-    // WireMessage.
-    inputStream.enableAliasing(true);
-    WireMessage wireMsg = WireMessage.parseFrom(inputStream);
-
-    String serializedMessageClassName = wireMsg.getName();
-    RequestTranslator translator = getParserForRequest(serializedMessageClassName);
-
-    // The ByteString should be logical offsets into the original byte array
-    return translator.transform(wireMsg.getWrappedMessage());
-  }
-
-  @Override public Response parseResponse(byte[] bytes) throws IOException {
-    ByteString byteString = HBaseZeroCopyByteString.wrap(bytes);
-    CodedInputStream inputStream = byteString.newCodedInput();
-    // Enable aliasing to avoid an extra copy to get at the serialized Response inside of the
-    // WireMessage.
-    inputStream.enableAliasing(true);
-    WireMessage wireMsg = WireMessage.parseFrom(inputStream);
-
-    String serializedMessageClassName = wireMsg.getName();
-    ResponseTranslator translator = getParserForResponse(serializedMessageClassName);
-
-    return translator.transform(wireMsg.getWrappedMessage());
-  }
-}
-
-// End ProtobufTranslationImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
deleted file mode 100644
index 463985a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ /dev/null
@@ -1,395 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaConnection.CallableWithoutException;
-import org.apache.calcite.avatica.AvaticaParameter;
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.MetaImpl;
-import org.apache.calcite.avatica.MissingResultsException;
-import org.apache.calcite.avatica.NoSuchStatementException;
-import org.apache.calcite.avatica.QueryState;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.Meta} for the remote
- * driver.
- */
-class RemoteMeta extends MetaImpl {
-  final Service service;
-  final Map<String, ConnectionPropertiesImpl> propsMap = new HashMap<>();
-  private Map<DatabaseProperty, Object> databaseProperties;
-
-  public RemoteMeta(AvaticaConnection connection, Service service) {
-    super(connection);
-    this.service = service;
-  }
-
-  private MetaResultSet toResultSet(Class clazz,
-      Service.ResultSetResponse response) {
-    if (response.updateCount != -1) {
-      return MetaResultSet.count(response.connectionId, response.statementId,
-          response.updateCount);
-    }
-    Signature signature0 = response.signature;
-    if (signature0 == null) {
-      final List<ColumnMetaData> columns =
-          clazz == null
-              ? Collections.<ColumnMetaData>emptyList()
-              : fieldMetaData(clazz).columns;
-      signature0 = Signature.create(columns,
-          "?", Collections.<AvaticaParameter>emptyList(), CursorFactory.ARRAY,
-          Meta.StatementType.SELECT);
-    }
-    return MetaResultSet.create(response.connectionId, response.statementId,
-        response.ownStatement, signature0, response.firstFrame);
-  }
-
-  @Override public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
-    synchronized (this) {
-      // Compute map on first use, and cache
-      if (databaseProperties == null) {
-        databaseProperties =
-            service.apply(new Service.DatabasePropertyRequest(ch.id)).map;
-      }
-      return databaseProperties;
-    }
-  }
-
-  @Override public StatementHandle createStatement(final ConnectionHandle ch) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<StatementHandle>() {
-          public StatementHandle call() {
-            // sync connection state if necessary
-            connectionSync(ch, new ConnectionPropertiesImpl());
-            final Service.CreateStatementResponse response =
-                service.apply(new Service.CreateStatementRequest(ch.id));
-            return new StatementHandle(response.connectionId, response.statementId, null);
-          }
-        });
-  }
-
-  @Override public void closeStatement(final StatementHandle h) {
-    connection.invokeWithRetries(
-        new CallableWithoutException<Void>() {
-          public Void call() {
-            final Service.CloseStatementResponse response =
-                service.apply(
-                    new Service.CloseStatementRequest(h.connectionId, h.id));
-            return null;
-          }
-        });
-  }
-
-  @Override public void openConnection(final ConnectionHandle ch, final Map<String, String> info) {
-    connection.invokeWithRetries(
-        new CallableWithoutException<Void>() {
-          public Void call() {
-            final Service.OpenConnectionResponse response =
-                service.apply(new Service.OpenConnectionRequest(ch.id, info));
-            return null;
-          }
-        });
-  }
-
-  @Override public void closeConnection(final ConnectionHandle ch) {
-    connection.invokeWithRetries(
-        new CallableWithoutException<Void>() {
-          public Void call() {
-            final Service.CloseConnectionResponse response =
-                service.apply(new Service.CloseConnectionRequest(ch.id));
-            propsMap.remove(ch.id);
-            return null;
-          }
-        });
-  }
-
-  @Override public ConnectionProperties connectionSync(final ConnectionHandle ch,
-      final ConnectionProperties connProps) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<ConnectionProperties>() {
-          public ConnectionProperties call() {
-            ConnectionPropertiesImpl localProps = propsMap.get(ch.id);
-            if (localProps == null) {
-              localProps = new ConnectionPropertiesImpl();
-              localProps.setDirty(true);
-              propsMap.put(ch.id, localProps);
-            }
-
-            // Only make an RPC if necessary. RPC is necessary when we have local changes that need
-            // flushed to the server (be sure to introduce any new changes from connProps before
-            // checking AND when connProps.isEmpty() (meaning, this was a request for a value, not
-            // overriding a value). Otherwise, accumulate the change locally and return immediately.
-            if (localProps.merge(connProps).isDirty() && connProps.isEmpty()) {
-              final Service.ConnectionSyncResponse response = service.apply(
-                  new Service.ConnectionSyncRequest(ch.id, localProps));
-              propsMap.put(ch.id, (ConnectionPropertiesImpl) response.connProps);
-              return response.connProps;
-            } else {
-              return localProps;
-            }
-          }
-        });
-  }
-
-  @Override public MetaResultSet getCatalogs(final ConnectionHandle ch) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(new Service.CatalogsRequest(ch.id));
-            return toResultSet(MetaCatalog.class, response);
-          }
-        });
-  }
-
-  @Override public MetaResultSet getSchemas(final ConnectionHandle ch, final String catalog,
-      final Pat schemaPattern) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(
-                    new Service.SchemasRequest(ch.id, catalog, schemaPattern.s));
-            return toResultSet(MetaSchema.class, response);
-          }
-        });
-  }
-
-  @Override public MetaResultSet getTables(final ConnectionHandle ch, final String catalog,
-      final Pat schemaPattern, final Pat tableNamePattern, final List<String> typeList) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(
-                    new Service.TablesRequest(ch.id, catalog, schemaPattern.s,
-                        tableNamePattern.s, typeList));
-            return toResultSet(MetaTable.class, response);
-          }
-        });
-  }
-
-  @Override public MetaResultSet getTableTypes(final ConnectionHandle ch) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(new Service.TableTypesRequest(ch.id));
-            return toResultSet(MetaTableType.class, response);
-          }
-        });
-  }
-
-  @Override public MetaResultSet getTypeInfo(final ConnectionHandle ch) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(new Service.TypeInfoRequest(ch.id));
-            return toResultSet(MetaTypeInfo.class, response);
-          }
-        });
-  }
-
-  @Override public MetaResultSet getColumns(final ConnectionHandle ch, final String catalog,
-      final Pat schemaPattern, final Pat tableNamePattern, final Pat columnNamePattern) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<MetaResultSet>() {
-          public MetaResultSet call() {
-            final Service.ResultSetResponse response =
-                service.apply(
-                    new Service.ColumnsRequest(ch.id, catalog, schemaPattern.s,
-                        tableNamePattern.s, columnNamePattern.s));
-            return toResultSet(MetaColumn.class, response);
-          }
-        });
-  }
-
-  @Override public StatementHandle prepare(final ConnectionHandle ch, final String sql,
-      final long maxRowCount) {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<StatementHandle>() {
-          public StatementHandle call() {
-            connectionSync(ch,
-                new ConnectionPropertiesImpl()); // sync connection state if necessary
-            final Service.PrepareResponse response = service.apply(
-                new Service.PrepareRequest(ch.id, sql, maxRowCount));
-            return response.statement;
-          }
-        });
-  }
-
-  @Override public ExecuteResult prepareAndExecute(final StatementHandle h, final String sql,
-      final long maxRowCount, final PrepareCallback callback) throws NoSuchStatementException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ExecuteResult>() {
-            public ExecuteResult call() {
-              // sync connection state if necessary
-              connectionSync(new ConnectionHandle(h.connectionId), new ConnectionPropertiesImpl());
-              final Service.ExecuteResponse response;
-              try {
-                synchronized (callback.getMonitor()) {
-                  callback.clear();
-                  response = service.apply(
-                      new Service.PrepareAndExecuteRequest(h.connectionId,
-                          h.id, sql, maxRowCount));
-                  if (response.missingStatement) {
-                    throw new RuntimeException(new NoSuchStatementException(h));
-                  }
-                  if (response.results.size() > 0) {
-                    final Service.ResultSetResponse result = response.results.get(0);
-                    callback.assign(result.signature, result.firstFrame,
-                        result.updateCount);
-                  }
-                }
-                callback.execute();
-                List<MetaResultSet> metaResultSets = new ArrayList<>();
-                for (Service.ResultSetResponse result : response.results) {
-                  metaResultSets.add(toResultSet(null, result));
-                }
-                return new ExecuteResult(metaResultSets);
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof NoSuchStatementException) {
-        throw (NoSuchStatementException) cause;
-      }
-      throw e;
-    }
-  }
-
-  @Override public Frame fetch(final StatementHandle h, final long offset,
-      final int fetchMaxRowCount) throws NoSuchStatementException, MissingResultsException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<Frame>() {
-            public Frame call() {
-              final Service.FetchResponse response =
-                  service.apply(
-                      new Service.FetchRequest(h.connectionId, h.id, offset, fetchMaxRowCount));
-              if (response.missingStatement) {
-                throw new RuntimeException(new NoSuchStatementException(h));
-              }
-              if (response.missingResults) {
-                throw new RuntimeException(new MissingResultsException(h));
-              }
-              return response.frame;
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof NoSuchStatementException) {
-        throw (NoSuchStatementException) cause;
-      } else if (cause instanceof MissingResultsException) {
-        throw (MissingResultsException) cause;
-      }
-      throw e;
-    }
-  }
-
-  @Override public ExecuteResult execute(final StatementHandle h,
-      final List<TypedValue> parameterValues, final long maxRowCount)
-      throws NoSuchStatementException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ExecuteResult>() {
-            public ExecuteResult call() {
-              final Service.ExecuteResponse response = service.apply(
-                  new Service.ExecuteRequest(h, parameterValues, maxRowCount));
-
-              if (response.missingStatement) {
-                throw new RuntimeException(new NoSuchStatementException(h));
-              }
-
-              List<MetaResultSet> metaResultSets = new ArrayList<>();
-              for (Service.ResultSetResponse result : response.results) {
-                metaResultSets.add(toResultSet(null, result));
-              }
-
-              return new ExecuteResult(metaResultSets);
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof NoSuchStatementException) {
-        throw (NoSuchStatementException) cause;
-      }
-      throw e;
-    }
-  }
-
-  @Override public boolean syncResults(final StatementHandle h, final QueryState state,
-      final long offset) throws NoSuchStatementException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<Boolean>() {
-            public Boolean call() {
-              final Service.SyncResultsResponse response =
-                  service.apply(
-                      new Service.SyncResultsRequest(h.connectionId, h.id, state, offset));
-              if (response.missingStatement) {
-                throw new RuntimeException(new NoSuchStatementException(h));
-              }
-              return response.moreResults;
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof NoSuchStatementException) {
-        throw (NoSuchStatementException) cause;
-      }
-      throw e;
-    }
-  }
-
-  @Override public void commit(final ConnectionHandle ch) {
-    connection.invokeWithRetries(new CallableWithoutException<Void>() {
-      public Void call() {
-        final Service.CommitResponse response =
-            service.apply(new Service.CommitRequest(ch.id));
-        return null;
-      }
-    });
-  }
-
-  @Override public void rollback(final ConnectionHandle ch) {
-    connection.invokeWithRetries(new CallableWithoutException<Void>() {
-      public Void call() {
-        final Service.RollbackResponse response =
-            service.apply(new Service.RollbackRequest(ch.id));
-        return null;
-      }
-    });
-  }
-}
-
-// End RemoteMeta.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
deleted file mode 100644
index 828513a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
+++ /dev/null
@@ -1,53 +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.remote;
-
-import java.io.IOException;
-
-/**
- * ProtobufService implementation that queries against a remote implementation, using
- * protocol buffers as the serialized form.
- */
-public class RemoteProtobufService extends ProtobufService {
-  private final AvaticaHttpClient client;
-  private final ProtobufTranslation translation;
-
-  public RemoteProtobufService(AvaticaHttpClient client, ProtobufTranslation translation) {
-    this.client = client;
-    this.translation = translation;
-  }
-
-  @Override public Response _apply(Request request) {
-    final Response resp;
-    try {
-      byte[] response = client.send(translation.serializeRequest(request));
-      resp = translation.parseResponse(response);
-    } catch (IOException e) {
-      // Not a protobuf that we could parse.
-      throw new RuntimeException(e);
-    }
-
-    // The server had an error, throw an Exception for that.
-    if (resp instanceof ErrorResponse) {
-      throw ((ErrorResponse) resp).toException();
-    }
-
-    return resp;
-  }
-}
-
-// End RemoteProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
deleted file mode 100644
index d4828b5..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
+++ /dev/null
@@ -1,39 +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.remote;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.remote.Service}
- * that translates requests into JSON and sends them to a remote server,
- * usually an HTTP server.
- */
-public class RemoteService extends JsonService {
-  private final AvaticaHttpClient client;
-
-  public RemoteService(AvaticaHttpClient client) {
-    this.client = client;
-  }
-
-  @Override public String apply(String request) {
-    byte[] response = client.send(request.getBytes(StandardCharsets.UTF_8));
-    return new String(response, StandardCharsets.UTF_8);
-  }
-}
-
-// End RemoteService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
deleted file mode 100644
index 417c6ed..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RequestTranslator.java
+++ /dev/null
@@ -1,45 +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.remote;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Message;
-import com.google.protobuf.Parser;
-
-/**
- * Encapsulate the logic of transforming a protobuf Request message into the Avatica POJO request.
- */
-public class RequestTranslator {
-
-  private final Parser<? extends Message> parser;
-  private final Service.Request impl;
-
-  public RequestTranslator(Parser<? extends Message> parser, Service.Request impl) {
-    this.parser = parser;
-    this.impl = impl;
-  }
-
-  public Service.Request transform(ByteString serializedMessage) throws
-      InvalidProtocolBufferException {
-    // This should already be an aliased CodedInputStream from the WireMessage parsing.
-    Message msg = parser.parseFrom(serializedMessage.newCodedInput());
-    return impl.deserialize(msg);
-  }
-}
-
-// End RequestTranslator.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
deleted file mode 100644
index 0311e13..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/ResponseTranslator.java
+++ /dev/null
@@ -1,44 +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.remote;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Message;
-import com.google.protobuf.Parser;
-
-/**
- * Encapsulate the logic of transforming a protobuf Response message into the Avatica POJO Response.
- */
-public class ResponseTranslator {
-
-  private final Parser<? extends Message> parser;
-  private final Service.Response impl;
-
-  public ResponseTranslator(Parser<? extends Message> parser, Service.Response impl) {
-    this.parser = parser;
-    this.impl = impl;
-  }
-
-  public Service.Response transform(ByteString serializedMessage) throws
-      InvalidProtocolBufferException {
-    Message msg = parser.parseFrom(serializedMessage);
-    return impl.deserialize(msg);
-  }
-}
-
-// End ResponseTranslator.java


[56/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/history.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/history.md b/avatica/site/_docs/history.md
index d46bfc8..f5e249e 100644
--- a/avatica/site/_docs/history.md
+++ b/avatica/site/_docs/history.md
@@ -42,2302 +42,7 @@ differences as some the JUL logging levels do not exist in SLF4J: `FINE`,
 `FINER`, and `FINEST`, specifically. To deal with this, `FINE` was mapped
 to SLF4J's `DEBUG` level, while `FINER` and `FINEST` were mapped to SLF4J's `TRACE`.
 
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.6.0">1.6.0</a> / 2016-01-22
-{: #v1-6-0}
+## Past releases
 
-As usual in this release, there are new SQL features, improvements to
-planning rules and Avatica, and lots of bug fixes. We'll spotlight a
-couple of features make it easier to handle complex queries.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
-allows you to represent sub-queries (`EXISTS`, `IN` and scalar) as
-`RexSubQuery`, a kind of expression in the relational algebra. Until
-now, the sql-to-rel converter was burdened with expanding sub-queries,
-and people creating relational algebra directly (or via RelBuilder)
-could only create 'flat' relational expressions. Now we have planner
-rules to expand and de-correlate sub-queries.
-
-Metadata is the fuel that powers query planning. It includes
-traditional query-planning statistics such as cost and row-count
-estimates, but also information such as which columns form unique
-keys, unique and what predicates are known to apply to a relational
-expression's output rows. From the predicates we can deduce which
-columns are constant, and following
-[<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
-we can now remove constant columns from `GROUP BY` keys.
-
-Metadata is often computed recursively, and it is hard to safely and
-efficiently calculate metadata on a graph of `RelNode`s that is large,
-frequently cyclic, and constantly changing.
-[<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
-introduces a context to each metadata call. That context can detect
-cyclic metadata calls and produce a safe answer to the metadata
-request. It will also allow us to add finer-grained caching and
-further tune the metadata layer.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
-  Represent sub-query as a `RexNode`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-854">CALCITE-854</a>]
-  Implement `UNNEST ... WITH ORDINALITY`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1003">CALCITE-1003</a>]
-  Utility to convert `RelNode` to SQL (Amogh Margoor)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1010">CALCITE-1010</a>]
-    `FETCH/LIMIT` and `OFFSET` in RelToSqlConverter (Amogh Margoor)
-  * Move code from `JdbcImplementor` and `JdbcRules` to new class
-    `SqlImplementor`
-  * Deduce dialect's null collation from `DatabaseMetaData`
-  * Fix `RelToSqlConverterTest` on Windows
-* Following
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-897">CALCITE-897</a>],
-  empty string for `boolean` properties means true
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-992">CALCITE-992</a>]
-  Validate and resolve sequence reference as a `Table` object
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-968">CALCITE-968</a>]
-  Stream-to-relation and stream-to-stream joins (Milinda Pathirage)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1041">CALCITE-1041</a>]
-  User-defined function that returns `DATE` or `TIMESTAMP` value
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-986">CALCITE-986</a>]
-  User-defined function with `DATE` or `TIMESTAMP` parameters
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-958">CALCITE-958</a>]
-  Overloaded Table Functions with named arguments (Julien Le Dem)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-970">CALCITE-970</a>]
-  If `NULLS FIRST`/`NULLS LAST` not specified, sort `NULL` values high
-
-Avatica features and bug fixes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1040">CALCITE-1040</a>]
-  Differentiate better between arrays and scalars in protobuf
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-934">CALCITE-934</a>]
-  Use an OS-assigned ephemeral port for `CalciteRemoteDriverTest`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-767">CALCITE-767</a>]
-  Create Avatica RPC endpoints for commit and rollback commands
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-983">CALCITE-983</a>]
-  Handle nulls in `ErrorResponse`'s protobuf representation better
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-989">CALCITE-989</a>]
-  Add server's address in each response
-* Fix some bugs found by static analysis
-* Make all `equals` and `hashCode` methods uniform
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-962">CALCITE-962</a>]
-  Propagate the cause, not just the cause's message, from `JdbcMeta`
-
-Planner rules
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1057">CALCITE-1057</a>]
-  Add `RelMetadataProvider` parameter to standard planner `Program`s
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1055">CALCITE-1055</a>]
-  `SubQueryRemoveRule` should create `Correlate`, not `Join`, for correlated
-  sub-queries
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-978">CALCITE-978</a>]
-  Enable customizing constant folding rule behavior when a `Filter` simplifies
-  to false (Jason Altekruse)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-977">CALCITE-977</a>]
-  Make the constant expression `Executor` configurable in `FrameworkConfig`
-  (Jason Altekruse)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1058">CALCITE-1058</a>]
-  Add method `RelBuilder.empty`, and rewrite LIMIT 0 and WHERE FALSE to it
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-996">CALCITE-996</a>]
-  Simplify predicate when we create a `Filter` operator
-* Simplify `RexProgram`, in particular `(NOT CASE ... END) IS TRUE`, which
-  occurs in when `NOT IN` is expanded
-* Fix variant of
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-923">CALCITE-923</a>]
-  that occurs in `RelOptRulesTest.testPushFilterPastProject`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
-  and
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-1038">CALCITE-1038</a>]
-  Planner rule that removes `Aggregate` keys that are constant
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1018">CALCITE-1018</a>]
-  `SortJoinTransposeRule` not firing due to `getMaxRowCount(RelSubset)` returning
-  null
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1019">CALCITE-1019</a>]
-  `RelMdUtil.checkInputForCollationAndLimit()` was wrong with `alreadySorted`
-  check
-* Not safe to use '=' for predicates on constant expressions that might be null
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-993">CALCITE-993</a>]
-  Pull up all constant expressions, not just literals, as predicates
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1005">CALCITE-1005</a>]
-  Handle null in `getMaxRowCount` for `Aggregate` (Mike Hinchey)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-995">CALCITE-995</a>]
-  Sort transpose rules might fall in an infinite loop
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-987">CALCITE-987</a>]
-  Pushing `LIMIT 0` results in an infinite loop (Pengcheng Xiong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-988">CALCITE-988</a>]
-  `FilterToProjectUnifyRule.invert(MutableRel, MutableRel, MutableProject)`
-  works incorrectly
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-969">CALCITE-969</a>]
-  Composite `EnumerableSort` with `DESC` wrongly sorts `NULL` values low
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-959">CALCITE-959</a>]
-  Add description to `SortProjectTransposeRule`'s constructor
-
-Bug fixes, API changes and minor enhancements
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1060">CALCITE-1060</a>]
-  Fix test deadlock by initializing `DriverManager` before registering `AlternatingDriver`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1047">CALCITE-1047</a>]
-  `ChunkList.clear` throws `AssertionError`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1053">CALCITE-1053</a>]
-  CPU spin, `ReflectiveRelMetadataProvider.apply` waiting for `HashMap.get`
-* Upgrade toolbox, to fix line length issue on Windows
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1051">CALCITE-1051</a>]
-  Underflow exception due to scaling IN clause literals (Frankie Bollaert)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-975">CALCITE-975</a>]
-  Allow Planner to return validated row type together with SqlNode
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1020">CALCITE-1020</a>]
-  Add `MILLISECOND` in `TimeUnit` (Pengcheng Xiong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
-  Detect cycles when computing statistics
-  (**This is a breaking change**.)
-* Tune algorithm that deduces the return type of `AND` expression
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-842">CALCITE-842</a>]
-  Decorrelator gets field offsets confused if fields have been trimmed
-* Fix `NullPointerException` in `SqlJoin.toString()`
-* Add `ImmutableBitSet.rebuild()`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-915">CALCITE-915</a>]
-  Tests now unset `ThreadLocal` values on exit
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1036">CALCITE-1036</a>]
-  `DiffRepository` should not insert new resources at the end of the repository
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-955">CALCITE-955</a>]
-  `Litmus` (continuation-passing style for methods that check invariants)
-* `RelBuilder.project` now does nothing if asked to project the identity with
-  the same field names
-* Deprecate some `Util` methods, and upgrade last Maven modules to JDK 1.7
-* Document `RelOptPredicateList`
-* Add `ImmutableNullableList.copyOf(Iterable)`
-* Fix "endPosTable already set" error from `javac`
-* Add benchmark of `Parser.create(sql).parseQuery()`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1042">CALCITE-1042</a>]
-  Ensure that `FILTER` is `BOOLEAN NOT NULL`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1039">CALCITE-1039</a>]
-  Assign a `SqlKind` value for each built-in aggregate function
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1030">CALCITE-1030</a>]
-  JSON `ModelHandler` calling `SchemaPlus.setCacheEnabled()` causes
-  `UnsupportedOperationException` when using `SimpleCalciteSchema`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1028">CALCITE-1028</a>]
-  Move populate materializations after sql-to-rel conversion
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1034">CALCITE-1034</a>]
-  Use a custom checker for code style rules that Checkstyle cannot express
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1032">CALCITE-1032</a>]
-  Verify javadoc of private methods
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1015">CALCITE-1015</a>]
-  `OFFSET 0` causes `AssertionError` (Zhen Wang)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1024">CALCITE-1024</a>]
-  In a planner test, if a rule should have no effect, state that explicitly
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1016">CALCITE-1016</a>]
-  `GROUP BY *constant*` on empty relation should return 0 rows
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1022">CALCITE-1022</a>]
-  Rename `.oq` Quidem files to `.iq`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-980">CALCITE-980</a>]
-  Fix `AND` and `OR` implementation in `Enumerable` convention
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-459">CALCITE-459</a>]
-  When parsing SQL, allow single line comment on last line (Zhen Wang)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1009">CALCITE-1009</a>]
-  `SelfPopulatingList` is not thread-safe
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1008">CALCITE-1008</a>]
-  Replace `Closeable` with `AutoCloseable`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-1001">CALCITE-1001</a>]
-  Upgrade to quidem-0.7
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-990">CALCITE-990</a>]
-  In `VolcanoPlanner`, populate `RelOptRuleCall.nodeInputs` for operands of type
-  "any"
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-966">CALCITE-966</a>]
-  `VolcanoPlanner` now clears `ruleNames` in order to avoid rule name
-  conflicting error
-* Factor user-defined function tests from `JdbcTest` to `UdfTest`, and classes
-  into `Smalls`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-974">CALCITE-974</a>]
-  Exception while validating `DELETE` (Yuri Au Yong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-964">CALCITE-964</a>]
-  Rename `timezone` connection property to `timeZone`
-
-Web site and documentation
-
-* Avatica
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1033">CALCITE-1033</a>]
-    Introduce Avatica protobuf documentation
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1029">CALCITE-1029</a>]
-     Add "purpose" descriptions to Avatica JSON docs
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-984">CALCITE-984</a>]
-    Massive cleanup of Avatica JSON docs
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-861">CALCITE-861</a>]
-  Be explicit that `mvn test` needs to be invoked
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-997">CALCITE-997</a>]
-  Document keywords
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-979">CALCITE-979</a>]
-  Broken links in web site
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-961">CALCITE-961</a>]
-  Web site: Add downloads and Apache navigation links
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-960">CALCITE-960</a>]
-  Download links for pgp, md5, `KEYS` files, and direct from mirrors
-* Remove embedded date-stamps from javadoc; add javadoc for test classes
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-965">CALCITE-965</a>]
-  Link to downloads page from each release news item
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.5.0">1.5.0</a> / 2015-11-06
-{: #v1-5-0}
-
-Our first release as a top-level Apache project!
-
-Avatica has undergone major improvements,
-including a new RPC layer that uses
-[protocol buffers](https://developers.google.com/protocol-buffers/),
-support for DML statements, better support for bind variables and
-unique identifiers for connections and statements.
-
-There are lots of improvements to planner rules, and the logic
-that replaces relational expressions with equivalent materializations.
-
-We continue to find more uses for
-[RelBuilder]({{ site.baseurl }}/docs/algebra.html).
-We now recommend that you use `RelBuilder` whenever you create
-relational expressions within a planner rule; the rule can then be
-re-used to create different sub-classes of relational expression, and
-the builder will perform simple optimizations automatically.
-
-Using `RelBuilder` we built Piglet,
-a subset of the classic Hadoop language
-[Pig](https://pig.apache.org/).
-Pig is particularly interesting because it makes heavy use of nested
-multi-sets.  You can follow this example to implement your own query
-language, and immediately taking advantage of Calcite's back-ends and
-optimizer rules. It's all just algebra, after all!
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-911">CALCITE-911</a>]
-  Add a variant of `CalciteSchema` that does not cache sub-objects
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-845">CALCITE-845</a>]
-  Derive `SUM`’s return type by a customizable policy (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-916">CALCITE-916</a>]
-  Support table function that implements `ScannableTable`
-  * Example table function that generates mazes and their solutions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-941">CALCITE-941</a>]
-  Named, optional and `DEFAULT` arguments to function calls;
-  support named arguments when calling table functions and table macros
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-910">CALCITE-910</a>]
-  Improve handling of `ARRAY`, `MULTISET`, `STRUCT` types
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-879">CALCITE-879</a>]
-  `COLLECT` aggregate function
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-546">CALCITE-546</a>]
-  Allow table, column and field called '*'
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-893">CALCITE-893</a>]
-  Theta join in JDBC adapter
-* Linq4j: Implement `EnumerableDefaults` methods (MiNG)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-823">CALCITE-823</a>]
-  Add `ALTER ... RESET` statement (Sudheesh Katkam)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-881">CALCITE-881</a>]
-  Allow schema.table.column references in `GROUP BY`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-852">CALCITE-852</a>]
-  DDL statements
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-851">CALCITE-851</a>]
-  Add original SQL string as a field in the parser
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-819">CALCITE-819</a>]
-  Add `RelRoot`, a contract for the result of a relational expression
-
-Avatica features and bug fixes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-951">CALCITE-951</a>]
-  Print the server-side stack in the local exception (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-936">CALCITE-936</a>]
-  Make HttpServer configurable (Navis Ryu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-903">CALCITE-903</a>]
-  Enable Avatica client to recover from missing server-side state (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-921">CALCITE-921</a>]
-  Fix incorrectness when calling `getString()` on binary data (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-913">CALCITE-913</a>]
-  Construct proper `ColumnMetaData` for arrays (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-871">CALCITE-871</a>]
-  In `JdbcMeta`, register each statement using an id from a generator (Bruno
-  Dumon)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-645">CALCITE-645</a>]
-  Implement `AvaticaSqlException` to pass server-side exception information to
-  clients (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-912">CALCITE-912</a>]
-  Add Avatica `OpenConnectionRequest` (Bruno Dumon)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-919">CALCITE-919</a>]
-  Avoid `setScale` on `BigDecimal` when scale is 0 (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-927">CALCITE-927</a>]
-  Call finagle for all calls that return ResultSetResponses (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-705">CALCITE-705</a>]
-  DML in Avatica, and split `Execute` out from `Fetch` request (Yeong Wei)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-914">CALCITE-914</a>]
-  Add `JsonSubType` for `ExecuteResponse`, and fix JSON docs (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-905">CALCITE-905</a>]
-  `getTables` returns empty result in `JdbcMeta` (Jan Van Besien)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-906">CALCITE-906</a>]
-  Avatica `JdbcMeta` statement IDs are not unique
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-866">CALCITE-866</a>]
-  Break out Avatica documentation and add JSON reference (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-843">CALCITE-843</a>]
-  `AvaticaConnection.getAutoCommit` throws `NullPointerException`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-840">CALCITE-840</a>]
-  Protocol buffer serialization over HTTP for Avatica Server (Josh Elser)
-
-Materializations
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-952">CALCITE-952</a>]
-  Organize applicable materializations in reversed topological order (Maryann
-  Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-890">CALCITE-890</a>]
-  Register all combinations of materialization substitutions (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-891">CALCITE-891</a>]
-  When substituting materializations, match `TableScan` without `Project`
-  (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-890">CALCITE-890</a>]
-  Register all combinations of materialization substitutions (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-925">CALCITE-925</a>]
-  Match materialized views when predicates contain strings and ranges (Amogh
-  Margoor)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-793">CALCITE-793</a>]
-  Planner requires unnecessary collation when using materialized view (Maryann
-  Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-825">CALCITE-825</a>]
-  Allow user to specify sort order of an `ArrayTable`
-
-Planner rules
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-953">CALCITE-953</a>]
-  Improve `RelMdPredicates` to deal with `RexLiteral` (Pengcheng Xiong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-939">CALCITE-939</a>]
-  Variant of `SortUnionTransposeRule` for order-preserving `Union`
-  (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-931">CALCITE-931</a>]
-  Wrong collation trait in `SortJoinTransposeRule` for right joins
-  (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-938">CALCITE-938</a>]
-  More accurate rowCount for `Aggregate` applied to already unique keys
-  (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-935">CALCITE-935</a>]
-  Improve how `ReduceExpressionsRule` handles duplicate constraints (Pengcheng
-  Xiong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-922">CALCITE-922</a>]
-  Extract value of an `INTERVAL` literal (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-889">CALCITE-889</a>]
-  Implement `SortUnionTransposeRule` (Pengcheng Xiong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-909">CALCITE-909</a>]
-  Make `ReduceExpressionsRule` extensible
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-856">CALCITE-856</a>]
-  Make more rules extensible
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-902">CALCITE-902</a>]
-  Match nullability when reducing expressions in a `Project`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-895">CALCITE-895</a>]
-  Simplify "(`CASE` ... `END`) = constant" inside `AND` or `OR` (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-828">CALCITE-828</a>]
-  Use RelBuilder in rules rather than type-specific RelNode factories
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-892">CALCITE-892</a>]
-  Implement `SortJoinTransposeRule`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-876">CALCITE-876</a>]
-  After pushing `LogicalProject` past `LogicalWindow`, adjust references to
-  constants properly (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-844">CALCITE-844</a>]
-  Push `Project` through `Window` (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-841">CALCITE-841</a>]
-  Redundant windows when window function arguments are expressions (Hsuan-Yi
-  Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-846">CALCITE-846</a>]
-  Push `Aggregate` with `Filter` through `Union(all)`
-
-RelBuilder and Piglet
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-933">CALCITE-933</a>]
-  `RelBuilder.scan()` now gives a nice exception if the table does not exist
-  (Andy Grove)
-* Fix Piglet `DUMP` applied to multisets and structs
-* Multisets and `COLLECT` in Piglet
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-785">CALCITE-785</a>]
-  Add "Piglet", a subset of Pig Latin on top of Calcite algebra
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-869">CALCITE-869</a>]
-  Add `VALUES` command to Piglet
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-868">CALCITE-868</a>]
-  Add API to execute queries expressed as `RelNode`
-* In RelBuilder, build expressions by table alias
-
-Bug fixes, API changes and minor enhancements
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-948">CALCITE-948</a>]
-  Indicator columns not preserved by `RelFieldTrimmer`
-* Fix Windows issues (line endings and checkstyle suppressions)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-937">CALCITE-937</a>]
-  User-defined function within view
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-926">CALCITE-926</a>]
-  Rules fail to match because of missing link to parent equivalence set
-  (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-908">CALCITE-908</a>]
-  Bump protobuf to 3.0.0-beta-1, fix deprecations and update docs (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-932">CALCITE-932</a>]
-  Fix muddled columns when `RelFieldTrimmer` is applied to `Aggregate`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-930">CALCITE-930</a>]
-  Now Calcite is a top-level project, remove references to "incubating"
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-929">CALCITE-929</a>]
-  Calls to `AbstractRelNode` may result in NPE
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-923">CALCITE-923</a>]
-  Type mismatch when converting `LEFT JOIN` to `INNER`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-666">CALCITE-666</a>]
-  Anti-semi-joins against JDBC adapter give wrong results (Yeong Wei)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-918">CALCITE-918</a>]
-  `createProject` in `RelOptUtil` should uniquify field names
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-792">CALCITE-792</a>]
-  Obsolete `RelNode.isKey` and `isDistinct` methods
-* Allow FlatLists of different length to be compared
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-898">CALCITE-898</a>]
-  Type of 'Java<Long> * `INTEGER`' should be `BIGINT`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-894">CALCITE-894</a>]
-  Do not generate redundant column alias for the left relation when
-  translating `IN` subquery (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-897">CALCITE-897</a>]
-  Enable debugging using "-Dcalcite.debug"
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-885">CALCITE-885</a>]
-  Add Oracle test environment
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-888">CALCITE-888</a>]
-  Overlay window loses `PARTITION BY` list (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-886">CALCITE-886</a>]
-  System functions in `GROUP BY` clause
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-860">CALCITE-860</a>]
-  Correct LICENSE file for generated web site
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-882">CALCITE-882</a>]
-  Allow web site to be deployed not as the root directory of the web server
-  (Josh Elser)
-* Upgrade parent POM to apache-17
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
-  Synchronize HSQLDB at a coarse level using a Lock (Josh Elser)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-870">CALCITE-870</a>]
-  Remove copyright content from archers.json
-* Replace `Stack` with `ArrayDeque`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-874">CALCITE-874</a>]
-  `ReflectiveRelMetadataProvider` is not thread-safe
-* Add `LogicalWindow.create()`
-* Add `ImmutableBitSet.get(int, int)`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-865">CALCITE-865</a>]
-  Unknown table type causes `NullPointerException` in `JdbcSchema`
-  * Add table types used by Oracle and DB2
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-862">CALCITE-862</a>]
-  `JdbcSchema` gives `NullPointerException` on non-standard column type (Marc
-  Prud'hommeaux)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-847">CALCITE-847</a>]
-  `AVG` window function in `GROUP BY` gives `AssertionError` (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-827">CALCITE-827</a>]
-  Calcite incorrectly permutes columns of `OVER` query (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-809">CALCITE-809</a>]
-  `TableScan` does not support large/infinite scans (Jesse Yates)
-* Lazily create exception only when it needs to be thrown (Marc Prud'hommeaux)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-812">CALCITE-812</a>]
-  Make JSON reader and writer use properly quoted key names (Marc
-  Prud'hommeaux)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-820">CALCITE-820</a>]
-  Validate that window functions have `OVER` clause (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-824">CALCITE-824</a>]
-  Type inference when converting `IN` clause to semijoin (Josh Wills)
-
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.4.0-incubating">1.4.0-incubating</a> / 2015-09-02
-{: #v1-4-0}
-
-In addition to a large number of bug fixes and minor enhancements,
-this release includes improvements to lattices and materialized views,
-and adds a builder API so that you can easily create relational
-algebra expressions.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-748">CALCITE-748</a>]
-      Add `RelBuilder`, builder for expressions in relational algebra
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-758">CALCITE-758</a>]
-      Use more than one lattice in the same query (Rajat Venkatesh)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-761">CALCITE-761</a>]
-      Pre-populated materializations (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-786">CALCITE-786</a>]
-      Detect if materialized view can be used to rewrite a query in
-  non-trivial cases (Amogh Margoor)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-732">CALCITE-732</a>]
-      Implement multiple distinct-`COUNT` using `GROUPING SETS`
-* Add various `BitSet` and `ImmutableBitSet` utilities
-
-Website updates
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-810">CALCITE-810</a>]
-      Add committers' organizations to the web site
-* Add news item (XLDB best lighting talk), and some talks
-* Fix javadoc links
-* Add license notice for web site
-* Wrap file header in HTML comments
-* How to release
-* Move disclaimer out of every page's footer and into home page and downloads
-  page
-* For web site files, add license headers where possible, apache-rat
-  exclusions otherwise
-* Calcite DOAP
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-355">CALCITE-355</a>]
-      Web site
-
-Bug fixes, API changes and minor enhancements
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-741">CALCITE-741</a>]
-      Ensure that the source release's `DEPENDENCIES` file includes all module
-  dependencies
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-743">CALCITE-743</a>]
-      Ensure only a single source assembly is executed
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-850">CALCITE-850</a>]
-      Remove push down expressions from `FilterJoinRule` and create a new rule
-  for it
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-834">CALCITE-834</a>]
-      `StackOverflowError` getting predicates from the metadata provider
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-833">CALCITE-833</a>]
-      `RelOptUtil.splitJoinCondition` incorrectly splits a join condition
-  (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-822">CALCITE-822</a>]
-      Add a unit test case to test collation of `LogicalAggregate`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-822">CALCITE-822</a>]
-      Revert incorrect `LogicalAggregate` collation inferring logic made in
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-783">CALCITE-783</a>]
-  (Milinda Pathirage)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-826">CALCITE-826</a>]
-      Use `ProjectFactory` in `AggregateJoinTranposeRule` and `FilterJoinRule`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-821">CALCITE-821</a>]
-      `Frameworks` gives NPE when `FrameworkConfig` has no default schema
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-811">CALCITE-811</a>]
-      Extend `JoinProjectTransposeRule` with option to support outer joins
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-805">CALCITE-805</a>]
-      Add support for using an alternative grammar specification for left and
-  right curly braces. Additionally, add support for including addition token
-  manager declarations
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-803">CALCITE-803</a>]
-      Add `MYSQL_ANSI` Lexing policy
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-717">CALCITE-717</a>]
-      Compare BINARY and VARBINARY on unsigned byte values (Low Chin Wei)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-814">CALCITE-814</a>]
-      `RexBuilder` reverses precision and scale of `DECIMAL` literal
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-813">CALCITE-813</a>]
-      Upgrade `updateCount`, `maxRows` from int to long
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-714">CALCITE-714</a>]
-      When de-correlating, push join condition into subquery
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-751">CALCITE-751</a>]
-      Push aggregate with aggregate functions through join
-* Add `RelBuilder.avg`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-806">CALCITE-806</a>]
-      `ROW_NUMBER` should emit distinct values
-* Document JSON model, making javadoc consistent with the model reference
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-808">CALCITE-808</a>]
-      Optimize `ProjectMergeRule`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-791">CALCITE-791</a>]
-      Optimize `RelOptUtil.pushFilterPastProject`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-783">CALCITE-783</a>]
-      Infer collation of `Project` using monotonicity (Milinda Pathirage)
-* Change the argument types of `SqlOperator.getMonotonicity` to allow it to be
-  used for `RexNode` as well as `SqlNode`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-800">CALCITE-800</a>]
-      Window function defined within another window function should be invalid
-  (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-787">CALCITE-787</a>]
-      Star table wrongly assigned to materialized view (Amogh Margoor)
-* Remove duplicate resources from XML test reference files
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-795">CALCITE-795</a>]
-      Loss of precision when sending a decimal number via the remote JSON
-  service (Lukáš Lalinský)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-774">CALCITE-774</a>]
-      When `GROUP BY` is present, ensure that window function operands only
-  refer to grouping keys (Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-799">CALCITE-799</a>]
-      Incorrect result for `HAVING count(*) > 1`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-801">CALCITE-801</a>]
-      `NullPointerException` using `USING` on table alias with column aliases
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-390">CALCITE-390</a>]
-      Infer predicates for semi-join
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-789">CALCITE-789</a>]
-      `MetaImpl.MetaCatalog` should expose `TABLE_CAT` instead of
-      `TABLE_CATALOG`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-752">CALCITE-752</a>]
-      Add back sqlline as a dependency to csv example
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-780">CALCITE-780</a>]
-      HTTP error 413 when sending a long string to the Avatica server
-* In `RelBuilder`, calling `sort` then `limit` has same effect as calling
-  `sortLimit`
-* Add `Ord.reverse`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-788">CALCITE-788</a>]
-      Allow `EnumerableJoin` to be sub-classed (Li Yang)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-280">CALCITE-280</a>]
-      `BigDecimal` underflow (Li Yang)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-763">CALCITE-763</a>]
-      Missing translation from `Sort` to `MutableSort` (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-770">CALCITE-770</a>]
-      Ignore window aggregates and ranking functions when finding aggregate
-  functions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-765">CALCITE-765</a>]
-      Set `Content-Type` from the RPC server to `application/json` (Lukáš Lalinský)
-* Fix Windows line-endings in `RelBuilderTest`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-727">CALCITE-727</a>]
-      Constant folding involving `CASE` and `NULL`
-* Related to
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-758">CALCITE-758</a>],
-  speed up matching by not considering tiles separately from other
-  materialized views
-* Test case and workaround for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-760">CALCITE-760</a>]
-      `Aggregate` recommender blows up if row count estimate is too high
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-753">CALCITE-753</a>]
-      `Aggregate` operators may derive row types with duplicate column names
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-457">CALCITE-457</a>]
-      Push condition of non-ansi join into join operator
-* Change jsonRequest encoding to UTF-8 (Guitao Ding)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-757">CALCITE-757</a>]
-      Fix expansion of view of another view (Venki Korukanti)
-* Fix coverity warnings
-* Remove deprecated `SqlTypeName` methods
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-754">CALCITE-754</a>]
-      Validator error when resolving `OVER` clause of `JOIN` query
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-429">CALCITE-429</a>]
-      Cardinality provider for use by lattice algorithm
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-740">CALCITE-740</a>]
-      Redundant `WHERE` clause causes wrong result in MongoDB adapter
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-665">CALCITE-665</a>]
-      `ClassCastException` in MongoDB adapter
-* Separate `TableFactory` from suggested table name, so one `TableFactory` can be
-  used for several tables
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-749">CALCITE-749</a>]
-      Add `MaterializationService.TableFactory` (Rajat Venkatesh)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-718">CALCITE-718</a>]
-      Enable fetch to work for `Statement.execute()` for Avatica (Xavier Leong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-712">CALCITE-712</a>]
-      Obey `setMaxRows` for statement execute (Xavier Leong)
-* Add `LoggingLocalJsonService`, to make it easier to test that JDBC requests
-  cause the right RPCs
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-708">CALCITE-708</a>]
-      Implement `DatabaseMetaData.getTypeInfo` (Xavier Leong)
-* Enable Travis CI on new-master branch and bug-fix branches named
-  "NNN-description"
-* Clean up
-* Upgrade tpcds
-* Make `JdbcTest.testVersion` more permissive, so that `version.major` and
-  `version.minor` can be set just before a release, rather than just after as at
-  present
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.3.0-incubating">1.3.0-incubating</a> / 2015-05-30
-{: #v1-3-0}
-
-Mainly bug-fixes, but this release adds support for
-<a href="https://issues.apache.org/jira/browse/CALCITE-505">modifiable views</a>
-and
-<a href="https://issues.apache.org/jira/browse/CALCITE-704">filtered aggregate functions</a>
-and various improvements to Avatica.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-505">CALCITE-505</a>]
-  Support modifiable view
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-704">CALCITE-704</a>]
-  `FILTER` clause for aggregate functions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-522">CALCITE-522</a>]
-  In remote JDBC driver, transmit static database properties as a map
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-661">CALCITE-661</a>]
-  Remote fetch in Calcite JDBC driver
-* Support Date, Time, Timestamp parameters
-
-API changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-722">CALCITE-722</a>]
-  Rename markdown files to lower-case
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-697">CALCITE-697</a>]
-  Obsolete class `RelOptQuery`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-693">CALCITE-693</a>]
-  Allow clients to control creation of `RelOptCluster`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-691">CALCITE-691</a>]
-  Allow projects to supply alternate SQL parser
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-675">CALCITE-675</a>]
-  Enable `AggregateProjectMergeRule` in standard rule set
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-679">CALCITE-679</a>]
-  Factory method for `SemiJoin`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-674">CALCITE-674</a>]
-  Add a `SWAP_OUTER` static instance to `JoinCommuteRule` (Maryann Xue)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-735">CALCITE-735</a>]
-  `Primitive.DOUBLE.min` should be large and negative
-
-Bug-fixes and internal changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-688">CALCITE-688</a>]
-  `splitCondition` does not behave correctly when one side of the condition
-  references columns from different inputs
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-259">CALCITE-259</a>]
-  Using sub-queries in `CASE` statement against JDBC tables generates invalid
-  Oracle SQL (Yeong Wei)
-* In sample code in README.md, rename optiq to calcite (Ethan)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-720">CALCITE-720</a>]
-  `VolcanoPlanner.ambitious` comment doc is inconsistent (Santiago M. Mola)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-729">CALCITE-729</a>]
-  `IndexOutOfBoundsException` in `ROLLUP` query on JDBC data source
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-733">CALCITE-733</a>]
-  Multiple distinct-`COUNT` query gives wrong results
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-730">CALCITE-730</a>]
-  `ClassCastException` in table from `CloneSchema`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-728">CALCITE-728</a>]
-  Test suite hangs on Windows
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-723">CALCITE-723</a>]
-  Document lattices
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-515">CALCITE-515</a>]
-  Add Apache headers to markdown files
-* Upgrade quidem
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-716">CALCITE-716</a>]
-  Scalar sub-query and aggregate function in `SELECT` or `HAVING` clause gives
-  `AssertionError`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-694">CALCITE-694</a>]
-  Scan `HAVING` clause for sub-queries and `IN`-lists (Hsuan-Yi Chu)
-* Upgrade hydromatic-resource-maven-plugin
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-710">CALCITE-710</a>]
-  Identical conditions in the `WHERE` clause cause `AssertionError` (Sean
-  Hsuan-Yi Chu)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-695">CALCITE-695</a>]
-  Do not add `SINGLE_VALUE` aggregate function to a sub-query that will never
-  return more than one row (Hsuan-Yi Chu)
-* Add tests for scalar sub-queries, including test cases for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-709">CALCITE-709</a>]
-  Errors with `LIMIT` inside scalar sub-query
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-702">CALCITE-702</a>]
-  Add validator test for monotonic expressions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-699">CALCITE-699</a>]
-  In Avatica, synchronize access to Calendar
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-700">CALCITE-700</a>]
-  Pass time zone into tests
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-698">CALCITE-698</a>]
-  For `GROUP BY ()`, `areColumnsUnique()` should return true for any key
-* Disable tests that fail under JDK 1.7 due to
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
-* Add "getting started" to HOWTO
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-692">CALCITE-692</a>]
-  Add back sqlline as a dependency
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-677">CALCITE-677</a>]
-  `RemoteDriverTest.testTypeHandling` fails east of Greenwich
-* Disable test for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
-  Make `RemoteDriverTest.testStatementLifecycle` thread-safe
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-686">CALCITE-686</a>]
-  `SqlNode.unparse` produces invalid SQL
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-507">CALCITE-507</a>]
-  Update HOWTO.md with running integration tests
-* Add H2 integration test
-* Add PostgreSQL integration test
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-590">CALCITE-590</a>]
-  Update MongoDB test suite to calcite-test-dataset
-* Add `CalciteAssert.assertArrayEqual` for more user-friendly asserts
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-585">CALCITE-585</a>]
-  Avatica JDBC methods should throw `SQLFeatureNotSupportedException` (Ng Jiunn
-  Jye)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-671">CALCITE-671</a>]
-  `ByteString` does not deserialize properly as a `FetchRequest` parameter value
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-676">CALCITE-676</a>]
-  `AssertionError` in `GROUPING SETS` query
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-678">CALCITE-678</a>]
-  `SemiJoinRule` mixes up fields when `Aggregate.groupSet` is not field #0
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.2.0-incubating">1.2.0-incubating</a> / 2015-04-07
-{: #v1-2-0}
-
-A short release, less than a month after 1.1.
-
-There have been many changes to Avatica, hugely improving its coverage of the
-JDBC API and overall robustness. A new provider, `JdbcMeta`, allows
-you to remote an existing JDBC driver.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
-improves how the planner propagates traits such as collation and
-distribution among relational expressions.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
-and [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
-improve implicit and explicit conversions in SQL.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-366">CALCITE-366</a>]
-  Support Aggregate push down in bushy joins (Jesus Camacho Rodriguez)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
-  Implicitly convert character values in comparisons
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
-  Implement `CAST` between date-time types
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-634">CALCITE-634</a>]
-  Allow `ORDER BY` aggregate function in `SELECT DISTINCT`, provided that it
-  occurs in `SELECT` clause (Sean Hsuan-Yi Chu)
-* In linq4j, implement `firstOrDefault`, `single`, and `singleOrDefault` methods
-  (Daniel Cooper)
-* JDBC adapter
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-631">CALCITE-631</a>]
-    Push theta joins down to JDBC adapter (Ng Jiunn Jye)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-657">CALCITE-657</a>]
-    `NullPointerException` when executing `JdbcAggregate.implement`
-    method (Yuri Au Yong)
-* Metadata
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-659">CALCITE-659</a>]
-    Missing types in `averageTypeValueSize` method in `RelMdSize`
-    (Jesus Camacho Rodriguez)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-650">CALCITE-650</a>]
-    Add metadata for average size of a tuple in `SemiJoin` (Jesus
-    Camacho Rodriguez)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-649">CALCITE-649</a>]
-    Extend `splitCondition` method in `RelOptUtil` to handle multiple
-    joins on the same key (Jesus Camacho Rodriguez)
-
-Avatica features and bug fixes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-670">CALCITE-670</a>]
-  `AvaticaPreparedStatement` should support `execute()` and
-  `executeUpdate()` (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-641">CALCITE-641</a>]
-  Implement logging throughout Avatica server (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-646">CALCITE-646</a>]
-  `AvaticaStatement.execute` method broken over remote JDBC (Yeong Wei
-  and Julian Hyde)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-660">CALCITE-660</a>]
-  Improve Avatica date support
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-655">CALCITE-655</a>]
-  Implement `ConnectionSync` RPC (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-654">CALCITE-654</a>]
-  Tighten up `AvaticaStatement.execute` semantics (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-658">CALCITE-658</a>]
-  Cleanup dependency usage (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-652">CALCITE-652</a>]
-  Move server pieces of `avatica` into `avatica-server` (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-651">CALCITE-651</a>]
-  In `JdbcMeta`, convert property definitions to an enum (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-640">CALCITE-640</a>]
-  Avatica server should expire stale connections/statements (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-639">CALCITE-639</a>]
-  Open up permissions on avatica server components (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-637">CALCITE-637</a>]
-  Implement Avatica `CloseConnection` RPC (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-636">CALCITE-636</a>]
-  Connection isolation for Avatica clients (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-626">CALCITE-626</a>]
-  Implement `CloseStatement` RPC (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-630">CALCITE-630</a>]
-  Flesh out `AvaticaParameter.setObject` (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-627">CALCITE-627</a>]
-  Add Avatica support for `getTableTypes`, `getColumns` (Xavier FH Leong)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-618">CALCITE-618</a>]
-  Add Avatica support for `getTables` (Julian Hyde and Nick Dimiduk)
-
-API changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-617">CALCITE-617</a>]
-  Check at initialization time in `CachingInvocationHandler` that MD provider
-  is not null (Jesus Camacho Rodriguez)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-638">CALCITE-638</a>]
-  SQL standard `REAL` is 4 bytes, `FLOAT` is 8 bytes
-
-Bug-fixes and internal changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-672">CALCITE-672</a>]
-  SQL `ANY` type should be nullable (Jinfeng Ni)
-* Disable tests, pending
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-673">CALCITE-673</a>]
-  Timeout executing joins against MySQL
-* Fix traits in MongoDB adapter, and `NullPointerException` in `JdbcTest`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-662">CALCITE-662</a>]
-  Query validation fails when an `ORDER BY` clause is used with `WITH CLAUSE`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
-  Fix trait propagation and add test case
-* Remove checkstyle Eclipse properties from git tracking
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-644">CALCITE-644</a>]
-  Increase check style line limit to 100 chars (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-648">CALCITE-648</a>]
-  Update `ProjectMergeRule` description for new naming convention (Jinfeng Ni)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-625">CALCITE-625</a>]
-  `README.md` linking to the wrong page of `optiq-csv` (hongbin ma)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-632">CALCITE-632</a>]
-  Sort order returned by `SUPERCLASS_COMPARATOR` in
-  `ReflectiveRelMetadataProvider` is inconsistent (Jesus Camacho
-  Rodriguez)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-335">CALCITE-335</a>]
-  Remove uses of linq4j `Functions.adapt`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-592">CALCITE-592</a>]
-  Upgrade to Guava 14.0.1
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-596">CALCITE-596</a>]
-  JDBC adapter incorrectly reads null values as 0 (Ng Jiunn Jye)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-633">CALCITE-633</a>]
-  `WITH ... ORDER BY` cannot find table
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-614">CALCITE-614</a>]
-  `IN` clause in `CASE` in `GROUP BY` gives `AssertionError`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-619">CALCITE-619</a>]
-  Slim down dependencies in parent POM
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.1.0-incubating">1.1.0-incubating</a> / 2015-03-13
-{: #v1-1-0}
-
-This Calcite release makes it possible to exploit physical properties
-of relational expressions to produce more efficient plans, introducing
-collation and distribution as traits, `Exchange` relational operator,
-and several new forms of metadata.
-
-We add experimental support for streaming SQL.
-
-This release drops support for JDK 1.6; Calcite now requires 1.7 or
-later.
-
-We have introduced static `create` methods for many sub-classes of
-`RelNode`. We strongly suggest that you use these rather than
-calling constructors directly.
-
-New features
-
-* SQL
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-602">CALCITE-602</a>]
-    Streaming queries (experimental)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-588">CALCITE-588</a>]
-    Allow `TableMacro` to consume maps and collections
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-583">CALCITE-583</a>]
-    Operator `||` mishandles `ANY` type (Sean Hsuan-Yi Chu)
-* Planner rule improvements
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-445">CALCITE-445</a>]
-    Pull up filters rejected by a `ProjectableFilterableTable`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-600">CALCITE-600</a>]
-    Use `SetOpFactory` in rules containing `Union` operator (Jesus
-    Camacho Rodriguez)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-603">CALCITE-603</a>]
-    Metadata providers for size, memory, parallelism
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-607">CALCITE-607</a>]
-      Change visibility of constructor in metadata providers for size,
-      memory, parallelism (Jesus Camacho Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-608">CALCITE-608</a>]
-      Exception is thrown when `RelMdDistribution` for `Project`
-      operator is called (Jesus Camacho Rodriguez)
-* Collation and distribution as traits
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-88">CALCITE-88</a>]
-    Add collation as a trait and a kind of `RelNode` metadata
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-569">CALCITE-569</a>]
-    `ArrayIndexOutOfBoundsException` when deducing collation (Aman Sinha)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-581">CALCITE-581</a>]
-    Add `LogicalSort` relational expression, and make `Sort` abstract
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-526">CALCITE-526</a>]
-    Add `EnumerableMergeJoin`, which exploits sorted inputs
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-71">CALCITE-71</a>]
-    Provide a way to declare that tables are sorted
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-576">CALCITE-576</a>]
-    Make `RelCollation` trait and `AbstractRelNode.getCollationList` consistent
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-254">CALCITE-254</a>]
-    Propagate `RelCollation` on aliased columns in `JoinRule`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-569">CALCITE-569</a>]
-    `ArrayIndexOutOfBoundsException` when deducing collation
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-594">CALCITE-594</a>]
-    Add `RelDistribution` trait and `Exchange` relational expression
-
-API changes
-
-* Many sub-classes of `RelNode` now have a static `create` method
-  which automatically sets up traits such as collation and
-  distribution. The constructors are not marked deprecated, but we
-  strongly suggest that you use the `create` method if it exists.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-591">CALCITE-591</a>]
-  Drop support for Java 1.6 (and JDBC 4.0)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-587">CALCITE-587</a>]
-  Upgrade `jetty-server` to 9.2.7.v20150116 and port avatica-server `HttpServer`
-  (Trevor Hartman)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-577">CALCITE-577</a>]
-  Revert temporary API changes introduced in
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-575">CALCITE-575</a>]
-* Add means to create `Context` instances by wrapping objects and by chaining
-  contexts
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-599">CALCITE-599</a>]
-  `EquiJoin` in wrong package (Jesus Camacho Rodriguez)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-573">CALCITE-573</a>]
-  Use user-given names in `RelOptUtil.createProject` and `createRename`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-572">CALCITE-572</a>]
-  Remove `Project.flags` (methods are deprecated, to be removed before 2.0)
-
-Bug-fixes and internal changes
-
-* Remove the `LICENSE` file of calcite-example-csv (the former
-  optiq-csv) and move its history into main history
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-615">CALCITE-615</a>]
-  AvaticaParameter should be Jackson serializable (Nick Dimiduk)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-612">CALCITE-612</a>]
-  Update AvaticaStatement to handle cancelled queries (Parth Chandra)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-605">CALCITE-605</a>]
-  Reduce dependency on third-party maven repositories
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-611">CALCITE-611</a>]
-  Method `setAggChildKeys` should take into account indicator columns of
-  `Aggregate` operator (Jesus Camacho Rodriguez)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-566">CALCITE-566</a>]
-  `ReduceExpressionsRule` requires planner to have an `Executor`
-* Refactor `TableScanNode.create` method
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-593">CALCITE-593</a>]
-  Validator in `Frameworks` should expand identifiers (Jinfeng Ni)
-* Australian time-zones changed in `tzdata2014f`, Java 1.8.0_31
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-580">CALCITE-580</a>]
-  Average aggregation on an `Integer` column throws `ClassCastException`
-* In Travis, ask Surefire to print results to screen
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-586">CALCITE-586</a>]
-  Prevent JSON serialization of `Signature.internalParameters`
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.0.0-incubating">1.0.0-incubating</a> / 2015-01-31
-{: #v1-0-0}
-
-Calcite's first major release.
-
-Since the previous release we have re-organized the into the `org.apache.calcite`
-namespace. To make migration of your code easier, we have described the
-<a href="https://issues.apache.org/jira/secure/attachment/12681620/mapping.txt">mapping from old to new class names</a>
-as an attachment to
-[<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>].
-
-The release adds SQL support for `GROUPING SETS`, `EXTEND`, `UPSERT` and sequences;
-a remote JDBC driver;
-improvements to the planner engine and built-in planner rules;
-improvements to the algorithms that implement the relational algebra,
-including an interpreter that can evaluate queries without compilation;
-and fixes about 30 bugs.
-
-New features
-
-* SQL
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-494">CALCITE-494</a>]
-    Support `NEXT`/`CURRENT VALUE FOR` syntax for using sequences
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-492">CALCITE-492</a>]
-    Support `UPSERT` statement in parser
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-493">CALCITE-493</a>]
-    Add `EXTEND` clause, for defining columns and their types at query/DML time
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-497">CALCITE-497</a>]
-    Support optional qualifier for column name references
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-356">CALCITE-356</a>]
-    Allow column references of the form `schema.table.column`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-462">CALCITE-462</a>]
-    Allow table functions in `LATERAL` expression
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-282">CALCITE-282</a>]
-    Add `{fn QUARTER(date)}` function (Benoy Antony)
-  * Grouping sets
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-370">CALCITE-370</a>]
-      Support `GROUPING SETS`, `CUBE`, `ROLLUP` in SQL and algebra
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-512">CALCITE-512</a>]
-      Add `GROUP_ID`,`GROUPING_ID`, `GROUPING` functions
-* Planner rule improvements
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-92">CALCITE-92</a>]
-    Optimize away `Project` that merely renames fields
-  * Detect and merge duplicate predicates `AND(x, y, x)` to `AND(x, y)` in more
-    circumstances
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-557">CALCITE-557</a>]
-    Speed up planning by never creating `AbstractConverter`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-545">CALCITE-545</a>]
-    When a projected expression can only have one value, replace with that
-    constant
-  * Grouping sets
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-542">CALCITE-542</a>]
-      Support for `Aggregate` with grouping sets in `RelMdColumnOrigins` (Jesus
-      Camacho Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-533">CALCITE-533</a>]
-      Support for grouping sets in `FilterAggregateTransposeRule` (Jesus Camacho
-      Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-532">CALCITE-532</a>]
-      Support for grouping sets in `AggregateFilterTransposeRule` (Jesus Camacho
-      Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-513">CALCITE-513</a>]
-      Support for grouping sets in `AggregateProjectMergeRule` (Jesus Camacho
-      Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-510">CALCITE-510</a>]
-      Support for grouping sets in `AggregateExpandDistinctAggregatesRule` (Jesus
-      Camacho Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-502">CALCITE-502</a>]
-      Support for grouping sets in `AggregateUnionTransposeRule` (Jesus Camacho
-      Rodriguez)
-    * [<a href="https://issues.apache.org/jira/browse/CALCITE-503">CALCITE-503</a>]
-      Tests to check rules on `Aggregate` operator without grouping sets (Jesus
-      Camacho Rodriguez)
-* Algorithms
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-451">CALCITE-451</a>]
-    Implement theta join, inner and outer, in enumerable convention
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-489">CALCITE-489</a>]
-    Update `Correlate` mechanics and implement `EnumerableCorrelate` (aka nested
-    loops join)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-544">CALCITE-544</a>]
-    Implement `Union` in interpreter
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-562">CALCITE-562</a>]
-    Implement inner `Join` in interpreter and improve handling of scalar expressions
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-543">CALCITE-543</a>]
-    Implement `Aggregate` (including `GROUPING SETS`) in interpreter (Jacques
-    Nadeau)
-  * In progress towards
-    [<a href="https://issues.apache.org/jira/browse/CALCITE-558">CALCITE-558</a>]
-    add `BINDABLE` convention (but `ENUMERABLE` is still the default), and add
-    `ArrayBindable` and `Scalar` interfaces
-* Remote driver
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-93">CALCITE-93</a>]
-    Calcite RPC server
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-94">CALCITE-94</a>]
-    Remote JDBC driver
-  * Make `JsonHandler` and `JsonService` thread-safe
-
-API changes
-
-* The great code re-org
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>]
-    Re-organize package structure
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-419">CALCITE-419</a>]
-    Naming convention for planner rules
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-306">CALCITE-306</a>]
-    Standardize code style for "import package.*;"
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-474">CALCITE-474</a>]
-    Clean up rule naming in order to support enabling/disabling rules
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-460">CALCITE-460</a>]
-    Add `ImmutableBitSet` and replace uses of `BitSet`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-479">CALCITE-479</a>]
-    Migrate `RelNode.getChildExps` to `RelNode.accept(RexShuttle)`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-527">CALCITE-527</a>]
-    Drop `rowType` field and constructor/copy argument of `Calc`
-* Add linq4j and example-csv modules
-  * Remove unused packages in linq4j, and fix checkstyle issues in linq4j and csv
-  * Add calcite-linq4j and calcite-example-csv as POM sub-modules
-  * Import 'optiq-csv' project as 'example/csv/', and add Apache headers
-  * Import 'linq4j' project, and add Apache headers
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-478">CALCITE-478</a>]
-    Move CSV tutorial (Siva Narayanan)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-464">CALCITE-464</a>]
-  Make parser accept configurable max length for SQL identifier
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-465">CALCITE-465</a>]
-  Remove `OneRow` and `Empty` relational expressions; `Values` will suffice
-
-Bug-fixes and internal changes
-
-* Build improvements
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-541">CALCITE-541</a>]
-    Update maven-source-plugin to 2.4 to get speedup in jdk 1.8
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-537">CALCITE-537</a>]
-    Skip overwrite of `NOTICE`, `DEPENDENCIES`, and `LICENSE` files
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-538">CALCITE-538</a>]
-    Generate `Parser.jj` only at first build
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-539">CALCITE-539</a>]
-    Avoid rewrite of `org-apache-calcite-jdbc.properties`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-540">CALCITE-540</a>]
-    Create git.properties file only at first build. This saves time in
-    development at a cost of stale `git.properties`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-536">CALCITE-536</a>]
-    Add `@PackageMarker` to `package-info.java` so maven-compiler skips
-    compilation when the sources are unchanged
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-535">CALCITE-535</a>]
-    Support skip overwrite in hydromatic-resource
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-582">CALCITE-582</a>]
-  `EnumerableTableScan` broken when table has single column
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-575">CALCITE-575</a>]
-  Variant of `ProjectRemoveRule` that considers a project trivial only if its
-  field names are identical (John Pullokkaran)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-571">CALCITE-571</a>]
-  `ReduceExpressionsRule` tries to reduce `SemiJoin` condition to non-equi
-  condition
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-568">CALCITE-568</a>]
-  Upgrade to a version of `pentaho-aggdesigner` that does not pull in
-  `servlet-api`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-567">CALCITE-567</a>]
-  Make `quidem` dependency have scope "test"
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-570">CALCITE-570</a>]
-  `ReduceExpressionsRule` throws "duplicate key" exception
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-561">CALCITE-561</a>]
-  Upgrade parent POM
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-458">CALCITE-458</a>]
-  ArrayIndexOutOfBoundsException when using just a single column in interpreter
-* Fix spurious extra row from `FULL JOIN`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-554">CALCITE-554</a>]
-  Outer join over NULL keys generates wrong result
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-489">CALCITE-489</a>]
-  Teach `CalciteAssert` to respect multiple settings
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-516">CALCITE-516</a>]
-  `GROUP BY` on a `CASE` expression containing `IN` predicate fails (Aman Sinha)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-552">CALCITE-552</a>]
-  Upgrade tpcds (which depends on an old version of guava)
-* Copy identifier when fully-qualifying, so column aliases have the right case
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-548">CALCITE-548</a>]
-  Extend `induce` method to return `CUBE` and `ROLLUP` (Jesus Camacho Rodriguez)
-  * Simplify `Group.induce` by assuming that group sets are sorted
-* Test case for
-  [<a  href="https://issues.apache.org/jira/browse/CALCITE-212">CALCITE-212</a>]
-  Join condition with `OR`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-550">CALCITE-550</a>]
-  Case-insensitive matching of sub-query columns fails
-  * Add more unit tests (Jinfeng Ni)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-448">CALCITE-448</a>]
-  `FilterIntoJoinRule` creates filters containing invalid `RexInputRef`
-* When registering a `RelNode`, be tolerant if it is equivalent to a `RelNode`
-  with different traits
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-547">CALCITE-547</a>]
-  Set nullability while inferring return type of `item(any,...)` operator
-* In Travis CI, enable containers, and cache `.m2` directory
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-534">CALCITE-534</a>]
-  Missing implementation of `ResultSetMetaData.getColumnClassName` (Knut
-  Forkalsrud)
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-506">CALCITE-506</a>]
-  Update `EnumerableRelImplementor.stash` so it is suitable for all kinds of
-  classes
-* Merge join algorithm for `Enumerable`s
-* Efficient `Enumerable` over random-access list
-* Add a test that calls all functions with arguments of all types that they
-  claim to accept
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-511">CALCITE-511</a>]
-  `copy` method in `LogicalAggregate` not copying the indicator value properly
-* Add a model that has lattices and works against HSQLDB
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-509">CALCITE-509</a>]
-  `RelMdColumnUniqueness` uses `ImmutableBitSet.Builder` twice, gets
-  `NullPointerException`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-488">CALCITE-488</a>]
-  `Enumerable<Holder>` does not work if where `Holder` is a custom class
-  with a single field; Calcite tries to treat it as `SCALAR` due to premature
-  `JavaRowFormat.optimize`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-352">CALCITE-352</a>]
-  Throw exception if `ResultSet.next()` is called after `close()`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-403">CALCITE-403</a>]
-  `Enumerable` gives `NullPointerException` with `NOT` on nullable expression
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-469">CALCITE-469</a>]
-  Update example/csv README.md instructions
-* Document `WITH`, `LATERAL`, `GROUPING SETS`, `CUBE`, `ROLLUP`;
-  add descriptions for all built-in functions and operators
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-470">CALCITE-470</a>]
-  Print warning when column type hint is not understood;
-  Update `EMPS.deptno` column Integer &rarr; int
-* Fix `Linq4j.product`; the cartesian product of 0 attributes is one row of 0
-  attributes
-* Update link optiq-mat-plugin &rarr; mat-calcite-plugin
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-467">CALCITE-467</a>]
-  Incorrect namespace in `package-info.java`
-* Add headers, to appease the RAT
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-446">CALCITE-446</a>]
-  CSV adapter should read from directory relative to the model file
-* Add examples of scannable and filterable tables, matching
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-436">CALCITE-436</a>]
-  Simpler SPI to query Table
-* Fix `JdbcTest.testVersion` now that version is 1.0
-* Update release HOWTO
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-0.9.2-incubating">0.9.2-incubating</a> / 2014-11-05
-{: #v0-9-2}
-
-A fairly minor release, and last release before we rename all of the
-packages and lots of classes, in what we expect to call 1.0. If you
-have an existing application, it's worth upgrading to this first,
-before you move on to 1.0.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-436">CALCITE-436</a>]
-  Simpler SPI to query `Table`
-
-API changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-447">CALCITE-447</a>]
-  Change semi-join rules to make use of factories
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-442">CALCITE-442</a>
-  Add `RelOptRuleOperand` constructor that takes a predicate
-
-Bug-fixes and internal changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-397">CALCITE-397</a>]
-  `SELECT DISTINCT *` on reflective schema gives `ClassCastException` at runtime
-* Various lattice improvements.
-* sqlline: Looking for class-path in inconsistent locations.
-* Re-order test suite, so that fast tests are run first.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-444">CALCITE-444</a>]
-  Filters wrongly pushed into full outer join
-* Make it more convenient to unit test `RelMetadataQuery`, and add some more
-  tests for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-443">CALCITE-443</a>]
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-443">CALCITE-443</a>]
-  `getPredicates` from a Union is not correct
-* Update references to web sites, git repositories, jira, mailing lists,
-  travis CI now that [INFRA-8413] is fixed
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-434">CALCITE-435</a>]
-  `FilterAggregateTransposeRule` loses conditions that cannot be pushed
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-435">CALCITE-435</a>]
-  `LoptOptimizeJoinRule` incorrectly re-orders outer joins
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-439">CALCITE-439</a>]
-  `SqlValidatorUtil.uniquify()` may not terminate under some conditions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-438">CALCITE-438</a>]
-  Push predicates through `SemiJoinRel`
-* Add test case for `LIKE ... ESCAPE`.
-* HOWTO: Modify release instructions.
-* Update `DiffRepository` documentation.
-* Add tests for windowed aggregates without `ORDER BY`. (Works already.)
-
-## <a href="https://github.com/apache/calcite/releases/tag/calcite-0.9.1-incubating">0.9.1-incubating</a> / 2014-10-02
-{: #v0-9-1}
-
-This is the first release as Calcite. (The project was previously called Optiq.)
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-430">CALCITE-430</a>]
-  Rename project from Optiq to Calcite
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-426">CALCITE-426</a>]
-  Pool JDBC data sources, to make it easier to pool connections
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-416">CALCITE-416</a>]
-  Execute logical `RelNode`s using an interpreter
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-376">CALCITE-376</a>]
-  Move `SqlRun` into its own artifact,
-  <a href="https://github.com/julianhyde/quidem">Quidem</a>.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-269">CALCITE-269</a>]
-  MongoDB result sets larger than 16MB
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-373">CALCITE-373</a>]
-  `NULL` values in `NOT IN` sub-queries
-* SQL functions:
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-422">CALCITE-422</a>]
-    Add `REGR_SXX` and `REGR_SYY` regression functions
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-421">CALCITE-421</a>]
-    Add `COVAR_POP` and `COVAR_SAMP` aggregate functions
-* Planner rules:
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-425">CALCITE-425</a>]
-    Add `FilterAggregateTransposeRule`, that pushes a filter through an
-    aggregate
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-399">CALCITE-399</a>]
-    Factorize common `AND` factors out of `OR` predicates
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-404">CALCITE-404</a>]
-    `MergeProjectRule` should not construct `RexProgram`s for simple mappings
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-394">CALCITE-394</a>]
-    Add `RexUtil.toCnf()`, to convert expressions to conjunctive normal form
-    (CNF)
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-389">CALCITE-389</a>]
-    `MergeFilterRule` should flatten `AND` condition
-* Lattices:
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-428">CALCITE-428</a>]
-    Use optimization algorithm to suggest which tiles of a lattice to
-    materialize
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-410">CALCITE-410</a>]
-    Allow lattice tiles to satisfy a query by rolling up
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-406">CALCITE-406</a>]
-    Add tile and measure elements to lattice model element
-  * Now, a lattice can materialize an aggregate-join and use it in a subsequent
-    query.
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-402">CALCITE-402</a>]
-    Lattice should create materializations on demand
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-344">CALCITE-344</a>]
-    Lattice data structure
-* Field trimmer:
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-408">CALCITE-408</a>]
-    Make `FieldTrimmer` work with `RelNode` base classes
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-388">CALCITE-388</a>]
-    Handle semi-joins in field trimmer
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-395">CALCITE-395</a>]
-    Make `FieldTrimmer.trimFields(SetOp)` generate `ProjectRel` instead of
-    `CalcRel`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-393">CALCITE-393</a>]
-    If no fields are projected from a table, field trimmer should project a
-    dummy expression
-
-API changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-413">CALCITE-413</a>]
-  Add `RelDataTypeSystem` plugin, allowing different max precision of a
-  `DECIMAL`
-* In `Planner`, query de-correlation no longer requires state in a
-  `SqlToRelConverter`.
-* Factories:
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-392">CALCITE-392</a>]
-    `RelFieldTrimmer` should use factory to create new rel nodes
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-382">CALCITE-382</a>]
-    Refactoring rules to use factories
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-398">CALCITE-398</a>]
-    Move `CalcRel.createProject` methods to `RelOptUtil`
-  * [<a href="https://issues.apache.org/jira/browse/CALCITE-396">CALCITE-396</a>]
-    Change return type of `JoinFactory.createJoin()`; add `SemiJoinFactory`
-
-Bug-fixes and internal changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-386">CALCITE-386</a>]
-  Fix NOTICE
-* Add tests inspired by Derby bugs.
-* Add recent presentation to README.md.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-427">CALCITE-427</a>]
-  Off-by-one issues in `RemoveDistinctAggregateRule`,
-  `AggregateFilterTransposeRule`
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-414">CALCITE-414</a>]
-  Bad class name in `sqlline` shell script
-* Bad package name in `package-info.java` was causing errors in Eclipse.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-412">CALCITE-412</a>]
-  `RelFieldTrimmer`: when trimming `SortRel`, the collation and trait set don't
-  match
-* Add test case for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-411">CALCITE-411</a>]
-  Duplicate column aliases
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-407">CALCITE-407</a>]
-  `RemoveTrivialProjectRule` drops child node's traits
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-409">CALCITE-409</a>]
-  `PushFilterPastProjectRule` should not push filters past windowed aggregates
-* Fix tests on Windows.
-* Don't load `FoodMartQuerySet` unless we have to. It's big.
-* Enable connection pooling in test suite.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-384">CALCITE-384</a>]
-  Add `apache-` prefix to tarball and directory within tarball
-* Freeze hive fmpp > freemarker plugin dependency.
-* Upgrade Janino
-* Removed hardcoded foodmart schema information
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-387">CALCITE-387</a>]
-  CompileException when cast TRUE to nullable boolean
-* Temporary fix for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-390">CALCITE-390</a>]
-  Transitive inference (`RelMdPredicates`) doesn't handle semi-join
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-385">CALCITE-385</a>]
-  Change comment style for Java headers
-* Disable test that is inconistent between JDK 1.7 and 1.8.
-* Fix `git-commit-id-plugin` error when running in Travis-CI.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-381">CALCITE-381</a>]
-  Remove plugin versions from the `<plugins>` tag in root pom
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-383">CALCITE-383</a>]
-  Each jar should have a `git.properties` file describing its exact version
-* Fix `mvn site` on JDK 1.8 and enable in Travis-CI.
-* Status icon based on master branch, not whichever branch happened to build
-  most recently.
-* HOWTO:
-  * Document how to build from git, and how to get jars from maven repo.
-  * Optiq web site
-  * Template emails for Apache votes
-  * Update JIRA cases following release
-  * Instructions for making and verifying a release
-
-## <a href="https://github.com/apache/calcite/releases/tag/optiq-0.9.0-incubating">0.9.0-incubating</a> / 2014-08-19
-{: #v0-9-0}
-
-This is the first release under the Apache incubator process.
-
-New features
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-371">CALCITE-371</a>]
-  Implement `JOIN` whose `ON` clause contains mixed equi and theta
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-369">CALCITE-369</a>]
-  Add `EnumerableSemiJoinRel`, implementation of semi-join in enumerable
-  convention
-* Add class `Strong`, for detecting null-rejecting predicates.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-368">CALCITE-368</a>]
-  Add SemiJoinRule, planner rule to convert project-join-aggregate into semi-join
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-367">CALCITE-367</a>]
-  `PushFilterPastJoinRule` should strengthen join type
-* Add `EquiJoinRel`, base class for joins known to be equi-joins.
-* Implement `CAST(<string> AS <datetime>)` and
-  `<datetime> + <interval>`.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-360">CALCITE-360</a>]
-  Introduce a rule to infer predicates from equi-join conditions
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-349">CALCITE-349</a>]
-  Add heuristic join-optimizer that can generate bushy joins
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-346">CALCITE-346</a>]
-  Add commutative join rule
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-347">CALCITE-347</a>]
-  In `SqlRun`, add `!plan` command
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-314">CALCITE-314</a>]
-  Allow simple UDFs based on methods
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-327">CALCITE-327</a>]
-  Rules should use base class to find rule match & use factory for object
-  creation
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-316">CALCITE-316</a>]
-  In `SqlRun`, match output regardless of order if `ORDER BY` not present
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-300">CALCITE-300</a>]
-  Support multiple parameters in `COUNT(DISTINCT x, y, ...)`
-
-API changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-343">CALCITE-343</a>]
-  RelDecorrelator should build its own mappings, not inherit from SqlToRelConverter
-* Remove deprecated methods.
-* Convert `Hook` to use Guava `Function` (was linq4j `Function1`).
-* Add fluent method `withHook`, to more easily add hooks in tests.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-321">CALCITE-321</a>]
-  Add support for overriding implementation of `CompoundIdentifier` in
-  `SqlParser`.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-322">CALCITE-322</a>]
-  Add support for `SqlExplain`, `SqlOrderBy` and `SqlWith` to support
-  `SqlShuttle` use.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-323">CALCITE-323</a>]
-  Override `SqlUnresolvedFunction.inferReturnType()` to return `ANY` type
-  so framework implementors can support late bound function implementations.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-324">CALCITE-324</a>]
-  Add `ViewExpander` for `Planner` in `Frameworks`. Expose additional
-  properties of `ViewTable` to allow subclassing.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-247">CALCITE-247</a>]
-  Add `Context` and `FrameworkConfig`
-
-Bug-fixes and internal changes
-
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-380">CALCITE-380</a>]
-  Downgrade to Guava 11.0.2
-* Move several .md files into new 'doc' directory, to keep the root directory simple.
-* Add DISCLAIMER
-* Update history and HOWTO
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-377">CALCITE-377</a>]
-  UnregisteredDriver should catch, log and re-throw NoClassDefFoundError
-* Inherit maven-release-plugin from Apache POM.
-* Test case for
-  [<a href="https://issues.apache.org/jira/browse/CALCITE-373">CALCITE-373</a>]
-  NOT IN and NULL values
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-372">CALCITE-372</a>]
-  Change `LoptOptimizeJoinRule` &amp; `PushFilterPast`* rules to use factory
-* Upgrade `maven-checkstyle-plugin`.
-* Add class `Holder`, a mutable slot that can contain one object.
-* Remove the 2-minute wait at the top of the hour for tests of
-  `CURRENT_TIME`, etc.
-* Tune `ImmutableIntList`'s iterators.
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-364">CALCITE-364</a>]
-  Validator rejects valid `WITH ... ORDER BY` query
-* [<a href="https://issues.apache.org/jira/browse/CALCITE-363">CALCITE-363</a>]
-  Use `dependencyManagement` and `pluginManagement` in POM files
-* Add `FilterFactory`.
-* Add `README` file, incubation disclaimers, and how-to build and running tests.
-* Add `KEYS` and start how-to for making snapshots and releases.
-* Capital case component names; inherit license info 

<TRUNCATED>

[22/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/history.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/history.md b/avatica/site/_docs/history.md
new file mode 100644
index 0000000..d46bfc8
--- /dev/null
+++ b/avatica/site/_docs/history.md
@@ -0,0 +1,2343 @@
+---
+layout: docs
+title: History
+permalink: "/docs/history.html"
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+For a full list of releases, see
+<a href="https://github.com/apache/calcite/releases">github</a>.
+Downloads are available on the
+[downloads page]({{ site.baseurl }}/downloads/).
+
+## 1.7.0 / (Under Development)
+{: #v1-7-0}
+
+One notable change is that the use of JUL (java.util.logging) has been replaced
+with [SLF4J](http://slf4j.org/). SLF4J provides an API which Calcite can use
+independent of the logging implementation. This ultimately provides additional
+flexibility to users, allowing them to configure Calcite's logging within their
+own chosen logging framework. This work was done in [CALCITE-669](https://issues.apache.org/jira/browse/CALCITE-669).
+
+For users experienced with configuring JUL in Calcite previously, there are some
+differences as some the JUL logging levels do not exist in SLF4J: `FINE`,
+`FINER`, and `FINEST`, specifically. To deal with this, `FINE` was mapped
+to SLF4J's `DEBUG` level, while `FINER` and `FINEST` were mapped to SLF4J's `TRACE`.
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.6.0">1.6.0</a> / 2016-01-22
+{: #v1-6-0}
+
+As usual in this release, there are new SQL features, improvements to
+planning rules and Avatica, and lots of bug fixes. We'll spotlight a
+couple of features make it easier to handle complex queries.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
+allows you to represent sub-queries (`EXISTS`, `IN` and scalar) as
+`RexSubQuery`, a kind of expression in the relational algebra. Until
+now, the sql-to-rel converter was burdened with expanding sub-queries,
+and people creating relational algebra directly (or via RelBuilder)
+could only create 'flat' relational expressions. Now we have planner
+rules to expand and de-correlate sub-queries.
+
+Metadata is the fuel that powers query planning. It includes
+traditional query-planning statistics such as cost and row-count
+estimates, but also information such as which columns form unique
+keys, unique and what predicates are known to apply to a relational
+expression's output rows. From the predicates we can deduce which
+columns are constant, and following
+[<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
+we can now remove constant columns from `GROUP BY` keys.
+
+Metadata is often computed recursively, and it is hard to safely and
+efficiently calculate metadata on a graph of `RelNode`s that is large,
+frequently cyclic, and constantly changing.
+[<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
+introduces a context to each metadata call. That context can detect
+cyclic metadata calls and produce a safe answer to the metadata
+request. It will also allow us to add finer-grained caching and
+further tune the metadata layer.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
+  Represent sub-query as a `RexNode`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-854">CALCITE-854</a>]
+  Implement `UNNEST ... WITH ORDINALITY`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1003">CALCITE-1003</a>]
+  Utility to convert `RelNode` to SQL (Amogh Margoor)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1010">CALCITE-1010</a>]
+    `FETCH/LIMIT` and `OFFSET` in RelToSqlConverter (Amogh Margoor)
+  * Move code from `JdbcImplementor` and `JdbcRules` to new class
+    `SqlImplementor`
+  * Deduce dialect's null collation from `DatabaseMetaData`
+  * Fix `RelToSqlConverterTest` on Windows
+* Following
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-897">CALCITE-897</a>],
+  empty string for `boolean` properties means true
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-992">CALCITE-992</a>]
+  Validate and resolve sequence reference as a `Table` object
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-968">CALCITE-968</a>]
+  Stream-to-relation and stream-to-stream joins (Milinda Pathirage)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1041">CALCITE-1041</a>]
+  User-defined function that returns `DATE` or `TIMESTAMP` value
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-986">CALCITE-986</a>]
+  User-defined function with `DATE` or `TIMESTAMP` parameters
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-958">CALCITE-958</a>]
+  Overloaded Table Functions with named arguments (Julien Le Dem)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-970">CALCITE-970</a>]
+  If `NULLS FIRST`/`NULLS LAST` not specified, sort `NULL` values high
+
+Avatica features and bug fixes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1040">CALCITE-1040</a>]
+  Differentiate better between arrays and scalars in protobuf
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-934">CALCITE-934</a>]
+  Use an OS-assigned ephemeral port for `CalciteRemoteDriverTest`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-767">CALCITE-767</a>]
+  Create Avatica RPC endpoints for commit and rollback commands
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-983">CALCITE-983</a>]
+  Handle nulls in `ErrorResponse`'s protobuf representation better
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-989">CALCITE-989</a>]
+  Add server's address in each response
+* Fix some bugs found by static analysis
+* Make all `equals` and `hashCode` methods uniform
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-962">CALCITE-962</a>]
+  Propagate the cause, not just the cause's message, from `JdbcMeta`
+
+Planner rules
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1057">CALCITE-1057</a>]
+  Add `RelMetadataProvider` parameter to standard planner `Program`s
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1055">CALCITE-1055</a>]
+  `SubQueryRemoveRule` should create `Correlate`, not `Join`, for correlated
+  sub-queries
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-978">CALCITE-978</a>]
+  Enable customizing constant folding rule behavior when a `Filter` simplifies
+  to false (Jason Altekruse)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-977">CALCITE-977</a>]
+  Make the constant expression `Executor` configurable in `FrameworkConfig`
+  (Jason Altekruse)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1058">CALCITE-1058</a>]
+  Add method `RelBuilder.empty`, and rewrite LIMIT 0 and WHERE FALSE to it
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-996">CALCITE-996</a>]
+  Simplify predicate when we create a `Filter` operator
+* Simplify `RexProgram`, in particular `(NOT CASE ... END) IS TRUE`, which
+  occurs in when `NOT IN` is expanded
+* Fix variant of
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-923">CALCITE-923</a>]
+  that occurs in `RelOptRulesTest.testPushFilterPastProject`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
+  and
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-1038">CALCITE-1038</a>]
+  Planner rule that removes `Aggregate` keys that are constant
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1018">CALCITE-1018</a>]
+  `SortJoinTransposeRule` not firing due to `getMaxRowCount(RelSubset)` returning
+  null
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1019">CALCITE-1019</a>]
+  `RelMdUtil.checkInputForCollationAndLimit()` was wrong with `alreadySorted`
+  check
+* Not safe to use '=' for predicates on constant expressions that might be null
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-993">CALCITE-993</a>]
+  Pull up all constant expressions, not just literals, as predicates
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1005">CALCITE-1005</a>]
+  Handle null in `getMaxRowCount` for `Aggregate` (Mike Hinchey)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-995">CALCITE-995</a>]
+  Sort transpose rules might fall in an infinite loop
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-987">CALCITE-987</a>]
+  Pushing `LIMIT 0` results in an infinite loop (Pengcheng Xiong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-988">CALCITE-988</a>]
+  `FilterToProjectUnifyRule.invert(MutableRel, MutableRel, MutableProject)`
+  works incorrectly
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-969">CALCITE-969</a>]
+  Composite `EnumerableSort` with `DESC` wrongly sorts `NULL` values low
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-959">CALCITE-959</a>]
+  Add description to `SortProjectTransposeRule`'s constructor
+
+Bug fixes, API changes and minor enhancements
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1060">CALCITE-1060</a>]
+  Fix test deadlock by initializing `DriverManager` before registering `AlternatingDriver`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1047">CALCITE-1047</a>]
+  `ChunkList.clear` throws `AssertionError`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1053">CALCITE-1053</a>]
+  CPU spin, `ReflectiveRelMetadataProvider.apply` waiting for `HashMap.get`
+* Upgrade toolbox, to fix line length issue on Windows
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1051">CALCITE-1051</a>]
+  Underflow exception due to scaling IN clause literals (Frankie Bollaert)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-975">CALCITE-975</a>]
+  Allow Planner to return validated row type together with SqlNode
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1020">CALCITE-1020</a>]
+  Add `MILLISECOND` in `TimeUnit` (Pengcheng Xiong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
+  Detect cycles when computing statistics
+  (**This is a breaking change**.)
+* Tune algorithm that deduces the return type of `AND` expression
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-842">CALCITE-842</a>]
+  Decorrelator gets field offsets confused if fields have been trimmed
+* Fix `NullPointerException` in `SqlJoin.toString()`
+* Add `ImmutableBitSet.rebuild()`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-915">CALCITE-915</a>]
+  Tests now unset `ThreadLocal` values on exit
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1036">CALCITE-1036</a>]
+  `DiffRepository` should not insert new resources at the end of the repository
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-955">CALCITE-955</a>]
+  `Litmus` (continuation-passing style for methods that check invariants)
+* `RelBuilder.project` now does nothing if asked to project the identity with
+  the same field names
+* Deprecate some `Util` methods, and upgrade last Maven modules to JDK 1.7
+* Document `RelOptPredicateList`
+* Add `ImmutableNullableList.copyOf(Iterable)`
+* Fix "endPosTable already set" error from `javac`
+* Add benchmark of `Parser.create(sql).parseQuery()`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1042">CALCITE-1042</a>]
+  Ensure that `FILTER` is `BOOLEAN NOT NULL`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1039">CALCITE-1039</a>]
+  Assign a `SqlKind` value for each built-in aggregate function
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1030">CALCITE-1030</a>]
+  JSON `ModelHandler` calling `SchemaPlus.setCacheEnabled()` causes
+  `UnsupportedOperationException` when using `SimpleCalciteSchema`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1028">CALCITE-1028</a>]
+  Move populate materializations after sql-to-rel conversion
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1034">CALCITE-1034</a>]
+  Use a custom checker for code style rules that Checkstyle cannot express
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1032">CALCITE-1032</a>]
+  Verify javadoc of private methods
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1015">CALCITE-1015</a>]
+  `OFFSET 0` causes `AssertionError` (Zhen Wang)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1024">CALCITE-1024</a>]
+  In a planner test, if a rule should have no effect, state that explicitly
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1016">CALCITE-1016</a>]
+  `GROUP BY *constant*` on empty relation should return 0 rows
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1022">CALCITE-1022</a>]
+  Rename `.oq` Quidem files to `.iq`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-980">CALCITE-980</a>]
+  Fix `AND` and `OR` implementation in `Enumerable` convention
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-459">CALCITE-459</a>]
+  When parsing SQL, allow single line comment on last line (Zhen Wang)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1009">CALCITE-1009</a>]
+  `SelfPopulatingList` is not thread-safe
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1008">CALCITE-1008</a>]
+  Replace `Closeable` with `AutoCloseable`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-1001">CALCITE-1001</a>]
+  Upgrade to quidem-0.7
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-990">CALCITE-990</a>]
+  In `VolcanoPlanner`, populate `RelOptRuleCall.nodeInputs` for operands of type
+  "any"
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-966">CALCITE-966</a>]
+  `VolcanoPlanner` now clears `ruleNames` in order to avoid rule name
+  conflicting error
+* Factor user-defined function tests from `JdbcTest` to `UdfTest`, and classes
+  into `Smalls`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-974">CALCITE-974</a>]
+  Exception while validating `DELETE` (Yuri Au Yong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-964">CALCITE-964</a>]
+  Rename `timezone` connection property to `timeZone`
+
+Web site and documentation
+
+* Avatica
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1033">CALCITE-1033</a>]
+    Introduce Avatica protobuf documentation
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-1029">CALCITE-1029</a>]
+     Add "purpose" descriptions to Avatica JSON docs
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-984">CALCITE-984</a>]
+    Massive cleanup of Avatica JSON docs
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-861">CALCITE-861</a>]
+  Be explicit that `mvn test` needs to be invoked
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-997">CALCITE-997</a>]
+  Document keywords
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-979">CALCITE-979</a>]
+  Broken links in web site
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-961">CALCITE-961</a>]
+  Web site: Add downloads and Apache navigation links
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-960">CALCITE-960</a>]
+  Download links for pgp, md5, `KEYS` files, and direct from mirrors
+* Remove embedded date-stamps from javadoc; add javadoc for test classes
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-965">CALCITE-965</a>]
+  Link to downloads page from each release news item
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.5.0">1.5.0</a> / 2015-11-06
+{: #v1-5-0}
+
+Our first release as a top-level Apache project!
+
+Avatica has undergone major improvements,
+including a new RPC layer that uses
+[protocol buffers](https://developers.google.com/protocol-buffers/),
+support for DML statements, better support for bind variables and
+unique identifiers for connections and statements.
+
+There are lots of improvements to planner rules, and the logic
+that replaces relational expressions with equivalent materializations.
+
+We continue to find more uses for
+[RelBuilder]({{ site.baseurl }}/docs/algebra.html).
+We now recommend that you use `RelBuilder` whenever you create
+relational expressions within a planner rule; the rule can then be
+re-used to create different sub-classes of relational expression, and
+the builder will perform simple optimizations automatically.
+
+Using `RelBuilder` we built Piglet,
+a subset of the classic Hadoop language
+[Pig](https://pig.apache.org/).
+Pig is particularly interesting because it makes heavy use of nested
+multi-sets.  You can follow this example to implement your own query
+language, and immediately taking advantage of Calcite's back-ends and
+optimizer rules. It's all just algebra, after all!
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-911">CALCITE-911</a>]
+  Add a variant of `CalciteSchema` that does not cache sub-objects
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-845">CALCITE-845</a>]
+  Derive `SUM`’s return type by a customizable policy (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-916">CALCITE-916</a>]
+  Support table function that implements `ScannableTable`
+  * Example table function that generates mazes and their solutions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-941">CALCITE-941</a>]
+  Named, optional and `DEFAULT` arguments to function calls;
+  support named arguments when calling table functions and table macros
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-910">CALCITE-910</a>]
+  Improve handling of `ARRAY`, `MULTISET`, `STRUCT` types
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-879">CALCITE-879</a>]
+  `COLLECT` aggregate function
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-546">CALCITE-546</a>]
+  Allow table, column and field called '*'
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-893">CALCITE-893</a>]
+  Theta join in JDBC adapter
+* Linq4j: Implement `EnumerableDefaults` methods (MiNG)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-823">CALCITE-823</a>]
+  Add `ALTER ... RESET` statement (Sudheesh Katkam)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-881">CALCITE-881</a>]
+  Allow schema.table.column references in `GROUP BY`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-852">CALCITE-852</a>]
+  DDL statements
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-851">CALCITE-851</a>]
+  Add original SQL string as a field in the parser
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-819">CALCITE-819</a>]
+  Add `RelRoot`, a contract for the result of a relational expression
+
+Avatica features and bug fixes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-951">CALCITE-951</a>]
+  Print the server-side stack in the local exception (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-936">CALCITE-936</a>]
+  Make HttpServer configurable (Navis Ryu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-903">CALCITE-903</a>]
+  Enable Avatica client to recover from missing server-side state (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-921">CALCITE-921</a>]
+  Fix incorrectness when calling `getString()` on binary data (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-913">CALCITE-913</a>]
+  Construct proper `ColumnMetaData` for arrays (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-871">CALCITE-871</a>]
+  In `JdbcMeta`, register each statement using an id from a generator (Bruno
+  Dumon)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-645">CALCITE-645</a>]
+  Implement `AvaticaSqlException` to pass server-side exception information to
+  clients (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-912">CALCITE-912</a>]
+  Add Avatica `OpenConnectionRequest` (Bruno Dumon)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-919">CALCITE-919</a>]
+  Avoid `setScale` on `BigDecimal` when scale is 0 (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-927">CALCITE-927</a>]
+  Call finagle for all calls that return ResultSetResponses (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-705">CALCITE-705</a>]
+  DML in Avatica, and split `Execute` out from `Fetch` request (Yeong Wei)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-914">CALCITE-914</a>]
+  Add `JsonSubType` for `ExecuteResponse`, and fix JSON docs (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-905">CALCITE-905</a>]
+  `getTables` returns empty result in `JdbcMeta` (Jan Van Besien)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-906">CALCITE-906</a>]
+  Avatica `JdbcMeta` statement IDs are not unique
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-866">CALCITE-866</a>]
+  Break out Avatica documentation and add JSON reference (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-843">CALCITE-843</a>]
+  `AvaticaConnection.getAutoCommit` throws `NullPointerException`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-840">CALCITE-840</a>]
+  Protocol buffer serialization over HTTP for Avatica Server (Josh Elser)
+
+Materializations
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-952">CALCITE-952</a>]
+  Organize applicable materializations in reversed topological order (Maryann
+  Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-890">CALCITE-890</a>]
+  Register all combinations of materialization substitutions (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-891">CALCITE-891</a>]
+  When substituting materializations, match `TableScan` without `Project`
+  (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-890">CALCITE-890</a>]
+  Register all combinations of materialization substitutions (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-925">CALCITE-925</a>]
+  Match materialized views when predicates contain strings and ranges (Amogh
+  Margoor)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-793">CALCITE-793</a>]
+  Planner requires unnecessary collation when using materialized view (Maryann
+  Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-825">CALCITE-825</a>]
+  Allow user to specify sort order of an `ArrayTable`
+
+Planner rules
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-953">CALCITE-953</a>]
+  Improve `RelMdPredicates` to deal with `RexLiteral` (Pengcheng Xiong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-939">CALCITE-939</a>]
+  Variant of `SortUnionTransposeRule` for order-preserving `Union`
+  (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-931">CALCITE-931</a>]
+  Wrong collation trait in `SortJoinTransposeRule` for right joins
+  (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-938">CALCITE-938</a>]
+  More accurate rowCount for `Aggregate` applied to already unique keys
+  (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-935">CALCITE-935</a>]
+  Improve how `ReduceExpressionsRule` handles duplicate constraints (Pengcheng
+  Xiong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-922">CALCITE-922</a>]
+  Extract value of an `INTERVAL` literal (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-889">CALCITE-889</a>]
+  Implement `SortUnionTransposeRule` (Pengcheng Xiong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-909">CALCITE-909</a>]
+  Make `ReduceExpressionsRule` extensible
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-856">CALCITE-856</a>]
+  Make more rules extensible
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-902">CALCITE-902</a>]
+  Match nullability when reducing expressions in a `Project`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-895">CALCITE-895</a>]
+  Simplify "(`CASE` ... `END`) = constant" inside `AND` or `OR` (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-828">CALCITE-828</a>]
+  Use RelBuilder in rules rather than type-specific RelNode factories
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-892">CALCITE-892</a>]
+  Implement `SortJoinTransposeRule`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-876">CALCITE-876</a>]
+  After pushing `LogicalProject` past `LogicalWindow`, adjust references to
+  constants properly (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-844">CALCITE-844</a>]
+  Push `Project` through `Window` (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-841">CALCITE-841</a>]
+  Redundant windows when window function arguments are expressions (Hsuan-Yi
+  Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-846">CALCITE-846</a>]
+  Push `Aggregate` with `Filter` through `Union(all)`
+
+RelBuilder and Piglet
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-933">CALCITE-933</a>]
+  `RelBuilder.scan()` now gives a nice exception if the table does not exist
+  (Andy Grove)
+* Fix Piglet `DUMP` applied to multisets and structs
+* Multisets and `COLLECT` in Piglet
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-785">CALCITE-785</a>]
+  Add "Piglet", a subset of Pig Latin on top of Calcite algebra
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-869">CALCITE-869</a>]
+  Add `VALUES` command to Piglet
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-868">CALCITE-868</a>]
+  Add API to execute queries expressed as `RelNode`
+* In RelBuilder, build expressions by table alias
+
+Bug fixes, API changes and minor enhancements
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-948">CALCITE-948</a>]
+  Indicator columns not preserved by `RelFieldTrimmer`
+* Fix Windows issues (line endings and checkstyle suppressions)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-937">CALCITE-937</a>]
+  User-defined function within view
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-926">CALCITE-926</a>]
+  Rules fail to match because of missing link to parent equivalence set
+  (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-908">CALCITE-908</a>]
+  Bump protobuf to 3.0.0-beta-1, fix deprecations and update docs (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-932">CALCITE-932</a>]
+  Fix muddled columns when `RelFieldTrimmer` is applied to `Aggregate`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-930">CALCITE-930</a>]
+  Now Calcite is a top-level project, remove references to "incubating"
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-929">CALCITE-929</a>]
+  Calls to `AbstractRelNode` may result in NPE
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-923">CALCITE-923</a>]
+  Type mismatch when converting `LEFT JOIN` to `INNER`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-666">CALCITE-666</a>]
+  Anti-semi-joins against JDBC adapter give wrong results (Yeong Wei)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-918">CALCITE-918</a>]
+  `createProject` in `RelOptUtil` should uniquify field names
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-792">CALCITE-792</a>]
+  Obsolete `RelNode.isKey` and `isDistinct` methods
+* Allow FlatLists of different length to be compared
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-898">CALCITE-898</a>]
+  Type of 'Java<Long> * `INTEGER`' should be `BIGINT`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-894">CALCITE-894</a>]
+  Do not generate redundant column alias for the left relation when
+  translating `IN` subquery (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-897">CALCITE-897</a>]
+  Enable debugging using "-Dcalcite.debug"
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-885">CALCITE-885</a>]
+  Add Oracle test environment
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-888">CALCITE-888</a>]
+  Overlay window loses `PARTITION BY` list (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-886">CALCITE-886</a>]
+  System functions in `GROUP BY` clause
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-860">CALCITE-860</a>]
+  Correct LICENSE file for generated web site
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-882">CALCITE-882</a>]
+  Allow web site to be deployed not as the root directory of the web server
+  (Josh Elser)
+* Upgrade parent POM to apache-17
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
+  Synchronize HSQLDB at a coarse level using a Lock (Josh Elser)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-870">CALCITE-870</a>]
+  Remove copyright content from archers.json
+* Replace `Stack` with `ArrayDeque`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-874">CALCITE-874</a>]
+  `ReflectiveRelMetadataProvider` is not thread-safe
+* Add `LogicalWindow.create()`
+* Add `ImmutableBitSet.get(int, int)`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-865">CALCITE-865</a>]
+  Unknown table type causes `NullPointerException` in `JdbcSchema`
+  * Add table types used by Oracle and DB2
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-862">CALCITE-862</a>]
+  `JdbcSchema` gives `NullPointerException` on non-standard column type (Marc
+  Prud'hommeaux)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-847">CALCITE-847</a>]
+  `AVG` window function in `GROUP BY` gives `AssertionError` (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-827">CALCITE-827</a>]
+  Calcite incorrectly permutes columns of `OVER` query (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-809">CALCITE-809</a>]
+  `TableScan` does not support large/infinite scans (Jesse Yates)
+* Lazily create exception only when it needs to be thrown (Marc Prud'hommeaux)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-812">CALCITE-812</a>]
+  Make JSON reader and writer use properly quoted key names (Marc
+  Prud'hommeaux)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-820">CALCITE-820</a>]
+  Validate that window functions have `OVER` clause (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-824">CALCITE-824</a>]
+  Type inference when converting `IN` clause to semijoin (Josh Wills)
+
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.4.0-incubating">1.4.0-incubating</a> / 2015-09-02
+{: #v1-4-0}
+
+In addition to a large number of bug fixes and minor enhancements,
+this release includes improvements to lattices and materialized views,
+and adds a builder API so that you can easily create relational
+algebra expressions.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-748">CALCITE-748</a>]
+      Add `RelBuilder`, builder for expressions in relational algebra
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-758">CALCITE-758</a>]
+      Use more than one lattice in the same query (Rajat Venkatesh)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-761">CALCITE-761</a>]
+      Pre-populated materializations (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-786">CALCITE-786</a>]
+      Detect if materialized view can be used to rewrite a query in
+  non-trivial cases (Amogh Margoor)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-732">CALCITE-732</a>]
+      Implement multiple distinct-`COUNT` using `GROUPING SETS`
+* Add various `BitSet` and `ImmutableBitSet` utilities
+
+Website updates
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-810">CALCITE-810</a>]
+      Add committers' organizations to the web site
+* Add news item (XLDB best lighting talk), and some talks
+* Fix javadoc links
+* Add license notice for web site
+* Wrap file header in HTML comments
+* How to release
+* Move disclaimer out of every page's footer and into home page and downloads
+  page
+* For web site files, add license headers where possible, apache-rat
+  exclusions otherwise
+* Calcite DOAP
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-355">CALCITE-355</a>]
+      Web site
+
+Bug fixes, API changes and minor enhancements
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-741">CALCITE-741</a>]
+      Ensure that the source release's `DEPENDENCIES` file includes all module
+  dependencies
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-743">CALCITE-743</a>]
+      Ensure only a single source assembly is executed
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-850">CALCITE-850</a>]
+      Remove push down expressions from `FilterJoinRule` and create a new rule
+  for it
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-834">CALCITE-834</a>]
+      `StackOverflowError` getting predicates from the metadata provider
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-833">CALCITE-833</a>]
+      `RelOptUtil.splitJoinCondition` incorrectly splits a join condition
+  (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-822">CALCITE-822</a>]
+      Add a unit test case to test collation of `LogicalAggregate`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-822">CALCITE-822</a>]
+      Revert incorrect `LogicalAggregate` collation inferring logic made in
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-783">CALCITE-783</a>]
+  (Milinda Pathirage)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-826">CALCITE-826</a>]
+      Use `ProjectFactory` in `AggregateJoinTranposeRule` and `FilterJoinRule`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-821">CALCITE-821</a>]
+      `Frameworks` gives NPE when `FrameworkConfig` has no default schema
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-811">CALCITE-811</a>]
+      Extend `JoinProjectTransposeRule` with option to support outer joins
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-805">CALCITE-805</a>]
+      Add support for using an alternative grammar specification for left and
+  right curly braces. Additionally, add support for including addition token
+  manager declarations
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-803">CALCITE-803</a>]
+      Add `MYSQL_ANSI` Lexing policy
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-717">CALCITE-717</a>]
+      Compare BINARY and VARBINARY on unsigned byte values (Low Chin Wei)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-814">CALCITE-814</a>]
+      `RexBuilder` reverses precision and scale of `DECIMAL` literal
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-813">CALCITE-813</a>]
+      Upgrade `updateCount`, `maxRows` from int to long
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-714">CALCITE-714</a>]
+      When de-correlating, push join condition into subquery
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-751">CALCITE-751</a>]
+      Push aggregate with aggregate functions through join
+* Add `RelBuilder.avg`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-806">CALCITE-806</a>]
+      `ROW_NUMBER` should emit distinct values
+* Document JSON model, making javadoc consistent with the model reference
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-808">CALCITE-808</a>]
+      Optimize `ProjectMergeRule`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-791">CALCITE-791</a>]
+      Optimize `RelOptUtil.pushFilterPastProject`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-783">CALCITE-783</a>]
+      Infer collation of `Project` using monotonicity (Milinda Pathirage)
+* Change the argument types of `SqlOperator.getMonotonicity` to allow it to be
+  used for `RexNode` as well as `SqlNode`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-800">CALCITE-800</a>]
+      Window function defined within another window function should be invalid
+  (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-787">CALCITE-787</a>]
+      Star table wrongly assigned to materialized view (Amogh Margoor)
+* Remove duplicate resources from XML test reference files
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-795">CALCITE-795</a>]
+      Loss of precision when sending a decimal number via the remote JSON
+  service (Lukáš Lalinský)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-774">CALCITE-774</a>]
+      When `GROUP BY` is present, ensure that window function operands only
+  refer to grouping keys (Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-799">CALCITE-799</a>]
+      Incorrect result for `HAVING count(*) > 1`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-801">CALCITE-801</a>]
+      `NullPointerException` using `USING` on table alias with column aliases
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-390">CALCITE-390</a>]
+      Infer predicates for semi-join
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-789">CALCITE-789</a>]
+      `MetaImpl.MetaCatalog` should expose `TABLE_CAT` instead of
+      `TABLE_CATALOG`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-752">CALCITE-752</a>]
+      Add back sqlline as a dependency to csv example
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-780">CALCITE-780</a>]
+      HTTP error 413 when sending a long string to the Avatica server
+* In `RelBuilder`, calling `sort` then `limit` has same effect as calling
+  `sortLimit`
+* Add `Ord.reverse`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-788">CALCITE-788</a>]
+      Allow `EnumerableJoin` to be sub-classed (Li Yang)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-280">CALCITE-280</a>]
+      `BigDecimal` underflow (Li Yang)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-763">CALCITE-763</a>]
+      Missing translation from `Sort` to `MutableSort` (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-770">CALCITE-770</a>]
+      Ignore window aggregates and ranking functions when finding aggregate
+  functions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-765">CALCITE-765</a>]
+      Set `Content-Type` from the RPC server to `application/json` (Lukáš Lalinský)
+* Fix Windows line-endings in `RelBuilderTest`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-727">CALCITE-727</a>]
+      Constant folding involving `CASE` and `NULL`
+* Related to
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-758">CALCITE-758</a>],
+  speed up matching by not considering tiles separately from other
+  materialized views
+* Test case and workaround for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-760">CALCITE-760</a>]
+      `Aggregate` recommender blows up if row count estimate is too high
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-753">CALCITE-753</a>]
+      `Aggregate` operators may derive row types with duplicate column names
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-457">CALCITE-457</a>]
+      Push condition of non-ansi join into join operator
+* Change jsonRequest encoding to UTF-8 (Guitao Ding)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-757">CALCITE-757</a>]
+      Fix expansion of view of another view (Venki Korukanti)
+* Fix coverity warnings
+* Remove deprecated `SqlTypeName` methods
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-754">CALCITE-754</a>]
+      Validator error when resolving `OVER` clause of `JOIN` query
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-429">CALCITE-429</a>]
+      Cardinality provider for use by lattice algorithm
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-740">CALCITE-740</a>]
+      Redundant `WHERE` clause causes wrong result in MongoDB adapter
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-665">CALCITE-665</a>]
+      `ClassCastException` in MongoDB adapter
+* Separate `TableFactory` from suggested table name, so one `TableFactory` can be
+  used for several tables
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-749">CALCITE-749</a>]
+      Add `MaterializationService.TableFactory` (Rajat Venkatesh)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-718">CALCITE-718</a>]
+      Enable fetch to work for `Statement.execute()` for Avatica (Xavier Leong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-712">CALCITE-712</a>]
+      Obey `setMaxRows` for statement execute (Xavier Leong)
+* Add `LoggingLocalJsonService`, to make it easier to test that JDBC requests
+  cause the right RPCs
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-708">CALCITE-708</a>]
+      Implement `DatabaseMetaData.getTypeInfo` (Xavier Leong)
+* Enable Travis CI on new-master branch and bug-fix branches named
+  "NNN-description"
+* Clean up
+* Upgrade tpcds
+* Make `JdbcTest.testVersion` more permissive, so that `version.major` and
+  `version.minor` can be set just before a release, rather than just after as at
+  present
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.3.0-incubating">1.3.0-incubating</a> / 2015-05-30
+{: #v1-3-0}
+
+Mainly bug-fixes, but this release adds support for
+<a href="https://issues.apache.org/jira/browse/CALCITE-505">modifiable views</a>
+and
+<a href="https://issues.apache.org/jira/browse/CALCITE-704">filtered aggregate functions</a>
+and various improvements to Avatica.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-505">CALCITE-505</a>]
+  Support modifiable view
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-704">CALCITE-704</a>]
+  `FILTER` clause for aggregate functions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-522">CALCITE-522</a>]
+  In remote JDBC driver, transmit static database properties as a map
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-661">CALCITE-661</a>]
+  Remote fetch in Calcite JDBC driver
+* Support Date, Time, Timestamp parameters
+
+API changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-722">CALCITE-722</a>]
+  Rename markdown files to lower-case
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-697">CALCITE-697</a>]
+  Obsolete class `RelOptQuery`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-693">CALCITE-693</a>]
+  Allow clients to control creation of `RelOptCluster`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-691">CALCITE-691</a>]
+  Allow projects to supply alternate SQL parser
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-675">CALCITE-675</a>]
+  Enable `AggregateProjectMergeRule` in standard rule set
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-679">CALCITE-679</a>]
+  Factory method for `SemiJoin`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-674">CALCITE-674</a>]
+  Add a `SWAP_OUTER` static instance to `JoinCommuteRule` (Maryann Xue)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-735">CALCITE-735</a>]
+  `Primitive.DOUBLE.min` should be large and negative
+
+Bug-fixes and internal changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-688">CALCITE-688</a>]
+  `splitCondition` does not behave correctly when one side of the condition
+  references columns from different inputs
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-259">CALCITE-259</a>]
+  Using sub-queries in `CASE` statement against JDBC tables generates invalid
+  Oracle SQL (Yeong Wei)
+* In sample code in README.md, rename optiq to calcite (Ethan)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-720">CALCITE-720</a>]
+  `VolcanoPlanner.ambitious` comment doc is inconsistent (Santiago M. Mola)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-729">CALCITE-729</a>]
+  `IndexOutOfBoundsException` in `ROLLUP` query on JDBC data source
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-733">CALCITE-733</a>]
+  Multiple distinct-`COUNT` query gives wrong results
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-730">CALCITE-730</a>]
+  `ClassCastException` in table from `CloneSchema`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-728">CALCITE-728</a>]
+  Test suite hangs on Windows
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-723">CALCITE-723</a>]
+  Document lattices
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-515">CALCITE-515</a>]
+  Add Apache headers to markdown files
+* Upgrade quidem
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-716">CALCITE-716</a>]
+  Scalar sub-query and aggregate function in `SELECT` or `HAVING` clause gives
+  `AssertionError`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-694">CALCITE-694</a>]
+  Scan `HAVING` clause for sub-queries and `IN`-lists (Hsuan-Yi Chu)
+* Upgrade hydromatic-resource-maven-plugin
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-710">CALCITE-710</a>]
+  Identical conditions in the `WHERE` clause cause `AssertionError` (Sean
+  Hsuan-Yi Chu)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-695">CALCITE-695</a>]
+  Do not add `SINGLE_VALUE` aggregate function to a sub-query that will never
+  return more than one row (Hsuan-Yi Chu)
+* Add tests for scalar sub-queries, including test cases for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-709">CALCITE-709</a>]
+  Errors with `LIMIT` inside scalar sub-query
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-702">CALCITE-702</a>]
+  Add validator test for monotonic expressions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-699">CALCITE-699</a>]
+  In Avatica, synchronize access to Calendar
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-700">CALCITE-700</a>]
+  Pass time zone into tests
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-698">CALCITE-698</a>]
+  For `GROUP BY ()`, `areColumnsUnique()` should return true for any key
+* Disable tests that fail under JDK 1.7 due to
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
+* Add "getting started" to HOWTO
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-692">CALCITE-692</a>]
+  Add back sqlline as a dependency
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-677">CALCITE-677</a>]
+  `RemoteDriverTest.testTypeHandling` fails east of Greenwich
+* Disable test for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-687">CALCITE-687</a>]
+  Make `RemoteDriverTest.testStatementLifecycle` thread-safe
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-686">CALCITE-686</a>]
+  `SqlNode.unparse` produces invalid SQL
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-507">CALCITE-507</a>]
+  Update HOWTO.md with running integration tests
+* Add H2 integration test
+* Add PostgreSQL integration test
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-590">CALCITE-590</a>]
+  Update MongoDB test suite to calcite-test-dataset
+* Add `CalciteAssert.assertArrayEqual` for more user-friendly asserts
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-585">CALCITE-585</a>]
+  Avatica JDBC methods should throw `SQLFeatureNotSupportedException` (Ng Jiunn
+  Jye)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-671">CALCITE-671</a>]
+  `ByteString` does not deserialize properly as a `FetchRequest` parameter value
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-676">CALCITE-676</a>]
+  `AssertionError` in `GROUPING SETS` query
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-678">CALCITE-678</a>]
+  `SemiJoinRule` mixes up fields when `Aggregate.groupSet` is not field #0
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.2.0-incubating">1.2.0-incubating</a> / 2015-04-07
+{: #v1-2-0}
+
+A short release, less than a month after 1.1.
+
+There have been many changes to Avatica, hugely improving its coverage of the
+JDBC API and overall robustness. A new provider, `JdbcMeta`, allows
+you to remote an existing JDBC driver.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
+improves how the planner propagates traits such as collation and
+distribution among relational expressions.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
+and [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
+improve implicit and explicit conversions in SQL.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-366">CALCITE-366</a>]
+  Support Aggregate push down in bushy joins (Jesus Camacho Rodriguez)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
+  Implicitly convert character values in comparisons
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
+  Implement `CAST` between date-time types
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-634">CALCITE-634</a>]
+  Allow `ORDER BY` aggregate function in `SELECT DISTINCT`, provided that it
+  occurs in `SELECT` clause (Sean Hsuan-Yi Chu)
+* In linq4j, implement `firstOrDefault`, `single`, and `singleOrDefault` methods
+  (Daniel Cooper)
+* JDBC adapter
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-631">CALCITE-631</a>]
+    Push theta joins down to JDBC adapter (Ng Jiunn Jye)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-657">CALCITE-657</a>]
+    `NullPointerException` when executing `JdbcAggregate.implement`
+    method (Yuri Au Yong)
+* Metadata
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-659">CALCITE-659</a>]
+    Missing types in `averageTypeValueSize` method in `RelMdSize`
+    (Jesus Camacho Rodriguez)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-650">CALCITE-650</a>]
+    Add metadata for average size of a tuple in `SemiJoin` (Jesus
+    Camacho Rodriguez)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-649">CALCITE-649</a>]
+    Extend `splitCondition` method in `RelOptUtil` to handle multiple
+    joins on the same key (Jesus Camacho Rodriguez)
+
+Avatica features and bug fixes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-670">CALCITE-670</a>]
+  `AvaticaPreparedStatement` should support `execute()` and
+  `executeUpdate()` (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-641">CALCITE-641</a>]
+  Implement logging throughout Avatica server (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-646">CALCITE-646</a>]
+  `AvaticaStatement.execute` method broken over remote JDBC (Yeong Wei
+  and Julian Hyde)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-660">CALCITE-660</a>]
+  Improve Avatica date support
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-655">CALCITE-655</a>]
+  Implement `ConnectionSync` RPC (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-654">CALCITE-654</a>]
+  Tighten up `AvaticaStatement.execute` semantics (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-658">CALCITE-658</a>]
+  Cleanup dependency usage (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-652">CALCITE-652</a>]
+  Move server pieces of `avatica` into `avatica-server` (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-651">CALCITE-651</a>]
+  In `JdbcMeta`, convert property definitions to an enum (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-640">CALCITE-640</a>]
+  Avatica server should expire stale connections/statements (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-639">CALCITE-639</a>]
+  Open up permissions on avatica server components (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-637">CALCITE-637</a>]
+  Implement Avatica `CloseConnection` RPC (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-636">CALCITE-636</a>]
+  Connection isolation for Avatica clients (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-626">CALCITE-626</a>]
+  Implement `CloseStatement` RPC (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-630">CALCITE-630</a>]
+  Flesh out `AvaticaParameter.setObject` (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-627">CALCITE-627</a>]
+  Add Avatica support for `getTableTypes`, `getColumns` (Xavier FH Leong)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-618">CALCITE-618</a>]
+  Add Avatica support for `getTables` (Julian Hyde and Nick Dimiduk)
+
+API changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-617">CALCITE-617</a>]
+  Check at initialization time in `CachingInvocationHandler` that MD provider
+  is not null (Jesus Camacho Rodriguez)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-638">CALCITE-638</a>]
+  SQL standard `REAL` is 4 bytes, `FLOAT` is 8 bytes
+
+Bug-fixes and internal changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-672">CALCITE-672</a>]
+  SQL `ANY` type should be nullable (Jinfeng Ni)
+* Disable tests, pending
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-673">CALCITE-673</a>]
+  Timeout executing joins against MySQL
+* Fix traits in MongoDB adapter, and `NullPointerException` in `JdbcTest`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-662">CALCITE-662</a>]
+  Query validation fails when an `ORDER BY` clause is used with `WITH CLAUSE`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
+  Fix trait propagation and add test case
+* Remove checkstyle Eclipse properties from git tracking
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-644">CALCITE-644</a>]
+  Increase check style line limit to 100 chars (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-648">CALCITE-648</a>]
+  Update `ProjectMergeRule` description for new naming convention (Jinfeng Ni)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-625">CALCITE-625</a>]
+  `README.md` linking to the wrong page of `optiq-csv` (hongbin ma)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-632">CALCITE-632</a>]
+  Sort order returned by `SUPERCLASS_COMPARATOR` in
+  `ReflectiveRelMetadataProvider` is inconsistent (Jesus Camacho
+  Rodriguez)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-335">CALCITE-335</a>]
+  Remove uses of linq4j `Functions.adapt`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-592">CALCITE-592</a>]
+  Upgrade to Guava 14.0.1
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-596">CALCITE-596</a>]
+  JDBC adapter incorrectly reads null values as 0 (Ng Jiunn Jye)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-633">CALCITE-633</a>]
+  `WITH ... ORDER BY` cannot find table
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-614">CALCITE-614</a>]
+  `IN` clause in `CASE` in `GROUP BY` gives `AssertionError`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-619">CALCITE-619</a>]
+  Slim down dependencies in parent POM
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.1.0-incubating">1.1.0-incubating</a> / 2015-03-13
+{: #v1-1-0}
+
+This Calcite release makes it possible to exploit physical properties
+of relational expressions to produce more efficient plans, introducing
+collation and distribution as traits, `Exchange` relational operator,
+and several new forms of metadata.
+
+We add experimental support for streaming SQL.
+
+This release drops support for JDK 1.6; Calcite now requires 1.7 or
+later.
+
+We have introduced static `create` methods for many sub-classes of
+`RelNode`. We strongly suggest that you use these rather than
+calling constructors directly.
+
+New features
+
+* SQL
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-602">CALCITE-602</a>]
+    Streaming queries (experimental)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-588">CALCITE-588</a>]
+    Allow `TableMacro` to consume maps and collections
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-583">CALCITE-583</a>]
+    Operator `||` mishandles `ANY` type (Sean Hsuan-Yi Chu)
+* Planner rule improvements
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-445">CALCITE-445</a>]
+    Pull up filters rejected by a `ProjectableFilterableTable`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-600">CALCITE-600</a>]
+    Use `SetOpFactory` in rules containing `Union` operator (Jesus
+    Camacho Rodriguez)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-603">CALCITE-603</a>]
+    Metadata providers for size, memory, parallelism
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-607">CALCITE-607</a>]
+      Change visibility of constructor in metadata providers for size,
+      memory, parallelism (Jesus Camacho Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-608">CALCITE-608</a>]
+      Exception is thrown when `RelMdDistribution` for `Project`
+      operator is called (Jesus Camacho Rodriguez)
+* Collation and distribution as traits
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-88">CALCITE-88</a>]
+    Add collation as a trait and a kind of `RelNode` metadata
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-569">CALCITE-569</a>]
+    `ArrayIndexOutOfBoundsException` when deducing collation (Aman Sinha)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-581">CALCITE-581</a>]
+    Add `LogicalSort` relational expression, and make `Sort` abstract
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-526">CALCITE-526</a>]
+    Add `EnumerableMergeJoin`, which exploits sorted inputs
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-71">CALCITE-71</a>]
+    Provide a way to declare that tables are sorted
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-576">CALCITE-576</a>]
+    Make `RelCollation` trait and `AbstractRelNode.getCollationList` consistent
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-254">CALCITE-254</a>]
+    Propagate `RelCollation` on aliased columns in `JoinRule`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-569">CALCITE-569</a>]
+    `ArrayIndexOutOfBoundsException` when deducing collation
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-594">CALCITE-594</a>]
+    Add `RelDistribution` trait and `Exchange` relational expression
+
+API changes
+
+* Many sub-classes of `RelNode` now have a static `create` method
+  which automatically sets up traits such as collation and
+  distribution. The constructors are not marked deprecated, but we
+  strongly suggest that you use the `create` method if it exists.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-591">CALCITE-591</a>]
+  Drop support for Java 1.6 (and JDBC 4.0)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-587">CALCITE-587</a>]
+  Upgrade `jetty-server` to 9.2.7.v20150116 and port avatica-server `HttpServer`
+  (Trevor Hartman)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-577">CALCITE-577</a>]
+  Revert temporary API changes introduced in
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-575">CALCITE-575</a>]
+* Add means to create `Context` instances by wrapping objects and by chaining
+  contexts
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-599">CALCITE-599</a>]
+  `EquiJoin` in wrong package (Jesus Camacho Rodriguez)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-573">CALCITE-573</a>]
+  Use user-given names in `RelOptUtil.createProject` and `createRename`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-572">CALCITE-572</a>]
+  Remove `Project.flags` (methods are deprecated, to be removed before 2.0)
+
+Bug-fixes and internal changes
+
+* Remove the `LICENSE` file of calcite-example-csv (the former
+  optiq-csv) and move its history into main history
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-615">CALCITE-615</a>]
+  AvaticaParameter should be Jackson serializable (Nick Dimiduk)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-612">CALCITE-612</a>]
+  Update AvaticaStatement to handle cancelled queries (Parth Chandra)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-605">CALCITE-605</a>]
+  Reduce dependency on third-party maven repositories
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-611">CALCITE-611</a>]
+  Method `setAggChildKeys` should take into account indicator columns of
+  `Aggregate` operator (Jesus Camacho Rodriguez)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-566">CALCITE-566</a>]
+  `ReduceExpressionsRule` requires planner to have an `Executor`
+* Refactor `TableScanNode.create` method
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-593">CALCITE-593</a>]
+  Validator in `Frameworks` should expand identifiers (Jinfeng Ni)
+* Australian time-zones changed in `tzdata2014f`, Java 1.8.0_31
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-580">CALCITE-580</a>]
+  Average aggregation on an `Integer` column throws `ClassCastException`
+* In Travis, ask Surefire to print results to screen
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-586">CALCITE-586</a>]
+  Prevent JSON serialization of `Signature.internalParameters`
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-1.0.0-incubating">1.0.0-incubating</a> / 2015-01-31
+{: #v1-0-0}
+
+Calcite's first major release.
+
+Since the previous release we have re-organized the into the `org.apache.calcite`
+namespace. To make migration of your code easier, we have described the
+<a href="https://issues.apache.org/jira/secure/attachment/12681620/mapping.txt">mapping from old to new class names</a>
+as an attachment to
+[<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>].
+
+The release adds SQL support for `GROUPING SETS`, `EXTEND`, `UPSERT` and sequences;
+a remote JDBC driver;
+improvements to the planner engine and built-in planner rules;
+improvements to the algorithms that implement the relational algebra,
+including an interpreter that can evaluate queries without compilation;
+and fixes about 30 bugs.
+
+New features
+
+* SQL
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-494">CALCITE-494</a>]
+    Support `NEXT`/`CURRENT VALUE FOR` syntax for using sequences
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-492">CALCITE-492</a>]
+    Support `UPSERT` statement in parser
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-493">CALCITE-493</a>]
+    Add `EXTEND` clause, for defining columns and their types at query/DML time
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-497">CALCITE-497</a>]
+    Support optional qualifier for column name references
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-356">CALCITE-356</a>]
+    Allow column references of the form `schema.table.column`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-462">CALCITE-462</a>]
+    Allow table functions in `LATERAL` expression
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-282">CALCITE-282</a>]
+    Add `{fn QUARTER(date)}` function (Benoy Antony)
+  * Grouping sets
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-370">CALCITE-370</a>]
+      Support `GROUPING SETS`, `CUBE`, `ROLLUP` in SQL and algebra
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-512">CALCITE-512</a>]
+      Add `GROUP_ID`,`GROUPING_ID`, `GROUPING` functions
+* Planner rule improvements
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-92">CALCITE-92</a>]
+    Optimize away `Project` that merely renames fields
+  * Detect and merge duplicate predicates `AND(x, y, x)` to `AND(x, y)` in more
+    circumstances
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-557">CALCITE-557</a>]
+    Speed up planning by never creating `AbstractConverter`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-545">CALCITE-545</a>]
+    When a projected expression can only have one value, replace with that
+    constant
+  * Grouping sets
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-542">CALCITE-542</a>]
+      Support for `Aggregate` with grouping sets in `RelMdColumnOrigins` (Jesus
+      Camacho Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-533">CALCITE-533</a>]
+      Support for grouping sets in `FilterAggregateTransposeRule` (Jesus Camacho
+      Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-532">CALCITE-532</a>]
+      Support for grouping sets in `AggregateFilterTransposeRule` (Jesus Camacho
+      Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-513">CALCITE-513</a>]
+      Support for grouping sets in `AggregateProjectMergeRule` (Jesus Camacho
+      Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-510">CALCITE-510</a>]
+      Support for grouping sets in `AggregateExpandDistinctAggregatesRule` (Jesus
+      Camacho Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-502">CALCITE-502</a>]
+      Support for grouping sets in `AggregateUnionTransposeRule` (Jesus Camacho
+      Rodriguez)
+    * [<a href="https://issues.apache.org/jira/browse/CALCITE-503">CALCITE-503</a>]
+      Tests to check rules on `Aggregate` operator without grouping sets (Jesus
+      Camacho Rodriguez)
+* Algorithms
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-451">CALCITE-451</a>]
+    Implement theta join, inner and outer, in enumerable convention
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-489">CALCITE-489</a>]
+    Update `Correlate` mechanics and implement `EnumerableCorrelate` (aka nested
+    loops join)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-544">CALCITE-544</a>]
+    Implement `Union` in interpreter
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-562">CALCITE-562</a>]
+    Implement inner `Join` in interpreter and improve handling of scalar expressions
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-543">CALCITE-543</a>]
+    Implement `Aggregate` (including `GROUPING SETS`) in interpreter (Jacques
+    Nadeau)
+  * In progress towards
+    [<a href="https://issues.apache.org/jira/browse/CALCITE-558">CALCITE-558</a>]
+    add `BINDABLE` convention (but `ENUMERABLE` is still the default), and add
+    `ArrayBindable` and `Scalar` interfaces
+* Remote driver
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-93">CALCITE-93</a>]
+    Calcite RPC server
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-94">CALCITE-94</a>]
+    Remote JDBC driver
+  * Make `JsonHandler` and `JsonService` thread-safe
+
+API changes
+
+* The great code re-org
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>]
+    Re-organize package structure
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-419">CALCITE-419</a>]
+    Naming convention for planner rules
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-306">CALCITE-306</a>]
+    Standardize code style for "import package.*;"
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-474">CALCITE-474</a>]
+    Clean up rule naming in order to support enabling/disabling rules
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-460">CALCITE-460</a>]
+    Add `ImmutableBitSet` and replace uses of `BitSet`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-479">CALCITE-479</a>]
+    Migrate `RelNode.getChildExps` to `RelNode.accept(RexShuttle)`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-527">CALCITE-527</a>]
+    Drop `rowType` field and constructor/copy argument of `Calc`
+* Add linq4j and example-csv modules
+  * Remove unused packages in linq4j, and fix checkstyle issues in linq4j and csv
+  * Add calcite-linq4j and calcite-example-csv as POM sub-modules
+  * Import 'optiq-csv' project as 'example/csv/', and add Apache headers
+  * Import 'linq4j' project, and add Apache headers
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-478">CALCITE-478</a>]
+    Move CSV tutorial (Siva Narayanan)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-464">CALCITE-464</a>]
+  Make parser accept configurable max length for SQL identifier
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-465">CALCITE-465</a>]
+  Remove `OneRow` and `Empty` relational expressions; `Values` will suffice
+
+Bug-fixes and internal changes
+
+* Build improvements
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-541">CALCITE-541</a>]
+    Update maven-source-plugin to 2.4 to get speedup in jdk 1.8
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-537">CALCITE-537</a>]
+    Skip overwrite of `NOTICE`, `DEPENDENCIES`, and `LICENSE` files
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-538">CALCITE-538</a>]
+    Generate `Parser.jj` only at first build
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-539">CALCITE-539</a>]
+    Avoid rewrite of `org-apache-calcite-jdbc.properties`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-540">CALCITE-540</a>]
+    Create git.properties file only at first build. This saves time in
+    development at a cost of stale `git.properties`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-536">CALCITE-536</a>]
+    Add `@PackageMarker` to `package-info.java` so maven-compiler skips
+    compilation when the sources are unchanged
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-535">CALCITE-535</a>]
+    Support skip overwrite in hydromatic-resource
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-582">CALCITE-582</a>]
+  `EnumerableTableScan` broken when table has single column
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-575">CALCITE-575</a>]
+  Variant of `ProjectRemoveRule` that considers a project trivial only if its
+  field names are identical (John Pullokkaran)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-571">CALCITE-571</a>]
+  `ReduceExpressionsRule` tries to reduce `SemiJoin` condition to non-equi
+  condition
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-568">CALCITE-568</a>]
+  Upgrade to a version of `pentaho-aggdesigner` that does not pull in
+  `servlet-api`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-567">CALCITE-567</a>]
+  Make `quidem` dependency have scope "test"
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-570">CALCITE-570</a>]
+  `ReduceExpressionsRule` throws "duplicate key" exception
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-561">CALCITE-561</a>]
+  Upgrade parent POM
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-458">CALCITE-458</a>]
+  ArrayIndexOutOfBoundsException when using just a single column in interpreter
+* Fix spurious extra row from `FULL JOIN`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-554">CALCITE-554</a>]
+  Outer join over NULL keys generates wrong result
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-489">CALCITE-489</a>]
+  Teach `CalciteAssert` to respect multiple settings
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-516">CALCITE-516</a>]
+  `GROUP BY` on a `CASE` expression containing `IN` predicate fails (Aman Sinha)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-552">CALCITE-552</a>]
+  Upgrade tpcds (which depends on an old version of guava)
+* Copy identifier when fully-qualifying, so column aliases have the right case
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-548">CALCITE-548</a>]
+  Extend `induce` method to return `CUBE` and `ROLLUP` (Jesus Camacho Rodriguez)
+  * Simplify `Group.induce` by assuming that group sets are sorted
+* Test case for
+  [<a  href="https://issues.apache.org/jira/browse/CALCITE-212">CALCITE-212</a>]
+  Join condition with `OR`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-550">CALCITE-550</a>]
+  Case-insensitive matching of sub-query columns fails
+  * Add more unit tests (Jinfeng Ni)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-448">CALCITE-448</a>]
+  `FilterIntoJoinRule` creates filters containing invalid `RexInputRef`
+* When registering a `RelNode`, be tolerant if it is equivalent to a `RelNode`
+  with different traits
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-547">CALCITE-547</a>]
+  Set nullability while inferring return type of `item(any,...)` operator
+* In Travis CI, enable containers, and cache `.m2` directory
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-534">CALCITE-534</a>]
+  Missing implementation of `ResultSetMetaData.getColumnClassName` (Knut
+  Forkalsrud)
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-506">CALCITE-506</a>]
+  Update `EnumerableRelImplementor.stash` so it is suitable for all kinds of
+  classes
+* Merge join algorithm for `Enumerable`s
+* Efficient `Enumerable` over random-access list
+* Add a test that calls all functions with arguments of all types that they
+  claim to accept
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-511">CALCITE-511</a>]
+  `copy` method in `LogicalAggregate` not copying the indicator value properly
+* Add a model that has lattices and works against HSQLDB
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-509">CALCITE-509</a>]
+  `RelMdColumnUniqueness` uses `ImmutableBitSet.Builder` twice, gets
+  `NullPointerException`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-488">CALCITE-488</a>]
+  `Enumerable<Holder>` does not work if where `Holder` is a custom class
+  with a single field; Calcite tries to treat it as `SCALAR` due to premature
+  `JavaRowFormat.optimize`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-352">CALCITE-352</a>]
+  Throw exception if `ResultSet.next()` is called after `close()`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-403">CALCITE-403</a>]
+  `Enumerable` gives `NullPointerException` with `NOT` on nullable expression
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-469">CALCITE-469</a>]
+  Update example/csv README.md instructions
+* Document `WITH`, `LATERAL`, `GROUPING SETS`, `CUBE`, `ROLLUP`;
+  add descriptions for all built-in functions and operators
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-470">CALCITE-470</a>]
+  Print warning when column type hint is not understood;
+  Update `EMPS.deptno` column Integer &rarr; int
+* Fix `Linq4j.product`; the cartesian product of 0 attributes is one row of 0
+  attributes
+* Update link optiq-mat-plugin &rarr; mat-calcite-plugin
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-467">CALCITE-467</a>]
+  Incorrect namespace in `package-info.java`
+* Add headers, to appease the RAT
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-446">CALCITE-446</a>]
+  CSV adapter should read from directory relative to the model file
+* Add examples of scannable and filterable tables, matching
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-436">CALCITE-436</a>]
+  Simpler SPI to query Table
+* Fix `JdbcTest.testVersion` now that version is 1.0
+* Update release HOWTO
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-0.9.2-incubating">0.9.2-incubating</a> / 2014-11-05
+{: #v0-9-2}
+
+A fairly minor release, and last release before we rename all of the
+packages and lots of classes, in what we expect to call 1.0. If you
+have an existing application, it's worth upgrading to this first,
+before you move on to 1.0.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-436">CALCITE-436</a>]
+  Simpler SPI to query `Table`
+
+API changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-447">CALCITE-447</a>]
+  Change semi-join rules to make use of factories
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-442">CALCITE-442</a>
+  Add `RelOptRuleOperand` constructor that takes a predicate
+
+Bug-fixes and internal changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-397">CALCITE-397</a>]
+  `SELECT DISTINCT *` on reflective schema gives `ClassCastException` at runtime
+* Various lattice improvements.
+* sqlline: Looking for class-path in inconsistent locations.
+* Re-order test suite, so that fast tests are run first.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-444">CALCITE-444</a>]
+  Filters wrongly pushed into full outer join
+* Make it more convenient to unit test `RelMetadataQuery`, and add some more
+  tests for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-443">CALCITE-443</a>]
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-443">CALCITE-443</a>]
+  `getPredicates` from a Union is not correct
+* Update references to web sites, git repositories, jira, mailing lists,
+  travis CI now that [INFRA-8413] is fixed
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-434">CALCITE-435</a>]
+  `FilterAggregateTransposeRule` loses conditions that cannot be pushed
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-435">CALCITE-435</a>]
+  `LoptOptimizeJoinRule` incorrectly re-orders outer joins
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-439">CALCITE-439</a>]
+  `SqlValidatorUtil.uniquify()` may not terminate under some conditions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-438">CALCITE-438</a>]
+  Push predicates through `SemiJoinRel`
+* Add test case for `LIKE ... ESCAPE`.
+* HOWTO: Modify release instructions.
+* Update `DiffRepository` documentation.
+* Add tests for windowed aggregates without `ORDER BY`. (Works already.)
+
+## <a href="https://github.com/apache/calcite/releases/tag/calcite-0.9.1-incubating">0.9.1-incubating</a> / 2014-10-02
+{: #v0-9-1}
+
+This is the first release as Calcite. (The project was previously called Optiq.)
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-430">CALCITE-430</a>]
+  Rename project from Optiq to Calcite
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-426">CALCITE-426</a>]
+  Pool JDBC data sources, to make it easier to pool connections
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-416">CALCITE-416</a>]
+  Execute logical `RelNode`s using an interpreter
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-376">CALCITE-376</a>]
+  Move `SqlRun` into its own artifact,
+  <a href="https://github.com/julianhyde/quidem">Quidem</a>.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-269">CALCITE-269</a>]
+  MongoDB result sets larger than 16MB
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-373">CALCITE-373</a>]
+  `NULL` values in `NOT IN` sub-queries
+* SQL functions:
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-422">CALCITE-422</a>]
+    Add `REGR_SXX` and `REGR_SYY` regression functions
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-421">CALCITE-421</a>]
+    Add `COVAR_POP` and `COVAR_SAMP` aggregate functions
+* Planner rules:
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-425">CALCITE-425</a>]
+    Add `FilterAggregateTransposeRule`, that pushes a filter through an
+    aggregate
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-399">CALCITE-399</a>]
+    Factorize common `AND` factors out of `OR` predicates
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-404">CALCITE-404</a>]
+    `MergeProjectRule` should not construct `RexProgram`s for simple mappings
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-394">CALCITE-394</a>]
+    Add `RexUtil.toCnf()`, to convert expressions to conjunctive normal form
+    (CNF)
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-389">CALCITE-389</a>]
+    `MergeFilterRule` should flatten `AND` condition
+* Lattices:
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-428">CALCITE-428</a>]
+    Use optimization algorithm to suggest which tiles of a lattice to
+    materialize
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-410">CALCITE-410</a>]
+    Allow lattice tiles to satisfy a query by rolling up
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-406">CALCITE-406</a>]
+    Add tile and measure elements to lattice model element
+  * Now, a lattice can materialize an aggregate-join and use it in a subsequent
+    query.
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-402">CALCITE-402</a>]
+    Lattice should create materializations on demand
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-344">CALCITE-344</a>]
+    Lattice data structure
+* Field trimmer:
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-408">CALCITE-408</a>]
+    Make `FieldTrimmer` work with `RelNode` base classes
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-388">CALCITE-388</a>]
+    Handle semi-joins in field trimmer
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-395">CALCITE-395</a>]
+    Make `FieldTrimmer.trimFields(SetOp)` generate `ProjectRel` instead of
+    `CalcRel`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-393">CALCITE-393</a>]
+    If no fields are projected from a table, field trimmer should project a
+    dummy expression
+
+API changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-413">CALCITE-413</a>]
+  Add `RelDataTypeSystem` plugin, allowing different max precision of a
+  `DECIMAL`
+* In `Planner`, query de-correlation no longer requires state in a
+  `SqlToRelConverter`.
+* Factories:
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-392">CALCITE-392</a>]
+    `RelFieldTrimmer` should use factory to create new rel nodes
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-382">CALCITE-382</a>]
+    Refactoring rules to use factories
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-398">CALCITE-398</a>]
+    Move `CalcRel.createProject` methods to `RelOptUtil`
+  * [<a href="https://issues.apache.org/jira/browse/CALCITE-396">CALCITE-396</a>]
+    Change return type of `JoinFactory.createJoin()`; add `SemiJoinFactory`
+
+Bug-fixes and internal changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-386">CALCITE-386</a>]
+  Fix NOTICE
+* Add tests inspired by Derby bugs.
+* Add recent presentation to README.md.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-427">CALCITE-427</a>]
+  Off-by-one issues in `RemoveDistinctAggregateRule`,
+  `AggregateFilterTransposeRule`
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-414">CALCITE-414</a>]
+  Bad class name in `sqlline` shell script
+* Bad package name in `package-info.java` was causing errors in Eclipse.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-412">CALCITE-412</a>]
+  `RelFieldTrimmer`: when trimming `SortRel`, the collation and trait set don't
+  match
+* Add test case for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-411">CALCITE-411</a>]
+  Duplicate column aliases
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-407">CALCITE-407</a>]
+  `RemoveTrivialProjectRule` drops child node's traits
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-409">CALCITE-409</a>]
+  `PushFilterPastProjectRule` should not push filters past windowed aggregates
+* Fix tests on Windows.
+* Don't load `FoodMartQuerySet` unless we have to. It's big.
+* Enable connection pooling in test suite.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-384">CALCITE-384</a>]
+  Add `apache-` prefix to tarball and directory within tarball
+* Freeze hive fmpp > freemarker plugin dependency.
+* Upgrade Janino
+* Removed hardcoded foodmart schema information
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-387">CALCITE-387</a>]
+  CompileException when cast TRUE to nullable boolean
+* Temporary fix for
+  [<a href="https://issues.apache.org/jira/browse/CALCITE-390">CALCITE-390</a>]
+  Transitive inference (`RelMdPredicates`) doesn't handle semi-join
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-385">CALCITE-385</a>]
+  Change comment style for Java headers
+* Disable test that is inconistent between JDK 1.7 and 1.8.
+* Fix `git-commit-id-plugin` error when running in Travis-CI.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-381">CALCITE-381</a>]
+  Remove plugin versions from the `<plugins>` tag in root pom
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-383">CALCITE-383</a>]
+  Each jar should have a `git.properties` file describing its exact version
+* Fix `mvn site` on JDK 1.8 and enable in Travis-CI.
+* Status icon based on master branch, not whichever branch happened to build
+  most recently.
+* HOWTO:
+  * Document how to build from git, and how to get jars from maven repo.
+  * Optiq web site
+  * Template emails for Apache votes
+  * Update JIRA cases following release
+  * Instructions for making and verifying a release
+
+## <a href="https://github.com/apache/calcite/releases/tag/optiq-0.9.0-incubating">0.9.0-incubating</a> / 2014-08-19
+{: #v0-9-0}
+
+This is the first release under the Apache incubator process.
+
+New features
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-371">CALCITE-371</a>]
+  Implement `JOIN` whose `ON` clause contains mixed equi and theta
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-369">CALCITE-369</a>]
+  Add `EnumerableSemiJoinRel`, implementation of semi-join in enumerable
+  convention
+* Add class `Strong`, for detecting null-rejecting predicates.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-368">CALCITE-368</a>]
+  Add SemiJoinRule, planner rule to convert project-join-aggregate into semi-join
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-367">CALCITE-367</a>]
+  `PushFilterPastJoinRule` should strengthen join type
+* Add `EquiJoinRel`, base class for joins known to be equi-joins.
+* Implement `CAST(<string> AS <datetime>)` and
+  `<datetime> + <interval>`.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-360">CALCITE-360</a>]
+  Introduce a rule to infer predicates from equi-join conditions
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-349">CALCITE-349</a>]
+  Add heuristic join-optimizer that can generate bushy joins
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-346">CALCITE-346</a>]
+  Add commutative join rule
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-347">CALCITE-347</a>]
+  In `SqlRun`, add `!plan` command
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-314">CALCITE-314</a>]
+  Allow simple UDFs based on methods
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-327">CALCITE-327</a>]
+  Rules should use base class to find rule match & use factory for object
+  creation
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-316">CALCITE-316</a>]
+  In `SqlRun`, match output regardless of order if `ORDER BY` not present
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-300">CALCITE-300</a>]
+  Support multiple parameters in `COUNT(DISTINCT x, y, ...)`
+
+API changes
+
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-343">CALCITE-343</a>]
+  RelDecorrelator should build its own mappings, not inherit from SqlToRelConverter
+* Remove deprecated methods.
+* Convert `Hook` to use Guava `Function` (was linq4j `Function1`).
+* Add fluent method `withHook`, to more easily add hooks in tests.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-321">CALCITE-321</a>]
+  Add support for overriding implementation of `CompoundIdentifier` in
+  `SqlParser`.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-322">CALCITE-322</a>]
+  Add support for `SqlExplain`, `SqlOrderBy` and `SqlWith` to support
+  `SqlShuttle` use.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-323">CALCITE-323</a>]
+  Override `SqlUnresolvedFunction.inferReturnType()` to return `ANY` type
+  so framework implementors can support late bound function implementations.
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-324">CALCITE-324</a>]
+  Add `ViewExpander` for `Planner` in `Frameworks`. Expose additional
+  properties of `ViewTable` to allow subclassing.
+* [<a href="

<TRUNCATED>

[21/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/howto.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/howto.md b/avatica/site/_docs/howto.md
new file mode 100644
index 0000000..13f2e72
--- /dev/null
+++ b/avatica/site/_docs/howto.md
@@ -0,0 +1,775 @@
+---
+layout: docs
+title: HOWTO
+permalink: /docs/howto.html
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Here's some miscellaneous documentation about using Calcite and its various
+adapters.
+
+* TOC
+{:toc}
+
+## Building from a source distribution
+
+Prerequisites are maven (3.2.1 or later)
+and Java (JDK 1.7 or later, 1.8 preferred) on your path.
+
+Unpack the source distribution `.tar.gz` or `.zip` file,
+`cd` to the root directory of the unpacked source,
+then build using maven:
+
+{% highlight bash %}
+$ tar xvfz calcite-1.6.0-source.tar.gz
+$ cd calcite-1.6.0
+$ mvn install
+{% endhighlight %}
+
+[Running tests](#running-tests) describes how to run more or fewer
+tests.
+
+## Building from git
+
+Prerequisites are git, maven (3.2.1 or later)
+and Java (JDK 1.7 or later, 1.8 preferred) on your path.
+
+Create a local copy of the github repository,
+`cd` to its root directory,
+then build using maven:
+
+{% highlight bash %}
+$ git clone git://github.com/apache/calcite.git
+$ cd calcite
+$ mvn install
+{% endhighlight %}
+
+Calcite includes a number of machine-generated codes. By default, these are
+regenerated on every build, but this has the negative side-effect of causing
+a re-compilation of the entire project when the non-machine-generated code
+has not changed. To make sure incremental compilation still works as intended,
+provide the `skipGenerate` command line option with your maven command.
+If you invoke the `clean` lifecycle phase, you must not specify the
+`skipGenerate` option as it will not recompile the necessary code for the build
+to succeed.
+
+{% highlight bash %}
+$ mvn clean
+$ mvn package
+... hacks ...
+$ mvn package -DskipGenerate
+{% endhighlight %}
+
+[Running tests](#running-tests) describes how to run more or fewer
+tests.
+
+## Running tests
+
+The test suite will run by default when you build, unless you specify
+`-DskipTests`:
+
+{% highlight bash %}
+$ mvn -DskipTests clean install
+$ mvn test
+{% endhighlight %}
+
+There are other options that control which tests are run, and in what
+environment, as follows.
+
+* `-Dcalcite.test.db=DB` (where db is `h2`, `hsqldb`, `mysql`, or `postgresql`) allows you
+  to change the JDBC data source for the test suite. Calcite's test
+  suite requires a JDBC data source populated with the foodmart data
+  set.
+   * `hsqldb`, the default, uses an in-memory hsqldb database.
+   * All others access a test virtual machine
+     (see [integration tests](#running-integration-tests) below).
+     `mysql` and `postgresql` might be somewhat faster than hsqldb, but you need
+     to populate it (i.e. provision a VM).
+* `-Dcalcite.debug` prints extra debugging information to stdout.
+* `-Dcalcite.test.slow` enables tests that take longer to execute. For
+  example, there are tests that create virtual TPC-H and TPC-DS schemas
+  in-memory and run tests from those benchmarks.
+* `-Dcalcite.test.splunk` enables tests that run against Splunk.
+  Splunk must be installed and running.
+
+## Running integration tests
+
+For testing Calcite's external adapters, a test virtual machine should be used.
+The VM includes H2, HSQLDB, MySQL, MongoDB, and PostgreSQL.
+
+Test VM requires 5GiB of disk space and it takes 30 minutes to build.
+
+Note: you can use [calcite-test-dataset](https://github.com/vlsi/calcite-test-dataset)
+ to populate your own database, however it is recommended to use test VM so the test environment can be reproduced.
+
+### VM preparation
+
+0) Install dependencies: [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/)
+
+1) Clone https://github.com/vlsi/calcite-test-dataset.git at the same level as calcite repository.
+For instance:
+
+{% highlight bash %}
+code
+  +-- calcite
+  +-- calcite-test-dataset
+{% endhighlight %}
+
+Note: integration tests search for ../calcite-test-dataset or ../../calcite-test-dataset.
+ You can specify full path via calcite.test.dataset system property.
+
+2) Build and start the VM:
+
+{% highlight bash %}
+cd calcite-test-dataset && mvn install
+{% endhighlight %}
+
+### VM management
+
+Test VM is provisioned by Vagrant, so regular Vagrant `vagrant up` and `vagrant halt` should be used to start and stop the VM.
+The connection strings for different databases are listed in [calcite-test-dataset](https://github.com/vlsi/calcite-test-dataset) readme.
+
+### Suggested test flow
+
+Note: test VM should be started before you launch integration tests. Calcite itself does not start/stop the VM.
+
+Command line:
+
+* Executing regular unit tests (does not require external data): no change. `mvn test` or `mvn install`.
+* Executing all tests, for all the DBs: `mvn verify -Pit`. `it` stands for "integration-test". `mvn install -Pit` works as well.
+* Executing just tests for external DBs, excluding unit tests: `mvn -Dtest=foo -DfailIfNoTests=false -Pit verify`
+* Executing just MongoDB tests: `cd mongo; mvn verify -Pit`
+
+From within IDE:
+
+* Executing regular unit tests: no change.
+* Executing MongoDB tests: run `MongoAdapterIT.java` as usual (no additional properties are required)
+* Executing MySQL tests: run `JdbcTest` and `JdbcAdapterTest` with setting `-Dcalcite.test.db=mysql`
+* Executing PostgreSQL tests: run `JdbcTest` and `JdbcAdapterTest` with setting `-Dcalcite.test.db=postgresql`
+
+### Integration tests technical details
+
+Tests with external data are executed at maven's integration-test phase.
+We do not currently use pre-integration-test/post-integration-test, however we could use that in future.
+The verification of build pass/failure is performed at verify phase.
+Integration tests should be named `...IT.java`, so they are not picked up on unit test execution.
+
+## Contributing
+
+See the [developers guide]({{ site.baseurl }}/develop/#contributing).
+
+## Getting started
+
+See the [developers guide]({{ site.baseurl }}/develop/#getting-started).
+
+## Tracing
+
+To enable tracing, add the following flags to the java command line:
+
+`-Dcalcite.debug=true`
+
+The first flag causes Calcite to print the Java code it generates
+(to execute queries) to stdout. It is especially useful if you are debugging
+mysterious problems like this:
+
+`Exception in thread "main" java.lang.ClassCastException: Integer cannot be cast to Long
+  at Baz$1$1.current(Unknown Source)`
+
+By default, Calcite uses the Log4j bindings for SLF4J. There is a provided configuration
+file which outputs logging at the INFO level to the console in `core/src/test/resources/log4j.properties`.
+You can modify the level for the rootLogger to increase verbosity or change the level
+for a specific class if you so choose.
+
+{% highlight properties %}
+# Change rootLogger level to WARN
+log4j.rootLogger=WARN, A1
+# Increase level to DEBUG for RelOptPlanner
+log4j.logger.org.apache.calcite.plan.RelOptPlanner=DEBUG
+# Increase level to TRACE for HepPlanner
+log4j.logger.org.apache.calcite.plan.hep.HepPlanner=TRACE
+{% endhighlight %}
+
+## CSV adapter
+
+See the [tutorial](/docs/tutorial.html).
+
+## MongoDB adapter
+
+First, download and install Calcite,
+and <a href="http://www.mongodb.org/downloads">install MongoDB</a>.
+
+Note: you can use MongoDB from integration test virtual machine above.
+
+Import MongoDB's zipcode data set into MongoDB:
+
+{% highlight bash %}
+$ curl -o /tmp/zips.json http://media.mongodb.org/zips.json
+$ mongoimport --db test --collection zips --file /tmp/zips.json
+Tue Jun  4 16:24:14.190 check 9 29470
+Tue Jun  4 16:24:14.469 imported 29470 objects
+{% endhighlight %}
+
+Log into MongoDB to check it's there:
+
+{% highlight bash %}
+$ mongo
+MongoDB shell version: 2.4.3
+connecting to: test
+> db.zips.find().limit(3)
+{ "city" : "ACMAR", "loc" : [ -86.51557, 33.584132 ], "pop" : 6055, "state" : "AL", "_id" : "35004" }
+{ "city" : "ADAMSVILLE", "loc" : [ -86.959727, 33.588437 ], "pop" : 10616, "state" : "AL", "_id" : "35005" }
+{ "city" : "ADGER", "loc" : [ -87.167455, 33.434277 ], "pop" : 3205, "state" : "AL", "_id" : "35006" }
+> exit
+bye
+{% endhighlight %}
+
+Connect using the
+[mongo-zips-model.json]({{ site.sourceRoot }}/mongodb/src/test/resources/mongo-zips-model.json)
+Calcite model:
+
+{% highlight bash %}
+$ ./sqlline
+sqlline> !connect jdbc:calcite:model=mongodb/target/test-classes/mongo-zips-model.json admin admin
+Connecting to jdbc:calcite:model=mongodb/target/test-classes/mongo-zips-model.json
+Connected to: Calcite (version 1.x.x)
+Driver: Calcite JDBC Driver (version 1.x.x)
+Autocommit status: true
+Transaction isolation: TRANSACTION_REPEATABLE_READ
+sqlline> !tables
++------------+--------------+-----------------+---------------+
+| TABLE_CAT  | TABLE_SCHEM  |   TABLE_NAME    |  TABLE_TYPE   |
++------------+--------------+-----------------+---------------+
+| null       | mongo_raw    | zips            | TABLE         |
+| null       | mongo_raw    | system.indexes  | TABLE         |
+| null       | mongo        | ZIPS            | VIEW          |
+| null       | metadata     | COLUMNS         | SYSTEM_TABLE  |
+| null       | metadata     | TABLES          | SYSTEM_TABLE  |
++------------+--------------+-----------------+---------------+
+sqlline> select count(*) from zips;
++---------+
+| EXPR$0  |
++---------+
+| 29467   |
++---------+
+1 row selected (0.746 seconds)
+sqlline> !quit
+Closing: org.apache.calcite.jdbc.FactoryJdbc41$CalciteConnectionJdbc41
+$
+{% endhighlight %}
+
+## Splunk adapter
+
+To run the test suite and sample queries against Splunk,
+load Splunk's `tutorialdata.zip` data set as described in
+<a href="http://docs.splunk.com/Documentation/Splunk/6.0.2/PivotTutorial/GetthetutorialdataintoSplunk">the Splunk tutorial</a>.
+
+(This step is optional, but it provides some interesting data for the sample
+queries. It is also necessary if you intend to run the test suite, using
+`-Dcalcite.test.splunk=true`.)
+
+## Implementing an adapter
+
+New adapters can be created by implementing `CalcitePrepare.Context`:
+
+{% highlight java %}
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.jdbc.CalciteSchema;
+
+public class AdapterContext implements CalcitePrepare.Context {
+  @Override
+  public JavaTypeFactory getTypeFactory() {
+    // adapter implementation
+    return typeFactory;
+  }
+
+  @Override
+  public CalciteSchema getRootSchema() {
+    // adapter implementation
+    return rootSchema;
+  }
+}
+{% endhighlight %}
+
+### Testing adapter in Java
+
+The example below shows how SQL query can be submitted to
+`CalcitePrepare` with a custom context (`AdapterContext` in this
+case). Calcite prepares and implements the query execution, using the
+resources provided by the `Context`. `CalcitePrepare.PrepareResult`
+provides access to the underlying enumerable and methods for
+enumeration. The enumerable itself can naturally be some adapter
+specific implementation.
+
+{% highlight java %}
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.prepare.CalcitePrepareImpl;
+import org.junit.Test;
+
+public class AdapterContextTest {
+  @Test
+  public void testSelectAllFromTable() {
+    AdapterContext ctx = new AdapterContext();
+    String sql = "SELECT * FROM TABLENAME";
+    Class elementType = Object[].class;
+    CalcitePrepare.PrepareResult<Object> prepared =
+        new CalcitePrepareImpl().prepareSql(ctx, sql, null, elementType, -1);
+    Object enumerable = prepared.getExecutable();
+    // etc.
+  }
+}
+{% endhighlight %}
+
+# Advanced topics for developers
+
+The following sections might be of interest if you are adding features
+to particular parts of the code base. You don't need to understand
+these topics if you are just building from source and running tests.
+
+## JavaTypeFactory
+
+When Calcite compares types (instances of `RelDataType`), it requires them to be the same
+object. If there are two distinct type instances that refer to the
+same Java type, Calcite may fail to recognize that they match.  It is
+recommended to:
+
+* Use a single instance of `JavaTypeFactory` within the calcite context;
+* Store the types so that the same object is always returned for the same type.
+
+## Rebuilding generated Protocol Buffer code
+
+Calcite's Avatica Server component supports RPC serialization
+using [Protocol Buffers](https://developers.google.com/protocol-buffers/).
+In the context of Avatica, Protocol Buffers can
+generate a collection of messages defined by a schema. The library
+itself can parse old serialized messages using a
+new schema. This is highly desirable in an environment where the
+client and server are not guaranteed to have the same version of
+objects.
+
+Typically, the code generated by the Protocol Buffers library doesn't
+need to be re-generated only every build, only when the schema changes.
+
+First, install Protobuf 3.0:
+
+{% highlight bash %}
+$ wget https://github.com/google/protobuf/releases/download/v3.0.0-beta-1/protobuf-java-3.0.0-beta-1.tar.gz
+$ tar xf protobuf-java-3.0.0-beta-1.tar.gz && cd protobuf-3.0.0-beta-1
+$ ./configure
+$ make
+$ sudo make install
+{% endhighlight %}
+
+Then, re-generate the compiled code:
+
+{% highlight bash %}
+$ cd avatica
+$ ./src/main/scripts/generate-protobuf.sh
+{% endhighlight %}
+
+# Advanced topics for committers
+
+The following sections are of interest to Calcite committers and in
+particular release managers.
+
+## Set up PGP signing keys (for Calcite committers)
+
+Follow instructions [here](http://www.apache.org/dev/release-signing) to
+create a key pair. (On Mac OS X, I did `brew install gpg` and
+`gpg --gen-key`.)
+
+Add your public key to the `KEYS` file by following instructions in
+the `KEYS` file.
+
+## Making a snapshot (for Calcite committers)
+
+Before you start:
+
+* Set up signing keys as described above.
+* Make sure you are using JDK 1.7 (not 1.8).
+* Make sure build and tests succeed with `-Dcalcite.test.db=hsqldb` (the default)
+
+{% highlight bash %}
+# Set passphrase variable without putting it into shell history
+read -s GPG_PASSPHRASE
+
+# Make sure that there are no junk files in the sandbox
+git clean -xn
+mvn clean
+
+mvn -Papache-release -Dgpg.passphrase=${GPG_PASSPHRASE} install
+{% endhighlight %}
+
+When the dry-run has succeeded, change `install` to `deploy`.
+
+## Making a release (for Calcite committers)
+
+Before you start:
+
+* Set up signing keys as described above.
+* Make sure you are using JDK 1.7 (not 1.8).
+* Check that `README` and `site/_docs/howto.md` have the correct version number.
+* Set `version.major` and `version.minor` in `pom.xml`.
+* Make sure build and tests succeed, including with
+  -Dcalcite.test.db={mysql,hsqldb}, -Dcalcite.test.slow,
+  -Dcalcite.test.mongodb, -Dcalcite.test.splunk.
+* Trigger a
+  <a href="https://scan.coverity.com/projects/2966">Coverity scan</a>
+  by merging the latest code into the `julianhyde/coverity_scan` branch,
+  and when it completes, make sure that there are no important issues.
+* Make sure that
+  <a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20CALCITE%20AND%20status%20%3D%20Resolved%20and%20fixVersion%20is%20null">
+  every "resolved" JIRA case</a> (including duplicates) has
+  a fix version assigned (most likely the version we are
+  just about to release)
+
+Create a release branch named after the release, e.g. `branch-1.1`, and push it to Apache.
+
+{% highlight bash %}
+$ git checkout -b branch-X.Y
+$ git push -u origin branch-X.Y
+{% endhighlight %}
+
+We will use the branch for the entire the release process. Meanwhile,
+we do not allow commits to the master branch. After the release is
+final, we can use `git merge --ff-only` to append the changes on the
+release branch onto the master branch. (Apache does not allow reverts
+to the master branch, which makes it difficult to clean up the kind of
+messy commits that inevitably happen while you are trying to finalize
+a release.)
+
+Now, set up your environment and do a dry run. The dry run will not
+commit any changes back to git and gives you the opportunity to verify
+that the release process will complete as expected.
+
+If any of the steps fail, clean up (see below), fix the problem, and
+start again from the top.
+
+{% highlight bash %}
+# Set passphrase variable without putting it into shell history
+read -s GPG_PASSPHRASE
+
+# Make sure that there are no junk files in the sandbox
+git clean -xn
+mvn clean
+
+# Do a dry run of the release:prepare step, which sets version numbers.
+mvn -DdryRun=true -DskipTests -DreleaseVersion=X.Y.Z -DdevelopmentVersion=X.Y.Z+1-SNAPSHOT -Papache-release -Darguments="-Dgpg.passphrase=${GPG_PASSPHRASE}" release:prepare 2>&1 | tee /tmp/prepare-dry.log
+{% endhighlight %}
+
+Check the artifacts:
+
+* In the `target` directory should be these 8 files, among others:
+  * apache-calcite-X.Y.Z-src.tar.gz
+  * apache-calcite-X.Y.Z-src.tar.gz.asc
+  * apache-calcite-X.Y.Z-src.tar.gz.md5
+  * apache-calcite-X.Y.Z-src.tar.gz.sha1
+  * apache-calcite-X.Y.Z-src.zip
+  * apache-calcite-X.Y.Z-src.zip.asc
+  * apache-calcite-X.Y.Z-src.zip.md5
+  * apache-calcite-X.Y.Z-src.zip.sha1
+* Note that the file names start `apache-calcite-`.
+* In the two source distros `.tar.gz` and `.zip` (currently there is
+  no binary distro), check that all files belong to a directory called
+  `apache-calcite-X.Y.Z-src`.
+* That directory must contain files `NOTICE`, `LICENSE`,
+  `README`, `README.md`
+  * Check that the version in `README` is correct
+* In each .jar (for example
+  `core/target/calcite-core-X.Y.Z.jar` and
+  `mongodb/target/calcite-mongodb-X.Y.Z-sources.jar`), check
+  that the `META-INF` directory contains `DEPENDENCIES`, `LICENSE`,
+  `NOTICE` and `git.properties`
+* In each .jar, check that `org-apache-calcite-jdbc.properties` is
+  present and does not contain un-substituted `${...}` variables
+* Check PGP, per [this](https://httpd.apache.org/dev/verification.html)
+
+Now, remove the `-DdryRun` flag and run the release for real.
+
+{% highlight bash %}
+# Prepare sets the version numbers, creates a tag, and pushes it to git.
+mvn -DdryRun=false -DskipTests -DreleaseVersion=X.Y.Z -DdevelopmentVersion=X.Y.Z+1-SNAPSHOT -Papache-release -Darguments="-Dgpg.passphrase=${GPG_PASSPHRASE}" release:prepare 2>&1 | tee /tmp/prepare.log
+
+# Perform checks out the tagged version, builds, and deploys to the staging repository
+mvn -DskipTests -Papache-release -Darguments="-Dgpg.passphrase=${GPG_PASSPHRASE}" release:perform 2>&1 | tee /tmp/perform.log
+{% endhighlight %}
+
+Verify the staged artifacts in the Nexus repository:
+
+* Go to [https://repository.apache.org/](https://repository.apache.org/) and login
+* Under `Build Promotion`, click `Staging Repositories`
+* In the `Staging Repositories` tab there should be a line with profile `org.apache.calcite`
+* Navigate through the artifact tree and make sure the .jar, .pom, .asc files are present
+* Check the box on in the first column of the row,
+  and press the 'Close' button to publish the repository at
+  https://repository.apache.org/content/repositories/orgapachecalcite-1000
+  (or a similar URL)
+
+Upload the artifacts via subversion to a staging area,
+https://dist.apache.org/repos/dist/dev/calcite/apache-calcite-X.Y.Z-rcN:
+
+{% highlight bash %}
+# Create a subversion workspace, if you haven't already
+mkdir -p ~/dist/dev
+pushd ~/dist/dev
+svn co https://dist.apache.org/repos/dist/dev/calcite
+popd
+
+# Move the files into a directory
+cd target
+mkdir ~/dist/dev/calcite/apache-calcite-X.Y.Z-rcN
+mv apache-calcite-* ~/dist/dev/calcite/apache-calcite-X.Y.Z-rcN
+
+# Check in
+cd ~/dist/dev/calcite
+svn add apache-calcite-X.Y.Z-rcN
+svn ci
+{% endhighlight %}
+
+## Cleaning up after a failed release attempt (for Calcite committers)
+
+{% highlight bash %}
+# Make sure that the tag you are about to generate does not already
+# exist (due to a failed release attempt)
+git tag
+
+# If the tag exists, delete it locally and remotely
+git tag -d apache-calcite-X.Y.Z
+git push origin :refs/tags/apache-calcite-X.Y.Z
+
+# Remove modified files
+mvn release:clean
+
+# Check whether there are modified files and if so, go back to the
+# original git commit
+git status
+git reset --hard HEAD
+{% endhighlight %}
+
+## Validate a release
+
+{% highlight bash %}
+# Check that the signing key (e.g. 2AD3FAE3) is pushed
+gpg --recv-keys key
+
+# Check keys
+curl -O https://dist.apache.org/repos/dist/release/calcite/KEYS
+
+# Sign/check md5 and sha1 hashes
+# (Assumes your O/S has 'md5' and 'sha1' commands.)
+function checkHash() {
+  cd "$1"
+  for i in *.{zip,pom,gz}; do
+    if [ ! -f $i ]; then
+      continue
+    fi
+    if [ -f $i.md5 ]; then
+      if [ "$(cat $i.md5)" = "$(md5 -q $i)" ]; then
+        echo $i.md5 present and correct
+      else
+        echo $i.md5 does not match
+      fi
+    else
+      md5 -q $i > $i.md5
+      echo $i.md5 created
+    fi
+    if [ -f $i.sha1 ]; then
+      if [ "$(cat $i.sha1)" = "$(sha1 -q $i)" ]; then
+        echo $i.sha1 present and correct
+      else
+        echo $i.sha1 does not match
+      fi
+    else
+      sha1 -q $i > $i.sha1
+      echo $i.sha1 created
+    fi
+  done
+}
+checkHash apache-calcite-X.Y.Z-rcN
+{% endhighlight %}
+
+## Get approval for a release via Apache voting process (for Calcite committers)
+
+Release vote on dev list
+
+{% highlight text %}
+To: dev@calcite.apache.org
+Subject: [VOTE] Release apache-calcite-X.Y.Z (release candidate N)
+
+Hi all,
+
+I have created a build for Apache Calcite X.Y.Z, release candidate N.
+
+Thanks to everyone who has contributed to this release.
+<Further details about release.> You can read the release notes here:
+https://github.com/apache/calcite/blob/XXXX/site/_docs/history.md
+
+The commit to be voted upon:
+http://git-wip-us.apache.org/repos/asf/calcite/commit/NNNNNN
+
+Its hash is XXXX.
+
+The artifacts to be voted on are located here:
+https://dist.apache.org/repos/dist/dev/calcite/apache-calcite-X.Y.Z-rcN/
+
+The hashes of the artifacts are as follows:
+src.tar.gz.md5 XXXX
+src.tar.gz.sha1 XXXX
+src.zip.md5 XXXX
+src.zip.sha1 XXXX
+
+A staged Maven repository is available for review at:
+https://repository.apache.org/content/repositories/orgapachecalcite-NNNN
+
+Release artifacts are signed with the following key:
+https://people.apache.org/keys/committer/jhyde.asc
+
+Please vote on releasing this package as Apache Calcite X.Y.Z.
+
+The vote is open for the next 72 hours and passes if a majority of
+at least three +1 PMC votes are cast.
+
+[ ] +1 Release this package as Apache Calcite X.Y.Z
+[ ]  0 I don't feel strongly about it, but I'm okay with the release
+[ ] -1 Do not release this package because...
+
+
+Here is my vote:
+
++1 (binding)
+
+Julian
+{% endhighlight %}
+
+After vote finishes, send out the result:
+
+{% highlight text %}
+Subject: [RESULT] [VOTE] Release apache-calcite-X.Y.Z (release candidate N)
+To: dev@calcite.apache.org
+
+Thanks to everyone who has tested the release candidate and given
+their comments and votes.
+
+The tally is as follows.
+
+N binding +1s:
+<names>
+
+N non-binding +1s:
+<names>
+
+No 0s or -1s.
+
+Therefore I am delighted to announce that the proposal to release
+Apache Calcite X.Y.Z has passed.
+
+Thanks everyone. We’ll now roll the release out to the mirrors.
+
+There was some feedback during voting. I shall open a separate
+thread to discuss.
+
+
+Julian
+{% endhighlight %}
+
+Use the [Apache URL shortener](http://s.apache.org) to generate
+shortened URLs for the vote proposal and result emails. Examples:
+[s.apache.org/calcite-1.2-vote](http://s.apache.org/calcite-1.2-vote) and
+[s.apache.org/calcite-1.2-result](http://s.apache.org/calcite-1.2-result).
+
+
+## Publishing a release (for Calcite committers)
+
+After a successful release vote, we need to push the release
+out to mirrors, and other tasks.
+
+Choose a release date.
+This is based on the time when you expect to announce the release.
+This is usually a day after the vote closes.
+Remember that UTC date changes at 4pm Pacific time.
+
+In JIRA, search for
+[all issues resolved in this release](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CALCITE%20and%20fixVersion%20%3D%201.5.0%20and%20status%20%3D%20Resolved%20and%20resolution%20%3D%20Fixed),
+and do a bulk update changing their status to "Closed",
+with a change comment
+"Resolved in release X.Y.Z (YYYY-MM-DD)"
+(fill in release number and date appropriately).
+Uncheck "Send mail for this update".
+
+Promote the staged nexus artifacts.
+
+* Go to [https://repository.apache.org/](https://repository.apache.org/) and login
+* Under "Build Promotion" click "Staging Repositories"
+* In the line with "orgapachecalcite-xxxx", check the box
+* Press "Release" button
+
+Check the artifacts into svn.
+
+{% highlight bash %}
+# Get the release candidate.
+mkdir -p ~/dist/dev
+cd ~/dist/dev
+svn co https://dist.apache.org/repos/dist/dev/calcite
+
+# Copy the artifacts. Note that the copy does not have '-rcN' suffix.
+mkdir -p ~/dist/release
+cd ~/dist/release
+svn co https://dist.apache.org/repos/dist/release/calcite
+cd calcite
+cp -rp ../../dev/calcite/apache-calcite-X.Y.Z-rcN apache-calcite-X.Y.Z
+svn add apache-calcite-X.Y.Z
+
+# Check in.
+svn ci
+{% endhighlight %}
+
+Svnpubsub will publish to the
+[release repo](https://dist.apache.org/repos/dist/release/calcite) and propagate to the
+[mirrors](http://www.apache.org/dyn/closer.cgi/calcite) within 24 hours.
+
+If there are now more than 2 releases, clear out the oldest ones:
+
+{% highlight bash %}
+cd ~/dist/release/calcite
+svn rm apache-calcite-X.Y.Z
+svn ci
+{% endhighlight %}
+
+The old releases will remain available in the
+[release archive](http://archive.apache.org/dist/calcite/).
+
+Add a release note by copying
+[site/_posts/2015-11-10-release-1.5.0.md]({{ site.sourceRoot }}/site/_posts/2015-11-10-release-1.5.0.md),
+generate the javadoc and copy to `site/target/apidocs` and `site/target/testapidocs`,
+[publish the site](#publish-the-web-site),
+and check that it appears in the contents in [news](http://localhost:4000/news/).
+
+After 24 hours, announce the release by sending an email to
+[announce@apache.org](https://mail-archives.apache.org/mod_mbox/www-announce/).
+You can use
+[the 1.6.0 announcement](https://mail-archives.apache.org/mod_mbox/www-announce/201601.mbox/%3C8DB4C1E5-B322-4A33-8E8F-9858FA6A1119%40apache.org%3E)
+as a template. Be sure to include a brief description of the project.
+
+## Publishing the web site (for Calcite committers)
+{: #publish-the-web-site}
+
+See instructions in
+[site/README.md]({{ site.sourceRoot }}/site/README.md).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/index.md b/avatica/site/_docs/index.md
new file mode 100644
index 0000000..f0c4afd
--- /dev/null
+++ b/avatica/site/_docs/index.md
@@ -0,0 +1,145 @@
+---
+layout: docs
+title: Background
+permalink: /docs/index.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Apache Calcite is a dynamic data management framework.
+
+It contains many of the pieces that comprise a typical database
+management system, but omits some key functions: storage of data,
+algorithms to process data, and a repository for storing metadata.
+
+Calcite intentionally stays out of the business of storing and
+processing data. As we shall see, this makes it an excellent choice
+for mediating between applications and one or more data storage
+locations and data processing engines. It is also a perfect foundation
+for building a database: just add data.
+
+To illustrate, let's create an empty instance of Calcite and then
+point it at some data.
+
+{% highlight java %}
+public static class HrSchema {
+  public final Employee[] emps = 0;
+  public final Department[] depts = 0;
+}
+Class.forName("org.apache.calcite.jdbc.Driver");
+Properties info = new Properties();
+info.setProperty("lex", "JAVA");
+Connection connection = DriverManager.getConnection("jdbc:calcite:", info);
+CalciteConnection calciteConnection =
+    connection.unwrap(CalciteConnection.class);
+ReflectiveSchema.create(calciteConnection,
+    calciteConnection.getRootSchema(), "hr", new HrSchema());
+Statement statement = calciteConnection.createStatement();
+ResultSet resultSet = statement.executeQuery(
+    "select d.deptno, min(e.empid)\n"
+    + "from hr.emps as e\n"
+    + "join hr.depts as d\n"
+    + "  on e.deptno = d.deptno\n"
+    + "group by d.deptno\n"
+    + "having count(*) > 1");
+print(resultSet);
+resultSet.close();
+statement.close();
+connection.close();
+{% endhighlight %}
+
+Where is the database? There is no database. The connection is
+completely empty until `ReflectiveSchema.create` registers a Java
+object as a schema and its collection fields `emps` and `depts` as
+tables.
+
+Calcite does not want to own data; it does not even have favorite data
+format. This example used in-memory data sets, and processed them
+using operators such as `groupBy` and `join` from the linq4j
+library. But Calcite can also process data in other data formats, such
+as JDBC. In the first example, replace
+
+{% highlight java %}
+ReflectiveSchema.create(calciteConnection,
+    calciteConnection.getRootSchema(), "hr", new HrSchema());
+{% endhighlight %}
+
+with
+
+{% highlight java %}
+Class.forName("com.mysql.jdbc.Driver");
+BasicDataSource dataSource = new BasicDataSource();
+dataSource.setUrl("jdbc:mysql://localhost");
+dataSource.setUsername("username");
+dataSource.setPassword("password");
+JdbcSchema.create(calciteConnection.getRootSchema(), "name", dataSource,
+    null, "hr");
+{% endhighlight %}
+
+and Calcite will execute the same query in JDBC. To the application,
+the data and API are the same, but behind the scenes the
+implementation is very different. Calcite uses optimizer rules to push
+the `JOIN` and `GROUP BY` operations to the source database.
+
+In-memory and JDBC are just two familiar examples. Calcite can handle
+any data source and data format. To add a data source, you need to
+write an adapter that tells Calcite what collections in the data
+source it should consider "tables".
+
+For more advanced integration, you can write optimizer
+rules. Optimizer rules allow Calcite to access data of a new format,
+allow you to register new operators (such as a better join algorithm),
+and allow Calcite to optimize how queries are translated to
+operators. Calcite will combine your rules and operators with built-in
+rules and operators, apply cost-based optimization, and generate an
+efficient plan.
+
+### Writing an adapter
+
+The subproject under example/csv provides a CSV adapter, which is
+fully functional for use in applications but is also simple enough to
+serve as a good template if you are writing your own adapter.
+
+See the <a href="{{ site.baseurl }}/docs/tutorial.html">tutorial</a> for information on using
+the CSV adapter and writing other adapters.
+
+See the <a href="howto.html">HOWTO</a> for more information about
+using other adapters, and about using Calcite in general.
+
+## Status
+
+The following features are complete.
+
+* Query parser, validator and optimizer
+* Support for reading models in JSON format
+* Many standard functions and aggregate functions
+* JDBC queries against Linq4j and JDBC back-ends
+* Linq4j front-end
+* SQL features: SELECT, FROM (including JOIN syntax), WHERE, GROUP BY
+  (including GROUPING SETS), aggregate functions (including
+  COUNT(DISTINCT ...) and FILTER), HAVING, ORDER BY (including NULLS
+  FIRST/LAST), set operations (UNION, INTERSECT, MINUS), sub-queries
+  (including correlated sub-queries), windowed aggregates, LIMIT
+  (syntax as <a
+  href="http://www.postgresql.org/docs/8.4/static/sql-select.html#SQL-LIMIT">Postgres</a>);
+  more details in the [SQL reference](reference.html)
+* Local and remote JDBC drivers; see [Avatica](avatica_overview.html)
+* Several [adapters](adapter.html)
+
+

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/lattice.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/lattice.md b/avatica/site/_docs/lattice.md
new file mode 100644
index 0000000..918261c
--- /dev/null
+++ b/avatica/site/_docs/lattice.md
@@ -0,0 +1,136 @@
+---
+layout: docs
+title: Lattices
+permalink: /docs/lattice.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+A lattice is a framework for creating and populating materialized views,
+and for recognizing that a materialized view can be used to solve a
+particular query.
+
+A lattice represents a star (or snowflake) schema, not a general
+schema. In particular, all relationships must be many-to-one, heading
+from a fact table at the center of the star.
+
+The name derives from the mathematics: a
+<a href="http://en.wikipedia.org/wiki/Lattice_(order)">lattice</a>
+is a
+<a href="http://en.wikipedia.org/wiki/Partially_ordered_set">partially
+ordered set</a> where any two elements have a unique greatest lower
+bound and least upper bound.
+
+[<a href="#ref-hru96">HRU96</a>] observed that the set of possible
+materializations of a data cube forms a lattice, and presented an
+algorithm to choose a good set of materializations. Calcite's
+recommendation algorithm is derived from this.
+
+The lattice definition uses a SQL statement to represent the star. SQL
+is a useful short-hand to represent several tables joined together,
+and assigning aliases to the column names (it more convenient than
+inventing a new language to represent relationships, join conditions
+and cardinalities).
+
+Unlike regular SQL, order is important. If you put A before B in the
+FROM clause, and make a join between A and B, you are saying that
+there is a many-to-one foreign key relationship from A to B. (E.g. in
+the example lattice, the Sales fact table occurs before the Time
+dimension table, and before the Product dimension table. The Product
+dimension table occurs before the ProductClass outer dimension table,
+further down an arm of a snowflake.)
+
+A lattice implies constraints. In the A to B relationship, there is a
+foreign key on A (i.e. every value of A's foreign key has a
+corresponding value in B's key), and a unique key on B (i.e. no key
+value occurs more than once). These constraints are really important,
+because it allows the planner to remove joins to tables whose columns
+are not being used, and know that the query results will not change.
+
+Calcite does not check these constraints. If they are violated,
+Calcite will return wrong results.
+
+A lattice is a big, virtual join view. It is not materialized (it
+would be several times larger than the star schema, because of
+denormalization) and you probably wouldn't want to query it (far too
+many columns). So what is it useful for? As we said above, (a) the
+lattice declares some very useful primary and foreign key constraints,
+(b) it helps the query planner map user queries onto
+filter-join-aggregate materialized views (the most useful kind of
+materialized view for DW queries), (c) gives Calcite a framework
+within which to gather stats about data volumes and user queries, (d)
+allows Calcite to automatically design and populate materialized
+views.
+
+Most star schema models force you to choose whether a column is a
+dimension or a measure. In a lattice, every column is a dimension
+column. (That is, it can become one of the columns in the GROUP BY clause
+to query the star schema at a particular dimensionality). Any column
+can also be used in a measure; you define measures by giving the
+column and an aggregate function.
+
+If "unit_sales" tends to be used much more often as a measure rather
+than a dimension, that's fine. Calcite's algorithm should notice that
+it is rarely aggregated, and not be inclined to create tiles that
+aggregate on it. (By "should" I mean "could and one day will". The
+algorithm does not currently take query history into account when
+designing tiles.)
+
+But someone might want to know whether orders with fewer than 5 items
+were more or less profitable than orders with more than 100. All of a
+sudden, "unit_sales" has become a dimension. If there's virtually zero
+cost to declaring a column a dimension column, I figured let's make
+them all dimension columns.
+
+The model allows for a particular table to be used more than once,
+with a different table alias. You could use this to model say
+OrderDate and ShipDate, with two uses to the Time dimension table.
+
+Most SQL systems require that the column names in a view are unique.
+This is hard to achieve in a lattice, because you often include
+primary and foreign key columns in a join. So Calcite lets you refer
+to columns in two ways. If the column is unique, you can use its name,
+["unit_sales"]. Whether or not it is unique in the lattice, it will be
+unique in its table, so you can use it qualified by its table alias.
+Examples:
+
+* ["sales", "unit_sales"]
+* ["ship_date", "time_id"]
+* ["order_date", "time_id"]
+
+A "tile" is a materialized table in a lattice, with a particular
+dimensionality. (What Kylin calls a "cuboid".) The "tiles" attribute
+of the <a href="{{ site.baseurl }}/docs/model.html#lattice">lattice JSON element</a>
+defines an initial set of tiles to materialize.
+
+If you run the algorithm, you can omit the tiles attribute. Calcite
+will choose an initial set. If you include the tiles attribute, the
+algorithm will start with that list and then start finding other tiles
+that are complementary (i.e. "fill in the gaps" left by the initial
+tiles).
+
+### References
+
+<ul>
+<li>[<a name="ref-hru96">HRU96</a>] V. Harinarayan, A. Rajaraman and J. Ullman.
+    <a href="http://web.eecs.umich.edu/~jag/eecs584/papers/implementing_data_cube.pdf">Implementing
+    data cubes efficiently</a>.
+    In <i>Proc. ACM SIGMOD Conf.</i>, Montreal, 1996.</li>
+</ul>
+

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/model.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/model.md b/avatica/site/_docs/model.md
new file mode 100644
index 0000000..2675453
--- /dev/null
+++ b/avatica/site/_docs/model.md
@@ -0,0 +1,517 @@
+---
+layout: docs
+title: JSON models
+permalink: /docs/model.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Calcite models can be represented as JSON files.
+This page describes the structure of those files.
+
+Models can also be built programmatically using the `Schema` SPI.
+
+## Elements
+
+### Root
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'mongo',
+  schemas: [ Schema... ]
+}
+{% endhighlight %}
+
+`version` (required string) must have value `1.0`.
+
+`defaultSchema` (optional string). If specified, it is
+the name (case-sensitive) of a schema defined in this model, and will
+become the default schema for connections to Calcite that use this model.
+
+`schemas` (optional list of <a href="#schema">Schema</a> elements).
+
+### Schema
+
+Occurs within `root.schemas`.
+
+{% highlight json %}
+{
+  name: 'foodmart',
+  path: ['lib'],
+  cache: true,
+  materializations: [ Materialization... ]
+}
+{% endhighlight %}
+
+`name` (required string) is the name of the schema.
+
+`type` (optional string, default `map`) indicates sub-type. Values are:
+
+* `map` for <a href="#map-schema">Map Schema</a>
+* `custom` for <a href="#custom-schema">Custom Schema</a>
+* `jdbc` for <a href="#jdbc-schema">JDBC Schema</a>
+
+`path` (optional list) is the SQL path that is used to
+resolve functions used in this schema. If specified it must be a list,
+and each element of the list must be either a string or a list of
+strings. For example,
+
+{% highlight json %}
+  path: [ ['usr', 'lib'], 'lib' ]
+{% endhighlight %}
+
+declares a path with two elements: the schema '/usr/lib' and the
+schema '/lib'. Most schemas are at the top level, and for these you can use a
+string.
+
+`materializations` (optional list of
+<a href="#materialization">Materialization</a>) defines the tables
+in this schema that are materializations of queries.
+
+`cache` (optional boolean, default true) tells Calcite whether to
+cache metadata (tables, functions and sub-schemas) generated
+by this schema.
+
+* If `false`, Calcite will go back to the schema each time it needs
+  metadata, for example, each time it needs a list of tables in order to
+  validate a query against the schema.
+
+* If `true`, Calcite will cache the metadata the first time it reads
+  it. This can lead to better performance, especially if name-matching is
+  case-insensitive.
+
+However, it also leads to the problem of cache staleness.
+A particular schema implementation can override the
+`Schema.contentsHaveChangedSince` method to tell Calcite
+when it should consider its cache to be out of date.
+
+Tables, functions and sub-schemas explicitly created in a schema are
+not affected by this caching mechanism. They always appear in the schema
+immediately, and are never flushed.
+
+### Map Schema
+
+Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
+
+{% highlight json %}
+{
+  name: 'foodmart',
+  type: 'map',
+  tables: [ Table... ],
+  functions: [ Function... ]
+}
+{% endhighlight %}
+
+`name`, `type`, `path`, `cache`, `materializations` inherited from
+<a href="#schema">Schema</a>.
+
+`tables` (optional list of <a href="#table">Table</a> elements)
+defines the tables in this schema.
+
+`functions` (optional list of <a href="#function">Function</a> elements)
+defines the functions in this schema.
+
+### Custom Schema
+
+Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
+
+{% highlight json %}
+{
+  name: 'mongo',
+  type: 'custom',
+  factory: 'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',
+  operand: {
+    host: 'localhost',
+    database: 'test'
+  }
+}
+{% endhighlight %}
+
+`name`, `type`, `path`, `cache`, `materializations` inherited from
+<a href="#schema">Schema</a>.
+
+`factory` (required string) is the name of the factory class for this
+schema. Must implement interface
+[org.apache.calcite.schema.SchemaFactory]({{ site.apiRoot }}/org/apache/calcite/schema/SchemaFactory.html)
+and have a public default constructor.
+
+`operand` (optional map) contains attributes to be passed to the
+factory.
+
+### JDBC Schema
+
+Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
+
+{% highlight json %}
+{
+  name: 'foodmart',
+  type: 'jdbc',
+  jdbcDriver: TODO,
+  jdbcUrl: TODO,
+  jdbcUser: TODO,
+  jdbcPassword: TODO,
+  jdbcCatalog: TODO,
+  jdbcSchema: TODO
+}
+{% endhighlight %}
+
+`name`, `type`, `path`, `cache`, `materializations` inherited from
+<a href="#schema">Schema</a>.
+
+`jdbcDriver` (optional string) is the name of the JDBC driver class. If not
+specified, uses whichever class the JDBC DriverManager chooses.
+
+`jdbcUrl` (optional string) is the JDBC connect string, for example
+"jdbc:mysql://localhost/foodmart".
+
+`jdbcUser` (optional string) is the JDBC user name.
+
+`jdbcPassword` (optional string) is the JDBC password.
+
+`jdbcCatalog` (optional string) is the name of the initial catalog in the JDBC
+data source.
+
+`jdbcSchema` (optional string) is the name of the initial schema in the JDBC
+data source.
+
+### Materialization
+
+Occurs within `root.schemas.materializations`.
+
+{% highlight json %}
+{
+  view: 'V',
+  table: 'T',
+  sql: 'select deptno, count(*) as c, sum(sal) as s from emp group by deptno'
+}
+{% endhighlight %}
+
+`view` (optional string) is the name of the view; null means that the table
+already exists and is populated with the correct data.
+
+`table` (required string) is the name of the table that materializes the data in
+the query. If `view` is not null, the table might not exist, and if it does not,
+Calcite will create and populate an in-memory table.
+
+`sql` (optional string, or list of strings that will be concatenated as a
+ multi-line string) is the SQL definition of the materialization.
+
+### Table
+
+Occurs within `root.schemas.tables`.
+
+{% highlight json %}
+{
+  name: 'sales_fact',
+  columns: [ Column... ]
+}
+{% endhighlight %}
+
+`name` (required string) is the name of this table. Must be unique within the schema.
+
+`type` (optional string, default `custom`) indicates sub-type. Values are:
+
+* `custom` for <a href="#custom-table">Custom Table</a>
+* `view` for <a href="#view">View</a>
+
+`columns` (list of <a href="#column">Column</a> elements, required for
+some kinds of table, optional for others such as View)
+
+### View
+
+Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
+
+{% highlight json %}
+{
+  name: 'female_emps',
+  type: 'view',
+  sql: "select * from emps where gender = 'F'",
+  modifiable: true
+}
+{% endhighlight %}
+
+`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
+
+`sql` (required string, or list of strings that will be concatenated as a
+ multi-line string) is the SQL definition of the view.
+
+`path` (optional list) is the SQL path to resolve the query. If not
+specified, defaults to the current schema.
+
+`modifiable` (optional boolean) is whether the view is modifiable.
+If null or not specified, Calcite deduces whether the view is modifiable.
+
+A view is modifiable if contains only SELECT, FROM, WHERE (no JOIN, aggregation
+or sub-queries) and every column:
+
+* is specified once in the SELECT clause; or
+* occurs in the WHERE clause with a `column = literal` predicate; or
+* is nullable.
+
+The second clause allows Calcite to automatically provide the correct value for
+hidden columns. It is useful in multi-tenant environments, where the `tenantId`
+column is hidden, mandatory (NOT NULL), and has a constant value for a
+particular view.
+
+Errors regarding modifiable views:
+
+* If a view is marked `modifiable: true` and is not modifiable, Calcite throws
+  an error while reading the schema.
+* If you submit an INSERT, UPDATE or UPSERT command to a non-modifiable view,
+  Calcite throws an error when validating the statement.
+* If a DML statement creates a row that would not appear in the view
+  (for example, a row in `female_emps`, above, with `gender = 'M'`),
+  Calcite throws an error when executing the statement.
+
+### Custom Table
+
+Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
+
+{% highlight json %}
+{
+  name: 'female_emps',
+  type: 'custom',
+  factory: 'TODO',
+  operand: {
+    todo: 'TODO'
+  }
+}
+{% endhighlight %}
+
+`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
+
+`factory` (required string) is the name of the factory class for this
+table. Must implement interface
+[org.apache.calcite.schema.TableFactory]({{ site.apiRoot }}/org/apache/calcite/schema/TableFactory.html)
+and have a public default constructor.
+
+`operand` (optional map) contains attributes to be passed to the
+factory.
+
+### Stream
+
+Information about whether a table allows streaming.
+
+Occurs within `root.schemas.tables.stream`.
+
+{% highlight json %}
+{
+  stream: true,
+  history: false
+}
+{% endhighlight %}
+
+`stream` (optional; default true) is whether the table allows streaming.
+
+`history` (optional; default false) is whether the history of the stream is
+available.
+
+### Column
+
+Occurs within `root.schemas.tables.columns`.
+
+{% highlight json %}
+{
+  name: 'empno'
+}
+{% endhighlight %}
+
+`name` (required string) is the name of this column.
+
+### Function
+
+Occurs within `root.schemas.functions`.
+
+{% highlight json %}
+{
+  name: 'MY_PLUS',
+  className: 'com.example.functions.MyPlusFunction',
+  methodName: 'apply',
+  path: []
+}
+{% endhighlight %}
+
+`name` (required string) is the name of this function.
+
+`className` (required string) is the name of the class that implements this
+function.
+
+`methodName` (optional string) is the name of the method that implements this
+function.
+
+If `methodName` is specified, the method must exist (case-sensitive) and Calcite
+will create a scalar function. The method may be static or non-static, but
+if non-static, the class must have a public constructor with no parameters.
+
+If `methodName` is "*", Calcite creates a function for every method
+in the class.
+
+If `methodName` is not specified, Calcite looks for a method called "eval", and
+if found, creates a a table macro or scalar function.
+It also looks for methods "init", "add", "merge", "result", and
+if found, creates an aggregate function.
+
+`path` (optional list of string) is the path for resolving this function.
+
+### Lattice
+
+Occurs within `root.schemas.lattices`.
+
+{% highlight json %}
+{
+  name: 'star',
+  sql: [
+    'select 1 from "foodmart"."sales_fact_1997" as "s"',
+    'join "foodmart"."product" as "p" using ("product_id")',
+    'join "foodmart"."time_by_day" as "t" using ("time_id")',
+    'join "foodmart"."product_class" as "pc" on "p"."product_class_id" = "pc"."product_class_id"'
+  ],
+  auto: false,
+  algorithm: true,
+  algorithmMaxMillis: 10000,
+  rowCountEstimate: 86837,
+  defaultMeasures: [ {
+    agg: 'count'
+  } ],
+  tiles: [ {
+    dimensions: [ 'the_year', ['t', 'quarter'] ],
+    measures: [ {
+      agg: 'sum',
+      args: 'unit_sales'
+    }, {
+      agg: 'sum',
+      args: 'store_sales'
+    }, {
+      agg: 'count'
+    } ]
+  } ]
+}
+{% endhighlight %}
+
+`name` (required string) is the name of this lattice.
+
+`sql` (required string, or list of strings that will be concatenated as a
+multi-line string) is the SQL statement that defines the fact table, dimension
+tables, and join paths for this lattice.
+
+`auto` (optional boolean, default true) is whether to materialize tiles on need
+as queries are executed.
+
+`algorithm` (optional boolean, default false) is whether to use an optimization
+algorithm to suggest and populate an initial set of tiles.
+
+`algorithmMaxMillis` (optional long, default -1, meaning no limit) is the
+maximum number of milliseconds for which to run the algorithm. After this point,
+takes the best result the algorithm has come up with so far.
+
+`rowCountEstimate` (optional double, default 1000.0) estimated number of rows in
+the lattice
+
+`tiles` (optional list of <a href="#tile">Tile</a> elements) is a list of
+materialized aggregates to create up front.
+
+`defaultMeasures`  (optional list of <a href="#measure">Measure</a> elements)
+is a list of measures that a tile should have by default.
+Any tile defined in `tiles` can still define its own measures, including
+measures not on this list. If not specified, the default list of measures is
+just 'count(*)':
+
+{% highlight json %}
+[ { name: 'count' } ]
+{% endhighlight %}
+
+`statisticProvider` (optional name of a class that implements
+[org.apache.calcite.materialize.LatticeStatisticProvider]({{ site.apiRoot }}/org/apache/calcite/materialize/LatticeStatisticProvider.html))
+provides estimates of the number of distinct values in each column.
+
+You can use a class name, or a class plus a static field. Example:
+
+{% highlight json %}
+  "statisticProvider": "org.apache.calcite.materialize.Lattices#CACHING_SQL_STATISTIC_PROVIDER"
+{% endhighlight %}
+
+If not set, Calcite will generate and execute a SQL query to find the real
+value, and cache the results.
+
+See also: <a href="{{ site.baseurl }}/docs/lattice.html">Lattices</a>.
+
+### Tile
+
+Occurs within `root.schemas.lattices.tiles`.
+
+{% highlight json %}
+{
+  dimensions: [ 'the_year', ['t', 'quarter'] ],
+  measures: [ {
+    agg: 'sum',
+    args: 'unit_sales'
+  }, {
+    agg: 'sum',
+    args: 'store_sales'
+  }, {
+    agg: 'count'
+  } ]
+}
+{% endhighlight %}
+
+`dimensions` (list of strings or string lists, required, but may be empty)
+defines the dimensionality of this tile.
+Each dimension is a column from the lattice, like a `GROUP BY` clause.
+Each element can be either a string
+(the unique label of the column within the lattice)
+or a string list (a pair consisting of a table alias and a column name).
+
+`measures` (optional list of <a href="#measure">Measure</a> elements) is a list
+of aggregate functions applied to arguments. If not specified, uses the
+lattice's default measure list.
+
+### Measure
+
+Occurs within `root.schemas.lattices.defaultMeasures`
+and `root.schemas.lattices.tiles.measures`.
+
+{% highlight json %}
+{
+  agg: 'sum',
+  args: [ 'unit_sales' ]
+}
+{% endhighlight %}
+
+`agg` is the name of an aggregate function (usually 'count', 'sum', 'min',
+'max').
+
+`args` (optional) is a column label (string), or list of zero or more column
+labels
+
+Valid values are:
+
+* Not specified: no arguments
+* null: no arguments
+* Empty list: no arguments
+* String: single argument, the name of a lattice column
+* List: multiple arguments, each a column label
+
+Unlike lattice dimensions, measures can not be specified in qualified
+format, {@code ["table", "column"]}. When you define a lattice, make sure
+that each column you intend to use as a measure has a unique label within
+the lattice (using "{@code AS label}" if necessary), and use that label
+when you want to pass the column as a measure argument.
+
+<!-- End model.md -->


[09/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/proto/Requests.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/proto/Requests.java b/avatica/src/main/java/org/apache/calcite/avatica/proto/Requests.java
deleted file mode 100644
index 6d34757..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/proto/Requests.java
+++ /dev/null
@@ -1,12327 +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.
- */
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: requests.proto
-
-package org.apache.calcite.avatica.proto;
-
-@SuppressWarnings({"unused", "rawtypes"}) public final class Requests {
-  private Requests() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  public interface CatalogsRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:CatalogsRequest)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-  }
-  /**
-   * Protobuf type {@code CatalogsRequest}
-   *
-   * <pre>
-   * Request for Meta#getCatalogs()
-   * </pre>
-   */
-  public  static final class CatalogsRequest extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:CatalogsRequest)
-      CatalogsRequestOrBuilder {
-    // Use CatalogsRequest.newBuilder() to construct.
-    private CatalogsRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private CatalogsRequest() {
-      connectionId_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private CatalogsRequest(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              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.Requests.internal_static_CatalogsRequest_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Requests.CatalogsRequest.class, org.apache.calcite.avatica.proto.Requests.CatalogsRequest.Builder.class);
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    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 {
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest 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 CatalogsRequest}
-     *
-     * <pre>
-     * Request for Meta#getCatalogs()
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:CatalogsRequest)
-        org.apache.calcite.avatica.proto.Requests.CatalogsRequestOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Requests.CatalogsRequest.class, org.apache.calcite.avatica.proto.Requests.CatalogsRequest.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Requests.CatalogsRequest.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        connectionId_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Requests.CatalogsRequest.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest build() {
-        org.apache.calcite.avatica.proto.Requests.CatalogsRequest result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest buildPartial() {
-        org.apache.calcite.avatica.proto.Requests.CatalogsRequest result = new org.apache.calcite.avatica.proto.Requests.CatalogsRequest(this);
-        result.connectionId_ = connectionId_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Requests.CatalogsRequest) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Requests.CatalogsRequest)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.CatalogsRequest other) {
-        if (other == org.apache.calcite.avatica.proto.Requests.CatalogsRequest.getDefaultInstance()) return this;
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        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.Requests.CatalogsRequest parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Requests.CatalogsRequest) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object connectionId_ = "";
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public java.lang.String getConnectionId() {
-        java.lang.Object ref = connectionId_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          connectionId_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getConnectionIdBytes() {
-        java.lang.Object ref = connectionId_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          connectionId_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionId(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder clearConnectionId() {
-        
-        connectionId_ = getDefaultInstance().getConnectionId();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionIdBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      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:CatalogsRequest)
-    }
-
-    // @@protoc_insertion_point(class_scope:CatalogsRequest)
-    private static final org.apache.calcite.avatica.proto.Requests.CatalogsRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.CatalogsRequest();
-    }
-
-    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<CatalogsRequest>
-        PARSER = new com.google.protobuf.AbstractParser<CatalogsRequest>() {
-      public CatalogsRequest parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new CatalogsRequest(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<CatalogsRequest> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CatalogsRequest> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface DatabasePropertyRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:DatabasePropertyRequest)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-  }
-  /**
-   * Protobuf type {@code DatabasePropertyRequest}
-   *
-   * <pre>
-   * Request for Meta#getDatabaseProperties()
-   * </pre>
-   */
-  public  static final class DatabasePropertyRequest extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:DatabasePropertyRequest)
-      DatabasePropertyRequestOrBuilder {
-    // Use DatabasePropertyRequest.newBuilder() to construct.
-    private DatabasePropertyRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private DatabasePropertyRequest() {
-      connectionId_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private DatabasePropertyRequest(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              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.Requests.internal_static_DatabasePropertyRequest_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.class, org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.Builder.class);
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    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 {
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest 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 DatabasePropertyRequest}
-     *
-     * <pre>
-     * Request for Meta#getDatabaseProperties()
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:DatabasePropertyRequest)
-        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequestOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.class, org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        connectionId_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest build() {
-        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest buildPartial() {
-        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest result = new org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest(this);
-        result.connectionId_ = connectionId_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest other) {
-        if (other == org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.getDefaultInstance()) return this;
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        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.Requests.DatabasePropertyRequest parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object connectionId_ = "";
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public java.lang.String getConnectionId() {
-        java.lang.Object ref = connectionId_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          connectionId_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getConnectionIdBytes() {
-        java.lang.Object ref = connectionId_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          connectionId_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionId(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder clearConnectionId() {
-        
-        connectionId_ = getDefaultInstance().getConnectionId();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionIdBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      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:DatabasePropertyRequest)
-    }
-
-    // @@protoc_insertion_point(class_scope:DatabasePropertyRequest)
-    private static final org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest();
-    }
-
-    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<DatabasePropertyRequest>
-        PARSER = new com.google.protobuf.AbstractParser<DatabasePropertyRequest>() {
-      public DatabasePropertyRequest parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new DatabasePropertyRequest(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<DatabasePropertyRequest> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<DatabasePropertyRequest> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SchemasRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:SchemasRequest)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    java.lang.String getCatalog();
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getCatalogBytes();
-
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    java.lang.String getSchemaPattern();
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    com.google.protobuf.ByteString
-        getSchemaPatternBytes();
-
-    /**
-     * <code>optional string connection_id = 3;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 3;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-  }
-  /**
-   * Protobuf type {@code SchemasRequest}
-   *
-   * <pre>
-   * Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
-   * </pre>
-   */
-  public  static final class SchemasRequest extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:SchemasRequest)
-      SchemasRequestOrBuilder {
-    // Use SchemasRequest.newBuilder() to construct.
-    private SchemasRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private SchemasRequest() {
-      catalog_ = "";
-      schemaPattern_ = "";
-      connectionId_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private SchemasRequest(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              catalog_ = s;
-              break;
-            }
-            case 18: {
-              String s = input.readStringRequireUtf8();
-
-              schemaPattern_ = s;
-              break;
-            }
-            case 26: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              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.Requests.internal_static_SchemasRequest_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Requests.SchemasRequest.class, org.apache.calcite.avatica.proto.Requests.SchemasRequest.Builder.class);
-    }
-
-    public static final int CATALOG_FIELD_NUMBER = 1;
-    private volatile java.lang.Object catalog_;
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    public java.lang.String getCatalog() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        catalog_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getCatalogBytes() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        catalog_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int SCHEMA_PATTERN_FIELD_NUMBER = 2;
-    private volatile java.lang.Object schemaPattern_;
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    public java.lang.String getSchemaPattern() {
-      java.lang.Object ref = schemaPattern_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        schemaPattern_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    public com.google.protobuf.ByteString
-        getSchemaPatternBytes() {
-      java.lang.Object ref = schemaPattern_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        schemaPattern_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 3;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 3;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 3;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    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 {
-      if (!getCatalogBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, catalog_);
-      }
-      if (!getSchemaPatternBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 2, schemaPattern_);
-      }
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 3, connectionId_);
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getCatalogBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, catalog_);
-      }
-      if (!getSchemaPatternBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, schemaPattern_);
-      }
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(3, connectionId_);
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest 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 SchemasRequest}
-     *
-     * <pre>
-     * Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:SchemasRequest)
-        org.apache.calcite.avatica.proto.Requests.SchemasRequestOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Requests.SchemasRequest.class, org.apache.calcite.avatica.proto.Requests.SchemasRequest.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Requests.SchemasRequest.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        catalog_ = "";
-
-        schemaPattern_ = "";
-
-        connectionId_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Requests.SchemasRequest.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.SchemasRequest build() {
-        org.apache.calcite.avatica.proto.Requests.SchemasRequest result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.SchemasRequest buildPartial() {
-        org.apache.calcite.avatica.proto.Requests.SchemasRequest result = new org.apache.calcite.avatica.proto.Requests.SchemasRequest(this);
-        result.catalog_ = catalog_;
-        result.schemaPattern_ = schemaPattern_;
-        result.connectionId_ = connectionId_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Requests.SchemasRequest) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Requests.SchemasRequest)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.SchemasRequest other) {
-        if (other == org.apache.calcite.avatica.proto.Requests.SchemasRequest.getDefaultInstance()) return this;
-        if (!other.getCatalog().isEmpty()) {
-          catalog_ = other.catalog_;
-          onChanged();
-        }
-        if (!other.getSchemaPattern().isEmpty()) {
-          schemaPattern_ = other.schemaPattern_;
-          onChanged();
-        }
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        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.Requests.SchemasRequest parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Requests.SchemasRequest) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object catalog_ = "";
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public java.lang.String getCatalog() {
-        java.lang.Object ref = catalog_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          catalog_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getCatalogBytes() {
-        java.lang.Object ref = catalog_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          catalog_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder setCatalog(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder clearCatalog() {
-        
-        catalog_ = getDefaultInstance().getCatalog();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder setCatalogBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object schemaPattern_ = "";
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public java.lang.String getSchemaPattern() {
-        java.lang.Object ref = schemaPattern_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          schemaPattern_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public com.google.protobuf.ByteString
-          getSchemaPatternBytes() {
-        java.lang.Object ref = schemaPattern_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          schemaPattern_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder setSchemaPattern(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        schemaPattern_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder clearSchemaPattern() {
-        
-        schemaPattern_ = getDefaultInstance().getSchemaPattern();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder setSchemaPatternBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        schemaPattern_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object connectionId_ = "";
-      /**
-       * <code>optional string connection_id = 3;</code>
-       */
-      public java.lang.String getConnectionId() {
-        java.lang.Object ref = connectionId_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          connectionId_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 3;</code>
-       */
-      public com.google.protobuf.ByteString
-          getConnectionIdBytes() {
-        java.lang.Object ref = connectionId_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          connectionId_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 3;</code>
-       */
-      public Builder setConnectionId(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 3;</code>
-       */
-      public Builder clearConnectionId() {
-        
-        connectionId_ = getDefaultInstance().getConnectionId();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 3;</code>
-       */
-      public Builder setConnectionIdBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      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:SchemasRequest)
-    }
-
-    // @@protoc_insertion_point(class_scope:SchemasRequest)
-    private static final org.apache.calcite.avatica.proto.Requests.SchemasRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.SchemasRequest();
-    }
-
-    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<SchemasRequest>
-        PARSER = new com.google.protobuf.AbstractParser<SchemasRequest>() {
-      public SchemasRequest parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new SchemasRequest(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<SchemasRequest> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<SchemasRequest> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface TablesRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:TablesRequest)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    java.lang.String getCatalog();
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getCatalogBytes();
-
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    java.lang.String getSchemaPattern();
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    com.google.protobuf.ByteString
-        getSchemaPatternBytes();
-
-    /**
-     * <code>optional string table_name_pattern = 3;</code>
-     */
-    java.lang.String getTableNamePattern();
-    /**
-     * <code>optional string table_name_pattern = 3;</code>
-     */
-    com.google.protobuf.ByteString
-        getTableNamePatternBytes();
-
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    com.google.protobuf.ProtocolStringList
-        getTypeListList();
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    int getTypeListCount();
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    java.lang.String getTypeList(int index);
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    com.google.protobuf.ByteString
-        getTypeListBytes(int index);
-
-    /**
-     * <code>optional bool has_type_list = 6;</code>
-     *
-     * <pre>
-     * Having an empty type_list is distinct from a null type_list
-     * </pre>
-     */
-    boolean getHasTypeList();
-
-    /**
-     * <code>optional string connection_id = 7;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 7;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-  }
-  /**
-   * Protobuf type {@code TablesRequest}
-   *
-   * <pre>
-   * Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
-   *   org.apache.calcite.avatica.Meta.Pat, java.util.List)
-   * </pre>
-   */
-  public  static final class TablesRequest extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:TablesRequest)
-      TablesRequestOrBuilder {
-    // Use TablesRequest.newBuilder() to construct.
-    private TablesRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private TablesRequest() {
-      catalog_ = "";
-      schemaPattern_ = "";
-      tableNamePattern_ = "";
-      typeList_ = com.google.protobuf.LazyStringArrayList.EMPTY;
-      hasTypeList_ = false;
-      connectionId_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private TablesRequest(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              catalog_ = s;
-              break;
-            }
-            case 18: {
-              String s = input.readStringRequireUtf8();
-
-              schemaPattern_ = s;
-              break;
-            }
-            case 26: {
-              String s = input.readStringRequireUtf8();
-
-              tableNamePattern_ = s;
-              break;
-            }
-            case 34: {
-              String s = input.readStringRequireUtf8();
-              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
-                typeList_ = new com.google.protobuf.LazyStringArrayList();
-                mutable_bitField0_ |= 0x00000008;
-              }
-              typeList_.add(s);
-              break;
-            }
-            case 48: {
-
-              hasTypeList_ = input.readBool();
-              break;
-            }
-            case 58: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              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 {
-        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
-          typeList_ = typeList_.getUnmodifiableView();
-        }
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Requests.TablesRequest.class, org.apache.calcite.avatica.proto.Requests.TablesRequest.Builder.class);
-    }
-
-    private int bitField0_;
-    public static final int CATALOG_FIELD_NUMBER = 1;
-    private volatile java.lang.Object catalog_;
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    public java.lang.String getCatalog() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        catalog_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string catalog = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getCatalogBytes() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        catalog_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int SCHEMA_PATTERN_FIELD_NUMBER = 2;
-    private volatile java.lang.Object schemaPattern_;
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    public java.lang.String getSchemaPattern() {
-      java.lang.Object ref = schemaPattern_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        schemaPattern_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string schema_pattern = 2;</code>
-     */
-    public com.google.protobuf.ByteString
-        getSchemaPatternBytes() {
-      java.lang.Object ref = schemaPattern_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        schemaPattern_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int TABLE_NAME_PATTERN_FIELD_NUMBER = 3;
-    private volatile java.lang.Object tableNamePattern_;
-    /**
-     * <code>optional string table_name_pattern = 3;</code>
-     */
-    public java.lang.String getTableNamePattern() {
-      java.lang.Object ref = tableNamePattern_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        tableNamePattern_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string table_name_pattern = 3;</code>
-     */
-    public com.google.protobuf.ByteString
-        getTableNamePatternBytes() {
-      java.lang.Object ref = tableNamePattern_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        tableNamePattern_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int TYPE_LIST_FIELD_NUMBER = 4;
-    private com.google.protobuf.LazyStringList typeList_;
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    public com.google.protobuf.ProtocolStringList
-        getTypeListList() {
-      return typeList_;
-    }
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    public int getTypeListCount() {
-      return typeList_.size();
-    }
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    public java.lang.String getTypeList(int index) {
-      return typeList_.get(index);
-    }
-    /**
-     * <code>repeated string type_list = 4;</code>
-     */
-    public com.google.protobuf.ByteString
-        getTypeListBytes(int index) {
-      return typeList_.getByteString(index);
-    }
-
-    public static final int HAS_TYPE_LIST_FIELD_NUMBER = 6;
-    private boolean hasTypeList_;
-    /**
-     * <code>optional bool has_type_list = 6;</code>
-     *
-     * <pre>
-     * Having an empty type_list is distinct from a null type_list
-     * </pre>
-     */
-    public boolean getHasTypeList() {
-      return hasTypeList_;
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 7;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 7;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 7;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    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 {
-      if (!getCatalogBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, catalog_);
-      }
-      if (!getSchemaPatternBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 2, schemaPattern_);
-      }
-      if (!getTableNamePatternBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 3, tableNamePattern_);
-      }
-      for (int i = 0; i < typeList_.size(); i++) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 4, typeList_.getRaw(i));
-      }
-      if (hasTypeList_ != false) {
-        output.writeBool(6, hasTypeList_);
-      }
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 7, connectionId_);
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getCatalogBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, catalog_);
-      }
-      if (!getSchemaPatternBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, schemaPattern_);
-      }
-      if (!getTableNamePatternBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(3, tableNamePattern_);
-      }
-      {
-        int dataSize = 0;
-        for (int i = 0; i < typeList_.size(); i++) {
-          dataSize += computeStringSizeNoTag(typeList_.getRaw(i));
-        }
-        size += dataSize;
-        size += 1 * getTypeListList().size();
-      }
-      if (hasTypeList_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(6, hasTypeList_);
-      }
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(7, connectionId_);
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest 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 TablesRequest}
-     *
-     * <pre>
-     * Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
-     *   org.apache.calcite.avatica.Meta.Pat, java.util.List)
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:TablesRequest)
-        org.apache.calcite.avatica.proto.Requests.TablesRequestOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Requests.TablesRequest.class, org.apache.calcite.avatica.proto.Requests.TablesRequest.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Requests.TablesRequest.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        catalog_ = "";
-
-        schemaPattern_ = "";
-
-        tableNamePattern_ = "";
-
-        typeList_ = com.google.protobuf.LazyStringArrayList.EMPTY;
-        bitField0_ = (bitField0_ & ~0x00000008);
-        hasTypeList_ = false;
-
-        connectionId_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.TablesRequest getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Requests.TablesRequest.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.TablesRequest build() {
-        org.apache.calcite.avatica.proto.Requests.TablesRequest result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Requests.TablesRequest buildPartial() {
-        org.apache.calcite.avatica.proto.Requests.TablesRequest result = new org.apache.calcite.avatica.proto.Requests.TablesRequest(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        result.catalog_ = catalog_;
-        result.schemaPattern_ = schemaPattern_;
-        result.tableNamePattern_ = tableNamePattern_;
-        if (((bitField0_ & 0x00000008) == 0x00000008)) {
-          typeList_ = typeList_.getUnmodifiableView();
-          bitField0_ = (bitField0_ & ~0x00000008);
-        }
-        result.typeList_ = typeList_;
-        result.hasTypeList_ = hasTypeList_;
-        result.connectionId_ = connectionId_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Requests.TablesRequest) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Requests.TablesRequest)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.TablesRequest other) {
-        if (other == org.apache.calcite.avatica.proto.Requests.TablesRequest.getDefaultInstance()) return this;
-        if (!other.getCatalog().isEmpty()) {
-          catalog_ = other.catalog_;
-          onChanged();
-        }
-        if (!other.getSchemaPattern().isEmpty()) {
-          schemaPattern_ = other.schemaPattern_;
-          onChanged();
-        }
-        if (!other.getTableNamePattern().isEmpty()) {
-          tableNamePattern_ = other.tableNamePattern_;
-          onChanged();
-        }
-        if (!other.typeList_.isEmpty()) {
-          if (typeList_.isEmpty()) {
-            typeList_ = other.typeList_;
-            bitField0_ = (bitField0_ & ~0x00000008);
-          } else {
-            ensureTypeListIsMutable();
-            typeList_.addAll(other.typeList_);
-          }
-          onChanged();
-        }
-        if (other.getHasTypeList() != false) {
-          setHasTypeList(other.getHasTypeList());
-        }
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        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.Requests.TablesRequest parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Requests.TablesRequest) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      private java.lang.Object catalog_ = "";
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public java.lang.String getCatalog() {
-        java.lang.Object ref = catalog_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          catalog_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getCatalogBytes() {
-        java.lang.Object ref = catalog_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          catalog_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder setCatalog(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder clearCatalog() {
-        
-        catalog_ = getDefaultInstance().getCatalog();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 1;</code>
-       */
-      public Builder setCatalogBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object schemaPattern_ = "";
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public java.lang.String getSchemaPattern() {
-        java.lang.Object ref = schemaPattern_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          schemaPattern_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public com.google.protobuf.ByteString
-          getSchemaPatternBytes() {
-        java.lang.Object ref = schemaPattern_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          schemaPattern_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder setSchemaPattern(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        schemaPattern_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder clearSchemaPattern() {
-        
-        schemaPattern_ = getDefaultInstance().getSchemaPattern();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema_pattern = 2;</code>
-       */
-      public Builder setSchemaPatternBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        schemaPattern_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object tableNamePattern_ = "";
-      /**
-       * <code>optional string table_name_pattern = 3;</code>
-       */
-      public java.lang.String getTableNamePattern() {
-        java.lang.Object ref = tableNamePattern_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          tableNamePattern_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string table_name_pattern = 3;</code>
-       */
-      public com.google.protobuf.ByteString
-          getTableNamePatternBytes() {
-        java.lang.Object ref = tableNamePattern_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          tableNamePattern_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string table_name_pattern = 3;</code>
-       */
-      public Builder setTableNamePattern(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        tableNamePattern_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-    

<TRUNCATED>

[41/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/QueryState.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/QueryState.java b/avatica/core/src/main/java/org/apache/calcite/avatica/QueryState.java
new file mode 100644
index 0000000..4ca9ce1
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/QueryState.java
@@ -0,0 +1,466 @@
+/*
+ * 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.proto.Common.MetaDataOperationArgument;
+import org.apache.calcite.avatica.proto.Common.MetaDataOperationArgument.ArgumentType;
+import org.apache.calcite.avatica.remote.MetaDataOperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A struct used to encapsulate the necessary information to reconstitute a ResultSet in the
+ * Avatica server.
+ */
+public class QueryState {
+
+  /**
+   * An enumeration that represents how a ResultSet was created.
+   */
+  public enum StateType {
+    SQL,
+    METADATA;
+
+    public Common.StateType toProto() {
+      switch (this) {
+      case SQL:
+        return Common.StateType.SQL;
+      case METADATA:
+        return Common.StateType.METADATA;
+      default:
+        return Common.StateType.UNRECOGNIZED;
+      }
+    }
+
+    public static StateType fromProto(Common.StateType protoType) {
+      switch (protoType) {
+      case SQL:
+        return StateType.SQL;
+      case METADATA:
+        return StateType.METADATA;
+      default:
+        throw new IllegalArgumentException("Unhandled StateType " + protoType);
+      }
+    }
+  }
+
+  @JsonProperty("type")
+  public final StateType type;
+
+  @JsonProperty("sql")
+  public final String sql;
+
+  @JsonProperty("metaDataOperation")
+  public final MetaDataOperation metaDataOperation;
+  @JsonProperty("operationArgs")
+  public final Object[] operationArgs;
+
+  /**
+   * Constructor encapsulating a SQL query used to create a result set.
+   *
+   * @param sql The SQL query.
+   */
+  public QueryState(String sql) {
+    // This doesn't to be non-null
+    this.sql = sql;
+    this.type = StateType.SQL;
+
+    // Null out the members we don't use.
+    this.metaDataOperation = null;
+    this.operationArgs = null;
+  }
+
+  /**
+   * Constructor encapsulating a metadata operation's result set.
+   *
+   * @param op A pointer to the {@link DatabaseMetaData} operation being invoked.
+   * @param args The arguments to the method being invoked.
+   */
+  public QueryState(MetaDataOperation op, Object... args) {
+    this.metaDataOperation = Objects.requireNonNull(op);
+    this.operationArgs = Arrays.copyOf(Objects.requireNonNull(args), args.length);
+    this.type = StateType.METADATA;
+
+    // Null out the members we won't use
+    this.sql = null;
+  }
+
+  /**
+   * Not intended for external use. For Jackson-databind only.
+   */
+  public QueryState(StateType type, String sql, MetaDataOperation op, Object... args) {
+    this.type = Objects.requireNonNull(type);
+    switch (type) {
+    case SQL:
+      this.sql = Objects.requireNonNull(sql);
+      if (null != op) {
+        throw new IllegalArgumentException("Expected null MetaDataOperation, but got " + op);
+      }
+      this.metaDataOperation = null;
+      if (null != args) {
+        throw new IllegalArgumentException("Expected null arguments, but got "
+            + Arrays.toString(args));
+      }
+      this.operationArgs = null;
+      break;
+    case METADATA:
+      this.metaDataOperation = Objects.requireNonNull(op);
+      this.operationArgs = Objects.requireNonNull(args);
+      if (null != sql) {
+        throw new IllegalArgumentException("Expected null SQl but got " + sql);
+      }
+      this.sql = null;
+      break;
+    default:
+      throw new IllegalArgumentException("Unable to handle StateType " + type);
+    }
+  }
+
+  /**
+   * Not intended for external use. For Jackson-databind only.
+   */
+  public QueryState() {
+    this.sql = null;
+    this.metaDataOperation = null;
+    this.type = null;
+    this.operationArgs = null;
+  }
+
+  /**
+   * @return The {@link StateType} for this encapsulated state.
+   */
+  public StateType getType() {
+    return type;
+  }
+
+  /**
+   * @return The SQL expression to invoke.
+   */
+  public String getSql() {
+    assert type == StateType.SQL;
+    return sql;
+  }
+
+  /**
+   * @return The metadata operation to invoke.
+   */
+  public MetaDataOperation getMetaDataOperation() {
+    assert type == StateType.METADATA;
+    return metaDataOperation;
+  }
+
+  /**
+   * @return The Arguments for the given metadata operation.
+   */
+  public Object[] getOperationArgs() {
+    assert type == StateType.METADATA;
+    return operationArgs;
+  }
+
+  public ResultSet invoke(Connection conn, Statement statement) throws SQLException {
+    switch (type) {
+    case SQL:
+      boolean ret = Objects.requireNonNull(statement).execute(sql);
+      ResultSet results = statement.getResultSet();
+
+      // Either execute(sql) returned true or the resultSet was null
+      assert ret || null == results;
+
+      return results;
+    case METADATA:
+      DatabaseMetaData metadata = Objects.requireNonNull(conn).getMetaData();
+      switch (metaDataOperation) {
+      case GET_ATTRIBUTES:
+        verifyOpArgs(4);
+        return metadata.getAttributes((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_BEST_ROW_IDENTIFIER:
+        verifyOpArgs(5);
+        return metadata.getBestRowIdentifier((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (int) operationArgs[3],
+            (boolean) operationArgs[4]);
+      case GET_CATALOGS:
+        verifyOpArgs(0);
+        return metadata.getCatalogs();
+      case GET_COLUMNS:
+        verifyOpArgs(4);
+        return metadata.getColumns((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_COLUMN_PRIVILEGES:
+        verifyOpArgs(4);
+        return metadata.getColumnPrivileges((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_CROSS_REFERENCE:
+        verifyOpArgs(6);
+        return metadata.getCrossReference((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3],
+            (String) operationArgs[4],
+            (String) operationArgs[5]);
+      case GET_EXPORTED_KEYS:
+        verifyOpArgs(3);
+        return metadata.getExportedKeys((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_FUNCTIONS:
+        verifyOpArgs(3);
+        return metadata.getFunctions((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_FUNCTION_COLUMNS:
+        verifyOpArgs(4);
+        return metadata.getFunctionColumns((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_IMPORTED_KEYS:
+        verifyOpArgs(3);
+        return metadata.getImportedKeys((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_INDEX_INFO:
+        verifyOpArgs(5);
+        return metadata.getIndexInfo((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (boolean) operationArgs[3],
+            (boolean) operationArgs[4]);
+      case GET_PRIMARY_KEYS:
+        verifyOpArgs(3);
+        return metadata.getPrimaryKeys((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_PROCEDURES:
+        verifyOpArgs(3);
+        return metadata.getProcedures((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_PROCEDURE_COLUMNS:
+        verifyOpArgs(4);
+        return metadata.getProcedureColumns((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_PSEUDO_COLUMNS:
+        verifyOpArgs(4);
+        return metadata.getPseudoColumns((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String) operationArgs[3]);
+      case GET_SCHEMAS:
+        verifyOpArgs(0);
+        return metadata.getSchemas();
+      case GET_SCHEMAS_WITH_ARGS:
+        verifyOpArgs(2);
+        return metadata.getSchemas((String) operationArgs[0],
+            (String) operationArgs[1]);
+      case GET_SUPER_TABLES:
+        verifyOpArgs(3);
+        return metadata.getSuperTables((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_SUPER_TYPES:
+        verifyOpArgs(3);
+        return metadata.getSuperTypes((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_TABLES:
+        verifyOpArgs(4);
+        return metadata.getTables((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (String[]) operationArgs[3]);
+      case GET_TABLE_PRIVILEGES:
+        verifyOpArgs(3);
+        return metadata.getTablePrivileges((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      case GET_TABLE_TYPES:
+        verifyOpArgs(0);
+        return metadata.getTableTypes();
+      case GET_TYPE_INFO:
+        verifyOpArgs(0);
+        return metadata.getTypeInfo();
+      case GET_UDTS:
+        verifyOpArgs(4);
+        return metadata.getUDTs((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2],
+            (int[]) operationArgs[3]);
+      case GET_VERSION_COLUMNS:
+        verifyOpArgs(3);
+        return metadata.getVersionColumns((String) operationArgs[0],
+            (String) operationArgs[1],
+            (String) operationArgs[2]);
+      default:
+        throw new IllegalArgumentException("Unhandled Metadata operation: " + metaDataOperation);
+      }
+    default:
+      throw new IllegalArgumentException("Unable to process QueryState of type " + type);
+    }
+  }
+
+  private void verifyOpArgs(int expectedArgs) {
+    if (expectedArgs != operationArgs.length) {
+      throw new RuntimeException("Expected " + expectedArgs + " arguments, but got "
+          + Arrays.toString(operationArgs));
+    }
+  }
+
+  public Common.QueryState toProto() {
+    Common.QueryState.Builder builder = Common.QueryState.newBuilder();
+
+    // Required
+    switch (type) {
+    case SQL:
+      builder.setType(Common.StateType.SQL);
+      break;
+    case METADATA:
+      builder.setType(Common.StateType.METADATA);
+      break;
+    default:
+      throw new IllegalStateException("Unhandled type: " + type);
+    }
+
+    // Optional SQL
+    if (null != sql) {
+      builder.setSql(sql).setHasSql(true);
+    }
+
+    // Optional metaDataOperation
+    if (null != metaDataOperation) {
+      builder.setOp(metaDataOperation.toProto()).setHasOp(true);
+    }
+
+    // Optional operationArgs
+    if (null != operationArgs) {
+      builder.setHasArgs(true);
+      for (Object arg : operationArgs) {
+        MetaDataOperationArgument.Builder argBuilder = MetaDataOperationArgument.newBuilder();
+
+        if (null == arg) {
+          builder.addArgs(argBuilder.setType(ArgumentType.NULL).build());
+        } else if (arg instanceof String) {
+          builder.addArgs(argBuilder.setType(ArgumentType.STRING)
+              .setStringValue((String) arg).build());
+        } else if (arg instanceof Integer) {
+          builder.addArgs(argBuilder.setType(ArgumentType.INT).setIntValue((int) arg).build());
+        } else if (arg instanceof Boolean) {
+          builder.addArgs(
+              argBuilder.setType(ArgumentType.BOOL).setBoolValue((boolean) arg).build());
+        } else if (arg instanceof String[]) {
+          argBuilder.setType(ArgumentType.REPEATED_STRING);
+          for (String strArg : (String[]) arg) {
+            argBuilder.addStringArrayValues(strArg);
+          }
+          builder.addArgs(argBuilder.build());
+        } else if (arg instanceof int[]) {
+          argBuilder.setType(ArgumentType.REPEATED_INT);
+          for (int intArg : (int[]) arg) {
+            argBuilder.addIntArrayValues(intArg);
+          }
+          builder.addArgs(argBuilder.build());
+        } else {
+          throw new RuntimeException("Unexpected operation argument: " + arg.getClass());
+        }
+      }
+    } else {
+      builder.setHasArgs(false);
+    }
+
+    return builder.build();
+  }
+
+  public static QueryState fromProto(Common.QueryState protoState) {
+    StateType type = StateType.fromProto(protoState.getType());
+    String sql = protoState.getHasSql() ? protoState.getSql() : null;
+    MetaDataOperation op = protoState.getHasOp()
+        ? MetaDataOperation.fromProto(protoState.getOp()) : null;
+    Object[] opArgs = null;
+    if (protoState.getHasArgs()) {
+      opArgs = new Object[protoState.getArgsCount()];
+      int i = 0;
+      for (Common.MetaDataOperationArgument arg : protoState.getArgsList()) {
+        switch (arg.getType()) {
+        case STRING:
+          opArgs[i] = arg.getStringValue();
+          break;
+        case BOOL:
+          opArgs[i] = arg.getBoolValue();
+          break;
+        case INT:
+          opArgs[i] = arg.getIntValue();
+          break;
+        case REPEATED_STRING:
+          opArgs[i] = arg.getStringArrayValuesList().toArray(
+              new String[arg.getStringArrayValuesCount()]);
+          break;
+        case REPEATED_INT:
+          int[] arr = new int[arg.getIntArrayValuesCount()];
+          int offset = 0;
+          for (Integer val : arg.getIntArrayValuesList()) {
+            arr[offset] = val;
+            offset++;
+          }
+          opArgs[i] = arr;
+          break;
+        case NULL:
+          opArgs[i] = null;
+          break;
+        default:
+          throw new RuntimeException("Could not interpret " + arg.getType());
+        }
+
+        i++;
+      }
+    }
+
+    return new QueryState(type, sql, op, opArgs);
+  }
+
+  @Override public int hashCode() {
+    return Objects.hash(metaDataOperation, Arrays.hashCode(operationArgs), sql);
+  }
+
+  @Override public boolean equals(Object o) {
+    return o == this
+        || o instanceof QueryState
+        && metaDataOperation == ((QueryState) o).metaDataOperation
+        && Arrays.deepEquals(operationArgs, ((QueryState) o).operationArgs)
+        && Objects.equals(sql, ((QueryState) o).sql);
+  }
+}
+
+// End QueryState.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/SqlType.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/SqlType.java b/avatica/core/src/main/java/org/apache/calcite/avatica/SqlType.java
new file mode 100644
index 0000000..e34bee6
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/SqlType.java
@@ -0,0 +1,559 @@
+/*
+ * 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.util.ByteString;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.Struct;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Extends the information in {@link java.sql.Types}.
+ *
+ * <p>The information in the following conversions tables
+ * (from the JDBC 4.1 specification) is held in members of this class.
+ *
+ * <p>Table B-1: JDBC Types Mapped to Java Types
+ *
+ * <pre>
+ * JDBC Type     Java Type
+ * ============= =========================
+ * CHAR          String
+ * VARCHAR       String
+ * LONGVARCHAR   String
+ * NUMERIC       java.math.BigDecimal
+ * DECIMAL       java.math.BigDecimal
+ * BIT           boolean
+ * BOOLEAN       boolean
+ * TINYINT       byte
+ * SMALLINT      short
+ * INTEGER       int
+ * BIGINT        long
+ * REAL          float
+ * FLOAT         double
+ * DOUBLE        double
+ * BINARY        byte[]
+ * VARBINARY     byte[]
+ * LONGVARBINARY byte[]
+ * DATE          java.sql.Date
+ * TIME          java.sql.Time
+ * TIMESTAMP     java.sql.Timestamp
+ * CLOB          java.sql.Clob
+ * BLOB          java.sql.Blob
+ * ARRAY         java.sql.Array
+ * DISTINCT      mapping of underlying type
+ * STRUCT        java.sql.Struct
+ * REF           java.sql.Ref
+ * DATALINK      java.net.URL
+ * JAVA_OBJECT   underlying Java class
+ * ROWID         java.sql.RowId
+ * NCHAR         String
+ * NVARCHAR      String
+ * LONGNVARCHAR  String
+ * NCLOB         java.sql.NClob
+ * SQLXML        java.sql.SQLXML
+ * </pre>
+ *
+ * <p>Table B-2: Standard Mapping from Java Types to JDBC Types
+ *
+ * <pre>
+ * Java Type            JDBC Type
+ * ==================== ==============================================
+ * String               CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR or
+ *                      LONGNVARCHAR
+ * java.math.BigDecimal NUMERIC
+ * boolean              BIT or BOOLEAN
+ * byte                 TINYINT
+ * short                SMALLINT
+ * int                  INTEGER
+ * long                 BIGINT
+ * float                REAL
+ * double               DOUBLE
+ * byte[]               BINARY, VARBINARY, or LONGVARBINARY
+ * java.sql.Date        DATE
+ * java.sql.Time        TIME
+ * java.sql.Timestamp   TIMESTAMP
+ * java.sql.Clob        CLOB
+ * java.sql.Blob        BLOB
+ * java.sql.Array       ARRAY
+ * java.sql.Struct      STRUCT
+ * java.sql.Ref         REF
+ * java.net.URL         DATALINK
+ * Java class           JAVA_OBJECT
+ * java.sql.RowId       ROWID
+ * java.sql.NClob       NCLOB
+ * java.sql.SQLXML      SQLXML
+ * </pre>
+ *
+ * <p>TABLE B-3: Mapping from JDBC Types to Java Object Types
+ *
+ * <pre>
+ * JDBC Type     Java Object Type
+ * ============= ======================
+ * CHAR          String
+ * VARCHAR       String
+ * LONGVARCHAR   String
+ * NUMERIC       java.math.BigDecimal
+ * DECIMAL       java.math.BigDecimal
+ * BIT           Boolean
+ * BOOLEAN       Boolean
+ * TINYINT       Integer
+ * SMALLINT      Integer
+ * INTEGER       Integer
+ * BIGINT        Long
+ * REAL          Float
+ * FLOAT         Double
+ * DOUBLE        Double
+ * BINARY        byte[]
+ * VARBINARY     byte[]
+ * LONGVARBINARY byte[]
+ * DATE          java.sql.Date
+ * TIME          java.sql.Time
+ * TIMESTAMP     java.sql.Timestamp
+ * DISTINCT      Object type of underlying type
+ * CLOB          java.sql.Clob
+ * BLOB          java.sql.Blob
+ * ARRAY         java.sql.Array
+ * STRUCT        java.sql.Struct or java.sql.SQLData
+ * REF           java.sql.Ref
+ * DATALINK      java.net.URL
+ * JAVA_OBJECT   underlying Java class
+ * ROWID         java.sql.RowId
+ * NCHAR         String
+ * NVARCHAR      String
+ * LONGNVARCHAR  String
+ * NCLOB         java.sql.NClob
+ * SQLXML        java.sql.SQLXML
+ * </pre>
+ *
+ * <p>TABLE B-4: Mapping from Java Object Types to JDBC Types
+ *
+ * <pre>
+ * Java Object Type     JDBC Type
+ * ==================== ===========================================
+ * String               CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR
+ *                      or LONGNVARCHAR
+ * java.math.BigDecimal NUMERIC
+ * Boolean              BIT or BOOLEAN
+ * Byte                 TINYINT
+ * Short                SMALLINT
+ * Integer              INTEGER
+ * Long                 BIGINT
+ * Float                REAL
+ * Double               DOUBLE
+ * byte[]               BINARY, VARBINARY, or LONGVARBINARY
+ * java.math.BigInteger BIGINT
+ * java.sql.Date        DATE
+ * java.sql.Time        TIME
+ * java.sql.Timestamp   TIMESTAMP
+ * java.sql.Clob        CLOB
+ * java.sql.Blob        BLOB
+ * java.sql.Array       ARRAY
+ * java.sql.Struct      STRUCT
+ * java.sql.Ref         REF
+ * java.net.URL         DATALINK
+ * Java class           JAVA_OBJECT
+ * java.sql.RowId       ROWID
+ * java.sql.NClob       NCLOB
+ * java.sql.SQLXML      SQLXML
+ * java.util.Calendar   TIMESTAMP
+ * java.util.Date       TIMESTAMP
+ * </pre>
+ *
+ * <p><a name="B5">TABLE B-5</a>: Conversions performed by {@code setObject} and
+ * {@code setNull} between Java object types and target JDBC types
+ *
+ * <!--
+ * CHECKSTYLE: OFF
+ * -->
+ * <pre>
+ *                      T S I B R F D D N B B C V L B V L D T T A B C S R D J R N N L N S
+ *                      I M N I E L O E U I O H A O I A O A I I R L L T E A A O C V O C Q
+ *                      N A T G A O U C M T O A R N N R N T M M R O O R F T V W H A N L L
+ *                      Y L E I L A B I E   L R C G A B G E E E A B B U   A A I A R G O X
+ *                      I L G N   T L M R   E   H V R I V E   S Y     C   L _ D R C N B M
+ *                      N I E T     E A I   A   A A Y N A     T       T   I O     H V   L
+ *                      T N R         L C   N   R R   A R     A           N B     A A
+ *                        T                       C   R B     M           K J     R R
+ *                                                H   Y I     P                     C
+ * Java type                                  
+ * ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+ * String               x x x x x x x x x x x x x x x x x x x x . . . . . . . . x x x . .
+ * java.math.BigDecimal x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Boolean              x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Byte                 x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Short                x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Integer              x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Long                 x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Float                x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * Double               x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * byte[]               . . . . . . . . . . . . . . x x x . . . . . . . . . . . . . . . .
+ * java.math.BigInteger . . . x . . . . . . . x x x . . . . . . . . . . . . . . . . . . .
+ * java.sql.Date        . . . . . . . . . . . x x x . . . x . x . . . . . . . . . . . . .
+ * java.sql.Time        . . . . . . . . . . . x x x . . . . x x . . . . . . . . . . . . .
+ * java.sql.Timestamp   . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
+ * java.sql.Array       . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . . .
+ * java.sql.Blob        . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . .
+ * java.sql.Clob        . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . .
+ * java.sql.Struct      . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . .
+ * java.sql.Ref         . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . .
+ * java.net.URL         . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . .
+ * Java class           . . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . .
+ * java.sql.Rowid       . . . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . .
+ * java.sql.NClob       . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x .
+ * java.sql.SQLXML      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x
+ * java.util.Calendar   . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
+ * java.util.Date       . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
+ * </pre>
+ * <!--
+ * CHECKSTYLE: ON
+ * -->
+ *
+ * <p><a name="B6">TABLE B-6</a>: Use of {@code ResultSet} getter methods to
+ * retrieve JDBC data types
+ *
+ * <!--
+ * CHECKSTYLE: OFF
+ * -->
+ * <pre>
+ *                      T S I B R F D D N B B C V L B V L D T T C B A R D S J R N N L N S
+ *                      I M N I E L O E U I O H A O I A O A I I L L R E A T A O C V O C Q
+ *                      N A T G A O U C M T O A R N N R N T M M O O R F T R V W H A N L L
+ *                      Y L E I L A B I E   L R C G A B G E E E B B A   A U A I A R G O X
+ *                      I L G N   T L M R   E   H V R I V E   S     Y   L C _ D R C N B M
+ *                      N I E T     E A I   A   A A Y N A     T         I T O     H V   L
+ *                      T N R         L C   N   R R   A R     A         N   B     A A
+ *                        T                       C   R B     M         K   J     R R
+ *                                                H   Y I     P                     C
+ * Java type                                                                
+ * ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+ * getByte              X x x x x x x x x x x x x . . . . . . . . . . . . . . x . . . . .
+ * getShort             x X x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * getInt               x x X x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * getLong              x x x X x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * getFloat             x x x x X x x x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * getDouble            x x x x x X X x x x x x x . . . . . . . . . . . . . . . . . . . .
+ * getBigDecimal        x x x x x x x X X x x x x . . . . . . . . . . . . . . . . . . . .
+ * getBoolean           x x x x x x x x x X x x x . . . . . . . . . . . . . . . . . . . .
+ * getString            x x x x x x x x x x x X X x x x x x x x . . . . x . . . x x x . .
+ * getNString           x x x x x x x x x x x x x x x x x x x x . . . . x . . . X X x . .
+ * getBytes             . . . . . . . . . . . . . . X X x . . . . . . . . . . . . . . . .
+ * getDate              . . . . . . . . . . . x x x . . . X . x . . . . . . . . . . . . .
+ * getTime              . . . . . . . . . . . x x x . . . . X x . . . . . . . . . . . . .
+ * getTimestamp         . . . . . . . . . . . x x x . . . x x X . . . . . . . . . . . x .
+ * getAsciiStream       . . . . . . . . . . . x x X x x x . . . x . . . . . . . . . . . x
+ * getBinaryStream      . . . . . . . . . . . . . . x x X . . . . x . . . . . . . . . x x
+ * getCharacterStream   . . . . . . . . . . . x x X x x x . . . x . . . . . . . x x x x x
+ * getNCharacterStream  . . . . . . . . . . . x x x x x x . . . x . . . . . . . x x X x x
+ * getClob              . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . x .
+ * getNClob             . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . X .
+ * getBlob              . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . .
+ * getArray             . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . .
+ * getRef               . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . .
+ * getURL               . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . .
+ * getObject            x x x x x x x x x x x x x x x x x x x x x x x x x X X x x x x x x
+ * getRowId             . . . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . .
+ * getSQLXML            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X
+ * </pre>
+ * <!--
+ * CHECKSTYLE: ON
+ * -->
+ */
+public enum SqlType {
+  BIT(Types.BIT, boolean.class),
+  BOOLEAN(Types.BOOLEAN, boolean.class),
+  TINYINT(Types.TINYINT, byte.class),
+  SMALLINT(Types.SMALLINT, short.class),
+  INTEGER(Types.INTEGER, int.class),
+  BIGINT(Types.BIGINT, long.class),
+  NUMERIC(Types.NUMERIC, BigDecimal.class),
+  DECIMAL(Types.DECIMAL, BigDecimal.class),
+  FLOAT(Types.FLOAT, double.class),
+  REAL(Types.REAL, float.class),
+  DOUBLE(Types.DOUBLE, double.class),
+  DATE(Types.DATE, java.sql.Date.class, int.class),
+  TIME(Types.TIME, Time.class, int.class),
+  TIMESTAMP(Types.TIMESTAMP, Timestamp.class, long.class),
+  INTERVAL_YEAR_MONTH(Types.OTHER, Boolean.class),
+  INTERVAL_DAY_TIME(Types.OTHER, Boolean.class),
+  CHAR(Types.CHAR, String.class),
+  VARCHAR(Types.VARCHAR, String.class),
+  LONGVARCHAR(Types.LONGVARCHAR, String.class),
+  BINARY(Types.BINARY, byte[].class, ByteString.class, String.class),
+  VARBINARY(Types.VARBINARY, byte[].class, ByteString.class, String.class),
+  LONGVARBINARY(Types.LONGVARBINARY, byte[].class, ByteString.class,
+      String.class),
+  NULL(Types.NULL, Void.class),
+  ANY(Types.JAVA_OBJECT, Object.class),
+  SYMBOL(Types.OTHER, Object.class),
+  MULTISET(Types.ARRAY, List.class),
+  ARRAY(Types.ARRAY, Array.class),
+  BLOB(Types.BLOB, Blob.class),
+  CLOB(Types.CLOB, Clob.class),
+  SQLXML(Types.SQLXML, java.sql.SQLXML.class),
+  MAP(Types.OTHER, Map.class),
+  DISTINCT(Types.DISTINCT, Object.class),
+  STRUCT(Types.STRUCT, Struct.class),
+  REF(Types.REF, Ref.class),
+  DATALINK(Types.DATALINK, URL.class),
+  JAVA_OBJECT(Types.JAVA_OBJECT, Object.class),
+  ROWID(Types.ROWID, RowId.class),
+  NCHAR(Types.NCHAR, String.class),
+  NVARCHAR(Types.NVARCHAR, String.class),
+  LONGNVARCHAR(Types.LONGNVARCHAR, String.class),
+  NCLOB(Types.NCLOB, NClob.class),
+  ROW(Types.STRUCT, Object.class),
+  OTHER(Types.OTHER, Object.class),
+  CURSOR(2012, Object.class),
+  COLUMN_LIST(Types.OTHER + 2, Object.class);
+
+  /** Type id as appears in {@link java.sql.Types},
+   * e.g. {@link java.sql.Types#INTEGER}. */
+  public final int id;
+
+  /** Default Java type for this SQL type, as described in table B-1. */
+  public final Class clazz;
+
+  /** Class used internally in Calcite to represent instances of this type. */
+  public final Class internal;
+
+  /** Class used to serialize values of this type as JSON. */
+  public final Class serial;
+
+  private static final Map<Integer, SqlType> BY_ID = new HashMap<>();
+  static {
+    for (SqlType sqlType : values()) {
+      BY_ID.put(sqlType.id, sqlType);
+    }
+  }
+
+  SqlType(int id, Class clazz, Class internal, Class serial) {
+    this.id = id;
+    this.clazz = clazz;
+    this.internal = internal;
+    this.serial = serial;
+  }
+
+  SqlType(int id, Class clazz, Class internal) {
+    this(id, clazz, internal, internal);
+  }
+
+  SqlType(int id, Class clazz) {
+    this(id, clazz, clazz, clazz);
+  }
+
+  public static SqlType valueOf(int type) {
+    final SqlType sqlType = BY_ID.get(type);
+    if (sqlType == null) {
+      throw new IllegalArgumentException("Unknown SQL type " + type);
+    }
+    return sqlType;
+  }
+
+  /** Returns the boxed type. */
+  public Class boxedClass() {
+    return AvaticaUtils.box(clazz);
+  }
+
+  /** Returns the entries in JDBC table B-5. */
+  public static Iterable<Map.Entry<Class, SqlType>> getSetConversions() {
+    final ArrayList<Map.Entry<Class, SqlType>> list = new ArrayList<>();
+    for (Map.Entry<Class, EnumSet<SqlType>> entry : SET_LIST.entrySet()) {
+      for (SqlType sqlType : entry.getValue()) {
+        list.add(new AbstractMap.SimpleEntry<>(entry.getKey(), sqlType));
+      }
+    }
+    return list;
+  }
+
+  public static final Map<Class, EnumSet<SqlType>> SET_LIST;
+  public static final Map<Method, EnumSet<SqlType>> GET_LIST;
+
+  static {
+    SET_LIST = new HashMap<>();
+    GET_LIST = new HashMap<>();
+
+    EnumSet<SqlType> numericTypes = EnumSet.of(TINYINT, SMALLINT, INTEGER,
+        BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, BOOLEAN);
+    Class[] numericClasses = {
+      BigDecimal.class, Boolean.class, Byte.class, Short.class, Integer.class,
+      Long.class, Float.class, Double.class
+    };
+    EnumSet<SqlType> charTypes = EnumSet.of(CHAR, VARCHAR, LONGVARCHAR);
+    EnumSet<SqlType> ncharTypes = EnumSet.of(NCHAR, NVARCHAR, LONGNVARCHAR);
+    EnumSet<SqlType> binaryTypes = EnumSet.of(BINARY, VARBINARY, LONGVARBINARY);
+    EnumSet<SqlType> dateTimeTypes = EnumSet.of(DATE, TIME, TIMESTAMP);
+    final EnumSet<SqlType> numericCharTypes = concat(numericTypes, charTypes);
+    SET_LIST.put(String.class,
+        concat(numericCharTypes, binaryTypes, dateTimeTypes, ncharTypes));
+    for (Class clazz : numericClasses) {
+      SET_LIST.put(clazz, numericCharTypes);
+    }
+    SET_LIST.put(byte[].class, binaryTypes);
+    SET_LIST.put(BigInteger.class,
+        EnumSet.of(BIGINT, CHAR, VARCHAR, LONGVARCHAR));
+    SET_LIST.put(java.sql.Date.class,
+        concat(charTypes, EnumSet.of(DATE, TIMESTAMP)));
+    SET_LIST.put(Time.class,
+        concat(charTypes, EnumSet.of(TIME, TIMESTAMP)));
+    SET_LIST.put(Timestamp.class,
+        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
+    SET_LIST.put(Array.class, EnumSet.of(ARRAY));
+    SET_LIST.put(Blob.class, EnumSet.of(BLOB));
+    SET_LIST.put(Clob.class, EnumSet.of(CLOB));
+    SET_LIST.put(Struct.class, EnumSet.of(STRUCT));
+    SET_LIST.put(Ref.class, EnumSet.of(REF));
+    SET_LIST.put(URL.class, EnumSet.of(DATALINK));
+    SET_LIST.put(Class.class, EnumSet.of(JAVA_OBJECT));
+    SET_LIST.put(RowId.class, EnumSet.of(ROWID));
+    SET_LIST.put(NClob.class, EnumSet.of(NCLOB));
+    SET_LIST.put(java.sql.SQLXML.class, EnumSet.of(SQLXML));
+    SET_LIST.put(Calendar.class,
+        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
+    SET_LIST.put(java.util.Date.class,
+        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
+
+    EnumSet<Method> numericMethods =
+        EnumSet.of(Method.GET_BYTE, Method.GET_SHORT, Method.GET_INT,
+            Method.GET_LONG, Method.GET_FLOAT, Method.GET_DOUBLE,
+            Method.GET_BIG_DECIMAL, Method.GET_BOOLEAN);
+    for (Method method : numericMethods) {
+      GET_LIST.put(method, numericCharTypes);
+    }
+    GET_LIST.put(Method.GET_BYTE, EnumSet.of(ROWID));
+    for (Method method : EnumSet.of(Method.GET_STRING, Method.GET_N_STRING)) {
+      GET_LIST.put(method,
+          concat(numericCharTypes, binaryTypes, dateTimeTypes,
+              EnumSet.of(DATALINK), ncharTypes));
+    }
+    GET_LIST.put(Method.GET_BYTES, binaryTypes);
+    GET_LIST.put(Method.GET_DATE,
+        concat(charTypes, EnumSet.of(DATE, TIMESTAMP)));
+    GET_LIST.put(Method.GET_TIME,
+        concat(charTypes, EnumSet.of(TIME, TIMESTAMP)));
+    GET_LIST.put(Method.GET_TIMESTAMP,
+        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
+    GET_LIST.put(Method.GET_ASCII_STREAM,
+        concat(charTypes, binaryTypes, EnumSet.of(CLOB, NCLOB)));
+    GET_LIST.put(Method.GET_BINARY_STREAM,
+        concat(binaryTypes, EnumSet.of(BLOB, SQLXML)));
+    GET_LIST.put(Method.GET_CHARACTER_STREAM,
+        concat(charTypes, binaryTypes, ncharTypes,
+            EnumSet.of(CLOB, NCLOB, SQLXML)));
+    GET_LIST.put(Method.GET_N_CHARACTER_STREAM,
+        concat(
+            charTypes, binaryTypes, ncharTypes, EnumSet.of(CLOB, NCLOB, SQLXML)));
+    GET_LIST.put(Method.GET_CLOB, EnumSet.of(CLOB, NCLOB));
+    GET_LIST.put(Method.GET_N_CLOB, EnumSet.of(CLOB, NCLOB));
+    GET_LIST.put(Method.GET_BLOB, EnumSet.of(BLOB));
+    GET_LIST.put(Method.GET_ARRAY, EnumSet.of(ARRAY));
+    GET_LIST.put(Method.GET_REF, EnumSet.of(REF));
+    GET_LIST.put(Method.GET_BLOB, EnumSet.of(BLOB));
+    GET_LIST.put(Method.GET_URL, EnumSet.of(DATALINK));
+    GET_LIST.put(Method.GET_OBJECT, EnumSet.allOf(SqlType.class));
+    GET_LIST.put(Method.GET_ROW_ID, EnumSet.of(ROWID));
+    GET_LIST.put(Method.GET_SQLXML, EnumSet.of(SQLXML));
+  }
+
+  @SafeVarargs
+  private static <E extends Enum<E>> EnumSet<E> concat(Collection<E>... ess) {
+    final List<E> list = new ArrayList<>();
+    for (Collection<E> es : ess) {
+      list.addAll(es);
+    }
+    return EnumSet.copyOf(list);
+  }
+
+  /** Returns whether {@link java.sql.PreparedStatement#setObject} and
+   * {@link PreparedStatement#setNull} can assign a value of a particular class
+   * to a column of a particular SQL type.
+   *
+   * <p>The JDBC standard describes the mapping in table <a href="#B5">B-5</a>.
+   */
+  public static boolean canSet(Class aClass, SqlType sqlType) {
+    final EnumSet<SqlType> sqlTypes = SET_LIST.get(aClass);
+    return sqlTypes != null && sqlTypes.contains(sqlType);
+  }
+
+  /** Returns whether {@link java.sql.ResultSet#getInt(int)} and similar methods
+   * can convert a value to a particular SQL type.
+   *
+   * <p>The JDBC standard describes the mapping in table <a href="#B6">B-6</a>.
+   */
+  public static boolean canGet(Method method, SqlType sqlType) {
+    final EnumSet<SqlType> sqlTypes = GET_LIST.get(method);
+    return sqlTypes != null && sqlTypes.contains(sqlType);
+  }
+
+  /** Getter methods in {@link java.sql.ResultSet}. */
+  public enum Method {
+    GET_BYTE("getByte"),
+    GET_SHORT("getShort"),
+    GET_INT("getInt"),
+    GET_LONG("getLong"),
+    GET_FLOAT("getFloat"),
+    GET_DOUBLE("getDouble"),
+    GET_BIG_DECIMAL("getBigDecimal"),
+    GET_BOOLEAN("getBoolean"),
+    GET_STRING("getString"),
+    GET_N_STRING("getNString"),
+    GET_BYTES("getBytes"),
+    GET_DATE("getDate"),
+    GET_TIME("getTime"),
+    GET_TIMESTAMP("getTimestamp"),
+    GET_ASCII_STREAM("getAsciiStream"),
+    GET_BINARY_STREAM("getBinaryStream"),
+    GET_CHARACTER_STREAM("getCharacterStream"),
+    GET_N_CHARACTER_STREAM("getNCharacterStream"),
+    GET_CLOB("getClob"),
+    GET_N_CLOB("getNClob"),
+    GET_BLOB("getBlob"),
+    GET_ARRAY("getArray"),
+    GET_REF("getRef"),
+    GET_URL("getURL"),
+    GET_OBJECT("getObject"),
+    GET_ROW_ID("getRowId"),
+    GET_SQLXML("getSQLXML");
+
+    public final String methodName;
+
+    Method(String methodName) {
+      this.methodName = methodName;
+    }
+  }
+}
+
+// End SqlType.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java b/avatica/core/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
new file mode 100644
index 0000000..b1fe787
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
@@ -0,0 +1,255 @@
+/*
+ * 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.Connection;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of JDBC driver that does not register itself.
+ *
+ * <p>You can easily create a "vanity driver" that recognizes its own
+ * URL prefix as a sub-class of this class. Per the JDBC specification it
+ * must register itself when the class is loaded.</p>
+ *
+ * <p>Derived classes must implement {@link #createDriverVersion()} and
+ * {@link #getConnectStringPrefix()}, and may override
+ * {@link #createFactory()}.</p>
+ *
+ * <p>The provider must implement:</p>
+ * <ul>
+ *   <li>{@link Meta#prepare(Meta.ConnectionHandle, String, long)}
+ *   <li>{@link Meta#createIterable(org.apache.calcite.avatica.Meta.StatementHandle, org.apache.calcite.avatica.QueryState, org.apache.calcite.avatica.Meta.Signature, java.util.List, Meta.Frame)}
+ * </ul>
+ */
+public abstract class UnregisteredDriver implements java.sql.Driver {
+  final DriverVersion version;
+  protected final AvaticaFactory factory;
+  public final Handler handler;
+
+  protected UnregisteredDriver() {
+    this.factory = createFactory();
+    this.version = createDriverVersion();
+    this.handler = createHandler();
+  }
+
+  /**
+   * Creates a factory for JDBC objects (connection, statement).
+   * Called from the driver constructor.
+   *
+   * <p>The default implementation calls {@link JdbcVersion#current},
+   * then {@link #getFactoryClassName} with that version,
+   * then passes that class name to {@link #instantiateFactory(String)}.
+   * This approach is recommended it does not include in the code references
+   * to classes that may not be instantiable in all JDK versions.
+   * But drivers are free to do it their own way.</p>
+   *
+   * @return JDBC object factory
+   */
+  protected AvaticaFactory createFactory() {
+    return instantiateFactory(getFactoryClassName(JdbcVersion.current()));
+  }
+
+  /** Creates a Handler. */
+  protected Handler createHandler() {
+    return new HandlerImpl();
+  }
+
+  /**
+   * Returns the name of a class to be factory for JDBC objects
+   * (connection, statement) appropriate for the current JDBC version.
+   */
+  protected String getFactoryClassName(JdbcVersion jdbcVersion) {
+    switch (jdbcVersion) {
+    case JDBC_30:
+    case JDBC_40:
+      throw new IllegalArgumentException("JDBC version not supported: "
+          + jdbcVersion);
+    case JDBC_41:
+    default:
+      return "org.apache.calcite.avatica.AvaticaJdbc41Factory";
+    }
+  }
+
+  /**
+   * Creates an object describing the name and version of this driver.
+   * Called from the driver constructor.
+   */
+  protected abstract DriverVersion createDriverVersion();
+
+  /**
+   * Returns the connection properties supported by this driver.
+   */
+  protected Collection<ConnectionProperty> getConnectionProperties() {
+    return Arrays.<ConnectionProperty>asList(
+        BuiltInConnectionProperty.values());
+  }
+
+  /** Helper method for creating factories. */
+  protected static AvaticaFactory instantiateFactory(String factoryClassName) {
+    try {
+      final Class<?> clazz = Class.forName(factoryClassName);
+      return (AvaticaFactory) clazz.newInstance();
+    } catch (ClassNotFoundException e) {
+      throw handle("Error loading factory " + factoryClassName, e);
+    } catch (IllegalAccessException e) {
+      throw handle("Error loading factory " + factoryClassName, e);
+    } catch (InstantiationException e) {
+      throw handle("Error loading factory " + factoryClassName, e);
+    } catch (Throwable e) {
+      // It is not usually good to catch Throwable. But class loading can fail
+      // with serious errors such as java.lang.NoClassDefFoundError
+      throw handle("Error loading factory " + factoryClassName, e);
+    }
+  }
+
+  private static RuntimeException handle(String msg, Throwable e) {
+    Logger.getLogger("").log(Level.SEVERE, msg, e);
+    throw new RuntimeException(msg, e);
+  }
+
+  public Connection connect(String url, Properties info) throws SQLException {
+    if (!acceptsURL(url)) {
+      return null;
+    }
+    final String prefix = getConnectStringPrefix();
+    assert url.startsWith(prefix);
+    final String urlSuffix = url.substring(prefix.length());
+    final Properties info2 = ConnectStringParser.parse(urlSuffix, info);
+    final AvaticaConnection connection =
+        factory.newConnection(this, factory, url, info2);
+    handler.onConnectionInit(connection);
+    return connection;
+  }
+
+  public boolean acceptsURL(String url) throws SQLException {
+    return url.startsWith(getConnectStringPrefix());
+  }
+
+  /** Returns the prefix of the connect string that this driver will recognize
+   * as its own. For example, "jdbc:calcite:". */
+  protected abstract String getConnectStringPrefix();
+
+  public DriverPropertyInfo[] getPropertyInfo(
+      String url, Properties info) throws SQLException {
+    List<DriverPropertyInfo> list = new ArrayList<DriverPropertyInfo>();
+
+    // First, add the contents of info
+    for (Map.Entry<Object, Object> entry : info.entrySet()) {
+      list.add(
+          new DriverPropertyInfo(
+              (String) entry.getKey(),
+              (String) entry.getValue()));
+    }
+    // Next, add property definitions not mentioned in info
+    for (ConnectionProperty p : getConnectionProperties()) {
+      if (info.containsKey(p.name())) {
+        continue;
+      }
+      list.add(new DriverPropertyInfo(p.name(), null));
+    }
+    return list.toArray(new DriverPropertyInfo[list.size()]);
+  }
+
+  // JDBC 4.1 support (JDK 1.7 and higher)
+  public Logger getParentLogger() {
+    return Logger.getLogger("");
+  }
+
+  /**
+   * Returns the driver version object. Not in the JDBC API.
+   *
+   * @return Driver version
+   */
+  public DriverVersion getDriverVersion() {
+    return version;
+  }
+
+  public final int getMajorVersion() {
+    return version.majorVersion;
+  }
+
+  public final int getMinorVersion() {
+    return version.minorVersion;
+  }
+
+  public boolean jdbcCompliant() {
+    return version.jdbcCompliant;
+  }
+
+  /**
+   * Registers this driver with the driver manager.
+   */
+  protected void register() {
+    try {
+      DriverManager.registerDriver(this);
+    } catch (SQLException e) {
+      System.out.println(
+          "Error occurred while registering JDBC driver "
+          + this + ": " + e.toString());
+    }
+  }
+
+  /** Creates a service handler that will give connections from this Driver
+   * their behavior. */
+  public abstract Meta createMeta(AvaticaConnection connection);
+
+  /** JDBC version. */
+  protected enum JdbcVersion {
+    /** Unknown JDBC version. */
+    JDBC_UNKNOWN,
+    /** JDBC version 3.0. Generally associated with JDK 1.5. */
+    JDBC_30,
+    /** JDBC version 4.0. Generally associated with JDK 1.6. */
+    JDBC_40,
+    /** JDBC version 4.1. Generally associated with JDK 1.7. */
+    JDBC_41;
+
+    /** Deduces the current JDBC version. */
+    public static JdbcVersion current() {
+      try {
+        // If java.sql.PseudoColumnUsage is present, we are running JDBC
+        // 4.1 or later.
+        Class.forName("java.sql.PseudoColumnUsage");
+        return JDBC_41;
+      } catch (ClassNotFoundException e) {
+        // java.sql.PseudoColumnUsage is not present. This means we are
+        // running JDBC 4.0 or earlier.
+        try {
+          Class.forName("java.sql.Wrapper");
+          return JDBC_40;
+        } catch (ClassNotFoundException e2) {
+          // java.sql.Wrapper is not present. This means we are
+          // running JDBC 3.0 or earlier (probably JDK 1.5).
+          return JDBC_30;
+        }
+      }
+    }
+  }
+}
+
+// End UnregisteredDriver.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/package-info.java b/avatica/core/src/main/java/org/apache/calcite/avatica/package-info.java
new file mode 100644
index 0000000..89a9fbb
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Avatica JDBC framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java


[50/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
deleted file mode 100644
index 633af78..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
+++ /dev/null
@@ -1,40 +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.metrics;
-
-/**
- * A metric which measures the distribution of values.
- */
-public interface Histogram extends Metric {
-
-  /**
-   * Adds a new value to the distribution.
-   *
-   * @param value The value to add
-   */
-  void update(int value);
-
-  /**
-   * Adds a new value to the distribution.
-   *
-   * @param value The value to add
-   */
-  void update(long value);
-
-}
-
-// End Histogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
deleted file mode 100644
index b27f023..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
+++ /dev/null
@@ -1,38 +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.metrics;
-
-/**
- * A metric which measure the rate at which some operation is invoked.
- */
-public interface Meter extends Metric {
-
-  /**
-   * Records one occurrence.
-   */
-  void mark();
-
-  /**
-   * Records {@code events} occurrences.
-   *
-   * @param events Number of occurrences to record.
-   */
-  void mark(long events);
-
-}
-
-// End Meter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
deleted file mode 100644
index fe133da..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
+++ /dev/null
@@ -1,26 +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.metrics;
-
-/**
- * Parent interface for all metrics.
- */
-public interface Metric {
-
-}
-
-// End Metric.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
deleted file mode 100644
index 0d1cb4b..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
+++ /dev/null
@@ -1,68 +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.metrics;
-
-/**
- * General purpose factory for creating various metrics. Modeled off of the Dropwizard Metrics API.
- */
-public interface MetricsSystem {
-
-  /**
-   * Get or construct a {@link Timer} used to measure durations and report rates.
-   *
-   * @param name The name of the Timer.
-   * @return An instance of {@link Timer}.
-   */
-  Timer getTimer(String name);
-
-  /**
-   * Get or construct a {@link Histogram} used to measure a distribution of values.
-   *
-   * @param name The name of the Histogram.
-   * @return An instance of {@link Histogram}.
-   */
-  Histogram getHistogram(String name);
-
-  /**
-   * Get or construct a {@link Meter} used to measure durations and report distributions (a
-   * combination of a {@link Timer} and a {@link Histogram}.
-   *
-   * @param name The name of the Meter.
-   * @return An instance of {@link Meter}.
-   */
-  Meter getMeter(String name);
-
-  /**
-   * Get or construct a {@link Counter} used to track a mutable number.
-   *
-   * @param name The name of the Counter
-   * @return An instance of {@link Counter}.
-   */
-  Counter getCounter(String name);
-
-  /**
-   * Register a {@link Gauge}. The Gauge will be invoked at a period defined by the implementation
-   * of {@link MetricsSystem}.
-   *
-   * @param name The name of the Gauge.
-   * @param gauge A callback to compute the current value.
-   */
-  <T> void register(String name, Gauge<T> gauge);
-
-}
-
-// End MetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
deleted file mode 100644
index 99b6e8c..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
+++ /dev/null
@@ -1,33 +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.metrics;
-
-/**
- * A container used by a {@link MetricsSystemFactory} to create a {@link MetricsSystem}.
- *
- * @param <T> Configuration/State for the {@link MetricsSystem}.
- */
-public interface MetricsSystemConfiguration<T> {
-
-  /**
-   * @return Some state or configuration to create a {@link MetricsSystem}.
-   */
-  T get();
-
-}
-
-// End MetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
deleted file mode 100644
index 484b230..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
+++ /dev/null
@@ -1,32 +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.metrics;
-
-/**
- * A factory class for creating instances of {@link MetricsSystem}.
- */
-public interface MetricsSystemFactory {
-
-  /**
-   * Creates an instance of a {@link MetricsSystem}.
-   *
-   * @return A new {@link MetricsSystem}.
-   */
-  MetricsSystem create(MetricsSystemConfiguration<?> config);
-}
-
-// End MetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java
deleted file mode 100644
index 3a15c5b..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.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.metrics;
-
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.ServiceLoader;
-
-/**
- * A utility encapsulating use of {@link ServiceLoader} to instantiate a {@link MetricsSystem}.
- */
-public class MetricsSystemLoader {
-  private static final Logger LOG = LoggerFactory.getLogger(MetricsSystemLoader.class);
-  private static final MetricsSystemLoader INSTANCE = new MetricsSystemLoader();
-
-  private MetricsSystemLoader() {}
-
-  /**
-   * Creates a {@link MetricsSystem} instance using the corresponding {@link MetricsSystemFactory}
-   * available to {@link ServiceLoader} on the classpath. If there is not exactly one instance of
-   * a {@link MetricsSystemFactory}, an instance of {@link NoopMetricsSystem} will be returned.
-   *
-   * @param config State to pass to the {@link MetricsSystemFactory}.
-   * @return A {@link MetricsSystem} implementation.
-   */
-  public static MetricsSystem load(MetricsSystemConfiguration<?> config) {
-    return INSTANCE._load(Objects.requireNonNull(config));
-  }
-
-  MetricsSystem _load(MetricsSystemConfiguration<?> config) {
-    List<MetricsSystemFactory> availableFactories = getFactories();
-
-    if (1 == availableFactories.size()) {
-      // One and only one instance -- what we want/expect
-      MetricsSystemFactory factory = availableFactories.get(0);
-      LOG.info("Loaded MetricsSystem {}", factory.getClass());
-      return factory.create(config);
-    } else if (availableFactories.isEmpty()) {
-      // None-provided default to no metrics
-      LOG.info("No metrics implementation available on classpath. Using No-op implementation");
-      return NoopMetricsSystem.getInstance();
-    } else {
-      // Tell the user they're doing something wrong, and choose the first impl.
-      StringBuilder sb = new StringBuilder();
-      for (MetricsSystemFactory factory : availableFactories) {
-        if (sb.length() > 0) {
-          sb.append(", ");
-        }
-        sb.append(factory.getClass());
-      }
-      LOG.warn("Found multiple MetricsSystemFactory implementations: {}."
-          + " Using No-op implementation", sb);
-      return NoopMetricsSystem.getInstance();
-    }
-  }
-
-  List<MetricsSystemFactory> getFactories() {
-    ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class);
-    List<MetricsSystemFactory> availableFactories = new ArrayList<>();
-    for (MetricsSystemFactory factory : loader) {
-      availableFactories.add(factory);
-    }
-    return availableFactories;
-  }
-}
-
-// End MetricsSystemLoader.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
deleted file mode 100644
index e627d31..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
+++ /dev/null
@@ -1,37 +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.metrics;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This is a dummy annotation that forces javac to produce output for
- * otherwise empty package-info.java.
- *
- * <p>The result is maven-compiler-plugin can properly identify the scope of
- * changed files
- *
- * <p>See more details in
- * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
- *   maven-compiler-plugin: incremental compilation broken</a>
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface PackageMarker {
-}
-
-// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
deleted file mode 100644
index be792cc..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
+++ /dev/null
@@ -1,37 +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.metrics;
-
-/**
- * A metric which encompasses a {@link Histogram} and {@link Meter}.
- */
-public interface Timer extends Metric {
-
-  Context start();
-
-  /**
-   * A object that tracks an active timing state.
-   */
-  public interface Context extends AutoCloseable {
-    /**
-     * Stops the timer.
-     */
-    void close();
-  }
-}
-
-// End Timer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
deleted file mode 100644
index 9ce8476..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
+++ /dev/null
@@ -1,36 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Counter;
-
-/**
- * {@link Counter} implementation which does nothing.
- */
-public class NoopCounter implements Counter {
-
-  @Override public void increment() {}
-
-  @Override public void increment(long n) {}
-
-  @Override public void decrement() {}
-
-  @Override public void decrement(long n) {}
-
-}
-
-// End NoopCounter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
deleted file mode 100644
index ee056e9..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
+++ /dev/null
@@ -1,32 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Histogram;
-
-/**
- * {@link Histogram} which does nothing.
- */
-public class NoopHistogram implements Histogram {
-
-  @Override public void update(int value) {}
-
-  @Override public void update(long value) {}
-
-}
-
-// End NoopHistogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
deleted file mode 100644
index 4ad68c9..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
+++ /dev/null
@@ -1,32 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Meter;
-
-/**
- * {@link Meter} which does nothing.
- */
-public class NoopMeter implements Meter {
-
-  @Override public void mark() {}
-
-  @Override public void mark(long events) {}
-
-}
-
-// End NoopMeter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
deleted file mode 100644
index 12b5af1..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
+++ /dev/null
@@ -1,69 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Counter;
-import org.apache.calcite.avatica.metrics.Gauge;
-import org.apache.calcite.avatica.metrics.Histogram;
-import org.apache.calcite.avatica.metrics.Meter;
-import org.apache.calcite.avatica.metrics.Metric;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-
-/**
- * {@link MetricsSystem} implementation which does nothing. Returns {@link Metric} implementations
- * which also does nothing (avoiding null instances).
- */
-public class NoopMetricsSystem implements MetricsSystem {
-
-  private static final NoopMetricsSystem NOOP_METRICS = new NoopMetricsSystem();
-
-  private static final Timer TIMER = new NoopTimer();
-  private static final Histogram HISTOGRAM = new NoopHistogram();
-  private static final Meter METER = new NoopMeter();
-  private static final Counter COUNTER = new NoopCounter();
-
-  /**
-   * @return A {@link NoopMetricsSystem} instance.
-   */
-  public static NoopMetricsSystem getInstance() {
-    return NOOP_METRICS;
-  }
-
-  private NoopMetricsSystem() {}
-
-  @Override public Timer getTimer(String name) {
-    return TIMER;
-  }
-
-  @Override public Histogram getHistogram(String name) {
-    return HISTOGRAM;
-  }
-
-  @Override public Meter getMeter(String name) {
-    return METER;
-  }
-
-  @Override public Counter getCounter(String name) {
-    return COUNTER;
-  }
-
-  @Override public <T> void register(String name, Gauge<T> gauge) {}
-
-}
-
-// End NoopMetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
deleted file mode 100644
index 42b3f24..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
+++ /dev/null
@@ -1,40 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-
-/**
- * An empty configuration for the {@link NoopMetricsSystem}.
- */
-public class NoopMetricsSystemConfiguration implements MetricsSystemConfiguration<Void> {
-
-  private static final NoopMetricsSystemConfiguration INSTANCE =
-      new NoopMetricsSystemConfiguration();
-
-  public static NoopMetricsSystemConfiguration getInstance() {
-    return INSTANCE;
-  }
-
-  private NoopMetricsSystemConfiguration() {}
-
-  @Override public Void get() {
-    return null;
-  }
-}
-
-// End NoopMetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
deleted file mode 100644
index c15f978..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
+++ /dev/null
@@ -1,35 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
-
-/**
- * A {@link MetricsSystemFactory} for the {@link NoopMetricsSystem}.
- *
- * No service file is provided for this implementation. It is the fallback implementation if
- * no implementation or more than one implementation is found on the classpath.
- */
-public class NoopMetricsSystemFactory implements MetricsSystemFactory {
-
-  @Override public NoopMetricsSystem create(MetricsSystemConfiguration<?> config) {
-    return NoopMetricsSystem.getInstance();
-  }
-}
-
-// End NoopMetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
deleted file mode 100644
index a45cd63..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
+++ /dev/null
@@ -1,43 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-
-/**
- * {@link Timer} which does nothing.
- */
-public class NoopTimer implements Timer {
-
-  private static final NoopContext CONTEXT = new NoopContext();
-
-  @Override public NoopContext start() {
-    return CONTEXT;
-  }
-
-  /**
-   * {@link Context} which does nothing.
-   */
-  public static class NoopContext implements Context {
-
-    @Override public void close() {}
-
-  }
-}
-
-// End NoopTimer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
deleted file mode 100644
index 826a655..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * No-operation implementation for the Avatica Metrics framework.
- */
-@PackageMarker
-package org.apache.calcite.avatica.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.PackageMarker;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java b/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
deleted file mode 100644
index efed28c..0000000
--- a/avatica-metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-
-/**
- * Metrics for the Avatica framework.
- */
-@PackageMarker
-package org.apache.calcite.avatica.metrics;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java b/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
deleted file mode 100644
index 1c405ee..0000000
--- a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
+++ /dev/null
@@ -1,114 +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.metrics;
-
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
-
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test class for {@link MetricsSystemLoader}.
- */
-public class MetricsSystemLoaderTest {
-
-  @Test public void testSingleInstance() {
-    final List<MetricsSystemFactory> factories =
-        Collections.<MetricsSystemFactory>singletonList(new MarkedNoopMetricsSystemFactory());
-    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
-
-    Mockito.when(loader.getFactories()).thenReturn(factories);
-    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
-
-    // One MetricsSystemFactory should return the MetricsSystem it creates
-    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
-    assertEquals(MarkedMetricsSystem.INSTANCE, system);
-  }
-
-  @Test public void testMultipleInstances() {
-    // The type of the factories doesn't matter (we can send duplicates for testing purposes)
-    final List<MetricsSystemFactory> factories =
-        Arrays.<MetricsSystemFactory>asList(new MarkedNoopMetricsSystemFactory(),
-            new MarkedNoopMetricsSystemFactory());
-    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
-
-    Mockito.when(loader.getFactories()).thenReturn(factories);
-    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
-
-    // We had two factories loaded, therefore we'll fall back to the NoopMetricsSystem
-    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
-    assertEquals(NoopMetricsSystem.getInstance(), system);
-  }
-
-  @Test public void testNoInstances() {
-    // The type of the factories doesn't matter (we can send duplicates for testing purposes)
-    final List<MetricsSystemFactory> factories = Collections.emptyList();
-    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
-
-    Mockito.when(loader.getFactories()).thenReturn(factories);
-    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
-
-    // We had no factories loaded, therefore we'll fall back to the NoopMetricsSystem
-    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
-    assertEquals(NoopMetricsSystem.getInstance(), system);
-  }
-
-  /**
-   * A test factory implementation which can return a recognized MetricsSystem implementation.
-   */
-  private static class MarkedNoopMetricsSystemFactory implements MetricsSystemFactory {
-    public MarkedMetricsSystem create(MetricsSystemConfiguration<?> config) {
-      return MarkedMetricsSystem.INSTANCE;
-    }
-  }
-
-  /**
-   * A metrics system implementation that is identifiable for testing.
-   */
-  private static class MarkedMetricsSystem implements MetricsSystem {
-    private static final MarkedMetricsSystem INSTANCE = new MarkedMetricsSystem();
-
-    private MarkedMetricsSystem() {}
-
-    @Override public Timer getTimer(String name) {
-      return null;
-    }
-
-    @Override public Histogram getHistogram(String name) {
-      return null;
-    }
-
-    @Override public Meter getMeter(String name) {
-      return null;
-    }
-
-    @Override public Counter getCounter(String name) {
-      return null;
-    }
-
-    @Override public <T> void register(String name, Gauge<T> gauge) {}
-  }
-}
-
-// End MetricsSystemLoaderTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java b/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
deleted file mode 100644
index 3060b2f..0000000
--- a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
+++ /dev/null
@@ -1,37 +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.metrics.noop;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * Test class for {@link NoopMetricsSystemFactory}.
- */
-public class NoopMetricsSystemFactoryTest {
-
-  @Test public void testSingleton() {
-    NoopMetricsSystemFactory factory = new NoopMetricsSystemFactory();
-    NoopMetricsSystemConfiguration config = NoopMetricsSystemConfiguration.getInstance();
-    assertTrue("The factory should only return one NoopMetricsSystem instance",
-        factory.create(config) == factory.create(config));
-  }
-
-}
-
-// End NoopMetricsSystemFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java b/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
deleted file mode 100644
index f28d123..0000000
--- a/avatica-metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
+++ /dev/null
@@ -1,73 +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.metrics.noop;
-
-import org.apache.calcite.avatica.metrics.Counter;
-import org.apache.calcite.avatica.metrics.Gauge;
-import org.apache.calcite.avatica.metrics.Histogram;
-import org.apache.calcite.avatica.metrics.Meter;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for {@link NoopMetricsSystem}.
- */
-public class NoopMetricsSystemTest {
-
-  @Test public void testNoNulls() {
-    // The NOOP implementation should act as a real implementation, no "nulls" allowed.
-    MetricsSystem metrics = NoopMetricsSystem.getInstance();
-
-    Counter counter = metrics.getCounter("counter");
-    counter.decrement();
-    counter.increment();
-    counter.decrement(1L);
-    counter.increment(1L);
-
-    Histogram histogram = metrics.getHistogram("histogram");
-    histogram.update(1);
-    histogram.update(1L);
-
-    Timer timer = metrics.getTimer("timer");
-    Context context = timer.start();
-    context.close();
-    Context contextTwo = timer.start();
-    assertTrue("Timer's context should be a singleton", context == contextTwo);
-
-    Meter meter = metrics.getMeter("meter");
-    meter.mark();
-    meter.mark(5L);
-
-    metrics.register("gauge", new Gauge<Long>() {
-      @Override public Long getValue() {
-        return 42L;
-      }
-    });
-  }
-
-  @Test public void testSingleton() {
-    assertTrue("Should be a singleton",
-        NoopMetricsSystem.getInstance() == NoopMetricsSystem.getInstance());
-  }
-}
-
-// End NoopMetricsSystemTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-metrics/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica-metrics/src/test/resources/log4j.properties b/avatica-metrics/src/test/resources/log4j.properties
deleted file mode 100644
index 834e2db..0000000
--- a/avatica-metrics/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +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.
-
-# Root logger is configured at INFO and is sent to A1
-log4j.rootLogger=INFO, A1
-
-# A1 goes to the console
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# Set the pattern for each log message
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p - %m%n

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/pom.xml
----------------------------------------------------------------------
diff --git a/avatica-noop/pom.xml b/avatica-noop/pom.xml
deleted file mode 100644
index 3a05cdd..0000000
--- a/avatica-noop/pom.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>calcite-avatica-noop</artifactId>
-  <packaging>jar</packaging>
-  <name>Calcite Avatica Noop</name>
-  <description>A Noop JDBC driver.</description>
-
-  <properties>
-    <top.dir>${project.basedir}/..</top.dir>
-  </properties>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <versionRange>[2.12.1,)</versionRange>
-                    <goals>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <!-- Parent module has the same plugin and does the work of
-           generating -sources.jar for each project. But without the
-           plugin declared here, IDEs don't know the sources are
-           available. -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-source-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-sources</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>jar-no-fork</goal>
-              <goal>test-jar-no-fork</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- Produce a tests jar so that avatica-server/pom.xml can reference for suite.
-           TODO: remove after moving over to annotation-based TestSuite definitions. -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-remote-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>non-root-resources</id>
-            <goals>
-              <goal>process</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
deleted file mode 100644
index 6870717..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopConnection.java
+++ /dev/null
@@ -1,256 +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.noop;
-
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Struct;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.Executor;
-
-/**
- * A {@link Connection} implementation which does nothing.
- */
-public class AvaticaNoopConnection implements Connection {
-
-  private static final AvaticaNoopConnection INSTANCE = new AvaticaNoopConnection();
-
-  public static AvaticaNoopConnection getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopConnection() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Statement createStatement() throws SQLException {
-    return AvaticaNoopStatement.getInstance();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql) throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public CallableStatement prepareCall(String sql) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String nativeSQL(String sql) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setAutoCommit(boolean autoCommit) throws SQLException {}
-
-  @Override public boolean getAutoCommit() throws SQLException {
-    return false;
-  }
-
-  @Override public void commit() throws SQLException {}
-
-  @Override public void rollback() throws SQLException {}
-
-  @Override public void close() throws SQLException {}
-
-  @Override public boolean isClosed() throws SQLException {
-    return true;
-  }
-
-  @Override public DatabaseMetaData getMetaData() throws SQLException {
-    return AvaticaNoopDatabaseMetaData.getInstance();
-  }
-
-  @Override public void setReadOnly(boolean readOnly) throws SQLException {}
-
-  @Override public boolean isReadOnly() throws SQLException {
-    return false;
-  }
-
-  @Override public void setCatalog(String catalog) throws SQLException {}
-
-  @Override public String getCatalog() throws SQLException {
-    return null;
-  }
-
-  @Override public void setTransactionIsolation(int level) throws SQLException {}
-
-  @Override public int getTransactionIsolation() throws SQLException {
-    return 0;
-  }
-
-  @Override public SQLWarning getWarnings() throws SQLException {
-    return null;
-  }
-
-  @Override public void clearWarnings() throws SQLException {}
-
-  @Override public Statement createStatement(int resultSetType, int resultSetConcurrency)
-      throws SQLException {
-    return AvaticaNoopStatement.getInstance();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql, int resultSetType,
-      int resultSetConcurrency) throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public CallableStatement prepareCall(String sql, int resultSetType,
-      int resultSetConcurrency) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Map<String, Class<?>> getTypeMap() throws SQLException {
-    return Collections.emptyMap();
-  }
-
-  @Override public void setTypeMap(Map<String, Class<?>> map) throws SQLException {}
-
-  @Override public void setHoldability(int holdability) throws SQLException {}
-
-  @Override public int getHoldability() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Savepoint setSavepoint() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Savepoint setSavepoint(String name) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void rollback(Savepoint savepoint) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Statement createStatement(int resultSetType, int resultSetConcurrency,
-      int resultSetHoldability) throws SQLException {
-    return AvaticaNoopStatement.getInstance();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql, int resultSetType,
-      int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public CallableStatement prepareCall(String sql, int resultSetType,
-      int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
-      throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
-      throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public PreparedStatement prepareStatement(String sql, String[] columnNames)
-      throws SQLException {
-    return AvaticaNoopPreparedStatement.getInstance();
-  }
-
-  @Override public Clob createClob() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Blob createBlob() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public NClob createNClob() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public SQLXML createSQLXML() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isValid(int timeout) throws SQLException {
-    return true;
-  }
-
-  @Override public void setClientInfo(String name, String value) throws SQLClientInfoException {}
-
-  @Override public void setClientInfo(Properties properties) throws SQLClientInfoException {}
-
-  @Override public String getClientInfo(String name) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Properties getClientInfo() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setSchema(String schema) throws SQLException {}
-
-  @Override public String getSchema() throws SQLException {
-    return null;
-  }
-
-  @Override public void abort(Executor executor) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setNetworkTimeout(Executor executor, int milliseconds)
-      throws SQLException {}
-
-  @Override public int getNetworkTimeout() throws SQLException {
-    throw unsupported();
-  }
-
-}
-
-// End AvaticaNoopConnection.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
deleted file mode 100644
index 2b58590..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDatabaseMetaData.java
+++ /dev/null
@@ -1,770 +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.noop;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.RowIdLifetime;
-import java.sql.SQLException;
-
-/**
- * A {@link DatabaseMetaData} implementation which does nothing.
- */
-public class AvaticaNoopDatabaseMetaData implements DatabaseMetaData {
-
-  private static final AvaticaNoopDatabaseMetaData INSTANCE = new AvaticaNoopDatabaseMetaData();
-
-  public static AvaticaNoopDatabaseMetaData getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopDatabaseMetaData() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean allProceduresAreCallable() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean allTablesAreSelectable() throws SQLException {
-    return false;
-  }
-
-  @Override public String getURL() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getUserName() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isReadOnly() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean nullsAreSortedHigh() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean nullsAreSortedLow() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean nullsAreSortedAtStart() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean nullsAreSortedAtEnd() throws SQLException {
-    return false;
-  }
-
-  @Override public String getDatabaseProductName() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getDatabaseProductVersion() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getDriverName() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getDriverVersion() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getDriverMajorVersion() {
-    return 0;
-  }
-
-  @Override public int getDriverMinorVersion() {
-    return 0;
-  }
-
-  @Override public boolean usesLocalFiles() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean usesLocalFilePerTable() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMixedCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesUpperCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesLowerCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesMixedCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override public String getIdentifierQuoteString() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getSQLKeywords() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getNumericFunctions() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getStringFunctions() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getSystemFunctions() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getTimeDateFunctions() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getSearchStringEscape() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getExtraNameCharacters() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean supportsAlterTableWithAddColumn() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsAlterTableWithDropColumn() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsColumnAliasing() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean nullPlusNonNullIsNull() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsConvert() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsConvert(int fromType, int toType) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsTableCorrelationNames() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsDifferentTableCorrelationNames() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsExpressionsInOrderBy() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOrderByUnrelated() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsGroupBy() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsGroupByUnrelated() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsGroupByBeyondSelect() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsLikeEscapeClause() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMultipleResultSets() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMultipleTransactions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsNonNullableColumns() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMinimumSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCoreSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsExtendedSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsANSI92EntryLevelSQL() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsANSI92IntermediateSQL() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsANSI92FullSQL() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsIntegrityEnhancementFacility() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsFullOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsLimitedOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override public String getSchemaTerm() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getProcedureTerm() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getCatalogTerm() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isCatalogAtStart() throws SQLException {
-    return false;
-  }
-
-  @Override public String getCatalogSeparator() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean supportsSchemasInDataManipulation() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSchemasInProcedureCalls() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSchemasInTableDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSchemasInIndexDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCatalogsInDataManipulation() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCatalogsInProcedureCalls() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCatalogsInTableDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsPositionedDelete() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsPositionedUpdate() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSelectForUpdate() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsStoredProcedures() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSubqueriesInComparisons() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSubqueriesInExists() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSubqueriesInIns() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsSubqueriesInQuantifieds() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsCorrelatedSubqueries() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsUnion() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsUnionAll() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  @Override public int getMaxBinaryLiteralLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxCharLiteralLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnsInGroupBy() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnsInIndex() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnsInOrderBy() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnsInSelect() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxColumnsInTable() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxConnections() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxCursorNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxIndexLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxSchemaNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxProcedureNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxCatalogNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxRowSize() throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
-    return false;
-  }
-
-  @Override public int getMaxStatementLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxStatements() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxTableNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxTablesInSelect() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getMaxUserNameLength() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getDefaultTransactionIsolation() throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean supportsTransactions() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsDataDefinitionAndDataManipulationTransactions()
-      throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getProcedures(String catalog, String schemaPattern,
-      String procedureNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getProcedureColumns(String catalog, String schemaPattern,
-      String procedureNamePattern, String columnNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getTables(String catalog, String schemaPattern,
-      String tableNamePattern, String[] types) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getSchemas() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getCatalogs() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getTableTypes() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getColumns(String catalog, String schemaPattern,
-      String tableNamePattern, String columnNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table,
-      String columnNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern,
-      String tableNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table,
-      int scope, boolean nullable) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getVersionColumns(String catalog, String schema, String table)
-      throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table)
-      throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getImportedKeys(String catalog, String schema, String table)
-      throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getExportedKeys(String catalog, String schema, String table)
-      throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema,
-      String parentTable, String foreignCatalog, String foreignSchema,
-      String foreignTable) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getTypeInfo() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getIndexInfo(String catalog, String schema, String table,
-      boolean unique, boolean approximate) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public boolean supportsResultSetType(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsResultSetConcurrency(int type, int concurrency)
-      throws SQLException {
-    return false;
-  }
-
-  @Override public boolean ownUpdatesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean ownDeletesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean ownInsertsAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean othersUpdatesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean othersDeletesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean othersInsertsAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean updatesAreDetected(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean deletesAreDetected(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean insertsAreDetected(int type) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsBatchUpdates() throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern,
-      int[] types) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Connection getConnection() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean supportsSavepoints() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsNamedParameters() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsMultipleOpenResults() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsGetGeneratedKeys() throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getSuperTypes(String catalog, String schemaPattern,
-      String typeNamePattern) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSet getSuperTables(String catalog, String schemaPattern,
-      String tableNamePattern) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSet getAttributes(String catalog, String schemaPattern,
-      String typeNamePattern, String attributeNamePattern) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean supportsResultSetHoldability(int holdability) throws SQLException {
-    return false;
-  }
-
-  @Override public int getResultSetHoldability() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getDatabaseMajorVersion() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getDatabaseMinorVersion() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getJDBCMajorVersion() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getJDBCMinorVersion() throws SQLException {
-    return 0;
-  }
-
-  @Override public int getSQLStateType() throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean locatorsUpdateCopy() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean supportsStatementPooling() throws SQLException {
-    return false;
-  }
-
-  @Override public RowIdLifetime getRowIdLifetime() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
-    return false;
-  }
-
-  @Override public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getClientInfoProperties() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getFunctions(String catalog, String schemaPattern,
-      String functionNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getFunctionColumns(String catalog, String schemaPattern,
-      String functionNamePattern, String columnNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public ResultSet getPseudoColumns(String catalog, String schemaPattern,
-      String tableNamePattern, String columnNamePattern) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public boolean generatedKeyAlwaysReturned() throws SQLException {
-    return false;
-  }
-}
-
-// End AvaticaNoopDatabaseMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
deleted file mode 100644
index 76f5356..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopDriver.java
+++ /dev/null
@@ -1,74 +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.noop;
-
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.util.Properties;
-import java.util.logging.Logger;
-
-/**
- * A Noop JDBC Driver.
- */
-public class AvaticaNoopDriver implements Driver {
-
-  private static final AvaticaNoopDriver INSTANCE = new AvaticaNoopDriver();
-
-  static {
-    try {
-      DriverManager.registerDriver(INSTANCE);
-    } catch (Exception e) {
-      System.err.println("Failed to register driver");
-      e.printStackTrace(System.err);
-    }
-  }
-
-  @Override public Connection connect(String url, Properties info) throws SQLException {
-    return AvaticaNoopConnection.getInstance();
-  }
-
-  @Override public boolean acceptsURL(String url) throws SQLException {
-    return url.startsWith("jdbc:avatica:noop");
-  }
-
-  @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
-      throws SQLException {
-    return new DriverPropertyInfo[0];
-  }
-
-  @Override public int getMajorVersion() {
-    return 1;
-  }
-
-  @Override public int getMinorVersion() {
-    return 7;
-  }
-
-  @Override public boolean jdbcCompliant() {
-    return true;
-  }
-
-  @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-    return Logger.getLogger("");
-  }
-}
-
-// End AvaticaNoopDriver.java


[31/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/protobuf/common.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/common.proto b/avatica/core/src/main/protobuf/common.proto
new file mode 100644
index 0000000..bd116c3
--- /dev/null
+++ b/avatica/core/src/main/protobuf/common.proto
@@ -0,0 +1,275 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+// Details about a connection
+message ConnectionProperties {
+  bool is_dirty = 1;
+  bool auto_commit = 2;
+  bool has_auto_commit = 7; // field is a Boolean, need to discern null and default value
+  bool read_only = 3;
+  bool has_read_only = 8; // field is a Boolean, need to discern null and default value
+  uint32 transaction_isolation = 4;
+  string catalog = 5;
+  string schema = 6;
+}
+
+// Statement handle
+message StatementHandle {
+  string connection_id = 1;
+  uint32 id = 2;
+  Signature signature = 3;
+}
+
+// Results of preparing a statement
+message Signature {
+  repeated ColumnMetaData columns = 1;
+  string sql = 2;
+  repeated AvaticaParameter parameters = 3;
+  CursorFactory cursor_factory = 4;
+  StatementType statementType = 5;
+}
+
+// Has to be consistent with Meta.StatementType
+enum StatementType {
+  SELECT = 0;
+  INSERT = 1;
+  UPDATE = 2;
+  DELETE = 3;
+  UPSERT = 4;
+  MERGE = 5;
+  OTHER_DML = 6;
+  CREATE = 7;
+  DROP = 8;
+  ALTER = 9;
+  OTHER_DDL = 10;
+  CALL = 11;
+}
+
+message ColumnMetaData {
+  uint32 ordinal = 1;
+  bool auto_increment = 2;
+  bool case_sensitive = 3;
+  bool searchable = 4;
+  bool currency = 5;
+  uint32 nullable = 6;
+  bool signed = 7;
+  uint32 display_size = 8;
+  string label = 9;
+  string column_name = 10;
+  string schema_name = 11;
+  uint32 precision = 12;
+  uint32 scale = 13;
+  string table_name = 14;
+  string catalog_name = 15;
+  bool read_only = 16;
+  bool writable = 17;
+  bool definitely_writable = 18;
+  string column_class_name = 19;
+  AvaticaType type = 20;
+}
+
+enum Rep {
+  PRIMITIVE_BOOLEAN = 0;
+  PRIMITIVE_BYTE = 1;
+  PRIMITIVE_CHAR = 2;
+  PRIMITIVE_SHORT = 3;
+  PRIMITIVE_INT = 4;
+  PRIMITIVE_LONG = 5;
+  PRIMITIVE_FLOAT = 6;
+  PRIMITIVE_DOUBLE = 7;
+  BOOLEAN = 8;
+  BYTE = 9;
+  CHARACTER = 10;
+  SHORT = 11;
+  INTEGER = 12;
+  LONG = 13;
+  FLOAT = 14;
+  DOUBLE = 15;
+  BIG_INTEGER = 25;
+  BIG_DECIMAL = 26;
+  JAVA_SQL_TIME = 16;
+  JAVA_SQL_TIMESTAMP = 17;
+  JAVA_SQL_DATE = 18;
+  JAVA_UTIL_DATE = 19;
+  BYTE_STRING = 20;
+  STRING = 21;
+  NUMBER = 22;
+  OBJECT = 23;
+  NULL = 24;
+  ARRAY = 27;
+  STRUCT = 28;
+  MULTISET = 29;
+}
+
+// Base class for a column type
+message AvaticaType {
+  uint32 id = 1;
+  string name = 2;
+  Rep rep = 3;
+
+  repeated ColumnMetaData columns = 4; // Only present when name = STRUCT
+  AvaticaType component = 5; // Only present when name = ARRAY
+}
+
+// Metadata for a parameter
+message AvaticaParameter {
+  bool signed = 1;
+  uint32 precision = 2;
+  uint32 scale = 3;
+  uint32 parameter_type = 4;
+  string type_name = 5;
+  string class_name = 6;
+  string name = 7;
+}
+
+// Information necessary to convert an Iterable into a Calcite Cursor
+message CursorFactory {
+  enum Style {
+    OBJECT = 0;
+    RECORD = 1;
+    RECORD_PROJECTION = 2;
+    ARRAY = 3;
+    LIST = 4;
+    MAP = 5;
+  }
+
+  Style style = 1;
+  string class_name = 2;
+  repeated string field_names = 3;
+}
+
+// A collection of rows
+message Frame {
+  uint64 offset = 1;
+  bool done = 2;
+  repeated Row rows = 3;
+}
+
+// A row is a collection of values
+message Row {
+  repeated ColumnValue value = 1;
+}
+
+// Database property, list of functions the database provides for a certain operation
+message DatabaseProperty {
+  string name = 1;
+  repeated string functions = 2;
+}
+
+// Message which encapsulates another message to support a single RPC endpoint
+message WireMessage {
+  string name = 1;
+  bytes wrapped_message = 2;
+}
+
+// A value might be a TypedValue or an Array of TypedValue's
+message ColumnValue {
+  repeated TypedValue value = 1; // deprecated, use array_value or scalar_value
+  repeated TypedValue array_value = 2;
+  bool has_array_value = 3; // Is an array value set?
+  TypedValue scalar_value = 4;
+}
+
+// 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
+
+  bool bool_value = 2; // boolean
+  string string_value = 3; // char/varchar
+  sint64 number_value = 4; // var-len encoding lets us shove anything from byte to long
+                           // includes numeric types and date/time types.
+  bytes bytes_values = 5; // binary/varbinary
+  double double_value = 6; // big numbers
+  bool null = 7; // a null object
+}
+
+// The severity of some unexpected outcome to an operation.
+// Protobuf enum values must be unique across all other enums
+enum Severity {
+  UNKNOWN_SEVERITY = 0;
+  FATAL_SEVERITY = 1;
+  ERROR_SEVERITY = 2;
+  WARNING_SEVERITY = 3;
+}
+
+// Enumeration corresponding to DatabaseMetaData operations
+enum MetaDataOperation {
+  GET_ATTRIBUTES = 0;
+  GET_BEST_ROW_IDENTIFIER = 1;
+  GET_CATALOGS = 2;
+  GET_CLIENT_INFO_PROPERTIES = 3;
+  GET_COLUMN_PRIVILEGES = 4;
+  GET_COLUMNS = 5;
+  GET_CROSS_REFERENCE = 6;
+  GET_EXPORTED_KEYS = 7;
+  GET_FUNCTION_COLUMNS = 8;
+  GET_FUNCTIONS = 9;
+  GET_IMPORTED_KEYS = 10;
+  GET_INDEX_INFO = 11;
+  GET_PRIMARY_KEYS = 12;
+  GET_PROCEDURE_COLUMNS = 13;
+  GET_PROCEDURES = 14;
+  GET_PSEUDO_COLUMNS = 15;
+  GET_SCHEMAS = 16;
+  GET_SCHEMAS_WITH_ARGS = 17;
+  GET_SUPER_TABLES = 18;
+  GET_SUPER_TYPES = 19;
+  GET_TABLE_PRIVILEGES = 20;
+  GET_TABLES = 21;
+  GET_TABLE_TYPES = 22;
+  GET_TYPE_INFO = 23;
+  GET_UDTS = 24;
+  GET_VERSION_COLUMNS = 25;
+}
+
+// Represents the breadth of arguments to DatabaseMetaData functions
+message MetaDataOperationArgument {
+  enum ArgumentType {
+    STRING = 0;
+    BOOL = 1;
+    INT = 2;
+    REPEATED_STRING = 3;
+    REPEATED_INT = 4;
+    NULL = 5;
+  }
+    
+  string string_value = 1;
+  bool bool_value = 2;
+  sint32 int_value = 3;
+  repeated string string_array_values = 4;
+  repeated sint32 int_array_values = 5;
+  ArgumentType type = 6;
+}
+
+enum StateType {
+  SQL = 0;
+  METADATA = 1;
+}
+
+message QueryState {
+  StateType type = 1;
+  string sql = 2;
+  MetaDataOperation op = 3;
+  repeated MetaDataOperationArgument args = 4;
+  bool has_args = 5;
+  bool has_sql = 6;
+  bool has_op = 7;
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/protobuf/requests.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/requests.proto b/avatica/core/src/main/protobuf/requests.proto
new file mode 100644
index 0000000..31b0941
--- /dev/null
+++ b/avatica/core/src/main/protobuf/requests.proto
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+import "common.proto";
+
+// Request for Meta#getCatalogs()
+message CatalogsRequest {
+  string connection_id = 1;
+}
+
+// Request for Meta#getDatabaseProperties()
+message DatabasePropertyRequest {
+  string connection_id = 1;
+}
+
+// Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
+message SchemasRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string connection_id = 3;
+}
+
+// Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
+//   org.apache.calcite.avatica.Meta.Pat, java.util.List)
+message TablesRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  repeated string type_list = 4;
+  bool has_type_list = 6; // Having an empty type_list is distinct from a null type_list
+  string connection_id = 7;
+}
+
+// Request for Meta#getTableTypes()
+message TableTypesRequest {
+  string connection_id = 1;
+}
+
+// Request for Meta#getColumns(String, org.apache.calcite.avatica.Meta.Pat,
+//   org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat).
+message ColumnsRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  string column_name_pattern = 4;
+  string connection_id = 5;
+}
+
+// Request for Meta#getTypeInfo()
+message TypeInfoRequest {
+  string connection_id = 1;
+}
+
+// Request for Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)
+message PrepareAndExecuteRequest {
+  string connection_id = 1;
+  string sql = 2;
+  uint64 max_row_count = 3;
+  uint32 statement_id = 4;
+}
+
+// Request for Meta.prepare(Meta.ConnectionHandle, String, long)
+message PrepareRequest {
+  string connection_id = 1;
+  string sql = 2;
+  uint64 max_row_count = 3;
+}
+
+// Request for Meta#fetch(Meta.StatementHandle, List, long, int)
+message FetchRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  uint64 offset = 3;
+  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+}
+
+// Request for Meta#createStatement(Meta.ConnectionHandle)
+message CreateStatementRequest {
+  string connection_id = 1;
+}
+
+// Request for Meta#closeStatement(Meta.StatementHandle)
+message CloseStatementRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+}
+
+// Request for Meta#openConnection(Meta.ConnectionHandle, Map<String, String>)
+message OpenConnectionRequest {
+  string connection_id = 1;
+  map<string, string> info = 2;
+}
+
+// Request for Meta#closeConnection(Meta.ConnectionHandle)
+message CloseConnectionRequest {
+  string connection_id = 1;
+}
+
+message ConnectionSyncRequest {
+  string connection_id = 1;
+  ConnectionProperties conn_props = 2;
+}
+
+// Request for Meta#execute(Meta.ConnectionHandle, list, long)
+message ExecuteRequest {
+  StatementHandle statementHandle = 1;
+  repeated TypedValue parameter_values = 2;
+  uint64 max_row_count = 3;
+  bool has_parameter_values = 4;
+}
+
+
+message SyncResultsRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  QueryState state = 3;
+  uint64 offset = 4;
+}
+
+// Request to invoke a commit on a Connection
+message CommitRequest {
+  string connection_id = 1;
+}
+
+// Request to invoke rollback on a Connection
+message RollbackRequest {
+  string connection_id = 1;
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/protobuf/responses.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/responses.proto b/avatica/core/src/main/protobuf/responses.proto
new file mode 100644
index 0000000..01a62ed
--- /dev/null
+++ b/avatica/core/src/main/protobuf/responses.proto
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+import "common.proto";
+
+// Response that contains a result set.
+message ResultSetResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  bool own_statement = 3;
+  Signature signature = 4;
+  Frame first_frame = 5;
+  uint64 update_count = 6; // -1 for normal result sets, else this response contains a dummy result set
+                                    // with no signature nor other data.
+  RpcMetadata metadata = 7;
+}
+
+// Response to PrepareAndExecuteRequest
+message ExecuteResponse {
+  repeated ResultSetResponse results = 1;
+  bool missing_statement = 2; // Did the request fail because of no-cached statement
+  RpcMetadata metadata = 3;
+}
+
+// Response to PrepareRequest
+message PrepareResponse {
+  StatementHandle statement = 1;
+  RpcMetadata metadata = 2;
+}
+
+// Response to FetchRequest
+message FetchResponse {
+  Frame frame = 1;
+  bool missing_statement = 2; // Did the request fail because of no-cached statement
+  bool missing_results = 3; // Did the request fail because of a cached-statement w/o ResultSet
+  RpcMetadata metadata = 4;
+}
+
+// Response to CreateStatementRequest
+message CreateStatementResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  RpcMetadata metadata = 3;
+}
+
+// Response to CloseStatementRequest
+message CloseStatementResponse {
+  RpcMetadata metadata = 1;
+}
+
+// Response to OpenConnectionRequest {
+message OpenConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+
+// Response to CloseConnectionRequest {
+message CloseConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+
+// Response to ConnectionSyncRequest
+message ConnectionSyncResponse {
+  ConnectionProperties conn_props = 1;
+  RpcMetadata metadata = 2;
+}
+
+message DatabasePropertyElement {
+  DatabaseProperty key = 1;
+  TypedValue value = 2;
+  RpcMetadata metadata = 3;
+}
+
+// Response for Meta#getDatabaseProperties()
+message DatabasePropertyResponse {
+  repeated DatabasePropertyElement props = 1;
+  RpcMetadata metadata = 2;
+}
+
+// Send contextual information about some error over the wire from the server.
+message ErrorResponse {
+  repeated string exceptions = 1; // exception stacktraces, many for linked exceptions.
+  bool has_exceptions = 7; // are there stacktraces contained?
+  string error_message = 2; // human readable description
+  Severity severity = 3;
+  uint32 error_code = 4; // numeric identifier for error
+  string sql_state = 5; // five-character standard-defined value
+  RpcMetadata metadata = 6;
+}
+
+message SyncResultsResponse {
+  bool missing_statement = 1; // Server doesn't have the statement with the ID from the request
+  bool more_results = 2; // Should the client fetch() to get more results
+  RpcMetadata metadata = 3;
+}
+
+// Generic metadata for the server to return with each response.
+message RpcMetadata {
+  string server_address = 1; // The host:port of the server
+}
+
+// Response to a commit request
+message CommitResponse {
+
+}
+
+// Response to a rollback request
+message RollbackResponse {
+
+}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/resources/META-INF/LICENSE b/avatica/core/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..7764d41
--- /dev/null
+++ b/avatica/core/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,257 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+
+
+
+
+-----------------------------------------------------------------------
+
+APACHE CALCITE SUBCOMPONENTS:
+
+The Apache Calcite project contains subcomponents with separate copyright
+notices and license terms. Your use of the source code for the these
+subcomponents is subject to the terms and conditions of the following
+licenses.
+
+-----------------------------------------------------------------------
+ 3-clause BSD license
+-----------------------------------------------------------------------
+
+The Apache Calcite Avatica project bundles Protocol Buffers, which is available
+under the following "3-clause BSD" license:
+
+    Copyright 2014, Google Inc. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, are permitted provided that the following
+    conditions are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the following disclaimer
+    in the documentation and/or other materials provided with the
+    distribution.
+
+    Neither the name of Google Inc. nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    Code generated by the Protocol Buffer compiler is owned by the owner
+    of the input file used when generating it. This code is not
+    standalone and requires a support library to be linked with it. This
+    support library is itself covered by the above license.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/resources/META-INF/services/java.sql.Driver
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/resources/META-INF/services/java.sql.Driver b/avatica/core/src/main/resources/META-INF/services/java.sql.Driver
new file mode 100644
index 0000000..beb1ac0
--- /dev/null
+++ b/avatica/core/src/main/resources/META-INF/services/java.sql.Driver
@@ -0,0 +1 @@
+org.apache.calcite.avatica.remote.Driver

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/scripts/generate-protobuf.sh
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/scripts/generate-protobuf.sh b/avatica/core/src/main/scripts/generate-protobuf.sh
new file mode 100755
index 0000000..c4d3abe
--- /dev/null
+++ b/avatica/core/src/main/scripts/generate-protobuf.sh
@@ -0,0 +1,99 @@
+#! /usr/bin/env bash
+
+# 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.
+
+# This script will regenerate the protobuf code for Avatica. Slightly
+# modified script over one in Accumulo.
+
+# NOTES:
+#   To support this script being called by other modules, only edit the right side.
+#   In other scripts, set the variables that diverge from the defaults below, then call this script.
+#   Leave the BUILD_DIR and FINAL_DIR alone for Maven builds.
+# ========================================================================================================================
+[[ -z $REQUIRED_PROTOC_VERSION ]] && REQUIRED_PROTOC_VERSION='libprotoc 3.0.0'
+[[ -z $BUILD_DIR ]]               && BUILD_DIR='target/proto-tmp'
+[[ -z $FINAL_DIR ]]               && FINAL_DIR='src/main'
+# ========================================================================================================================
+
+fail() {
+  echo "$@"
+  exit 1
+}
+
+# Test to see if we have protoc installed
+VERSION=$(protoc --version 2>/dev/null | grep -F "${REQUIRED_PROTOC_VERSION}" |  wc -l)
+if [[ $VERSION -ne 1 ]] ; then
+  # Nope: bail
+  echo "****************************************************"
+  echo "*** protoc is not available"
+  echo "***   expecting 'protoc --version' to return ${REQUIRED_PROTOC_VERSION}"
+  echo "*** generated code will not be updated"
+  fail "****************************************************"
+fi
+
+# Ensure output directories are created
+PROTOC_ARGS="-I src/main/protobuf --java_out=$BUILD_DIR"
+rm -rf $BUILD_DIR
+mkdir -p $BUILD_DIR
+
+protoc ${PROTOC_ARGS} src/main/protobuf/*.proto || fail unable to generate Java protocol buffer classes
+
+# For all generated protobuf code, suppress all warnings and add the LICENSE header
+s='@SuppressWarnings({"unused", "rawtypes"})'
+find $BUILD_DIR -name '*.java' -print0 | xargs -0 sed -i.orig -e 's/\(public final class \)/'"$s"' \1/'
+
+PREFIX="/*
+"
+LINE_NOTATION=" *"
+SUFFIX="
+ */"
+FILE_SUFFIX=(.java)
+
+for file in "${FILE_SUFFIX[@]}"; do
+  for f in $(find $BUILD_DIR/ -name "*$file"); do
+    cat - "$f" > "${f}-with-license" <<EOF
+${PREFIX}${LINE_NOTATION} Licensed to the Apache Software Foundation (ASF) under one or more
+${LINE_NOTATION} contributor license agreements.  See the NOTICE file distributed with
+${LINE_NOTATION} this work for additional information regarding copyright ownership.
+${LINE_NOTATION} The ASF licenses this file to you under the Apache License, Version 2.0
+${LINE_NOTATION} (the "License"); you may not use this file except in compliance with
+${LINE_NOTATION} the License.  You may obtain a copy of the License at
+${LINE_NOTATION}
+${LINE_NOTATION} http://www.apache.org/licenses/LICENSE-2.0
+${LINE_NOTATION}
+${LINE_NOTATION} Unless required by applicable law or agreed to in writing, software
+${LINE_NOTATION} distributed under the License is distributed on an "AS IS" BASIS,
+${LINE_NOTATION} WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+${LINE_NOTATION} See the License for the specific language governing permissions and
+${LINE_NOTATION} limitations under the License.${SUFFIX}
+EOF
+  done
+done
+
+# For every generated java file, compare it with the version-controlled one, and copy the ones that have changed into place
+SDIR="${BUILD_DIR}/org/apache/calcite/avatica/proto"
+DDIR="${FINAL_DIR}/java/org/apache/calcite/avatica/proto"
+FILE_SUFFIX=(.java)
+mkdir -p "$DDIR"
+for file in "${FILE_SUFFIX[@]}"; do
+  for f in $(find $SDIR -name *$file); do
+    DEST=$DDIR/$(basename "$f")
+    if ! cmp -s "${f}-with-license" "${DEST}" ; then
+      echo cp -f "${f}-with-license" "${DEST}"
+      cp -f "${f}-with-license" "${DEST}" || fail unable to copy files to java workspace
+    fi
+  done
+done

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaConnectionTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaConnectionTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaConnectionTest.java
new file mode 100644
index 0000000..a1414c3
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaConnectionTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Properties;
+
+/**
+ * Tests for AvaticaConnection
+ */
+public class AvaticaConnectionTest {
+
+  @Test
+  public void testNumExecuteRetries() {
+    AvaticaConnection statement = Mockito.mock(AvaticaConnection.class);
+
+    Mockito.when(statement.getNumStatementRetries(Mockito.any(Properties.class)))
+      .thenCallRealMethod();
+
+    // Bad argument should throw an exception
+    try {
+      statement.getNumStatementRetries(null);
+      Assert.fail("Calling getNumStatementRetries with a null object should throw an exception");
+    } catch (NullPointerException e) {
+      // Pass
+    }
+
+    Properties props = new Properties();
+
+    // Verify the default value
+    Assert.assertEquals(Long.valueOf(AvaticaConnection.NUM_EXECUTE_RETRIES_DEFAULT).longValue(),
+        statement.getNumStatementRetries(props));
+
+    // Set a non-default value
+    props.setProperty(AvaticaConnection.NUM_EXECUTE_RETRIES_KEY, "10");
+
+    // Verify that we observe that value
+    Assert.assertEquals(10, statement.getNumStatementRetries(props));
+  }
+
+}
+
+// End AvaticaConnectionTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/FrameTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
new file mode 100644
index 0000000..bdd989b
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.Meta.Frame;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Common.ColumnValue;
+import org.apache.calcite.avatica.proto.Common.TypedValue;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests serialization of {@link Frame}.
+ */
+public class FrameTest {
+
+  private static final TypedValue NUMBER_VALUE = TypedValue.newBuilder().setNumberValue(1)
+      .setType(Common.Rep.LONG).build();
+
+  private void serializeAndTestEquality(Frame frame) {
+    Frame frameCopy = Frame.fromProto(frame.toProto());
+
+    assertEquals(frame.done, frameCopy.done);
+    assertEquals(frame.offset, frameCopy.offset);
+
+    Iterable<Object> origRows = frame.rows;
+    Iterable<Object> copiedRows = frameCopy.rows;
+
+    assertEquals("Expected rows to both be null, or both be non-null",
+        origRows == null, copiedRows == null);
+
+    Iterator<Object> origIter = origRows.iterator();
+    Iterator<Object> copiedIter = copiedRows.iterator();
+    while (origIter.hasNext() && copiedIter.hasNext()) {
+      Object orig = origIter.next();
+      Object copy = copiedIter.next();
+
+      assertEquals(orig == null, copy == null);
+
+      // This is goofy, but it seems like an Array comes from the JDBC implementation but then
+      // the resulting Frame has a List to support the Avatica typed Accessors
+      assertEquals(Object[].class, orig.getClass());
+      assertTrue("Expected List but got " + copy.getClass(), copy instanceof List);
+
+      @SuppressWarnings("unchecked")
+      List<Object> copyList = (List<Object>) copy;
+
+      assertArrayEquals((Object[]) orig, copyList.toArray(new Object[0]));
+    }
+
+    assertEquals(origIter.hasNext(), copiedIter.hasNext());
+  }
+
+  @Test
+  public void testEmpty() {
+    serializeAndTestEquality(Frame.EMPTY);
+  }
+
+  @Test
+  public void testSingleRow() {
+    ArrayList<Object> rows = new ArrayList<>();
+    rows.add(new Object[] {"string", Integer.MAX_VALUE, new Date().getTime()});
+
+    Frame singleRow = new Frame(0, true, rows);
+
+    serializeAndTestEquality(singleRow);
+  }
+
+  @Test
+  public void testMultipleRows() {
+    ArrayList<Object> rows = new ArrayList<>();
+    rows.add(new Object[] {"string", Integer.MAX_VALUE, new Date().getTime()});
+    rows.add(new Object[] {"gnirts", 0, Long.MIN_VALUE});
+    rows.add(new Object[] {"", null, Long.MAX_VALUE});
+
+    Frame singleRow = new Frame(0, true, rows);
+
+    serializeAndTestEquality(singleRow);
+  }
+
+  @Test public void testMalformedColumnValue() {
+    // Invalid ColumnValue: has an array and scalar
+    final ColumnValue bothAttributesColumnValue = ColumnValue.newBuilder().setHasArrayValue(true)
+        .setScalarValue(NUMBER_VALUE).build();
+    // Note omission of setScalarValue(TypedValue).
+    final ColumnValue neitherAttributeColumnValue = ColumnValue.newBuilder().setHasArrayValue(false)
+        .build();
+
+    try {
+      Frame.validateColumnValue(bothAttributesColumnValue);
+      fail("Validating the ColumnValue should have failed as it has an array and scalar");
+    } catch (IllegalArgumentException e) {
+      // Pass
+    }
+
+    try {
+      Frame.validateColumnValue(neitherAttributeColumnValue);
+      fail("Validating the ColumnValue should have failed as it has neither an array nor scalar");
+    } catch (IllegalArgumentException e) {
+      // Pass
+    }
+  }
+
+  @Test public void testColumnValueBackwardsCompatibility() {
+    // 1
+    final ColumnValue oldStyleScalarValue = ColumnValue.newBuilder().addValue(NUMBER_VALUE).build();
+    // [1, 1]
+    final ColumnValue oldStyleArrayValue = ColumnValue.newBuilder().addValue(NUMBER_VALUE)
+        .addValue(NUMBER_VALUE).build();
+
+    assertFalse(Frame.isNewStyleColumn(oldStyleScalarValue));
+    assertFalse(Frame.isNewStyleColumn(oldStyleArrayValue));
+
+    Object scalar = Frame.parseOldStyleColumn(oldStyleScalarValue);
+    assertEquals(1L, scalar);
+
+    Object array = Frame.parseOldStyleColumn(oldStyleArrayValue);
+    assertEquals(Arrays.asList(1L, 1L), array);
+  }
+
+  @Test public void testColumnValueParsing() {
+    // 1
+    final ColumnValue scalarValue = ColumnValue.newBuilder().setScalarValue(NUMBER_VALUE).build();
+    // [1, 1]
+    final ColumnValue arrayValue = ColumnValue.newBuilder().addArrayValue(NUMBER_VALUE)
+        .addArrayValue(NUMBER_VALUE).setHasArrayValue(true).build();
+
+    assertTrue(Frame.isNewStyleColumn(scalarValue));
+    assertTrue(Frame.isNewStyleColumn(arrayValue));
+
+    Object scalar = Frame.parseColumn(scalarValue);
+    assertEquals(1L, scalar);
+
+    Object array = Frame.parseColumn(arrayValue);
+    assertEquals(Arrays.asList(1L, 1L), array);
+  }
+}
+
+// End FrameTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/QueryStateTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/QueryStateTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/QueryStateTest.java
new file mode 100644
index 0000000..d97bfa2
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/QueryStateTest.java
@@ -0,0 +1,513 @@
+/*
+ * 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.remote.MetaDataOperation;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests that {@link QueryState} properly retains the necessary state to recreate
+ * a {@link ResultSet}.
+ */
+public class QueryStateTest {
+
+  private Connection conn;
+  private DatabaseMetaData metadata;
+  private Statement statement;
+
+
+  @Before
+  public void setup() throws Exception {
+    conn = Mockito.mock(Connection.class);
+    metadata = Mockito.mock(DatabaseMetaData.class);
+    statement = Mockito.mock(Statement.class);
+
+    Mockito.when(conn.getMetaData()).thenReturn(metadata);
+  }
+
+  @Test
+  public void testMetadataGetAttributes() throws Exception {
+    final String catalog = "catalog";
+    final String schemaPattern = null;
+    final String typeNamePattern = "%";
+    final String attributeNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_ATTRIBUTES, catalog, schemaPattern,
+        typeNamePattern, attributeNamePattern);
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getAttributes(catalog, schemaPattern, typeNamePattern,
+        attributeNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetBestRowIdentifier() throws Exception {
+    final String catalog = "catalog";
+    final String schema = null;
+    final String table = "table";
+    final int scope = 1;
+    final boolean nullable = true;
+
+    QueryState state = new QueryState(MetaDataOperation.GET_BEST_ROW_IDENTIFIER, new Object[] {
+      catalog,
+      schema,
+      table,
+      scope,
+      nullable
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getBestRowIdentifier(catalog, schema, table, scope, nullable);
+  }
+
+  @Test
+  public void testMetadataGetCatalogs() throws Exception {
+    QueryState state = new QueryState(MetaDataOperation.GET_CATALOGS, new Object[0]);
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getCatalogs();
+  }
+
+  @Test
+  public void testMetadataGetColumnPrivileges() throws Exception {
+    final String catalog = null;
+    final String schema = "schema";
+    final String table = "table";
+    final String columnNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_COLUMN_PRIVILEGES, new Object[] {
+      catalog,
+      schema,
+      table,
+      columnNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getColumnPrivileges(catalog, schema, table, columnNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetColumns() throws Exception {
+    final String catalog = null;
+    final String schemaPattern = "%";
+    final String tableNamePattern = "%";
+    final String columnNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_COLUMNS, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern,
+      columnNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getColumns(catalog, schemaPattern, tableNamePattern,
+        columnNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetCrossReference() throws Exception {
+    final String parentCatalog = null;
+    final String parentSchema = null;
+    final String parentTable = "%";
+    final String foreignCatalog = null;
+    final String foreignSchema = null;
+    final String foreignTable = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_CROSS_REFERENCE, new Object[] {
+      parentCatalog,
+      parentSchema,
+      parentTable,
+      foreignCatalog,
+      foreignSchema,
+      foreignTable
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getCrossReference(parentCatalog, parentSchema, parentTable,
+        foreignCatalog, foreignSchema, foreignTable);
+  }
+
+  @Test
+  public void testMetadataGetExportedKeys() throws Exception {
+    final String catalog = "";
+    final String schema = null;
+    final String table = "mytable";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_EXPORTED_KEYS, new Object[] {
+      catalog,
+      schema,
+      table
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getExportedKeys(catalog, schema, table);
+  }
+
+  @Test
+  public void testMetadataGetFunctionColumns() throws Exception {
+    final String catalog = null;
+    final String schemaPattern = "%";
+    final String functionNamePattern = "%";
+    final String columnNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_FUNCTION_COLUMNS, new Object[] {
+      catalog,
+      schemaPattern,
+      functionNamePattern,
+      columnNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getFunctionColumns(catalog, schemaPattern, functionNamePattern,
+        columnNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetFunctions() throws Exception {
+    final String catalog = null;
+    final String schemaPattern = "%";
+    final String functionNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_FUNCTIONS, new Object[] {
+      catalog,
+      schemaPattern,
+      functionNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getFunctions(catalog, schemaPattern, functionNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetImportedKeys() throws Exception {
+    final String catalog = "";
+    final String schema = null;
+    final String table = "my_table";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_IMPORTED_KEYS, new Object[] {
+      catalog,
+      schema,
+      table
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getImportedKeys(catalog, schema, table);
+  }
+
+  @Test
+  public void testMetadataGetIndexInfo() throws Exception {
+    final String catalog = "";
+    final String schema = null;
+    final String table = "my_table";
+    final boolean unique = true;
+    final boolean approximate = true;
+
+    QueryState state = new QueryState(MetaDataOperation.GET_INDEX_INFO, new Object[] {
+      catalog,
+      schema,
+      table,
+      unique,
+      approximate
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getIndexInfo(catalog, schema, table, unique, approximate);
+  }
+
+  @Test
+  public void testMetadataGetPrimaryKeys() throws Exception {
+    final String catalog = "";
+    final String schema = null;
+    final String table = "my_table";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_PRIMARY_KEYS, new Object[] {
+      catalog,
+      schema,
+      table
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getPrimaryKeys(catalog, schema, table);
+  }
+
+  @Test
+  public void testMetadataGetProcedureColumns() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String procedureNamePattern = "%";
+    final String columnNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_PROCEDURE_COLUMNS, new Object[] {
+      catalog,
+      schemaPattern,
+      procedureNamePattern,
+      columnNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getProcedureColumns(catalog, schemaPattern, procedureNamePattern,
+        columnNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetProcedures() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String procedureNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_PROCEDURES, new Object[] {
+      catalog,
+      schemaPattern,
+      procedureNamePattern,
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getProcedures(catalog, schemaPattern, procedureNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetPseudoColumns() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String tableNamePattern = "%";
+    final String columnNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_PSEUDO_COLUMNS, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern,
+      columnNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getPseudoColumns(catalog, schemaPattern, tableNamePattern,
+        columnNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetSchemas() throws Exception {
+    QueryState state = new QueryState(MetaDataOperation.GET_SCHEMAS, new Object[0]);
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getSchemas();
+  }
+
+  @Test
+  public void testMetadataGetSchemasWithArgs() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+
+    QueryState state = new QueryState(MetaDataOperation.GET_SCHEMAS_WITH_ARGS, new Object[] {
+      catalog,
+      schemaPattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getSchemas(catalog, schemaPattern);
+  }
+
+  @Test
+  public void testMetadataGetSuperTables() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String tableNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_SUPER_TABLES, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getSuperTables(catalog, schemaPattern, tableNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetSuperTypes() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String tableNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_SUPER_TYPES, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getSuperTypes(catalog, schemaPattern, tableNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetTablePrivileges() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String tableNamePattern = "%";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_TABLE_PRIVILEGES, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getTablePrivileges(catalog, schemaPattern, tableNamePattern);
+  }
+
+  @Test
+  public void testMetadataGetTables() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String tableNamePattern = "%";
+    final String[] types = new String[] {"VIEW", "TABLE"};
+
+    QueryState state = new QueryState(MetaDataOperation.GET_TABLES, new Object[] {
+      catalog,
+      schemaPattern,
+      tableNamePattern,
+      types
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getTables(catalog, schemaPattern, tableNamePattern, types);
+  }
+
+  @Test
+  public void testMetadataGetTableTypes() throws Exception {
+    QueryState state = new QueryState(MetaDataOperation.GET_TABLE_TYPES, new Object[0]);
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getTableTypes();
+  }
+
+  @Test
+  public void testMetadataGetTypeInfo() throws Exception {
+    QueryState state = new QueryState(MetaDataOperation.GET_TYPE_INFO, new Object[0]);
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getTypeInfo();
+  }
+
+  @Test
+  public void testMetadataGetUDTs() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String typeNamePattern = "%";
+    final int[] types = new int[] {1, 2};
+
+    QueryState state = new QueryState(MetaDataOperation.GET_UDTS, new Object[] {
+      catalog,
+      schemaPattern,
+      typeNamePattern,
+      types
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getUDTs(catalog, schemaPattern, typeNamePattern, types);
+  }
+
+  @Test
+  public void testMetadataGetVersionColumns() throws Exception {
+    final String catalog = "";
+    final String schemaPattern = null;
+    final String table = "my_table";
+
+    QueryState state = new QueryState(MetaDataOperation.GET_VERSION_COLUMNS, new Object[] {
+      catalog,
+      schemaPattern,
+      table
+    });
+
+    state.invoke(conn, statement);
+
+    Mockito.verify(metadata).getVersionColumns(catalog, schemaPattern, table);
+  }
+
+  @Test
+  public void testSerialization() throws Exception {
+    final String catalog = "catalog";
+    final String schema = null;
+    final String table = "table";
+    final int scope = 1;
+    final boolean nullable = true;
+
+    QueryState state = new QueryState(MetaDataOperation.GET_BEST_ROW_IDENTIFIER, new Object[] {
+      catalog,
+      schema,
+      table,
+      scope,
+      nullable
+    });
+
+    assertEquals(state, QueryState.fromProto(state.toProto()));
+
+    final String schemaPattern = null;
+    final String typeNamePattern = "%";
+    final int[] types = new int[] {1, 2};
+
+    state = new QueryState(MetaDataOperation.GET_UDTS, new Object[] {
+      catalog,
+      schemaPattern,
+      typeNamePattern,
+      types
+    });
+
+    assertEquals(state, QueryState.fromProto(state.toProto()));
+
+    state = new QueryState("SELECT * FROM foo");
+
+    assertEquals(state, QueryState.fromProto(state.toProto()));
+  }
+
+}
+
+// End QueryStateTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/metrics/MetricsHelperTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/metrics/MetricsHelperTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/metrics/MetricsHelperTest.java
new file mode 100644
index 0000000..c85312d
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/metrics/MetricsHelperTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics;
+
+import org.apache.calcite.avatica.remote.MetricsHelper;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link MetricsHelper}.
+ */
+public class MetricsHelperTest {
+
+  @Test(expected = NullPointerException.class) public void testNullConcat() {
+    MetricsHelper.concat(null, "foo");
+  }
+
+  @Test public void testConcat() {
+    String suffix = "suffix";
+    String finalName = getClass().getName() + "." + suffix;
+    assertEquals(finalName, MetricsHelper.concat(getClass(), suffix));
+  }
+
+}
+
+// End MetricsHelperTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AbstractHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AbstractHandlerTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AbstractHandlerTest.java
new file mode 100644
index 0000000..012cccc
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AbstractHandlerTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Objects;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for common functionality across {@link Handler} implementations.
+ */
+public class AbstractHandlerTest {
+
+  private String exceptionToString(Exception e) {
+    StringWriter sw = new StringWriter();
+    PrintWriter pw = new PrintWriter(sw);
+    Objects.requireNonNull(e).printStackTrace(pw);
+    return sw.toString();
+  }
+
+  @Test public void testExceptionUnwrappingWithoutContext() {
+    @SuppressWarnings("unchecked")
+    AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
+
+    Mockito.when(handler.unwrapException(Mockito.any(Exception.class))).thenCallRealMethod();
+
+    Exception e = new RuntimeException();
+    Response resp = handler.unwrapException(e);
+    assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
+        resp instanceof ErrorResponse);
+    ErrorResponse errorResp = (ErrorResponse) resp;
+    assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
+    assertEquals(AvaticaSeverity.UNKNOWN, errorResp.severity);
+    assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
+
+    e = new AvaticaRuntimeException();
+    resp = handler.unwrapException(e);
+    assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
+        resp instanceof ErrorResponse);
+    errorResp = (ErrorResponse) resp;
+    assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
+    assertEquals(AvaticaSeverity.UNKNOWN, errorResp.severity);
+    assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
+  }
+
+  @Test public void testExceptionUnwrappingWithContext() {
+    @SuppressWarnings("unchecked")
+    AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
+
+    Mockito.when(handler.unwrapException(Mockito.any(Exception.class))).thenCallRealMethod();
+
+    final String msg = "Something failed!";
+    AvaticaRuntimeException e = new AvaticaRuntimeException(msg,
+        ErrorResponse.UNKNOWN_ERROR_CODE, ErrorResponse.UNKNOWN_SQL_STATE, AvaticaSeverity.FATAL);
+    Response resp = handler.unwrapException(e);
+    assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
+        resp instanceof ErrorResponse);
+    ErrorResponse errorResp = (ErrorResponse) resp;
+    assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
+    assertEquals(AvaticaSeverity.FATAL, errorResp.severity);
+    assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
+    assertEquals(msg, errorResp.errorMessage);
+  }
+
+  @Test public void testFailedResponseSerialization() throws IOException {
+    @SuppressWarnings("unchecked")
+    final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
+    final Request request = Mockito.mock(Request.class);
+    final Response response = Mockito.mock(Response.class);
+    final IOException exception = new IOException();
+    final ErrorResponse errorResponse = Mockito.mock(ErrorResponse.class);
+    final String serializedErrorResponse = "An ErrorResponse";
+
+    // Accept a serialized request
+    Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
+    // Deserialize it back into a POJO
+    Mockito.when(handler.decode(Mockito.anyString())).thenReturn(request);
+    // Construct the Response for that Request
+    Mockito.when(request.accept(Mockito.any(Service.class))).thenReturn(response);
+    // Throw an IOException when serializing the Response.
+    Mockito.when(handler.encode(response)).thenThrow(exception);
+    // Convert the IOException into an ErrorResponse
+    Mockito.when(handler.unwrapException(exception)).thenReturn(errorResponse);
+    Mockito.when(handler.encode(errorResponse)).thenReturn(serializedErrorResponse);
+
+    HandlerResponse<String> handlerResp = handler.apply("this is mocked out");
+    assertEquals(500, handlerResp.getStatusCode());
+    assertEquals(serializedErrorResponse, handlerResp.getResponse());
+  }
+
+  @Test public void testFailedErrorResponseSerialization() throws IOException {
+    @SuppressWarnings("unchecked")
+    final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
+    final Request request = Mockito.mock(Request.class);
+    final Response response = Mockito.mock(Response.class);
+    final IOException exception = new IOException();
+    final ErrorResponse errorResponse = Mockito.mock(ErrorResponse.class);
+
+    // Accept a serialized request
+    Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
+    // Deserialize it back into a POJO
+    Mockito.when(handler.decode(Mockito.anyString())).thenReturn(request);
+    // Construct the Response for that Request
+    Mockito.when(request.accept(Mockito.any(Service.class))).thenReturn(response);
+    // Throw an IOException when serializing the Response.
+    Mockito.when(handler.encode(response)).thenThrow(exception);
+    // Convert the IOException into an ErrorResponse
+    Mockito.when(handler.unwrapException(exception)).thenReturn(errorResponse);
+    // Fail to serialize the ErrorResponse
+    Mockito.when(handler.encode(errorResponse)).thenThrow(exception);
+
+    try {
+      handler.apply("this is mocked out");
+    } catch (RuntimeException e) {
+      assertEquals(exception, e.getCause());
+    }
+  }
+
+  @Test public void testFailedRequestDeserialization() throws IOException {
+    @SuppressWarnings("unchecked")
+    final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
+    final IOException exception = new IOException();
+
+    // Accept a serialized request
+    Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
+    // Throw an Exception trying to convert it back into a POJO
+    Mockito.when(handler.decode(Mockito.anyString())).thenThrow(exception);
+
+    try {
+      handler.apply("this is mocked out");
+    } catch (RuntimeException e) {
+      assertEquals(exception, e.getCause());
+    }
+  }
+}
+
+// End AbstractHandlerTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryTest.java
new file mode 100644
index 0000000..cd64329
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.BuiltInConnectionProperty;
+import org.apache.calcite.avatica.ConnectionConfig;
+import org.apache.calcite.avatica.ConnectionConfigImpl;
+
+import org.junit.Test;
+
+import java.net.URL;
+import java.util.Properties;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the factory that creates http clients.
+ */
+public class AvaticaHttpClientFactoryTest {
+
+  @Test public void testDefaultHttpClient() throws Exception {
+    Properties props = new Properties();
+    URL url = new URL("http://localhost:8765");
+    ConnectionConfig config = new ConnectionConfigImpl(props);
+    AvaticaHttpClientFactory httpClientFactory = new AvaticaHttpClientFactoryImpl();
+
+    AvaticaHttpClient client = httpClientFactory.getClient(url, config);
+    assertTrue("Client was an instance of " + client.getClass(),
+        client instanceof AvaticaCommonsHttpClientImpl);
+  }
+
+  @Test public void testOverridenHttpClient() throws Exception {
+    Properties props = new Properties();
+    props.setProperty(BuiltInConnectionProperty.HTTP_CLIENT_IMPL.name(),
+        AvaticaHttpClientImpl.class.getName());
+    URL url = new URL("http://localhost:8765");
+    ConnectionConfig config = new ConnectionConfigImpl(props);
+    AvaticaHttpClientFactory httpClientFactory = new AvaticaHttpClientFactoryImpl();
+
+    AvaticaHttpClient client = httpClientFactory.getClient(url, config);
+    assertTrue("Client was an instance of " + client.getClass(),
+        client instanceof AvaticaHttpClientImpl);
+  }
+}
+
+// End AvaticaHttpClientFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientTest.java
new file mode 100644
index 0000000..33369d2
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/AvaticaHttpClientTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.remote;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * Tests for the HTTP transport.
+ */
+public class AvaticaHttpClientTest {
+  private static final String REQUEST =
+      "{\"request\":\"createStatement\",\"connectionId\":\"8f3f28ee-d0bb-4cdb-a4b1-8f6e8476c534\"}";
+  private static final String RESPONSE =
+      "{\"response\":\"createStatement\",\"connectionId\":"
+          + "\"8f3f28ee-d0bb-4cdb-a4b1-8f6e8476c534\",\"statementId\":1608176856}";
+
+  @Test
+  public void testRetryOnUnavailable() throws Exception {
+    // HTTP-503, try again
+    URL url = new URL("http://127.0.0.1:8765");
+    final HttpURLConnection cnxn = Mockito.mock(HttpURLConnection.class);
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ByteArrayInputStream bais = new ByteArrayInputStream(RESPONSE.getBytes(StandardCharsets.UTF_8));
+
+    // Create the HTTP client
+    AvaticaHttpClientImpl client = new AvaticaHttpClientImpl(url) {
+      @Override HttpURLConnection openConnection() throws IOException {
+        return cnxn;
+      }
+    };
+
+    // HTTP 503 then 200
+    Mockito.when(cnxn.getResponseCode()).thenReturn(HttpURLConnection.HTTP_UNAVAILABLE,
+        HttpURLConnection.HTTP_OK);
+
+    Mockito.when(cnxn.getOutputStream()).thenReturn(baos);
+    Mockito.when(cnxn.getInputStream()).thenReturn(bais);
+
+    byte[] response = client.send(REQUEST.getBytes(StandardCharsets.UTF_8));
+
+    assertArrayEquals(RESPONSE.getBytes(StandardCharsets.UTF_8), response);
+  }
+
+  @Test(expected = RuntimeException.class)
+  public void testServerError() throws Exception {
+    // HTTP 500 should error out
+    URL url = new URL("http://127.0.0.1:8765");
+    final HttpURLConnection cnxn = Mockito.mock(HttpURLConnection.class);
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+    // Create the HTTP client
+    AvaticaHttpClientImpl client = new AvaticaHttpClientImpl(url) {
+      @Override HttpURLConnection openConnection() throws IOException {
+        return cnxn;
+      }
+    };
+
+    // HTTP 500
+    Mockito.when(cnxn.getResponseCode()).thenReturn(HttpURLConnection.HTTP_INTERNAL_ERROR);
+
+    Mockito.when(cnxn.getOutputStream()).thenReturn(baos);
+
+    // Should throw an RTE
+    client.send(REQUEST.getBytes(StandardCharsets.UTF_8));
+  }
+
+}
+
+// End AvaticaHttpClientTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ErrorResponseTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ErrorResponseTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ErrorResponseTest.java
new file mode 100644
index 0000000..f66cb26
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ErrorResponseTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaClientRuntimeException;
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * A test class for ErrorResponse.
+ */
+public class ErrorResponseTest {
+
+  @Test public void testEquality() {
+    final String message = "There was an error";
+    final int code = 23;
+    final String state = "a1b2c";
+    final AvaticaSeverity severity = AvaticaSeverity.ERROR;
+    final List<String> exceptions = Arrays.asList("Server Stacktrace 1", "Server Stacktace 2");
+    final RpcMetadataResponse metadata = new RpcMetadataResponse("localhost:8765");
+    assertEquals(new ErrorResponse(message, code, state, severity, exceptions, metadata),
+        new ErrorResponse(message, code, state, severity, exceptions, metadata));
+  }
+
+  @Test public void testToClientRTE() {
+    final String message = "There was an error";
+    final int code = 23;
+    final String state = "a1b2c";
+    final AvaticaSeverity severity = AvaticaSeverity.ERROR;
+    final List<String> exceptions = Arrays.asList("Server Stacktrace 1", "Server Stacktace 2");
+    final RpcMetadataResponse metadata = new RpcMetadataResponse("localhost:8765");
+    final ErrorResponse resp = new ErrorResponse(message, code, state, severity, exceptions,
+        metadata);
+    AvaticaClientRuntimeException exception = resp.toException();
+    assertTrue("Expected error message to end with '" + resp.errorMessage + "', but was '"
+        + exception.getMessage() + "'", exception.getMessage().endsWith(resp.errorMessage));
+    assertEquals(resp.errorCode, exception.getErrorCode());
+    assertEquals(resp.severity, exception.getSeverity());
+    assertEquals(resp.sqlState, exception.getSqlState());
+    assertEquals(resp.exceptions, exception.getServerExceptions());
+    assertEquals(resp.rpcMetadata, exception.getRpcMetadata());
+  }
+}
+
+// End ErrorResponseTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/MetaDataOperationTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/MetaDataOperationTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/MetaDataOperationTest.java
new file mode 100644
index 0000000..c64b32c
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/MetaDataOperationTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.remote;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link MetaDataOperation}
+ */
+public class MetaDataOperationTest {
+
+  @Test
+  public void testProtobufSerialization() {
+    for (MetaDataOperation metadataOp : MetaDataOperation.values()) {
+      assertEquals(metadataOp, MetaDataOperation.fromProto(metadataOp.toProto()));
+    }
+  }
+
+}
+
+// End MetaDataOperationTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
new file mode 100644
index 0000000..afb15c3
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.Meta.Frame;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Common.ColumnValue;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.proto.Responses;
+import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
+import org.apache.calcite.avatica.remote.Service.FetchRequest;
+import org.apache.calcite.avatica.remote.Service.FetchResponse;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test basic serialization of objects with protocol buffers.
+ */
+public class ProtobufHandlerTest {
+
+  // Mocks
+  private Service service;
+  private ProtobufTranslation translation;
+
+  // Real objects
+  private ProtobufHandler handler;
+
+  @Before
+  public void setupMocks() {
+    // Mocks
+    service = Mockito.mock(Service.class);
+    translation = Mockito.mock(ProtobufTranslation.class);
+
+    // Real objects
+    handler = new ProtobufHandler(service, translation, NoopMetricsSystem.getInstance());
+  }
+
+  @Test
+  public void testFetch() throws Exception {
+    final String connectionId = "cnxn1";
+    final int statementId = 30;
+    final long offset = 10;
+    final int fetchMaxRowCount = 100;
+    final List<Common.TypedValue> values = new ArrayList<>();
+
+    values.add(Common.TypedValue.newBuilder().setType(Common.Rep.BOOLEAN).setBoolValue(true)
+        .build());
+    values.add(Common.TypedValue.newBuilder().setType(Common.Rep.STRING)
+        .setStringValue("my_string").build());
+
+    Requests.FetchRequest protoRequest = Requests.FetchRequest.newBuilder()
+        .setConnectionId(connectionId).setStatementId(statementId)
+        .setOffset(offset).setFetchMaxRowCount(fetchMaxRowCount)
+        .build();
+    byte[] serializedRequest = protoRequest.toByteArray();
+
+    FetchRequest request = new FetchRequest().deserialize(protoRequest);
+
+    List<Object> frameRows = new ArrayList<>();
+    frameRows.add(new Object[] {true, "my_string"});
+
+    Meta.Frame frame = Frame.create(0, true, frameRows);
+    RpcMetadataResponse metadata = new RpcMetadataResponse("localhost:8765");
+    FetchResponse response = new FetchResponse(frame, false, false, metadata);
+
+    when(translation.parseRequest(serializedRequest)).thenReturn(request);
+    when(service.apply(request)).thenReturn(response);
+    when(translation.serializeResponse(response))
+        .thenReturn(response.serialize().toByteArray());
+
+    HandlerResponse<byte[]> handlerResponse = handler.apply(serializedRequest);
+    byte[] serializedResponse = handlerResponse.getResponse();
+    assertEquals(200, handlerResponse.getStatusCode());
+
+    Responses.FetchResponse protoResponse = Responses.FetchResponse.parseFrom(serializedResponse);
+
+    Common.Frame protoFrame = protoResponse.getFrame();
+
+    assertEquals(frame.offset, protoFrame.getOffset());
+    assertEquals(frame.done, protoFrame.getDone());
+
+    List<Common.Row> rows = protoFrame.getRowsList();
+    assertEquals(1, rows.size());
+    Common.Row row = rows.get(0);
+    List<Common.ColumnValue> columnValues = row.getValueList();
+    assertEquals(2, columnValues.size());
+
+    Iterator<Common.ColumnValue> iter = columnValues.iterator();
+    assertTrue(iter.hasNext());
+    Common.ColumnValue column = iter.next();
+    assertTrue("The Column should have contained a scalar: " + column,
+        column.hasField(ColumnValue.getDescriptor()
+            .findFieldByNumber(ColumnValue.SCALAR_VALUE_FIELD_NUMBER)));
+
+    Common.TypedValue value = column.getScalarValue();
+    assertEquals(Common.Rep.BOOLEAN, value.getType());
+    assertEquals(true, value.getBoolValue());
+
+    assertTrue(iter.hasNext());
+    column = iter.next();
+    assertTrue("The Column should have contained a scalar: " + column,
+        column.hasField(ColumnValue.getDescriptor()
+            .findFieldByNumber(ColumnValue.SCALAR_VALUE_FIELD_NUMBER)));
+    value = column.getScalarValue();
+    assertEquals(Common.Rep.STRING, value.getType());
+    assertEquals("my_string", value.getStringValue());
+  }
+
+}
+
+// End ProtobufHandlerTest.java


[43/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
new file mode 100644
index 0000000..a999f19
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
@@ -0,0 +1,329 @@
+/*
+ * 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.util.UnsynchronizedBuffer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Field;
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.AbstractList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** Avatica utilities. */
+public class AvaticaUtils {
+  private static final Map<Class, Class> BOX;
+
+  private static final MethodHandle SET_LARGE_MAX_ROWS =
+      method(void.class, Statement.class, "setLargeMaxRows", long.class);
+  private static final MethodHandle GET_LARGE_MAX_ROWS =
+      method(long.class, Statement.class, "getLargeMaxRows");
+  private static final MethodHandle GET_LARGE_UPDATE_COUNT =
+      method(void.class, Statement.class, "getLargeUpdateCount");
+
+  private static final Set<String> UNIQUE_STRINGS = new HashSet<>();
+
+  private static final ThreadLocal<byte[]> PER_THREAD_BUFFER  = new ThreadLocal<byte[]>() {
+    @Override protected byte[] initialValue() {
+      return new byte[4096];
+    }
+  };
+
+  private AvaticaUtils() {}
+
+  static {
+    BOX = new HashMap<>();
+    BOX.put(boolean.class, Boolean.class);
+    BOX.put(byte.class, Byte.class);
+    BOX.put(char.class, Character.class);
+    BOX.put(short.class, Short.class);
+    BOX.put(int.class, Integer.class);
+    BOX.put(long.class, Long.class);
+    BOX.put(float.class, Float.class);
+    BOX.put(double.class, Double.class);
+  }
+
+  private static MethodHandle method(Class returnType, Class targetType,
+      String name, Class... argTypes) {
+    final MethodHandles.Lookup lookup = MethodHandles.lookup();
+    try {
+      return lookup.findVirtual(targetType, name,
+          MethodType.methodType(returnType, targetType, argTypes));
+    } catch (NoSuchMethodException e) {
+      return null;
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+   * Does nothing with its argument. Call this method when you have a value
+   * you are not interested in, but you don't want the compiler to warn that
+   * you are not using it.
+   */
+  public static void discard(Object o) {
+    if (false) {
+      discard(o);
+    }
+  }
+
+  /**
+   * Adapts a primitive array into a {@link List}. For example,
+   * {@code asList(new double[2])} returns a {@code List&lt;Double&gt;}.
+   */
+  public static List<?> primitiveList(final Object array) {
+    // REVIEW: A per-type list might be more efficient. (Or might not.)
+    return new AbstractList() {
+      public Object get(int index) {
+        return java.lang.reflect.Array.get(array, index);
+      }
+
+      public int size() {
+        return java.lang.reflect.Array.getLength(array);
+      }
+    };
+  }
+
+  /**
+   * Converts a camelCase name into an upper-case underscore-separated name.
+   * For example, {@code camelToUpper("myJdbcDriver")} returns
+   * "MY_JDBC_DRIVER".
+   */
+  public static String camelToUpper(String name) {
+    StringBuilder buf = new StringBuilder();
+    for (int i = 0; i < name.length(); i++) {
+      char c = name.charAt(i);
+      if (Character.isUpperCase(c)) {
+        buf.append('_');
+      } else {
+        c = Character.toUpperCase(c);
+      }
+      buf.append(c);
+    }
+    return buf.toString();
+  }
+
+  /**
+   * Converts an underscore-separated name into a camelCase name.
+   * For example, {@code uncamel("MY_JDBC_DRIVER")} returns "myJdbcDriver".
+   */
+  public static String toCamelCase(String name) {
+    StringBuilder buf = new StringBuilder();
+    int nextUpper = -1;
+    for (int i = 0; i < name.length(); i++) {
+      char c = name.charAt(i);
+      if (c == '_') {
+        nextUpper = i + 1;
+        continue;
+      }
+      if (nextUpper == i) {
+        c = Character.toUpperCase(c);
+      } else {
+        c = Character.toLowerCase(c);
+      }
+      buf.append(c);
+    }
+    return buf.toString();
+  }
+
+  /** Returns the boxed class. For example, {@code box(int.class)}
+   * returns {@code java.lang.Integer}. */
+  public static Class box(Class clazz) {
+    if (clazz.isPrimitive()) {
+      return BOX.get(clazz);
+    }
+    return clazz;
+  }
+
+  /** Creates an instance of a plugin class. First looks for a static
+   * member called INSTANCE, then calls a public default constructor.
+   *
+   * <p>If className contains a "#" instead looks for a static field.
+   *
+   * @param pluginClass Class (or interface) to instantiate
+   * @param className Name of implementing class
+   * @param <T> Class
+   * @return Plugin instance
+   */
+  public static <T> T instantiatePlugin(Class<T> pluginClass,
+      String className) {
+    try {
+      // Given a static field, say "com.example.MyClass#FOO_INSTANCE", return
+      // the value of that static field.
+      if (className.contains("#")) {
+        try {
+          int i = className.indexOf('#');
+          String left = className.substring(0, i);
+          String right = className.substring(i + 1);
+          //noinspection unchecked
+          final Class<T> clazz = (Class) Class.forName(left);
+          final Field field;
+          field = clazz.getField(right);
+          return pluginClass.cast(field.get(null));
+        } catch (NoSuchFieldException e) {
+          // ignore
+        }
+      }
+      //noinspection unchecked
+      final Class<T> clazz = (Class) Class.forName(className);
+      assert pluginClass.isAssignableFrom(clazz);
+      try {
+        // We assume that if there is an INSTANCE field it is static and
+        // has the right type.
+        final Field field = clazz.getField("INSTANCE");
+        return pluginClass.cast(field.get(null));
+      } catch (NoSuchFieldException e) {
+        // ignore
+      }
+      return clazz.newInstance();
+    } catch (Exception e) {
+      throw new RuntimeException("Property '" + className
+          + "' not valid for plugin type " + pluginClass.getName(), e);
+    }
+  }
+
+  /** Reads the contents of an input stream and returns as a string. */
+  public static String readFully(InputStream inputStream) throws IOException {
+    return readFully(inputStream, new UnsynchronizedBuffer(1024));
+  }
+
+  /** Reads the contents of an input stream and returns as a string. */
+  public static String readFully(InputStream inputStream, UnsynchronizedBuffer buffer)
+      throws IOException {
+    // Variant that lets us use a pooled Buffer
+    final byte[] bytes = _readFully(inputStream, buffer);
+    return new String(bytes, 0, bytes.length, StandardCharsets.UTF_8);
+  }
+
+  /** Reads the contents of an input stream and returns as a string. */
+  public static byte[] readFullyToBytes(InputStream inputStream) throws IOException {
+    return readFullyToBytes(inputStream, new UnsynchronizedBuffer(1024));
+  }
+
+  /** Reads the contents of an input stream and returns as a string. */
+  public static byte[] readFullyToBytes(InputStream inputStream, UnsynchronizedBuffer buffer)
+      throws IOException {
+    // Variant that lets us use a pooled Buffer
+    return _readFully(inputStream, buffer);
+  }
+
+  /**
+   * Reads the contents of an input stream and returns a byte array.
+   *
+   * @param inputStream the input to read from.
+   * @return A byte array whose length is equal to the number of bytes contained.
+   */
+  static byte[] _readFully(InputStream inputStream, UnsynchronizedBuffer buffer)
+      throws IOException {
+    final byte[] bytes = PER_THREAD_BUFFER.get();
+    for (;;) {
+      int count = inputStream.read(bytes, 0, bytes.length);
+      if (count < 0) {
+        break;
+      }
+      buffer.write(bytes, 0, count);
+    }
+    return buffer.toArray();
+  }
+
+  /** Invokes {@code Statement#setLargeMaxRows}, falling back on
+   * {@link Statement#setMaxRows(int)} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static void setLargeMaxRows(Statement statement, long n)
+      throws SQLException {
+    if (SET_LARGE_MAX_ROWS != null) {
+      try {
+        // Call Statement.setLargeMaxRows
+        SET_LARGE_MAX_ROWS.invokeExact(n);
+        return;
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.setMaxRows
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    int i = (int) Math.max(Math.min(n, Integer.MAX_VALUE), Integer.MIN_VALUE);
+    statement.setMaxRows(i);
+  }
+
+  /** Invokes {@code Statement#getLargeMaxRows}, falling back on
+   * {@link Statement#getMaxRows()} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static long getLargeMaxRows(Statement statement) throws SQLException {
+    if (GET_LARGE_MAX_ROWS != null) {
+      try {
+        // Call Statement.getLargeMaxRows
+        return (long) GET_LARGE_MAX_ROWS.invokeExact();
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.getMaxRows
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return statement.getMaxRows();
+  }
+
+  /** Invokes {@code Statement#getLargeUpdateCount}, falling back on
+   * {@link Statement#getUpdateCount()} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static long getLargeUpdateCount(Statement statement)
+      throws SQLException {
+    if (GET_LARGE_UPDATE_COUNT != null) {
+      try {
+        // Call Statement.getLargeUpdateCount
+        return (long) GET_LARGE_UPDATE_COUNT.invokeExact();
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.getUpdateCount
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return statement.getUpdateCount();
+  }
+
+  /** Generates a string that is unique in the execution of the JVM.
+   * It is used by tests to ensure that they create distinct temporary tables.
+   * The strings are never thrown away, so don't put too much in there!
+   * Thread safe. */
+  public static String unique(String base) {
+    synchronized (UNIQUE_STRINGS) {
+      String s = base;
+      while (!UNIQUE_STRINGS.add(s)) {
+        s = base + "_" + UNIQUE_STRINGS.size();
+      }
+      return s;
+    }
+  }
+}
+
+// End AvaticaUtils.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java b/avatica/core/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
new file mode 100644
index 0000000..086ae4a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
@@ -0,0 +1,103 @@
+/*
+ * 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.remote.AvaticaHttpClientFactoryImpl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.apache.calcite.avatica.ConnectionConfigImpl.PropEnv;
+import static org.apache.calcite.avatica.ConnectionConfigImpl.parse;
+
+/**
+ * Enumeration of Avatica's built-in connection properties.
+ */
+public enum BuiltInConnectionProperty implements ConnectionProperty {
+  /** Factory. */
+  FACTORY("factory", Type.PLUGIN, null, false),
+
+  /** Name of initial schema. */
+  SCHEMA("schema", Type.STRING, null, false),
+
+  /** Time zone, for example 'gmt-3'. Default is the JVM's time zone. */
+  TIME_ZONE("timeZone", Type.STRING, null, false),
+
+  /** Remote URL. */
+  URL("url", Type.STRING, null, false),
+
+  /** Serialization used over remote connections */
+  SERIALIZATION("serialization", Type.STRING, "json", false),
+
+  /** Factory for constructing http clients. */
+  HTTP_CLIENT_FACTORY("httpclient_factory", Type.PLUGIN,
+      AvaticaHttpClientFactoryImpl.class.getName(), false),
+
+  /** HttpClient implementation class name. */
+  HTTP_CLIENT_IMPL("httpclient_impl", Type.STRING, null, false);
+
+  private final String camelName;
+  private final Type type;
+  private final Object defaultValue;
+  private final boolean required;
+
+  /** Deprecated; use {@link #TIME_ZONE}. */
+  @Deprecated // to be removed before 2.0
+  public static final BuiltInConnectionProperty TIMEZONE = TIME_ZONE;
+
+  private static final Map<String, BuiltInConnectionProperty> NAME_TO_PROPS;
+
+  static {
+    NAME_TO_PROPS = new HashMap<>();
+    for (BuiltInConnectionProperty p : BuiltInConnectionProperty.values()) {
+      NAME_TO_PROPS.put(p.camelName.toUpperCase(), p);
+      NAME_TO_PROPS.put(p.name(), p);
+    }
+  }
+
+  BuiltInConnectionProperty(String camelName, Type type, Object defaultValue,
+      boolean required) {
+    this.camelName = camelName;
+    this.type = type;
+    this.defaultValue = defaultValue;
+    this.required = required;
+    assert defaultValue == null || type.valid(defaultValue);
+  }
+
+  public String camelName() {
+    return camelName;
+  }
+
+  public Object defaultValue() {
+    return defaultValue;
+  }
+
+  public Type type() {
+    return type;
+  }
+
+  public boolean required() {
+    return required;
+  }
+
+  public PropEnv wrap(Properties properties) {
+    return new PropEnv(parse(properties, NAME_TO_PROPS), this);
+  }
+}
+
+// End BuiltInConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
new file mode 100644
index 0000000..bcdc228
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
@@ -0,0 +1,593 @@
+/*
+ * 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.util.ByteString;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+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.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;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Metadata for a column.
+ *
+ * <p>(Compare with {@link java.sql.ResultSetMetaData}.)
+ */
+public class ColumnMetaData {
+  private static final FieldDescriptor CATALOG_NAME_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.CATALOG_NAME_FIELD_NUMBER);
+  private static final FieldDescriptor SCHEMA_NAME_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.SCHEMA_NAME_FIELD_NUMBER);
+  private static final FieldDescriptor LABEL_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.LABEL_FIELD_NUMBER);
+  private static final FieldDescriptor COLUMN_NAME_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.COLUMN_NAME_FIELD_NUMBER);
+  private static final FieldDescriptor TABLE_NAME_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.TABLE_NAME_FIELD_NUMBER);
+  private static final FieldDescriptor COLUMN_CLASS_NAME_DESCRIPTOR = Common.ColumnMetaData
+      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.COLUMN_CLASS_NAME_FIELD_NUMBER);
+
+  public final int ordinal; // 0-based
+  public final boolean autoIncrement;
+  public final boolean caseSensitive;
+  public final boolean searchable;
+  public final boolean currency;
+  public final int nullable;
+  public final boolean signed;
+  public final int displaySize;
+  public final String label;
+  public final String columnName;
+  public final String schemaName;
+  public final int precision;
+  public final int scale;
+  public final String tableName;
+  public final String catalogName;
+  public final boolean readOnly;
+  public final boolean writable;
+  public final boolean definitelyWritable;
+  public final String columnClassName;
+  public final AvaticaType type;
+
+  @JsonCreator
+  public ColumnMetaData(
+      @JsonProperty("ordinal") int ordinal,
+      @JsonProperty("autoIncrement") boolean autoIncrement,
+      @JsonProperty("caseSensitive") boolean caseSensitive,
+      @JsonProperty("searchable") boolean searchable,
+      @JsonProperty("currency") boolean currency,
+      @JsonProperty("nullable") int nullable,
+      @JsonProperty("signed") boolean signed,
+      @JsonProperty("displaySize") int displaySize,
+      @JsonProperty("label") String label,
+      @JsonProperty("columnName") String columnName,
+      @JsonProperty("schemaName") String schemaName,
+      @JsonProperty("precision") int precision,
+      @JsonProperty("scale") int scale,
+      @JsonProperty("tableName") String tableName,
+      @JsonProperty("catalogName") String catalogName,
+      @JsonProperty("type") AvaticaType type,
+      @JsonProperty("readOnly") boolean readOnly,
+      @JsonProperty("writable") boolean writable,
+      @JsonProperty("definitelyWritable") boolean definitelyWritable,
+      @JsonProperty("columnClassName") String columnClassName) {
+    this.ordinal = ordinal;
+    this.autoIncrement = autoIncrement;
+    this.caseSensitive = caseSensitive;
+    this.searchable = searchable;
+    this.currency = currency;
+    this.nullable = nullable;
+    this.signed = signed;
+    this.displaySize = displaySize;
+    this.label = label;
+    // Per the JDBC spec this should be just columnName.
+    // For example, the query
+    //     select 1 as x, c as y from t
+    // should give columns
+    //     (label=x, column=null, table=null)
+    //     (label=y, column=c table=t)
+    // But DbUnit requires every column to have a name. Duh.
+    this.columnName = first(columnName, label);
+    this.schemaName = schemaName;
+    this.precision = precision;
+    this.scale = scale;
+    this.tableName = tableName;
+    this.catalogName = catalogName;
+    this.type = type;
+    this.readOnly = readOnly;
+    this.writable = writable;
+    this.definitelyWritable = definitelyWritable;
+    this.columnClassName = columnClassName;
+  }
+
+  public Common.ColumnMetaData toProto() {
+    Common.ColumnMetaData.Builder builder = Common.ColumnMetaData.newBuilder();
+
+    // Primitive fields (can't be null)
+    builder.setOrdinal(ordinal)
+      .setAutoIncrement(autoIncrement)
+      .setCaseSensitive(caseSensitive)
+      .setSearchable(searchable)
+      .setCurrency(currency)
+      .setNullable(nullable)
+      .setSigned(signed)
+      .setDisplaySize(displaySize)
+      .setPrecision(precision)
+      .setScale(scale)
+      .setReadOnly(readOnly)
+      .setWritable(writable)
+      .setDefinitelyWritable(definitelyWritable);
+
+    // Potentially null fields
+    if (null != label) {
+      builder.setLabel(label);
+    }
+
+    if (null != columnName) {
+      builder.setColumnName(columnName);
+    }
+
+    if (null != schemaName) {
+      builder.setSchemaName(schemaName);
+    }
+
+    if (null != tableName) {
+      builder.setTableName(tableName);
+    }
+
+    if (null != catalogName) {
+      builder.setCatalogName(catalogName);
+    }
+
+    if (null != type) {
+      builder.setType(type.toProto());
+    }
+
+    if (null != columnClassName) {
+      builder.setColumnClassName(columnClassName);
+    }
+
+    return builder.build();
+  }
+
+  public static ColumnMetaData fromProto(Common.ColumnMetaData proto) {
+    AvaticaType nestedType = AvaticaType.fromProto(proto.getType());
+
+    String catalogName = null;
+    if (proto.hasField(CATALOG_NAME_DESCRIPTOR)) {
+      catalogName = proto.getCatalogName();
+    }
+
+    String schemaName = null;
+    if (proto.hasField(SCHEMA_NAME_DESCRIPTOR)) {
+      schemaName = proto.getSchemaName();
+    }
+
+    String label = null;
+    if (proto.hasField(LABEL_DESCRIPTOR)) {
+      label = proto.getLabel();
+    }
+
+    String columnName = null;
+    if (proto.hasField(COLUMN_NAME_DESCRIPTOR)) {
+      columnName = proto.getColumnName();
+    }
+
+    String tableName = null;
+    if (proto.hasField(TABLE_NAME_DESCRIPTOR)) {
+      tableName = proto.getTableName();
+    }
+
+    String columnClassName = null;
+    if (proto.hasField(COLUMN_CLASS_NAME_DESCRIPTOR)) {
+      columnClassName = proto.getColumnClassName();
+    }
+
+    // Recreate the ColumnMetaData
+    return new ColumnMetaData(proto.getOrdinal(), proto.getAutoIncrement(),
+        proto.getCaseSensitive(), proto.getSearchable(), proto.getCurrency(), proto.getNullable(),
+        proto.getSigned(), proto.getDisplaySize(), label, columnName,
+        schemaName, proto.getPrecision(), proto.getScale(), tableName,
+        catalogName, nestedType, proto.getReadOnly(), proto.getWritable(),
+        proto.getDefinitelyWritable(), columnClassName);
+  }
+
+  @Override public int hashCode() {
+    return Objects.hash(autoIncrement, caseSensitive, catalogName,
+        columnClassName, columnName, currency, definitelyWritable, displaySize,
+        label, nullable, ordinal, precision, readOnly, scale, schemaName,
+        searchable, signed, tableName, type, writable);
+  }
+
+  @Override public boolean equals(Object o) {
+    return o == this
+        || o instanceof ColumnMetaData
+        && autoIncrement == ((ColumnMetaData) o).autoIncrement
+        && caseSensitive == ((ColumnMetaData) o).caseSensitive
+        && Objects.equals(catalogName, ((ColumnMetaData) o).catalogName)
+        && Objects.equals(columnClassName, ((ColumnMetaData) o).columnClassName)
+        && Objects.equals(columnName, ((ColumnMetaData) o).columnName)
+        && currency == ((ColumnMetaData) o).currency
+        && definitelyWritable == ((ColumnMetaData) o).definitelyWritable
+        && displaySize == ((ColumnMetaData) o).displaySize
+        && Objects.equals(label, ((ColumnMetaData) o).label)
+        && nullable == ((ColumnMetaData) o).nullable
+        && ordinal == ((ColumnMetaData) o).ordinal
+        && precision == ((ColumnMetaData) o).precision
+        && readOnly == ((ColumnMetaData) o).readOnly
+        && scale == ((ColumnMetaData) o).scale
+        && Objects.equals(schemaName, ((ColumnMetaData) o).schemaName)
+        && searchable == ((ColumnMetaData) o).searchable
+        && signed == ((ColumnMetaData) o).signed
+        && Objects.equals(tableName, ((ColumnMetaData) o).tableName)
+        && Objects.equals(type, ((ColumnMetaData) o).type)
+        && writable == ((ColumnMetaData) o).writable;
+  }
+
+  private static <T> T first(T t0, T t1) {
+    return t0 != null ? t0 : t1;
+  }
+
+  /** Creates a {@link ScalarType}. */
+  public static ScalarType scalar(int type, String typeName, Rep rep) {
+    return new ScalarType(type, typeName, rep);
+  }
+
+  /** Creates a {@link StructType}. */
+  public static StructType struct(List<ColumnMetaData> columns) {
+    return new StructType(columns);
+  }
+
+  /** Creates an {@link ArrayType}. */
+  public static ArrayType array(AvaticaType componentType, String typeName,
+      Rep rep) {
+    return new ArrayType(Types.ARRAY, typeName, rep, componentType);
+  }
+
+  /** Creates a ColumnMetaData for result sets that are not based on a struct
+   * but need to have a single 'field' for purposes of
+   * {@link java.sql.ResultSetMetaData}. */
+  public static ColumnMetaData dummy(AvaticaType type, boolean nullable) {
+    return new ColumnMetaData(
+        0,
+        false,
+        true,
+        false,
+        false,
+        nullable
+            ? DatabaseMetaData.columnNullable
+            : DatabaseMetaData.columnNoNulls,
+        true,
+        -1,
+        null,
+        null,
+        null,
+        -1,
+        -1,
+        null,
+        null,
+        type,
+        true,
+        false,
+        false,
+        type.columnClassName());
+  }
+
+  public ColumnMetaData setRep(Rep rep) {
+    return new ColumnMetaData(ordinal, autoIncrement, caseSensitive, searchable,
+        currency, nullable, signed, displaySize, label, columnName, schemaName,
+        precision, scale, tableName, catalogName, type.setRep(rep), readOnly,
+        writable, definitelyWritable, columnClassName);
+  }
+
+  /** Description of the type used to internally represent a value. For example,
+   * a {@link java.sql.Date} might be represented as a {@link #PRIMITIVE_INT}
+   * if not nullable, or a {@link #JAVA_SQL_DATE}. */
+  public enum Rep {
+    PRIMITIVE_BOOLEAN(boolean.class),
+    PRIMITIVE_BYTE(byte.class),
+    PRIMITIVE_CHAR(char.class),
+    PRIMITIVE_SHORT(short.class),
+    PRIMITIVE_INT(int.class),
+    PRIMITIVE_LONG(long.class),
+    PRIMITIVE_FLOAT(float.class),
+    PRIMITIVE_DOUBLE(double.class),
+    BOOLEAN(Boolean.class),
+    BYTE(Byte.class),
+    CHARACTER(Character.class),
+    SHORT(Short.class),
+    INTEGER(Integer.class),
+    LONG(Long.class),
+    FLOAT(Float.class),
+    DOUBLE(Double.class),
+    JAVA_SQL_TIME(Time.class),
+    JAVA_SQL_TIMESTAMP(Timestamp.class),
+    JAVA_SQL_DATE(java.sql.Date.class),
+    JAVA_UTIL_DATE(java.util.Date.class),
+    BYTE_STRING(ByteString.class),
+    STRING(String.class),
+
+    /** 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;
+
+    public static final Map<Class, Rep> VALUE_MAP;
+
+    static {
+      Map<Class, Rep> builder = new HashMap<>();
+      for (Rep rep : values()) {
+        builder.put(rep.clazz, rep);
+      }
+      VALUE_MAP = Collections.unmodifiableMap(builder);
+    }
+
+    Rep(Class clazz) {
+      this.clazz = clazz;
+    }
+
+    public static Rep of(Type clazz) {
+      //noinspection SuspiciousMethodCalls
+      final Rep rep = VALUE_MAP.get(clazz);
+      return rep != null ? rep : OBJECT;
+    }
+
+    /** Returns the value of a column of this type from a result set. */
+    public Object jdbcGet(ResultSet resultSet, int i) throws SQLException {
+      switch (this) {
+      case PRIMITIVE_BOOLEAN:
+        return resultSet.getBoolean(i);
+      case PRIMITIVE_BYTE:
+        return resultSet.getByte(i);
+      case PRIMITIVE_SHORT:
+        return resultSet.getShort(i);
+      case PRIMITIVE_INT:
+        return resultSet.getInt(i);
+      case PRIMITIVE_LONG:
+        return resultSet.getLong(i);
+      case PRIMITIVE_FLOAT:
+        return resultSet.getFloat(i);
+      case PRIMITIVE_DOUBLE:
+        return resultSet.getDouble(i);
+      case BOOLEAN:
+        final boolean aBoolean = resultSet.getBoolean(i);
+        return resultSet.wasNull() ? null : aBoolean;
+      case BYTE:
+        final byte aByte = resultSet.getByte(i);
+        return resultSet.wasNull() ? null : aByte;
+      case SHORT:
+        final short aShort = resultSet.getShort(i);
+        return resultSet.wasNull() ? null : aShort;
+      case INTEGER:
+        final int anInt = resultSet.getInt(i);
+        return resultSet.wasNull() ? null : anInt;
+      case LONG:
+        final long aLong = resultSet.getLong(i);
+        return resultSet.wasNull() ? null : aLong;
+      case FLOAT:
+        final float aFloat = resultSet.getFloat(i);
+        return resultSet.wasNull() ? null : aFloat;
+      case DOUBLE:
+        final double aDouble = resultSet.getDouble(i);
+        return resultSet.wasNull() ? null : aDouble;
+      case JAVA_SQL_DATE:
+        return resultSet.getDate(i);
+      case JAVA_SQL_TIME:
+        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);
+      }
+    }
+
+    public Common.Rep toProto() {
+      return Common.Rep.valueOf(name());
+    }
+
+    public static Rep fromProto(Common.Rep proto) {
+      return Rep.valueOf(proto.name());
+    }
+  }
+
+  /** Base class for a column type. */
+  @JsonTypeInfo(
+      use = JsonTypeInfo.Id.NAME,
+      property = "type",
+      defaultImpl = ScalarType.class)
+  @JsonSubTypes({
+      @JsonSubTypes.Type(value = ScalarType.class, name = "scalar"),
+      @JsonSubTypes.Type(value = StructType.class, name = "struct"),
+      @JsonSubTypes.Type(value = ArrayType.class, name = "array") })
+  public static class AvaticaType {
+    public final int id;
+    public final String name;
+
+    /** The type of the field that holds the value. Not a JDBC property. */
+    public final Rep rep;
+
+    public AvaticaType(int id, String name, Rep rep) {
+      this.id = id;
+      this.name = Objects.requireNonNull(name);
+      this.rep = Objects.requireNonNull(rep);
+    }
+
+    public String columnClassName() {
+      return SqlType.valueOf(id).boxedClass().getName();
+    }
+
+    public AvaticaType setRep(Rep rep) {
+      throw new UnsupportedOperationException();
+    }
+
+    public Common.AvaticaType toProto() {
+      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder();
+
+      builder.setName(name);
+      builder.setId(id);
+      builder.setRep(rep.toProto());
+
+      return builder.build();
+    }
+
+    public static AvaticaType fromProto(Common.AvaticaType proto) {
+      Common.Rep repProto = proto.getRep();
+      Rep rep = Rep.valueOf(repProto.name());
+      AvaticaType type;
+
+      if (proto.hasComponent()) {
+        // ArrayType
+        // recurse on the type for the array elements
+        AvaticaType nestedType = AvaticaType.fromProto(proto.getComponent());
+        type = ColumnMetaData.array(nestedType, proto.getName(), rep);
+      } else if (proto.getColumnsCount() > 0) {
+        // StructType
+        List<ColumnMetaData> columns = new ArrayList<>(proto.getColumnsCount());
+        for (Common.ColumnMetaData protoColumn : proto.getColumnsList()) {
+          columns.add(ColumnMetaData.fromProto(protoColumn));
+        }
+        type = ColumnMetaData.struct(columns);
+      } else {
+        // ScalarType
+        type = ColumnMetaData.scalar(proto.getId(), proto.getName(), rep);
+      }
+
+      return type;
+    }
+
+    @Override public int hashCode() {
+      return Objects.hash(id, name, rep);
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof AvaticaType
+          && id == ((AvaticaType) o).id
+          && Objects.equals(name, ((AvaticaType) o).name)
+          && rep == ((AvaticaType) o).rep;
+    }
+  }
+
+  /** Scalar type. */
+  public static class ScalarType extends AvaticaType {
+    @JsonCreator
+    public ScalarType(@JsonProperty("id") int id,
+        @JsonProperty("name") String name,
+        @JsonProperty("rep") Rep rep) {
+      super(id, name, rep);
+    }
+
+    @Override public AvaticaType setRep(Rep rep) {
+      return new ScalarType(id, name, rep);
+    }
+  }
+
+  /** Record type. */
+  public static class StructType extends AvaticaType {
+    public final List<ColumnMetaData> columns;
+
+    @JsonCreator
+    public StructType(List<ColumnMetaData> columns) {
+      super(Types.STRUCT, "STRUCT", ColumnMetaData.Rep.OBJECT);
+      this.columns = columns;
+    }
+
+    @Override public Common.AvaticaType toProto() {
+      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder(super.toProto());
+      for (ColumnMetaData valueType : columns) {
+        builder.addColumns(valueType.toProto());
+      }
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      return Objects.hash(id, name, rep, columns);
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof StructType
+          && super.equals(o)
+          && Objects.equals(columns, ((StructType) o).columns);
+    }
+  }
+
+  /** Array type. */
+  public static class ArrayType extends AvaticaType {
+    public final 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;
+    }
+
+    @Override public Common.AvaticaType toProto() {
+      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder(super.toProto());
+
+      builder.setComponent(component.toProto());
+
+      return builder.build();
+    }
+
+    @Override public int hashCode() {
+      return Objects.hash(id, name, rep, component);
+    }
+
+    @Override public boolean equals(Object o) {
+      return o == this
+          || o instanceof ArrayType
+          && super.equals(o)
+          && Objects.equals(component, ((ArrayType) o).component);
+    }
+  }
+}
+
+// End ColumnMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
new file mode 100644
index 0000000..0145024
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
@@ -0,0 +1,391 @@
+/*
+ * 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;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * ConnectStringParser is a utility class that parses or creates a JDBC connect
+ * string according to the
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms722656(v=vs.85).aspx">
+ * OLE DB Connection String Syntax</a>.
+ *
+ * <p>This code was adapted from Mondrian's mondrian.olap.Util class.
+ * The primary differences between this and its Mondrian progenitor are:
+ *
+ * <ul>
+ * <li>use of regular {@link Properties} for compatibility with the JDBC API
+ * (replaces Mondrian's use of its own order-preserving and case-insensitive
+ * PropertyList)</li>
+ *
+ * <li>ability to pass to {@link #parse} a pre-existing Properties object into
+ * which properties are to be parsed, possibly overriding prior values</li>
+ *
+ * <li>use of {@link SQLException}s rather than unchecked
+ * {@link RuntimeException}s</li>
+ *
+ * <li>static members for parsing and creating connect strings</li>
+ *
+ * </ul>
+ *
+ * <p>ConnectStringParser has a private constructor. Callers use the static
+ * members:
+ *
+ * <dl>
+ * <dt>{@link #parse(String)}
+ * <dd>Parses the connect string into a new Properties object.
+ *
+ * <dt>{@link #parse(String, Properties)}
+ * <dd>Parses the connect string into an existing Properties object.
+ *
+ * <dt>{@link #getParamString(Properties)}
+ * <dd>Returns a param string, quoted and escaped as needed, to represent the
+ * supplied name-value pairs.
+ * </dl>
+ */
+public class ConnectStringParser {
+  //~ Instance fields --------------------------------------------------------
+
+  private final String s;
+  private final int n;
+  private int i;
+  private final StringBuilder nameBuf = new StringBuilder();
+  private final StringBuilder valueBuf = new StringBuilder();
+
+  //~ Constructors -----------------------------------------------------------
+
+  /**
+   * Creates a new connect string parser.
+   *
+   * @param s connect string to parse
+   *
+   * @see #parse(String)
+   * @see #parse(String, Properties)
+   */
+  private ConnectStringParser(String s) {
+    this.s = s;
+    this.i = 0;
+    this.n = s.length();
+  }
+
+  //~ Methods ----------------------------------------------------------------
+
+  /**
+   * Parses the connect string into a new Properties object.
+   *
+   * @param s connect string to parse
+   *
+   * @return properties object with parsed params
+   *
+   * @throws SQLException error parsing name-value pairs
+   */
+  public static Properties parse(String s)
+      throws SQLException {
+    return new ConnectStringParser(s).parseInternal(null);
+  }
+
+  /**
+   * Parses the connect string into an existing Properties object.
+   *
+   * @param s connect string to parse
+   * @param props optional properties object, may be <code>null</code>
+   *
+   * @return properties object with parsed params; if an input <code>
+   * props</code> was supplied, any duplicate properties will have been
+   * replaced by those from the connect string.
+   *
+   * @throws SQLException error parsing name-value pairs
+   */
+  public static Properties parse(String s, Properties props)
+      throws SQLException {
+    return new ConnectStringParser(s).parseInternal(props);
+  }
+
+  /**
+   * Parses the connect string into a Properties object. Note that the string
+   * can only be parsed once. Subsequent calls return empty/unchanged
+   * Properties.
+   *
+   * @param props optional properties object, may be <code>null</code>
+   *
+   * @return properties object with parsed params; if an input <code>
+   * props</code> was supplied, any duplicate properties will have been
+   * replaced by those from the connect string.
+   *
+   * @throws SQLException error parsing name-value pairs
+   */
+  Properties parseInternal(Properties props)
+      throws SQLException {
+    if (props == null) {
+      props = new Properties();
+    }
+    while (i < n) {
+      parsePair(props);
+    }
+    return props;
+  }
+
+  /**
+   * Reads "name=value;" or "name=value&lt;EOF&gt;".
+   *
+   * @throws SQLException error parsing value
+   */
+  void parsePair(Properties props)
+      throws SQLException {
+    String name = parseName();
+    String value;
+    if (i >= n) {
+      value = "";
+    } else if (s.charAt(i) == ';') {
+      i++;
+      value = "";
+    } else {
+      value = parseValue();
+    }
+    props.put(name, value);
+  }
+
+  /**
+   * Reads "name=". Name can contain equals sign if equals sign is doubled.
+   */
+  String parseName() {
+    nameBuf.setLength(0);
+    while (true) {
+      char c = s.charAt(i);
+      switch (c) {
+      case '=':
+        i++;
+        if ((i < n) && ((c = s.charAt(i)) == '=')) {
+          // doubled equals sign; take one of them, and carry on
+          i++;
+          nameBuf.append(c);
+          break;
+        }
+        String name = nameBuf.toString();
+        name = name.trim();
+        return name;
+      case ' ':
+        if (nameBuf.length() == 0) {
+          // ignore preceding spaces
+          i++;
+          break;
+        }
+        // fall through
+      default:
+        nameBuf.append(c);
+        i++;
+        if (i >= n) {
+          return nameBuf.toString().trim();
+        }
+      }
+    }
+  }
+
+  /**
+   * Reads "value;" or "value&lt;EOF&gt;"
+   *
+   * @throws SQLException if find an unterminated quoted value
+   */
+  String parseValue()
+      throws SQLException {
+    char c;
+
+    // skip over leading white space
+    while ((c = s.charAt(i)) == ' ') {
+      i++;
+      if (i >= n) {
+        return "";
+      }
+    }
+    if ((c == '"') || (c == '\'')) {
+      String value = parseQuoted(c);
+
+      // skip over trailing white space
+      while (i < n && s.charAt(i) == ' ') {
+        i++;
+      }
+      if (i >= n) {
+        return value;
+      } else if (s.charAt(i) == ';') {
+        i++;
+        return value;
+      } else {
+        throw new SQLException(
+            "quoted value ended too soon, at position " + i
+                + " in '" + s + "'");
+      }
+    } else {
+      String value;
+      int semi = s.indexOf(';', i);
+      if (semi >= 0) {
+        value = s.substring(i, semi);
+        i = semi + 1;
+      } else {
+        value = s.substring(i);
+        i = n;
+      }
+      return value.trim();
+    }
+  }
+
+  /**
+   * Reads a string quoted by a given character. Occurrences of the quoting
+   * character must be doubled. For example, <code>parseQuoted('"')</code>
+   * reads <code>"a ""new"" string"</code> and returns <code>a "new"
+   * string</code>.
+   *
+   * @throws SQLException if find an unterminated quoted value
+   */
+  String parseQuoted(char q)
+      throws SQLException {
+    char c = s.charAt(i++);
+    if (c != q) {
+      throw new AssertionError("c != q: c=" + c + " q=" + q);
+    }
+    valueBuf.setLength(0);
+    while (i < n) {
+      c = s.charAt(i);
+      if (c == q) {
+        i++;
+        if (i < n) {
+          c = s.charAt(i);
+          if (c == q) {
+            valueBuf.append(c);
+            i++;
+            continue;
+          }
+        }
+        return valueBuf.toString();
+      } else {
+        valueBuf.append(c);
+        i++;
+      }
+    }
+    throw new SQLException(
+        "Connect string '" + s
+            + "' contains unterminated quoted value '"
+            + valueBuf.toString() + "'");
+  }
+
+  /**
+   * Returns a param string, quoted and escaped as needed, to represent the
+   * supplied name-value pairs.
+   *
+   * @param props name-value pairs
+   *
+   * @return param string, never <code>null</code>
+   */
+  public static String getParamString(Properties props) {
+    if (props == null) {
+      return "";
+    }
+
+    StringBuilder buf = new StringBuilder();
+    for (Map.Entry<String, String> entry : toMap(props).entrySet()) {
+      final String name = entry.getKey();
+      final String value = entry.getValue();
+      String quote = "";
+      if (buf.length() > 0) {
+        buf.append(';');
+      }
+
+      // write parameter name
+      if (name.startsWith(" ") || name.endsWith(" ")) {
+        quote = "'";
+        buf.append(quote);
+      }
+      int len = name.length();
+      for (int i = 0; i < len; ++i) {
+        char c = name.charAt(i);
+        if (c == '=') {
+          buf.append('=');
+        }
+        buf.append(c);
+      }
+
+      buf.append(quote); // might be empty
+      quote = "";
+
+      buf.append('=');
+
+      // write parameter value
+      len = value.length();
+      boolean hasSemi = value.indexOf(';') >= 0;
+      boolean hasSQ = value.indexOf('\'') >= 0;
+      boolean hasDQ = value.indexOf('"') >= 0;
+      if (value.startsWith(" ") || value.endsWith(" ")) {
+        quote = "'";
+      } else if (hasSemi || hasSQ || hasDQ) {
+        // try to choose the least painful quote
+        if (value.startsWith("\"")) {
+          quote = "'";
+        } else if (value.startsWith("'")) {
+          quote = "\"";
+        } else {
+          quote = hasSQ ? "\"" : "'";
+        }
+      }
+      char q;
+      if (quote.length() > 0) {
+        buf.append(quote);
+        q = quote.charAt(0);
+      } else {
+        q = '\0';
+      }
+      for (int i = 0; i < len; ++i) {
+        char c = value.charAt(i);
+        if (c == q) {
+          buf.append(q);
+        }
+        buf.append(c);
+      }
+      buf.append(quote); // might be empty
+    }
+
+    return buf.toString();
+  }
+
+  /**
+   * Converts a {@link Properties} object to a <code>{@link Map}&lt;String,
+   * String&gt;</code>.
+   *
+   * <p>This is necessary because {@link Properties} is a dinosaur class. It
+   * ought to extend <code>Map&lt;String,String&gt;</code>, but instead
+   * extends <code>{@link java.util.Hashtable}&lt;Object,Object&gt;</code>.
+   *
+   * <p>Typical usage, to iterate over a {@link Properties}:
+   *
+   * <blockquote>
+   * <code>
+   * Properties properties;<br>
+   * for (Map.Entry&lt;String, String&gt; entry =
+   * Util.toMap(properties).entrySet()) {<br>
+   *   println("key=" + entry.getKey() + ", value=" + entry.getValue());<br>
+   * }
+   * </code>
+   * </blockquote>
+   */
+  public static Map<String, String> toMap(
+      final Properties properties) {
+    //noinspection unchecked
+    return (Map) properties;
+  }
+}
+
+// End ConnectStringParser.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
new file mode 100644
index 0000000..8e4790c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
@@ -0,0 +1,40 @@
+/*
+ * 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.remote.AvaticaHttpClientFactory;
+import org.apache.calcite.avatica.remote.Service;
+
+/**
+ * Connection configuration.
+ */
+public interface ConnectionConfig {
+  /** @see BuiltInConnectionProperty#SCHEMA */
+  String schema();
+  /** @see BuiltInConnectionProperty#TIME_ZONE */
+  String timeZone();
+  /** @see BuiltInConnectionProperty#FACTORY */
+  Service.Factory factory();
+  /** @see BuiltInConnectionProperty#URL */
+  String url();
+  /** @see BuiltInConnectionProperty#SERIALIZATION */
+  String serialization();
+  AvaticaHttpClientFactory httpClientFactory();
+  String httpClientClass();
+}
+
+// End ConnectionConfig.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
new file mode 100644
index 0000000..bbeefea
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
@@ -0,0 +1,239 @@
+/*
+ * 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.remote.AvaticaHttpClientFactory;
+import org.apache.calcite.avatica.remote.Service;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/** Implementation of {@link ConnectionConfig}. */
+public class ConnectionConfigImpl implements ConnectionConfig {
+  protected final Properties properties;
+
+  public ConnectionConfigImpl(Properties properties) {
+    this.properties = properties;
+  }
+
+  public String schema() {
+    return BuiltInConnectionProperty.SCHEMA.wrap(properties).getString();
+  }
+
+  public String timeZone() {
+    return BuiltInConnectionProperty.TIME_ZONE.wrap(properties).getString();
+  }
+
+  public Service.Factory factory() {
+    return BuiltInConnectionProperty.FACTORY.wrap(properties)
+        .getPlugin(Service.Factory.class, null);
+  }
+
+  public String url() {
+    return BuiltInConnectionProperty.URL.wrap(properties).getString();
+  }
+
+  public String serialization() {
+    return BuiltInConnectionProperty.SERIALIZATION.wrap(properties).getString();
+  }
+
+  public AvaticaHttpClientFactory httpClientFactory() {
+    return BuiltInConnectionProperty.HTTP_CLIENT_FACTORY.wrap(properties)
+        .getPlugin(AvaticaHttpClientFactory.class, null);
+  }
+
+  public String httpClientClass() {
+    return BuiltInConnectionProperty.HTTP_CLIENT_IMPL.wrap(properties).getString();
+  }
+
+  /** Converts a {@link Properties} object containing (name, value)
+   * pairs into a map whose keys are
+   * {@link org.apache.calcite.avatica.InternalProperty} objects.
+   *
+   * <p>Matching is case-insensitive. Throws if a property is not known.
+   * If a property occurs more than once, takes the last occurrence.</p>
+   *
+   * @param properties Properties
+   * @return Map
+   * @throws RuntimeException if a property is not known
+   */
+  public static Map<ConnectionProperty, String> parse(Properties properties,
+      Map<String, ? extends ConnectionProperty> nameToProps) {
+    final Map<ConnectionProperty, String> map =
+        new LinkedHashMap<ConnectionProperty, String>();
+    for (String name : properties.stringPropertyNames()) {
+      final ConnectionProperty connectionProperty =
+          nameToProps.get(name.toUpperCase());
+      if (connectionProperty == null) {
+        // For now, don't throw. It messes up sub-projects.
+        //throw new RuntimeException("Unknown property '" + name + "'");
+        continue;
+      }
+      map.put(connectionProperty, properties.getProperty(name));
+    }
+    return map;
+  }
+
+  /** The combination of a property definition and a map of property values. */
+  public static class PropEnv {
+    final Map<? extends ConnectionProperty, String> map;
+    private final ConnectionProperty property;
+
+    public PropEnv(Map<? extends ConnectionProperty, String> map,
+        ConnectionProperty property) {
+      this.map = map;
+      this.property = property;
+    }
+
+    private <T> T get_(Converter<T> converter, String defaultValue) {
+      final String s = map.get(property);
+      if (s != null) {
+        return converter.apply(property, s);
+      }
+      return converter.apply(property, defaultValue);
+    }
+
+    /** Returns the string value of this property, or null if not specified and
+     * no default. */
+    public String getString() {
+      return getString((String) property.defaultValue());
+    }
+
+    /** Returns the string value of this property, or null if not specified and
+     * no default. */
+    public String getString(String defaultValue) {
+      assert property.type() == ConnectionProperty.Type.STRING;
+      return get_(IDENTITY_CONVERTER, defaultValue);
+    }
+
+    /** Returns the boolean value of this property. Throws if not set and no
+     * default. */
+    public boolean getBoolean() {
+      return getBoolean((Boolean) property.defaultValue());
+    }
+
+    /** Returns the boolean value of this property. Throws if not set and no
+     * default. */
+    public boolean getBoolean(boolean defaultValue) {
+      assert property.type() == ConnectionProperty.Type.BOOLEAN;
+      return get_(BOOLEAN_CONVERTER, Boolean.toString(defaultValue));
+    }
+
+    /** Returns the enum value of this property. Throws if not set and no
+     * default. */
+    public <E extends Enum<E>> E getEnum(Class<E> enumClass) {
+      //noinspection unchecked
+      return getEnum(enumClass, (E) property.defaultValue());
+    }
+
+    /** Returns the enum value of this property. Throws if not set and no
+     * default. */
+    public <E extends Enum<E>> E getEnum(Class<E> enumClass, E defaultValue) {
+      assert property.type() == ConnectionProperty.Type.ENUM;
+      //noinspection unchecked
+      return get_(enumConverter(enumClass), defaultValue.name());
+    }
+
+    /** Returns an instance of a plugin.
+     *
+     * <p>Throws if not set and no default.
+     * Also throws if the class does not implement the required interface,
+     * or if it does not have a public default constructor or an public static
+     * field called {@code #INSTANCE}. */
+    public <T> T getPlugin(Class<T> pluginClass, T defaultInstance) {
+      return getPlugin(pluginClass, (String) property.defaultValue(),
+          defaultInstance);
+    }
+
+    /** Returns an instance of a plugin, using a given class name if none is
+     * set.
+     *
+     * <p>Throws if not set and no default.
+     * Also throws if the class does not implement the required interface,
+     * or if it does not have a public default constructor or an public static
+     * field called {@code #INSTANCE}. */
+    public <T> T getPlugin(Class<T> pluginClass, String defaultClassName,
+        T defaultInstance) {
+      assert property.type() == ConnectionProperty.Type.PLUGIN;
+      return get_(pluginConverter(pluginClass, defaultInstance),
+          defaultClassName);
+    }
+  }
+
+  /** Callback to parse a property from string to its native type. */
+  public interface Converter<T> {
+    T apply(ConnectionProperty connectionProperty, String s);
+  }
+
+  public static final Converter<Boolean> BOOLEAN_CONVERTER =
+      new Converter<Boolean>() {
+        public Boolean apply(ConnectionProperty connectionProperty, String s) {
+          if (s == null) {
+            throw new RuntimeException("Required property '"
+                + connectionProperty.camelName() + "' not specified");
+          }
+          return Boolean.parseBoolean(s);
+        }
+      };
+
+  public static final Converter<String> IDENTITY_CONVERTER =
+      new Converter<String>() {
+        public String apply(ConnectionProperty connectionProperty, String s) {
+          return s;
+        }
+      };
+
+  public static <E extends Enum> Converter<E> enumConverter(
+      final Class<E> enumClass) {
+    return new Converter<E>() {
+      public E apply(ConnectionProperty connectionProperty, String s) {
+        if (s == null) {
+          throw new RuntimeException("Required property '"
+              + connectionProperty.camelName() + "' not specified");
+        }
+        try {
+          return (E) Enum.valueOf(enumClass, s);
+        } catch (IllegalArgumentException e) {
+          throw new RuntimeException("Property '" + s + "' not valid for enum "
+              + enumClass.getName());
+        }
+      }
+    };
+  }
+
+  public static <T> Converter<T> pluginConverter(final Class<T> pluginClass,
+      final T defaultInstance) {
+    return new Converter<T>() {
+      public T apply(ConnectionProperty connectionProperty, String s) {
+        if (s == null) {
+          if (defaultInstance != null) {
+            return defaultInstance;
+          }
+          if (!connectionProperty.required()) {
+            return null;
+          }
+          throw new RuntimeException("Required property '"
+              + connectionProperty.camelName() + "' not specified");
+        }
+        return AvaticaUtils.instantiatePlugin(pluginClass, s);
+      }
+    };
+  }
+}
+
+// End ConnectionConfigImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
new file mode 100644
index 0000000..c147ecc
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
@@ -0,0 +1,279 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Objects;
+
+/** Concrete implementation of {@link Meta.ConnectionProperties}. Provides additional state
+ * tracking to enable {@code RemoteMeta} to lazily push changes up to a query server.
+ *
+ * <p>{@code Meta} instances should probably hold authority on the {@code isDirty}
+ * flag because {@code AvaticaConnection} instances have no way of knowing if they're local or
+ * remote.
+ */
+public class ConnectionPropertiesImpl implements Meta.ConnectionProperties {
+  private static final FieldDescriptor CATALOG_DESCRIPTOR = Common.ConnectionProperties
+      .getDescriptor().findFieldByNumber(Common.ConnectionProperties.CATALOG_FIELD_NUMBER);
+  private static final FieldDescriptor SCHEMA_DESCRIPTOR = Common.ConnectionProperties
+      .getDescriptor().findFieldByNumber(Common.ConnectionProperties.SCHEMA_FIELD_NUMBER);
+  private static final FieldDescriptor TRANSACTION_ISOLATION_DESCRIPTOR = Common
+      .ConnectionProperties.getDescriptor().findFieldByNumber(
+          Common.ConnectionProperties.TRANSACTION_ISOLATION_FIELD_NUMBER);
+
+  private boolean isDirty = false;
+  private Boolean autoCommit;
+  private Boolean readOnly;
+  private Integer transactionIsolation;
+  private String catalog;
+  private String schema;
+
+  // TODO: replace with Meta.ConnectionProperties$EMPTY instance?
+  public ConnectionPropertiesImpl() {}
+
+  public ConnectionPropertiesImpl(Connection conn) throws SQLException {
+    this(conn.getAutoCommit(), conn.isReadOnly(), conn.getTransactionIsolation(),
+        conn.getCatalog(), conn.getSchema());
+  }
+
+  @JsonCreator
+  public ConnectionPropertiesImpl(
+      @JsonProperty("autoCommit") Boolean autoCommit,
+      @JsonProperty("readOnly") Boolean readOnly,
+      @JsonProperty("transactionIsolation") Integer transactionIsolation,
+      @JsonProperty("catalog") String catalog,
+      @JsonProperty("schema") String schema) {
+    this.autoCommit = autoCommit;
+    this.readOnly = readOnly;
+    this.transactionIsolation = transactionIsolation;
+    this.catalog = catalog;
+    this.schema = schema;
+  }
+
+  public ConnectionPropertiesImpl setDirty(boolean val) {
+    this.isDirty = val;
+    return this;
+  }
+
+  public boolean isDirty() {
+    return this.isDirty;
+  }
+
+  @Override public boolean isEmpty() {
+    return autoCommit == null && readOnly == null && transactionIsolation == null
+        && catalog == null && schema == null;
+  }
+
+  /** Overwrites fields in {@code this} with any non-null fields in {@code that}. Sets
+   * {@code isDirty} if any fields are changed.
+   *
+   * @return {@code this}
+   */
+  @Override public ConnectionPropertiesImpl merge(Meta.ConnectionProperties that) {
+    if (this == that) {
+      return this;
+    }
+    if (that.isAutoCommit() != null && this.autoCommit != that.isAutoCommit()) {
+      this.autoCommit = that.isAutoCommit();
+      this.isDirty = true;
+    }
+    if (that.isReadOnly() != null && this.readOnly != that.isReadOnly()) {
+      this.readOnly = that.isReadOnly();
+      this.isDirty = true;
+    }
+    if (that.getTransactionIsolation() != null
+        && !that.getTransactionIsolation().equals(this.transactionIsolation)) {
+      this.transactionIsolation = that.getTransactionIsolation();
+      this.isDirty = true;
+    }
+    if (that.getCatalog() != null && !that.getCatalog().equalsIgnoreCase(this.catalog)) {
+      this.catalog = that.getCatalog();
+      this.isDirty = true;
+    }
+    if (that.getSchema() != null && !that.getSchema().equalsIgnoreCase(this.schema)) {
+      this.schema = that.getSchema();
+      this.isDirty = true;
+    }
+    return this;
+  }
+
+  /** Sets {@code autoCommit} status and flag as dirty.
+   *
+   * @return {@code this}
+   */
+  @Override public Meta.ConnectionProperties setAutoCommit(boolean val) {
+    this.autoCommit = val;
+    this.isDirty = true;
+    return this;
+  }
+
+  @Override public Boolean isAutoCommit() {
+    return this.autoCommit;
+  }
+
+  /** Sets {@code readOnly} status and flag as dirty.
+   *
+   * @return {@code this}
+   */
+  @Override public Meta.ConnectionProperties setReadOnly(boolean val) {
+    this.readOnly = val;
+    this.isDirty = true;
+    return this;
+  }
+
+  @Override public Boolean isReadOnly() {
+    return this.readOnly;
+  }
+
+  /** Sets {@code transactionIsolation} status and flag as dirty.
+   *
+   * @return {@code this}
+   */
+  @Override public Meta.ConnectionProperties setTransactionIsolation(int val) {
+    this.transactionIsolation = val;
+    this.isDirty = true;
+    return this;
+  }
+
+  public Integer getTransactionIsolation() {
+    return this.transactionIsolation;
+  }
+
+  /** Sets {@code catalog} and flag as dirty.
+   *
+   * @return {@code this}
+   */
+  @Override public Meta.ConnectionProperties setCatalog(String val) {
+    this.catalog = val;
+    this.isDirty = true;
+    return this;
+  }
+
+  @Override public String getCatalog() {
+    return this.catalog;
+  }
+
+  /** Sets {@code schema} and flag as dirty.
+   *
+   * @return {@code this}
+   */
+  @Override public Meta.ConnectionProperties setSchema(String val) {
+    this.schema = val;
+    this.isDirty = true;
+    return this;
+  }
+
+  public String getSchema() {
+    return this.schema;
+  }
+
+  @Override public int hashCode() {
+    return Objects.hash(autoCommit, catalog, isDirty, readOnly, schema,
+        transactionIsolation);
+  }
+
+  @Override public boolean equals(Object o) {
+    return o == this
+        || o instanceof ConnectionPropertiesImpl
+        && Objects.equals(autoCommit, ((ConnectionPropertiesImpl) o).autoCommit)
+        && Objects.equals(catalog, ((ConnectionPropertiesImpl) o).catalog)
+        && isDirty == ((ConnectionPropertiesImpl) o).isDirty
+        && Objects.equals(readOnly, ((ConnectionPropertiesImpl) o).readOnly)
+        && Objects.equals(schema, ((ConnectionPropertiesImpl) o).schema)
+        && Objects.equals(transactionIsolation,
+            ((ConnectionPropertiesImpl) o).transactionIsolation);
+  }
+
+  public Common.ConnectionProperties toProto() {
+    Common.ConnectionProperties.Builder builder = Common.ConnectionProperties.newBuilder();
+
+    if (null != autoCommit) {
+      builder.setHasAutoCommit(true);
+      builder.setAutoCommit(autoCommit.booleanValue());
+    } else {
+      // Be explicit to avoid default value confusion
+      builder.setHasAutoCommit(false);
+    }
+
+    if (null != catalog) {
+      builder.setCatalog(catalog);
+    }
+
+    builder.setIsDirty(isDirty);
+
+    if (null != readOnly) {
+      builder.setHasReadOnly(true);
+      builder.setReadOnly(readOnly.booleanValue());
+    } else {
+      // Be explicit to avoid default value confusion
+      builder.setHasReadOnly(false);
+    }
+
+    if (null != schema) {
+      builder.setSchema(schema);
+    }
+
+    if (null != transactionIsolation) {
+      builder.setTransactionIsolation(transactionIsolation.intValue());
+    }
+
+    return builder.build();
+  }
+
+  public static ConnectionPropertiesImpl fromProto(Common.ConnectionProperties proto) {
+    String catalog = null;
+    if (proto.hasField(CATALOG_DESCRIPTOR)) {
+      catalog = proto.getCatalog();
+    }
+
+    String schema = null;
+    if (proto.hasField(SCHEMA_DESCRIPTOR)) {
+      schema = proto.getSchema();
+    }
+
+    Boolean autoCommit = null;
+    if (proto.getHasAutoCommit()) {
+      autoCommit = Boolean.valueOf(proto.getAutoCommit());
+    }
+
+    Boolean readOnly = null;
+    if (proto.getHasReadOnly()) {
+      readOnly = Boolean.valueOf(proto.getReadOnly());
+    }
+
+    Integer transactionIsolation = null;
+    if (proto.hasField(TRANSACTION_ISOLATION_DESCRIPTOR)) {
+      transactionIsolation = Integer.valueOf(proto.getTransactionIsolation());
+    }
+
+    ConnectionPropertiesImpl impl = new ConnectionPropertiesImpl(autoCommit, readOnly,
+        transactionIsolation, catalog, schema);
+
+    impl.setDirty(proto.getIsDirty());
+
+    return impl;
+  }
+}
+
+// End ConnectionPropertiesImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
new file mode 100644
index 0000000..d380d80
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
@@ -0,0 +1,69 @@
+/*
+ * 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.util.Properties;
+
+/**
+ * Definition of a property that may be specified on the JDBC connect string.
+ * {@link BuiltInConnectionProperty} enumerates built-in properties, but
+ * there may be others; the list is not closed.
+ */
+public interface ConnectionProperty {
+  /** The name of this property. (E.g. "MATERIALIZATIONS_ENABLED".) */
+  String name();
+
+  /** The name of this property in camel-case.
+   * (E.g. "materializationsEnabled".) */
+  String camelName();
+
+  /** Returns the default value of this property. The type must match its data
+   * type. */
+  Object defaultValue();
+
+  /** Returns the data type of this property. */
+  Type type();
+
+  /** Wraps this property with a properties object from which its value can be
+   * obtained when needed. */
+  ConnectionConfigImpl.PropEnv wrap(Properties properties);
+
+  /** Whether the property is mandatory. */
+  boolean required();
+
+  /** Data type of property. */
+  enum Type {
+    BOOLEAN,
+    STRING,
+    ENUM,
+    PLUGIN;
+
+    public boolean valid(Object defaultValue) {
+      switch (this) {
+      case BOOLEAN:
+        return defaultValue instanceof Boolean;
+      case STRING:
+      case PLUGIN:
+        return defaultValue instanceof String;
+      default:
+        return defaultValue instanceof Enum;
+      }
+    }
+  }
+}
+
+// End ConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
new file mode 100644
index 0000000..15c966a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/DriverVersion.java
@@ -0,0 +1,149 @@
+/*
+ * 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/blob/5cee486f/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
new file mode 100644
index 0000000..831e66d
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/Handler.java
@@ -0,0 +1,87 @@
+/*
+ * 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/blob/5cee486f/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
new file mode 100644
index 0000000..c2e6c1a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
@@ -0,0 +1,47 @@
+/*
+ * 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/blob/5cee486f/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
new file mode 100644
index 0000000..27c6056
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/Helper.java
@@ -0,0 +1,76 @@
+/*
+ * 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


[49/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
deleted file mode 100644
index f7117e9..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopParameterMetaData.java
+++ /dev/null
@@ -1,85 +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.noop;
-
-import java.sql.ParameterMetaData;
-import java.sql.SQLException;
-
-/**
- * An implementation of {@link ParameterMetaData} which does nothing.
- */
-public class AvaticaNoopParameterMetaData implements ParameterMetaData {
-
-  private static final AvaticaNoopParameterMetaData INSTANCE = new AvaticaNoopParameterMetaData();
-
-  public static AvaticaNoopParameterMetaData getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopParameterMetaData() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return false;
-  }
-
-  @Override public int getParameterCount() throws SQLException {
-    return 0;
-  }
-
-  @Override public int isNullable(int param) throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean isSigned(int param) throws SQLException {
-    return false;
-  }
-
-  @Override public int getPrecision(int param) throws SQLException {
-    return 0;
-  }
-
-  @Override public int getScale(int param) throws SQLException {
-    return 0;
-  }
-
-  @Override public int getParameterType(int param) throws SQLException {
-    return 0;
-  }
-
-  @Override public String getParameterTypeName(int param) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getParameterClassName(int param) throws SQLException {
-    return "java.lang.Object";
-  }
-
-  @Override public int getParameterMode(int param) throws SQLException {
-    return 0;
-  }
-
-}
-
-// End AvaticaNoopParameterMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
deleted file mode 100644
index b8ad8cc..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopPreparedStatement.java
+++ /dev/null
@@ -1,344 +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.noop;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-
-/**
- * A {@link PreparedStatement} instance which does nothing.
- */
-public class AvaticaNoopPreparedStatement implements PreparedStatement {
-
-  private static final AvaticaNoopPreparedStatement INSTANCE = new AvaticaNoopPreparedStatement();
-
-  public static AvaticaNoopPreparedStatement getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopPreparedStatement() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public ResultSet executeQuery(String sql) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public int executeUpdate(String sql) throws SQLException {
-    return 1;
-  }
-
-  @Override public void close() throws SQLException {}
-
-  @Override public int getMaxFieldSize() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setMaxFieldSize(int max) throws SQLException {}
-
-  @Override public int getMaxRows() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setMaxRows(int max) throws SQLException {}
-
-  @Override public void setEscapeProcessing(boolean enable) throws SQLException {}
-
-  @Override public int getQueryTimeout() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setQueryTimeout(int seconds) throws SQLException {}
-
-  @Override public void cancel() throws SQLException {}
-
-  @Override public SQLWarning getWarnings() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void clearWarnings() throws SQLException {}
-
-  @Override public void setCursorName(String name) throws SQLException {}
-
-  @Override public boolean execute(String sql) throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getResultSet() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public int getUpdateCount() throws SQLException {
-    return 1;
-  }
-
-  @Override public boolean getMoreResults() throws SQLException {
-    return false;
-  }
-
-  @Override public void setFetchDirection(int direction) throws SQLException {}
-
-  @Override public int getFetchDirection() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setFetchSize(int rows) throws SQLException {}
-
-  @Override public int getFetchSize() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getResultSetConcurrency() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getResultSetType() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void addBatch(String sql) throws SQLException {}
-
-  @Override public void clearBatch() throws SQLException {}
-
-  @Override public int[] executeBatch() throws SQLException {
-    return new int[0];
-  }
-
-  @Override public Connection getConnection() throws SQLException {
-    return AvaticaNoopConnection.getInstance();
-  }
-
-  @Override public boolean getMoreResults(int current) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSet getGeneratedKeys() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-    return 1;
-  }
-
-  @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-    return 1;
-  }
-
-  @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-    return 1;
-  }
-
-  @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-    return true;
-  }
-
-  @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-    return true;
-  }
-
-  @Override public boolean execute(String sql, String[] columnNames) throws SQLException {
-    return true;
-  }
-
-  @Override public int getResultSetHoldability() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isClosed() throws SQLException {
-    return false;
-  }
-
-  @Override public void setPoolable(boolean poolable) throws SQLException {}
-
-  @Override public boolean isPoolable() throws SQLException {
-    return true;
-  }
-
-  @Override public void closeOnCompletion() throws SQLException {}
-
-  @Override public boolean isCloseOnCompletion() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet executeQuery() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public int executeUpdate() throws SQLException {
-    return 1;
-  }
-
-  @Override public void setNull(int parameterIndex, int sqlType) throws SQLException {}
-
-  @Override public void setBoolean(int parameterIndex, boolean x) throws SQLException {}
-
-  @Override public void setByte(int parameterIndex, byte x) throws SQLException {}
-
-  @Override public void setShort(int parameterIndex, short x) throws SQLException {}
-
-  @Override public void setInt(int parameterIndex, int x) throws SQLException {}
-
-  @Override public void setLong(int parameterIndex, long x) throws SQLException {}
-
-  @Override public void setFloat(int parameterIndex, float x) throws SQLException {}
-
-  @Override public void setDouble(int parameterIndex, double x) throws SQLException {}
-
-  @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {}
-
-  @Override public void setString(int parameterIndex, String x) throws SQLException {}
-
-  @Override public void setBytes(int parameterIndex, byte[] x) throws SQLException {}
-
-  @Override public void setDate(int parameterIndex, Date x) throws SQLException {}
-
-  @Override public void setTime(int parameterIndex, Time x) throws SQLException {}
-
-  @Override public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {}
-
-  @Override public void setAsciiStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void setUnicodeStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void setBinaryStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void clearParameters() throws SQLException {}
-
-  @Override public void setObject(int parameterIndex, Object x, int targetSqlType)
-      throws SQLException {}
-
-  @Override public void setObject(int parameterIndex, Object x) throws SQLException {}
-
-  @Override public boolean execute() throws SQLException {
-    return false;
-  }
-
-  @Override public void addBatch() throws SQLException {}
-
-  @Override public void setCharacterStream(int parameterIndex, Reader reader, int length)
-      throws SQLException {}
-
-  @Override public void setRef(int parameterIndex, Ref x) throws SQLException {}
-
-  @Override public void setBlob(int parameterIndex, Blob x) throws SQLException {}
-
-  @Override public void setClob(int parameterIndex, Clob x) throws SQLException {}
-
-  @Override public void setArray(int parameterIndex, Array x) throws SQLException {}
-
-  @Override public ResultSetMetaData getMetaData() throws SQLException {
-    return AvaticaNoopResultSetMetaData.getInstance();
-  }
-
-  @Override public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {}
-
-  @Override public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {}
-
-  @Override public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
-      throws SQLException {}
-
-  @Override public void setNull(int parameterIndex, int sqlType, String typeName)
-      throws SQLException {}
-
-  @Override public void setURL(int parameterIndex, URL x) throws SQLException {}
-
-  @Override public ParameterMetaData getParameterMetaData() throws SQLException {
-    return AvaticaNoopParameterMetaData.getInstance();
-  }
-
-  @Override public void setRowId(int parameterIndex, RowId x) throws SQLException {}
-
-  @Override public void setNString(int parameterIndex, String value) throws SQLException {}
-
-  @Override public void setNCharacterStream(int parameterIndex, Reader value, long length)
-      throws SQLException {}
-
-  @Override public void setNClob(int parameterIndex, NClob value) throws SQLException {}
-
-  @Override public void setClob(int parameterIndex, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void setBlob(int parameterIndex, InputStream inputStream, long length)
-      throws SQLException {}
-
-  @Override public void setNClob(int parameterIndex, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {}
-
-  @Override public void setObject(int parameterIndex, Object x, int targetSqlType,
-      int scaleOrLength)
-      throws SQLException {}
-
-  @Override public void setAsciiStream(int parameterIndex, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void setBinaryStream(int parameterIndex, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void setCharacterStream(int parameterIndex, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {}
-
-  @Override public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {}
-
-  @Override public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {}
-
-  @Override public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {}
-
-  @Override public void setClob(int parameterIndex, Reader reader) throws SQLException {}
-
-  @Override public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {}
-
-  @Override public void setNClob(int parameterIndex, Reader reader) throws SQLException {}
-}
-
-// End AvaticaNoopPreparedStatement.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
deleted file mode 100644
index 2d71184..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSet.java
+++ /dev/null
@@ -1,661 +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.noop;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Map;
-
-/**
- * A {@link ResultSet} implementation which does nothing.
- */
-public class AvaticaNoopResultSet implements ResultSet {
-
-  private static final AvaticaNoopResultSet INSTANCE = new AvaticaNoopResultSet();
-
-  public static AvaticaNoopResultSet getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopResultSet() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("unsupported");
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean next() throws SQLException {
-    return false;
-  }
-
-  @Override public void close() throws SQLException {}
-
-  @Override public boolean wasNull() throws SQLException {
-    return false;
-  }
-
-  @Override public String getString(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean getBoolean(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public byte getByte(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public short getShort(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getInt(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public long getLong(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public float getFloat(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public double getDouble(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public byte[] getBytes(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Date getDate(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Time getTime(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Timestamp getTimestamp(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getAsciiStream(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getUnicodeStream(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getBinaryStream(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getString(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean getBoolean(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public byte getByte(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public short getShort(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getInt(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public long getLong(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public float getFloat(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public double getDouble(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public byte[] getBytes(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Date getDate(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Time getTime(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Timestamp getTimestamp(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getAsciiStream(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getUnicodeStream(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public InputStream getBinaryStream(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public SQLWarning getWarnings() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void clearWarnings() throws SQLException {}
-
-  @Override public String getCursorName() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSetMetaData getMetaData() throws SQLException {
-    return AvaticaNoopResultSetMetaData.getInstance();
-  }
-
-  @Override public Object getObject(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Object getObject(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int findColumn(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Reader getCharacterStream(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Reader getCharacterStream(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isBeforeFirst() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isAfterLast() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isFirst() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isLast() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void beforeFirst() throws SQLException {}
-
-  @Override public void afterLast() throws SQLException {}
-
-  @Override public boolean first() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean last() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getRow() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean absolute(int row) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean relative(int rows) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean previous() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setFetchDirection(int direction) throws SQLException {}
-
-  @Override public int getFetchDirection() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setFetchSize(int rows) throws SQLException {}
-
-  @Override public int getFetchSize() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getType() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getConcurrency() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean rowUpdated() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean rowInserted() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean rowDeleted() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void updateNull(int columnIndex) throws SQLException {}
-
-  @Override public void updateBoolean(int columnIndex, boolean x) throws SQLException {}
-
-  @Override public void updateByte(int columnIndex, byte x) throws SQLException {}
-
-  @Override public void updateShort(int columnIndex, short x) throws SQLException {}
-
-  @Override public void updateInt(int columnIndex, int x) throws SQLException {}
-
-  @Override public void updateLong(int columnIndex, long x) throws SQLException {}
-
-  @Override public void updateFloat(int columnIndex, float x) throws SQLException {}
-
-  @Override public void updateDouble(int columnIndex, double x) throws SQLException {}
-
-  @Override public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {}
-
-  @Override public void updateString(int columnIndex, String x) throws SQLException {}
-
-  @Override public void updateBytes(int columnIndex, byte[] x) throws SQLException {}
-
-  @Override public void updateDate(int columnIndex, Date x) throws SQLException {}
-
-  @Override public void updateTime(int columnIndex, Time x) throws SQLException {}
-
-  @Override public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {}
-
-  @Override public void updateAsciiStream(int columnIndex, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void updateBinaryStream(int columnIndex, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void updateCharacterStream(int columnIndex, Reader x, int length)
-      throws SQLException {}
-
-  @Override public void updateObject(int columnIndex, Object x, int scaleOrLength)
-      throws SQLException {}
-
-  @Override public void updateObject(int columnIndex, Object x) throws SQLException {}
-
-  @Override public void updateNull(String columnLabel) throws SQLException {}
-
-  @Override public void updateBoolean(String columnLabel, boolean x) throws SQLException {}
-
-  @Override public void updateByte(String columnLabel, byte x) throws SQLException {}
-
-  @Override public void updateShort(String columnLabel, short x) throws SQLException {}
-
-  @Override public void updateInt(String columnLabel, int x) throws SQLException {}
-
-  @Override public void updateLong(String columnLabel, long x) throws SQLException {}
-
-  @Override public void updateFloat(String columnLabel, float x) throws SQLException {}
-
-  @Override public void updateDouble(String columnLabel, double x) throws SQLException {}
-
-  @Override public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {}
-
-  @Override public void updateString(String columnLabel, String x) throws SQLException {}
-
-  @Override public void updateBytes(String columnLabel, byte[] x) throws SQLException {}
-
-  @Override public void updateDate(String columnLabel, Date x) throws SQLException {}
-
-  @Override public void updateTime(String columnLabel, Time x) throws SQLException {}
-
-  @Override public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {}
-
-  @Override public void updateAsciiStream(String columnLabel, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void updateBinaryStream(String columnLabel, InputStream x, int length)
-      throws SQLException {}
-
-  @Override public void updateCharacterStream(String columnLabel, Reader reader, int length)
-      throws SQLException {}
-
-  @Override public void updateObject(String columnLabel, Object x, int scaleOrLength)
-      throws SQLException {}
-
-  @Override public void updateObject(String columnLabel, Object x) throws SQLException {}
-
-  @Override public void insertRow() throws SQLException {}
-
-  @Override public void updateRow() throws SQLException {}
-
-  @Override public void deleteRow() throws SQLException {}
-
-  @Override public void refreshRow() throws SQLException {}
-
-  @Override public void cancelRowUpdates() throws SQLException {}
-
-  @Override public void moveToInsertRow() throws SQLException {}
-
-  @Override public void moveToCurrentRow() throws SQLException {}
-
-  @Override public Statement getStatement() throws SQLException {
-    return AvaticaNoopStatement.getInstance();
-  }
-
-  @Override public Object getObject(int columnIndex, Map<String, Class<?>> map)
-      throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Ref getRef(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Blob getBlob(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Clob getClob(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Array getArray(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Object getObject(String columnLabel, Map<String, Class<?>> map)
-      throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Ref getRef(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Blob getBlob(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Clob getClob(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Array getArray(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Date getDate(int columnIndex, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Date getDate(String columnLabel, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Time getTime(int columnIndex, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Time getTime(String columnLabel, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public URL getURL(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public URL getURL(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void updateRef(int columnIndex, Ref x) throws SQLException {}
-
-  @Override public void updateRef(String columnLabel, Ref x) throws SQLException {}
-
-  @Override public void updateBlob(int columnIndex, Blob x) throws SQLException {}
-
-  @Override public void updateBlob(String columnLabel, Blob x) throws SQLException {}
-
-  @Override public void updateClob(int columnIndex, Clob x) throws SQLException {}
-
-  @Override public void updateClob(String columnLabel, Clob x) throws SQLException {}
-
-  @Override public void updateArray(int columnIndex, Array x) throws SQLException {}
-
-  @Override public void updateArray(String columnLabel, Array x) throws SQLException {}
-
-  @Override public RowId getRowId(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public RowId getRowId(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void updateRowId(int columnIndex, RowId x) throws SQLException {}
-
-  @Override public void updateRowId(String columnLabel, RowId x) throws SQLException {}
-
-  @Override public int getHoldability() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isClosed() throws SQLException {
-    return false;
-  }
-
-  @Override public void updateNString(int columnIndex, String nString) throws SQLException {}
-
-  @Override public void updateNString(String columnLabel, String nString) throws SQLException {}
-
-  @Override public void updateNClob(int columnIndex, NClob nClob) throws SQLException {}
-
-  @Override public void updateNClob(String columnLabel, NClob nClob) throws SQLException {}
-
-  @Override public NClob getNClob(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public NClob getNClob(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public SQLXML getSQLXML(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public SQLXML getSQLXML(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {}
-
-  @Override public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {}
-
-  @Override public String getNString(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getNString(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Reader getNCharacterStream(int columnIndex) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public Reader getNCharacterStream(String columnLabel) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void updateNCharacterStream(int columnIndex, Reader x, long length)
-      throws SQLException {}
-
-  @Override public void updateNCharacterStream(String columnLabel, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateAsciiStream(int columnIndex, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void updateBinaryStream(int columnIndex, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void updateCharacterStream(int columnIndex, Reader x, long length)
-      throws SQLException {}
-
-  @Override public void updateAsciiStream(String columnLabel, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void updateBinaryStream(String columnLabel, InputStream x, long length)
-      throws SQLException {}
-
-  @Override public void updateCharacterStream(String columnLabel, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateBlob(int columnIndex, InputStream inputStream, long length)
-      throws SQLException {}
-
-  @Override public void updateBlob(String columnLabel, InputStream inputStream, long length)
-      throws SQLException {}
-
-  @Override public void updateClob(int columnIndex, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateClob(String columnLabel, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateNClob(int columnIndex, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateNClob(String columnLabel, Reader reader, long length)
-      throws SQLException {}
-
-  @Override public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {}
-
-  @Override public void updateNCharacterStream(String columnLabel, Reader reader)
-      throws SQLException {}
-
-  @Override public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {}
-
-  @Override public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {}
-
-  @Override public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {}
-
-  @Override public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {}
-
-  @Override public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {}
-
-  @Override public void updateCharacterStream(String columnLabel, Reader reader)
-      throws SQLException {}
-
-  @Override public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {}
-
-  @Override public void updateBlob(String columnLabel, InputStream inputStream)
-      throws SQLException {}
-
-  @Override public void updateClob(int columnIndex, Reader reader) throws SQLException {}
-
-  @Override public void updateClob(String columnLabel, Reader reader) throws SQLException {}
-
-  @Override public void updateNClob(int columnIndex, Reader reader) throws SQLException {}
-
-  @Override public void updateNClob(String columnLabel, Reader reader) throws SQLException {}
-
-  @Override public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
-    throw unsupported();
-  }
-
-}
-
-// End AvaticaNoopResultSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
deleted file mode 100644
index ddc8c3b..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopResultSetMetaData.java
+++ /dev/null
@@ -1,133 +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.noop;
-
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-
-/**
- * A {@link ResultSetMetaData} implementation which does nothing.
- */
-public class AvaticaNoopResultSetMetaData implements ResultSetMetaData {
-
-  private static final AvaticaNoopResultSetMetaData INSTANCE = new AvaticaNoopResultSetMetaData();
-
-  public static AvaticaNoopResultSetMetaData getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopResultSetMetaData() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getColumnCount() throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean isAutoIncrement(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean isCaseSensitive(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean isSearchable(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean isCurrency(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public int isNullable(int column) throws SQLException {
-    return 0;
-  }
-
-  @Override public boolean isSigned(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public int getColumnDisplaySize(int column) throws SQLException {
-    return 0;
-  }
-
-  @Override public String getColumnLabel(int column) throws SQLException {
-    return "";
-  }
-
-  @Override public String getColumnName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getSchemaName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getPrecision(int column) throws SQLException {
-    return 0;
-  }
-
-  @Override public int getScale(int column) throws SQLException {
-    return 0;
-  }
-
-  @Override public String getTableName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public String getCatalogName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getColumnType(int column) throws SQLException {
-    return 0;
-  }
-
-  @Override public String getColumnTypeName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isReadOnly(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean isWritable(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public boolean isDefinitelyWritable(int column) throws SQLException {
-    return false;
-  }
-
-  @Override public String getColumnClassName(int column) throws SQLException {
-    throw unsupported();
-  }
-
-}
-
-// End AvaticaNoopResultSetMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
deleted file mode 100644
index 079cea4..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/AvaticaNoopStatement.java
+++ /dev/null
@@ -1,191 +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.noop;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-
-/**
- * A {@link Statement} implementation which does nothing.
- */
-public class AvaticaNoopStatement implements Statement {
-
-  private static final AvaticaNoopStatement INSTANCE = new AvaticaNoopStatement();
-
-  public static AvaticaNoopStatement getInstance() {
-    return INSTANCE;
-  }
-
-  private AvaticaNoopStatement() {}
-
-  private UnsupportedOperationException unsupported() {
-    return new UnsupportedOperationException("Unsupported");
-  }
-
-  @Override public ResultSet executeQuery(String sql) throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public int executeUpdate(String sql) throws SQLException {
-    return 1;
-  }
-
-  @Override public void close() throws SQLException {}
-
-  @Override public int getMaxFieldSize() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setMaxFieldSize(int max) throws SQLException {}
-
-  @Override public int getMaxRows() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setMaxRows(int max) throws SQLException {}
-
-  @Override public void setEscapeProcessing(boolean enable) throws SQLException {}
-
-  @Override public int getQueryTimeout() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setQueryTimeout(int seconds) throws SQLException {}
-
-  @Override public void cancel() throws SQLException {}
-
-  @Override public SQLWarning getWarnings() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void clearWarnings() throws SQLException {}
-
-  @Override public void setCursorName(String name) throws SQLException {}
-
-  @Override public boolean execute(String sql) throws SQLException {
-    return false;
-  }
-
-  @Override public ResultSet getResultSet() throws SQLException {
-    return AvaticaNoopResultSet.getInstance();
-  }
-
-  @Override public int getUpdateCount() throws SQLException {
-    return 1;
-  }
-
-  @Override public boolean getMoreResults() throws SQLException {
-    return false;
-  }
-
-  @Override public void setFetchDirection(int direction) throws SQLException {}
-
-  @Override public int getFetchDirection() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void setFetchSize(int rows) throws SQLException {}
-
-  @Override public int getFetchSize() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getResultSetConcurrency() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int getResultSetType() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public void addBatch(String sql) throws SQLException {}
-
-  @Override public void clearBatch() throws SQLException {}
-
-  @Override public int[] executeBatch() throws SQLException {
-    return new int[0];
-  }
-
-  @Override public Connection getConnection() throws SQLException {
-    return AvaticaNoopConnection.getInstance();
-  }
-
-  @Override public boolean getMoreResults(int current) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public ResultSet getGeneratedKeys() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-    return 1;
-  }
-
-  @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-    return 1;
-  }
-
-  @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-    return 1;
-  }
-
-  @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-    return true;
-  }
-
-  @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-    return true;
-  }
-
-  @Override public boolean execute(String sql, String[] columnNames) throws SQLException {
-    return true;
-  }
-
-  @Override public int getResultSetHoldability() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isClosed() throws SQLException {
-    return false;
-  }
-
-  @Override public void setPoolable(boolean poolable) throws SQLException {}
-
-  @Override public boolean isPoolable() throws SQLException {
-    return true;
-  }
-
-  @Override public void closeOnCompletion() throws SQLException {}
-
-  @Override public boolean isCloseOnCompletion() throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw unsupported();
-  }
-
-  @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw unsupported();
-  }
-}
-
-// End AvaticaNoopStatement.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
deleted file mode 100644
index 6ae1905..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/PackageMarker.java
+++ /dev/null
@@ -1,37 +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.noop;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This is a dummy annotation that forces javac to produce output for
- * otherwise empty package-info.java.
- *
- * <p>The result is maven-compiler-plugin can properly identify the scope of
- * changed files
- *
- * <p>See more details in
- * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
- *   maven-compiler-plugin: incremental compilation broken</a>
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface PackageMarker {
-}
-
-// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/package-info.java b/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/package-info.java
deleted file mode 100644
index da1c5c4..0000000
--- a/avatica-noop/src/main/java/org/apache/calcite/avatica/noop/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-
-/**
- * A no-operation implementation of a JDBC driver built for testing Avatica.
- */
-@PackageMarker
-package org.apache.calcite.avatica.noop;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-noop/src/main/resources/META-INF/services/java.sql.Driver
----------------------------------------------------------------------
diff --git a/avatica-noop/src/main/resources/META-INF/services/java.sql.Driver b/avatica-noop/src/main/resources/META-INF/services/java.sql.Driver
deleted file mode 100644
index 24845b0..0000000
--- a/avatica-noop/src/main/resources/META-INF/services/java.sql.Driver
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.calcite.avatica.noop.AvaticaNoopDriver

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/pom.xml
----------------------------------------------------------------------
diff --git a/avatica-server/pom.xml b/avatica-server/pom.xml
deleted file mode 100644
index 9a896f5..0000000
--- a/avatica-server/pom.xml
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>calcite-avatica-server</artifactId>
-  <packaging>jar</packaging>
-  <name>Calcite Avatica Server</name>
-  <description>JDBC server.</description>
-
-  <properties>
-    <top.dir>${project.basedir}/..</top.dir>
-  </properties>
-
-  <dependencies>
-    <!-- Sorted by groupId, artifactId; calcite dependencies first. Put versions
-         in dependencyManagement in the root POM, not here. -->
-    <dependency>
-      <groupId>org.apache.calcite</groupId>
-      <artifactId>calcite-avatica</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>javax.servlet-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-util</artifactId>
-    </dependency>
-
-    <!-- test dependencies -->
-    <dependency>
-      <groupId>org.apache.calcite</groupId>
-      <artifactId>calcite-avatica</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <!-- Used in RemoteDriverTest but dependency not detected by maven-dependency-plugin:2.8:analyze -->
-      <groupId>net.hydromatic</groupId>
-      <artifactId>scott-data-hsqldb</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <!-- Used in RemoteDriverTest but dependency not detected by maven-dependency-plugin:2.8:analyze -->
-      <groupId>org.hsqldb</groupId>
-      <artifactId>hsqldb</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.github.stephenc.jcip</groupId>
-      <artifactId>jcip-annotations</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <versionRange>[2.12.1,)</versionRange>
-                    <goals>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <!-- Parent module has the same plugin and does the work of
-           generating -sources.jar for each project. But without the
-           plugin declared here, IDEs don't know the sources are
-           available. -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-source-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-sources</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>jar-no-fork</goal>
-              <goal>test-jar-no-fork</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <version>${maven-dependency-plugin.version}</version>
-        <!-- configurations do not cascade, so all of the definition from
-             ../pom.xml:build:plugin-management:plugins:plugin must be repeated in child poms -->
-        <executions>
-          <execution>
-            <id>analyze</id>
-            <goals>
-              <goal>analyze-only</goal>
-            </goals>
-            <configuration>
-              <failOnWarning>true</failOnWarning>
-              <!-- ignore "unused but declared" warnings -->
-              <ignoredUnusedDeclaredDependencies>
-                <ignoredUnusedDeclaredDependency>io.dropwizard.metrics:metrics-core</ignoredUnusedDeclaredDependency>
-                <ignoredUnusedDeclaredDependency>net.hydromatic:scott-data-hsqldb</ignoredUnusedDeclaredDependency>
-                <ignoredUnusedDeclaredDependency>org.hsqldb:hsqldb</ignoredUnusedDeclaredDependency>
-                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
-                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
-              </ignoredUnusedDeclaredDependencies>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-remote-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>non-root-resources</id>
-            <goals>
-              <goal>process</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>


[58/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
[CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica


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

Branch: refs/heads/master
Commit: 65f2afa7add341c614cb59fb80f93da5e575e96a
Parents: 5cee486
Author: Josh Elser <el...@apache.org>
Authored: Fri Mar 4 00:40:43 2016 -0500
Committer: Josh Elser <el...@apache.org>
Committed: Mon Mar 7 10:50:09 2016 -0500

----------------------------------------------------------------------
 avatica/site/_config.yml                        |    4 +-
 avatica/site/_data/contributors.yml             |   96 -
 avatica/site/_data/docs.yml                     |   20 +-
 avatica/site/_docs/adapter.md                   |   38 -
 avatica/site/_docs/algebra.md                   |  369 ---
 avatica/site/_docs/avatica_json_reference.md    | 1086 ---------
 avatica/site/_docs/avatica_overview.md          |  130 -
 .../site/_docs/avatica_protobuf_reference.md    | 1181 ---------
 avatica/site/_docs/avatica_roadmap.md           |   51 -
 avatica/site/_docs/history.md                   | 2301 +-----------------
 avatica/site/_docs/index.md                     |  185 +-
 avatica/site/_docs/json_reference.md            | 1086 +++++++++
 avatica/site/_docs/lattice.md                   |  136 --
 avatica/site/_docs/model.md                     |  517 ----
 avatica/site/_docs/protobuf_reference.md        | 1181 +++++++++
 avatica/site/_docs/reference.md                 | 1248 ----------
 avatica/site/_docs/roadmap.md                   |   51 +
 avatica/site/_docs/stream.md                    | 1023 --------
 avatica/site/_docs/tutorial.md                  |  760 ------
 avatica/site/_includes/header.html              |    2 +-
 avatica/site/_includes/news_contents.html       |    2 +-
 .../2014-06-27-release-0.8.0-incubating.md      |   31 -
 .../2014-08-19-release-0.9.0-incubating.md      |   30 -
 .../2014-10-02-release-0.9.1-incubating.md      |   29 -
 .../2014-11-05-release-0.9.2-incubating.md      |   32 -
 .../2015-01-31-release-1.0.0-incubating.md      |   42 -
 .../2015-03-13-release-1.1.0-incubating.md      |   41 -
 .../2015-04-07-release-1.2.0-incubating.md      |   41 -
 .../site/_posts/2015-04-24-new-committers.md    |   34 -
 .../2015-05-30-release-1.3.0-incubating.md      |   33 -
 .../site/_posts/2015-06-05-algebra-builder.md   |   87 -
 .../2015-07-31-xldb-best-lightning-talk.md      |   41 -
 .../2015-09-02-release-1.4.0-incubating.md      |   39 -
 .../site/_posts/2015-10-22-calcite-graduates.md |   63 -
 .../site/_posts/2015-11-08-new-committers.md    |   31 -
 avatica/site/_posts/2015-11-10-release-1.5.0.md |   33 -
 avatica/site/_posts/2016-01-22-release-1.6.0.md |   59 -
 avatica/site/_posts/2016-02-17-elser-pmc.md     |   33 -
 .../_posts/2016-02-17-streaming-sql-talk.md     |   40 -
 .../site/_posts/2016-03-03-separate-project.md  |   32 +
 avatica/site/_posts/2016-03-03-tbd-release.md   |   30 +
 avatica/site/community/index.md                 |   48 +-
 avatica/site/develop/index.md                   |    5 +-
 avatica/site/doap_calcite.rdf                   |   59 -
 avatica/site/downloads/index.md                 |    8 +-
 avatica/site/index.html                         |   23 +-
 site/index.html                                 |    8 +
 47 files changed, 2493 insertions(+), 9926 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_config.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_config.yml b/avatica/site/_config.yml
index 9b8de85..c765da2 100644
--- a/avatica/site/_config.yml
+++ b/avatica/site/_config.yml
@@ -27,7 +27,7 @@ collections:
     output: true
 
 # The URL where the code can be found
-sourceRoot: https://github.com/apache/calcite/blob/master
+sourceRoot: https://github.com/apache/calcite/tree/master/avatica
 
 # The URL where Javadocs are located
 apiRoot: /apidocs
@@ -38,6 +38,6 @@ testApiRoot: /testapidocs
 # testApiRoot: http://calcite.apache.org/testapidocs
 
 # The base path where the website is deployed
-baseurl:
+baseurl: /avatica
 
 # End _config.yml

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_data/contributors.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_data/contributors.yml b/avatica/site/_data/contributors.yml
deleted file mode 100644
index 98f8bf9..0000000
--- a/avatica/site/_data/contributors.yml
+++ /dev/null
@@ -1,96 +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.
-#
-# Database of contributors to Apache Calcite.
-# Pages such as developer.md use this data.
-#
-- name: Alan Gates
-  apacheId: gates
-  githubId: alanfgates
-  org: Hortonworks
-  role: PMC
-- name: Aman Sinha
-  apacheId: amansinha
-  githubId: amansinha100
-  org: MapR
-  role: PMC
-- name: Ashutosh Chauhan
-  apacheId: hashutosh
-  githubId: ashutoshc
-  org: Hortonworks
-  role: PMC
-- name: James R. Taylor
-  apacheId: jamestaylor
-  githubId: JamesRTaylor
-  org: Salesforce
-  role: PMC
-- name: Jacques Nadeau
-  apacheId: jacques
-  githubId: jacques-n
-  org: Dremio
-  role: PMC
-- name: Jesús Camacho Rodríguez
-  apacheId: jcamacho
-  githubId: jcamachor
-  org: Hortonworks
-  role: PMC
-- name: Jinfeng Ni
-  apacheId: jni
-  githubId: jinfengni
-  org: MapR
-  role: PMC
-- name: John Pullokkaran
-  apacheId: jpullokk
-  githubId: jpullokkaran
-  org: Hortonworks
-  role: PMC
-- name: Josh Elser
-  apacheId: elserj
-  githubId: joshelser
-  org: Hortonworks
-  role: PMC
-- name: Julian Hyde
-  apacheId: jhyde
-  githubId: julianhyde
-  org: Hortonworks
-  role: PMC Chair
-  homepage: http://people.apache.org/~jhyde
-- name: Maryann Xue
-  apacheId: maryannxue
-  githubId: maryannxue
-  org: Intel
-  role: Committer
-- name: Nick Dimiduk
-  apacheId: ndimiduk
-  githubId: ndimiduk
-  org: Hortonworks
-  role: PMC
-- name: Steven Noels
-  apacheId: stevenn
-  githubId: stevenn
-  org: NGData
-  role: PMC
-- name: Ted Dunning
-  apacheId: tdunning
-  githubId: tdunning
-  org: MapR
-  role: PMC
-  avatar: https://www.mapr.com/sites/default/files/otherpageimages/ted-circle-80.png
-- name: Vladimir Sitnikov
-  apacheId: vladimirsitnikov
-  githubId: vlsi
-  org: NetCracker
-  role: PMC
-# End contributors.yml

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_data/docs.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_data/docs.yml b/avatica/site/_data/docs.yml
index a996097..8b1af11 100644
--- a/avatica/site/_data/docs.yml
+++ b/avatica/site/_data/docs.yml
@@ -18,26 +18,12 @@
 - title: Overview
   docs:
   - index
-  - tutorial
-  - algebra
-
-- title: Advanced
-  docs:
-  - adapter
-  - stream
-  - lattice
-
-- title: Avatica
-  docs:
-  - avatica_overview
-  - avatica_roadmap
-  - avatica_json_reference
-  - avatica_protobuf_reference
+  - roadmap
 
 - title: Reference
   docs:
-  - reference
-  - model
+  - json_reference
+  - protobuf_reference
   - howto
 
 - title: Meta

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/adapter.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/adapter.md b/avatica/site/_docs/adapter.md
deleted file mode 100644
index fa8eb21..0000000
--- a/avatica/site/_docs/adapter.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-layout: docs
-title: Adapters
-permalink: /docs/adapter.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-* <a href="https://github.com/apache/drill">Apache Drill adapter</a>
-* Cascading adapter (<a href="https://github.com/Cascading/lingual">Lingual</a>)
-* Cassandra adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/cassandra/package-summary.html">calcite-cassandra</a>)
-* CSV adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/csv/package-summary.html">example/csv</a>)
-* JDBC adapter (part of <a href="{{ site.apiRoot }}/org/apache/calcite/adapter/jdbc/package-summary.html">calcite-core</a>)
-* MongoDB adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/mongodb/package-summary.html">calcite-mongodb</a>)
-* Spark adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/spark/package-summary.html">calcite-spark</a>)
-* Splunk adapter (<a href="{{ site.apiRoot }}/org/apache/calcite/adapter/splunk/package-summary.html">calcite-splunk</a>)
-* Eclipse Memory Analyzer (MAT) adapter (<a href="https://github.com/vlsi/mat-calcite-plugin">mat-calcite-plugin</a>)
-
-## Drivers
-
-* <a href="{{ site.apiRoot }}/org/apache/calcite/jdbc/package-summary.html">JDBC driver</a>
-

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/algebra.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/algebra.md b/avatica/site/_docs/algebra.md
deleted file mode 100644
index e651dd0..0000000
--- a/avatica/site/_docs/algebra.md
+++ /dev/null
@@ -1,369 +0,0 @@
----
-layout: docs
-title: Algebra
-permalink: /docs/algebra.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Relational algebra is at the heart of Calcite. Every query is
-represented as a tree of relational operators. You can translate from
-SQL to relational algebra, or you can build the tree directly.
-
-Planner rules transform expression trees using mathematical identities
-that preserve semantics. For example, it is valid to push a filter
-into an input of an inner join if the filter does not reference
-columns from the other input.
-
-Calcite optimizes queries by repeatedly applying planner rules to a
-relational expression. A cost model guides the process, and the
-planner engine generates an alternative expression that has the same
-semantics as the original but a lower cost.
-
-The planning process is extensible. You can add your own relational
-operators, planner rules, cost model, and statistics.
-
-## Algebra builder
-
-The simplest way to build a relational expression is to use the algebra builder,
-[RelBuilder]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html).
-Here is an example:
-
-### TableScan
-
-{% highlight java %}
-final FrameworkConfig config;
-final RelBuilder builder = RelBuilder.create(config);
-final RelNode node = builder
-  .scan("EMP")
-  .build();
-System.out.println(RelOptUtil.toString(node));
-{% endhighlight %}
-
-(You can find the full code for this and other examples in
-[RelBuilderExample.java]({{ site.sourceRoot }}/core/src/test/java/org/apache/calcite/examples/RelBuilderExample.java).)
-
-The code prints
-
-{% highlight text %}
-LogicalTableScan(table=[[scott, EMP]])
-{% endhighlight %}
-
-It has created a scan of the `EMP` table; equivalent to the SQL
-
-{% highlight sql %}
-SELECT *
-FROM scott.EMP;
-{% endhighlight %}
-
-### Adding a Project
-
-Now, let's add a Project, the equivalent of
-
-{% highlight sql %}
-SELECT ename, deptno
-FROM scott.EMP;
-{% endhighlight %}
-
-We just add a call to the `project` method before calling
-`build`:
-
-{% highlight java %}
-final RelNode node = builder
-  .scan("EMP")
-  .project(builder.field("DEPTNO"), builder.field("ENAME"))
-  .build();
-System.out.println(RelOptUtil.toString(node));
-{% endhighlight %}
-
-and the output is
-
-{% highlight text %}
-LogicalProject(DEPTNO=[$7], ENAME=[$1])
-  LogicalTableScan(table=[[scott, EMP]])
-{% endhighlight %}
-
-The two calls to `builder.field` create simple expressions
-that return the fields from the input relational expression,
-namely the TableScan created by the `scan` call.
-
-Calcite has converted them to field references by ordinal,
-`$7` and `$1`.
-
-### Adding a Filter and Aggregate
-
-A query with an Aggregate, and a Filter:
-
-{% highlight java %}
-final RelNode node = builder
-  .scan("EMP")
-  .aggregate(builder.groupKey("DEPTNO"),
-      builder.count(false, "C"),
-      builder.sum(false, "S", builder.field("SAL")))
-  .filter(
-      builder.call(SqlStdOperatorTable.GREATER_THAN,
-          builder.field("C"),
-          builder.literal(10)))
-  .build();
-System.out.println(RelOptUtil.toString(node));
-{% endhighlight %}
-
-is equivalent to SQL
-
-{% highlight sql %}
-SELECT deptno, count(*) AS c, sum(sal) AS s
-FROM emp
-GROUP BY deptno
-HAVING count(*) > 10
-{% endhighlight %}
-
-and produces
-
-{% highlight text %}
-LogicalFilter(condition=[>($1, 10)])
-  LogicalAggregate(group=[{7}], C=[COUNT()], S=[SUM($5)])
-    LogicalTableScan(table=[[scott, EMP]])
-{% endhighlight %}
-
-### Push and pop
-
-The builder uses a stack to store the relational expression produced by
-one step and pass it as an input to the next step. This allows the
-methods that produce relational expressions to produce a builder.
-
-Most of the time, the only stack method you will use is `build()`, to get the
-last relational expression, namely the root of the tree.
-
-Sometimes the stack becomes so deeply nested it gets confusing. To keep things
-straight, you can remove expressions from the stack. For example, here we are
-building a bushy join:
-
-{% highlight text %}
-.
-               join
-             /      \
-        join          join
-      /      \      /      \
-CUSTOMERS ORDERS LINE_ITEMS PRODUCTS
-{% endhighlight %}
-
-We build it in three stages. Store the intermediate results in variables
-`left` and `right`, and use `push()` to put them back on the stack when it is
-time to create the final `Join`:
-
-{% highlight java %}
-final RelNode left = builder
-  .scan("CUSTOMERS")
-  .scan("ORDERS")
-  .join(JoinRelType.INNER, "ORDER_ID")
-  .build();
-
-final RelNode right = builder
-  .scan("LINE_ITEMS")
-  .scan("PRODUCTS")
-  .join(JoinRelType.INNER, "PRODUCT_ID")
-  .build();
-
-final RelNode result = builder
-  .push(left)
-  .push(right)
-  .join(JoinRelType.INNER, "ORDER_ID")
-  .build();
-{% endhighlight %}
-
-### Field names and ordinals
-
-You can reference a field by name or ordinal.
-
-Ordinals are zero-based. Each operator guarantees the order in which its output
-fields occur. For example, `Project` returns the fields in the generated by
-each of the scalar expressions.
-
-The field names of an operator are guaranteed to be unique, but sometimes that
-means that the names are not exactly what you expect. For example, when you
-join EMP to DEPT, one of the output fields will be called DEPTNO and another
-will be called something like DEPTNO_1.
-
-Some relational expression methods give you more control over field names:
-
-* `project` lets you wrap expressions using `alias(expr, fieldName)`. It
-  removes the wrapper but keeps the suggested name (as long as it is unique).
-* `values(String[] fieldNames, Object... values)` accepts an array of field
-  names. If any element of the array is null, the builder will generate a unique
-  name.
-
-If an expression projects an input field, or a cast of an input field, it will
-use the name of that input field.
-
-Once the unique field names have been assigned, the names are immutable.
-If you have a particular `RelNode` instance, you can rely on the field names not
-changing. In fact, the whole relational expression is immutable.
-
-But if a relational expression has passed through several rewrite rules (see
-([RelOptRule]({{ site.apiRoot }}/org/apache/calcite/plan/RelOptRule.html)), the field
-names of the resulting expression might not look much like the originals.
-At that point it is better to reference fields by ordinal.
-
-When you are building a relational expression that accepts multiple inputs,
-you need to build field references that take that into account. This occurs
-most often when building join conditions.
-
-Suppose you are building a join on EMP,
-which has 8 fields [EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO]
-and DEPT,
-which has 3 fields [DEPTNO, DNAME, LOC].
-Internally, Calcite represents those fields as offsets into
-a combined input row with 11 fields: the first field of the left input is
-field #0 (0-based, remember), and the first field of the right input is
-field #8.
-
-But through the builder API, you specify which field of which input.
-To reference "SAL", internal field #5,
-write `builder.field(2, 0, "SAL")`
-or `builder.field(2, 0, 5)`.
-This means "the field #5 of input #0 of two inputs".
-(Why does it need to know that there are two inputs? Because they are stored on
-the stack; input #1 is at the top of the stack, and input #0 is below it.
-If we did not tell the builder that were two inputs, it would not know how deep
-to go for input #0.)
-
-Similarly, to reference "DNAME", internal field #9 (8 + 1),
-write `builder.field(2, 1, "DNAME")`
-or `builder.field(2, 1, 1)`.
-
-### API summary
-
-#### Relational operators
-
-The following methods create a relational expression
-([RelNode]({{ site.apiRoot }}/org/apache/calcite/rel/RelNode.html)),
-push it onto the stack, and
-return the `RelBuilder`.
-
-| Method              | Description
-|:------------------- |:-----------
-| `scan(tableName)` | Creates a [TableScan]({{ site.apiRoot }}/org/apache/calcite/rel/core/TableScan.html).
-| `values(fieldNames, value...)`<br/>`values(rowType, tupleList)` | Creates a [Values]({{ site.apiRoot }}/org/apache/calcite/rel/core/Values.html).
-| `filter(expr...)`<br/>`filter(exprList)` | Creates a [Filter]({{ site.apiRoot }}/org/apache/calcite/rel/core/Filter.html) over the AND of the given predicates.
-| `project(expr...)`<br/>`project(exprList [, fieldNames])` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html). To override the default name, wrap expressions using `alias`, or specify the `fieldNames` argument.
-| `permute(mapping)` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html) that permutes the fields using `mapping`.
-| `convert(rowType [, rename])` | Creates a [Project]({{ site.apiRoot }}/org/apache/calcite/rel/core/Project.html) that converts the fields to the given types, optionally also renaming them.
-| `aggregate(groupKey, aggCall...)`<br/>`aggregate(groupKey, aggCallList)` | Creates an [Aggregate]({{ site.apiRoot }}/org/apache/calcite/rel/core/Aggregate.html).
-| `distinct()` | Creates an [Aggregate]({{ site.apiRoot }}/org/apache/calcite/rel/core/Aggregate.html) that eliminates duplicate records.
-| `sort(fieldOrdinal...)`<br/>`sort(expr...)`<br/>`sort(exprList)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html).<br/><br/>In the first form, field ordinals are 0-based, and a negative ordinal indicates descending; for example, -2 means field 1 descending.<br/><br/>In the other forms, you can wrap expressions in `as`, `nullsFirst` or `nullsLast`.
-| `sortLimit(offset, fetch, expr...)`<br/>`sortLimit(offset, fetch, exprList)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html) with offset and limit.
-| `limit(offset, fetch)` | Creates a [Sort]({{ site.apiRoot }}/org/apache/calcite/rel/core/Sort.html) that does not sort, only applies with offset and limit.
-| `join(joinType, expr...)`<br/>`join(joinType, exprList)`<br/>`join(joinType, fieldName...)` | Creates a [Join]({{ site.apiRoot }}/org/apache/calcite/rel/core/Join.html) of the two most recent relational expressions.<br/><br/>The first form joins on a boolean expression (multiple conditions are combined using AND).<br/><br/>The last form joins on named fields; each side must have a field of each name.
-| `semiJoin(expr)` | Creates a [SemiJoin]({{ site.apiRoot }}/org/apache/calcite/rel/core/SemiJoin.html) of the two most recent relational expressions.
-| `union(all [, n])` | Creates a [Union]({{ site.apiRoot }}/org/apache/calcite/rel/core/Union.html) of the `n` (default two) most recent relational expressions.
-| `intersect(all [, n])` | Creates an [Intersect]({{ site.apiRoot }}/org/apache/calcite/rel/core/Intersect.html) of the `n` (default two) most recent relational expressions.
-| `minus(all)` | Creates a [Minus]({{ site.apiRoot }}/org/apache/calcite/rel/core/Minus.html) of the two most recent relational expressions.
-
-Argument types:
-
-* `expr`  [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
-* `expr...` Array of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
-* `exprList` Iterable of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
-* `fieldOrdinal` Ordinal of a field within its row (starting from 0)
-* `fieldName` Name of a field, unique within its row
-* `fieldName...` Array of String
-* `fieldNames` Iterable of String
-* `rowType` [RelDataType]({{ site.apiRoot }}/org/apache/calcite/rel/type/RelDataType.html)
-* `groupKey` [RelBuilder.GroupKey]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.GroupKey.html)
-* `aggCall...` Array of [RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html)
-* `aggCallList` Iterable of [RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html)
-* `value...` Array of Object
-* `value` Object
-* `tupleList` Iterable of List of [RexLiteral]({{ site.apiRoot }}/org/apache/calcite/rex/RexLiteral.html)
-* `all` boolean
-* `distinct` boolean
-* `alias` String
-
-The builder methods perform various optimizations, including:
-* `project` returns its input if asked to project all columns in order
-* `filter` flattens the condition (so an `AND` and `OR` may have more than 2 children),
-  simplifies (converting say `x = 1 AND TRUE` to `x = 1`)
-* If you apply `sort` then `limit`, the effect is as if you had called `sortLimit`
-
-### Stack methods
-
-
-| Method              | Description
-|:------------------- |:-----------
-| `build()`           | Pops the most recently created relational expression off the stack
-| `push(rel)`         | Pushes a relational expression onto the stack. Relational methods such as `scan`, above, call this method, but user code generally does not
-| `pushAll(collection)` | Pushes a collection of relational expressions onto the stack
-| `peek()`            | Returns the relational expression most recently put onto the stack, but does not remove it
-
-#### Scalar expression methods
-
-The following methods return a scalar expression
-([RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)).
-
-Many of them use the contents of the stack. For example, `field("DEPTNO")`
-returns a reference to the "DEPTNO" field of the relational expression just
-added to the stack.
-
-| Method              | Description
-|:------------------- |:-----------
-| `literal(value)` | Constant
-| `field(fieldName)` | Reference, by name, to a field of the top-most relational expression
-| `field(fieldOrdinal)` | Reference, by ordinal, to a field of the top-most relational expression
-| `field(inputCount, inputOrdinal, fieldName)` | Reference, by name, to a field of the (`inputCount` - `inputOrdinal`)th relational expression
-| `field(inputCount, inputOrdinal, fieldOrdinal)` | Reference, by ordinal, to a field of the (`inputCount` - `inputOrdinal`)th relational expression
-| `fields(fieldOrdinalList)` | List of expressions referencing input fields by ordinal
-| `fields(mapping)` | List of expressions referencing input fields by a given mapping
-| `fields(collation)` | List of expressions, `exprList`, such that `sort(exprList)` would replicate collation
-| `call(op, expr...)`<br/>`call(op, exprList)` | Call to a function or operator
-| `and(expr...)`<br/>`and(exprList)` | Logical AND. Flattens nested ANDs, and optimizes cases involving TRUE and FALSE.
-| `or(expr...)`<br/>`or(exprList)` | Logical OR. Flattens nested ORs, and optimizes cases involving TRUE and FALSE.
-| `not(expr)` | Logical NOT
-| `equals(expr, expr)` | Equals
-| `isNull(expr)` | Checks whether an expression is null
-| `isNotNull(expr)` | Checks whether an expression is not null
-| `alias(expr, fieldName)` | Renames an expression (only valid as an argument to `project`)
-| `cast(expr, typeName)`<br/>`cast(expr, typeName, precision)`<br/>`cast(expr, typeName, precision, scale)`<br/> | Converts an expression to a given type
-| `desc(expr)` | Changes sort direction to descending (only valid as an argument to `sort` or `sortLimit`)
-| `nullsFirst(expr)` | Changes sort order to nulls first (only valid as an argument to `sort` or `sortLimit`)
-| `nullsLast(expr)` | Changes sort order to nulls last (only valid as an argument to `sort` or `sortLimit`)
-
-### Group key methods
-
-The following methods return a
-[RelBuilder.GroupKey]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.GroupKey.html).
-
-| Method              | Description
-|:------------------- |:-----------
-| `groupKey(fieldName...)`<br/>`groupKey(fieldOrdinal...)`<br/>`groupKey(expr...)`<br/>`groupKey(exprList)` | Creates a group key of the given expressions
-| `groupKey(exprList, exprListList)` | Creates a group key of the given expressions with grouping sets
-| `groupKey(bitSet, bitSets)` | Creates a group key of the given input columns with grouping sets
-
-### Aggregate call methods
-
-The following methods return an
-[RelBuilder.AggCall]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.AggCall.html).
-
-| Method              | Description
-|:------------------- |:-----------
-| `aggregateCall(op, distinct, filter, alias, expr...)`<br/>`aggregateCall(op, distinct, filter, alias, exprList)` | Creates a call to a given aggregate function, with an optional filter expression
-| `count(distinct, alias, expr...)` | Creates a call to the COUNT aggregate function
-| `countStar(alias)` | Creates a call to the COUNT(*) aggregate function
-| `sum(distinct, alias, expr)` | Creates a call to the SUM aggregate function
-| `min(alias, expr)` | Creates a call to the MIN aggregate function
-| `max(alias, expr)` | Creates a call to the MAX aggregate function

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/avatica_json_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_json_reference.md b/avatica/site/_docs/avatica_json_reference.md
deleted file mode 100644
index d49be7c..0000000
--- a/avatica/site/_docs/avatica_json_reference.md
+++ /dev/null
@@ -1,1086 +0,0 @@
----
-layout: docs
-title: Avatica JSON Reference
-sidebar_title: JSON Reference
-permalink: /docs/avatica_json_reference.html
-requests:
-  - { name: "CatalogsRequest" }
-  - { name: "CloseConnectionRequest" }
-  - { name: "CloseStatementRequest" }
-  - { name: "ColumnsRequest" }
-  - { name: "CommitRequest" }
-  - { name: "ConnectionSyncRequest" }
-  - { name: "CreateStatementRequest" }
-  - { name: "DatabasePropertyRequest" }
-  - { name: "ExecuteRequest" }
-  - { name: "FetchRequest" }
-  - { name: "OpenConnectionRequest" }
-  - { name: "PrepareAndExecuteRequest" }
-  - { name: "PrepareRequest" }
-  - { name: "RollbackRequest" }
-  - { name: "SchemasRequest" }
-  - { name: "SyncResultsRequest" }
-  - { name: "TableTypesRequest" }
-  - { name: "TablesRequest" }
-  - { name: "TypeInfoRequest" }
-miscellaneous:
-  - { name: "AvaticaParameter" }
-  - { name: "AvaticaSeverity" }
-  - { name: "AvaticaType" }
-  - { name: "ColumnMetaData" }
-  - { name: "ConnectionProperties" }
-  - { name: "CursorFactory" }
-  - { name: "DatabaseProperty" }
-  - { name: "Frame" }
-  - { name: "QueryState" }
-  - { name: "Rep" }
-  - { name: "RpcMetadata" }
-  - { name: "Signature" }
-  - { name: "StateType" }
-  - { name: "StatementHandle" }
-  - { name: "StatementType" }
-  - { name: "Style" }
-  - { name: "TypedValue" }
-responses:
-  - { name: "CloseConnectionResponse" }
-  - { name: "CloseStatementResponse" }
-  - { name: "CommitResponse" }
-  - { name: "ConnectionSyncResponse" }
-  - { name: "CreateStatementResponse" }
-  - { name: "DatabasePropertyResponse" }
-  - { name: "ErrorResponse" }
-  - { name: "ExecuteResponse" }
-  - { name: "FetchResponse" }
-  - { name: "OpenConnectionResponse" }
-  - { name: "PrepareResponse" }
-  - { name: "ResultSetResponse" }
-  - { name: "RollbackResponse" }
-  - { name: "SyncResultsResponse" }
----
-
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-As Avatica uses JSON to serialize messages sent over an HTTP transport,
-the RPC layer is agnostic of the language used by a client. While the Avatica
-server is written in Java, this enables clients to interact with the server
-using any language instead of being limited to Java.
-
-A specification of the JSON request and response objects are documented
-below. Programmatic bindings for these JSON objects are only available
-in Java. For support outside of Java, see the Protocol Buffer
-[bindings]({{ site.baseurl }}/docs/avatica_protobuf_reference.html)
-
-## Index
-
-### Requests
-<ul>
-  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-### Responses
-<ul>
-  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-### Miscellaneous
-<ul>
-  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
-</ul>
-
-
-## Requests
-
-The collection of all JSON objects accepted as requests to Avatica. All Requests include a `request` attribute
-which uniquely identifies the concrete Request from all other Requests.
-
-### CatalogsRequest
-
-This request is used to fetch the available catalog names in the database.
-
-{% highlight json %}
-{
-  "request": "getCatalogs",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to use.
-
-### CloseConnectionRequest
-
-This request is used to close the Connection object in the Avatica server identified by the given IDs.
-
-{% highlight json %}
-{
-  "request": "closeConnection",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to close.
-
-### CloseStatementRequest
-
-This request is used to close the Statement object in the Avatica server identified by the given IDs.
-
-{% highlight json %}
-{
-  "request": "closeStatement",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to which the statement belongs.
-
-`statementId` (required integer) The identifier of the statement to close.
-
-### ColumnsRequest
-
-This request is used to fetch columns in the database given some optional filtering criteria.
-
-{% highlight json %}
-{
-  "request": "getColumns",
-  "connectionId": "000000-0000-0000-00000000",
-  "catalog": "catalog",
-  "schemaPattern": "schema_pattern.*",
-  "tableNamePattern": "table_pattern.*",
-  "columnNamePattern": "column_pattern.*"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection on which to fetch the columns.
-
-`catalog` (optional string) The name of a catalog to limit returned columns.
-
-`schemaPattern` (optional string) A Java Pattern against schemas to limit returned columns.
-
-`tableNamePattern` (optional string) A Java Pattern against table names to limit returned columns.
-
-`columnNamePattern` (optional string) A Java Pattern against column names to limit returned columns.
-
-### CommitRequest
-
-This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
-
-{% highlight json %}
-{
-  "request": "commit",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection on which to invoke commit.
-
-### ConnectionSyncRequest
-
-This request is used to ensure that the client and server have a consistent view of the database properties.
-
-{% highlight json %}
-{
-  "request": "connectionSync",
-  "connectionId": "000000-0000-0000-00000000",
-  "connProps": ConnectionProperties
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to synchronize.
-
-`connProps` (optional nested object) A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
-
-### CreateStatementRequest
-
-This request is used to create a new Statement in the Avatica server.
-
-{% highlight json %}
-{
-  "request": "createStatement",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to use in creating a statement.
-
-### DatabasePropertyRequest
-
-This request is used to fetch all <a href="#databaseproperty">database properties</a>.
-
-{% highlight json %}
-{
-  "request": "databaseProperties",
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to use when fetching the database properties.
-
-### ExecuteRequest
-
-This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
-
-{% highlight json %}
-{
-  "request": "execute",
-  "statementHandle": StatementHandle,
-  "parameterValues": [TypedValue, TypedValue, ... ],
-  "maxRowCount": 100
-}
-{% endhighlight %}
-
-`statementHandle` (required object) A <a href="#statementhandle">StatementHandle</a> object.
-
-`parameterValues` (optional array of nested objects) The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
-
-`maxRowCount` (required long) The maximum number of rows returned in the response.
-
-### FetchRequest
-
-This request is used to fetch a batch of rows from a Statement previously created.
-
-{% highlight json %}
-{
-  "request": "fetch",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345,
-  "offset": 0,
-  "fetchMaxRowCount": 100
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to use.
-
-`statementId` (required integer) The identifier of the statement created using the above connection.
-
-`offset` (required integer) The positional offset into a result set to fetch.
-
-`fetchMatchRowCount` (required integer) The maximum number of rows to return in the response to this request.
-
-### OpenConnectionRequest
-
-This request is used to open a new Connection in the Avatica server.
-
-{% highlight json %}
-{
-  "request": "openConnection",
-  "connectionId": "000000-0000-0000-00000000",
-  "info": {"key":"value", ...}
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier of the connection to open in the server.
-
-`info` (optional string-to-string map) A Map containing properties to include when creating the Connection.
-
-### PrepareAndExecuteRequest
-
-This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
-
-{% highlight json %}
-{
-  "request": "prepareAndExecute",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345,
-  "sql": "SELECT * FROM table",
-  "maxRowCount": 100,
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier for the connection to use.
-
-`statementId` (required integer) The identifier for the statement created by the above connection to use.
-
-`sql` (required string) A SQL statement
-
-`maxRowCount` (required long) The maximum number of rows returned in the response.
-
-### PrepareRequest
-
-This request is used to create create a new Statement with the given query in the Avatica server.
-
-{% highlight json %}
-{
-  "request": "prepare",
-  "connectionId": "000000-0000-0000-00000000",
-  "sql": "SELECT * FROM table",
-  "maxRowCount": 100,
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier for the connection to use.
-
-`sql` (required string) A SQL statement
-
-`maxRowCount` (required long) The maximum number of rows returned in the response.
-
-### SyncResultsRequest
-
-This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
-
-{% highlight json %}
-{
-  "request": "syncResults",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345,
-  "state": QueryState,
-  "offset": 200
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier for the connection to use.
-
-`statementId` (required integer) The identifier for the statement to use.
-
-`state` (required object) The <a href="#querystate">QueryState</a> object.
-
-`offset` (required long) The offset into the ResultSet to seek to.
-
-### RollbackRequest
-
-This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
-
-{% highlight json %}
-{
-  "request": "rollback",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` (required string) The identifier for the connection on which to invoke rollback.
-
-### SchemasRequest
-
-This request is used to fetch the schemas matching the provided criteria in the database.
-
-{% highlight json %}
-{
-  "request": "getSchemas",
-  "connectionId": "000000-0000-0000-00000000",
-  "catalog": "name",
-  "schemaPattern": "pattern.*"
-}
-{% endhighlight %}
-
-`connection_id` The identifier for the connection to fetch schemas from.
-
-`catalog` (required string) The name of the catalog to fetch the schema from.
-
-`schemaPattern` (required string) A Java pattern of schemas to fetch.
-
-### TableTypesRequest
-
-This request is used to fetch the table types available in this database.
-
-{% highlight json %}
-{
-  "request": "getTableTypes",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` The identifier of the connection to fetch the table types from.
-
-### TablesRequest
-
-This request is used to fetch the tables available in this database filtered by the provided criteria.
-
-{% highlight json %}
-{
-  "request": "getTables",
-  "connectionId": "000000-0000-0000-00000000",
-  "catalog": "catalog_name",
-  "schemaPattern": "schema_pattern.*",
-  "tableNamePattern": "table_name_pattern.*",
-  "typeList": [ "TABLE", "VIEW", ... ]
-}
-{% endhighlight %}
-
-`catalog` (optional string) The name of a catalog to restrict fetched tables.
-
-`connectionId` The identifier of the connection to fetch the tables from.
-
-`schemaPattern` (optional string) A Java Pattern representing schemas to include in fetched tables.
-
-`tableNamePattern` (optional string) A Java Pattern representing table names to include in fetched tables.
-
-`typeList` (optional array of string) A list of table types used to restrict fetched tables.
-
-### TypeInfoRequest
-
-This request is used to fetch the types available in this database.
-
-{% highlight json %}
-{
-  "request": "getTypeInfo",
-  "connectionId": "000000-0000-0000-00000000"
-}
-{% endhighlight %}
-
-`connectionId` The identifier of the connection to fetch the types from.
-
-## Responses
-
-The collection of all JSON objects returned as responses from Avatica. All Responses include a `response` attribute
-which uniquely identifies the concrete Response from all other Responses.
-
-### CloseConnectionResponse
-
-A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
-
-{% highlight json %}
-{
-  "response": "closeConnection",
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CloseStatementResponse
-
-A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
-
-{% highlight json %}
-{
-  "response": "closeStatement",
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CommitResponse
-
-A response to the <a href="#commitrequest">CommitRequest</a>.
-
-{% highlight json %}
-{
-  "response": "commit"
-}
-{% endhighlight %}
-
-There are no extra attributes on this Response.
-
-### ConnectionSyncResponse
-
-A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
-response are those of the Connection in the Avatica server.
-
-{% highlight json %}
-{
-  "response": "connectionSync",
-  "connProps": ConnectionProperties,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`connProps` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### CreateStatementResponse
-
-A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
-that was created is included in the response. Clients will use this `statementId` in subsequent calls.
-
-{% highlight json %}
-{
-  "response": "createStatement",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`connectionId` The identifier for the connection used to create the statement.
-
-`statementId` The identifier for the created statement.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### DatabasePropertyResponse
-
-A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
-for information on the available property keys.
-
-{% highlight json %}
-{
-  "response": "databaseProperties",
-  "map": { DatabaseProperty: Object, DatabaseProperty: Object, ... },
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`map` A map of <a href="#databaseproperty">DatabaseProperty</a> to value of that property. The value may be some
-primitive type or an array of primitive types.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ErrorResponse
-
-A response when an error was caught executing a request. Any request may return this response.
-
-{% highlight json %}
-{
-  "response": "error",
-  "exceptions": [ "stacktrace", "stacktrace", ... ],
-  "errorMessage": "The error message",
-  "errorCode": 42,
-  "sqlState": "ABC12",
-  "severity": AvaticaSeverity,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`exceptions` A list of stringified Java StackTraces.
-
-`errorMessage` A human-readable error message.
-
-`errorCode` A numeric code for this error.
-
-`sqlState` A five character alphanumeric code for this error.
-
-`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ExecuteResponse
-
-A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
-
-{% highlight json %}
-{
-  "response": "executeResults",
-  "resultSets": [ ResultSetResponse, ResultSetResponse, ... ],
-  "missingStatement": false,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`resultSets` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
-
-`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### FetchResponse
-
-A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
-
-{% highlight json %}
-{
-  "response": "fetch",
-  "frame": Frame,
-  "missingStatement": false,
-  "missingResults": false,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
-
-`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
-
-`missingResults` A boolean which denotes if the request failed due to a missing ResultSet.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### OpenConnectionResponse
-
-A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
-the client should use in subsequent calls was provided by the client in the request.
-
-{% highlight json %}
-{
-  "response": "openConnection",
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### PrepareResponse
-
-A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
-which clients must use to fetch the results from the Statement.
-
-{% highlight json %}
-{
-  "response": "prepare",
-  "statement": StatementHandle,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`statement` A <a href="#statementhandle">StatementHandle</a> object.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### ResultSetResponse
-
-A response which contains the results and type details from a query.
-
-{% highlight json %}
-{
-  "response": "resultSet",
-  "connectionId": "000000-0000-0000-00000000",
-  "statementId": 12345,
-  "ownStatement": true,
-  "signature": Signature,
-  "firstFrame": Frame,
-  "updateCount": 10,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`connectionId` The identifier for the connection used to generate this response.
-
-`statementId` The identifier for the statement used to generate this response.
-
-`ownStatement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
-statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
-
-`signature` A non-optional nested object <a href="#signature">Signature</a>
-
-`firstFrame` A optional nested object <a href="#frame">Frame</a>
-
-`updateCount` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
-that only contains this count and no additional data.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-### RollbackResponse
-
-A response to the <a href="#rollbackrequest">RollBackRequest</a>.
-
-{% highlight json %}
-{
-  "response": "rollback"
-}
-{% endhighlight %}
-
-There are no extra attributes on this Response.
-
-### SyncResultsResponse
-
-A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
-should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
-or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
-
-{% highlight json %}
-{
-  "response": "syncResults",
-  "moreResults": true,
-  "missingStatement": false,
-  "rpcMetadata": RpcMetadata
-}
-{% endhighlight %}
-
-`moreResults` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
-
-`missingStatement` A boolean which denotes if the statement for the ResultSet still exists.
-
-`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
-
-## Miscellaneous
-
-### AvaticaParameter
-
-This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
-complex types such as arrays.
-
-{% highlight json %}
-{
-  "signed": true,
-  "precision": 10,
-  "scale": 2,
-  "parameterType": 8,
-  "typeName": "integer",
-  "className": "java.lang.Integer",
-  "name": "number"
-}
-{% endhighlight %}
-
-`signed` A boolean denoting whether the column is a signed numeric.
-
-`precision` The maximum numeric precision supported by this column.
-
-`scale` The maximum numeric scale supported by this column.
-
-`parameterType` An integer corresponding to the JDBC Types class denoting the column's type.
-
-`typeName` The JDBC type name for this column.
-
-`className` The Java class backing the JDBC type for this column.
-
-`name` The name of the column.
-
-### AvaticaSeverity
-
-This enumeration describes the various levels of concern for an error in the Avatica server.
-
-One of:
-
-* `UNKNOWN`
-* `FATAL`
-* `ERROR`
-* `WARNING`
-
-### AvaticaType
-
-This object describes a simple or complex type for a column. Complex types will contain
-additional information in the `component` or `columns` attribute which describe the nested
-types of the complex parent type.
-
-{% highlight json %}
-{
-  "type": "scalar",
-  "id": "identifier",
-  "name": "column",
-  "rep": Rep,
-  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
-  "component": AvaticaType
-}
-{% endhighlight %}
-
-`type` One of: `scalar`, `array`, `struct`.
-
-`id` A numeric value corresponding to the type of the object per the JDBC Types class.
-
-`name` The readable name of the JDBC type.
-
-`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
-
-`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
-
-`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
-
-### ColumnMetaData
-
-This object represents the JDBC ResultSetMetaData for a column.
-
-{% highlight json %}
-{
-  "ordinal": 0,
-  "autoIncrement": true,
-  "caseSensitive": true,
-  "searchable": false,
-  "currency": false,
-  "nullable": 0,
-  "signed": true,
-  "displaySize": 20,
-  "label": "Description",
-  "columnName": "col1",
-  "schemaName": "schema",
-  "precision": 10,
-  "scale": 2,
-  "tableName": "table",
-  "catalogName": "catalog",
-  "type": AvaticaType,
-  "readOnly": false,
-  "writable": true,
-  "definitelyWritable": true,
-  "columnClassName": "java.lang.String"
-}
-{% endhighlight %}
-
-`ordinal` A positional offset number.
-
-`autoIncrement` A boolean denoting whether the column is automatically incremented.
-
-`caseSensitive` A boolean denoting whether the column is case sensitive.
-
-`searchable` A boolean denoting whether this column supports all WHERE search clauses.
-
-`currency` A boolean denoting whether this column represents currency.
-
-`nullable` A number denoting whether this column supports null values.
-
-* 0 = No null values are allowed
-* 1 = Null values are allowed
-* 2 = It is unknown if null values are allowed
-
-`signed` A boolean denoting whether the column is a signed numeric.
-
-`displaySize` The character width of the column.
-
-`label` A description for this column.
-
-`columnName` The name of the column.
-
-`schemaName` The schema to which this column belongs.
-
-`precision` The maximum numeric precision supported by this column.
-
-`scale` The maximum numeric scale supported by this column.
-
-`tableName` The name of the table to which this column belongs.
-
-`catalogName` The name of the catalog to which this column belongs.
-
-`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
-
-`readOnly` A boolean denoting whether the column is read-only.
-
-`writable` A boolean denoting whether the column is possible to be updated.
-
-`definitelyWritable` A boolean denoting whether the column definitely can be updated.
-
-`columnClassName` The name of the Java class backing the column's type.
-
-### ConnectionProperties
-
-This object represents the properties for a given JDBC Connection.
-
-{% highlight json %}
-{
-  "connProps": "connPropsImpl",
-  "autoCommit": true,
-  "readOnly": true,
-  "transactionIsolation": 0,
-  "catalog": "catalog",
-  "schema": "schema"
-}
-{% endhighlight %}
-
-`autoCommit` (optional boolean) A boolean denoting if autoCommit is enabled for transactions.
-
-`readOnly` (optional boolean) A boolean denoting if a JDBC connection is read-only.
-
-`transactionIsolation` (optional integer) An integer which denotes the level of transactions isolation per the JDBC
-specification. This value is analogous to the values defined in `java.sql.Connection`.
-
-* 0 = Transactions are not supported
-* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
-* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
-* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
-* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
-
-`catalog` (optional string) The name of the catalog to include when fetching connection properties.
-
-`schema` (optional string) The name of the schema to include when fetching connection properties.
-
-### CursorFactory
-
-This object represents the information required to cast untyped objects into the necessary type for some results.
-
-{% highlight json %}
-{
-  "style": Style,
-  "clazz": "java.lang.String",
-  "fieldNames": [ "column1", "column2", ... ]
-}
-{% endhighlight %}
-
-`style` A string denoting the <a href="#style">Style</a> of the contained objects.
-
-### DatabaseProperty
-
-This object represents the exposed database properties for a Connection through the Avatica server.
-
-One of:
-
-* `GET_STRING_FUNCTIONS`
-* `GET_NUMERIC_FUNCTIONS`
-* `GET_SYSTEM_FUNCTIONS`
-* `GET_TIME_DATE_FUNCTIONS`
-* `GET_S_Q_L_KEYWORDS`
-* `GET_DEFAULT_TRANSACTION_ISOLATION`
-
-### Frame
-
-This object represents a batch of results, tracking the offset into the results and whether more results still exist
-to be fetched in the Avatica server.
-
-{% highlight json %}
-{
-  "offset": 100,
-  "done": true,
-  "rows": [ [ val1, val2, ... ], ... ]
-}
-{% endhighlight %}
-
-`offset` The starting position of these `rows` in the encompassing result set.
-
-`done` A boolean denoting whether more results exist for this result set.
-
-`rows` An array of arrays corresponding to the rows and columns for the result set.
-
-### QueryState
-
-This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
-SQL or by a DatabaseMetaData operation with arguments on that operation.
-
-{% highlight json %}
-{
-  "type": StateType,
-  "sql": "SELECT * FROM table",
-  "metaDataOperation": MetaDataOperation,
-  "operationArgs": ["arg0", "arg1", ... ]
-}
-{% endhighlight %}
-
-`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
-
-`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
-
-`metaDataOperation` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
-
-`operationArgs` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
-
-### Rep
-
-This enumeration represents the concrete Java type for some value.
-
-One of:
-
-* `PRIMITIVE_BOOLEAN`
-* `PRIMITIVE_BYTE`
-* `PRIMITIVE_CHAR`
-* `PRIMITIVE_SHORT`
-* `PRIMITIVE_INT`
-* `PRIMITIVE_LONG`
-* `PRIMITIVE_FLOAT`
-* `PRIMITIVE_DOUBLE`
-* `BOOLEAN`
-* `BYTE`
-* `CHARACTER`
-* `SHORT`
-* `INTEGER`
-* `LONG`
-* `FLOAT`
-* `DOUBLE`
-* `JAVA_SQL_TIME`
-* `JAVA_SQL_TIMESTAMP`
-* `JAVA_SQL_DATE`
-* `JAVA_UTIL_DATE`
-* `BYTE_STRING`
-* `STRING`
-* `NUMBER`
-* `OBJECT`
-
-### RpcMetadata
-
-This object contains assorted per-call/contextual metadata returned by the Avatica server.
-
-{% highlight json %}
-{
-  "serverAddress": "localhost:8765"
-}
-{% endhighlight %}
-
-`serverAddress` The `host:port` of the server which created this object.
-
-### Signature
-
-This object represents the result of preparing a Statement in the Avatica server.
-
-{% highlight json %}
-{
-  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
-  "sql": "SELECT * FROM table",
-  "parameters": [ AvaticaParameter, AvaticaParameter, ... ],
-  "cursorFactory": CursorFactory,
-  "statementType": StatementType
-}
-{% endhighlight %}
-
-`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
-
-`sql` The SQL executed.
-
-`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
-
-`cursorFactory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
-
-`statementType` An <a href="#statementtype">StatementType</a> object representing the type of Statement.
-
-### StateType
-
-This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
-
-One of:
-
-* `SQL`
-* `METADATA`
-
-### StatementHandle
-
-This object encapsulates all of the information of a Statement created in the Avatica server.
-
-{% highlight json %}
-{
-  "connectionId": "000000-0000-0000-00000000",
-  "id": 12345,
-  "signature": Signature
-}
-{% endhighlight %}
-
-`connectionId` The identifier of the connection to which this statement belongs.
-
-`id` The identifier of the statement.
-
-`signature` A <a href="#signature">Signature</a> object for the statement.
-
-### StatementType
-
-This enumeration represents what kind the Statement is.
-
-One of:
-
-* `SELECT`
-* `INSERT`
-* `UPDATE`
-* `DELETE`
-* `UPSERT`
-* `MERGE`
-* `OTHER_DML`
-* `CREATE`
-* `DROP`
-* `ALTER`
-* `OTHER_DDL`
-* `CALL`
-
-### Style
-
-This enumeration represents the generic "class" of type for a value.
-
-One of:
-
-* `OBJECT`
-* `RECORD`
-* `RECORD_PROJECTION`
-* `ARRAY`
-* `LIST`
-* `MAP`
-
-### TypedValue
-
-This object encapsulates the type and value for a column in a row.
-
-{% highlight json %}
-{
-  "type": "type_name",
-  "value": object
-}
-{% endhighlight %}
-
-`type` A name referring to the type of the object stored in `value`.
-
-`value` A JSON representation of a JDBC type.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/avatica_overview.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_overview.md b/avatica/site/_docs/avatica_overview.md
deleted file mode 100644
index 6c77eb9..0000000
--- a/avatica/site/_docs/avatica_overview.md
+++ /dev/null
@@ -1,130 +0,0 @@
----
-layout: docs
-title: Avatica Overview
-sidebar_title: Overview
-permalink: /docs/avatica_overview.html
----
-
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Avatica is a framework for building JDBC and ODBC drivers for databases,
-and an RPC wire protocol.
-
-![Avatica Architecture](https://raw.githubusercontent.com/julianhyde/share/master/slides/avatica-architecture.png)
-
-Avatica's Java binding has very few dependencies.
-Even though it is part of Apache Calcite it does not depend on other parts of
-Calcite. It depends only on JDK 1.7+ and Jackson.
-
-Avatica's wire protocol is JSON over HTTP.
-The Java implementation uses Jackson to convert request/response command
-objects to/from JSON.
-
-Avatica-Server is a Java implementation of Avatica RPC.
-
-Core concepts:
-
-* Meta is a local API sufficient to implement any Avatica provider
-* Factory creates implementations of the JDBC classes (Driver, Connection,
-  Statement, ResultSet) on top of a Meta
-* Service is an interface that implements the functions of Meta in terms
-  of request and response command objects
-
-## JDBC
-
-Avatica implements JDBC by means of Factory.
-Factory creates implementations of the JDBC classes (Driver, Connection,
-Statement, PreparedStatement, ResultSet) on top of a Meta.
-
-## ODBC
-
-Work has not started on Avatica ODBC.
-
-Avatica ODBC would use the same wire protocol and could use the same server
-implementation in Java. The ODBC client would be written in C or C++.
-
-Since the Avatica protocol abstracts many of the differences between providers,
-the same ODBC client could be used for different databases.
-
-## HTTP Server
-
-Avatica-server embeds the Jetty HTTP server, providing a class
-[HttpServer]({{ site.apiRoot }}/org/apache/calcite/avatica/server/HttpServer.html)
-that implements the Avatica RPC protocol
-and can be run as a standalone Java application.
-
-Connectors in HTTP server can be configured if needed by extending
-`HttpServer` class and overriding its `configureConnector()` method.
-For example, user can set `requestHeaderSize` to 64K bytes as follows:
-
-{% highlight java %}
-HttpServer server = new HttpServer(handler) {
-  @Override
-  protected ServerConnector configureConnector(
-      ServerConnector connector, int port) {
-    HttpConnectionFactory factory = (HttpConnectionFactory)
-        connector.getDefaultConnectionFactory();
-    factory.getHttpConfiguration().setRequestHeaderSize(64 << 10);
-    return super.configureConnector(connector, port);
-  }
-};
-server.start();
-{% endhighlight %}
-
-## Project structure
-
-We know that it is important that client libraries have minimal dependencies.
-
-Avatica is currently part of Apache Calcite.
-It does not depend upon any other part of Calcite.
-At some point Avatica could become a separate project.
-
-Packages:
-
-* [org.apache.calcite.avatica]({{ site.apiRoot }}/org/apache/calcite/avatica/package-summary.html) Core framework
-* [org.apache.calcite.avatica.remote]({{ site.apiRoot }}/org/apache/calcite/avatica/remote/package-summary.html) JDBC driver that uses remote procedure calls
-* [org.apache.calcite.avatica.server]({{ site.apiRoot }}/org/apache/calcite/avatica/server/package-summary.html) HTTP server
-* [org.apache.calcite.avatica.util]({{ site.apiRoot }}/org/apache/calcite/avatica/util/package-summary.html) Utilities
-
-## Status
-
-### Implemented
-
-* Create connection, create statement, metadata, prepare, bind, execute, fetch
-* RPC using JSON over HTTP
-* Local implementation
-* Implementation over an existing JDBC driver
-* Composite RPCs (combining several requests into one round trip)
-  * Execute-Fetch
-  * Metadata-Fetch (metadata calls such as getTables return all rows)
-
-### Not implemented
-
-* ODBC
-* RPCs
-  * CloseStatement
-  * CloseConnection
-* Composite RPCs
-  * CreateStatement-Prepare
-  * CloseStatement-CloseConnection
-  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
-* Remove statements from statement table
-* DML (INSERT, UPDATE, DELETE)
-* Statement.execute applied to SELECT statement


[02/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/ByteString.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/ByteString.java b/avatica/src/main/java/org/apache/calcite/avatica/util/ByteString.java
deleted file mode 100644
index 4e606b7..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/ByteString.java
+++ /dev/null
@@ -1,347 +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.util;
-
-import com.fasterxml.jackson.annotation.JsonValue;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Arrays;
-
-/**
- * Collection of bytes.
- *
- * <p>ByteString is to bytes what {@link String} is to chars: It is immutable,
- * implements equality ({@link #hashCode} and {@link #equals}),
- * comparison ({@link #compareTo}) and
- * {@link Serializable serialization} correctly.</p>
- */
-public class ByteString implements Comparable<ByteString>, Serializable {
-  private final byte[] bytes;
-
-  /** An empty byte string. */
-  public static final ByteString EMPTY = new ByteString(new byte[0], false);
-
-  private static final char[] DIGITS = {
-    '0', '1', '2', '3', '4', '5', '6', '7',
-    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-  };
-
-  /**
-   * Creates a ByteString.
-   *
-   * @param bytes Bytes
-   */
-  public ByteString(byte[] bytes) {
-    this(bytes.clone(), false);
-  }
-
-  // private constructor that does not copy
-  private ByteString(byte[] bytes, boolean dummy) {
-    this.bytes = bytes;
-  }
-
-  @Override public int hashCode() {
-    return Arrays.hashCode(bytes);
-  }
-
-  @Override public boolean equals(Object obj) {
-    return this == obj
-        || obj instanceof ByteString
-        && Arrays.equals(bytes, ((ByteString) obj).bytes);
-  }
-
-  public int compareTo(ByteString that) {
-    final byte[] v1 = bytes;
-    final byte[] v2 = that.bytes;
-    final int n = Math.min(v1.length, v2.length);
-    for (int i = 0; i < n; i++) {
-      int c1 = v1[i] & 0xff;
-      int c2 = v2[i] & 0xff;
-      if (c1 != c2) {
-        return c1 - c2;
-      }
-    }
-    return v1.length - v2.length;
-  }
-
-  /**
-   * Returns this byte string in hexadecimal format.
-   *
-   * @return Hexadecimal string
-   */
-  @Override public String toString() {
-    return toString(16);
-  }
-
-  /**
-   * Returns this byte string in a given base.
-   *
-   * @return String in given base
-   */
-  public String toString(int base) {
-    return toString(bytes, base);
-  }
-
-  /**
-   * Returns the given byte array in hexadecimal format.
-   *
-   * <p>For example, <tt>toString(new byte[] {0xDE, 0xAD})</tt>
-   * returns {@code "DEAD"}.</p>
-   *
-   * @param bytes Array of bytes
-   * @param base Base (2 or 16)
-   * @return String
-   */
-  public static String toString(byte[] bytes, int base) {
-    char[] chars;
-    int j = 0;
-    switch (base) {
-    case 2:
-      chars = new char[bytes.length * 8];
-      for (byte b : bytes) {
-        chars[j++] = DIGITS[(b & 0x80) >> 7];
-        chars[j++] = DIGITS[(b & 0x40) >> 6];
-        chars[j++] = DIGITS[(b & 0x20) >> 5];
-        chars[j++] = DIGITS[(b & 0x10) >> 4];
-        chars[j++] = DIGITS[(b & 0x08) >> 3];
-        chars[j++] = DIGITS[(b & 0x04) >> 2];
-        chars[j++] = DIGITS[(b & 0x02) >> 1];
-        chars[j++] = DIGITS[b & 0x01];
-      }
-      break;
-    case 16:
-      chars = new char[bytes.length * 2];
-      for (byte b : bytes) {
-        chars[j++] = DIGITS[(b & 0xF0) >> 4];
-        chars[j++] = DIGITS[b & 0x0F];
-      }
-      break;
-    default:
-      throw new IllegalArgumentException("bad base " + base);
-    }
-    return new String(chars, 0, j);
-  }
-
-  /**
-   * Returns this byte string in Base64 format.
-   *
-   * @return Base64 string
-   */
-  public String toBase64String() {
-    return Base64.encodeBytes(bytes);
-  }
-
-  /**
-   * Creates a byte string from a hexadecimal or binary string.
-   *
-   * <p>For example, <tt>of("DEAD", 16)</tt>
-   * returns the same as {@code ByteString(new byte[] {0xDE, 0xAD})}.
-   *
-   * @param string Array of bytes
-   * @param base Base (2 or 16)
-   * @return String
-   */
-  public static ByteString of(String string, int base) {
-    final byte[] bytes = parse(string, base);
-    return new ByteString(bytes, false);
-  }
-
-  /**
-   * Parses a hexadecimal or binary string to a byte array.
-   *
-   * @param string Hexadecimal or binary string
-   * @param base Base (2 or 16)
-   * @return Byte array
-   */
-  public static byte[] parse(String string, int base) {
-    char[] chars = string.toCharArray();
-    byte[] bytes;
-    int j = 0;
-    byte b = 0;
-    switch (base) {
-    case 2:
-      bytes = new byte[chars.length / 8];
-      for (char c : chars) {
-        b <<= 1;
-        if (c == '1') {
-          b |= 0x1;
-        }
-        if (j % 8 == 7) {
-          bytes[j / 8] = b;
-          b = 0;
-        }
-        ++j;
-      }
-      break;
-    case 16:
-      if (chars.length % 2 != 0) {
-        throw new IllegalArgumentException("hex string has odd length");
-      }
-      bytes = new byte[chars.length / 2];
-      for (char c : chars) {
-        b <<= 4;
-        byte i = decodeHex(c);
-        b |= i & 0x0F;
-        if (j % 2 == 1) {
-          bytes[j / 2] = b;
-          b = 0;
-        }
-        ++j;
-      }
-      break;
-    default:
-      throw new IllegalArgumentException("bad base " + base);
-    }
-    return bytes;
-  }
-
-  private static byte decodeHex(char c) {
-    if (c >= '0' && c <= '9') {
-      return (byte) (c - '0');
-    }
-    if (c >= 'a' && c <= 'f') {
-      return (byte) (c - 'a' + 10);
-    }
-    if (c >= 'A' && c <= 'F') {
-      return (byte) (c - 'A' + 10);
-    }
-    throw new IllegalArgumentException("invalid hex character: " + c);
-  }
-
-  /**
-   * Creates a byte string from a Base64 string.
-   *
-   * @param string Base64 string
-   * @return Byte string
-   */
-  public static ByteString ofBase64(String string) {
-    final byte[] bytes = parseBase64(string);
-    return new ByteString(bytes, false);
-  }
-
-  /**
-   * Parses a Base64 to a byte array.
-   *
-   * @param string Base64 string
-   * @return Byte array
-   */
-  public static byte[] parseBase64(String string) {
-    try {
-      return Base64.decode(string);
-    } catch (IOException e) {
-      throw new IllegalArgumentException("bad base64 string", e);
-    }
-  }
-
-  @SuppressWarnings({
-      "CloneDoesntCallSuperClone",
-      "CloneDoesntDeclareCloneNotSupportedException"
-  })
-  @Override public Object clone() {
-    return this;
-  }
-
-  /**
-   * Returns the number of bytes in this byte string.
-   *
-   * @return Length of this byte string
-   */
-  public int length() {
-    return bytes.length;
-  }
-
-  /**
-   * Returns the byte at a given position in the byte string.
-   *
-   * @param i Index
-   * @throws  IndexOutOfBoundsException
-   *          if the <tt>index</tt> argument is negative or not less than
-   *          <tt>length()</tt>
-   * @return Byte at given position
-   */
-  public byte byteAt(int i) {
-    return bytes[i];
-  }
-
-  /**
-   * Returns a ByteString that consists of a given range.
-   *
-   * @param start Start of range
-   * @param end Position after end of range
-   * @return Substring
-   */
-  public ByteString substring(int start, int end) {
-    byte[] bytes = Arrays.copyOfRange(this.bytes, start, end);
-    return new ByteString(bytes, false);
-  }
-
-  /**
-   * Returns a ByteString that starts at a given position.
-   *
-   * @param start Start of range
-   * @return Substring
-   */
-  public ByteString substring(int start) {
-    return substring(start, length());
-  }
-
-  /**
-   * Returns a copy of the byte array.
-   */
-  @JsonValue
-  public byte[] getBytes() {
-    return bytes.clone();
-  }
-
-  /**
-   * Returns a ByteString consisting of the concatenation of this and another
-   * string.
-   *
-   * @param other Byte string to concatenate
-   * @return Combined byte string
-   */
-  public ByteString concat(ByteString other) {
-    int otherLen = other.length();
-    if (otherLen == 0) {
-      return this;
-    }
-    int len = bytes.length;
-    byte[] buf = Arrays.copyOf(bytes, len + otherLen);
-    System.arraycopy(other.bytes, 0, buf, len, other.bytes.length);
-    return new ByteString(buf, false);
-  }
-
-  /** Returns the position at which {@code seek} first occurs in this byte
-   * string, or -1 if it does not occur. */
-  public int indexOf(ByteString seek) {
-  iLoop:
-    for (int i = 0; i < bytes.length - seek.bytes.length + 1; i++) {
-      for (int j = 0;; j++) {
-        if (j == seek.bytes.length) {
-          return i;
-        }
-        if (bytes[i + j] != seek.bytes[j]) {
-          continue iLoop;
-        }
-      }
-    }
-    return -1;
-  }
-}
-
-// End ByteString.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Casing.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Casing.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Casing.java
deleted file mode 100644
index 5f13214..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Casing.java
+++ /dev/null
@@ -1,35 +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.util;
-
-/** Policy for converting case of identifiers before storing them.
- *
- * <p>A database often has policies for quoted versus unquoted identifiers.
- * For example, Oracle converts unquoted identifiers to upper-case, but
- * quoted identifiers are unchanged.</p> */
-public enum Casing {
-  /** The case of identifiers is not changed. */
-  UNCHANGED,
-
-  /** Identifiers are converted to upper-case. */
-  TO_UPPER,
-
-  /** Identifiers are converted to lower-case. */
-  TO_LOWER
-}
-
-// End Casing.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Cursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Cursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Cursor.java
deleted file mode 100644
index 8eab72f..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Cursor.java
+++ /dev/null
@@ -1,145 +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.util;
-
-import org.apache.calcite.avatica.ColumnMetaData;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Interface to an iteration that is similar to, and can easily support,
- * a JDBC {@link java.sql.ResultSet}, but is simpler to implement.
- */
-public interface Cursor extends AutoCloseable {
-  /**
-   * Creates a list of accessors, one per column.
-   *
-   *
-   * @param types List of column types, per {@link java.sql.Types}.
-   * @param localCalendar Calendar in local time zone
-   * @param factory Factory that creates sub-ResultSets when needed
-   * @return List of column accessors
-   */
-  List<Accessor> createAccessors(List<ColumnMetaData> types,
-      Calendar localCalendar, ArrayImpl.Factory factory);
-
-  /**
-   * Moves to the next row.
-   *
-   * @return Whether moved
-   *
-   * @throws SQLException on database error
-   */
-  boolean next() throws SQLException;
-
-  /**
-   * Closes this cursor and releases resources.
-   */
-  void close();
-
-  /**
-   * Returns whether the last value returned was null.
-   *
-   * @throws SQLException on database error
-   */
-  boolean wasNull() throws SQLException;
-
-  /**
-   * Accessor of a column value.
-   */
-  public interface Accessor {
-    boolean wasNull() throws SQLException;
-
-    String getString() throws SQLException;
-
-    boolean getBoolean() throws SQLException;
-
-    byte getByte() throws SQLException;
-
-    short getShort() throws SQLException;
-
-    int getInt() throws SQLException;
-
-    long getLong() throws SQLException;
-
-    float getFloat() throws SQLException;
-
-    double getDouble() throws SQLException;
-
-    BigDecimal getBigDecimal() throws SQLException;
-
-    BigDecimal getBigDecimal(int scale) throws SQLException;
-
-    byte[] getBytes() throws SQLException;
-
-    InputStream getAsciiStream() throws SQLException;
-
-    InputStream getUnicodeStream() throws SQLException;
-
-    InputStream getBinaryStream() throws SQLException;
-
-    Object getObject() throws SQLException;
-
-    Reader getCharacterStream() throws SQLException;
-
-    Object getObject(Map<String, Class<?>> map) throws SQLException;
-
-    Ref getRef() throws SQLException;
-
-    Blob getBlob() throws SQLException;
-
-    Clob getClob() throws SQLException;
-
-    Array getArray() throws SQLException;
-
-    Date getDate(Calendar calendar) throws SQLException;
-
-    Time getTime(Calendar calendar) throws SQLException;
-
-    Timestamp getTimestamp(Calendar calendar) throws SQLException;
-
-    URL getURL() throws SQLException;
-
-    NClob getNClob() throws SQLException;
-
-    SQLXML getSQLXML() throws SQLException;
-
-    String getNString() throws SQLException;
-
-    Reader getNCharacterStream() throws SQLException;
-
-    <T> T getObject(Class<T> type) throws SQLException;
-  }
-}
-
-// End Cursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java b/avatica/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
deleted file mode 100644
index 67e1245..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
+++ /dev/null
@@ -1,842 +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.util;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-/**
- * Utility functions for datetime types: date, time, timestamp.
- *
- * <p>Used by the JDBC driver.
- *
- * <p>TODO: review methods for performance. Due to allocations required, it may
- * be preferable to introduce a "formatter" with the required state.
- */
-public class DateTimeUtils {
-  /** The julian date of the epoch, 1970-01-01. */
-  public static final int EPOCH_JULIAN = 2440588;
-
-  private DateTimeUtils() {}
-
-  //~ Static fields/initializers ---------------------------------------------
-
-  /** The SimpleDateFormat string for ISO dates, "yyyy-MM-dd". */
-  public static final String DATE_FORMAT_STRING = "yyyy-MM-dd";
-
-  /** The SimpleDateFormat string for ISO times, "HH:mm:ss". */
-  public static final String TIME_FORMAT_STRING = "HH:mm:ss";
-
-  /** The SimpleDateFormat string for ISO timestamps, "yyyy-MM-dd HH:mm:ss". */
-  public static final String TIMESTAMP_FORMAT_STRING =
-      DATE_FORMAT_STRING + " " + TIME_FORMAT_STRING;
-
-  /** The GMT time zone. */
-  public static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
-
-  /** The Java default time zone. */
-  public static final TimeZone DEFAULT_ZONE = TimeZone.getDefault();
-
-  /**
-   * The number of milliseconds in a second.
-   */
-  public static final long MILLIS_PER_SECOND = 1000L;
-
-  /**
-   * The number of milliseconds in a minute.
-   */
-  public static final long MILLIS_PER_MINUTE = 60000L;
-
-  /**
-   * The number of milliseconds in an hour.
-   */
-  public static final long MILLIS_PER_HOUR = 3600000L; // = 60 * 60 * 1000
-
-  /**
-   * The number of milliseconds in a day.
-   *
-   * <p>This is the modulo 'mask' used when converting
-   * TIMESTAMP values to DATE and TIME values.
-   */
-  public static final long MILLIS_PER_DAY = 86400000; // = 24 * 60 * 60 * 1000
-
-  /**
-   * Calendar set to the epoch (1970-01-01 00:00:00 UTC). Useful for
-   * initializing other values. Calendars are not immutable, so be careful not
-   * to screw up this object for everyone else.
-   */
-  public static final Calendar ZERO_CALENDAR;
-
-  static {
-    ZERO_CALENDAR = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
-    ZERO_CALENDAR.setTimeInMillis(0);
-  }
-
-  /**
-   * Calendar set to local time.
-   */
-  private static final Calendar LOCAL_CALENDAR = Calendar.getInstance();
-
-  //~ Methods ----------------------------------------------------------------
-
-  /**
-   * Parses a string using {@link SimpleDateFormat} and a given pattern. This
-   * method parses a string at the specified parse position and if successful,
-   * updates the parse position to the index after the last character used.
-   * The parsing is strict and requires months to be less than 12, days to be
-   * less than 31, etc.
-   *
-   * @param s       string to be parsed
-   * @param pattern {@link SimpleDateFormat} pattern (not null)
-   * @param tz      time zone in which to interpret string. Defaults to the Java
-   *                default time zone
-   * @param pp      position to start parsing from
-   * @return a Calendar initialized with the parsed value, or null if parsing
-   * failed. If returned, the Calendar is configured to the GMT time zone.
-   */
-  private static Calendar parseDateFormat(
-      String s,
-      String pattern,
-      TimeZone tz,
-      ParsePosition pp) {
-    assert pattern != null;
-    SimpleDateFormat df = new SimpleDateFormat(pattern);
-    if (tz == null) {
-      tz = DEFAULT_ZONE;
-    }
-    Calendar ret = Calendar.getInstance(tz);
-    df.setCalendar(ret);
-    df.setLenient(false);
-
-    java.util.Date d = df.parse(s, pp);
-    if (null == d) {
-      return null;
-    }
-    ret.setTime(d);
-    ret.setTimeZone(GMT_ZONE);
-    return ret;
-  }
-
-  /**
-   * Parses a string using {@link SimpleDateFormat} and a given pattern. The
-   * entire string must match the pattern specified.
-   *
-   * @param s       string to be parsed
-   * @param pattern {@link SimpleDateFormat}  pattern
-   * @param tz      time zone in which to interpret string. Defaults to the Java
-   *                default time zone
-   * @return a Calendar initialized with the parsed value, or null if parsing
-   * failed. If returned, the Calendar is configured to the GMT time zone.
-   */
-  public static Calendar parseDateFormat(
-      String s,
-      String pattern,
-      TimeZone tz) {
-    assert pattern != null;
-    ParsePosition pp = new ParsePosition(0);
-    Calendar ret = parseDateFormat(s, pattern, tz, pp);
-    if (pp.getIndex() != s.length()) {
-      // Didn't consume entire string - not good
-      return null;
-    }
-    return ret;
-  }
-
-  /**
-   * Parses a string using {@link SimpleDateFormat} and a given pattern, and
-   * if present, parses a fractional seconds component. The fractional seconds
-   * component must begin with a decimal point ('.') followed by numeric
-   * digits. The precision is rounded to a maximum of 3 digits of fractional
-   * seconds precision (to obtain milliseconds).
-   *
-   * @param s       string to be parsed
-   * @param pattern {@link SimpleDateFormat}  pattern
-   * @param tz      time zone in which to interpret string. Defaults to the
-   *                local time zone
-   * @return a {@link DateTimeUtils.PrecisionTime PrecisionTime} initialized
-   * with the parsed value, or null if parsing failed. The PrecisionTime
-   * contains a GMT Calendar and a precision.
-   */
-  public static PrecisionTime parsePrecisionDateTimeLiteral(
-      String s,
-      String pattern,
-      TimeZone tz) {
-    assert pattern != null;
-    ParsePosition pp = new ParsePosition(0);
-    Calendar cal = parseDateFormat(s, pattern, tz, pp);
-    if (cal == null) {
-      return null; // Invalid date/time format
-    }
-
-    // Note: the Java SimpleDateFormat 'S' treats any number after
-    // the decimal as milliseconds. That means 12:00:00.9 has 9
-    // milliseconds and 12:00:00.9999 has 9999 milliseconds.
-    int p = 0;
-    if (pp.getIndex() < s.length()) {
-      // Check to see if rest is decimal portion
-      if (s.charAt(pp.getIndex()) != '.') {
-        return null;
-      }
-
-      // Skip decimal sign
-      pp.setIndex(pp.getIndex() + 1);
-
-      // Parse decimal portion
-      if (pp.getIndex() < s.length()) {
-        String secFraction = s.substring(pp.getIndex());
-        if (!secFraction.matches("\\d+")) {
-          return null;
-        }
-        NumberFormat nf = NumberFormat.getIntegerInstance();
-        Number num = nf.parse(s, pp);
-        if ((num == null) || (pp.getIndex() != s.length())) {
-          // Invalid decimal portion
-          return null;
-        }
-
-        // Determine precision - only support prec 3 or lower
-        // (milliseconds) Higher precisions are quietly rounded away
-        p = Math.min(
-            3,
-            secFraction.length());
-
-        // Calculate milliseconds
-        int ms =
-            (int) Math.round(
-                num.longValue()
-                * Math.pow(10, 3 - secFraction.length()));
-        cal.add(Calendar.MILLISECOND, ms);
-      }
-    }
-
-    assert pp.getIndex() == s.length();
-    PrecisionTime ret = new PrecisionTime(cal, p);
-    return ret;
-  }
-
-  /**
-   * Gets the active time zone based on a Calendar argument
-   */
-  public static TimeZone getTimeZone(Calendar cal) {
-    if (cal == null) {
-      return DEFAULT_ZONE;
-    }
-    return cal.getTimeZone();
-  }
-
-  /**
-   * Checks if the date/time format is valid
-   *
-   * @param pattern {@link SimpleDateFormat}  pattern
-   * @throws IllegalArgumentException if the given pattern is invalid
-   */
-  public static void checkDateFormat(String pattern) {
-    new SimpleDateFormat(pattern);
-  }
-
-  /**
-   * Creates a new date formatter with Farrago specific options. Farrago
-   * parsing is strict and does not allow values such as day 0, month 13, etc.
-   *
-   * @param format {@link SimpleDateFormat}  pattern
-   */
-  public static SimpleDateFormat newDateFormat(String format) {
-    SimpleDateFormat sdf = new SimpleDateFormat(format);
-    sdf.setLenient(false);
-    return sdf;
-  }
-
-  /** Helper for CAST({timestamp} AS VARCHAR(n)). */
-  public static String unixTimestampToString(long timestamp) {
-    final StringBuilder buf = new StringBuilder(17);
-    int date = (int) (timestamp / MILLIS_PER_DAY);
-    int time = (int) (timestamp % MILLIS_PER_DAY);
-    if (time < 0) {
-      --date;
-      time += MILLIS_PER_DAY;
-    }
-    unixDateToString(buf, date);
-    buf.append(' ');
-    unixTimeToString(buf, time);
-    return buf.toString();
-  }
-
-  /** Helper for CAST({timestamp} AS VARCHAR(n)). */
-  public static String unixTimeToString(int time) {
-    final StringBuilder buf = new StringBuilder(8);
-    unixTimeToString(buf, time);
-    return buf.toString();
-  }
-
-  private static void unixTimeToString(StringBuilder buf, int time) {
-    int h = time / 3600000;
-    int time2 = time % 3600000;
-    int m = time2 / 60000;
-    int time3 = time2 % 60000;
-    int s = time3 / 1000;
-    int ms = time3 % 1000;
-    int2(buf, h);
-    buf.append(':');
-    int2(buf, m);
-    buf.append(':');
-    int2(buf, s);
-  }
-
-  private static void int2(StringBuilder buf, int i) {
-    buf.append((char) ('0' + (i / 10) % 10));
-    buf.append((char) ('0' + i % 10));
-  }
-
-  private static void int4(StringBuilder buf, int i) {
-    buf.append((char) ('0' + (i / 1000) % 10));
-    buf.append((char) ('0' + (i / 100) % 10));
-    buf.append((char) ('0' + (i / 10) % 10));
-    buf.append((char) ('0' + i % 10));
-  }
-
-  /** Helper for CAST({date} AS VARCHAR(n)). */
-  public static String unixDateToString(int date) {
-    final StringBuilder buf = new StringBuilder(10);
-    unixDateToString(buf, date);
-    return buf.toString();
-  }
-
-  private static void unixDateToString(StringBuilder buf, int date) {
-    julianToString(buf, date + EPOCH_JULIAN);
-  }
-
-  private static void julianToString(StringBuilder buf, int julian) {
-    // this shifts the epoch back to astronomical year -4800 instead of the
-    // start of the Christian era in year AD 1 of the proleptic Gregorian
-    // calendar.
-    int j = julian + 32044;
-    int g = j / 146097;
-    int dg = j % 146097;
-    int c = (dg / 36524 + 1) * 3 / 4;
-    int dc = dg - c * 36524;
-    int b = dc / 1461;
-    int db = dc % 1461;
-    int a = (db / 365 + 1) * 3 / 4;
-    int da = db - a * 365;
-
-    // integer number of full years elapsed since March 1, 4801 BC
-    int y = g * 400 + c * 100 + b * 4 + a;
-    // integer number of full months elapsed since the last March 1
-    int m = (da * 5 + 308) / 153 - 2;
-    // number of days elapsed since day 1 of the month
-    int d = da - (m + 4) * 153 / 5 + 122;
-    int year = y - 4800 + (m + 2) / 12;
-    int month = (m + 2) % 12 + 1;
-    int day = d + 1;
-    int4(buf, year);
-    buf.append('-');
-    int2(buf, month);
-    buf.append('-');
-    int2(buf, day);
-  }
-
-  public static String intervalYearMonthToString(int v, TimeUnitRange range) {
-    final StringBuilder buf = new StringBuilder();
-    if (v >= 0) {
-      buf.append('+');
-    } else {
-      buf.append('-');
-      v = -v;
-    }
-    final int y;
-    final int m;
-    switch (range) {
-    case YEAR:
-      v = roundUp(v, 12);
-      y = v / 12;
-      buf.append(y);
-      break;
-    case YEAR_TO_MONTH:
-      y = v / 12;
-      buf.append(y);
-      buf.append('-');
-      m = v % 12;
-      number(buf, m, 2);
-      break;
-    case MONTH:
-      m = v;
-      buf.append(m);
-      break;
-    default:
-      throw new AssertionError(range);
-    }
-    return buf.toString();
-  }
-
-  public static StringBuilder number(StringBuilder buf, int v, int n) {
-    for (int k = digitCount(v); k < n; k++) {
-      buf.append('0');
-    }
-    return buf.append(v);
-  }
-
-  public static int digitCount(int v) {
-    for (int n = 1;; n++) {
-      v /= 10;
-      if (v == 0) {
-        return n;
-      }
-    }
-  }
-
-  private static int roundUp(int dividend, int divisor) {
-    int remainder = dividend % divisor;
-    dividend -= remainder;
-    if (remainder * 2 > divisor) {
-      dividend += divisor;
-    }
-    return dividend;
-  }
-
-  /** Cheap, unsafe, long power. power(2, 3) returns 8. */
-  public static long powerX(long a, long b) {
-    long x = 1;
-    while (b > 0) {
-      x *= a;
-      --b;
-    }
-    return x;
-  }
-
-  public static String intervalDayTimeToString(long v, TimeUnitRange range,
-      int scale) {
-    final StringBuilder buf = new StringBuilder();
-    if (v >= 0) {
-      buf.append('+');
-    } else {
-      buf.append('-');
-      v = -v;
-    }
-    final long ms;
-    final long s;
-    final long m;
-    final long h;
-    final long d;
-    switch (range) {
-    case DAY_TO_SECOND:
-      v = roundUp(v, powerX(10, 3 - scale));
-      ms = v % 1000;
-      v /= 1000;
-      s = v % 60;
-      v /= 60;
-      m = v % 60;
-      v /= 60;
-      h = v % 24;
-      v /= 24;
-      d = v;
-      buf.append((int) d);
-      buf.append(' ');
-      number(buf, (int) h, 2);
-      buf.append(':');
-      number(buf, (int) m, 2);
-      buf.append(':');
-      number(buf, (int) s, 2);
-      fraction(buf, scale, ms);
-      break;
-    case DAY_TO_MINUTE:
-      v = roundUp(v, 1000 * 60);
-      v /= 1000;
-      v /= 60;
-      m = v % 60;
-      v /= 60;
-      h = v % 24;
-      v /= 24;
-      d = v;
-      buf.append((int) d);
-      buf.append(' ');
-      number(buf, (int) h, 2);
-      buf.append(':');
-      number(buf, (int) m, 2);
-      break;
-    case DAY_TO_HOUR:
-      v = roundUp(v, 1000 * 60 * 60);
-      v /= 1000;
-      v /= 60;
-      v /= 60;
-      h = v % 24;
-      v /= 24;
-      d = v;
-      buf.append((int) d);
-      buf.append(' ');
-      number(buf, (int) h, 2);
-      break;
-    case DAY:
-      v = roundUp(v, 1000 * 60 * 60 * 24);
-      d = v / (1000 * 60 * 60 * 24);
-      buf.append((int) d);
-      break;
-    case HOUR:
-      v = roundUp(v, 1000 * 60 * 60);
-      v /= 1000;
-      v /= 60;
-      v /= 60;
-      h = v;
-      buf.append((int) h);
-      break;
-    case HOUR_TO_MINUTE:
-      v = roundUp(v, 1000 * 60);
-      v /= 1000;
-      v /= 60;
-      m = v % 60;
-      v /= 60;
-      h = v;
-      buf.append((int) h);
-      buf.append(':');
-      number(buf, (int) m, 2);
-      break;
-    case HOUR_TO_SECOND:
-      v = roundUp(v, powerX(10, 3 - scale));
-      ms = v % 1000;
-      v /= 1000;
-      s = v % 60;
-      v /= 60;
-      m = v % 60;
-      v /= 60;
-      h = v;
-      buf.append((int) h);
-      buf.append(':');
-      number(buf, (int) m, 2);
-      buf.append(':');
-      number(buf, (int) s, 2);
-      fraction(buf, scale, ms);
-      break;
-    case MINUTE_TO_SECOND:
-      v = roundUp(v, powerX(10, 3 - scale));
-      ms = v % 1000;
-      v /= 1000;
-      s = v % 60;
-      v /= 60;
-      m = v;
-      buf.append((int) m);
-      buf.append(':');
-      number(buf, (int) s, 2);
-      fraction(buf, scale, ms);
-      break;
-    case MINUTE:
-      v = roundUp(v, 1000 * 60);
-      v /= 1000;
-      v /= 60;
-      m = v;
-      buf.append((int) m);
-      break;
-    case SECOND:
-      v = roundUp(v, powerX(10, 3 - scale));
-      ms = v % 1000;
-      v /= 1000;
-      s = v;
-      buf.append((int) s);
-      fraction(buf, scale, ms);
-      break;
-    default:
-      throw new AssertionError(range);
-    }
-    return buf.toString();
-  }
-
-  /**
-   * Rounds a dividend to the nearest divisor.
-   * For example roundUp(31, 10) yields 30; roundUp(37, 10) yields 40.
-   * @param dividend Number to be divided
-   * @param divisor Number to divide by
-   * @return Rounded dividend
-   */
-  private static long roundUp(long dividend, long divisor) {
-    long remainder = dividend % divisor;
-    dividend -= remainder;
-    if (remainder * 2 > divisor) {
-      dividend += divisor;
-    }
-    return dividend;
-  }
-
-  private static void fraction(StringBuilder buf, int scale, long ms) {
-    if (scale > 0) {
-      buf.append('.');
-      long v1 = scale == 3 ? ms
-          : scale == 2 ? ms / 10
-          : scale == 1 ? ms / 100
-            : 0;
-      number(buf, (int) v1, scale);
-    }
-  }
-
-  public static int dateStringToUnixDate(String s) {
-    int hyphen1 = s.indexOf('-');
-    int y;
-    int m;
-    int d;
-    if (hyphen1 < 0) {
-      y = Integer.parseInt(s.trim());
-      m = 1;
-      d = 1;
-    } else {
-      y = Integer.parseInt(s.substring(0, hyphen1).trim());
-      final int hyphen2 = s.indexOf('-', hyphen1 + 1);
-      if (hyphen2 < 0) {
-        m = Integer.parseInt(s.substring(hyphen1 + 1).trim());
-        d = 1;
-      } else {
-        m = Integer.parseInt(s.substring(hyphen1 + 1, hyphen2).trim());
-        d = Integer.parseInt(s.substring(hyphen2 + 1).trim());
-      }
-    }
-    return ymdToUnixDate(y, m, d);
-  }
-
-  public static int timeStringToUnixDate(String v) {
-    return timeStringToUnixDate(v, 0);
-  }
-
-  public static int timeStringToUnixDate(String v, int start) {
-    final int colon1 = v.indexOf(':', start);
-    int hour;
-    int minute;
-    int second;
-    int milli;
-    if (colon1 < 0) {
-      hour = Integer.parseInt(v.trim());
-      minute = 1;
-      second = 1;
-      milli = 0;
-    } else {
-      hour = Integer.parseInt(v.substring(start, colon1).trim());
-      final int colon2 = v.indexOf(':', colon1 + 1);
-      if (colon2 < 0) {
-        minute = Integer.parseInt(v.substring(colon1 + 1).trim());
-        second = 1;
-        milli = 0;
-      } else {
-        minute = Integer.parseInt(v.substring(colon1 + 1, colon2).trim());
-        int dot = v.indexOf('.', colon2);
-        if (dot < 0) {
-          second = Integer.parseInt(v.substring(colon2 + 1).trim());
-          milli = 0;
-        } else {
-          second = Integer.parseInt(v.substring(colon2 + 1, dot).trim());
-          milli = Integer.parseInt(v.substring(dot + 1).trim());
-        }
-      }
-    }
-    return hour * (int) MILLIS_PER_HOUR
-        + minute * (int) MILLIS_PER_MINUTE
-        + second * (int) MILLIS_PER_SECOND
-        + milli;
-  }
-
-  public static long timestampStringToUnixDate(String s) {
-    final long d;
-    final long t;
-    s = s.trim();
-    int space = s.indexOf(' ');
-    if (space >= 0) {
-      d = dateStringToUnixDate(s.substring(0, space));
-      t = timeStringToUnixDate(s, space + 1);
-    } else {
-      d = dateStringToUnixDate(s);
-      t = 0;
-    }
-    return d * MILLIS_PER_DAY + t;
-  }
-
-  public static long unixDateExtract(TimeUnitRange range, long date) {
-    return julianExtract(range, (int) date + EPOCH_JULIAN);
-  }
-
-  private static int julianExtract(TimeUnitRange range, int julian) {
-    // this shifts the epoch back to astronomical year -4800 instead of the
-    // start of the Christian era in year AD 1 of the proleptic Gregorian
-    // calendar.
-    int j = julian + 32044;
-    int g = j / 146097;
-    int dg = j % 146097;
-    int c = (dg / 36524 + 1) * 3 / 4;
-    int dc = dg - c * 36524;
-    int b = dc / 1461;
-    int db = dc % 1461;
-    int a = (db / 365 + 1) * 3 / 4;
-    int da = db - a * 365;
-
-    // integer number of full years elapsed since March 1, 4801 BC
-    int y = g * 400 + c * 100 + b * 4 + a;
-    // integer number of full months elapsed since the last March 1
-    int m = (da * 5 + 308) / 153 - 2;
-    // number of days elapsed since day 1 of the month
-    int d = da - (m + 4) * 153 / 5 + 122;
-    int year = y - 4800 + (m + 2) / 12;
-    int month = (m + 2) % 12 + 1;
-    int day = d + 1;
-    switch (range) {
-    case YEAR:
-      return year;
-    case MONTH:
-      return month;
-    case DAY:
-      return day;
-    default:
-      throw new AssertionError(range);
-    }
-  }
-
-  /** Resets to zero the "time" part of a timestamp. */
-  public static long resetTime(long timestamp) {
-    int date = (int) (timestamp / MILLIS_PER_DAY);
-    return (long) date * MILLIS_PER_DAY;
-  }
-
-  /** Resets to epoch (1970-01-01) the "date" part of a timestamp. */
-  public static long resetDate(long timestamp) {
-    return floorMod(timestamp, MILLIS_PER_DAY);
-  }
-
-  public static long unixTimestampFloor(TimeUnitRange range, long timestamp) {
-    int date = (int) (timestamp / MILLIS_PER_DAY);
-    final int f = julianDateFloor(range, date + EPOCH_JULIAN, true);
-    return (long) f * MILLIS_PER_DAY;
-  }
-
-  public static long unixDateFloor(TimeUnitRange range, long date) {
-    return julianDateFloor(range, (int) date + EPOCH_JULIAN, true);
-  }
-
-  public static long unixTimestampCeil(TimeUnitRange range, long timestamp) {
-    int date = (int) (timestamp / MILLIS_PER_DAY);
-    final int f = julianDateFloor(range, date + EPOCH_JULIAN, false);
-    return (long) f * MILLIS_PER_DAY;
-  }
-
-  public static long unixDateCeil(TimeUnitRange range, long date) {
-    return julianDateFloor(range, (int) date + EPOCH_JULIAN, true);
-  }
-
-  private static int julianDateFloor(TimeUnitRange range, int julian,
-      boolean floor) {
-    // this shifts the epoch back to astronomical year -4800 instead of the
-    // start of the Christian era in year AD 1 of the proleptic Gregorian
-    // calendar.
-    int j = julian + 32044;
-    int g = j / 146097;
-    int dg = j % 146097;
-    int c = (dg / 36524 + 1) * 3 / 4;
-    int dc = dg - c * 36524;
-    int b = dc / 1461;
-    int db = dc % 1461;
-    int a = (db / 365 + 1) * 3 / 4;
-    int da = db - a * 365;
-
-    // integer number of full years elapsed since March 1, 4801 BC
-    int y = g * 400 + c * 100 + b * 4 + a;
-    // integer number of full months elapsed since the last March 1
-    int m = (da * 5 + 308) / 153 - 2;
-    // number of days elapsed since day 1 of the month
-    int d = da - (m + 4) * 153 / 5 + 122;
-    int year = y - 4800 + (m + 2) / 12;
-    int month = (m + 2) % 12 + 1;
-    int day = d + 1;
-    switch (range) {
-    case YEAR:
-      if (!floor && (month > 1 || day > 1)) {
-        ++year;
-      }
-      return ymdToUnixDate(year, 1, 1);
-    case MONTH:
-      if (!floor && day > 1) {
-        ++month;
-      }
-      return ymdToUnixDate(year, month, 1);
-    default:
-      throw new AssertionError(range);
-    }
-  }
-
-  public static int ymdToUnixDate(int year, int month, int day) {
-    final int julian = ymdToJulian(year, month, day);
-    return julian - EPOCH_JULIAN;
-  }
-
-  public static int ymdToJulian(int year, int month, int day) {
-    int a = (14 - month) / 12;
-    int y = year + 4800 - a;
-    int m = month + 12 * a - 3;
-    int j = day + (153 * m + 2) / 5
-        + 365 * y
-        + y / 4
-        - y / 100
-        + y / 400
-        - 32045;
-    if (j < 2299161) {
-      j = day + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
-    }
-    return j;
-  }
-
-  public static long unixTimestamp(int year, int month, int day, int hour,
-      int minute, int second) {
-    final int date = ymdToUnixDate(year, month, day);
-    return (long) date * MILLIS_PER_DAY
-        + (long) hour * MILLIS_PER_HOUR
-        + (long) minute * MILLIS_PER_MINUTE
-        + (long) second * MILLIS_PER_SECOND;
-  }
-
-  /** Divide, rounding towards negative infinity. */
-  public static long floorDiv(long x, long y) {
-    long r = x / y;
-    // if the signs are different and modulo not zero, round down
-    if ((x ^ y) < 0 && (r * y != x)) {
-      r--;
-    }
-    return r;
-  }
-
-  /** Modulo, always returning a non-negative result. */
-  public static long floorMod(long x, long y) {
-    return x - floorDiv(x, y) * y;
-  }
-
-  //~ Inner Classes ----------------------------------------------------------
-
-  /**
-   * Helper class for {@link DateTimeUtils#parsePrecisionDateTimeLiteral}
-   */
-  public static class PrecisionTime {
-    private final Calendar cal;
-    private final int precision;
-
-    public PrecisionTime(Calendar cal, int precision) {
-      this.cal = cal;
-      this.precision = precision;
-    }
-
-    public Calendar getCalendar() {
-      return cal;
-    }
-
-    public int getPrecision() {
-      return precision;
-    }
-  }
-}
-
-// End DateTimeUtils.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
deleted file mode 100644
index c09373b..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
+++ /dev/null
@@ -1,85 +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.util;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.util.Cursor}
- * on top of an {@link Iterator} that
- * returns a record for each row. The returned record is cached to avoid
- * multiple computations of current row.
- *
- * @param <E> Element type
- */
-public abstract class IteratorCursor<E> extends PositionedCursor<E> {
-  private Position position = Position.BEFORE_START;
-  private final Iterator<E> iterator;
-  private E current = null;
-
-  /**
-   * Creates an {@code IteratorCursor}.
-   *
-   * @param iterator input iterator
-   */
-  protected IteratorCursor(Iterator<E> iterator) {
-    this.iterator = iterator;
-  }
-
-  public boolean next() {
-    if (iterator.hasNext()) {
-      current = iterator.next();
-      position = Position.OK;
-      return true;
-    }
-    current = null;
-    position = Position.AFTER_END;
-    return false;
-  }
-
-  public void close() {
-    current = null;
-    position = Position.CLOSED;
-    if (iterator instanceof AutoCloseable) {
-      try {
-        ((AutoCloseable) iterator).close();
-      } catch (RuntimeException e) {
-        throw e;
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  protected E current() {
-    if (position != Position.OK) {
-      throw new NoSuchElementException();
-    }
-    return current;
-  }
-
-  /** Are we positioned on a valid row? */
-  private enum Position {
-    CLOSED,
-    BEFORE_START,
-    OK,
-    AFTER_END
-  }
-}
-
-// End IteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
deleted file mode 100644
index e2801ec..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
+++ /dev/null
@@ -1,43 +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.util;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Implementation of {@link Cursor} on top of an
- * {@link java.util.Iterator} that
- * returns a {@link List} for each row.
- */
-public class ListIteratorCursor extends IteratorCursor<List<Object>> {
-
-  /**
-   * Creates a RecordEnumeratorCursor.
-   *
-   * @param iterator Iterator
-   */
-  public ListIteratorCursor(Iterator<List<Object>> iterator) {
-    super(iterator);
-  }
-
-  protected Getter createGetter(int ordinal) {
-    return new ListGetter(ordinal);
-  }
-}
-
-// End ListIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
deleted file mode 100644
index 9ab6c9c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
+++ /dev/null
@@ -1,51 +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.util;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of {@link Cursor} on top of an
- * {@link java.util.Iterator} that
- * returns a {@link Map} for each row.
- *
- * <p>The Map contains (field, value) pairs.
- */
-public class MapIteratorCursor extends IteratorCursor<Map<String, Object>> {
-  private final List<String> fieldNames;
-
-  /**
-   * Creates a MapIteratorCursor.
-   *
-   * @param iterator Iterator
-   * @param fieldNames Field names to project
-   */
-  public MapIteratorCursor(Iterator<Map<String, Object>> iterator,
-      List<String> fieldNames) {
-    super(iterator);
-    assert fieldNames != null;
-    this.fieldNames = fieldNames;
-  }
-
-  protected Getter createGetter(int ordinal) {
-    return new MapGetter<String>(fieldNames.get(ordinal));
-  }
-}
-
-// End MapIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java b/avatica/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
deleted file mode 100644
index 3a6a9c6..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
+++ /dev/null
@@ -1,37 +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.util;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This is a dummy annotation that forces javac to produce output for
- * otherwise empty package-info.java.
- *
- * <p>The result is maven-compiler-plugin can properly identify the scope of
- * changed files
- *
- * <p>See more details in
- * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
- *   maven-compiler-plugin: incremental compilation broken</a>
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface PackageMarker {
-}
-
-// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
deleted file mode 100644
index f60f47d..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
+++ /dev/null
@@ -1,134 +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.util;
-
-import java.lang.reflect.Field;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Abstract implementation of {@link org.apache.calcite.avatica.util.Cursor}
- * that caches its current row.
- *
- * @param <T> Element type
- */
-public abstract class PositionedCursor<T> extends AbstractCursor {
-  /**
-   * Returns the current row.
-   *
-   * @return current row
-   *
-   * @throws java.util.NoSuchElementException if the iteration has no more
-   * elements
-   */
-  protected abstract T current();
-
-  /** Implementation of
-   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
-   * that reads from records that are arrays. */
-  protected class ArrayGetter extends AbstractGetter {
-    protected final int field;
-
-    public ArrayGetter(int field) {
-      this.field = field;
-    }
-
-    public Object getObject() {
-      Object o = ((Object[]) current())[field];
-      wasNull[0] = o == null;
-      return o;
-    }
-  }
-
-  /** Implementation of
-   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
-   * that reads items from a list. */
-  protected class ListGetter extends AbstractGetter {
-    protected final int index;
-
-    public ListGetter(int index) {
-      this.index = index;
-    }
-
-    public Object getObject() {
-      Object o = ((List) current()).get(index);
-      wasNull[0] = o == null;
-      return o;
-    }
-  }
-
-  /** Implementation of
-   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
-   * for records that consist of a single field.
-   *
-   * <p>Each record is represented as an object, and the value of the sole
-   * field is that object. */
-  protected class ObjectGetter extends AbstractGetter {
-    public ObjectGetter(int field) {
-      assert field == 0;
-    }
-
-    public Object getObject() {
-      Object o = current();
-      wasNull[0] = o == null;
-      return o;
-    }
-  }
-
-  /** Implementation of
-   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
-   * that reads fields via reflection. */
-  protected class FieldGetter extends AbstractGetter {
-    protected final Field field;
-
-    public FieldGetter(Field field) {
-      this.field = field;
-    }
-
-    public Object getObject() {
-      Object o;
-      try {
-        o = field.get(current());
-      } catch (IllegalAccessException e) {
-        throw new RuntimeException(e);
-      }
-      wasNull[0] = o == null;
-      return o;
-    }
-  }
-
-  /** Implementation of
-   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
-   * that reads entries from a {@link java.util.Map}. */
-  protected class MapGetter<K> extends AbstractGetter {
-    protected final K key;
-
-    public MapGetter(K key) {
-      this.key = key;
-    }
-
-    public Object getObject() {
-      @SuppressWarnings("unchecked") final Map<K, Object> map =
-          (Map<K, Object>) current();
-      Object o = map.get(key);
-      wasNull[0] = o == null;
-      return o;
-    }
-  }
-}
-
-// End PositionedCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Quoting.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Quoting.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Quoting.java
deleted file mode 100644
index 855e4a6..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Quoting.java
+++ /dev/null
@@ -1,37 +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.util;
-
-/** Syntax for quoting identifiers in SQL statements. */
-public enum Quoting {
-  /** Quote identifiers in double-quotes. For example, {@code "my id"}. */
-  DOUBLE_QUOTE("\""),
-
-  /** Quote identifiers in back-quotes. For example, {@code `my id`}. */
-  BACK_TICK("`"),
-
-  /** Quote identifiers in brackets. For example, {@code [my id]}. */
-  BRACKET("[");
-
-  public String string;
-
-  Quoting(String string) {
-    this.string = string;
-  }
-}
-
-// End Quoting.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
deleted file mode 100644
index 717247d..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
+++ /dev/null
@@ -1,63 +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.util;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Implementation of {@link org.apache.calcite.avatica.util.Cursor} on top of an
- * {@link java.util.Iterator} that
- * returns a record for each row. The record is a synthetic class whose fields
- * are all public.
- *
- * @param <E> Element type
- */
-public class RecordIteratorCursor<E> extends IteratorCursor<E> {
-  private final List<Field> fields;
-
-  /**
-   * Creates a RecordIteratorCursor.
-   *
-   * @param iterator Iterator
-   * @param clazz Element type
-   */
-  public RecordIteratorCursor(Iterator<E> iterator, Class<E> clazz) {
-    this(iterator, clazz, Arrays.asList(clazz.getFields()));
-  }
-
-  /**
-   * Creates a RecordIteratorCursor that projects particular fields.
-   *
-   * @param iterator Iterator
-   * @param clazz Element type
-   * @param fields Fields to project
-   */
-  public RecordIteratorCursor(Iterator<E> iterator, Class<E> clazz,
-      List<Field> fields) {
-    super(iterator);
-    this.fields = fields;
-  }
-
-  protected Getter createGetter(int ordinal) {
-    return new FieldGetter(fields.get(ordinal));
-  }
-}
-
-// End RecordIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Spacer.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Spacer.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Spacer.java
deleted file mode 100644
index cc0a097..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Spacer.java
+++ /dev/null
@@ -1,80 +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.util;
-
-/**
- * Efficiently writes strings of spaces.
- */
-public class Spacer {
-  private int n;
-
-  /** Creates a Spacer with zero spaces. */
-  public Spacer() {
-    this(0);
-  }
-
-  /** Creates a Spacer with a given number of spaces. */
-  public Spacer(int n) {
-    set(n);
-  }
-
-  /** Sets the current number of spaces. */
-  public Spacer set(int n) {
-    this.n = n;
-    return this;
-  }
-
-  /** Returns the current number of spaces. */
-  public int get() {
-    return n;
-  }
-
-  /** Increases the current number of spaces by {@code n}. */
-  public Spacer add(int n) {
-    return set(this.n + n);
-  }
-
-  /** Reduces the current number of spaces by {@code n}. */
-  public Spacer subtract(int n) {
-    return set(this.n - n);
-  }
-
-  /** Returns a string of the current number of spaces. */
-  public String toString() {
-    return Spaces.of(n);
-  }
-
-  /** Appends current number of spaces to a {@link StringBuilder}. */
-  public StringBuilder spaces(StringBuilder buf) {
-    return Spaces.append(buf, n);
-  }
-
-  /** Returns a string that is padded on the right with spaces to the current
-   * length. */
-  public String padRight(String string) {
-    Spaces.padRight(string, n);
-    final int x = n - string.length();
-    if (x <= 0) {
-      return string;
-    }
-    // Replacing StringBuffer with String would hurt performance.
-    //noinspection StringBufferReplaceableByString
-    return Spaces.append(new StringBuilder(string), x).toString();
-  }
-}
-
-// End Spacer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/Spaces.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/Spaces.java b/avatica/src/main/java/org/apache/calcite/avatica/util/Spaces.java
deleted file mode 100644
index 6469400..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/Spaces.java
+++ /dev/null
@@ -1,185 +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.util;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.AbstractList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/** Utilities for creating strings of spaces. */
-public class Spaces {
-  /** It doesn't look like this list is ever updated. But it is - when a call to
-   * to {@link SpaceList#get} causes an {@link IndexOutOfBoundsException}. */
-  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
-  private static final List<String> SPACE_LIST = new SpaceList();
-
-  /** The longest possible string of spaces. Fine as long as you don't try
-   * to print it.
-   *
-   * <p>Use with {@link StringBuilder#append(CharSequence, int, int)} to
-   * append spaces without doing memory allocation.</p>
-   */
-  public static final CharSequence MAX = sequence(Integer.MAX_VALUE);
-
-  // Utility class. Do not instantiate.
-  private Spaces() {}
-
-  /** Creates a sequence of {@code n} spaces. */
-  public static CharSequence sequence(int n) {
-    return new SpaceString(n);
-  }
-
-  /** Returns a string of {@code n} spaces. */
-  public static String of(int n) {
-    return SPACE_LIST.get(n);
-  }
-
-  /** Appends {@code n} spaces to an {@link Appendable}. */
-  public static Appendable append(Appendable buf, int n) throws IOException {
-    buf.append(MAX, 0, n);
-    return buf;
-  }
-
-  /** Appends {@code n} spaces to a {@link PrintWriter}. */
-  public static PrintWriter append(PrintWriter pw, int n) {
-    pw.append(MAX, 0, n);
-    return pw;
-  }
-
-  /** Appends {@code n} spaces to a {@link StringWriter}. */
-  public static StringWriter append(StringWriter pw, int n) {
-    pw.append(MAX, 0, n);
-    return pw;
-  }
-
-  /** Appends {@code n} spaces to a {@link StringBuilder}. */
-  public static StringBuilder append(StringBuilder buf, int n) {
-    buf.append(MAX, 0, n);
-    return buf;
-  }
-
-  /** Appends {@code n} spaces to a {@link StringBuffer}. */
-  public static StringBuffer append(StringBuffer buf, int n) {
-    buf.append(MAX, 0, n);
-    return buf;
-  }
-
-  /** Returns a string that is padded on the right with spaces to the given
-   * length. */
-  public static String padRight(String string, int n) {
-    final int x = n - string.length();
-    if (x <= 0) {
-      return string;
-    }
-    // Replacing StringBuffer with String would hurt performance.
-    //noinspection StringBufferReplaceableByString
-    return append(new StringBuilder(string), x).toString();
-  }
-
-  /** Returns a string that is padded on the left with spaces to the given
-   * length. */
-  public static String padLeft(String string, int n) {
-    final int x = n - string.length();
-    if (x <= 0) {
-      return string;
-    }
-    // Replacing StringBuffer with String would hurt performance.
-    //noinspection StringBufferReplaceableByString
-    return append(new StringBuilder(), x).append(string).toString();
-  }
-
-  /** A string of spaces. */
-  private static class SpaceString implements CharSequence {
-    private final int length;
-
-    private SpaceString(int length) {
-      this.length = length;
-    }
-
-    // Do not override equals and hashCode to be like String. CharSequence does
-    // not require it.
-
-    @SuppressWarnings("NullableProblems")
-    @Override public String toString() {
-      return of(length);
-    }
-
-    public int length() {
-      return length;
-    }
-
-    public char charAt(int index) {
-      return ' ';
-    }
-
-    public CharSequence subSequence(int start, int end) {
-      return new SpaceString(end - start);
-    }
-  }
-
-  /** List whose {@code i}th entry is a string consisting of {@code i} spaces.
-   * It populates itself the first time you ask for a particular string, and
-   * caches the result. */
-  private static class SpaceList extends CopyOnWriteArrayList<String> {
-    @Override public String get(int index) {
-      for (;;) {
-        try {
-          return super.get(index);
-        } catch (IndexOutOfBoundsException e) {
-          if (index < 0) {
-            throw e;
-          }
-          populate(Math.max(16, index + 1));
-        }
-      }
-    }
-
-    /**
-     * Populates this list with all prefix strings of a given string. All
-     * of the prefix strings share the same backing array of chars.
-     */
-    private synchronized void populate(int newSize) {
-      final int size = size();
-      if (newSize <= size) {
-        return;
-      }
-      final char[] chars = new char[newSize];
-      Arrays.fill(chars, ' ');
-      final int length = newSize - size;
-      final int offset = size;
-
-      // addAll is much more efficient than repeated add for
-      // CopyOnWriteArrayList
-      addAll(
-          new AbstractList<String>() {
-            public String get(int index) {
-              return new String(chars, 0, offset + index);
-            }
-
-            public int size() {
-              return length;
-            }
-          });
-    }
-  }
-}
-
-// End Spaces.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/StructImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
deleted file mode 100644
index b25fce6..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
+++ /dev/null
@@ -1,79 +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.util;
-
-import org.apache.calcite.avatica.ColumnMetaData;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Struct;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/** Implementation of JDBC {@link Struct}. */
-public class StructImpl implements Struct {
-  private final List list;
-
-  public StructImpl(List list) {
-    this.list = list;
-  }
-
-  @Override public String toString() {
-    final Iterator iterator = list.iterator();
-    if (!iterator.hasNext()) {
-      return "{}";
-    }
-    final StringBuilder buf = new StringBuilder("{");
-    for (;;) {
-      append(buf, iterator.next());
-      if (!iterator.hasNext()) {
-        return buf.append("}").toString();
-      }
-      buf.append(", ");
-    }
-  }
-
-  @Override public String getSQLTypeName() throws SQLException {
-    return "ROW";
-  }
-
-  @Override public Object[] getAttributes() throws SQLException {
-    return list.toArray();
-  }
-
-  @Override public Object[] getAttributes(Map<String, Class<?>> map)
-      throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  private void append(StringBuilder buf, Object o) {
-    if (o == null) {
-      buf.append("null");
-    } else {
-      buf.append(o);
-    }
-  }
-
-  /** Factory that can create a result set based on a list of values. */
-  public interface Factory {
-    ResultSet create(ColumnMetaData.AvaticaType elementType,
-        Iterable<Object> iterable);
-  }
-}
-
-// End StructImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java b/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
deleted file mode 100644
index b249232..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
+++ /dev/null
@@ -1,75 +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.util;
-
-import java.math.BigDecimal;
-
-/**
- * Enumeration of time units used to construct an interval.
- */
-public enum TimeUnit {
-  YEAR(true, ' ', 12 /* months */, null),
-  MONTH(true, '-', 1 /* months */, BigDecimal.valueOf(12)),
-  DAY(false, '-', DateTimeUtils.MILLIS_PER_DAY, null),
-  HOUR(false, ' ', DateTimeUtils.MILLIS_PER_HOUR, BigDecimal.valueOf(24)),
-  MINUTE(false, ':', DateTimeUtils.MILLIS_PER_MINUTE, BigDecimal.valueOf(60)),
-  SECOND(false, ':', DateTimeUtils.MILLIS_PER_SECOND, BigDecimal.valueOf(60)),
-
-  /** Unlike the other units, MILLISECOND may not be the unit of a SQL interval.
-   * Still, it is convenient to use it internally, when converting to and from
-   * UNIX timestamps. */
-  MILLISECOND(false, '.', 1, BigDecimal.valueOf(1));
-
-  public final boolean yearMonth;
-  public final char separator;
-  public final long multiplier;
-  private final BigDecimal limit;
-
-  private static final TimeUnit[] CACHED_VALUES = values();
-
-  TimeUnit(boolean yearMonth, char separator, long multiplier,
-      BigDecimal limit) {
-    this.yearMonth = yearMonth;
-    this.separator = separator;
-    this.multiplier = multiplier;
-    this.limit = limit;
-  }
-
-  /**
-   * Returns the TimeUnit associated with an ordinal. The value returned
-   * is null if the ordinal is not a member of the TimeUnit enumeration.
-   */
-  public static TimeUnit getValue(int ordinal) {
-    return ordinal < 0 || ordinal >= CACHED_VALUES.length
-        ? null
-        : CACHED_VALUES[ordinal];
-  }
-
-  /**
-   * Returns whether a given value is valid for a field of this time unit.
-   *
-   * @param field Field value
-   * @return Whether value
-   */
-  public boolean isValidValue(BigDecimal field) {
-    return field.compareTo(BigDecimal.ZERO) >= 0
-        && (limit == null
-        || field.compareTo(limit) < 0);
-  }
-}
-
-// End TimeUnit.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java b/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
deleted file mode 100644
index 4d9b322..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
+++ /dev/null
@@ -1,107 +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.util;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/** A range of time units. The first is more significant than the
- * other (e.g. year-to-day) or the same as the other (e.g. month). */
-public enum TimeUnitRange {
-  YEAR(TimeUnit.YEAR, null),
-  YEAR_TO_MONTH(TimeUnit.YEAR, TimeUnit.MONTH),
-  MONTH(TimeUnit.MONTH, null),
-  DAY(TimeUnit.DAY, null),
-  DAY_TO_HOUR(TimeUnit.DAY, TimeUnit.HOUR),
-  DAY_TO_MINUTE(TimeUnit.DAY, TimeUnit.MINUTE),
-  DAY_TO_SECOND(TimeUnit.DAY, TimeUnit.SECOND),
-  HOUR(TimeUnit.HOUR, null),
-  HOUR_TO_MINUTE(TimeUnit.HOUR, TimeUnit.MINUTE),
-  HOUR_TO_SECOND(TimeUnit.HOUR, TimeUnit.SECOND),
-  MINUTE(TimeUnit.MINUTE, null),
-  MINUTE_TO_SECOND(TimeUnit.MINUTE, TimeUnit.SECOND),
-  SECOND(TimeUnit.SECOND, null);
-
-  public final TimeUnit startUnit;
-  public final TimeUnit endUnit;
-
-  private static final Map<Pair<TimeUnit>, TimeUnitRange> MAP = createMap();
-
-  /**
-   * Creates a TimeUnitRange.
-   *
-   * @param startUnit Start time unit
-   * @param endUnit   End time unit
-   */
-  TimeUnitRange(TimeUnit startUnit, TimeUnit endUnit) {
-    assert startUnit != null;
-    this.startUnit = startUnit;
-    this.endUnit = endUnit;
-  }
-
-  /**
-   * Returns a {@code TimeUnitRange} with a given start and end unit.
-   *
-   * @param startUnit Start unit
-   * @param endUnit   End unit
-   * @return Time unit range, or null if not valid
-   */
-  public static TimeUnitRange of(TimeUnit startUnit, TimeUnit endUnit) {
-    return MAP.get(new Pair<>(startUnit, endUnit));
-  }
-
-  private static Map<Pair<TimeUnit>, TimeUnitRange> createMap() {
-    Map<Pair<TimeUnit>, TimeUnitRange> map = new HashMap<>();
-    for (TimeUnitRange value : values()) {
-      map.put(new Pair<>(value.startUnit, value.endUnit), value);
-    }
-    return Collections.unmodifiableMap(map);
-  }
-
-  /** Whether this is in the YEAR-TO-MONTH family of intervals. */
-  public boolean monthly() {
-    return ordinal() <= MONTH.ordinal();
-  }
-
-  /** Immutable pair of values of the same type. */
-  private static class Pair<E> {
-    final E left;
-    final E right;
-
-    private Pair(E left, E right) {
-      this.left = left;
-      this.right = right;
-    }
-
-    @Override public int hashCode() {
-      int k = (left == null) ? 0 : left.hashCode();
-      int k1 = (right == null) ? 0 : right.hashCode();
-      return ((k << 4) | k) ^ k1;
-    }
-
-    @Override public boolean equals(Object obj) {
-      return obj == this
-          || obj instanceof Pair
-          && Objects.equals(left, ((Pair) obj).left)
-          && Objects.equals(right, ((Pair) obj).right);
-    }
-  }
-}
-
-// End TimeUnitRange.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java b/avatica/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
deleted file mode 100644
index 8daee60..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
+++ /dev/null
@@ -1,152 +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.util;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A utility class for reading and writing bytes to byte buffers without synchronization. A
- * reduced variant taken from Apache Accumulo. This class is <b>not</b> thread-safe by design.
- * It is up to the caller to guarantee mutual exclusion as necessary.
- */
-public class UnsynchronizedBuffer extends OutputStream {
-  // Anything larger than 64K, reap the backing buffer
-  private static final int LARGE_BUFFER_SIZE = 1024 * 64;
-
-  final int initialCapacity;
-  int offset = 0;
-  byte[] data;
-
-  /**
-   * Creates a new writer.
-   */
-  public UnsynchronizedBuffer() {
-    this(4096);
-  }
-
-  /**
-   * Creates a new writer.
-   *
-   * @param initialCapacity initial byte capacity
-   */
-  public UnsynchronizedBuffer(int initialCapacity) {
-    this.initialCapacity = initialCapacity;
-    data = new byte[initialCapacity];
-  }
-
-  private void reserve(int l) {
-    if (offset + l > data.length) {
-      int newSize = UnsynchronizedBuffer.nextArraySize(offset + l);
-
-      byte[] newData = new byte[newSize];
-      System.arraycopy(data, 0, newData, 0, offset);
-      data = newData;
-    }
-
-  }
-
-  /**
-   * Adds bytes to this writer's buffer.
-   *
-   * @param bytes byte array
-   * @param off offset into array to start copying bytes
-   * @param length number of bytes to add
-   * @throws IndexOutOfBoundsException if off or length are invalid
-   */
-  public void write(byte[] bytes, int off, int length) {
-    reserve(length);
-    System.arraycopy(bytes, off, data, offset, length);
-    offset += length;
-  }
-
-  @Override public void write(int b) throws IOException {
-    reserve(1);
-    data[offset] = (byte) b;
-    offset++;
-  }
-
-  /**
-   * Gets (a copy of) the contents of this writer's buffer.
-   *
-   * @return byte buffer contents
-   */
-  public byte[] toArray() {
-    byte[] ret = new byte[offset];
-    System.arraycopy(data, 0, ret, 0, offset);
-    return ret;
-  }
-
-  /**
-   * Resets the internal pointer into the buffer.
-   */
-  public void reset() {
-    offset = 0;
-    if (data.length >= LARGE_BUFFER_SIZE) {
-      data = new byte[this.initialCapacity];
-    }
-  }
-
-  /**
-   * @return The current offset into the backing array.
-   */
-  public int getOffset() {
-    return offset;
-  }
-
-  /**
-   * @return The current length of the backing array.
-   */
-  public long getSize() {
-    return data.length;
-  }
-
-  /**
-   * Determines what next array size should be by rounding up to next power of two.
-   *
-   * @param i current array size
-   * @return next array size
-   * @throws IllegalArgumentException if i is negative
-   */
-  public static int nextArraySize(int i) {
-    if (i < 0) {
-      throw new IllegalArgumentException();
-    }
-
-    if (i > (1 << 30)) {
-      return Integer.MAX_VALUE; // this is the next power of 2 minus one... a special case
-    }
-
-    if (i == 0) {
-      return 1;
-    }
-
-    // round up to next power of two
-    int ret = i;
-    ret--;
-    ret |= ret >> 1;
-    ret |= ret >> 2;
-    ret |= ret >> 4;
-    ret |= ret >> 8;
-    ret |= ret >> 16;
-    ret++;
-
-    return ret;
-  }
-}
-
-// End UnsynchronizedBuffer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/package-info.java b/avatica/src/main/java/org/apache/calcite/avatica/util/package-info.java
deleted file mode 100644
index eab457c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-
-/**
- * Avatica utilities.
- */
-@PackageMarker
-package org.apache.calcite.avatica.util;
-
-// End package-info.java


[19/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/tutorial.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/tutorial.md b/avatica/site/_docs/tutorial.md
new file mode 100644
index 0000000..73f8f8f
--- /dev/null
+++ b/avatica/site/_docs/tutorial.md
@@ -0,0 +1,760 @@
+---
+layout: docs
+title: Tutorial
+permalink: /docs/tutorial.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This is a step-by-step tutorial that shows how to build and connect to
+Calcite. It uses a simple adapter that makes a directory of CSV files
+appear to be a schema containing tables. Calcite does the rest, and
+provides a full SQL interface.
+
+Calcite-example-CSV is a fully functional adapter for
+Calcite that reads
+text files in
+<a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV
+(comma-separated values)</a> format. It is remarkable that a couple of
+hundred lines of Java code are sufficient to provide full SQL query
+capability.
+
+CSV also serves as a template for building adapters to other
+data formats. Even though there are not many lines of code, it covers
+several important concepts:
+
+* user-defined schema using SchemaFactory and Schema interfaces;
+* declaring schemas in a model JSON file;
+* declaring views in a model JSON file;
+* user-defined table using the Table interface;
+* determining the record type of a table;
+* a simple implementation of Table, using the ScannableTable interface, that
+  enumerates all rows directly;
+* a more advanced implementation that implements FilterableTable, and can
+  filter out rows according to simple predicates;
+* advanced implementation of Table, using TranslatableTable, that translates
+  to relational operators using planner rules.
+
+## Download and build
+
+You need Java (1.7 or higher; 1.8 preferred), git and maven (3.2.1 or later).
+
+{% highlight bash %}
+$ git clone https://github.com/apache/calcite.git
+$ cd calcite
+$ mvn install -DskipTests -Dcheckstyle.skip=true
+$ cd example/csv
+{% endhighlight %}
+
+## First queries
+
+Now let's connect to Calcite using
+<a href="https://github.com/julianhyde/sqlline">sqlline</a>, a SQL shell
+that is included in this project.
+
+{% highlight bash %}
+$ ./sqlline
+sqlline> !connect jdbc:calcite:model=target/test-classes/model.json admin admin
+{% endhighlight %}
+
+(If you are running Windows, the command is `sqlline.bat`.)
+
+Execute a metadata query:
+
+{% highlight bash %}
+sqlline> !tables
++------------+--------------+-------------+---------------+----------+------+
+| TABLE_CAT  | TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | REMARKS  | TYPE |
++------------+--------------+-------------+---------------+----------+------+
+| null       | SALES        | DEPTS       | TABLE         | null     | null |
+| null       | SALES        | EMPS        | TABLE         | null     | null |
+| null       | SALES        | HOBBIES     | TABLE         | null     | null |
+| null       | metadata     | COLUMNS     | SYSTEM_TABLE  | null     | null |
+| null       | metadata     | TABLES      | SYSTEM_TABLE  | null     | null |
++------------+--------------+-------------+---------------+----------+------+
+{% endhighlight %}
+
+(JDBC experts, note: sqlline's <code>!tables</code> command is just executing
+<a href="http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><code>DatabaseMetaData.getTables()</code></a>
+behind the scenes.
+It has other commands to query JDBC metadata, such as <code>!columns</code> and <code>!describe</code>.)
+
+As you can see there are 5 tables in the system: tables
+<code>EMPS</code>, <code>DEPTS</code> and <code>HOBBIES</code> in the current
+<code>SALES</code> schema, and <code>COLUMNS</code> and
+<code>TABLES</code> in the system <code>metadata</code> schema. The
+system tables are always present in Calcite, but the other tables are
+provided by the specific implementation of the schema; in this case,
+the <code>EMPS</code> and <code>DEPTS</code> tables are based on the
+<code>EMPS.csv</code> and <code>DEPTS.csv</code> files in the
+<code>target/test-classes</code> directory.
+
+Let's execute some queries on those tables, to show that Calcite is providing
+a full implementation of SQL. First, a table scan:
+
+{% highlight bash %}
+sqlline> SELECT * FROM emps;
++--------+--------+---------+---------+----------------+--------+-------+---+
+| EMPNO  |  NAME  | DEPTNO  | GENDER  |      CITY      | EMPID  |  AGE  | S |
++--------+--------+---------+---------+----------------+--------+-------+---+
+| 100    | Fred   | 10      |         |                | 30     | 25    | t |
+| 110    | Eric   | 20      | M       | San Francisco  | 3      | 80    | n |
+| 110    | John   | 40      | M       | Vancouver      | 2      | null  | f |
+| 120    | Wilma  | 20      | F       |                | 1      | 5     | n |
+| 130    | Alice  | 40      | F       | Vancouver      | 2      | null  | f |
++--------+--------+---------+---------+----------------+--------+-------+---+
+{% endhighlight %}
+
+Now JOIN and GROUP BY:
+
+{% highlight bash %}
+sqlline> SELECT d.name, COUNT(*)
+. . . .> FROM emps AS e JOIN depts AS d ON e.deptno = d.deptno
+. . . .> GROUP BY d.name;
++------------+---------+
+|    NAME    | EXPR$1  |
++------------+---------+
+| Sales      | 1       |
+| Marketing  | 2       |
++------------+---------+
+{% endhighlight %}
+
+Last, the VALUES operator generates a single row, and is a convenient
+way to test expressions and SQL built-in functions:
+
+{% highlight bash %}
+sqlline> VALUES CHAR_LENGTH('Hello, ' || 'world!');
++---------+
+| EXPR$0  |
++---------+
+| 13      |
++---------+
+{% endhighlight %}
+
+Calcite has many other SQL features. We don't have time to cover them
+here. Write some more queries to experiment.
+
+## Schema discovery
+
+Now, how did Calcite find these tables? Remember, core Calcite does not
+know anything about CSV files. (As a "database without a storage
+layer", Calcite doesn't know about any file formats.) Calcite knows about
+those tables because we told it to run code in the calcite-example-csv
+project.
+
+There are a couple of steps in that chain. First, we define a schema
+based on a schema factory class in a model file. Then the schema
+factory creates a schema, and the schema creates several tables, each
+of which knows how to get data by scanning a CSV file. Last, after
+Calcite has parsed the query and planned it to use those tables, Calcite
+invokes the tables to read the data as the query is being
+executed. Now let's look at those steps in more detail.
+
+On the JDBC connect string we gave the path of a model in JSON
+format. Here is the model:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'SALES',
+  schemas: [
+    {
+      name: 'SALES',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
+      operand: {
+        directory: 'target/test-classes/sales'
+      }
+    }
+  ]
+}
+{% endhighlight %}
+
+The model defines a single schema called 'SALES'. The schema is
+powered by a plugin class,
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java">org.apache.calcite.adapter.csv.CsvSchemaFactory</a>,
+which is part of the
+calcite-example-csv project and implements the Calcite interface
+<a href="{{ site.apiRoot }}/org/apache/calcite/schema/SchemaFactory.html">SchemaFactory</a>.
+Its <code>create</code> method instantiates a
+schema, passing in the <code>directory</code> argument from the model file:
+
+{% highlight java %}
+public Schema create(SchemaPlus parentSchema, String name,
+    Map<String, Object> operand) {
+  String directory = (String) operand.get("directory");
+  String flavorName = (String) operand.get("flavor");
+  CsvTable.Flavor flavor;
+  if (flavorName == null) {
+    flavor = CsvTable.Flavor.SCANNABLE;
+  } else {
+    flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase());
+  }
+  return new CsvSchema(
+      new File(directory),
+      flavor);
+}
+{% endhighlight %}
+
+Driven by the model, the schema factory instantiates a single schema
+called 'SALES'.  The schema is an instance of
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java">org.apache.calcite.adapter.csv.CsvSchema</a>
+and implements the Calcite interface
+<a href="{{ site.apiRoot }}/org/apache/calcite/schema/Schema.html">Schema</a>.
+
+A schema's job is to produce a list of tables. (It can also list sub-schemas and
+table-functions, but these are advanced features and calcite-example-csv does
+not support them.) The tables implement Calcite's
+<a href="{{ site.apiRoot }}/org/apache/calcite/schema/Table.html">Table</a>
+interface. <code>CsvSchema</code> produces tables that are instances of
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTable.java">CsvTable</a>
+and its sub-classes.
+
+Here is the relevant code from <code>CsvSchema</code>, overriding the
+<code><a href="{{ site.apiRoot }}/org/apache/calcite/schema/impl/AbstractSchema.html#getTableMap()">getTableMap()</a></code>
+method in the <code>AbstractSchema</code> base class.
+
+{% highlight java %}
+protected Map<String, Table> getTableMap() {
+  // Look for files in the directory ending in ".csv", ".csv.gz", ".json",
+  // ".json.gz".
+  File[] files = directoryFile.listFiles(
+      new FilenameFilter() {
+        public boolean accept(File dir, String name) {
+          final String nameSansGz = trim(name, ".gz");
+          return nameSansGz.endsWith(".csv")
+              || nameSansGz.endsWith(".json");
+        }
+      });
+  if (files == null) {
+    System.out.println("directory " + directoryFile + " not found");
+    files = new File[0];
+  }
+  // Build a map from table name to table; each file becomes a table.
+  final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
+  for (File file : files) {
+    String tableName = trim(file.getName(), ".gz");
+    final String tableNameSansJson = trimOrNull(tableName, ".json");
+    if (tableNameSansJson != null) {
+      JsonTable table = new JsonTable(file);
+      builder.put(tableNameSansJson, table);
+      continue;
+    }
+    tableName = trim(tableName, ".csv");
+    final Table table = createTable(file);
+    builder.put(tableName, table);
+  }
+  return builder.build();
+}
+
+/** Creates different sub-type of table based on the "flavor" attribute. */
+private Table createTable(File file) {
+  switch (flavor) {
+  case TRANSLATABLE:
+    return new CsvTranslatableTable(file, null);
+  case SCANNABLE:
+    return new CsvScannableTable(file, null);
+  case FILTERABLE:
+    return new CsvFilterableTable(file, null);
+  default:
+    throw new AssertionError("Unknown flavor " + flavor);
+  }
+}
+{% endhighlight %}
+
+The schema scans the directory and finds all files whose name ends
+with ".csv" and creates tables for them. In this case, the directory
+is <code>target/test-classes/sales</code> and contains files
+<code>EMPS.csv</code> and <code>DEPTS.csv</code>, which these become
+the tables <code>EMPS</code> and <code>DEPTS</code>.
+
+## Tables and views in schemas
+
+Note how we did not need to define any tables in the model; the schema
+generated the tables automatically.
+
+You can define extra tables,
+beyond those that are created automatically,
+using the <code>tables</code> property of a schema.
+
+Let's see how to create
+an important and useful type of table, namely a view.
+
+A view looks like a table when you are writing a query, but it doesn't store data.
+It derives its result by executing a query.
+The view is expanded while the query is being planned, so the query planner
+can often perform optimizations like removing expressions from the SELECT
+clause that are not used in the final result.
+
+Here is a schema that defines a view:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'SALES',
+  schemas: [
+    {
+      name: 'SALES',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
+      operand: {
+        directory: 'target/test-classes/sales'
+      },
+      tables: [
+        {
+          name: 'FEMALE_EMPS',
+          type: 'view',
+          sql: 'SELECT * FROM emps WHERE gender = \'F\''
+        }
+      ]
+    }
+  ]
+}
+{% endhighlight %}
+
+The line <code>type: 'view'</code> tags <code>FEMALE_EMPS</code> as a view,
+as opposed to a regular table or a custom table.
+Note that single-quotes within the view definition are escaped using a
+back-slash, in the normal way for JSON.
+
+JSON doesn't make it easy to author long strings, so Calcite supports an
+alternative syntax. If your view has a long SQL statement, you can instead
+supply a list of lines rather than a single string:
+
+{% highlight json %}
+{
+  name: 'FEMALE_EMPS',
+  type: 'view',
+  sql: [
+    'SELECT * FROM emps',
+    'WHERE gender = \'F\''
+  ]
+}
+{% endhighlight %}
+
+Now we have defined a view, we can use it in queries just as if it were a table:
+
+{% highlight sql %}
+sqlline> SELECT e.name, d.name FROM female_emps AS e JOIN depts AS d on e.deptno = d.deptno;
++--------+------------+
+|  NAME  |    NAME    |
++--------+------------+
+| Wilma  | Marketing  |
++--------+------------+
+{% endhighlight %}
+
+## Custom tables
+
+Custom tables are tables whose implementation is driven by user-defined code.
+They don't need to live in a custom schema.
+
+There is an example in <code>model-with-custom-table.json</code>:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'CUSTOM_TABLE',
+  schemas: [
+    {
+      name: 'CUSTOM_TABLE',
+      tables: [
+        {
+          name: 'EMPS',
+          type: 'custom',
+          factory: 'org.apache.calcite.adapter.csv.CsvTableFactory',
+          operand: {
+            file: 'target/test-classes/sales/EMPS.csv.gz',
+            flavor: "scannable"
+          }
+        }
+      ]
+    }
+  ]
+}
+{% endhighlight %}
+
+We can query the table in the usual way:
+
+{% highlight sql %}
+sqlline> !connect jdbc:calcite:model=target/test-classes/model-with-custom-table.json admin admin
+sqlline> SELECT empno, name FROM custom_table.emps;
++--------+--------+
+| EMPNO  |  NAME  |
++--------+--------+
+| 100    | Fred   |
+| 110    | Eric   |
+| 110    | John   |
+| 120    | Wilma  |
+| 130    | Alice  |
++--------+--------+
+{% endhighlight %}
+
+The schema is a regular one, and contains a custom table powered by
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableFactory.java">org.apache.calcite.adapter.csv.CsvTableFactory</a>,
+which implements the Calcite interface
+<a href="{{ site.apiRoot }}/org/apache/calcite/schema/TableFactory.html">TableFactory</a>.
+Its <code>create</code> method instantiates a <code>CsvScannableTable</code>,
+passing in the <code>file</code> argument from the model file:
+
+{% highlight java %}
+public CsvTable create(SchemaPlus schema, String name,
+    Map<String, Object> map, RelDataType rowType) {
+  String fileName = (String) map.get("file");
+  final File file = new File(fileName);
+  final RelProtoDataType protoRowType =
+      rowType != null ? RelDataTypeImpl.proto(rowType) : null;
+  return new CsvScannableTable(file, protoRowType);
+}
+{% endhighlight %}
+
+Implementing a custom table is often a simpler alternative to implementing
+a custom schema. Both approaches might end up creating a similar implementation
+of the <code>Table</code> interface, but for the custom table you don't
+need to implement metadata discovery. (<code>CsvTableFactory</code>
+creates a <code>CsvScannableTable</code>, just as <code>CsvSchema</code> does,
+but the table implementation does not scan the filesystem for .csv files.)
+
+Custom tables require more work for the author of the model (the author
+needs to specify each table and its file explicitly) but also give the author
+more control (say, providing different parameters for each table).
+
+## Comments in models
+
+Models can include comments using `/* ... */` and `//` syntax:
+
+{% highlight json %}
+{
+  version: '1.0',
+  /* Multi-line
+     comment. */
+  defaultSchema: 'CUSTOM_TABLE',
+  // Single-line comment.
+  schemas: [
+    ..
+  ]
+}
+{% endhighlight %}
+
+(Comments are not standard JSON, but are a harmless extension.)
+
+## Optimizing queries using planner rules
+
+The table implementations we have seen so far are fine as long as the tables
+don't contain a great deal of data. But if your customer table has, say, a
+hundred columns and a million rows, you would rather that the system did not
+retrieve all of the data for every query. You would like Calcite to negotiate
+with the adapter and find a more efficient way of accessing the data.
+
+This negotiation is a simple form of query optimization. Calcite supports query
+optimization by adding <i>planner rules</i>. Planner rules operate by
+looking for patterns in the query parse tree (for instance a project on top
+of a certain kind of table), and
+
+Planner rules are also extensible, like schemas and tables. So, if you have a
+data store that you want to access via SQL, you first define a custom table or
+schema, and then you define some rules to make the access efficient.
+
+To see this in action, let's use a planner rule to access
+a subset of columns from a CSV file. Let's run the same query against two very
+similar schemas:
+
+{% highlight sql %}
+sqlline> !connect jdbc:calcite:model=target/test-classes/model.json admin admin
+sqlline> explain plan for select name from emps;
++-----------------------------------------------------+
+| PLAN                                                |
++-----------------------------------------------------+
+| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
+|   EnumerableTableAccessRel(table=[[SALES, EMPS]])   |
++-----------------------------------------------------+
+sqlline> !connect jdbc:calcite:model=target/test-classes/smart.json admin admin
+sqlline> explain plan for select name from emps;
++-----------------------------------------------------+
+| PLAN                                                |
++-----------------------------------------------------+
+| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
+|   CsvTableScan(table=[[SALES, EMPS]])               |
++-----------------------------------------------------+
+{% endhighlight %}
+
+What causes the difference in plan? Let's follow the trail of evidence. In the
+<code>smart.json</code> model file, there is just one extra line:
+
+{% highlight json %}
+flavor: "translatable"
+{% endhighlight %}
+
+This causes a <code>CsvSchema</code> to be created with
+<code>flavor = TRANSLATABLE</code>,
+and its <code>createTable</code> method creates instances of
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTranslatableTable.java">CsvTranslatableTable</a>
+rather than a <code>CsvScannableTable</code>.
+
+<code>CsvTranslatableTable</code> implements the
+<code><a href="{{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html#toRel()">TranslatableTable.toRel()</a></code>
+method to create
+<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableScan.java">CsvTableScan</a>.
+Table scans are the leaves of a query operator tree.
+The usual implementation is
+<code><a href="{{ site.apiRoot }}/org/apache/calcite/adapter/enumerable/EnumerableTableScan.html">EnumerableTableScan</a></code>,
+but we have created a distinctive sub-type that will cause rules to fire.
+
+Here is the rule in its entirety:
+
+{% highlight java %}
+public class CsvProjectTableScanRule extends RelOptRule {
+  public static final CsvProjectTableScanRule INSTANCE =
+      new CsvProjectTableScanRule();
+
+  private CsvProjectTableScanRule() {
+    super(
+        operand(Project.class,
+            operand(CsvTableScan.class, none())),
+        "CsvProjectTableScanRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final Project project = call.rel(0);
+    final CsvTableScan scan = call.rel(1);
+    int[] fields = getProjectFields(project.getProjects());
+    if (fields == null) {
+      // Project contains expressions more complex than just field references.
+      return;
+    }
+    call.transformTo(
+        new CsvTableScan(
+            scan.getCluster(),
+            scan.getTable(),
+            scan.csvTable,
+            fields));
+  }
+
+  private int[] getProjectFields(List<RexNode> exps) {
+    final int[] fields = new int[exps.size()];
+    for (int i = 0; i < exps.size(); i++) {
+      final RexNode exp = exps.get(i);
+      if (exp instanceof RexInputRef) {
+        fields[i] = ((RexInputRef) exp).getIndex();
+      } else {
+        return null; // not a simple projection
+      }
+    }
+    return fields;
+  }
+}
+{% endhighlight %}
+
+The constructor declares the pattern of relational expressions that will cause
+the rule to fire.
+
+The <code>onMatch</code> method generates a new relational expression and calls
+<code><a href="{{ site.apiRoot }}/org/apache/calcite/plan/RelOptRuleCall.html#transformTo(org.apache.calcite.rel.RelNode)">RelOptRuleCall.transformTo()</a></code>
+to indicate that the rule has fired successfully.
+
+## The query optimization process
+
+There's a lot to say about how clever Calcite's query planner is, but we won't
+say it here. The cleverness is designed to take the burden off you, the writer
+of planner rules.
+
+First, Calcite doesn't fire rules in a prescribed order. The query optimization
+process follows many branches of a branching tree, just like a chess playing
+program examines many possible sequences of moves. If rules A and B both match a
+given section of the query operator tree, then Calcite can fire both.
+
+Second, Calcite uses cost in choosing between plans, but the cost model doesn't
+prevent rules from firing which may seem to be more expensive in the short term.
+
+Many optimizers have a linear optimization scheme. Faced with a choice between
+rule A and rule B, as above, such an optimizer needs to choose immediately. It
+might have a policy such as "apply rule A to the whole tree, then apply rule B
+to the whole tree", or apply a cost-based policy, applying the rule that
+produces the cheaper result.
+
+Calcite doesn't require such compromises.
+This makes it simple to combine various sets of rules.
+If, say you want to combine rules to recognize materialized views with rules to
+read from CSV and JDBC source systems, you just give Calcite the set of all
+rules and tell it to go at it.
+
+Calcite does use a cost model. The cost model decides which plan to ultimately
+use, and sometimes to prune the search tree to prevent the search space from
+exploding, but it never forces you to choose between rule A and rule B. This is
+important, because it avoids falling into local minima in the search space that
+are not actually optimal.
+
+Also (you guessed it) the cost model is pluggable, as are the table and query
+operator statistics it is based upon. But that can be a subject for later.
+
+## JDBC adapter
+
+The JDBC adapter maps a schema in a JDBC data source as a Calcite schema.
+
+For example, this schema reads from a MySQL "foodmart" database:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART',
+  schemas: [
+    {
+      name: 'FOODMART',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    }
+  ]
+}
+{% endhighlight %}
+
+(The FoodMart database will be familiar to those of you who have used
+the Mondrian OLAP engine, because it is Mondrian's main test data
+set. To load the data set, follow <a
+href="http://mondrian.pentaho.com/documentation/installation.php#2_Set_up_test_data">Mondrian's
+installation instructions</a>.)
+
+<b>Current limitations</b>: The JDBC adapter currently only pushes
+down table scan operations; all other processing (filtering, joins,
+aggregations and so forth) occurs within Calcite. Our goal is to push
+down as much processing as possible to the source system, translating
+syntax, data types and built-in functions as we go. If a Calcite query
+is based on tables from a single JDBC database, in principle the whole
+query should go to that database. If tables are from multiple JDBC
+sources, or a mixture of JDBC and non-JDBC, Calcite will use the most
+efficient distributed query approach that it can.
+
+## The cloning JDBC adapter
+
+The cloning JDBC adapter creates a hybrid database. The data is
+sourced from a JDBC database but is read into in-memory tables the
+first time each table is accessed. Calcite evaluates queries based on
+those in-memory tables, effectively a cache of the database.
+
+For example, the following model reads tables from a MySQL
+"foodmart" database:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART_CLONE',
+  schemas: [
+    {
+      name: 'FOODMART_CLONE',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    }
+  ]
+}
+{% endhighlight %}
+
+Another technique is to build a clone schema on top of an existing
+schema. You use the <code>source</code> property to reference a schema
+defined earlier in the model, like this:
+
+{% highlight json %}
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART_CLONE',
+  schemas: [
+    {
+      name: 'FOODMART',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    },
+    {
+      name: 'FOODMART_CLONE',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
+      operand: {
+        source: 'FOODMART'
+      }
+    }
+  ]
+}
+{% endhighlight %}
+
+You can use this approach to create a clone schema on any type of
+schema, not just JDBC.
+
+The cloning adapter isn't the be-all and end-all. We plan to develop
+more sophisticated caching strategies, and a more complete and
+efficient implementation of in-memory tables, but for now the cloning
+JDBC adapter shows what is possible and allows us to try out our
+initial implementations.
+
+## Further topics
+
+### Defining a custom schema
+
+(To be written.)
+
+### Modifying data
+
+How to enable DML operations (INSERT, UPDATE and DELETE) on your schema.
+
+(To be written.)
+
+### Calling conventions
+
+(To be written.)
+
+### Statistics and cost
+
+(To be written.)
+
+### Defining and using user-defined functions
+
+(To be written.)
+
+###  Defining tables in a schema
+
+(To be written.)
+
+### Defining custom tables
+
+(To be written.)
+
+### Built-in SQL implementation
+
+How does Calcite implement SQL, if an adapter does not implement all of the core
+relational operators?
+
+(To be written.)
+
+### Table functions
+
+(To be written.)

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/anchor_links.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/anchor_links.html b/avatica/site/_includes/anchor_links.html
new file mode 100644
index 0000000..c584ce5
--- /dev/null
+++ b/avatica/site/_includes/anchor_links.html
@@ -0,0 +1,33 @@
+<script>
+  var anchorForId = function (id) {
+    var anchor = document.createElement("a");
+    anchor.className = "header-link";
+    anchor.href      = "#" + id;
+    anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
+    anchor.title = "Permalink";
+    return anchor;
+  };
+
+  var linkifyAnchors = function (level, containingElement) {
+    var headers = containingElement.getElementsByTagName("h" + level);
+    for (var h = 0; h < headers.length; h++) {
+      var header = headers[h];
+
+      if (typeof header.id !== "undefined" && header.id !== "") {
+        header.appendChild(anchorForId(header.id));
+      }
+    }
+  };
+
+  document.onreadystatechange = function () {
+    if (this.readyState === "complete") {
+      var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
+      if (!contentBlock) {
+        return;
+      }
+      for (var level = 1; level <= 6; level++) {
+        linkifyAnchors(level, contentBlock);
+      }
+    }
+  };
+</script>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/docs_contents.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/docs_contents.html b/avatica/site/_includes/docs_contents.html
new file mode 100644
index 0000000..2ac64bb
--- /dev/null
+++ b/avatica/site/_includes/docs_contents.html
@@ -0,0 +1,8 @@
+<div class="unit one-fifth hide-on-mobiles">
+  <aside>
+    {% for section in site.data.docs %}
+    <h4>{{ section.title }}</h4>
+    {% include docs_ul.html items=section.docs %}
+    {% endfor %}
+  </aside>
+</div>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/docs_contents_mobile.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/docs_contents_mobile.html b/avatica/site/_includes/docs_contents_mobile.html
new file mode 100644
index 0000000..b3e0110
--- /dev/null
+++ b/avatica/site/_includes/docs_contents_mobile.html
@@ -0,0 +1,10 @@
+<div class="docs-nav-mobile unit whole show-on-mobiles">
+  <select onchange="if (this.value) window.location.href=this.value">
+    <option value="">Navigate the docs…</option>
+    {% for section in site.data.docs %}
+    <optgroup label="{{ section.title }}">
+      {% include docs_option.html items=section.docs %}
+    </optgroup>
+    {% endfor %}
+  </select>
+</div>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/docs_option.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/docs_option.html b/avatica/site/_includes/docs_option.html
new file mode 100644
index 0000000..8c61578
--- /dev/null
+++ b/avatica/site/_includes/docs_option.html
@@ -0,0 +1,11 @@
+{% assign items = include.items %}
+
+{% for item in items %}
+  {% assign item_url = item | prepend:"{{ site.baseurl }}/docs/" | append:".html" %}
+
+  {% for p in site.docs %}
+    {% if p.url == item_url %}
+      <option value="{{ site.url }}{{ p.url }}">{{ p.title }}</option>
+    {% endif %}
+  {% endfor %}
+{% endfor %}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/docs_ul.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/docs_ul.html b/avatica/site/_includes/docs_ul.html
new file mode 100644
index 0000000..768259c
--- /dev/null
+++ b/avatica/site/_includes/docs_ul.html
@@ -0,0 +1,29 @@
+{% assign items = include.items %}
+
+<ul>
+{% for item in items %}
+  {% comment %} Account for the baseurl to make sure we compare the full URI. {% endcomment %}
+  {% capture item_url %}{{site.baseurl}}{{ item | prepend:"/docs/" | append:".html" }}{% endcapture %}
+  {% capture current_url %}{{ site.baseurl }}{{ page.url }}{% endcapture %}
+
+  {% if item_url == current_url %}
+    {% assign c = "current" %}
+  {% else %}
+    {% assign c = "" %}
+  {% endif %}
+
+  {% for p in site.docs %}
+    {% capture p_url %}{{site.baseurl}}{{p.url}}{% endcapture %}
+    {% if p.sidebar_title != nil %}
+      {% assign anchor_text = p.sidebar_title %}
+    {% else %}
+      {% assign anchor_text = p.title %}
+    {% endif %}
+    {% if p_url == item_url %}
+      <li class="{{ c }}"><a href="{{ p_url }}">{{ anchor_text }}</a></li>
+      {% break %}
+    {% endif %}
+  {% endfor %}
+
+{% endfor %}
+</ul>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/footer.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/footer.html b/avatica/site/_includes/footer.html
new file mode 100644
index 0000000..f965817
--- /dev/null
+++ b/avatica/site/_includes/footer.html
@@ -0,0 +1,15 @@
+<footer role="contentinfo">
+  <div id="poweredby">
+    <a href="http://www.apache.org/">
+      <span class="sr-only">Apache</span>
+      <img src="{{ site.baseurl }}/img/feather.png" width="190" height="77" alt="Apache Logo"></a>
+  </div>
+  <div id="copyright">
+  <p>The contents of this website are &copy;&nbsp;{{ site.time | date: '%Y' }}
+     <a href="https://www.apache.org/">Apache Software Foundation</a>
+     under the terms of
+     the <a href="https://www.apache.org/licenses/LICENSE-2.0.html">
+     Apache&nbsp;License&nbsp;v2</a>. Apache Calcite and its logo are
+     trademarks of the Apache Software Foundation.</p>
+  </div>
+</footer>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/header.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/header.html b/avatica/site/_includes/header.html
new file mode 100644
index 0000000..7d42786
--- /dev/null
+++ b/avatica/site/_includes/header.html
@@ -0,0 +1,18 @@
+<header role="banner">
+  <nav class="mobile-nav show-on-mobiles">
+    {% include primary-nav-items.html %}
+  </nav>
+  <div class="grid">
+    <div class="unit one-third center-on-mobiles">
+      <h1>
+        <a href="{{ site.baseurl }}/">
+          <span class="sr-only">Apache Calcite</span>
+          <img src="{{ site.baseurl }}/img/logo.png" width="226" height="140" alt="Calcite Logo">
+        </a>
+      </h1>
+    </div>
+    <nav class="main-nav unit two-thirds hide-on-mobiles">
+      {% include primary-nav-items.html %}
+    </nav>
+  </div>
+</header>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/news_contents.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/news_contents.html b/avatica/site/_includes/news_contents.html
new file mode 100644
index 0000000..d1481e7
--- /dev/null
+++ b/avatica/site/_includes/news_contents.html
@@ -0,0 +1,30 @@
+<div class="unit one-fifth hide-on-mobiles">
+  <aside>
+    <ul>
+      <li class="{% if page.title == 'News' %}current{% endif %}">
+        <a href="{{ site.baseurl }}/news/">All News</a>
+      </li>
+      <li class="{% if page.title == 'Releases' %}current{% endif %}">
+        <a href="{{ site.baseurl }}/news/releases/">Calcite Releases</a>
+      </li>
+    </ul>
+    <h4>Recent Releases</h4>
+    <ul>
+      {% for post in site.categories.release limit:5 %}
+      <li class="{% if page.title == post.title %}current{% endif %}">
+        <a href="{{ site.baseurl }}{{ post.url }}">{{ post.version }}</a>
+      </li>
+      {% endfor %}
+    </ul>
+    <h4>Other News</h4>
+    <ul>
+        {% for post in site.posts %}
+        {% unless post.categories contains 'release' %}
+        <li class="{% if page.title == post.title %}current{% endif %}">
+          <a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
+        </li>
+        {% endunless %}
+        {% endfor %}
+    </ul>
+  </aside>
+</div>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/news_contents_mobile.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/news_contents_mobile.html b/avatica/site/_includes/news_contents_mobile.html
new file mode 100644
index 0000000..094da46
--- /dev/null
+++ b/avatica/site/_includes/news_contents_mobile.html
@@ -0,0 +1,11 @@
+<div class="docs-nav-mobile unit whole show-on-mobiles">
+  <select onchange="if (this.value) window.location.href=this.value">
+    <option value="">Navigate the blog…</option>
+    <option value="{{ site.baseurl }}/news/">Home</option>
+    <optgroup label="v1.x">
+      {% for post in site.posts %}
+      <option value="{{ post.url }}">{{ post.title }}</option>
+      {% endfor %}
+    </optgroup>
+  </select>
+</div>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/news_item.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/news_item.html b/avatica/site/_includes/news_item.html
new file mode 100644
index 0000000..34eea0b
--- /dev/null
+++ b/avatica/site/_includes/news_item.html
@@ -0,0 +1,62 @@
+{% comment %}
+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.
+{% endcomment %}
+<article>
+  <h2>
+    <a href="{{ site.baseurl }}{{ post.url }}">
+      {{ post.title }}
+    </a>
+  </h2>
+  <span class="post-category">
+    <span class="label">
+      {{ post.categories | array_to_sentence_string }}
+    </span>
+  </span>
+  <div class="post-meta">
+    <span class="post-date">
+      {{ post.date | date_to_string }}
+    </span>
+    {% capture homepage %}http://people.apache.org/~{{ post.author }}{% endcapture %}
+    {% capture avatar %}http://people.apache.org/~{{ post.author }}/{{ post.author }}.jpg{% endcapture %}
+    {% for c in site.data.contributors %}
+      {% if c.apacheId == post.author %}
+        {% if c.homepage %}
+          {% assign homepage = c.homepage %}
+        {% else %}
+          {% capture homepage %}http://github.com/{{ c.githubId }}{% endcapture %}
+        {% endif %}
+        {% if c.avatar %}
+          {% assign avatar = c.avatar %}
+        {% else %}
+          {% capture avatar %}http://github.com/{{ c.githubId }}.png{% endcapture %}
+        {% endif %}
+      {% endif %}
+    {% endfor %}
+    <a href="{{ homepage }}" class="post-author">
+      <img src="{{ avatar }}"
+           class="avatar" alt="{{ post.author }} avatar"
+           width="24" height="24">
+      {{ post.author }}
+    </a>
+  </div>
+  <div class="post-content">
+    {{ post.content }}
+    {% if post.categories contains 'release' %}
+    <p>See the <a href="{{ site.baseurl }}/docs/history.html#{{ post.tag }}">release notes</a>;
+      <a href="{{ site.baseurl }}/downloads#source-releases">download</a> the release.</p>
+    {% endif %}
+  </div>
+</article>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/primary-nav-items.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/primary-nav-items.html b/avatica/site/_includes/primary-nav-items.html
new file mode 100644
index 0000000..687cdd2
--- /dev/null
+++ b/avatica/site/_includes/primary-nav-items.html
@@ -0,0 +1,20 @@
+<ul>
+  <li class="{% if page.overview %}current{% endif %}">
+    <a href="{{ site.baseurl }}/">Home</a>
+  </li>
+  <li class="{% if page.url contains '/downloads/' %}current{% endif %}">
+    <a href="{{ site.baseurl }}/downloads/">Download</a>
+  </li>
+  <li class="{% if page.url contains '/community/' %}current{% endif %}">
+    <a href="{{ site.baseurl }}/community/">Community</a>
+  </li>
+  <li class="{% if page.url contains '/develop/' %}current{% endif %}">
+    <a href="{{ site.baseurl }}/develop/">Develop</a>
+  </li>
+  <li class="{% if page.url contains '/news/' %}current{% endif %}">
+    <a href="{{ site.baseurl }}/news/">News</a>
+  </li>
+  <li class="{% if page.url contains '/docs/' %}current{% endif %}">
+    <a href="{{ site.baseurl }}/docs/">Docs</a>
+  </li>
+</ul>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/section_nav.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/section_nav.html b/avatica/site/_includes/section_nav.html
new file mode 100644
index 0000000..b025a70
--- /dev/null
+++ b/avatica/site/_includes/section_nav.html
@@ -0,0 +1,39 @@
+{% comment %}
+Map grabs the doc sections, giving us an array of arrays. Join, flattens all
+the items to a comma delimited string. Split turns it into an array again.
+{% endcomment %}
+{% assign docs = site.data.docs | map: 'docs' | join: ',' | split: ',' %}
+
+{% comment %}
+Because this is built for every page, lets find where we are in the ordered
+document list by comparing url strings. Then if there's something previous or
+next, lets build a link to it.
+{% endcomment %}
+
+{% for document in docs %}
+  {% assign document_url = document | prepend:"/docs/" | append:".html" %}
+  {% if document_url == page.url %}
+    <div class="section-nav">
+      <div class="left align-right">
+          {% if forloop.first %}
+            <span class="prev disabled">Previous</span>
+          {% else %}
+            {% assign previous = forloop.index0 | minus: 1 %}
+            {% capture previous_page %}{{ site.baseurl }}{{docs[previous] | prepend:"/docs/" | append:".html" }}{% endcapture %}
+            <a href="{{ previous_page }}" class="prev">Previous</a>
+          {% endif %}
+      </div>
+      <div class="right align-left">
+          {% if forloop.last %}
+            <span class="next disabled">Next</span>
+          {% else %}
+            {% assign next = forloop.index0 | plus: 1 %}
+            {% capture next_page %}{{ site.baseurl }}{{ docs[next] | prepend:"/docs/" | append:".html" }}{% endcapture %}
+            <a href="{{ next_page }}" class="next">Next</a>
+          {% endif %}
+      </div>
+    </div>
+    <div class="clear"></div>
+    {% break %}
+  {% endif %}
+{% endfor %}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_includes/top.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/top.html b/avatica/site/_includes/top.html
new file mode 100644
index 0000000..6eab814
--- /dev/null
+++ b/avatica/site/_includes/top.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <title>{{ page.title }}</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <meta name="generator" content="Jekyll v{{ jekyll.version }}">
+  <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
+  <link rel="stylesheet" href="{{ site.baseurl }}/css/screen.css">
+  <link rel="icon" type="image/x-icon" href="{{ site.baseurl }}/favicon.ico">
+  <!--[if lt IE 9]>
+  <script src="/js/html5shiv.min.js"></script>
+  <script src="/js/respond.min.js"></script>
+  <![endif]-->
+</head>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/default.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/default.html b/avatica/site/_layouts/default.html
new file mode 100644
index 0000000..f734c79
--- /dev/null
+++ b/avatica/site/_layouts/default.html
@@ -0,0 +1,12 @@
+{% include top.html %}
+
+<body class="wrap">
+  {% include header.html %}
+
+  {{ content }}
+
+  {% include footer.html %}
+  {% include anchor_links.html %}
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/docs.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/docs.html b/avatica/site/_layouts/docs.html
new file mode 100644
index 0000000..a0a8a5c
--- /dev/null
+++ b/avatica/site/_layouts/docs.html
@@ -0,0 +1,23 @@
+---
+layout: default
+---
+
+  <section class="docs">
+    <div class="grid">
+
+      {% include docs_contents_mobile.html %}
+
+      <div class="unit four-fifths">
+        <article>
+          <h1>{{ page.title }}</h1>
+          {{ content }}
+          {% include section_nav.html %}
+        </article>
+      </div>
+
+      {% include docs_contents.html %}
+
+      <div class="clear"></div>
+
+    </div>
+  </section>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/external.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/external.html b/avatica/site/_layouts/external.html
new file mode 100644
index 0000000..b934309
--- /dev/null
+++ b/avatica/site/_layouts/external.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>{{ page.title }}</title>
+
+    <meta http-equiv="refresh" content="0;url={{ page.external_url }}">
+  </head>
+  <body><!-- Google Analytics JavaScript --></body>
+</html>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/news.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/news.html b/avatica/site/_layouts/news.html
new file mode 100644
index 0000000..8f7945f
--- /dev/null
+++ b/avatica/site/_layouts/news.html
@@ -0,0 +1,19 @@
+---
+layout: default
+---
+
+  <section class="news">
+    <div class="grid">
+
+      {% include news_contents_mobile.html %}
+
+      <div class="unit four-fifths">
+        {{ content }}
+      </div>
+
+      {% include news_contents.html %}
+
+      <div class="clear"></div>
+
+    </div>
+  </section>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/news_item.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/news_item.html b/avatica/site/_layouts/news_item.html
new file mode 100644
index 0000000..e91e9e5
--- /dev/null
+++ b/avatica/site/_layouts/news_item.html
@@ -0,0 +1,49 @@
+---
+layout: news
+---
+
+<article>
+  <h2>
+    {{ page.title }}
+    <a href="{{ page.url }}" class="permalink" title="Permalink">∞</a>
+  </h2>
+  <span class="post-category">
+    <span class="label">
+      {{ page.categories | array_to_sentence_string }}
+    </span>
+  </span>
+  <div class="post-meta">
+    <span class="post-date">
+      {{ page.date | date_to_string }}
+    </span>
+    {% capture homepage %}http://people.apache.org/~{{ page.author }}{% endcapture %}
+    {% capture avatar %}http://people.apache.org/~{{ page.author }}/{{ page.author }}.jpg{% endcapture %}
+    {% for c in site.data.contributors %}
+      {% if c.apacheId == page.author %}
+        {% if c.homepage %}
+          {% assign homepage = c.homepage %}
+        {% else %}
+          {% capture homepage %}http://github.com/{{ c.githubId }}{% endcapture %}
+        {% endif %}
+        {% if c.avatar %}
+          {% assign avatar = c.avatar %}
+        {% else %}
+          {% capture avatar %}http://github.com/{{ c.githubId }}.png{% endcapture %}
+        {% endif %}
+      {% endif %}
+    {% endfor %}
+    <a href="{{ homepage }}" class="post-author">
+      <img src="{{ avatar }}"
+           class="avatar" alt="{{ page.author }} avatar"
+           width="24" height="24">
+      {{ page.author }}
+    </a>
+  </div>
+  <div class="post-content">
+    {{ content }}
+    {% if page.categories contains 'release' %}
+    <p>See the <a href="{{ site.baseurl }}/docs/history.html#{{ page.tag }}">release notes</a>;
+      <a href="{{ site.baseurl }}/downloads#source-releases">download</a> the release.</p>
+    {% endif %}
+  </div>
+</article>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_layouts/page.html
----------------------------------------------------------------------
diff --git a/avatica/site/_layouts/page.html b/avatica/site/_layouts/page.html
new file mode 100644
index 0000000..bae31bb
--- /dev/null
+++ b/avatica/site/_layouts/page.html
@@ -0,0 +1,18 @@
+---
+layout: default
+---
+
+<section class="standalone">
+  <div class="grid">
+
+    <div class="unit whole">
+      <article>
+        <h1>{{ page.title }}</h1>
+        {{ content }}
+      </article>
+    </div>
+
+    <div class="clear"></div>
+
+  </div>
+</section>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_plugins/bundler.rb
----------------------------------------------------------------------
diff --git a/avatica/site/_plugins/bundler.rb b/avatica/site/_plugins/bundler.rb
new file mode 100644
index 0000000..1cdec10
--- /dev/null
+++ b/avatica/site/_plugins/bundler.rb
@@ -0,0 +1,20 @@
+# 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.
+#
+require "rubygems"
+require "bundler/setup"
+Bundler.require(:default)
+
+# End bundler.rb

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md b/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
new file mode 100644
index 0000000..83f975d
--- /dev/null
+++ b/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
@@ -0,0 +1,31 @@
+---
+layout: news_item
+date: "2014-06-27 00:00:00 -0800"
+author: jhyde
+version: 0.8
+tag: v0-8
+sha: 3da850a1
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Several new features, including a heuristic rule to plan queries with
+a large number of joins, a number of windowed aggregate functions, and
+new utility, `SqlRun`.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md b/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
new file mode 100644
index 0000000..7ca65ac
--- /dev/null
+++ b/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
@@ -0,0 +1,30 @@
+---
+layout: news_item
+date: "2014-08-19 00:00:00 -0800"
+author: jhyde
+version: 0.9.0-incubating
+fullVersion: apache-optiq-0.9.0-incubating
+tag: v0-9-0
+sha: 45e5269b
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This is the first release under the Apache incubator process.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md b/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
new file mode 100644
index 0000000..bca9113
--- /dev/null
+++ b/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
@@ -0,0 +1,29 @@
+---
+layout: news_item
+date: "2014-10-02 00:00:00 -0800"
+author: jhyde
+version: 0.9.1-incubating
+tag: v0-9-1
+sha: 68012573
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This is the first release as Calcite. (The project was previously called Optiq.)

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md b/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
new file mode 100644
index 0000000..47741c0
--- /dev/null
+++ b/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
@@ -0,0 +1,32 @@
+---
+layout: news_item
+date: "2014-11-05 00:00:00 -0800"
+author: jhyde
+version: 0.9.2-incubating
+tag: v0-9-2
+sha: 0404fd23
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+A fairly minor release, and last release before we rename all of the
+packages and lots of classes, in what we expect to call 1.0. If you
+have an existing application, it's worth upgrading to this first,
+before you move on to 1.0.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md b/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
new file mode 100644
index 0000000..ad60205
--- /dev/null
+++ b/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
@@ -0,0 +1,42 @@
+---
+layout: news_item
+date: "2015-01-31 19:03:07 -0800"
+author: jhyde
+version: 1.0.0-incubating
+tag: v1-0-0
+sha: 2dd83f2
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Calcite's first major release.
+
+Since the previous release we have re-organized the into the `org.apache.calcite`
+namespace. To make migration of your code easier, we have described the
+<a href="https://issues.apache.org/jira/secure/attachment/12681620/mapping.txt">mapping from old to new class names</a>
+as an attachment to
+[<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>].
+
+The release adds SQL support for `GROUPING SETS`, `EXTEND`, `UPSERT` and sequences;
+a remote JDBC driver;
+improvements to the planner engine and built-in planner rules;
+improvements to the algorithms that implement the relational algebra,
+including an interpreter that can evaluate queries without compilation;
+and fixes about 30 bugs.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md b/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
new file mode 100644
index 0000000..327b023
--- /dev/null
+++ b/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
@@ -0,0 +1,41 @@
+---
+layout: news_item
+date: "2015-03-13 19:03:07 -0800"
+author: jhyde
+version: 1.1.0-incubating
+tag: v1-1-0
+sha: f10ea367
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This Calcite release makes it possible to exploit physical properties
+of relational expressions to produce more efficient plans, introducing
+collation and distribution as traits, `Exchange` relational operator,
+and several new forms of metadata.
+
+We add experimental support for streaming SQL.
+
+This release drops support for JDK 1.6; Calcite now requires 1.7 or
+later.
+
+We have introduced static `create` methods for many sub-classes of
+`RelNode`. We strongly suggest that you use these rather than
+calling constructors directly.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md b/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
new file mode 100644
index 0000000..8332063
--- /dev/null
+++ b/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
@@ -0,0 +1,41 @@
+---
+layout: news_item
+date: "2015-04-07 19:03:07 -0800"
+author: jhyde
+version: 1.2.0-incubating
+tag: v1-2-0
+sha: d60f2aa
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+A short release, less than a month after 1.1.
+
+There have been many changes to Avatica, hugely improving its coverage of the
+JDBC API and overall robustness. A new provider, `JdbcMeta`, allows
+you to remote an existing JDBC driver.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
+improves how the planner propagates traits such as collation and
+distribution among relational expressions.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
+and [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
+improve implicit and explicit conversions in SQL.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-04-24-new-committers.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-04-24-new-committers.md b/avatica/site/_posts/2015-04-24-new-committers.md
new file mode 100644
index 0000000..92a2466
--- /dev/null
+++ b/avatica/site/_posts/2015-04-24-new-committers.md
@@ -0,0 +1,34 @@
+---
+layout: news_item
+title: "Calcite adds 5 committers"
+date: "2015-04-24 19:03:07 -0800"
+author: jhyde
+categories: [team]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+The Calcite project management committee today added five new
+committers for their work on Calcite. Welcome all!
+
+* Aman Sinha
+* Jesús Camacho-Rodríguez
+* Jinfeng Ni
+* John Pullokkaran
+* Nick Dimiduk

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md b/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
new file mode 100644
index 0000000..b72765f
--- /dev/null
+++ b/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
@@ -0,0 +1,33 @@
+---
+layout: news_item
+date: "2015-05-30 23:05:37 +0000"
+author: jhyde
+version: 1.3.0-incubating
+categories: [release]
+tag: v1-3-0
+sha: 495f1859
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Mainly bug-fixes, but this release adds support for
+<a href="https://issues.apache.org/jira/browse/CALCITE-505">modifiable views</a>
+and
+<a href="https://issues.apache.org/jira/browse/CALCITE-704">filtered aggregate functions</a>
+and various improvements to Avatica.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-06-05-algebra-builder.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-06-05-algebra-builder.md b/avatica/site/_posts/2015-06-05-algebra-builder.md
new file mode 100644
index 0000000..ddf3377
--- /dev/null
+++ b/avatica/site/_posts/2015-06-05-algebra-builder.md
@@ -0,0 +1,87 @@
+---
+layout: news_item
+title: "Algebra builder"
+date: "2015-06-05 19:29:07 -0800"
+author: jhyde
+categories: ["new features"]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Calcite's foundation is a comprehensive implementation of relational
+algebra (together with transformation rules, cost model, and metadata)
+but to create algebra expressions you had to master a complex API.
+
+We're solving this problem by introducing an
+[algebra builder]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html),
+a single class with all the methods you need to build any relational
+expression.
+
+For example,
+
+{% highlight java %}
+final FrameworkConfig config;
+final RelBuilder builder = RelBuilder.create(config);
+final RelNode node = builder
+  .scan("EMP")
+  .aggregate(builder.groupKey("DEPTNO"),
+      builder.count(false, "C"),
+      builder.sum(false, "S", builder.field("SAL")))
+  .filter(
+      builder.call(SqlStdOperatorTable.GREATER_THAN,
+          builder.field("C"),
+          builder.literal(10)))
+  .build();
+System.out.println(RelOptUtil.toString(node));
+{% endhighlight %}
+
+creates the algebra
+
+{% highlight text %}
+LogicalFilter(condition=[>($1, 10)])
+  LogicalAggregate(group=[{7}], C=[COUNT()], S=[SUM($5)])
+    LogicalTableScan(table=[[scott, EMP]])
+{% endhighlight %}
+
+which is equivalent to the SQL
+
+{% highlight sql %}
+SELECT deptno, count(*) AS c, sum(sal) AS s
+FROM emp
+GROUP BY deptno
+HAVING count(*) > 10
+{% endhighlight %}
+
+The [algebra builder documentation]({{ site.baseurl }}/docs/algebra.html) describes the
+full API and has lots of examples.
+
+We're still working on the algebra builder, but plan to release it
+with Calcite 1.4 (see
+[[CALCITE-748](https://issues.apache.org/jira/browse/CALCITE-748)]).
+
+The algebra builder will make some existing tasks easier (such as
+writing planner rules), but will also enable new things, such as
+writing applications directly on top of Calcite, or implementing
+non-SQL query languages. These applications and languages will be able
+to take advantage of Calcite's existing back-ends (including
+Hive-on-Tez, Drill, MongoDB, Splunk, Spark, JDBC data sources) and
+extensive set of query-optimization rules.
+
+If you have questions or comments, please post to the
+[mailing list]({{ site.baseurl }}/develop).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md b/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
new file mode 100644
index 0000000..b0e1f46
--- /dev/null
+++ b/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
@@ -0,0 +1,41 @@
+---
+layout: news_item
+title: "XLDB 2015 best lightning talk"
+date: "2015-07-31 11:53:00 -0800"
+author: jhyde
+categories: ["talks"]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Julian Hyde's talk Apache Calcite: One planner fits all won
+[Best Lightning Talk](http://www.xldb.org/archives/2015/05/best-lightning-talks-selected/)
+at the XLDB-2015 conference (with Eric Tschetter's talk "Sketchy
+Approximations").
+
+XLDB is an annual conference that brings together experts from
+science, industry and academia to find practical solutions to problems
+involving extremely large data sets.
+
+As a result of winning Best Lightning Talk, Julian will get a 30
+minute keynote speaking slot at XLDB-2016.
+
+The talk is available in
+[slides](http://www.slideshare.net/julianhyde/apache-calcite-one-planner-fits-all)
+and [video](https://www.youtube.com/watch?v=5_MyORYjq3w).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md b/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
new file mode 100644
index 0000000..6a2bde4
--- /dev/null
+++ b/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
@@ -0,0 +1,39 @@
+---
+layout: news_item
+date: "2015-09-02 12:00:00 +0000"
+author: jhyde
+version: 1.4.0-incubating
+categories: [release]
+tag: v1-4-0
+sha: 0c0c203d
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+In addition to a large number of bug fixes and minor enhancements,
+this release includes improvements to
+<a href="https://issues.apache.org/jira/browse/CALCITE-758">lattices</a> and
+<a href="https://issues.apache.org/jira/browse/CALCITE-761">materialized views</a>,
+and adds a
+<a href="https://issues.apache.org/jira/browse/CALCITE-748">builder API</a>
+so that you can easily create relational algebra expressions.
+
+Read more about the [builder]({{ site.baseurl }}/news/2015/06/05/algebra-builder/),
+[relational algebra]({{ site.baseurl }}/docs/algebra.html), and
+[lattices]({{ site.baseurl }}/docs/lattice.html).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-10-22-calcite-graduates.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-10-22-calcite-graduates.md b/avatica/site/_posts/2015-10-22-calcite-graduates.md
new file mode 100644
index 0000000..fb954cb
--- /dev/null
+++ b/avatica/site/_posts/2015-10-22-calcite-graduates.md
@@ -0,0 +1,63 @@
+---
+layout: news_item
+date: "2015-10-22 12:00:00 +0000"
+author: jhyde
+categories: [milestones]
+tag: v1-4-0
+sha: 0c0c203d
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+On October 21st, 2015 the board of the
+[Apache Software Foundation](http://www.apache.org)
+voted to establish Calcite as a top-level Apache project.
+
+![Calcite's graduation cake]({{ site.baseurl }}/img/cake.jpg)
+
+Describing itself as "the foundation for your next high-performance
+database", Calcite is a
+[framework for building data management systems]({{ site.baseurl }}/docs/).
+Calcite includes a comprehensive implementation of relational algebra
+and an extensible cost-based query optimizer. It also includes an
+optional SQL parser and JDBC driver.
+
+Calcite joined Apache as an incubator project in May, 2014. To
+graduate from the incubator, projects have to prove that they can
+create high quality releases, form a diverse community, and operate as
+a meritocracy.
+
+Calcite's committers have delivered eight releases during incubation
+(roughly one every two months) including the
+[milestone 1.0 release in January, 2015]({{ site.baseurl }}/news/2015/01/31/release-1.0.0-incubating/).
+
+The project has become a key component in many high-performance
+databases, including the
+[Apache Drill](http://drill.apache.org),
+[Apache Hive](http://hive.apache.org),
+[Apache Kylin](http://kylin.apache.org) and
+[Apache Phoenix](http://phoenix.apache.org) open source projects,
+and several commercial products.
+
+Also, in collaboration with [Apache Samza](http://samza.apache.org) and
+[Apache Storm](http://storm.apache.org), Calcite is developing
+[streaming extensions to standard SQL]({{ site.baseurl }}/docs/stream.html).
+
+The Calcite community met at a hangout on October 27th, 2015, and
+celebrated with a graduation cake.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-11-08-new-committers.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-11-08-new-committers.md b/avatica/site/_posts/2015-11-08-new-committers.md
new file mode 100644
index 0000000..8946fc5
--- /dev/null
+++ b/avatica/site/_posts/2015-11-08-new-committers.md
@@ -0,0 +1,31 @@
+---
+layout: news_item
+title: "Calcite adds 2 committers"
+date: "2015-11-08 19:03:07 -0800"
+author: jhyde
+categories: [team]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+The Calcite project management committee today added two new
+committers for their work on Calcite. Welcome!
+
+* [Josh Elser](http://mail-archives.apache.org/mod_mbox/incubator-calcite-dev/201511.mbox/%3CCAPSgeEQ4%2Bj8MNjYFaa%3D15QjJV%2BiVDwG6bAhW1muk8Gdo0UAYWg%40mail.gmail.com%3E)
+* [Maryann Xue](http://mail-archives.apache.org/mod_mbox/incubator-calcite-dev/201511.mbox/%3CCAPSgeEQg7ACNWfPXiPY69PNPqA9ov%2BKGzzrNe7t7mMyOEV7hYQ%40mail.gmail.com%3E)

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2015-11-10-release-1.5.0.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-11-10-release-1.5.0.md b/avatica/site/_posts/2015-11-10-release-1.5.0.md
new file mode 100644
index 0000000..e4bb8d1
--- /dev/null
+++ b/avatica/site/_posts/2015-11-10-release-1.5.0.md
@@ -0,0 +1,33 @@
+---
+layout: news_item
+date: "2015-11-10 12:00:00 +0000"
+author: jcamacho
+version: 1.5.0
+categories: [release]
+tag: v1-5-0
+sha: ba6e43c
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This is our first release as a top-level Apache project! Thanks to everyone who has contributed to it.
+
+In addition to a large number of bug fixes and minor enhancements, this release includes major improvements to Avatica, planner rules, and RelBuilder.
+
+Further, we built Piglet, a subset of the classic Hadoop language Pig. Pig is particularly interesting because it makes heavy use of nested multi-sets. You can follow this example to implement your own query language, and immediately taking advantage of Calcite's back-ends and optimizer rules.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2016-01-22-release-1.6.0.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-01-22-release-1.6.0.md b/avatica/site/_posts/2016-01-22-release-1.6.0.md
new file mode 100644
index 0000000..beb5267
--- /dev/null
+++ b/avatica/site/_posts/2016-01-22-release-1.6.0.md
@@ -0,0 +1,59 @@
+---
+layout: news_item
+date: "2016-01-22 12:00:00 +0000"
+author: jhyde
+version: 1.6.0
+categories: [release]
+tag: v1-6-0
+sha: c4d346b
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+As usual in this release, there are new SQL features, improvements to
+planning rules and Avatica, and lots of bug fixes. We'll spotlight a
+couple of features make it easier to handle complex queries.
+
+[<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
+allows you to represent sub-queries (`EXISTS`, `IN` and scalar) as
+<a href="{{ site.apiRoot }}/org/apache/calcite/rex/RexSubQuery.html">RexSubQuery</a>,
+a kind of expression in the relational algebra. Until
+now, the sql-to-rel converter was burdened with expanding sub-queries,
+and people creating relational algebra directly (or via
+<a href="{{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html">RelBuilder</a>)
+could only create 'flat' relational expressions. Now we have planner
+rules to expand and de-correlate sub-queries.
+
+Metadata is the fuel that powers query planning. It includes
+traditional query-planning statistics such as cost and row-count
+estimates, but also information such as which columns form unique
+keys, unique and what predicates are known to apply to a relational
+expression's output rows. From the predicates we can deduce which
+columns are constant, and following
+[<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
+we can now remove constant columns from `GROUP BY` keys.
+
+Metadata is often computed recursively, and it is hard to safely and
+efficiently calculate metadata on a graph of `RelNode`s that is large,
+frequently cyclic, and constantly changing.
+[<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
+introduces a context to each metadata call. That context can detect
+cyclic metadata calls and produce a safe answer to the metadata
+request. It will also allow us to add finer-grained caching and
+further tune the metadata layer.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2016-02-17-elser-pmc.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-02-17-elser-pmc.md b/avatica/site/_posts/2016-02-17-elser-pmc.md
new file mode 100644
index 0000000..960fe79
--- /dev/null
+++ b/avatica/site/_posts/2016-02-17-elser-pmc.md
@@ -0,0 +1,33 @@
+---
+layout: news_item
+title: "Calcite appoints Josh Elser to PMC"
+date: "2016-02-17 10:30:00 -0800"
+author: jhyde
+categories: [team]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+The Apache Calcite project management committee (PMC) today announced the
+appointment of [Josh Elser](https://mail-archives.apache.org/mod_mbox/calcite-dev/201602.mbox/%3C12AA8D09-BBF8-470B-8933-5B672162546C%40apache.org%3E)
+to the committee.
+
+Josh has only been a committer for a few months, but has become a prominent
+member of the Calcite project, and has taken leadership in several areas,
+not least in discussing [the future of Avatica](https://mail-archives.apache.org/mod_mbox/calcite-dev/201601.mbox/%3C56ABCCFF.3010205%40gmail.com%3E).

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-02-17-streaming-sql-talk.md b/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
new file mode 100644
index 0000000..9c5d55a
--- /dev/null
+++ b/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
@@ -0,0 +1,40 @@
+---
+layout: news_item
+title: "Streaming SQL in Samza"
+date: "2016-02-17 11:53:00 -0800"
+author: jhyde
+categories: ["talks"]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Julian Hyde gave a talk at the [Apache Samza](http://samza.apache.org/)
+meetup in Mountain View, CA.
+
+His talk asked the questions:
+
+* What is [SamzaSQL](https://github.com/milinda/samza-sql),
+  and what might I use it for?
+* Does this mean that Samza is turning into a database?
+* What is a query optimizer, and what can it do for my streaming queries?
+
+The talk is available in
+[[slides](http://www.slideshare.net/julianhyde/streaming-sql)]
+and
+[[video](http://www.ustream.tv/recorded/83322450#to00:55:48)].

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_sass/_font-awesome.scss
----------------------------------------------------------------------
diff --git a/avatica/site/_sass/_font-awesome.scss b/avatica/site/_sass/_font-awesome.scss
new file mode 100644
index 0000000..d90676c
--- /dev/null
+++ b/avatica/site/_sass/_font-awesome.scss
@@ -0,0 +1,25 @@
+/*!
+ *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('../fonts/fontawesome-webfont.eot?v=4.2.0');
+  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+.fa {
+  display: inline-block;
+  font: normal normal normal 14px/1 FontAwesome;
+  font-size: inherit;
+  text-rendering: auto;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.fa-link:before {
+  content: "\f0c1";
+}
+.fa-pencil:before {
+  content: "\f040";
+}


[04/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
deleted file mode 100644
index d96293b..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
+++ /dev/null
@@ -1,533 +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.remote;
-
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.proto.Common;
-import org.apache.calcite.avatica.util.ByteString;
-import org.apache.calcite.avatica.util.DateTimeUtils;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.protobuf.HBaseZeroCopyByteString;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-/** Value and type.
- *
- * <p>There are 3 representations:
- * <ul>
- *   <li>JDBC - the representation used by JDBC get and set methods
- *   <li>Serial - suitable for serializing using JSON
- *   <li>Local - used by Calcite for efficient computation
- * </ul>
- *
- * <p>The following table shows the Java type(s) that may represent each SQL
- * type in each representation.
- *
- * <table>
- *   <caption>SQL types and their representations</caption>
- *   <tr>
- *     <th>Type</th> <th>JDBC</th> <th>Serial</th> <th>Local</th>
- *   </tr>
- *   <tr>
- *     <td>BOOLEAN</td> <td>boolean</td> <td>boolean</td> <td>boolean</td>
- *   </tr>
- *   <tr>
- *     <td>BINARY, VARBINARY</td> <td>byte[]</td>
- *                    <td>String (base64)</td> <td>{@link ByteString}</td>
- *   </tr>
- *   <tr>
- *     <td>DATE</td> <td>{@link java.sql.Date}</td>
- *                                   <td>int</td> <td>int</td>
- *   </tr>
- *   <tr>
- *     <td>TIME</td> <td>{@link java.sql.Time}</td>
- *                                   <td>int</td> <td>int</td>
- *   </tr>
- *   <tr>
- *     <td>DATE</td> <td>{@link java.sql.Timestamp}</td>
- *                                   <td>long</td> <td>long</td>
- *   </tr>
- *   <tr>
- *     <td>CHAR, VARCHAR</td>
- *                   <td>String</td> <td>String</td> <td>String</td>
- *   </tr>
- *   <tr>
- *     <td>TINYINT</td> <td>byte</td> <td>Number</td> <td>byte</td>
- *   </tr>
- *   <tr>
- *     <td>SMALLINT</td> <td>short</td> <td>Number</td> <td>short</td>
- *   </tr>
- *   <tr>
- *     <td>INTEGER</td> <td>int</td> <td>Number</td> <td>int</td>
- *   </tr>
- *   <tr>
- *     <td>BIGINT</td> <td>long</td> <td>Number</td> <td>long</td>
- *   </tr>
- *   <tr>
- *     <td>REAL</td> <td>float</td> <td>Number</td> <td>float</td>
- *   </tr>
- *   <tr>
- *     <td>FLOAT, DOUBLE</td>
- *                   <td>double</td> <td>Number</td> <td>double</td>
- *   </tr>
- *   <tr>
- *     <td>DECIMAL</td>
- *                   <td>BigDecimal</td> <td>Number</td> <td>BigDecimal</td>
- *   </tr>
- * </table>
- *
- * Note:
- * <ul>
- *   <li>The various numeric types (TINYINT, SMALLINT, INTEGER, BIGINT, REAL,
- *   FLOAT, DOUBLE) are represented by {@link Number} in serial format because
- *   JSON numbers are not strongly typed. A {@code float} value {@code 3.0} is
- *   transmitted as {@code 3}, and is therefore decoded as an {@code int}.
- *
- *   <li>The date-time types (DATE, TIME, TIMESTAMP) are represented in JDBC as
- *   {@link java.sql.Date}, {@link java.sql.Time}, {@link java.sql.Timestamp},
- *   all sub-classes of {@link java.util.Date}. When they are passed to and
- *   from the server, they are interpreted in terms of a time zone, by default
- *   the current connection's time zone. Their serial and local representations
- *   as {@code int} (days since 1970-01-01 for DATE, milliseconds since
- *   00:00:00.000 for TIME), and long (milliseconds since 1970-01-01
- *   00:00:00.000 for TIMESTAMP) are easier to work with, because it is clear
- *   that time zone is not involved.
- *
- *   <li>BINARY and VARBINARY values are represented as base64-encoded strings
- *   for serialization over JSON.
- * </ul>
- */
-public class TypedValue {
-  public static final TypedValue NULL =
-      new TypedValue(ColumnMetaData.Rep.OBJECT, null);
-
-  /** Type of the value. */
-  public final ColumnMetaData.Rep type;
-
-  /** Value.
-   *
-   * <p>Always in a form that can be serialized to JSON by Jackson.
-   * For example, byte arrays are represented as String. */
-  public final Object value;
-
-  private TypedValue(ColumnMetaData.Rep rep, Object value) {
-    this.type = rep;
-    this.value = value;
-    assert isSerial(rep, value) : "rep: " + rep + ", value: " + value;
-  }
-
-  private boolean isSerial(ColumnMetaData.Rep rep, Object value) {
-    if (value == null) {
-      return true;
-    }
-    switch (rep) {
-    case BYTE_STRING:
-      return value instanceof String;
-    case JAVA_SQL_DATE:
-    case JAVA_SQL_TIME:
-      return value instanceof Integer;
-    case JAVA_SQL_TIMESTAMP:
-    case JAVA_UTIL_DATE:
-      return value instanceof Long;
-    default:
-      return true;
-    }
-  }
-
-  @JsonCreator
-  public static TypedValue create(@JsonProperty("type") String type,
-      @JsonProperty("value") Object value) {
-    if (value == null) {
-      return NULL;
-    }
-    ColumnMetaData.Rep rep = ColumnMetaData.Rep.valueOf(type);
-    return ofLocal(rep, serialToLocal(rep, value));
-  }
-
-  /** Creates a TypedValue from a value in local representation. */
-  public static TypedValue ofLocal(ColumnMetaData.Rep rep, Object value) {
-    return new TypedValue(rep, localToSerial(rep, value));
-  }
-
-  /** Creates a TypedValue from a value in serial representation. */
-  public static TypedValue ofSerial(ColumnMetaData.Rep rep, Object value) {
-    return new TypedValue(rep, value);
-  }
-
-  /** Creates a TypedValue from a value in JDBC representation. */
-  public static TypedValue ofJdbc(ColumnMetaData.Rep rep, Object value,
-      Calendar calendar) {
-    if (value == null) {
-      return NULL;
-    }
-    return new TypedValue(rep, jdbcToSerial(rep, value, calendar));
-  }
-
-  /** Creates a TypedValue from a value in JDBC representation,
-   * deducing its type. */
-  public static TypedValue ofJdbc(Object value, Calendar calendar) {
-    if (value == null) {
-      return NULL;
-    }
-    final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(value.getClass());
-    return new TypedValue(rep, jdbcToSerial(rep, value, calendar));
-  }
-
-  /** Converts the value into the local representation.
-   *
-   * <p>For example, a byte string is represented as a {@link ByteString};
-   * a long is represented as a {@link Long} (not just some {@link Number}).
-   */
-  public Object toLocal() {
-    if (value == null) {
-      return null;
-    }
-    return serialToLocal(type, value);
-  }
-
-  /** Converts a value to the exact type required for the given
-   * representation. */
-  private static Object serialToLocal(ColumnMetaData.Rep rep, Object value) {
-    assert value != null;
-    if (value.getClass() == rep.clazz) {
-      return value;
-    }
-    switch (rep) {
-    case BYTE:
-      return ((Number) value).byteValue();
-    case SHORT:
-      return ((Number) value).shortValue();
-    case INTEGER:
-    case JAVA_SQL_DATE:
-    case JAVA_SQL_TIME:
-      return ((Number) value).intValue();
-    case LONG:
-    case JAVA_UTIL_DATE:
-    case JAVA_SQL_TIMESTAMP:
-      return ((Number) value).longValue();
-    case FLOAT:
-      return ((Number) value).floatValue();
-    case DOUBLE:
-      return ((Number) value).doubleValue();
-    case NUMBER:
-      return value instanceof BigDecimal ? value
-          : value instanceof BigInteger ? new BigDecimal((BigInteger) value)
-          : value instanceof Double ? new BigDecimal((Double) value)
-          : value instanceof Float ? new BigDecimal((Float) value)
-          : new BigDecimal(((Number) value).longValue());
-    case BYTE_STRING:
-      return ByteString.ofBase64((String) value);
-    default:
-      throw new IllegalArgumentException("cannot convert " + value + " ("
-          + value.getClass() + ") to " + rep);
-    }
-  }
-
-  /** Converts the value into the JDBC representation.
-   *
-   * <p>For example, a byte string is represented as a {@link ByteString};
-   * a long is represented as a {@link Long} (not just some {@link Number}).
-   */
-  public Object toJdbc(Calendar calendar) {
-    if (value == null) {
-      return null;
-    }
-    return serialToJdbc(type, value, calendar);
-  }
-
-  private static Object serialToJdbc(ColumnMetaData.Rep type, Object value,
-      Calendar calendar) {
-    switch (type) {
-    case BYTE_STRING:
-      return ByteString.ofBase64((String) value).getBytes();
-    case JAVA_UTIL_DATE:
-      return new java.util.Date(adjust((Number) value, calendar));
-    case JAVA_SQL_DATE:
-      return new java.sql.Date(
-          adjust(((Number) value).longValue() * DateTimeUtils.MILLIS_PER_DAY,
-              calendar));
-    case JAVA_SQL_TIME:
-      return new java.sql.Time(adjust((Number) value, calendar));
-    case JAVA_SQL_TIMESTAMP:
-      return new java.sql.Timestamp(adjust((Number) value, calendar));
-    default:
-      return serialToLocal(type, value);
-    }
-  }
-
-  private static long adjust(Number number, Calendar calendar) {
-    long t = number.longValue();
-    if (calendar != null) {
-      t -= calendar.getTimeZone().getOffset(t);
-    }
-    return t;
-  }
-
-  /** Converts a value from JDBC format to a type that can be serialized as
-   * JSON. */
-  private static Object jdbcToSerial(ColumnMetaData.Rep rep, Object value,
-      Calendar calendar) {
-    switch (rep) {
-    case BYTE_STRING:
-      return new ByteString((byte[]) value).toBase64String();
-    case JAVA_UTIL_DATE:
-    case JAVA_SQL_TIMESTAMP:
-    case JAVA_SQL_DATE:
-    case JAVA_SQL_TIME:
-      long t = ((Date) value).getTime();
-      if (calendar != null) {
-        t += calendar.getTimeZone().getOffset(t);
-      }
-      switch (rep) {
-      case JAVA_SQL_DATE:
-        return (int) DateTimeUtils.floorDiv(t, DateTimeUtils.MILLIS_PER_DAY);
-      case JAVA_SQL_TIME:
-        return (int) DateTimeUtils.floorMod(t, DateTimeUtils.MILLIS_PER_DAY);
-      default:
-        return t;
-      }
-    default:
-      return value;
-    }
-  }
-
-  /** Converts a value from internal format to a type that can be serialized
-   * as JSON. */
-  private static Object localToSerial(ColumnMetaData.Rep rep, Object value) {
-    switch (rep) {
-    case BYTE_STRING:
-      return ((ByteString) value).toBase64String();
-    default:
-      return value;
-    }
-  }
-
-  /** Converts a list of {@code TypedValue} to a list of values. */
-  public static List<Object> values(List<TypedValue> typedValues) {
-    final List<Object> list = new ArrayList<>();
-    for (TypedValue typedValue : typedValues) {
-      list.add(typedValue.toLocal());
-    }
-    return list;
-  }
-
-  public Common.TypedValue toProto() {
-    final Common.TypedValue.Builder builder = Common.TypedValue.newBuilder();
-
-    Common.Rep protoRep = type.toProto();
-    builder.setType(protoRep);
-
-    // Serialize the type into the protobuf
-    switch (protoRep) {
-    case BOOLEAN:
-    case PRIMITIVE_BOOLEAN:
-      builder.setBoolValue((boolean) value);
-      break;
-    case BYTE_STRING:
-    case STRING:
-      builder.setStringValueBytes(HBaseZeroCopyByteString.wrap(((String) value).getBytes()));
-      break;
-    case PRIMITIVE_CHAR:
-    case CHARACTER:
-      builder.setStringValue(Character.toString((char) value));
-      break;
-    case BYTE:
-    case PRIMITIVE_BYTE:
-      builder.setNumberValue(Byte.valueOf((byte) value).longValue());
-      break;
-    case DOUBLE:
-    case PRIMITIVE_DOUBLE:
-      builder.setDoubleValue((double) value);
-      break;
-    case FLOAT:
-    case PRIMITIVE_FLOAT:
-      builder.setNumberValue(Float.floatToIntBits((float) value));
-      break;
-    case INTEGER:
-    case PRIMITIVE_INT:
-      builder.setNumberValue(Integer.valueOf((int) value).longValue());
-      break;
-    case PRIMITIVE_SHORT:
-    case SHORT:
-      builder.setNumberValue(Short.valueOf((short) value).longValue());
-      break;
-    case LONG:
-    case PRIMITIVE_LONG:
-      builder.setNumberValue((long) value);
-      break;
-    case JAVA_SQL_DATE:
-    case JAVA_SQL_TIME:
-      // Persisted as integers
-      builder.setNumberValue(Integer.valueOf((int) value).longValue());
-      break;
-    case JAVA_SQL_TIMESTAMP:
-    case JAVA_UTIL_DATE:
-      // Persisted as longs
-      builder.setNumberValue((long) value);
-      break;
-    case BIG_INTEGER:
-      byte[] bytes = ((BigInteger) value).toByteArray();
-      builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bytes));
-      break;
-    case BIG_DECIMAL:
-      final BigDecimal bigDecimal = (BigDecimal) value;
-      final int scale = bigDecimal.scale();
-      final BigInteger bigInt = bigDecimal.toBigInteger();
-      builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bigInt.toByteArray()))
-        .setNumberValue(scale);
-      break;
-    case NUMBER:
-      builder.setNumberValue(((Number) value).longValue());
-      break;
-    case OBJECT:
-      if (null == value) {
-        // We can persist a null value through easily
-        builder.setNull(true);
-        break;
-      }
-      // Intentional fall-through to RTE because we can't serialize something we have no type
-      // insight into.
-    case UNRECOGNIZED:
-      // Fail?
-      throw new RuntimeException("Unhandled value: " + protoRep + " " + value.getClass());
-    default:
-      // Fail?
-      throw new RuntimeException("Unknown serialized type: " + protoRep);
-    }
-
-    return builder.build();
-  }
-
-  public static TypedValue fromProto(Common.TypedValue proto) {
-    ColumnMetaData.Rep rep = ColumnMetaData.Rep.fromProto(proto.getType());
-
-    Object value = null;
-
-    // Deserialize the value again
-    switch (proto.getType()) {
-    case BOOLEAN:
-    case PRIMITIVE_BOOLEAN:
-      value = proto.getBoolValue();
-      break;
-    case BYTE_STRING:
-    case STRING:
-      value = proto.getStringValue();
-      break;
-    case PRIMITIVE_CHAR:
-    case CHARACTER:
-      value = proto.getStringValue().charAt(0);
-      break;
-    case BYTE:
-    case PRIMITIVE_BYTE:
-      value = Long.valueOf(proto.getNumberValue()).byteValue();
-      break;
-    case DOUBLE:
-    case PRIMITIVE_DOUBLE:
-      value = proto.getDoubleValue();
-      break;
-    case FLOAT:
-    case PRIMITIVE_FLOAT:
-      value = Float.intBitsToFloat((int) proto.getNumberValue());
-      break;
-    case INTEGER:
-    case PRIMITIVE_INT:
-      value = Long.valueOf(proto.getNumberValue()).intValue();
-      break;
-    case PRIMITIVE_SHORT:
-    case SHORT:
-      value = Long.valueOf(proto.getNumberValue()).shortValue();
-      break;
-    case LONG:
-    case PRIMITIVE_LONG:
-      value = Long.valueOf(proto.getNumberValue());
-      break;
-    case JAVA_SQL_DATE:
-    case JAVA_SQL_TIME:
-      value = Long.valueOf(proto.getNumberValue()).intValue();
-      break;
-    case JAVA_SQL_TIMESTAMP:
-    case JAVA_UTIL_DATE:
-      value = proto.getNumberValue();
-      break;
-    case BIG_INTEGER:
-      value = new BigInteger(proto.getBytesValues().toByteArray());
-      break;
-    case BIG_DECIMAL:
-      BigInteger bigInt = new BigInteger(proto.getBytesValues().toByteArray());
-      value = new BigDecimal(bigInt, (int) proto.getNumberValue());
-      break;
-    case NUMBER:
-      value = Long.valueOf(proto.getNumberValue());
-      break;
-    case OBJECT:
-      if (proto.getNull()) {
-        value = null;
-        break;
-      }
-      // Intentional fall through to RTE. If we sent an object over the wire, it could only
-      // possibly be null (at this point). Anything else has to be an error.
-    case UNRECOGNIZED:
-      // Fail?
-      throw new RuntimeException("Unhandled type: " + proto.getType());
-    default:
-      // Fail?
-      throw new RuntimeException("Unknown type: " + proto.getType());
-    }
-
-    return new TypedValue(rep, value);
-  }
-
-  @Override public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((type == null) ? 0 : type.hashCode());
-    result = prime * result + ((value == null) ? 0 : value.hashCode());
-    return result;
-  }
-
-  @Override public boolean equals(Object o) {
-    if (o == this) {
-      return true;
-    }
-    if (o instanceof TypedValue) {
-      TypedValue other = (TypedValue) o;
-
-      if (type != other.type) {
-        return false;
-      }
-
-      if (null == value) {
-        if (null != other.value) {
-          return false;
-        }
-      }
-
-      return value.equals(other.value);
-    }
-
-    return false;
-  }
-}
-
-// End TypedValue.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/package-info.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/package-info.java
deleted file mode 100644
index 1cf3e14..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * JDBC driver that uses remote procedure calls.
- */
-@PackageMarker
-package org.apache.calcite.avatica.remote;
-
-import org.apache.calcite.avatica.util.PackageMarker;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
deleted file mode 100644
index 70f87a7..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
+++ /dev/null
@@ -1,1377 +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.util;
-
-import org.apache.calcite.avatica.AvaticaSite;
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.ColumnMetaData;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-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.Map;
-
-/**
- * Base class for implementing a cursor.
- *
- * <p>Derived class needs to provide {@link Getter} and can override
- * {@link org.apache.calcite.avatica.util.Cursor.Accessor} implementations if it
- * wishes.</p>
- */
-public abstract class AbstractCursor implements Cursor {
-  /**
-   * Slot into which each accessor should write whether the
-   * value returned was null.
-   */
-  protected final boolean[] wasNull = {false};
-
-  protected AbstractCursor() {
-  }
-
-  public boolean wasNull() {
-    return wasNull[0];
-  }
-
-  public List<Accessor> createAccessors(List<ColumnMetaData> types,
-      Calendar localCalendar, ArrayImpl.Factory factory) {
-    List<Accessor> accessors = new ArrayList<>();
-    for (ColumnMetaData type : types) {
-      accessors.add(
-          createAccessor(type, accessors.size(), localCalendar, factory));
-    }
-    return accessors;
-  }
-
-  protected Accessor createAccessor(ColumnMetaData columnMetaData, int ordinal,
-      Calendar localCalendar, ArrayImpl.Factory factory) {
-    // Create an accessor appropriate to the underlying type; the accessor
-    // can convert to any type in the same family.
-    Getter getter = createGetter(ordinal);
-    return createAccessor(columnMetaData, getter, localCalendar, factory);
-  }
-
-  protected Accessor createAccessor(ColumnMetaData columnMetaData,
-      Getter getter, Calendar localCalendar, ArrayImpl.Factory factory) {
-    switch (columnMetaData.type.rep) {
-    case NUMBER:
-      switch (columnMetaData.type.id) {
-      case Types.TINYINT:
-      case Types.SMALLINT:
-      case Types.INTEGER:
-      case Types.BIGINT:
-      case Types.REAL:
-      case Types.FLOAT:
-      case Types.DOUBLE:
-      case Types.NUMERIC:
-      case Types.DECIMAL:
-        return new NumberAccessor(getter, columnMetaData.scale);
-      }
-    }
-    switch (columnMetaData.type.id) {
-    case Types.TINYINT:
-      return new ByteAccessor(getter);
-    case Types.SMALLINT:
-      return new ShortAccessor(getter);
-    case Types.INTEGER:
-      return new IntAccessor(getter);
-    case Types.BIGINT:
-      return new LongAccessor(getter);
-    case Types.BOOLEAN:
-      return new BooleanAccessor(getter);
-    case Types.REAL:
-      return new FloatAccessor(getter);
-    case Types.FLOAT:
-    case Types.DOUBLE:
-      return new DoubleAccessor(getter);
-    case Types.DECIMAL:
-      return new BigDecimalAccessor(getter);
-    case Types.CHAR:
-      switch (columnMetaData.type.rep) {
-      case PRIMITIVE_CHAR:
-      case CHARACTER:
-        return new StringFromCharAccessor(getter, columnMetaData.displaySize);
-      default:
-        return new FixedStringAccessor(getter, columnMetaData.displaySize);
-      }
-    case Types.VARCHAR:
-      return new StringAccessor(getter);
-    case Types.BINARY:
-    case Types.VARBINARY:
-      switch (columnMetaData.type.rep) {
-      case STRING:
-        return new BinaryFromStringAccessor(getter);
-      default:
-        return new BinaryAccessor(getter);
-      }
-    case Types.DATE:
-      switch (columnMetaData.type.rep) {
-      case PRIMITIVE_INT:
-      case INTEGER:
-      case NUMBER:
-        return new DateFromNumberAccessor(getter, localCalendar);
-      case JAVA_SQL_DATE:
-        return new DateAccessor(getter);
-      default:
-        throw new AssertionError("bad " + columnMetaData.type.rep);
-      }
-    case Types.TIME:
-      switch (columnMetaData.type.rep) {
-      case PRIMITIVE_INT:
-      case INTEGER:
-      case NUMBER:
-        return new TimeFromNumberAccessor(getter, localCalendar);
-      case JAVA_SQL_TIME:
-        return new TimeAccessor(getter);
-      default:
-        throw new AssertionError("bad " + columnMetaData.type.rep);
-      }
-    case Types.TIMESTAMP:
-      switch (columnMetaData.type.rep) {
-      case PRIMITIVE_LONG:
-      case LONG:
-      case NUMBER:
-        return new TimestampFromNumberAccessor(getter, localCalendar);
-      case JAVA_SQL_TIMESTAMP:
-        return new TimestampAccessor(getter);
-      case JAVA_UTIL_DATE:
-        return new TimestampFromUtilDateAccessor(getter, localCalendar);
-      default:
-        throw new AssertionError("bad " + columnMetaData.type.rep);
-      }
-    case Types.ARRAY:
-      final ColumnMetaData.ArrayType arrayType =
-          (ColumnMetaData.ArrayType) columnMetaData.type;
-      final SlotGetter componentGetter = new SlotGetter();
-      final Accessor componentAccessor =
-          createAccessor(ColumnMetaData.dummy(arrayType.component, true),
-              componentGetter, localCalendar, factory);
-      return new ArrayAccessor(getter, arrayType.component, componentAccessor,
-          componentGetter, factory);
-    case Types.STRUCT:
-      switch (columnMetaData.type.rep) {
-      case OBJECT:
-        final ColumnMetaData.StructType structType =
-            (ColumnMetaData.StructType) columnMetaData.type;
-        List<Accessor> accessors = new ArrayList<>();
-        for (ColumnMetaData column : structType.columns) {
-          final Getter fieldGetter =
-              structType.columns.size() == 1
-                  ? getter
-                  : new StructGetter(getter, column);
-          accessors.add(
-              createAccessor(column, fieldGetter, localCalendar, factory));
-        }
-        return new StructAccessor(getter, accessors);
-      default:
-        throw new AssertionError("bad " + columnMetaData.type.rep);
-      }
-    case Types.JAVA_OBJECT:
-    case Types.OTHER: // e.g. map
-      if (columnMetaData.type.name.startsWith("INTERVAL_")) {
-        int end = columnMetaData.type.name.indexOf("(");
-        if (end < 0) {
-          end = columnMetaData.type.name.length();
-        }
-        TimeUnitRange range =
-            TimeUnitRange.valueOf(
-                columnMetaData.type.name.substring("INTERVAL_".length(), end));
-        if (range.monthly()) {
-          return new IntervalYearMonthAccessor(getter, range);
-        } else {
-          return new IntervalDayTimeAccessor(getter, range,
-              columnMetaData.scale);
-        }
-      }
-      return new ObjectAccessor(getter);
-    default:
-      throw new RuntimeException("unknown type " + columnMetaData.type.id);
-    }
-  }
-
-  protected abstract Getter createGetter(int ordinal);
-
-  public abstract boolean next();
-
-  /** Accesses a timestamp value as a string.
-   * The timestamp is in SQL format (e.g. "2013-09-22 22:30:32"),
-   * not Java format ("2013-09-22 22:30:32.123"). */
-  private static String timestampAsString(long v, Calendar calendar) {
-    if (calendar != null) {
-      v -= calendar.getTimeZone().getOffset(v);
-    }
-    return DateTimeUtils.unixTimestampToString(v);
-  }
-
-  /** Accesses a date value as a string, e.g. "2013-09-22". */
-  private static String dateAsString(int v, Calendar calendar) {
-    AvaticaUtils.discard(calendar); // time zone shift doesn't make sense
-    return DateTimeUtils.unixDateToString(v);
-  }
-
-  /** Accesses a time value as a string, e.g. "22:30:32". */
-  private static String timeAsString(int v, Calendar calendar) {
-    if (calendar != null) {
-      v -= calendar.getTimeZone().getOffset(v);
-    }
-    return DateTimeUtils.unixTimeToString(v);
-  }
-
-  private static Date longToDate(long v, Calendar calendar) {
-    if (calendar != null) {
-      v -= calendar.getTimeZone().getOffset(v);
-    }
-    return new Date(v);
-  }
-
-  static Time intToTime(int v, Calendar calendar) {
-    if (calendar != null) {
-      v -= calendar.getTimeZone().getOffset(v);
-    }
-    return new Time(v);
-  }
-
-  static Timestamp longToTimestamp(long v, Calendar calendar) {
-    if (calendar != null) {
-      v -= calendar.getTimeZone().getOffset(v);
-    }
-    return new Timestamp(v);
-  }
-
-  /** Implementation of {@link Cursor.Accessor}. */
-  static class AccessorImpl implements Accessor {
-    protected final Getter getter;
-
-    public AccessorImpl(Getter getter) {
-      assert getter != null;
-      this.getter = getter;
-    }
-
-    public boolean wasNull() {
-      return getter.wasNull();
-    }
-
-    public String getString() {
-      final Object o = getObject();
-      return o == null ? null : o.toString();
-    }
-
-    public boolean getBoolean() {
-      return getLong() != 0L;
-    }
-
-    public byte getByte() {
-      return (byte) getLong();
-    }
-
-    public short getShort() {
-      return (short) getLong();
-    }
-
-    public int getInt() {
-      return (int) getLong();
-    }
-
-    public long getLong() {
-      throw cannotConvert("long");
-    }
-
-    public float getFloat() {
-      return (float) getDouble();
-    }
-
-    public double getDouble() {
-      throw cannotConvert("double");
-    }
-
-    public BigDecimal getBigDecimal() {
-      throw cannotConvert("BigDecimal");
-    }
-
-    public BigDecimal getBigDecimal(int scale) {
-      throw cannotConvert("BigDecimal with scale");
-    }
-
-    public byte[] getBytes() {
-      throw cannotConvert("byte[]");
-    }
-
-    public InputStream getAsciiStream() {
-      throw cannotConvert("InputStream (ascii)");
-    }
-
-    public InputStream getUnicodeStream() {
-      throw cannotConvert("InputStream (unicode)");
-    }
-
-    public InputStream getBinaryStream() {
-      throw cannotConvert("InputStream (binary)");
-    }
-
-    public Object getObject() {
-      return getter.getObject();
-    }
-
-    public Reader getCharacterStream() {
-      throw cannotConvert("Reader");
-    }
-
-    private RuntimeException cannotConvert(String targetType) {
-      return new RuntimeException("cannot convert to " + targetType + " ("
-          + this + ")");
-    }
-
-    public Object getObject(Map<String, Class<?>> map) {
-      throw cannotConvert("Object (with map)");
-    }
-
-    public Ref getRef() {
-      throw cannotConvert("Ref");
-    }
-
-    public Blob getBlob() {
-      throw cannotConvert("Blob");
-    }
-
-    public Clob getClob() {
-      throw cannotConvert("Clob");
-    }
-
-    public Array getArray() {
-      throw cannotConvert("Array");
-    }
-
-    public Struct getStruct() {
-      throw cannotConvert("Struct");
-    }
-
-    public Date getDate(Calendar calendar) {
-      throw cannotConvert("Date");
-    }
-
-    public Time getTime(Calendar calendar) {
-      throw cannotConvert("Time");
-    }
-
-    public Timestamp getTimestamp(Calendar calendar) {
-      throw cannotConvert("Timestamp");
-    }
-
-    public URL getURL() {
-      throw cannotConvert("URL");
-    }
-
-    public NClob getNClob() {
-      throw cannotConvert("NClob");
-    }
-
-    public SQLXML getSQLXML() {
-      throw cannotConvert("SQLXML");
-    }
-
-    public String getNString() {
-      throw cannotConvert("NString");
-    }
-
-    public Reader getNCharacterStream() {
-      throw cannotConvert("NCharacterStream");
-    }
-
-    public <T> T getObject(Class<T> type) {
-      throw cannotConvert("Object (with type)");
-    }
-  }
-
-  /**
-   * Accessor of exact numeric values. The subclass must implement the
-   * {@link #getLong()} method.
-   */
-  private abstract static class ExactNumericAccessor extends AccessorImpl {
-    public ExactNumericAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public BigDecimal getBigDecimal(int scale) {
-      final long v = getLong();
-      if (v == 0 && getter.wasNull()) {
-        return null;
-      }
-      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
-    }
-
-    public BigDecimal getBigDecimal() {
-      final long val = getLong();
-      if (val == 0 && getter.wasNull()) {
-        return null;
-      }
-      return BigDecimal.valueOf(val);
-    }
-
-    public double getDouble() {
-      return getLong();
-    }
-
-    public float getFloat() {
-      return getLong();
-    }
-
-    public abstract long getLong();
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Boolean};
-   * corresponds to {@link java.sql.Types#BOOLEAN}.
-   */
-  private static class BooleanAccessor extends ExactNumericAccessor {
-    public BooleanAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public boolean getBoolean() {
-      Boolean o = (Boolean) getObject();
-      return o != null && o;
-    }
-
-    public long getLong() {
-      return getBoolean() ? 1 : 0;
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Byte};
-   * corresponds to {@link java.sql.Types#TINYINT}.
-   */
-  private static class ByteAccessor extends ExactNumericAccessor {
-    public ByteAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public byte getByte() {
-      Byte o = (Byte) getObject();
-      return o == null ? 0 : o;
-    }
-
-    public long getLong() {
-      return getByte();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Short};
-   * corresponds to {@link java.sql.Types#SMALLINT}.
-   */
-  private static class ShortAccessor extends ExactNumericAccessor {
-    public ShortAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public short getShort() {
-      Short o = (Short) getObject();
-      return o == null ? 0 : o;
-    }
-
-    public long getLong() {
-      return getShort();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is an {@link Integer};
-   * corresponds to {@link java.sql.Types#INTEGER}.
-   */
-  private static class IntAccessor extends ExactNumericAccessor {
-    public IntAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public int getInt() {
-      Integer o = (Integer) super.getObject();
-      return o == null ? 0 : o;
-    }
-
-    public long getLong() {
-      return getInt();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Long};
-   * corresponds to {@link java.sql.Types#BIGINT}.
-   */
-  private static class LongAccessor extends ExactNumericAccessor {
-    public LongAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public long getLong() {
-      Long o = (Long) super.getObject();
-      return o == null ? 0 : o;
-    }
-  }
-
-  /**
-   * Accessor of values that are {@link Double} or null.
-   */
-  private abstract static class ApproximateNumericAccessor
-      extends AccessorImpl {
-    public ApproximateNumericAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public BigDecimal getBigDecimal(int scale) {
-      final double v = getDouble();
-      if (v == 0d && getter.wasNull()) {
-        return null;
-      }
-      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
-    }
-
-    public BigDecimal getBigDecimal() {
-      final double v = getDouble();
-      if (v == 0 && getter.wasNull()) {
-        return null;
-      }
-      return BigDecimal.valueOf(v);
-    }
-
-    public abstract double getDouble();
-
-    public long getLong() {
-      return (long) getDouble();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Float};
-   * corresponds to {@link java.sql.Types#FLOAT}.
-   */
-  private static class FloatAccessor extends ApproximateNumericAccessor {
-    public FloatAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public float getFloat() {
-      Float o = (Float) getObject();
-      return o == null ? 0f : o;
-    }
-
-    public double getDouble() {
-      return getFloat();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Double};
-   * corresponds to {@link java.sql.Types#DOUBLE}.
-   */
-  private static class DoubleAccessor extends ApproximateNumericAccessor {
-    public DoubleAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public double getDouble() {
-      Double o = (Double) getObject();
-      return o == null ? 0d : o;
-    }
-  }
-
-  /**
-   * Accessor of exact numeric values. The subclass must implement the
-   * {@link #getLong()} method.
-   */
-  private abstract static class BigNumberAccessor extends AccessorImpl {
-    public BigNumberAccessor(Getter getter) {
-      super(getter);
-    }
-
-    protected abstract Number getNumber();
-
-    public double getDouble() {
-      Number number = getNumber();
-      return number == null ? 0d : number.doubleValue();
-    }
-
-    public float getFloat() {
-      Number number = getNumber();
-      return number == null ? 0f : number.floatValue();
-    }
-
-    public long getLong() {
-      Number number = getNumber();
-      return number == null ? 0L : number.longValue();
-    }
-
-    public int getInt() {
-      Number number = getNumber();
-      return number == null ? 0 : number.intValue();
-    }
-
-    public short getShort() {
-      Number number = getNumber();
-      return number == null ? 0 : number.shortValue();
-    }
-
-    public byte getByte() {
-      Number number = getNumber();
-      return number == null ? 0 : number.byteValue();
-    }
-
-    public boolean getBoolean() {
-      Number number = getNumber();
-      return number != null && number.doubleValue() != 0;
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link BigDecimal};
-   * corresponds to {@link java.sql.Types#DECIMAL}.
-   */
-  private static class BigDecimalAccessor extends BigNumberAccessor {
-    public BigDecimalAccessor(Getter getter) {
-      super(getter);
-    }
-
-    protected Number getNumber() {
-      return (Number) getObject();
-    }
-
-    public BigDecimal getBigDecimal(int scale) {
-      return (BigDecimal) getObject();
-    }
-
-    public BigDecimal getBigDecimal() {
-      return (BigDecimal) getObject();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link Number};
-   * corresponds to {@link java.sql.Types#NUMERIC}.
-   *
-   * <p>This is useful when numbers have been translated over JSON. JSON
-   * converts a 0L (0 long) value to the string "0" and back to 0 (0 int).
-   * So you cannot be sure that the source and target type are the same.
-   */
-  static class NumberAccessor extends BigNumberAccessor {
-    private final int scale;
-
-    public NumberAccessor(Getter getter, int scale) {
-      super(getter);
-      this.scale = scale;
-    }
-
-    protected Number getNumber() {
-      return (Number) super.getObject();
-    }
-
-    public BigDecimal getBigDecimal(int scale) {
-      Number n = getNumber();
-      if (n == null) {
-        return null;
-      }
-      BigDecimal decimal = AvaticaSite.toBigDecimal(n);
-      if (0 != scale) {
-        return decimal.setScale(scale, BigDecimal.ROUND_UNNECESSARY);
-      }
-      return decimal;
-    }
-
-    public BigDecimal getBigDecimal() {
-      return getBigDecimal(scale);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link String};
-   * corresponds to {@link java.sql.Types#CHAR}
-   * and {@link java.sql.Types#VARCHAR}.
-   */
-  private static class StringAccessor extends AccessorImpl {
-    public StringAccessor(Getter getter) {
-      super(getter);
-    }
-
-    public String getString() {
-      return (String) getObject();
-    }
-
-    @Override public byte[] getBytes() {
-      return super.getBytes();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link String};
-   * corresponds to {@link java.sql.Types#CHAR}.
-   */
-  private static class FixedStringAccessor extends StringAccessor {
-    protected final Spacer spacer;
-
-    public FixedStringAccessor(Getter getter, int length) {
-      super(getter);
-      this.spacer = new Spacer(length);
-    }
-
-    public String getString() {
-      String s = super.getString();
-      if (s == null) {
-        return null;
-      }
-      return spacer.padRight(s);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link String};
-   * corresponds to {@link java.sql.Types#CHAR}.
-   */
-  private static class StringFromCharAccessor extends FixedStringAccessor {
-    public StringFromCharAccessor(Getter getter, int length) {
-      super(getter, length);
-    }
-
-    public String getString() {
-      Character s = (Character) super.getObject();
-      if (s == null) {
-        return null;
-      }
-      return spacer.padRight(s.toString());
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is an array of
-   * {@link org.apache.calcite.avatica.util.ByteString} values;
-   * corresponds to {@link java.sql.Types#BINARY}
-   * and {@link java.sql.Types#VARBINARY}.
-   */
-  private static class BinaryAccessor extends AccessorImpl {
-    public BinaryAccessor(Getter getter) {
-      super(getter);
-    }
-
-    //FIXME: Protobuf gets byte[]
-    @Override public byte[] getBytes() {
-      Object obj = getObject();
-      try {
-        final ByteString o = (ByteString) obj;
-        return o == null ? null : o.getBytes();
-      } catch (Exception ex) {
-        return obj == null ? null : (byte[]) obj;
-      }
-    }
-
-    @Override public String getString() {
-      Object o = getObject();
-      if (null == o) {
-        return null;
-      }
-      if (o instanceof byte[]) {
-        return new String((byte[]) o, StandardCharsets.UTF_8);
-      } else if (o instanceof ByteString) {
-        return ((ByteString) o).toString();
-      }
-      throw new IllegalStateException("Unhandled value type: " + o.getClass());
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@link String},
-   * encoding {@link java.sql.Types#BINARY}
-   * and {@link java.sql.Types#VARBINARY} values in Base64 format.
-   */
-  private static class BinaryFromStringAccessor extends StringAccessor {
-    public BinaryFromStringAccessor(Getter getter) {
-      super(getter);
-    }
-
-    @Override public Object getObject() {
-      return super.getObject();
-    }
-
-    @Override public byte[] getBytes() {
-      // JSON sends this as a base64-enc string, protobuf can do binary.
-      Object obj = getObject();
-
-      if (obj instanceof byte[]) {
-        // If we already have bytes, just send them back.
-        return (byte[]) obj;
-      }
-
-      return getBase64Decoded();
-    }
-
-    private byte[] getBase64Decoded() {
-      final String string = super.getString();
-      if (null == string) {
-        return null;
-      }
-      // Need to base64 decode the string.
-      return ByteString.parseBase64(string);
-    }
-
-    @Override public String getString() {
-      final byte[] bytes = getBase64Decoded();
-      if (null == bytes) {
-        return null;
-      }
-      // Need to base64 decode the string.
-      return new String(bytes, StandardCharsets.UTF_8);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a DATE,
-   * in its default representation {@code int};
-   * corresponds to {@link java.sql.Types#DATE}.
-   */
-  private static class DateFromNumberAccessor extends NumberAccessor {
-    private final Calendar localCalendar;
-
-    public DateFromNumberAccessor(Getter getter, Calendar localCalendar) {
-      super(getter, 0);
-      this.localCalendar = localCalendar;
-    }
-
-    @Override public Object getObject() {
-      return getDate(localCalendar);
-    }
-
-    @Override public Date getDate(Calendar calendar) {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return longToDate(v.longValue() * DateTimeUtils.MILLIS_PER_DAY, calendar);
-    }
-
-    @Override public Timestamp getTimestamp(Calendar calendar) {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return longToTimestamp(v.longValue() * DateTimeUtils.MILLIS_PER_DAY,
-          calendar);
-    }
-
-    @Override public String getString() {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return dateAsString(v.intValue(), null);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a Time,
-   * in its default representation {@code int};
-   * corresponds to {@link java.sql.Types#TIME}.
-   */
-  private static class TimeFromNumberAccessor extends NumberAccessor {
-    private final Calendar localCalendar;
-
-    public TimeFromNumberAccessor(Getter getter, Calendar localCalendar) {
-      super(getter, 0);
-      this.localCalendar = localCalendar;
-    }
-
-    @Override public Object getObject() {
-      return getTime(localCalendar);
-    }
-
-    @Override public Time getTime(Calendar calendar) {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return intToTime(v.intValue(), calendar);
-    }
-
-    @Override public Timestamp getTimestamp(Calendar calendar) {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return longToTimestamp(v.longValue(), calendar);
-    }
-
-    @Override public String getString() {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return timeAsString(v.intValue(), null);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a TIMESTAMP,
-   * in its default representation {@code long};
-   * corresponds to {@link java.sql.Types#TIMESTAMP}.
-   */
-  private static class TimestampFromNumberAccessor extends NumberAccessor {
-    private final Calendar localCalendar;
-
-    public TimestampFromNumberAccessor(Getter getter, Calendar localCalendar) {
-      super(getter, 0);
-      this.localCalendar = localCalendar;
-    }
-
-    @Override public Object getObject() {
-      return getTimestamp(localCalendar);
-    }
-
-    @Override public Timestamp getTimestamp(Calendar calendar) {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return longToTimestamp(v.longValue(), calendar);
-    }
-
-    @Override public Date getDate(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Date(timestamp.getTime());
-    }
-
-    @Override public Time getTime(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Time(
-          DateTimeUtils.floorMod(timestamp.getTime(),
-              DateTimeUtils.MILLIS_PER_DAY));
-    }
-
-    @Override public String getString() {
-      final Number v = getNumber();
-      if (v == null) {
-        return null;
-      }
-      return timestampAsString(v.longValue(), null);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a DATE,
-   * represented as a java.sql.Date;
-   * corresponds to {@link java.sql.Types#DATE}.
-   */
-  private static class DateAccessor extends ObjectAccessor {
-    public DateAccessor(Getter getter) {
-      super(getter);
-    }
-
-    @Override public Date getDate(Calendar calendar) {
-      java.sql.Date date = (Date) getObject();
-      if (date == null) {
-        return null;
-      }
-      if (calendar != null) {
-        long v = date.getTime();
-        v -= calendar.getTimeZone().getOffset(v);
-        date = new Date(v);
-      }
-      return date;
-    }
-
-    @Override public String getString() {
-      final int v = getInt();
-      if (v == 0 && wasNull()) {
-        return null;
-      }
-      return dateAsString(v, null);
-    }
-
-    @Override public long getLong() {
-      Date date = getDate(null);
-      return date == null
-          ? 0L
-          : (date.getTime() / DateTimeUtils.MILLIS_PER_DAY);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a TIME,
-   * represented as a java.sql.Time;
-   * corresponds to {@link java.sql.Types#TIME}.
-   */
-  private static class TimeAccessor extends ObjectAccessor {
-    public TimeAccessor(Getter getter) {
-      super(getter);
-    }
-
-    @Override public Time getTime(Calendar calendar) {
-      Time date  = (Time) getObject();
-      if (date == null) {
-        return null;
-      }
-      if (calendar != null) {
-        long v = date.getTime();
-        v -= calendar.getTimeZone().getOffset(v);
-        date = new Time(v);
-      }
-      return date;
-    }
-
-    @Override public String getString() {
-      final int v = getInt();
-      if (v == 0 && wasNull()) {
-        return null;
-      }
-      return timeAsString(v, null);
-    }
-
-    @Override public long getLong() {
-      Time time = getTime(null);
-      return time == null ? 0L
-          : (time.getTime() % DateTimeUtils.MILLIS_PER_DAY);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a TIMESTAMP,
-   * represented as a java.sql.Timestamp;
-   * corresponds to {@link java.sql.Types#TIMESTAMP}.
-   */
-  private static class TimestampAccessor extends ObjectAccessor {
-    public TimestampAccessor(Getter getter) {
-      super(getter);
-    }
-
-    @Override public Timestamp getTimestamp(Calendar calendar) {
-      Timestamp timestamp  = (Timestamp) getObject();
-      if (timestamp == null) {
-        return null;
-      }
-      if (calendar != null) {
-        long v = timestamp.getTime();
-        v -= calendar.getTimeZone().getOffset(v);
-        timestamp = new Timestamp(v);
-      }
-      return timestamp;
-    }
-
-    @Override public Date getDate(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Date(timestamp.getTime());
-    }
-
-    @Override public Time getTime(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Time(
-          DateTimeUtils.floorMod(timestamp.getTime(),
-              DateTimeUtils.MILLIS_PER_DAY));
-    }
-
-    @Override public String getString() {
-      final long v = getLong();
-      if (v == 0 && wasNull()) {
-        return null;
-      }
-      return timestampAsString(v, null);
-    }
-
-    @Override public long getLong() {
-      Timestamp timestamp = getTimestamp(null);
-      return timestamp == null ? 0 : timestamp.getTime();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a TIMESTAMP,
-   * represented as a java.util.Date;
-   * corresponds to {@link java.sql.Types#TIMESTAMP}.
-   */
-  private static class TimestampFromUtilDateAccessor extends ObjectAccessor {
-    private final Calendar localCalendar;
-
-    public TimestampFromUtilDateAccessor(Getter getter,
-        Calendar localCalendar) {
-      super(getter);
-      this.localCalendar = localCalendar;
-    }
-
-    @Override public Timestamp getTimestamp(Calendar calendar) {
-      java.util.Date date  = (java.util.Date) getObject();
-      if (date == null) {
-        return null;
-      }
-      long v = date.getTime();
-      if (calendar != null) {
-        v -= calendar.getTimeZone().getOffset(v);
-      }
-      return new Timestamp(v);
-    }
-
-    @Override public Date getDate(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Date(timestamp.getTime());
-    }
-
-    @Override public Time getTime(Calendar calendar) {
-      final Timestamp timestamp  = getTimestamp(calendar);
-      if (timestamp == null) {
-        return null;
-      }
-      return new Time(
-          DateTimeUtils.floorMod(timestamp.getTime(),
-              DateTimeUtils.MILLIS_PER_DAY));
-    }
-
-    @Override public String getString() {
-      java.util.Date date  = (java.util.Date) getObject();
-      if (date == null) {
-        return null;
-      }
-      return timestampAsString(date.getTime(), null);
-    }
-
-    @Override public long getLong() {
-      Timestamp timestamp = getTimestamp(localCalendar);
-      return timestamp == null ? 0 : timestamp.getTime();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@code int};
-   * corresponds to {@link java.sql.Types#OTHER}.
-   */
-  private static class IntervalYearMonthAccessor extends IntAccessor {
-    private final TimeUnitRange range;
-
-    public IntervalYearMonthAccessor(Getter getter, TimeUnitRange range) {
-      super(getter);
-      this.range = range;
-    }
-
-    @Override public String getString() {
-      final int v = getInt();
-      if (v == 0 && wasNull()) {
-        return null;
-      }
-      return DateTimeUtils.intervalYearMonthToString(v, range);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a {@code long};
-   * corresponds to {@link java.sql.Types#OTHER}.
-   */
-  private static class IntervalDayTimeAccessor extends LongAccessor {
-    private final TimeUnitRange range;
-    private final int scale;
-
-    public IntervalDayTimeAccessor(Getter getter, TimeUnitRange range,
-        int scale) {
-      super(getter);
-      this.range = range;
-      this.scale = scale;
-    }
-
-    @Override public String getString() {
-      final long v = getLong();
-      if (v == 0 && wasNull()) {
-        return null;
-      }
-      return DateTimeUtils.intervalDayTimeToString(v, range, scale);
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is an ARRAY;
-   * corresponds to {@link java.sql.Types#ARRAY}.
-   */
-  static class ArrayAccessor extends AccessorImpl {
-    final ColumnMetaData.AvaticaType componentType;
-    final Accessor componentAccessor;
-    final SlotGetter componentSlotGetter;
-    final ArrayImpl.Factory factory;
-
-    public ArrayAccessor(Getter getter,
-        ColumnMetaData.AvaticaType componentType, Accessor componentAccessor,
-        SlotGetter componentSlotGetter, ArrayImpl.Factory factory) {
-      super(getter);
-      this.componentType = componentType;
-      this.componentAccessor = componentAccessor;
-      this.componentSlotGetter = componentSlotGetter;
-      this.factory = factory;
-    }
-
-    @Override public Object getObject() {
-      final Object object = super.getObject();
-      if (object == null || object instanceof List) {
-        return object;
-      }
-      // The object can be java array in case of user-provided class for row
-      // storage.
-      return AvaticaUtils.primitiveList(object);
-    }
-
-    @Override public Array getArray() {
-      final List list = (List) getObject();
-      if (list == null) {
-        return null;
-      }
-      return new ArrayImpl(list, this);
-    }
-
-    @Override public String getString() {
-      final Array array = getArray();
-      return array == null ? null : array.toString();
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is a STRUCT;
-   * corresponds to {@link java.sql.Types#STRUCT}.
-   */
-  private static class StructAccessor extends AccessorImpl {
-    private final List<Accessor> fieldAccessors;
-
-    public StructAccessor(Getter getter, List<Accessor> fieldAccessors) {
-      super(getter);
-      this.fieldAccessors = fieldAccessors;
-    }
-
-    @Override public Object getObject() {
-      return getStruct();
-    }
-
-    @Override public Struct getStruct() {
-      final Object o = super.getObject();
-      if (o == null) {
-        return null;
-      } else if (o instanceof List) {
-        return new StructImpl((List) o);
-      } else {
-        final List<Object> list = new ArrayList<>();
-        for (Accessor fieldAccessor : fieldAccessors) {
-          try {
-            list.add(fieldAccessor.getObject());
-          } catch (SQLException e) {
-            throw new RuntimeException(e);
-          }
-        }
-        return new StructImpl(list);
-      }
-    }
-  }
-
-  /**
-   * Accessor that assumes that the underlying value is an OBJECT;
-   * corresponds to {@link java.sql.Types#JAVA_OBJECT}.
-   */
-  private static class ObjectAccessor extends AccessorImpl {
-    public ObjectAccessor(Getter getter) {
-      super(getter);
-    }
-  }
-
-  /** Gets a value from a particular field of the current record of this
-   * cursor. */
-  protected interface Getter {
-    Object getObject();
-
-    boolean wasNull();
-  }
-
-  /** Abstract implementation of {@link Getter}. */
-  protected abstract class AbstractGetter implements Getter {
-    public boolean wasNull() {
-      return wasNull[0];
-    }
-  }
-
-  /** Implementation of {@link Getter} that returns the current contents of
-   * a mutable slot. */
-  public class SlotGetter implements Getter {
-    public Object slot;
-
-    public Object getObject() {
-      return slot;
-    }
-
-    public boolean wasNull() {
-      return slot == null;
-    }
-  }
-
-  /** Implementation of {@link Getter} that returns the value of a given field
-   * of the current contents of another getter. */
-  public class StructGetter implements Getter {
-    public final Getter getter;
-    private final ColumnMetaData columnMetaData;
-
-    public StructGetter(Getter getter, ColumnMetaData columnMetaData) {
-      this.getter = getter;
-      this.columnMetaData = columnMetaData;
-    }
-
-    public Object getObject() {
-      final Object o = getter.getObject();
-      if (o instanceof Object[]) {
-        Object[] objects = (Object[]) o;
-        return objects[columnMetaData.ordinal];
-      }
-      try {
-        final Field field = o.getClass().getField(columnMetaData.label);
-        return field.get(getter.getObject());
-      } catch (IllegalAccessException | NoSuchFieldException e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-    public boolean wasNull() {
-      return getObject() == null;
-    }
-  }
-}
-
-// End AbstractCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
deleted file mode 100644
index b2d5ae9..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
+++ /dev/null
@@ -1,204 +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.util;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.ColumnMetaData;
-
-import java.sql.Array;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/** Implementation of JDBC {@link Array}. */
-public class ArrayImpl implements Array {
-  private final List list;
-  private final AbstractCursor.ArrayAccessor accessor;
-
-  public ArrayImpl(List list, AbstractCursor.ArrayAccessor accessor) {
-    this.list = list;
-    this.accessor = accessor;
-  }
-
-  public String getBaseTypeName() throws SQLException {
-    return accessor.componentType.name;
-  }
-
-  public int getBaseType() throws SQLException {
-    return accessor.componentType.id;
-  }
-
-  public Object getArray() throws SQLException {
-    return getArray(list);
-  }
-
-  @Override public String toString() {
-    final Iterator iterator = list.iterator();
-    if (!iterator.hasNext()) {
-      return "[]";
-    }
-    final StringBuilder buf = new StringBuilder("[");
-    for (;;) {
-      accessor.componentSlotGetter.slot = iterator.next();
-      try {
-        append(buf, accessor.componentAccessor.getString());
-      } catch (SQLException e) {
-        throw new RuntimeException(e);
-      }
-      accessor.componentSlotGetter.slot = null;
-      if (!iterator.hasNext()) {
-        return buf.append("]").toString();
-      }
-      buf.append(", ");
-    }
-  }
-
-  private void append(StringBuilder buf, Object o) {
-    if (o == null) {
-      buf.append("null");
-    } else if (o.getClass().isArray()) {
-      append(buf, AvaticaUtils.primitiveList(o));
-    } else {
-      buf.append(o);
-    }
-  }
-
-  /**
-   * Converts a list into an array.
-   *
-   * <p>If the elements of the list are primitives, converts to an array of
-   * primitives (e.g. {@code boolean[]}.</p>
-   *
-   * @param list List of objects
-   *
-   * @return array
-   * @throws ClassCastException   if any element is not of the box type
-   * @throws NullPointerException if any element is null
-   */
-  @SuppressWarnings("unchecked")
-  protected Object getArray(List list) throws SQLException {
-    int i = 0;
-    switch (accessor.componentType.rep) {
-    case PRIMITIVE_DOUBLE:
-      final double[] doubles = new double[list.size()];
-      for (double v : (List<Double>) list) {
-        doubles[i++] = v;
-      }
-      return doubles;
-    case PRIMITIVE_FLOAT:
-      final float[] floats = new float[list.size()];
-      for (float v : (List<Float>) list) {
-        floats[i++] = v;
-      }
-      return floats;
-    case PRIMITIVE_INT:
-      final int[] ints = new int[list.size()];
-      for (int v : (List<Integer>) list) {
-        ints[i++] = v;
-      }
-      return ints;
-    case PRIMITIVE_LONG:
-      final long[] longs = new long[list.size()];
-      for (long v : (List<Long>) list) {
-        longs[i++] = v;
-      }
-      return longs;
-    case PRIMITIVE_SHORT:
-      final short[] shorts = new short[list.size()];
-      for (short v : (List<Short>) list) {
-        shorts[i++] = v;
-      }
-      return shorts;
-    case PRIMITIVE_BOOLEAN:
-      final boolean[] booleans = new boolean[list.size()];
-      for (boolean v : (List<Boolean>) list) {
-        booleans[i++] = v;
-      }
-      return booleans;
-    case PRIMITIVE_BYTE:
-      final byte[] bytes = new byte[list.size()];
-      for (byte v : (List<Byte>) list) {
-        bytes[i++] = v;
-      }
-      return bytes;
-    case PRIMITIVE_CHAR:
-      final char[] chars = new char[list.size()];
-      for (char v : (List<Character>) list) {
-        chars[i++] = v;
-      }
-      return chars;
-    default:
-      // fall through
-    }
-    final Object[] objects = list.toArray();
-    switch (accessor.componentType.id) {
-    case Types.ARRAY:
-      final AbstractCursor.ArrayAccessor componentAccessor =
-          (AbstractCursor.ArrayAccessor) accessor.componentAccessor;
-      for (i = 0; i < objects.length; i++) {
-        objects[i] = new ArrayImpl((List) objects[i], componentAccessor);
-      }
-    }
-    return objects;
-  }
-
-  public Object getArray(Map<String, Class<?>> map) throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  public Object getArray(long index, int count) throws SQLException {
-    return getArray(list.subList((int) index, count));
-  }
-
-  public Object getArray(long index, int count, Map<String, Class<?>> map)
-      throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  public ResultSet getResultSet() throws SQLException {
-    return accessor.factory.create(accessor.componentType, list);
-  }
-
-  public ResultSet getResultSet(Map<String, Class<?>> map)
-      throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  public ResultSet getResultSet(long index, int count) throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  public ResultSet getResultSet(long index, int count,
-      Map<String, Class<?>> map) throws SQLException {
-    throw new UnsupportedOperationException(); // TODO
-  }
-
-  public void free() throws SQLException {
-    // nothing to do
-  }
-
-  /** Factory that can create a result set based on a list of values. */
-  public interface Factory {
-    ResultSet create(ColumnMetaData.AvaticaType elementType,
-        Iterable<Object> iterable);
-  }
-}
-
-// End ArrayImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
deleted file mode 100644
index 0477984..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/ArrayIteratorCursor.java
+++ /dev/null
@@ -1,41 +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.util;
-
-import java.util.Iterator;
-
-/**
- * Implementation of {@link Cursor} on top of an
- * {@link java.util.Iterator} that
- * returns an array of {@link Object} for each row.
- */
-public class ArrayIteratorCursor extends IteratorCursor<Object[]> {
-  /**
-   * Creates an ArrayEnumeratorCursor.
-   *
-   * @param iterator Iterator
-   */
-  public ArrayIteratorCursor(Iterator<Object[]> iterator) {
-    super(iterator);
-  }
-
-  protected Getter createGetter(int ordinal) {
-    return new ArrayGetter(ordinal);
-  }
-}
-
-// End ArrayIteratorCursor.java


[23/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/avatica_json_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_json_reference.md b/avatica/site/_docs/avatica_json_reference.md
new file mode 100644
index 0000000..d49be7c
--- /dev/null
+++ b/avatica/site/_docs/avatica_json_reference.md
@@ -0,0 +1,1086 @@
+---
+layout: docs
+title: Avatica JSON Reference
+sidebar_title: JSON Reference
+permalink: /docs/avatica_json_reference.html
+requests:
+  - { name: "CatalogsRequest" }
+  - { name: "CloseConnectionRequest" }
+  - { name: "CloseStatementRequest" }
+  - { name: "ColumnsRequest" }
+  - { name: "CommitRequest" }
+  - { name: "ConnectionSyncRequest" }
+  - { name: "CreateStatementRequest" }
+  - { name: "DatabasePropertyRequest" }
+  - { name: "ExecuteRequest" }
+  - { name: "FetchRequest" }
+  - { name: "OpenConnectionRequest" }
+  - { name: "PrepareAndExecuteRequest" }
+  - { name: "PrepareRequest" }
+  - { name: "RollbackRequest" }
+  - { name: "SchemasRequest" }
+  - { name: "SyncResultsRequest" }
+  - { name: "TableTypesRequest" }
+  - { name: "TablesRequest" }
+  - { name: "TypeInfoRequest" }
+miscellaneous:
+  - { name: "AvaticaParameter" }
+  - { name: "AvaticaSeverity" }
+  - { name: "AvaticaType" }
+  - { name: "ColumnMetaData" }
+  - { name: "ConnectionProperties" }
+  - { name: "CursorFactory" }
+  - { name: "DatabaseProperty" }
+  - { name: "Frame" }
+  - { name: "QueryState" }
+  - { name: "Rep" }
+  - { name: "RpcMetadata" }
+  - { name: "Signature" }
+  - { name: "StateType" }
+  - { name: "StatementHandle" }
+  - { name: "StatementType" }
+  - { name: "Style" }
+  - { name: "TypedValue" }
+responses:
+  - { name: "CloseConnectionResponse" }
+  - { name: "CloseStatementResponse" }
+  - { name: "CommitResponse" }
+  - { name: "ConnectionSyncResponse" }
+  - { name: "CreateStatementResponse" }
+  - { name: "DatabasePropertyResponse" }
+  - { name: "ErrorResponse" }
+  - { name: "ExecuteResponse" }
+  - { name: "FetchResponse" }
+  - { name: "OpenConnectionResponse" }
+  - { name: "PrepareResponse" }
+  - { name: "ResultSetResponse" }
+  - { name: "RollbackResponse" }
+  - { name: "SyncResultsResponse" }
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+As Avatica uses JSON to serialize messages sent over an HTTP transport,
+the RPC layer is agnostic of the language used by a client. While the Avatica
+server is written in Java, this enables clients to interact with the server
+using any language instead of being limited to Java.
+
+A specification of the JSON request and response objects are documented
+below. Programmatic bindings for these JSON objects are only available
+in Java. For support outside of Java, see the Protocol Buffer
+[bindings]({{ site.baseurl }}/docs/avatica_protobuf_reference.html)
+
+## Index
+
+### Requests
+<ul>
+  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Responses
+<ul>
+  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Miscellaneous
+<ul>
+  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+
+## Requests
+
+The collection of all JSON objects accepted as requests to Avatica. All Requests include a `request` attribute
+which uniquely identifies the concrete Request from all other Requests.
+
+### CatalogsRequest
+
+This request is used to fetch the available catalog names in the database.
+
+{% highlight json %}
+{
+  "request": "getCatalogs",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use.
+
+### CloseConnectionRequest
+
+This request is used to close the Connection object in the Avatica server identified by the given IDs.
+
+{% highlight json %}
+{
+  "request": "closeConnection",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to close.
+
+### CloseStatementRequest
+
+This request is used to close the Statement object in the Avatica server identified by the given IDs.
+
+{% highlight json %}
+{
+  "request": "closeStatement",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to which the statement belongs.
+
+`statementId` (required integer) The identifier of the statement to close.
+
+### ColumnsRequest
+
+This request is used to fetch columns in the database given some optional filtering criteria.
+
+{% highlight json %}
+{
+  "request": "getColumns",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "catalog",
+  "schemaPattern": "schema_pattern.*",
+  "tableNamePattern": "table_pattern.*",
+  "columnNamePattern": "column_pattern.*"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection on which to fetch the columns.
+
+`catalog` (optional string) The name of a catalog to limit returned columns.
+
+`schemaPattern` (optional string) A Java Pattern against schemas to limit returned columns.
+
+`tableNamePattern` (optional string) A Java Pattern against table names to limit returned columns.
+
+`columnNamePattern` (optional string) A Java Pattern against column names to limit returned columns.
+
+### CommitRequest
+
+This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight json %}
+{
+  "request": "commit",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection on which to invoke commit.
+
+### ConnectionSyncRequest
+
+This request is used to ensure that the client and server have a consistent view of the database properties.
+
+{% highlight json %}
+{
+  "request": "connectionSync",
+  "connectionId": "000000-0000-0000-00000000",
+  "connProps": ConnectionProperties
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to synchronize.
+
+`connProps` (optional nested object) A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
+
+### CreateStatementRequest
+
+This request is used to create a new Statement in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "createStatement",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use in creating a statement.
+
+### DatabasePropertyRequest
+
+This request is used to fetch all <a href="#databaseproperty">database properties</a>.
+
+{% highlight json %}
+{
+  "request": "databaseProperties",
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use when fetching the database properties.
+
+### ExecuteRequest
+
+This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
+
+{% highlight json %}
+{
+  "request": "execute",
+  "statementHandle": StatementHandle,
+  "parameterValues": [TypedValue, TypedValue, ... ],
+  "maxRowCount": 100
+}
+{% endhighlight %}
+
+`statementHandle` (required object) A <a href="#statementhandle">StatementHandle</a> object.
+
+`parameterValues` (optional array of nested objects) The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### FetchRequest
+
+This request is used to fetch a batch of rows from a Statement previously created.
+
+{% highlight json %}
+{
+  "request": "fetch",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "offset": 0,
+  "fetchMaxRowCount": 100
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to use.
+
+`statementId` (required integer) The identifier of the statement created using the above connection.
+
+`offset` (required integer) The positional offset into a result set to fetch.
+
+`fetchMatchRowCount` (required integer) The maximum number of rows to return in the response to this request.
+
+### OpenConnectionRequest
+
+This request is used to open a new Connection in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "openConnection",
+  "connectionId": "000000-0000-0000-00000000",
+  "info": {"key":"value", ...}
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier of the connection to open in the server.
+
+`info` (optional string-to-string map) A Map containing properties to include when creating the Connection.
+
+### PrepareAndExecuteRequest
+
+This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
+
+{% highlight json %}
+{
+  "request": "prepareAndExecute",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "sql": "SELECT * FROM table",
+  "maxRowCount": 100,
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`statementId` (required integer) The identifier for the statement created by the above connection to use.
+
+`sql` (required string) A SQL statement
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### PrepareRequest
+
+This request is used to create create a new Statement with the given query in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "prepare",
+  "connectionId": "000000-0000-0000-00000000",
+  "sql": "SELECT * FROM table",
+  "maxRowCount": 100,
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`sql` (required string) A SQL statement
+
+`maxRowCount` (required long) The maximum number of rows returned in the response.
+
+### SyncResultsRequest
+
+This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
+
+{% highlight json %}
+{
+  "request": "syncResults",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "state": QueryState,
+  "offset": 200
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection to use.
+
+`statementId` (required integer) The identifier for the statement to use.
+
+`state` (required object) The <a href="#querystate">QueryState</a> object.
+
+`offset` (required long) The offset into the ResultSet to seek to.
+
+### RollbackRequest
+
+This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight json %}
+{
+  "request": "rollback",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` (required string) The identifier for the connection on which to invoke rollback.
+
+### SchemasRequest
+
+This request is used to fetch the schemas matching the provided criteria in the database.
+
+{% highlight json %}
+{
+  "request": "getSchemas",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "name",
+  "schemaPattern": "pattern.*"
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to fetch schemas from.
+
+`catalog` (required string) The name of the catalog to fetch the schema from.
+
+`schemaPattern` (required string) A Java pattern of schemas to fetch.
+
+### TableTypesRequest
+
+This request is used to fetch the table types available in this database.
+
+{% highlight json %}
+{
+  "request": "getTableTypes",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to fetch the table types from.
+
+### TablesRequest
+
+This request is used to fetch the tables available in this database filtered by the provided criteria.
+
+{% highlight json %}
+{
+  "request": "getTables",
+  "connectionId": "000000-0000-0000-00000000",
+  "catalog": "catalog_name",
+  "schemaPattern": "schema_pattern.*",
+  "tableNamePattern": "table_name_pattern.*",
+  "typeList": [ "TABLE", "VIEW", ... ]
+}
+{% endhighlight %}
+
+`catalog` (optional string) The name of a catalog to restrict fetched tables.
+
+`connectionId` The identifier of the connection to fetch the tables from.
+
+`schemaPattern` (optional string) A Java Pattern representing schemas to include in fetched tables.
+
+`tableNamePattern` (optional string) A Java Pattern representing table names to include in fetched tables.
+
+`typeList` (optional array of string) A list of table types used to restrict fetched tables.
+
+### TypeInfoRequest
+
+This request is used to fetch the types available in this database.
+
+{% highlight json %}
+{
+  "request": "getTypeInfo",
+  "connectionId": "000000-0000-0000-00000000"
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to fetch the types from.
+
+## Responses
+
+The collection of all JSON objects returned as responses from Avatica. All Responses include a `response` attribute
+which uniquely identifies the concrete Response from all other Responses.
+
+### CloseConnectionResponse
+
+A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
+
+{% highlight json %}
+{
+  "response": "closeConnection",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CloseStatementResponse
+
+A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
+
+{% highlight json %}
+{
+  "response": "closeStatement",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CommitResponse
+
+A response to the <a href="#commitrequest">CommitRequest</a>.
+
+{% highlight json %}
+{
+  "response": "commit"
+}
+{% endhighlight %}
+
+There are no extra attributes on this Response.
+
+### ConnectionSyncResponse
+
+A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
+response are those of the Connection in the Avatica server.
+
+{% highlight json %}
+{
+  "response": "connectionSync",
+  "connProps": ConnectionProperties,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connProps` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CreateStatementResponse
+
+A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
+that was created is included in the response. Clients will use this `statementId` in subsequent calls.
+
+{% highlight json %}
+{
+  "response": "createStatement",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connectionId` The identifier for the connection used to create the statement.
+
+`statementId` The identifier for the created statement.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### DatabasePropertyResponse
+
+A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
+for information on the available property keys.
+
+{% highlight json %}
+{
+  "response": "databaseProperties",
+  "map": { DatabaseProperty: Object, DatabaseProperty: Object, ... },
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`map` A map of <a href="#databaseproperty">DatabaseProperty</a> to value of that property. The value may be some
+primitive type or an array of primitive types.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ErrorResponse
+
+A response when an error was caught executing a request. Any request may return this response.
+
+{% highlight json %}
+{
+  "response": "error",
+  "exceptions": [ "stacktrace", "stacktrace", ... ],
+  "errorMessage": "The error message",
+  "errorCode": 42,
+  "sqlState": "ABC12",
+  "severity": AvaticaSeverity,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`exceptions` A list of stringified Java StackTraces.
+
+`errorMessage` A human-readable error message.
+
+`errorCode` A numeric code for this error.
+
+`sqlState` A five character alphanumeric code for this error.
+
+`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ExecuteResponse
+
+A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
+
+{% highlight json %}
+{
+  "response": "executeResults",
+  "resultSets": [ ResultSetResponse, ResultSetResponse, ... ],
+  "missingStatement": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`resultSets` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
+
+`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### FetchResponse
+
+A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
+
+{% highlight json %}
+{
+  "response": "fetch",
+  "frame": Frame,
+  "missingStatement": false,
+  "missingResults": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
+
+`missingStatement` A boolean which denotes if the request failed due to a missing Statement.
+
+`missingResults` A boolean which denotes if the request failed due to a missing ResultSet.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### OpenConnectionResponse
+
+A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
+the client should use in subsequent calls was provided by the client in the request.
+
+{% highlight json %}
+{
+  "response": "openConnection",
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### PrepareResponse
+
+A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
+which clients must use to fetch the results from the Statement.
+
+{% highlight json %}
+{
+  "response": "prepare",
+  "statement": StatementHandle,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`statement` A <a href="#statementhandle">StatementHandle</a> object.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ResultSetResponse
+
+A response which contains the results and type details from a query.
+
+{% highlight json %}
+{
+  "response": "resultSet",
+  "connectionId": "000000-0000-0000-00000000",
+  "statementId": 12345,
+  "ownStatement": true,
+  "signature": Signature,
+  "firstFrame": Frame,
+  "updateCount": 10,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`connectionId` The identifier for the connection used to generate this response.
+
+`statementId` The identifier for the statement used to generate this response.
+
+`ownStatement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
+statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
+
+`signature` A non-optional nested object <a href="#signature">Signature</a>
+
+`firstFrame` A optional nested object <a href="#frame">Frame</a>
+
+`updateCount` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
+that only contains this count and no additional data.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### RollbackResponse
+
+A response to the <a href="#rollbackrequest">RollBackRequest</a>.
+
+{% highlight json %}
+{
+  "response": "rollback"
+}
+{% endhighlight %}
+
+There are no extra attributes on this Response.
+
+### SyncResultsResponse
+
+A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
+should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
+or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
+
+{% highlight json %}
+{
+  "response": "syncResults",
+  "moreResults": true,
+  "missingStatement": false,
+  "rpcMetadata": RpcMetadata
+}
+{% endhighlight %}
+
+`moreResults` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
+
+`missingStatement` A boolean which denotes if the statement for the ResultSet still exists.
+
+`rpcMetadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+## Miscellaneous
+
+### AvaticaParameter
+
+This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
+complex types such as arrays.
+
+{% highlight json %}
+{
+  "signed": true,
+  "precision": 10,
+  "scale": 2,
+  "parameterType": 8,
+  "typeName": "integer",
+  "className": "java.lang.Integer",
+  "name": "number"
+}
+{% endhighlight %}
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`parameterType` An integer corresponding to the JDBC Types class denoting the column's type.
+
+`typeName` The JDBC type name for this column.
+
+`className` The Java class backing the JDBC type for this column.
+
+`name` The name of the column.
+
+### AvaticaSeverity
+
+This enumeration describes the various levels of concern for an error in the Avatica server.
+
+One of:
+
+* `UNKNOWN`
+* `FATAL`
+* `ERROR`
+* `WARNING`
+
+### AvaticaType
+
+This object describes a simple or complex type for a column. Complex types will contain
+additional information in the `component` or `columns` attribute which describe the nested
+types of the complex parent type.
+
+{% highlight json %}
+{
+  "type": "scalar",
+  "id": "identifier",
+  "name": "column",
+  "rep": Rep,
+  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
+  "component": AvaticaType
+}
+{% endhighlight %}
+
+`type` One of: `scalar`, `array`, `struct`.
+
+`id` A numeric value corresponding to the type of the object per the JDBC Types class.
+
+`name` The readable name of the JDBC type.
+
+`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
+
+`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
+
+`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
+
+### ColumnMetaData
+
+This object represents the JDBC ResultSetMetaData for a column.
+
+{% highlight json %}
+{
+  "ordinal": 0,
+  "autoIncrement": true,
+  "caseSensitive": true,
+  "searchable": false,
+  "currency": false,
+  "nullable": 0,
+  "signed": true,
+  "displaySize": 20,
+  "label": "Description",
+  "columnName": "col1",
+  "schemaName": "schema",
+  "precision": 10,
+  "scale": 2,
+  "tableName": "table",
+  "catalogName": "catalog",
+  "type": AvaticaType,
+  "readOnly": false,
+  "writable": true,
+  "definitelyWritable": true,
+  "columnClassName": "java.lang.String"
+}
+{% endhighlight %}
+
+`ordinal` A positional offset number.
+
+`autoIncrement` A boolean denoting whether the column is automatically incremented.
+
+`caseSensitive` A boolean denoting whether the column is case sensitive.
+
+`searchable` A boolean denoting whether this column supports all WHERE search clauses.
+
+`currency` A boolean denoting whether this column represents currency.
+
+`nullable` A number denoting whether this column supports null values.
+
+* 0 = No null values are allowed
+* 1 = Null values are allowed
+* 2 = It is unknown if null values are allowed
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`displaySize` The character width of the column.
+
+`label` A description for this column.
+
+`columnName` The name of the column.
+
+`schemaName` The schema to which this column belongs.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`tableName` The name of the table to which this column belongs.
+
+`catalogName` The name of the catalog to which this column belongs.
+
+`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
+
+`readOnly` A boolean denoting whether the column is read-only.
+
+`writable` A boolean denoting whether the column is possible to be updated.
+
+`definitelyWritable` A boolean denoting whether the column definitely can be updated.
+
+`columnClassName` The name of the Java class backing the column's type.
+
+### ConnectionProperties
+
+This object represents the properties for a given JDBC Connection.
+
+{% highlight json %}
+{
+  "connProps": "connPropsImpl",
+  "autoCommit": true,
+  "readOnly": true,
+  "transactionIsolation": 0,
+  "catalog": "catalog",
+  "schema": "schema"
+}
+{% endhighlight %}
+
+`autoCommit` (optional boolean) A boolean denoting if autoCommit is enabled for transactions.
+
+`readOnly` (optional boolean) A boolean denoting if a JDBC connection is read-only.
+
+`transactionIsolation` (optional integer) An integer which denotes the level of transactions isolation per the JDBC
+specification. This value is analogous to the values defined in `java.sql.Connection`.
+
+* 0 = Transactions are not supported
+* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
+* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
+* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
+* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
+
+`catalog` (optional string) The name of the catalog to include when fetching connection properties.
+
+`schema` (optional string) The name of the schema to include when fetching connection properties.
+
+### CursorFactory
+
+This object represents the information required to cast untyped objects into the necessary type for some results.
+
+{% highlight json %}
+{
+  "style": Style,
+  "clazz": "java.lang.String",
+  "fieldNames": [ "column1", "column2", ... ]
+}
+{% endhighlight %}
+
+`style` A string denoting the <a href="#style">Style</a> of the contained objects.
+
+### DatabaseProperty
+
+This object represents the exposed database properties for a Connection through the Avatica server.
+
+One of:
+
+* `GET_STRING_FUNCTIONS`
+* `GET_NUMERIC_FUNCTIONS`
+* `GET_SYSTEM_FUNCTIONS`
+* `GET_TIME_DATE_FUNCTIONS`
+* `GET_S_Q_L_KEYWORDS`
+* `GET_DEFAULT_TRANSACTION_ISOLATION`
+
+### Frame
+
+This object represents a batch of results, tracking the offset into the results and whether more results still exist
+to be fetched in the Avatica server.
+
+{% highlight json %}
+{
+  "offset": 100,
+  "done": true,
+  "rows": [ [ val1, val2, ... ], ... ]
+}
+{% endhighlight %}
+
+`offset` The starting position of these `rows` in the encompassing result set.
+
+`done` A boolean denoting whether more results exist for this result set.
+
+`rows` An array of arrays corresponding to the rows and columns for the result set.
+
+### QueryState
+
+This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
+SQL or by a DatabaseMetaData operation with arguments on that operation.
+
+{% highlight json %}
+{
+  "type": StateType,
+  "sql": "SELECT * FROM table",
+  "metaDataOperation": MetaDataOperation,
+  "operationArgs": ["arg0", "arg1", ... ]
+}
+{% endhighlight %}
+
+`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
+
+`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
+
+`metaDataOperation` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
+
+`operationArgs` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
+
+### Rep
+
+This enumeration represents the concrete Java type for some value.
+
+One of:
+
+* `PRIMITIVE_BOOLEAN`
+* `PRIMITIVE_BYTE`
+* `PRIMITIVE_CHAR`
+* `PRIMITIVE_SHORT`
+* `PRIMITIVE_INT`
+* `PRIMITIVE_LONG`
+* `PRIMITIVE_FLOAT`
+* `PRIMITIVE_DOUBLE`
+* `BOOLEAN`
+* `BYTE`
+* `CHARACTER`
+* `SHORT`
+* `INTEGER`
+* `LONG`
+* `FLOAT`
+* `DOUBLE`
+* `JAVA_SQL_TIME`
+* `JAVA_SQL_TIMESTAMP`
+* `JAVA_SQL_DATE`
+* `JAVA_UTIL_DATE`
+* `BYTE_STRING`
+* `STRING`
+* `NUMBER`
+* `OBJECT`
+
+### RpcMetadata
+
+This object contains assorted per-call/contextual metadata returned by the Avatica server.
+
+{% highlight json %}
+{
+  "serverAddress": "localhost:8765"
+}
+{% endhighlight %}
+
+`serverAddress` The `host:port` of the server which created this object.
+
+### Signature
+
+This object represents the result of preparing a Statement in the Avatica server.
+
+{% highlight json %}
+{
+  "columns": [ ColumnMetaData, ColumnMetaData, ... ],
+  "sql": "SELECT * FROM table",
+  "parameters": [ AvaticaParameter, AvaticaParameter, ... ],
+  "cursorFactory": CursorFactory,
+  "statementType": StatementType
+}
+{% endhighlight %}
+
+`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
+
+`sql` The SQL executed.
+
+`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
+
+`cursorFactory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
+
+`statementType` An <a href="#statementtype">StatementType</a> object representing the type of Statement.
+
+### StateType
+
+This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
+
+One of:
+
+* `SQL`
+* `METADATA`
+
+### StatementHandle
+
+This object encapsulates all of the information of a Statement created in the Avatica server.
+
+{% highlight json %}
+{
+  "connectionId": "000000-0000-0000-00000000",
+  "id": 12345,
+  "signature": Signature
+}
+{% endhighlight %}
+
+`connectionId` The identifier of the connection to which this statement belongs.
+
+`id` The identifier of the statement.
+
+`signature` A <a href="#signature">Signature</a> object for the statement.
+
+### StatementType
+
+This enumeration represents what kind the Statement is.
+
+One of:
+
+* `SELECT`
+* `INSERT`
+* `UPDATE`
+* `DELETE`
+* `UPSERT`
+* `MERGE`
+* `OTHER_DML`
+* `CREATE`
+* `DROP`
+* `ALTER`
+* `OTHER_DDL`
+* `CALL`
+
+### Style
+
+This enumeration represents the generic "class" of type for a value.
+
+One of:
+
+* `OBJECT`
+* `RECORD`
+* `RECORD_PROJECTION`
+* `ARRAY`
+* `LIST`
+* `MAP`
+
+### TypedValue
+
+This object encapsulates the type and value for a column in a row.
+
+{% highlight json %}
+{
+  "type": "type_name",
+  "value": object
+}
+{% endhighlight %}
+
+`type` A name referring to the type of the object stored in `value`.
+
+`value` A JSON representation of a JDBC type.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/avatica_overview.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_overview.md b/avatica/site/_docs/avatica_overview.md
new file mode 100644
index 0000000..6c77eb9
--- /dev/null
+++ b/avatica/site/_docs/avatica_overview.md
@@ -0,0 +1,130 @@
+---
+layout: docs
+title: Avatica Overview
+sidebar_title: Overview
+permalink: /docs/avatica_overview.html
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Avatica is a framework for building JDBC and ODBC drivers for databases,
+and an RPC wire protocol.
+
+![Avatica Architecture](https://raw.githubusercontent.com/julianhyde/share/master/slides/avatica-architecture.png)
+
+Avatica's Java binding has very few dependencies.
+Even though it is part of Apache Calcite it does not depend on other parts of
+Calcite. It depends only on JDK 1.7+ and Jackson.
+
+Avatica's wire protocol is JSON over HTTP.
+The Java implementation uses Jackson to convert request/response command
+objects to/from JSON.
+
+Avatica-Server is a Java implementation of Avatica RPC.
+
+Core concepts:
+
+* Meta is a local API sufficient to implement any Avatica provider
+* Factory creates implementations of the JDBC classes (Driver, Connection,
+  Statement, ResultSet) on top of a Meta
+* Service is an interface that implements the functions of Meta in terms
+  of request and response command objects
+
+## JDBC
+
+Avatica implements JDBC by means of Factory.
+Factory creates implementations of the JDBC classes (Driver, Connection,
+Statement, PreparedStatement, ResultSet) on top of a Meta.
+
+## ODBC
+
+Work has not started on Avatica ODBC.
+
+Avatica ODBC would use the same wire protocol and could use the same server
+implementation in Java. The ODBC client would be written in C or C++.
+
+Since the Avatica protocol abstracts many of the differences between providers,
+the same ODBC client could be used for different databases.
+
+## HTTP Server
+
+Avatica-server embeds the Jetty HTTP server, providing a class
+[HttpServer]({{ site.apiRoot }}/org/apache/calcite/avatica/server/HttpServer.html)
+that implements the Avatica RPC protocol
+and can be run as a standalone Java application.
+
+Connectors in HTTP server can be configured if needed by extending
+`HttpServer` class and overriding its `configureConnector()` method.
+For example, user can set `requestHeaderSize` to 64K bytes as follows:
+
+{% highlight java %}
+HttpServer server = new HttpServer(handler) {
+  @Override
+  protected ServerConnector configureConnector(
+      ServerConnector connector, int port) {
+    HttpConnectionFactory factory = (HttpConnectionFactory)
+        connector.getDefaultConnectionFactory();
+    factory.getHttpConfiguration().setRequestHeaderSize(64 << 10);
+    return super.configureConnector(connector, port);
+  }
+};
+server.start();
+{% endhighlight %}
+
+## Project structure
+
+We know that it is important that client libraries have minimal dependencies.
+
+Avatica is currently part of Apache Calcite.
+It does not depend upon any other part of Calcite.
+At some point Avatica could become a separate project.
+
+Packages:
+
+* [org.apache.calcite.avatica]({{ site.apiRoot }}/org/apache/calcite/avatica/package-summary.html) Core framework
+* [org.apache.calcite.avatica.remote]({{ site.apiRoot }}/org/apache/calcite/avatica/remote/package-summary.html) JDBC driver that uses remote procedure calls
+* [org.apache.calcite.avatica.server]({{ site.apiRoot }}/org/apache/calcite/avatica/server/package-summary.html) HTTP server
+* [org.apache.calcite.avatica.util]({{ site.apiRoot }}/org/apache/calcite/avatica/util/package-summary.html) Utilities
+
+## Status
+
+### Implemented
+
+* Create connection, create statement, metadata, prepare, bind, execute, fetch
+* RPC using JSON over HTTP
+* Local implementation
+* Implementation over an existing JDBC driver
+* Composite RPCs (combining several requests into one round trip)
+  * Execute-Fetch
+  * Metadata-Fetch (metadata calls such as getTables return all rows)
+
+### Not implemented
+
+* ODBC
+* RPCs
+  * CloseStatement
+  * CloseConnection
+* Composite RPCs
+  * CreateStatement-Prepare
+  * CloseStatement-CloseConnection
+  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
+* Remove statements from statement table
+* DML (INSERT, UPDATE, DELETE)
+* Statement.execute applied to SELECT statement

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/avatica_protobuf_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_protobuf_reference.md b/avatica/site/_docs/avatica_protobuf_reference.md
new file mode 100644
index 0000000..02a8ab1
--- /dev/null
+++ b/avatica/site/_docs/avatica_protobuf_reference.md
@@ -0,0 +1,1181 @@
+---
+layout: docs
+title: Avatica Protocol Buffers Reference
+sidebar_title: Protobuf Reference
+permalink: /docs/avatica_protobuf_reference.html
+requests:
+  - { name: "CatalogsRequest" }
+  - { name: "CloseConnectionRequest" }
+  - { name: "CloseStatementRequest" }
+  - { name: "ColumnsRequest" }
+  - { name: "CommitRequest" }
+  - { name: "ConnectionSyncRequest" }
+  - { name: "CreateStatementRequest" }
+  - { name: "DatabasePropertyRequest" }
+  - { name: "ExecuteRequest" }
+  - { name: "FetchRequest" }
+  - { name: "OpenConnectionRequest" }
+  - { name: "PrepareAndExecuteRequest" }
+  - { name: "PrepareRequest" }
+  - { name: "RollbackRequest" }
+  - { name: "SchemasRequest" }
+  - { name: "SyncResultsRequest" }
+  - { name: "TableTypesRequest" }
+  - { name: "TablesRequest" }
+  - { name: "TypeInfoRequest" }
+miscellaneous:
+  - { name: "AvaticaParameter" }
+  - { name: "AvaticaSeverity" }
+  - { name: "AvaticaType" }
+  - { name: "ColumnMetaData" }
+  - { name: "ColumnValue" }
+  - { name: "ConnectionProperties" }
+  - { name: "CursorFactory" }
+  - { name: "DatabaseProperty" }
+  - { name: "Frame" }
+  - { name: "QueryState" }
+  - { name: "Rep" }
+  - { name: "Row" }
+  - { name: "RpcMetadata" }
+  - { name: "Signature" }
+  - { name: "StateType" }
+  - { name: "StatementHandle" }
+  - { name: "StatementType" }
+  - { name: "Style" }
+  - { name: "TypedValue" }
+  - { name: "WireMessage" }
+responses:
+  - { name: "CloseConnectionResponse" }
+  - { name: "CloseStatementResponse" }
+  - { name: "CommitResponse" }
+  - { name: "ConnectionSyncResponse" }
+  - { name: "CreateStatementResponse" }
+  - { name: "DatabasePropertyResponse" }
+  - { name: "ErrorResponse" }
+  - { name: "ExecuteResponse" }
+  - { name: "FetchResponse" }
+  - { name: "OpenConnectionResponse" }
+  - { name: "PrepareResponse" }
+  - { name: "ResultSetResponse" }
+  - { name: "RollbackResponse" }
+  - { name: "SyncResultsResponse" }
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Avatica also supports [Protocol Buffers](https://developers.google.com/protocol-buffers/)
+as a message format since version 1.5.0. The Protocol Buffer, or protobuf for
+short, implementation is extremely similar to the JSON implementation. Some
+differences include protobuf's expanded type support (such as native byte arrays)
+and inability to differentiate between the default value for a field and the
+absence of a value for a field.
+
+Other notable structural differences to JSON include the addition of a
+`WireMessage` message which is used to identify the type of the wrapped message
+returned by the server (synonymous with `request` or `response` attribute on the
+JSON messages) and a change to `TypedValue` containing an `Object` value to
+a collection of optional strongly-typed values (as protobuf does not natively
+support an `Object` type that is unwrapped at runtime).
+
+Unless otherwise specified with use of the `required` modifier, all fields in
+all protocol buffer messages are `optional` by default.
+
+## Index
+
+### Requests
+<ul>
+  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Responses
+<ul>
+  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Miscellaneous
+<ul>
+  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+
+## Requests
+
+The collection of all protobuf objects accepted as requests to Avatica. All request
+objects should be wrapped in a `WireMessage` before being sent to Avatica.
+
+### CatalogsRequest
+
+This request is used to fetch the available catalog names in the database.
+
+{% highlight protobuf %}
+message CatalogsRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+### CloseConnectionRequest
+
+This request is used to close the Connection object in the Avatica server identified by the given IDs.
+
+{% highlight protobuf %}
+message CloseConnectionRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to close.
+
+### CloseStatementRequest
+
+This request is used to close the Statement object in the Avatica server identified by the given IDs.
+
+{% highlight protobuf %}
+message CloseStatementRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to which the statement belongs.
+
+`statement_id` The identifier of the statement to close.
+
+### ColumnsRequest
+
+This request is used to fetch columns in the database given some optional filtering criteria.
+
+{% highlight protobuf %}
+message ColumnsRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  string column_name_pattern = 4;
+  string connection_id = 5;
+}
+{% endhighlight %}
+
+`catalog` The name of a catalog to limit returned columns.
+
+`schema_pattern` A Java Pattern against schemas to limit returned columns.
+
+`table_name_pattern` A Java Pattern against table names to limit returned columns.
+
+`column_name_pattern` A Java Pattern against column names to limit returned columns.
+
+`connection_id` The identifier of the connection which to use to fetch the columns.
+
+### CommitRequest
+
+This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight protobuf %}
+message CommitRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection on which to invoke commit.
+
+### ConnectionSyncRequest
+
+This request is used to ensure that the client and server have a consistent view of the database properties.
+
+{% highlight protobuf %}
+message ConnectionSyncRequest {
+  string connection_id = 1;
+  ConnectionProperties conn_props = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to synchronize.
+
+`conn_props` A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
+
+### CreateStatementRequest
+
+This request is used to create a new Statement in the Avatica server.
+
+{% highlight protobuf %}
+message CreateStatementRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use in creating a statement.
+
+### DatabasePropertyRequest
+
+This request is used to fetch all <a href="#databaseproperty">database properties</a>.
+
+{% highlight protobuf %}
+message DatabasePropertyRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use when fetching the database properties.
+
+### ExecuteRequest
+
+This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
+
+{% highlight protobuf %}
+message ExecuteRequest {
+  StatementHandle statementHandle = 1;
+  repeated TypedValue parameter_values = 2;
+  uint64 max_row_count = 3;
+  bool has_parameter_values = 4;
+}
+{% endhighlight %}
+
+`statementHandle` A <a href="#statementhandle">StatementHandle</a> object.
+
+`parameter_values` The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
+
+`max_row_count` The maximum number of rows returned in the response.
+
+`has_parameter_values` A boolean which denotes if the user set a value for the `parameter_values` field.
+
+### FetchRequest
+
+This request is used to fetch a batch of rows from a Statement previously created.
+
+{% highlight protobuf %}
+message FetchRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  uint64 offset = 3;
+  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use.
+
+`statement_id` The identifier of the statement created using the above connection.
+
+`offset` The positional offset into a result set to fetch.
+
+`fetch_match_row_count` The maximum number of rows to return in the response to this request.
+
+### OpenConnectionRequest
+
+This request is used to open a new Connection in the Avatica server.
+
+{% highlight protobuf %}
+message OpenConnectionRequest {
+  string connection_id = 1;
+  map<string, string> info = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to open in the server.
+
+`info` A Map containing properties to include when creating the Connection.
+
+### PrepareAndExecuteRequest
+
+This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
+
+{% highlight protobuf %}
+message PrepareAndExecuteRequest {
+  string connection_id = 1;
+  uint32 statement_id = 4;
+  string sql = 2;
+  uint64 max_row_count = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`statement_id` The identifier for the statement created by the above connection to use.
+
+`sql` A SQL statement
+
+`max_row_count` The maximum number of rows returned in the response.
+
+### PrepareRequest
+
+This request is used to create create a new Statement with the given query in the Avatica server.
+
+{% highlight protobuf %}
+message PrepareRequest {
+  string connection_id = 1;
+  string sql = 2;
+  uint64 max_row_count = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`sql` A SQL statement
+
+`max_row_count` The maximum number of rows returned in the response.
+
+### SyncResultsRequest
+
+This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
+
+{% highlight protobuf %}
+message SyncResultsRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  QueryState state = 3;
+  uint64 offset = 4;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`statement_id` The identifier for the statement to use.
+
+`state` The <a href="#querystate">QueryState</a> object.
+
+`offset` The offset into the ResultSet to seek to.
+
+### RollbackRequest
+
+This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight protobuf %}
+message RollbackRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection on which to invoke rollback.
+
+### SchemasRequest
+
+This request is used to fetch the schemas matching the provided criteria in the database.
+
+{% highlight protobuf %}
+message SchemasRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string connection_id = 3;
+}
+{% endhighlight %}
+
+`catalog` The name of the catalog to fetch the schema from.
+
+`schema_pattern` A Java pattern of schemas to fetch.
+
+`connection_id` The identifier for the connection to fetch schemas from.
+
+### TableTypesRequest
+
+This request is used to fetch the table types available in this database.
+
+{% highlight protobuf %}
+message TableTypesRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to fetch the table types from.
+
+### TablesRequest
+
+This request is used to fetch the tables available in this database filtered by the provided criteria.
+
+{% highlight protobuf %}
+message TablesRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  repeated string type_list = 4;
+  bool has_type_list = 6;
+  string connection_id = 7;
+}
+{% endhighlight %}
+
+`catalog` The name of a catalog to restrict fetched tables.
+
+`schema_pattern` A Java Pattern representing schemas to include in fetched tables.
+
+`table_name_pattern` A Java Pattern representing table names to include in fetched tables.
+
+`type_list` A list of table types used to restrict fetched tables.
+
+`has_type_list` A boolean which denotes if the field `type_list` was provided.
+
+`connection_id` The identifier of the connection to fetch the tables from.
+
+### TypeInfoRequest
+
+This request is used to fetch the types available in this database.
+
+{% highlight protobuf %}
+message TypeInfoRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to fetch the types from.
+
+## Responses
+
+The collection of all protobuf objects accepted as requests to Avatica. All response
+objects will be wrapped in a `WireMessage` before being returned from Avatica.
+
+### CloseConnectionResponse
+
+A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
+
+{% highlight protobuf %}
+message CloseConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CloseStatementResponse
+
+A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
+
+{% highlight protobuf %}
+message CloseStatementResponse {
+  RpcMetadata metadata = 1;
+}
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CommitResponse
+
+A response to the <a href="#commitrequest">CommitRequest</a>.
+
+{% highlight protobuf %}
+message CommitResponse {
+
+}
+{% endhighlight %}
+
+There are no attributes on this Response.
+
+### ConnectionSyncResponse
+
+A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
+response are those of the Connection in the Avatica server.
+
+{% highlight protobuf %}
+message ConnectionSyncResponse {
+  ConnectionProperties conn_props = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`conn_props` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CreateStatementResponse
+
+A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
+that was created is included in the response. Clients will use this `statement_id` in subsequent calls.
+
+{% highlight protobuf %}
+message CreateStatementResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection used to create the statement.
+
+`statement_id` The identifier for the created statement.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### DatabasePropertyResponse
+
+A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
+for information on the available property keys.
+
+{% highlight protobuf %}
+message DatabasePropertyResponse {
+  repeated DatabasePropertyElement props = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`props` A collection of <a href="#databaseproperty">DatabaseProperty</a>'s.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ErrorResponse
+
+A response when an error was caught executing a request. Any request may return this response.
+
+{% highlight protobuf %}
+message ErrorResponse {
+  repeated string exceptions = 1;
+  bool has_exceptions = 7;
+  string error_message = 2;
+  Severity severity = 3;
+  uint32 error_code = 4;
+  string sql_state = 5;
+  RpcMetadata metadata = 6;
+}
+{% endhighlight %}
+
+`exceptions` A list of stringified Java StackTraces.
+
+`has_exceptions` A boolean which denotes the presence of `exceptions`.
+
+`error_message` A human-readable error message.
+
+`error_code` A numeric code for this error.
+
+`sql_state` A five character alphanumeric code for this error.
+
+`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ExecuteResponse
+
+A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
+
+{% highlight protobuf %}
+message ExecuteResponse {
+  repeated ResultSetResponse results = 1;
+  bool missing_statement = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`results` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
+
+`missing_statement` A boolean which denotes if the request failed due to a missing statement.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### FetchResponse
+
+A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
+
+{% highlight protobuf %}
+message FetchResponse {
+  Frame frame = 1;
+  bool missing_statement = 2;
+  bool missing_results = 3;
+  RpcMetadata metadata = 4;
+}
+{% endhighlight %}
+
+`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
+
+`missing_statement` A boolean which denotes if the request failed due to a missing Statement.
+
+`missing_results` A boolean which denotes if the request failed due to a missing ResultSet.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### OpenConnectionResponse
+
+A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
+the client should use in subsequent calls was provided by the client in the request.
+
+{% highlight protobuf %}
+message OpenConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### PrepareResponse
+
+A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
+which clients must use to fetch the results from the Statement.
+
+{% highlight protobuf %}
+message PrepareResponse {
+  StatementHandle statement = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`statement` A <a href="#statementhandle">StatementHandle</a> object.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ResultSetResponse
+
+A response which contains the results and type details from a query.
+
+{% highlight protobuf %}
+message ResultSetResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  bool own_statement = 3;
+  Signature signature = 4;
+  Frame first_frame = 5;
+  uint64 update_count = 6;
+  RpcMetadata metadata = 7;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection used to generate this response.
+
+`statement_id` The identifier for the statement used to generate this response.
+
+`own_statement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
+statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
+
+`signature` A non-optional nested object <a href="#signature">Signature</a>
+
+`first_frame` A optional nested object <a href="#frame">Frame</a>
+
+`update_count` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
+that only contains this count and no additional data.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### RollbackResponse
+
+A response to the <a href="#rollbackrequest">RollBackRequest</a>.
+
+{% highlight protobuf %}
+message RollbackResponse {
+
+}
+{% endhighlight %}
+
+There are no attributes on this Response.
+
+### SyncResultsResponse
+
+A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
+should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
+or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
+
+{% highlight protobuf %}
+message SyncResultsResponse {
+  bool missing_statement = 1;
+  bool more_results = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`more_results` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
+
+`missing_statement` A boolean which denotes if the statement for the ResultSet still exists.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+## Miscellaneous
+
+### AvaticaParameter
+
+This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
+complex types such as arrays.
+
+{% highlight protobuf %}
+message AvaticaParameter {
+  bool signed = 1;
+  uint32 precision = 2;
+  uint32 scale = 3;
+  uint32 parameter_type = 4;
+  string class_name = 5;
+  string class_name = 6;
+  string name = 7;
+}
+{% endhighlight %}
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`parameter_type` An integer corresponding to the JDBC Types class denoting the column's type.
+
+`type_name` The JDBC type name for this column.
+
+`class_name` The Java class backing the JDBC type for this column.
+
+`name` The name of the column.
+
+### AvaticaSeverity
+
+This enumeration describes the various levels of concern for an error in the Avatica server.
+
+{% highlight protobuf %}
+enum Severity {
+  UNKNOWN_SEVERITY = 0;
+  FATAL_SEVERITY = 1;
+  ERROR_SEVERITY = 2;
+  WARNING_SEVERITY = 3;
+}
+{% endhighlight %}
+
+### AvaticaType
+
+This object describes a simple or complex type for a column. Complex types will contain
+additional information in the `component` or `columns` attribute which describe the nested
+types of the complex parent type.
+
+{% highlight protobuf %}
+message AvaticaType {
+  uint32 id = 1;
+  string name = 2;
+  Rep rep = 3;
+  repeated ColumnMetaData columns = 4;
+  AvaticaType component = 5;
+}
+{% endhighlight %}
+
+`type` One of: `scalar`, `array`, `struct`.
+
+`id` A numeric value corresponding to the type of the object per the JDBC Types class.
+
+`name` The readable name of the JDBC type.
+
+`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
+
+`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
+
+`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
+
+### ColumnMetaData
+
+This object represents the JDBC ResultSetMetaData for a column.
+
+{% highlight protobuf %}
+message ColumnMetaData {
+  uint32 ordinal = 1;
+  bool auto_increment = 2;
+  bool case_sensitive = 3;
+  bool searchable = 4;
+  bool currency = 5;
+  uint32 nullable = 6;
+  bool signed = 7;
+  uint32 display_size = 8;
+  string label = 9;
+  string column_name = 10;
+  string schema_name = 11;
+  uint32 precision = 12;
+  uint32 scale = 13;
+  string table_name = 14;
+  string catalog_name = 15;
+  bool read_only = 16;
+  bool writable = 17;
+  bool definitely_writable = 18;
+  string column_class_name = 19;
+  AvaticaType type = 20;
+}
+{% endhighlight %}
+
+`ordinal` A positional offset number.
+
+`auto_increment` A boolean denoting whether the column is automatically incremented.
+
+`case_sensitive` A boolean denoting whether the column is case sensitive.
+
+`searchable` A boolean denoting whether this column supports all WHERE search clauses.
+
+`currency` A boolean denoting whether this column represents currency.
+
+`nullable` A number denoting whether this column supports null values.
+
+* 0 = No null values are allowed
+* 1 = Null values are allowed
+* 2 = It is unknown if null values are allowed
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`display_size` The character width of the column.
+
+`label` A description for this column.
+
+`column_name` The name of the column.
+
+`schema_name` The schema to which this column belongs.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`table_name` The name of the table to which this column belongs.
+
+`catalog_name` The name of the catalog to which this column belongs.
+
+`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
+
+`read_only` A boolean denoting whether the column is read-only.
+
+`writable` A boolean denoting whether the column is possible to be updated.
+
+`definitely_writable` A boolean denoting whether the column definitely can be updated.
+
+`column_class_name` The name of the Java class backing the column's type.
+
+### ConnectionProperties
+
+This object represents the properties for a given JDBC Connection.
+
+{% highlight protobuf %}
+message ConnectionProperties {
+  bool is_dirty = 1;
+  bool auto_commit = 2;
+  bool has_auto_commit = 7;
+  bool read_only = 3;
+  bool has_read_only = 8;
+  uint32 transaction_isolation = 4;
+  string catalog = 5;
+  string schema = 6;
+}
+{% endhighlight %}
+
+`is_dirty` A boolean denoting if the properties have been altered.
+
+`auto_commit` A boolean denoting if autoCommit is enabled for transactions.
+
+`has_auto_commit` A boolean denoting if `auto_commit` was set.
+
+`read_only` A boolean denoting if a JDBC connection is read-only.
+
+`has_read_only` A boolean denoting if `read_only` was set.
+
+`transaction_isolation` An integer which denotes the level of transactions isolation per the JDBC
+specification. This value is analogous to the values defined in `java.sql.Connection`.
+
+* 0 = Transactions are not supported
+* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
+* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
+* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
+* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
+
+`catalog` The name of a catalog to use when fetching connection properties.
+
+`schema` The name of the schema to use when fetching connection properties.
+
+### CursorFactory
+
+This object represents the information required to cast untyped objects into the necessary type for some results.
+
+{% highlight protobuf %}
+message CursorFactory {
+  enum Style {
+    OBJECT = 0;
+    RECORD = 1;
+    RECORD_PROJECTION = 2;
+    ARRAY = 3;
+    LIST = 4;
+    MAP = 5;
+  }
+
+  Style style = 1;
+  string class_name = 2;
+  repeated string field_names = 3;
+}
+{% endhighlight %}
+
+`style` A string denoting the <a href="#style">Style</a> of the contained objects.
+
+`class_name` The name of the for `RECORD` or `RECORD_PROJECTION`.
+
+### DatabaseProperty
+
+This object represents the exposed database properties for a Connection through the Avatica server.
+
+{% highlight protobuf %}
+message DatabaseProperty {
+  string name = 1;
+  repeated string functions = 2;
+}
+{% endhighlight %}
+
+`name` The name of the database property.
+
+`functions` A collection of values for the property.
+
+### Frame
+
+This object represents a batch of results, tracking the offset into the results and whether more results still exist
+to be fetched in the Avatica server.
+
+{% highlight protobuf %}
+message Frame {
+  uint64 offset = 1;
+  bool done = 2;
+  repeated Row rows = 3;
+}
+{% endhighlight %}
+
+`offset` The starting position of these `rows` in the encompassing result set.
+
+`done` A boolean denoting whether more results exist for this result set.
+
+`rows` A collection of <a href="#row">Row</a>s.
+
+### Row
+
+This object represents a row in a relational database table.
+
+{% highlight protobuf %}
+message Row {
+  repeated ColumnValue value = 1;
+}
+{% endhighlight %}
+
+`value` A collection of <a href="#columnvalue">ColumnValue</a>s, the columns in the row.
+
+### ColumnValue
+
+{% highlight protobuf %}
+message ColumnValue {
+  repeated TypedValue value = 1; // Deprecated!
+  repeated ColumnValue array_value = 2;
+  boolean has_array_value = 3;
+  TypedValue scalar_value = 4;
+}
+{% endhighlight %}
+
+`value` The pre Calcite-1.6 means of serializing <a href="#typedvalue">TypedValue</a>s. Not used anymore.
+
+`array_value` The value of this column if it is an array (not a scalar).
+
+`has_array_value` Should be set to true if `array_value` is set.
+
+`scalar_value` The value of this column if it is a scalar (not an array).
+
+### QueryState
+
+This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
+SQL or by a DatabaseMetaData operation with arguments on that operation.
+
+{% highlight protobuf %}
+message QueryState {
+  StateType type = 1;
+  string sql = 2;
+  MetaDataOperation op = 3;
+  repeated MetaDataOperationArgument args = 4;
+  bool has_args = 5;
+  bool has_sql = 6;
+  bool has_op = 7;
+}
+{% endhighlight %}
+
+`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
+
+`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
+
+`op` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
+
+`args` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
+
+`has_args` A boolean which denotes if the field `args` is provided.
+
+`has_sql` A boolean which denotes if the field `sql` is provided.
+
+`has_op` A boolean which denotes if the field `op` is provided.
+
+### Rep
+
+This enumeration represents the concrete Java type for some value.
+
+{% highlight protobuf %}
+enum Rep {
+  PRIMITIVE_BOOLEAN = 0;
+  PRIMITIVE_BYTE = 1;
+  PRIMITIVE_CHAR = 2;
+  PRIMITIVE_SHORT = 3;
+  PRIMITIVE_INT = 4;
+  PRIMITIVE_LONG = 5;
+  PRIMITIVE_FLOAT = 6;
+  PRIMITIVE_DOUBLE = 7;
+  BOOLEAN = 8;
+  BYTE = 9;
+  CHARACTER = 10;
+  SHORT = 11;
+  INTEGER = 12;
+  LONG = 13;
+  FLOAT = 14;
+  DOUBLE = 15;
+  BIG_INTEGER = 25;
+  BIG_DECIMAL = 26;
+  JAVA_SQL_TIME = 16;
+  JAVA_SQL_TIMESTAMP = 17;
+  JAVA_SQL_DATE = 18;
+  JAVA_UTIL_DATE = 19;
+  BYTE_STRING = 20;
+  STRING = 21;
+  NUMBER = 22;
+  OBJECT = 23;
+  NULL = 24;
+  ARRAY = 27;
+  STRUCT = 28;
+  MULTISET = 29;
+}
+{% endhighlight %}
+
+### RpcMetadata
+
+This object contains assorted per-call/contextual metadata returned by the Avatica server.
+
+{% highlight protobuf %}
+message RpcMetadata {
+  string server_address = 1;
+}
+{% endhighlight %}
+
+`serverAddress` The `host:port` of the server which created this object.
+
+### Signature
+
+This object represents the result of preparing a Statement in the Avatica server.
+
+{% highlight protobuf %}
+message Signature {
+  repeated ColumnMetaData columns = 1;
+  string sql = 2;
+  repeated AvaticaParameter parameters = 3;
+  CursorFactory cursor_factory = 4;
+  StatementType statementType = 5;
+}
+{% endhighlight %}
+
+`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
+
+`sql` The SQL executed.
+
+`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
+
+`cursor_factory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
+
+`statementType` The type of the statement.
+
+### StateType
+
+This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
+
+{% highlight protobuf %}
+enum StateType {
+  SQL = 0;
+  METADATA = 1;
+}
+{% endhighlight %}
+
+### StatementHandle
+
+This object encapsulates all of the information of a Statement created in the Avatica server.
+
+{% highlight protobuf %}
+message StatementHandle {
+  string connection_id = 1;
+  uint32 id = 2;
+  Signature signature = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to which this statement belongs.
+
+`id` The identifier of the statement.
+
+`signature` A <a href="#signature">Signature</a> object for the statement.
+
+### StatementType
+
+This message represents what kind the Statement is.
+
+{% highlight protobuf %}
+enum StatementType {
+  SELECT = 0;
+  INSERT = 1;
+  UPDATE = 2;
+  DELETE = 3;
+  UPSERT = 4;
+  MERGE = 5;
+  OTHER_DML = 6;
+  CREATE = 7;
+  DROP = 8;
+  ALTER = 9;
+  OTHER_DDL = 10;
+  CALL = 11;
+}
+{% endhighlight %}
+
+### Style
+
+This enumeration represents the generic "class" of type for a value. Defined within <a href="#cursorfactory">CursorFactory</a>.
+
+{% highlight protobuf %}
+enum Style {
+  OBJECT = 0;
+  RECORD = 1;
+  RECORD_PROJECTION = 2;
+  ARRAY = 3;
+  LIST = 4;
+  MAP = 5;
+}
+{% endhighlight %}
+
+### TypedValue
+
+This object encapsulates the type and value for a column in a row.
+
+{% highlight protobuf %}
+message TypedValue {
+  Rep type = 1;
+  bool bool_value = 2;
+  string string_value = 3;
+  sint64 number_value = 4;
+  bytes bytes_values = 5;
+  double double_value = 6;
+  bool null = 7;
+}
+{% endhighlight %}
+
+`type` A name referring to which attribute is populated with the column's value.
+
+`bool_value` A boolean value.
+
+`string_value` A character/string value.
+
+`number_value` A numeric value (non-`double`).
+
+`bytes_value` A byte-array value.
+
+`double_value` A `double` value.
+
+`null` A boolean which denotes if the value was null.
+
+### WireMessage
+
+This message wraps all `Request`s and `Response`s.
+
+{% highlight protobuf %}
+message WireMessage {
+  string name = 1;
+  bytes wrapped_message = 2;
+}
+{% endhighlight %}
+
+`name` The Java class name of the wrapped message.
+
+`wrapped_message` A serialized representation of the wrapped message of the same type specified by `name`.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/avatica_roadmap.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/avatica_roadmap.md b/avatica/site/_docs/avatica_roadmap.md
new file mode 100644
index 0000000..4caebd4
--- /dev/null
+++ b/avatica/site/_docs/avatica_roadmap.md
@@ -0,0 +1,51 @@
+---
+layout: docs
+title: Avatica Roadmap
+sidebar_title: Roadmap
+permalink: /docs/avatica_roadmap.html
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+## Status
+
+### Implemented
+
+* Create connection, create statement, metadata, prepare, bind, execute, fetch
+* RPC using JSON over HTTP
+* Local implementation
+* Implementation over an existing JDBC driver
+* Composite RPCs (combining several requests into one round trip)
+  * Execute-Fetch
+  * Metadata-Fetch (metadata calls such as getTables return all rows)
+
+### Not implemented
+
+* ODBC
+* RPCs
+  * CloseStatement
+  * CloseConnection
+* Composite RPCs
+  * CreateStatement-Prepare
+  * CloseStatement-CloseConnection
+  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
+* Remove statements from statement table
+* DML (INSERT, UPDATE, DELETE)
+* Statement.execute applied to SELECT statement


[38/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
new file mode 100644
index 0000000..cd3d0cf
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
@@ -0,0 +1,11853 @@
+/*
+ * 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.
+ */
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: responses.proto
+
+package org.apache.calcite.avatica.proto;
+
+@SuppressWarnings({"unused", "rawtypes"}) public final class Responses {
+  private Responses() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface ResultSetResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:ResultSetResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+
+    /**
+     * <code>optional uint32 statement_id = 2;</code>
+     */
+    int getStatementId();
+
+    /**
+     * <code>optional bool own_statement = 3;</code>
+     */
+    boolean getOwnStatement();
+
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    boolean hasSignature();
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.Signature getSignature();
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder();
+
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    boolean hasFirstFrame();
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.Frame getFirstFrame();
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder();
+
+    /**
+     * <code>optional uint64 update_count = 6;</code>
+     *
+     * <pre>
+     * -1 for normal result sets, else this response contains a dummy result set
+     * </pre>
+     */
+    long getUpdateCount();
+
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    boolean hasMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
+  }
+  /**
+   * Protobuf type {@code ResultSetResponse}
+   *
+   * <pre>
+   * Response that contains a result set.
+   * </pre>
+   */
+  public  static final class ResultSetResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:ResultSetResponse)
+      ResultSetResponseOrBuilder {
+    // Use ResultSetResponse.newBuilder() to construct.
+    private ResultSetResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private ResultSetResponse() {
+      connectionId_ = "";
+      statementId_ = 0;
+      ownStatement_ = false;
+      updateCount_ = 0L;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private ResultSetResponse(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              break;
+            }
+            case 16: {
+
+              statementId_ = input.readUInt32();
+              break;
+            }
+            case 24: {
+
+              ownStatement_ = input.readBool();
+              break;
+            }
+            case 34: {
+              org.apache.calcite.avatica.proto.Common.Signature.Builder subBuilder = null;
+              if (signature_ != null) {
+                subBuilder = signature_.toBuilder();
+              }
+              signature_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Signature.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(signature_);
+                signature_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 42: {
+              org.apache.calcite.avatica.proto.Common.Frame.Builder subBuilder = null;
+              if (firstFrame_ != null) {
+                subBuilder = firstFrame_.toBuilder();
+              }
+              firstFrame_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Frame.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(firstFrame_);
+                firstFrame_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 48: {
+
+              updateCount_ = input.readUInt64();
+              break;
+            }
+            case 58: {
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
+              if (metadata_ != null) {
+                subBuilder = metadata_.toBuilder();
+              }
+              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(metadata_);
+                metadata_ = subBuilder.buildPartial();
+              }
+
+              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.Responses.internal_static_ResultSetResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Responses.ResultSetResponse.class, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder.class);
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int STATEMENT_ID_FIELD_NUMBER = 2;
+    private int statementId_;
+    /**
+     * <code>optional uint32 statement_id = 2;</code>
+     */
+    public int getStatementId() {
+      return statementId_;
+    }
+
+    public static final int OWN_STATEMENT_FIELD_NUMBER = 3;
+    private boolean ownStatement_;
+    /**
+     * <code>optional bool own_statement = 3;</code>
+     */
+    public boolean getOwnStatement() {
+      return ownStatement_;
+    }
+
+    public static final int SIGNATURE_FIELD_NUMBER = 4;
+    private org.apache.calcite.avatica.proto.Common.Signature signature_;
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    public boolean hasSignature() {
+      return signature_ != null;
+    }
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
+      return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+    }
+    /**
+     * <code>optional .Signature signature = 4;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
+      return getSignature();
+    }
+
+    public static final int FIRST_FRAME_FIELD_NUMBER = 5;
+    private org.apache.calcite.avatica.proto.Common.Frame firstFrame_;
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    public boolean hasFirstFrame() {
+      return firstFrame_ != null;
+    }
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.Frame getFirstFrame() {
+      return firstFrame_ == null ? org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
+    }
+    /**
+     * <code>optional .Frame first_frame = 5;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder() {
+      return getFirstFrame();
+    }
+
+    public static final int UPDATE_COUNT_FIELD_NUMBER = 6;
+    private long updateCount_;
+    /**
+     * <code>optional uint64 update_count = 6;</code>
+     *
+     * <pre>
+     * -1 for normal result sets, else this response contains a dummy result set
+     * </pre>
+     */
+    public long getUpdateCount() {
+      return updateCount_;
+    }
+
+    public static final int METADATA_FIELD_NUMBER = 7;
+    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    public boolean hasMetadata() {
+      return metadata_ != null;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 7;</code>
+     *
+     * <pre>
+     * with no signature nor other data.
+     * </pre>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+      return getMetadata();
+    }
+
+    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 {
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
+      }
+      if (statementId_ != 0) {
+        output.writeUInt32(2, statementId_);
+      }
+      if (ownStatement_ != false) {
+        output.writeBool(3, ownStatement_);
+      }
+      if (signature_ != null) {
+        output.writeMessage(4, getSignature());
+      }
+      if (firstFrame_ != null) {
+        output.writeMessage(5, getFirstFrame());
+      }
+      if (updateCount_ != 0L) {
+        output.writeUInt64(6, updateCount_);
+      }
+      if (metadata_ != null) {
+        output.writeMessage(7, getMetadata());
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
+      }
+      if (statementId_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(2, statementId_);
+      }
+      if (ownStatement_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(3, ownStatement_);
+      }
+      if (signature_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, getSignature());
+      }
+      if (firstFrame_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getFirstFrame());
+      }
+      if (updateCount_ != 0L) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt64Size(6, updateCount_);
+      }
+      if (metadata_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(7, getMetadata());
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse 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 ResultSetResponse}
+     *
+     * <pre>
+     * Response that contains a result set.
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:ResultSetResponse)
+        org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Responses.ResultSetResponse.class, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Responses.ResultSetResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        connectionId_ = "";
+
+        statementId_ = 0;
+
+        ownStatement_ = false;
+
+        if (signatureBuilder_ == null) {
+          signature_ = null;
+        } else {
+          signature_ = null;
+          signatureBuilder_ = null;
+        }
+        if (firstFrameBuilder_ == null) {
+          firstFrame_ = null;
+        } else {
+          firstFrame_ = null;
+          firstFrameBuilder_ = null;
+        }
+        updateCount_ = 0L;
+
+        if (metadataBuilder_ == null) {
+          metadata_ = null;
+        } else {
+          metadata_ = null;
+          metadataBuilder_ = null;
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse build() {
+        org.apache.calcite.avatica.proto.Responses.ResultSetResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse buildPartial() {
+        org.apache.calcite.avatica.proto.Responses.ResultSetResponse result = new org.apache.calcite.avatica.proto.Responses.ResultSetResponse(this);
+        result.connectionId_ = connectionId_;
+        result.statementId_ = statementId_;
+        result.ownStatement_ = ownStatement_;
+        if (signatureBuilder_ == null) {
+          result.signature_ = signature_;
+        } else {
+          result.signature_ = signatureBuilder_.build();
+        }
+        if (firstFrameBuilder_ == null) {
+          result.firstFrame_ = firstFrame_;
+        } else {
+          result.firstFrame_ = firstFrameBuilder_.build();
+        }
+        result.updateCount_ = updateCount_;
+        if (metadataBuilder_ == null) {
+          result.metadata_ = metadata_;
+        } else {
+          result.metadata_ = metadataBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Responses.ResultSetResponse) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Responses.ResultSetResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Responses.ResultSetResponse other) {
+        if (other == org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance()) return this;
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        if (other.getStatementId() != 0) {
+          setStatementId(other.getStatementId());
+        }
+        if (other.getOwnStatement() != false) {
+          setOwnStatement(other.getOwnStatement());
+        }
+        if (other.hasSignature()) {
+          mergeSignature(other.getSignature());
+        }
+        if (other.hasFirstFrame()) {
+          mergeFirstFrame(other.getFirstFrame());
+        }
+        if (other.getUpdateCount() != 0L) {
+          setUpdateCount(other.getUpdateCount());
+        }
+        if (other.hasMetadata()) {
+          mergeMetadata(other.getMetadata());
+        }
+        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.Responses.ResultSetResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Responses.ResultSetResponse) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object connectionId_ = "";
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public java.lang.String getConnectionId() {
+        java.lang.Object ref = connectionId_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          connectionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getConnectionIdBytes() {
+        java.lang.Object ref = connectionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          connectionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder clearConnectionId() {
+        
+        connectionId_ = getDefaultInstance().getConnectionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+
+      private int statementId_ ;
+      /**
+       * <code>optional uint32 statement_id = 2;</code>
+       */
+      public int getStatementId() {
+        return statementId_;
+      }
+      /**
+       * <code>optional uint32 statement_id = 2;</code>
+       */
+      public Builder setStatementId(int value) {
+        
+        statementId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional uint32 statement_id = 2;</code>
+       */
+      public Builder clearStatementId() {
+        
+        statementId_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private boolean ownStatement_ ;
+      /**
+       * <code>optional bool own_statement = 3;</code>
+       */
+      public boolean getOwnStatement() {
+        return ownStatement_;
+      }
+      /**
+       * <code>optional bool own_statement = 3;</code>
+       */
+      public Builder setOwnStatement(boolean value) {
+        
+        ownStatement_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool own_statement = 3;</code>
+       */
+      public Builder clearOwnStatement() {
+        
+        ownStatement_ = false;
+        onChanged();
+        return this;
+      }
+
+      private org.apache.calcite.avatica.proto.Common.Signature signature_ = null;
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> signatureBuilder_;
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public boolean hasSignature() {
+        return signatureBuilder_ != null || signature_ != null;
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
+        if (signatureBuilder_ == null) {
+          return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+        } else {
+          return signatureBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public Builder setSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
+        if (signatureBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          signature_ = value;
+          onChanged();
+        } else {
+          signatureBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public Builder setSignature(
+          org.apache.calcite.avatica.proto.Common.Signature.Builder builderForValue) {
+        if (signatureBuilder_ == null) {
+          signature_ = builderForValue.build();
+          onChanged();
+        } else {
+          signatureBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public Builder mergeSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
+        if (signatureBuilder_ == null) {
+          if (signature_ != null) {
+            signature_ =
+              org.apache.calcite.avatica.proto.Common.Signature.newBuilder(signature_).mergeFrom(value).buildPartial();
+          } else {
+            signature_ = value;
+          }
+          onChanged();
+        } else {
+          signatureBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public Builder clearSignature() {
+        if (signatureBuilder_ == null) {
+          signature_ = null;
+          onChanged();
+        } else {
+          signature_ = null;
+          signatureBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Signature.Builder getSignatureBuilder() {
+        
+        onChanged();
+        return getSignatureFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
+        if (signatureBuilder_ != null) {
+          return signatureBuilder_.getMessageOrBuilder();
+        } else {
+          return signature_ == null ?
+              org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+        }
+      }
+      /**
+       * <code>optional .Signature signature = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> 
+          getSignatureFieldBuilder() {
+        if (signatureBuilder_ == null) {
+          signatureBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder>(
+                  getSignature(),
+                  getParentForChildren(),
+                  isClean());
+          signature_ = null;
+        }
+        return signatureBuilder_;
+      }
+
+      private org.apache.calcite.avatica.proto.Common.Frame firstFrame_ = null;
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder> firstFrameBuilder_;
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public boolean hasFirstFrame() {
+        return firstFrameBuilder_ != null || firstFrame_ != null;
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Frame getFirstFrame() {
+        if (firstFrameBuilder_ == null) {
+          return firstFrame_ == null ? org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
+        } else {
+          return firstFrameBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public Builder setFirstFrame(org.apache.calcite.avatica.proto.Common.Frame value) {
+        if (firstFrameBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          firstFrame_ = value;
+          onChanged();
+        } else {
+          firstFrameBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public Builder setFirstFrame(
+          org.apache.calcite.avatica.proto.Common.Frame.Builder builderForValue) {
+        if (firstFrameBuilder_ == null) {
+          firstFrame_ = builderForValue.build();
+          onChanged();
+        } else {
+          firstFrameBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public Builder mergeFirstFrame(org.apache.calcite.avatica.proto.Common.Frame value) {
+        if (firstFrameBuilder_ == null) {
+          if (firstFrame_ != null) {
+            firstFrame_ =
+              org.apache.calcite.avatica.proto.Common.Frame.newBuilder(firstFrame_).mergeFrom(value).buildPartial();
+          } else {
+            firstFrame_ = value;
+          }
+          onChanged();
+        } else {
+          firstFrameBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public Builder clearFirstFrame() {
+        if (firstFrameBuilder_ == null) {
+          firstFrame_ = null;
+          onChanged();
+        } else {
+          firstFrame_ = null;
+          firstFrameBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Frame.Builder getFirstFrameBuilder() {
+        
+        onChanged();
+        return getFirstFrameFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder() {
+        if (firstFrameBuilder_ != null) {
+          return firstFrameBuilder_.getMessageOrBuilder();
+        } else {
+          return firstFrame_ == null ?
+              org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
+        }
+      }
+      /**
+       * <code>optional .Frame first_frame = 5;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder> 
+          getFirstFrameFieldBuilder() {
+        if (firstFrameBuilder_ == null) {
+          firstFrameBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder>(
+                  getFirstFrame(),
+                  getParentForChildren(),
+                  isClean());
+          firstFrame_ = null;
+        }
+        return firstFrameBuilder_;
+      }
+
+      private long updateCount_ ;
+      /**
+       * <code>optional uint64 update_count = 6;</code>
+       *
+       * <pre>
+       * -1 for normal result sets, else this response contains a dummy result set
+       * </pre>
+       */
+      public long getUpdateCount() {
+        return updateCount_;
+      }
+      /**
+       * <code>optional uint64 update_count = 6;</code>
+       *
+       * <pre>
+       * -1 for normal result sets, else this response contains a dummy result set
+       * </pre>
+       */
+      public Builder setUpdateCount(long value) {
+        
+        updateCount_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional uint64 update_count = 6;</code>
+       *
+       * <pre>
+       * -1 for normal result sets, else this response contains a dummy result set
+       * </pre>
+       */
+      public Builder clearUpdateCount() {
+        
+        updateCount_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_ = null;
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> metadataBuilder_;
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public boolean hasMetadata() {
+        return metadataBuilder_ != null || metadata_ != null;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+        if (metadataBuilder_ == null) {
+          return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+        } else {
+          return metadataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public Builder setMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+        if (metadataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          metadata_ = value;
+          onChanged();
+        } else {
+          metadataBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public Builder setMetadata(
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder builderForValue) {
+        if (metadataBuilder_ == null) {
+          metadata_ = builderForValue.build();
+          onChanged();
+        } else {
+          metadataBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public Builder mergeMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+        if (metadataBuilder_ == null) {
+          if (metadata_ != null) {
+            metadata_ =
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.newBuilder(metadata_).mergeFrom(value).buildPartial();
+          } else {
+            metadata_ = value;
+          }
+          onChanged();
+        } else {
+          metadataBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public Builder clearMetadata() {
+        if (metadataBuilder_ == null) {
+          metadata_ = null;
+          onChanged();
+        } else {
+          metadata_ = null;
+          metadataBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder getMetadataBuilder() {
+        
+        onChanged();
+        return getMetadataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+        if (metadataBuilder_ != null) {
+          return metadataBuilder_.getMessageOrBuilder();
+        } else {
+          return metadata_ == null ?
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+        }
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 7;</code>
+       *
+       * <pre>
+       * with no signature nor other data.
+       * </pre>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> 
+          getMetadataFieldBuilder() {
+        if (metadataBuilder_ == null) {
+          metadataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>(
+                  getMetadata(),
+                  getParentForChildren(),
+                  isClean());
+          metadata_ = null;
+        }
+        return metadataBuilder_;
+      }
+      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:ResultSetResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:ResultSetResponse)
+    private static final org.apache.calcite.avatica.proto.Responses.ResultSetResponse DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Responses.ResultSetResponse();
+    }
+
+    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<ResultSetResponse>
+        PARSER = new com.google.protobuf.AbstractParser<ResultSetResponse>() {
+      public ResultSetResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new ResultSetResponse(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<ResultSetResponse> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ResultSetResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface ExecuteResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:ExecuteResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> 
+        getResultsList();
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index);
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    int getResultsCount();
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
+        getResultsOrBuilderList();
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
+        int index);
+
+    /**
+     * <code>optional bool missing_statement = 2;</code>
+     *
+     * <pre>
+     * Did the request fail because of no-cached statement
+     * </pre>
+     */
+    boolean getMissingStatement();
+
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    boolean hasMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
+  }
+  /**
+   * Protobuf type {@code ExecuteResponse}
+   *
+   * <pre>
+   * Response to PrepareAndExecuteRequest
+   * </pre>
+   */
+  public  static final class ExecuteResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:ExecuteResponse)
+      ExecuteResponseOrBuilder {
+    // Use ExecuteResponse.newBuilder() to construct.
+    private ExecuteResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private ExecuteResponse() {
+      results_ = java.util.Collections.emptyList();
+      missingStatement_ = false;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private ExecuteResponse(
+        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 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                results_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Responses.ResultSetResponse>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              results_.add(input.readMessage(org.apache.calcite.avatica.proto.Responses.ResultSetResponse.parser(), extensionRegistry));
+              break;
+            }
+            case 16: {
+
+              missingStatement_ = input.readBool();
+              break;
+            }
+            case 26: {
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
+              if (metadata_ != null) {
+                subBuilder = metadata_.toBuilder();
+              }
+              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(metadata_);
+                metadata_ = subBuilder.buildPartial();
+              }
+
+              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 {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          results_ = java.util.Collections.unmodifiableList(results_);
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Responses.ExecuteResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteResponse.Builder.class);
+    }
+
+    private int bitField0_;
+    public static final int RESULTS_FIELD_NUMBER = 1;
+    private java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> results_;
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> getResultsList() {
+      return results_;
+    }
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    public java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
+        getResultsOrBuilderList() {
+      return results_;
+    }
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    public int getResultsCount() {
+      return results_.size();
+    }
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index) {
+      return results_.get(index);
+    }
+    /**
+     * <code>repeated .ResultSetResponse results = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
+        int index) {
+      return results_.get(index);
+    }
+
+    public static final int MISSING_STATEMENT_FIELD_NUMBER = 2;
+    private boolean missingStatement_;
+    /**
+     * <code>optional bool missing_statement = 2;</code>
+     *
+     * <pre>
+     * Did the request fail because of no-cached statement
+     * </pre>
+     */
+    public boolean getMissingStatement() {
+      return missingStatement_;
+    }
+
+    public static final int METADATA_FIELD_NUMBER = 3;
+    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    public boolean hasMetadata() {
+      return metadata_ != null;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 3;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+      return getMetadata();
+    }
+
+    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 < results_.size(); i++) {
+        output.writeMessage(1, results_.get(i));
+      }
+      if (missingStatement_ != false) {
+        output.writeBool(2, missingStatement_);
+      }
+      if (metadata_ != null) {
+        output.writeMessage(3, getMetadata());
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < results_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, results_.get(i));
+      }
+      if (missingStatement_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(2, missingStatement_);
+      }
+      if (metadata_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getMetadata());
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse 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 ExecuteResponse}
+     *
+     * <pre>
+     * Response to PrepareAndExecuteRequest
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:ExecuteResponse)
+        org.apache.calcite.avatica.proto.Responses.ExecuteResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Responses.ExecuteResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteResponse.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Responses.ExecuteResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getResultsFieldBuilder();
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        if (resultsBuilder_ == null) {
+          results_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          resultsBuilder_.clear();
+        }
+        missingStatement_ = false;
+
+        if (metadataBuilder_ == null) {
+          metadata_ = null;
+        } else {
+          metadata_ = null;
+          metadataBuilder_ = null;
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Responses.ExecuteResponse.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse build() {
+        org.apache.calcite.avatica.proto.Responses.ExecuteResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse buildPartial() {
+        org.apache.calcite.avatica.proto.Responses.ExecuteResponse result = new org.apache.calcite.avatica.proto.Responses.ExecuteResponse(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (resultsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            results_ = java.util.Collections.unmodifiableList(results_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.results_ = results_;
+        } else {
+          result.results_ = resultsBuilder_.build();
+        }
+        result.missingStatement_ = missingStatement_;
+        if (metadataBuilder_ == null) {
+          result.metadata_ = metadata_;
+        } else {
+          result.metadata_ = metadataBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Responses.ExecuteResponse) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Responses.ExecuteResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Responses.ExecuteResponse other) {
+        if (other == org.apache.calcite.avatica.proto.Responses.ExecuteResponse.getDefaultInstance()) return this;
+        if (resultsBuilder_ == null) {
+          if (!other.results_.isEmpty()) {
+            if (results_.isEmpty()) {
+              results_ = other.results_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureResultsIsMutable();
+              results_.addAll(other.results_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.results_.isEmpty()) {
+            if (resultsBuilder_.isEmpty()) {
+              resultsBuilder_.dispose();
+              resultsBuilder_ = null;
+              results_ = other.results_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              resultsBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getResultsFieldBuilder() : null;
+            } else {
+              resultsBuilder_.addAllMessages(other.results_);
+            }
+          }
+        }
+        if (other.getMissingStatement() != false) {
+          setMissingStatement(other.getMissingStatement());
+        }
+        if (other.hasMetadata()) {
+          mergeMetadata(other.getMetadata());
+        }
+        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.Responses.ExecuteResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Responses.ExecuteResponse) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> results_ =
+        java.util.Collections.emptyList();
+      private void ensureResultsIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          results_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Responses.ResultSetResponse>(results_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> resultsBuilder_;
+
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> getResultsList() {
+        if (resultsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(results_);
+        } else {
+          return resultsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public int getResultsCount() {
+        if (resultsBuilder_ == null) {
+          return results_.size();
+        } else {
+          return resultsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index) {
+        if (resultsBuilder_ == null) {
+          return results_.get(index);
+        } else {
+          return resultsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder setResults(
+          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
+        if (resultsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureResultsIsMutable();
+          results_.set(index, value);
+          onChanged();
+        } else {
+          resultsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder setResults(
+          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
+        if (resultsBuilder_ == null) {
+          ensureResultsIsMutable();
+          results_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          resultsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder addResults(org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
+        if (resultsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureResultsIsMutable();
+          results_.add(value);
+          onChanged();
+        } else {
+          resultsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder addResults(
+          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
+        if (resultsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureResultsIsMutable();
+          results_.add(index, value);
+          onChanged();
+        } else {
+          resultsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder addResults(
+          org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
+        if (resultsBuilder_ == null) {
+          ensureResultsIsMutable();
+          results_.add(builderForValue.build());
+          onChanged();
+        } else {
+          resultsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder addResults(
+          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
+        if (resultsBuilder_ == null) {
+          ensureResultsIsMutable();
+          results_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          resultsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder addAllResults(
+          java.lang.Iterable<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponse> values) {
+        if (resultsBuilder_ == null) {
+          ensureResultsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, results_);
+          onChanged();
+        } else {
+          resultsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder clearResults() {
+        if (resultsBuilder_ == null) {
+          results_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          resultsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public Builder removeResults(int index) {
+        if (resultsBuilder_ == null) {
+          ensureResultsIsMutable();
+          results_.remove(index);
+          onChanged();
+        } else {
+          resultsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder getResultsBuilder(
+          int index) {
+        return getResultsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
+          int index) {
+        if (resultsBuilder_ == null) {
+          return results_.get(index);  } else {
+          return resultsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
+           getResultsOrBuilderList() {
+        if (resultsBuilder_ != null) {
+          return resultsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(results_);
+        }
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder addResultsBuilder() {
+        return getResultsFieldBuilder().addBuilder(
+            org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder addResultsBuilder(
+          int index) {
+        return getResultsFieldBuilder().addBuilder(
+            index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .ResultSetResponse results = 1;</code>
+       */
+      public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder> 
+           getResultsBuilderList() {
+        return getResultsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
+          getResultsFieldBuilder() {
+        if (resultsBuilder_ == null) {
+          resultsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder>(
+                  results_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          results_ = null;
+        }
+        return resultsBuilder_;
+      }
+
+      private boolean missingStatement_ ;
+      /**
+       * <code>optional bool missing_statement = 2;</code>
+       *
+       * <pre>
+       * Did the request fail because of no-cached statement
+       * </pre>
+       */
+      public boolean getMissingStatement() {
+        return missingStatement_;
+      }
+      /**
+       * <code>optional bool missing_statement = 2;</code>
+       *
+       * <pre>
+       * Did the request fail because of no-cached statement
+       * </pre>
+       */
+      public Builder setMissingStatement(boolean value) {
+        
+        missingStatement_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool missing_statement = 2;</code>
+       *
+       * <pre>
+       * Did the request fail because of no-cached statement
+       * </pre>
+       */
+      public Builder clearMissingStatement() {
+        
+        missingStatement_ = false;
+        onChanged();
+        return this;
+      }
+
+      private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_ = null;
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> metadataBuilder_;
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public boolean hasMetadata() {
+        return metadataBuilder_ != null || metadata_ != null;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+        if (metadataBuilder_ == null) {
+          return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+        } else {
+          return metadataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public Builder setMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+        if (metadataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          metadata_ = value;
+          onChanged();
+        } else {
+          metadataBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public Builder setMetadata(
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder builderForValue) {
+        if (metadataBuilder_ == null) {
+          metadata_ = builderForValue.build();
+          onChanged();
+        } else {
+          metadataBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public Builder mergeMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+        if (metadataBuilder_ == null) {
+          if (metadata_ != null) {
+            metadata_ =
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.newBuilder(metadata_).mergeFrom(value).buildPartial();
+          } else {
+            metadata_ = value;
+          }
+          onChanged();
+        } else {
+          metadataBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public Builder clearMetadata() {
+        if (metadataBuilder_ == null) {
+          metadata_ = null;
+          onChanged();
+        } else {
+          metadata_ = null;
+          metadataBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder getMetadataBuilder() {
+        
+        onChanged();
+        return getMetadataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+        if (metadataBuilder_ != null) {
+          return metadataBuilder_.getMessageOrBuilder();
+        } else {
+          return metadata_ == null ?
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+        }
+      }
+      /**
+       * <code>optional .RpcMetadata metadata = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> 
+          getMetadataFieldBuilder() {
+        if (metadataBuilder_ == null) {
+          metadataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>(
+                  getMetadata(),
+                  getParentForChildren(),
+                  isClean());
+          metadata_ = null;
+        }
+        return metadataBuilder_;
+      }
+      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:ExecuteResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:ExecuteResponse)
+    private static final org.apache.calcite.avatica.proto.Responses.ExecuteResponse DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Responses.ExecuteResponse();
+    }
+
+    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<ExecuteResponse>
+        PARSER = new com.google.protobuf.AbstractParser<ExecuteResponse>() {
+      public ExecuteResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new ExecuteResponse(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<ExecuteResponse> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ExecuteResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface PrepareResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:PrepareResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    boolean hasStatement();
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.StatementHandle getStatement();
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder getStatementOrBuilder();
+
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    boolean hasMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
+  }
+  /**
+   * Protobuf type {@code PrepareResponse}
+   *
+   * <pre>
+   * Response to PrepareRequest
+   * </pre>
+   */
+  public  static final class PrepareResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:PrepareResponse)
+      PrepareResponseOrBuilder {
+    // Use PrepareResponse.newBuilder() to construct.
+    private PrepareResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private PrepareResponse() {
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private PrepareResponse(
+        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 10: {
+              org.apache.calcite.avatica.proto.Common.StatementHandle.Builder subBuilder = null;
+              if (statement_ != null) {
+                subBuilder = statement_.toBuilder();
+              }
+              statement_ = input.readMessage(org.apache.calcite.avatica.proto.Common.StatementHandle.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(statement_);
+                statement_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
+              if (metadata_ != null) {
+                subBuilder = metadata_.toBuilder();
+              }
+              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(metadata_);
+                metadata_ = subBuilder.buildPartial();
+              }
+
+              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.Responses.internal_static_PrepareResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Responses.internal_static_PrepareResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Responses.PrepareResponse.class, org.apache.calcite.avatica.proto.Responses.PrepareResponse.Builder.class);
+    }
+
+    public static final int STATEMENT_FIELD_NUMBER = 1;
+    private org.apache.calcite.avatica.proto.Common.StatementHandle statement_;
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    public boolean hasStatement() {
+      return statement_ != null;
+    }
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.StatementHandle getStatement() {
+      return statement_ == null ? org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance() : statement_;
+    }
+    /**
+     * <code>optional .StatementHandle statement = 1;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder getStatementOrBuilder() {
+      return getStatement();
+    }
+
+    public static final int METADATA_FIELD_NUMBER = 2;
+    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    public boolean hasMetadata() {
+      return metadata_ != null;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+    }
+    /**
+     * <code>optional .RpcMetadata metadata = 2;</code>
+     */
+    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+      return getMetadata();
+    }
+
+    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 {
+      if (statement_ != null) {
+        output.writeMessage(1, getStatement());
+      }
+      if (metadata_ != null) {
+        output.writeMessage(2, getMetadata());
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (statement_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getStatement());
+      }
+      if (metadata_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getMetadata());
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Responses.PrepareResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.PrepareResponse 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.Responses.

<TRUNCATED>

[32/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/ByteString.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/ByteString.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ByteString.java
new file mode 100644
index 0000000..4e606b7
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ByteString.java
@@ -0,0 +1,347 @@
+/*
+ * 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.util;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+
+/**
+ * Collection of bytes.
+ *
+ * <p>ByteString is to bytes what {@link String} is to chars: It is immutable,
+ * implements equality ({@link #hashCode} and {@link #equals}),
+ * comparison ({@link #compareTo}) and
+ * {@link Serializable serialization} correctly.</p>
+ */
+public class ByteString implements Comparable<ByteString>, Serializable {
+  private final byte[] bytes;
+
+  /** An empty byte string. */
+  public static final ByteString EMPTY = new ByteString(new byte[0], false);
+
+  private static final char[] DIGITS = {
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+  };
+
+  /**
+   * Creates a ByteString.
+   *
+   * @param bytes Bytes
+   */
+  public ByteString(byte[] bytes) {
+    this(bytes.clone(), false);
+  }
+
+  // private constructor that does not copy
+  private ByteString(byte[] bytes, boolean dummy) {
+    this.bytes = bytes;
+  }
+
+  @Override public int hashCode() {
+    return Arrays.hashCode(bytes);
+  }
+
+  @Override public boolean equals(Object obj) {
+    return this == obj
+        || obj instanceof ByteString
+        && Arrays.equals(bytes, ((ByteString) obj).bytes);
+  }
+
+  public int compareTo(ByteString that) {
+    final byte[] v1 = bytes;
+    final byte[] v2 = that.bytes;
+    final int n = Math.min(v1.length, v2.length);
+    for (int i = 0; i < n; i++) {
+      int c1 = v1[i] & 0xff;
+      int c2 = v2[i] & 0xff;
+      if (c1 != c2) {
+        return c1 - c2;
+      }
+    }
+    return v1.length - v2.length;
+  }
+
+  /**
+   * Returns this byte string in hexadecimal format.
+   *
+   * @return Hexadecimal string
+   */
+  @Override public String toString() {
+    return toString(16);
+  }
+
+  /**
+   * Returns this byte string in a given base.
+   *
+   * @return String in given base
+   */
+  public String toString(int base) {
+    return toString(bytes, base);
+  }
+
+  /**
+   * Returns the given byte array in hexadecimal format.
+   *
+   * <p>For example, <tt>toString(new byte[] {0xDE, 0xAD})</tt>
+   * returns {@code "DEAD"}.</p>
+   *
+   * @param bytes Array of bytes
+   * @param base Base (2 or 16)
+   * @return String
+   */
+  public static String toString(byte[] bytes, int base) {
+    char[] chars;
+    int j = 0;
+    switch (base) {
+    case 2:
+      chars = new char[bytes.length * 8];
+      for (byte b : bytes) {
+        chars[j++] = DIGITS[(b & 0x80) >> 7];
+        chars[j++] = DIGITS[(b & 0x40) >> 6];
+        chars[j++] = DIGITS[(b & 0x20) >> 5];
+        chars[j++] = DIGITS[(b & 0x10) >> 4];
+        chars[j++] = DIGITS[(b & 0x08) >> 3];
+        chars[j++] = DIGITS[(b & 0x04) >> 2];
+        chars[j++] = DIGITS[(b & 0x02) >> 1];
+        chars[j++] = DIGITS[b & 0x01];
+      }
+      break;
+    case 16:
+      chars = new char[bytes.length * 2];
+      for (byte b : bytes) {
+        chars[j++] = DIGITS[(b & 0xF0) >> 4];
+        chars[j++] = DIGITS[b & 0x0F];
+      }
+      break;
+    default:
+      throw new IllegalArgumentException("bad base " + base);
+    }
+    return new String(chars, 0, j);
+  }
+
+  /**
+   * Returns this byte string in Base64 format.
+   *
+   * @return Base64 string
+   */
+  public String toBase64String() {
+    return Base64.encodeBytes(bytes);
+  }
+
+  /**
+   * Creates a byte string from a hexadecimal or binary string.
+   *
+   * <p>For example, <tt>of("DEAD", 16)</tt>
+   * returns the same as {@code ByteString(new byte[] {0xDE, 0xAD})}.
+   *
+   * @param string Array of bytes
+   * @param base Base (2 or 16)
+   * @return String
+   */
+  public static ByteString of(String string, int base) {
+    final byte[] bytes = parse(string, base);
+    return new ByteString(bytes, false);
+  }
+
+  /**
+   * Parses a hexadecimal or binary string to a byte array.
+   *
+   * @param string Hexadecimal or binary string
+   * @param base Base (2 or 16)
+   * @return Byte array
+   */
+  public static byte[] parse(String string, int base) {
+    char[] chars = string.toCharArray();
+    byte[] bytes;
+    int j = 0;
+    byte b = 0;
+    switch (base) {
+    case 2:
+      bytes = new byte[chars.length / 8];
+      for (char c : chars) {
+        b <<= 1;
+        if (c == '1') {
+          b |= 0x1;
+        }
+        if (j % 8 == 7) {
+          bytes[j / 8] = b;
+          b = 0;
+        }
+        ++j;
+      }
+      break;
+    case 16:
+      if (chars.length % 2 != 0) {
+        throw new IllegalArgumentException("hex string has odd length");
+      }
+      bytes = new byte[chars.length / 2];
+      for (char c : chars) {
+        b <<= 4;
+        byte i = decodeHex(c);
+        b |= i & 0x0F;
+        if (j % 2 == 1) {
+          bytes[j / 2] = b;
+          b = 0;
+        }
+        ++j;
+      }
+      break;
+    default:
+      throw new IllegalArgumentException("bad base " + base);
+    }
+    return bytes;
+  }
+
+  private static byte decodeHex(char c) {
+    if (c >= '0' && c <= '9') {
+      return (byte) (c - '0');
+    }
+    if (c >= 'a' && c <= 'f') {
+      return (byte) (c - 'a' + 10);
+    }
+    if (c >= 'A' && c <= 'F') {
+      return (byte) (c - 'A' + 10);
+    }
+    throw new IllegalArgumentException("invalid hex character: " + c);
+  }
+
+  /**
+   * Creates a byte string from a Base64 string.
+   *
+   * @param string Base64 string
+   * @return Byte string
+   */
+  public static ByteString ofBase64(String string) {
+    final byte[] bytes = parseBase64(string);
+    return new ByteString(bytes, false);
+  }
+
+  /**
+   * Parses a Base64 to a byte array.
+   *
+   * @param string Base64 string
+   * @return Byte array
+   */
+  public static byte[] parseBase64(String string) {
+    try {
+      return Base64.decode(string);
+    } catch (IOException e) {
+      throw new IllegalArgumentException("bad base64 string", e);
+    }
+  }
+
+  @SuppressWarnings({
+      "CloneDoesntCallSuperClone",
+      "CloneDoesntDeclareCloneNotSupportedException"
+  })
+  @Override public Object clone() {
+    return this;
+  }
+
+  /**
+   * Returns the number of bytes in this byte string.
+   *
+   * @return Length of this byte string
+   */
+  public int length() {
+    return bytes.length;
+  }
+
+  /**
+   * Returns the byte at a given position in the byte string.
+   *
+   * @param i Index
+   * @throws  IndexOutOfBoundsException
+   *          if the <tt>index</tt> argument is negative or not less than
+   *          <tt>length()</tt>
+   * @return Byte at given position
+   */
+  public byte byteAt(int i) {
+    return bytes[i];
+  }
+
+  /**
+   * Returns a ByteString that consists of a given range.
+   *
+   * @param start Start of range
+   * @param end Position after end of range
+   * @return Substring
+   */
+  public ByteString substring(int start, int end) {
+    byte[] bytes = Arrays.copyOfRange(this.bytes, start, end);
+    return new ByteString(bytes, false);
+  }
+
+  /**
+   * Returns a ByteString that starts at a given position.
+   *
+   * @param start Start of range
+   * @return Substring
+   */
+  public ByteString substring(int start) {
+    return substring(start, length());
+  }
+
+  /**
+   * Returns a copy of the byte array.
+   */
+  @JsonValue
+  public byte[] getBytes() {
+    return bytes.clone();
+  }
+
+  /**
+   * Returns a ByteString consisting of the concatenation of this and another
+   * string.
+   *
+   * @param other Byte string to concatenate
+   * @return Combined byte string
+   */
+  public ByteString concat(ByteString other) {
+    int otherLen = other.length();
+    if (otherLen == 0) {
+      return this;
+    }
+    int len = bytes.length;
+    byte[] buf = Arrays.copyOf(bytes, len + otherLen);
+    System.arraycopy(other.bytes, 0, buf, len, other.bytes.length);
+    return new ByteString(buf, false);
+  }
+
+  /** Returns the position at which {@code seek} first occurs in this byte
+   * string, or -1 if it does not occur. */
+  public int indexOf(ByteString seek) {
+  iLoop:
+    for (int i = 0; i < bytes.length - seek.bytes.length + 1; i++) {
+      for (int j = 0;; j++) {
+        if (j == seek.bytes.length) {
+          return i;
+        }
+        if (bytes[i + j] != seek.bytes[j]) {
+          continue iLoop;
+        }
+      }
+    }
+    return -1;
+  }
+}
+
+// End ByteString.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Casing.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Casing.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Casing.java
new file mode 100644
index 0000000..5f13214
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Casing.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+/** Policy for converting case of identifiers before storing them.
+ *
+ * <p>A database often has policies for quoted versus unquoted identifiers.
+ * For example, Oracle converts unquoted identifiers to upper-case, but
+ * quoted identifiers are unchanged.</p> */
+public enum Casing {
+  /** The case of identifiers is not changed. */
+  UNCHANGED,
+
+  /** Identifiers are converted to upper-case. */
+  TO_UPPER,
+
+  /** Identifiers are converted to lower-case. */
+  TO_LOWER
+}
+
+// End Casing.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
new file mode 100644
index 0000000..8eab72f
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
@@ -0,0 +1,145 @@
+/*
+ * 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.util;
+
+import org.apache.calcite.avatica.ColumnMetaData;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface to an iteration that is similar to, and can easily support,
+ * a JDBC {@link java.sql.ResultSet}, but is simpler to implement.
+ */
+public interface Cursor extends AutoCloseable {
+  /**
+   * Creates a list of accessors, one per column.
+   *
+   *
+   * @param types List of column types, per {@link java.sql.Types}.
+   * @param localCalendar Calendar in local time zone
+   * @param factory Factory that creates sub-ResultSets when needed
+   * @return List of column accessors
+   */
+  List<Accessor> createAccessors(List<ColumnMetaData> types,
+      Calendar localCalendar, ArrayImpl.Factory factory);
+
+  /**
+   * Moves to the next row.
+   *
+   * @return Whether moved
+   *
+   * @throws SQLException on database error
+   */
+  boolean next() throws SQLException;
+
+  /**
+   * Closes this cursor and releases resources.
+   */
+  void close();
+
+  /**
+   * Returns whether the last value returned was null.
+   *
+   * @throws SQLException on database error
+   */
+  boolean wasNull() throws SQLException;
+
+  /**
+   * Accessor of a column value.
+   */
+  public interface Accessor {
+    boolean wasNull() throws SQLException;
+
+    String getString() throws SQLException;
+
+    boolean getBoolean() throws SQLException;
+
+    byte getByte() throws SQLException;
+
+    short getShort() throws SQLException;
+
+    int getInt() throws SQLException;
+
+    long getLong() throws SQLException;
+
+    float getFloat() throws SQLException;
+
+    double getDouble() throws SQLException;
+
+    BigDecimal getBigDecimal() throws SQLException;
+
+    BigDecimal getBigDecimal(int scale) throws SQLException;
+
+    byte[] getBytes() throws SQLException;
+
+    InputStream getAsciiStream() throws SQLException;
+
+    InputStream getUnicodeStream() throws SQLException;
+
+    InputStream getBinaryStream() throws SQLException;
+
+    Object getObject() throws SQLException;
+
+    Reader getCharacterStream() throws SQLException;
+
+    Object getObject(Map<String, Class<?>> map) throws SQLException;
+
+    Ref getRef() throws SQLException;
+
+    Blob getBlob() throws SQLException;
+
+    Clob getClob() throws SQLException;
+
+    Array getArray() throws SQLException;
+
+    Date getDate(Calendar calendar) throws SQLException;
+
+    Time getTime(Calendar calendar) throws SQLException;
+
+    Timestamp getTimestamp(Calendar calendar) throws SQLException;
+
+    URL getURL() throws SQLException;
+
+    NClob getNClob() throws SQLException;
+
+    SQLXML getSQLXML() throws SQLException;
+
+    String getNString() throws SQLException;
+
+    Reader getNCharacterStream() throws SQLException;
+
+    <T> T getObject(Class<T> type) throws SQLException;
+  }
+}
+
+// End Cursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
new file mode 100644
index 0000000..67e1245
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java
@@ -0,0 +1,842 @@
+/*
+ * 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.util;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * Utility functions for datetime types: date, time, timestamp.
+ *
+ * <p>Used by the JDBC driver.
+ *
+ * <p>TODO: review methods for performance. Due to allocations required, it may
+ * be preferable to introduce a "formatter" with the required state.
+ */
+public class DateTimeUtils {
+  /** The julian date of the epoch, 1970-01-01. */
+  public static final int EPOCH_JULIAN = 2440588;
+
+  private DateTimeUtils() {}
+
+  //~ Static fields/initializers ---------------------------------------------
+
+  /** The SimpleDateFormat string for ISO dates, "yyyy-MM-dd". */
+  public static final String DATE_FORMAT_STRING = "yyyy-MM-dd";
+
+  /** The SimpleDateFormat string for ISO times, "HH:mm:ss". */
+  public static final String TIME_FORMAT_STRING = "HH:mm:ss";
+
+  /** The SimpleDateFormat string for ISO timestamps, "yyyy-MM-dd HH:mm:ss". */
+  public static final String TIMESTAMP_FORMAT_STRING =
+      DATE_FORMAT_STRING + " " + TIME_FORMAT_STRING;
+
+  /** The GMT time zone. */
+  public static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
+
+  /** The Java default time zone. */
+  public static final TimeZone DEFAULT_ZONE = TimeZone.getDefault();
+
+  /**
+   * The number of milliseconds in a second.
+   */
+  public static final long MILLIS_PER_SECOND = 1000L;
+
+  /**
+   * The number of milliseconds in a minute.
+   */
+  public static final long MILLIS_PER_MINUTE = 60000L;
+
+  /**
+   * The number of milliseconds in an hour.
+   */
+  public static final long MILLIS_PER_HOUR = 3600000L; // = 60 * 60 * 1000
+
+  /**
+   * The number of milliseconds in a day.
+   *
+   * <p>This is the modulo 'mask' used when converting
+   * TIMESTAMP values to DATE and TIME values.
+   */
+  public static final long MILLIS_PER_DAY = 86400000; // = 24 * 60 * 60 * 1000
+
+  /**
+   * Calendar set to the epoch (1970-01-01 00:00:00 UTC). Useful for
+   * initializing other values. Calendars are not immutable, so be careful not
+   * to screw up this object for everyone else.
+   */
+  public static final Calendar ZERO_CALENDAR;
+
+  static {
+    ZERO_CALENDAR = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
+    ZERO_CALENDAR.setTimeInMillis(0);
+  }
+
+  /**
+   * Calendar set to local time.
+   */
+  private static final Calendar LOCAL_CALENDAR = Calendar.getInstance();
+
+  //~ Methods ----------------------------------------------------------------
+
+  /**
+   * Parses a string using {@link SimpleDateFormat} and a given pattern. This
+   * method parses a string at the specified parse position and if successful,
+   * updates the parse position to the index after the last character used.
+   * The parsing is strict and requires months to be less than 12, days to be
+   * less than 31, etc.
+   *
+   * @param s       string to be parsed
+   * @param pattern {@link SimpleDateFormat} pattern (not null)
+   * @param tz      time zone in which to interpret string. Defaults to the Java
+   *                default time zone
+   * @param pp      position to start parsing from
+   * @return a Calendar initialized with the parsed value, or null if parsing
+   * failed. If returned, the Calendar is configured to the GMT time zone.
+   */
+  private static Calendar parseDateFormat(
+      String s,
+      String pattern,
+      TimeZone tz,
+      ParsePosition pp) {
+    assert pattern != null;
+    SimpleDateFormat df = new SimpleDateFormat(pattern);
+    if (tz == null) {
+      tz = DEFAULT_ZONE;
+    }
+    Calendar ret = Calendar.getInstance(tz);
+    df.setCalendar(ret);
+    df.setLenient(false);
+
+    java.util.Date d = df.parse(s, pp);
+    if (null == d) {
+      return null;
+    }
+    ret.setTime(d);
+    ret.setTimeZone(GMT_ZONE);
+    return ret;
+  }
+
+  /**
+   * Parses a string using {@link SimpleDateFormat} and a given pattern. The
+   * entire string must match the pattern specified.
+   *
+   * @param s       string to be parsed
+   * @param pattern {@link SimpleDateFormat}  pattern
+   * @param tz      time zone in which to interpret string. Defaults to the Java
+   *                default time zone
+   * @return a Calendar initialized with the parsed value, or null if parsing
+   * failed. If returned, the Calendar is configured to the GMT time zone.
+   */
+  public static Calendar parseDateFormat(
+      String s,
+      String pattern,
+      TimeZone tz) {
+    assert pattern != null;
+    ParsePosition pp = new ParsePosition(0);
+    Calendar ret = parseDateFormat(s, pattern, tz, pp);
+    if (pp.getIndex() != s.length()) {
+      // Didn't consume entire string - not good
+      return null;
+    }
+    return ret;
+  }
+
+  /**
+   * Parses a string using {@link SimpleDateFormat} and a given pattern, and
+   * if present, parses a fractional seconds component. The fractional seconds
+   * component must begin with a decimal point ('.') followed by numeric
+   * digits. The precision is rounded to a maximum of 3 digits of fractional
+   * seconds precision (to obtain milliseconds).
+   *
+   * @param s       string to be parsed
+   * @param pattern {@link SimpleDateFormat}  pattern
+   * @param tz      time zone in which to interpret string. Defaults to the
+   *                local time zone
+   * @return a {@link DateTimeUtils.PrecisionTime PrecisionTime} initialized
+   * with the parsed value, or null if parsing failed. The PrecisionTime
+   * contains a GMT Calendar and a precision.
+   */
+  public static PrecisionTime parsePrecisionDateTimeLiteral(
+      String s,
+      String pattern,
+      TimeZone tz) {
+    assert pattern != null;
+    ParsePosition pp = new ParsePosition(0);
+    Calendar cal = parseDateFormat(s, pattern, tz, pp);
+    if (cal == null) {
+      return null; // Invalid date/time format
+    }
+
+    // Note: the Java SimpleDateFormat 'S' treats any number after
+    // the decimal as milliseconds. That means 12:00:00.9 has 9
+    // milliseconds and 12:00:00.9999 has 9999 milliseconds.
+    int p = 0;
+    if (pp.getIndex() < s.length()) {
+      // Check to see if rest is decimal portion
+      if (s.charAt(pp.getIndex()) != '.') {
+        return null;
+      }
+
+      // Skip decimal sign
+      pp.setIndex(pp.getIndex() + 1);
+
+      // Parse decimal portion
+      if (pp.getIndex() < s.length()) {
+        String secFraction = s.substring(pp.getIndex());
+        if (!secFraction.matches("\\d+")) {
+          return null;
+        }
+        NumberFormat nf = NumberFormat.getIntegerInstance();
+        Number num = nf.parse(s, pp);
+        if ((num == null) || (pp.getIndex() != s.length())) {
+          // Invalid decimal portion
+          return null;
+        }
+
+        // Determine precision - only support prec 3 or lower
+        // (milliseconds) Higher precisions are quietly rounded away
+        p = Math.min(
+            3,
+            secFraction.length());
+
+        // Calculate milliseconds
+        int ms =
+            (int) Math.round(
+                num.longValue()
+                * Math.pow(10, 3 - secFraction.length()));
+        cal.add(Calendar.MILLISECOND, ms);
+      }
+    }
+
+    assert pp.getIndex() == s.length();
+    PrecisionTime ret = new PrecisionTime(cal, p);
+    return ret;
+  }
+
+  /**
+   * Gets the active time zone based on a Calendar argument
+   */
+  public static TimeZone getTimeZone(Calendar cal) {
+    if (cal == null) {
+      return DEFAULT_ZONE;
+    }
+    return cal.getTimeZone();
+  }
+
+  /**
+   * Checks if the date/time format is valid
+   *
+   * @param pattern {@link SimpleDateFormat}  pattern
+   * @throws IllegalArgumentException if the given pattern is invalid
+   */
+  public static void checkDateFormat(String pattern) {
+    new SimpleDateFormat(pattern);
+  }
+
+  /**
+   * Creates a new date formatter with Farrago specific options. Farrago
+   * parsing is strict and does not allow values such as day 0, month 13, etc.
+   *
+   * @param format {@link SimpleDateFormat}  pattern
+   */
+  public static SimpleDateFormat newDateFormat(String format) {
+    SimpleDateFormat sdf = new SimpleDateFormat(format);
+    sdf.setLenient(false);
+    return sdf;
+  }
+
+  /** Helper for CAST({timestamp} AS VARCHAR(n)). */
+  public static String unixTimestampToString(long timestamp) {
+    final StringBuilder buf = new StringBuilder(17);
+    int date = (int) (timestamp / MILLIS_PER_DAY);
+    int time = (int) (timestamp % MILLIS_PER_DAY);
+    if (time < 0) {
+      --date;
+      time += MILLIS_PER_DAY;
+    }
+    unixDateToString(buf, date);
+    buf.append(' ');
+    unixTimeToString(buf, time);
+    return buf.toString();
+  }
+
+  /** Helper for CAST({timestamp} AS VARCHAR(n)). */
+  public static String unixTimeToString(int time) {
+    final StringBuilder buf = new StringBuilder(8);
+    unixTimeToString(buf, time);
+    return buf.toString();
+  }
+
+  private static void unixTimeToString(StringBuilder buf, int time) {
+    int h = time / 3600000;
+    int time2 = time % 3600000;
+    int m = time2 / 60000;
+    int time3 = time2 % 60000;
+    int s = time3 / 1000;
+    int ms = time3 % 1000;
+    int2(buf, h);
+    buf.append(':');
+    int2(buf, m);
+    buf.append(':');
+    int2(buf, s);
+  }
+
+  private static void int2(StringBuilder buf, int i) {
+    buf.append((char) ('0' + (i / 10) % 10));
+    buf.append((char) ('0' + i % 10));
+  }
+
+  private static void int4(StringBuilder buf, int i) {
+    buf.append((char) ('0' + (i / 1000) % 10));
+    buf.append((char) ('0' + (i / 100) % 10));
+    buf.append((char) ('0' + (i / 10) % 10));
+    buf.append((char) ('0' + i % 10));
+  }
+
+  /** Helper for CAST({date} AS VARCHAR(n)). */
+  public static String unixDateToString(int date) {
+    final StringBuilder buf = new StringBuilder(10);
+    unixDateToString(buf, date);
+    return buf.toString();
+  }
+
+  private static void unixDateToString(StringBuilder buf, int date) {
+    julianToString(buf, date + EPOCH_JULIAN);
+  }
+
+  private static void julianToString(StringBuilder buf, int julian) {
+    // this shifts the epoch back to astronomical year -4800 instead of the
+    // start of the Christian era in year AD 1 of the proleptic Gregorian
+    // calendar.
+    int j = julian + 32044;
+    int g = j / 146097;
+    int dg = j % 146097;
+    int c = (dg / 36524 + 1) * 3 / 4;
+    int dc = dg - c * 36524;
+    int b = dc / 1461;
+    int db = dc % 1461;
+    int a = (db / 365 + 1) * 3 / 4;
+    int da = db - a * 365;
+
+    // integer number of full years elapsed since March 1, 4801 BC
+    int y = g * 400 + c * 100 + b * 4 + a;
+    // integer number of full months elapsed since the last March 1
+    int m = (da * 5 + 308) / 153 - 2;
+    // number of days elapsed since day 1 of the month
+    int d = da - (m + 4) * 153 / 5 + 122;
+    int year = y - 4800 + (m + 2) / 12;
+    int month = (m + 2) % 12 + 1;
+    int day = d + 1;
+    int4(buf, year);
+    buf.append('-');
+    int2(buf, month);
+    buf.append('-');
+    int2(buf, day);
+  }
+
+  public static String intervalYearMonthToString(int v, TimeUnitRange range) {
+    final StringBuilder buf = new StringBuilder();
+    if (v >= 0) {
+      buf.append('+');
+    } else {
+      buf.append('-');
+      v = -v;
+    }
+    final int y;
+    final int m;
+    switch (range) {
+    case YEAR:
+      v = roundUp(v, 12);
+      y = v / 12;
+      buf.append(y);
+      break;
+    case YEAR_TO_MONTH:
+      y = v / 12;
+      buf.append(y);
+      buf.append('-');
+      m = v % 12;
+      number(buf, m, 2);
+      break;
+    case MONTH:
+      m = v;
+      buf.append(m);
+      break;
+    default:
+      throw new AssertionError(range);
+    }
+    return buf.toString();
+  }
+
+  public static StringBuilder number(StringBuilder buf, int v, int n) {
+    for (int k = digitCount(v); k < n; k++) {
+      buf.append('0');
+    }
+    return buf.append(v);
+  }
+
+  public static int digitCount(int v) {
+    for (int n = 1;; n++) {
+      v /= 10;
+      if (v == 0) {
+        return n;
+      }
+    }
+  }
+
+  private static int roundUp(int dividend, int divisor) {
+    int remainder = dividend % divisor;
+    dividend -= remainder;
+    if (remainder * 2 > divisor) {
+      dividend += divisor;
+    }
+    return dividend;
+  }
+
+  /** Cheap, unsafe, long power. power(2, 3) returns 8. */
+  public static long powerX(long a, long b) {
+    long x = 1;
+    while (b > 0) {
+      x *= a;
+      --b;
+    }
+    return x;
+  }
+
+  public static String intervalDayTimeToString(long v, TimeUnitRange range,
+      int scale) {
+    final StringBuilder buf = new StringBuilder();
+    if (v >= 0) {
+      buf.append('+');
+    } else {
+      buf.append('-');
+      v = -v;
+    }
+    final long ms;
+    final long s;
+    final long m;
+    final long h;
+    final long d;
+    switch (range) {
+    case DAY_TO_SECOND:
+      v = roundUp(v, powerX(10, 3 - scale));
+      ms = v % 1000;
+      v /= 1000;
+      s = v % 60;
+      v /= 60;
+      m = v % 60;
+      v /= 60;
+      h = v % 24;
+      v /= 24;
+      d = v;
+      buf.append((int) d);
+      buf.append(' ');
+      number(buf, (int) h, 2);
+      buf.append(':');
+      number(buf, (int) m, 2);
+      buf.append(':');
+      number(buf, (int) s, 2);
+      fraction(buf, scale, ms);
+      break;
+    case DAY_TO_MINUTE:
+      v = roundUp(v, 1000 * 60);
+      v /= 1000;
+      v /= 60;
+      m = v % 60;
+      v /= 60;
+      h = v % 24;
+      v /= 24;
+      d = v;
+      buf.append((int) d);
+      buf.append(' ');
+      number(buf, (int) h, 2);
+      buf.append(':');
+      number(buf, (int) m, 2);
+      break;
+    case DAY_TO_HOUR:
+      v = roundUp(v, 1000 * 60 * 60);
+      v /= 1000;
+      v /= 60;
+      v /= 60;
+      h = v % 24;
+      v /= 24;
+      d = v;
+      buf.append((int) d);
+      buf.append(' ');
+      number(buf, (int) h, 2);
+      break;
+    case DAY:
+      v = roundUp(v, 1000 * 60 * 60 * 24);
+      d = v / (1000 * 60 * 60 * 24);
+      buf.append((int) d);
+      break;
+    case HOUR:
+      v = roundUp(v, 1000 * 60 * 60);
+      v /= 1000;
+      v /= 60;
+      v /= 60;
+      h = v;
+      buf.append((int) h);
+      break;
+    case HOUR_TO_MINUTE:
+      v = roundUp(v, 1000 * 60);
+      v /= 1000;
+      v /= 60;
+      m = v % 60;
+      v /= 60;
+      h = v;
+      buf.append((int) h);
+      buf.append(':');
+      number(buf, (int) m, 2);
+      break;
+    case HOUR_TO_SECOND:
+      v = roundUp(v, powerX(10, 3 - scale));
+      ms = v % 1000;
+      v /= 1000;
+      s = v % 60;
+      v /= 60;
+      m = v % 60;
+      v /= 60;
+      h = v;
+      buf.append((int) h);
+      buf.append(':');
+      number(buf, (int) m, 2);
+      buf.append(':');
+      number(buf, (int) s, 2);
+      fraction(buf, scale, ms);
+      break;
+    case MINUTE_TO_SECOND:
+      v = roundUp(v, powerX(10, 3 - scale));
+      ms = v % 1000;
+      v /= 1000;
+      s = v % 60;
+      v /= 60;
+      m = v;
+      buf.append((int) m);
+      buf.append(':');
+      number(buf, (int) s, 2);
+      fraction(buf, scale, ms);
+      break;
+    case MINUTE:
+      v = roundUp(v, 1000 * 60);
+      v /= 1000;
+      v /= 60;
+      m = v;
+      buf.append((int) m);
+      break;
+    case SECOND:
+      v = roundUp(v, powerX(10, 3 - scale));
+      ms = v % 1000;
+      v /= 1000;
+      s = v;
+      buf.append((int) s);
+      fraction(buf, scale, ms);
+      break;
+    default:
+      throw new AssertionError(range);
+    }
+    return buf.toString();
+  }
+
+  /**
+   * Rounds a dividend to the nearest divisor.
+   * For example roundUp(31, 10) yields 30; roundUp(37, 10) yields 40.
+   * @param dividend Number to be divided
+   * @param divisor Number to divide by
+   * @return Rounded dividend
+   */
+  private static long roundUp(long dividend, long divisor) {
+    long remainder = dividend % divisor;
+    dividend -= remainder;
+    if (remainder * 2 > divisor) {
+      dividend += divisor;
+    }
+    return dividend;
+  }
+
+  private static void fraction(StringBuilder buf, int scale, long ms) {
+    if (scale > 0) {
+      buf.append('.');
+      long v1 = scale == 3 ? ms
+          : scale == 2 ? ms / 10
+          : scale == 1 ? ms / 100
+            : 0;
+      number(buf, (int) v1, scale);
+    }
+  }
+
+  public static int dateStringToUnixDate(String s) {
+    int hyphen1 = s.indexOf('-');
+    int y;
+    int m;
+    int d;
+    if (hyphen1 < 0) {
+      y = Integer.parseInt(s.trim());
+      m = 1;
+      d = 1;
+    } else {
+      y = Integer.parseInt(s.substring(0, hyphen1).trim());
+      final int hyphen2 = s.indexOf('-', hyphen1 + 1);
+      if (hyphen2 < 0) {
+        m = Integer.parseInt(s.substring(hyphen1 + 1).trim());
+        d = 1;
+      } else {
+        m = Integer.parseInt(s.substring(hyphen1 + 1, hyphen2).trim());
+        d = Integer.parseInt(s.substring(hyphen2 + 1).trim());
+      }
+    }
+    return ymdToUnixDate(y, m, d);
+  }
+
+  public static int timeStringToUnixDate(String v) {
+    return timeStringToUnixDate(v, 0);
+  }
+
+  public static int timeStringToUnixDate(String v, int start) {
+    final int colon1 = v.indexOf(':', start);
+    int hour;
+    int minute;
+    int second;
+    int milli;
+    if (colon1 < 0) {
+      hour = Integer.parseInt(v.trim());
+      minute = 1;
+      second = 1;
+      milli = 0;
+    } else {
+      hour = Integer.parseInt(v.substring(start, colon1).trim());
+      final int colon2 = v.indexOf(':', colon1 + 1);
+      if (colon2 < 0) {
+        minute = Integer.parseInt(v.substring(colon1 + 1).trim());
+        second = 1;
+        milli = 0;
+      } else {
+        minute = Integer.parseInt(v.substring(colon1 + 1, colon2).trim());
+        int dot = v.indexOf('.', colon2);
+        if (dot < 0) {
+          second = Integer.parseInt(v.substring(colon2 + 1).trim());
+          milli = 0;
+        } else {
+          second = Integer.parseInt(v.substring(colon2 + 1, dot).trim());
+          milli = Integer.parseInt(v.substring(dot + 1).trim());
+        }
+      }
+    }
+    return hour * (int) MILLIS_PER_HOUR
+        + minute * (int) MILLIS_PER_MINUTE
+        + second * (int) MILLIS_PER_SECOND
+        + milli;
+  }
+
+  public static long timestampStringToUnixDate(String s) {
+    final long d;
+    final long t;
+    s = s.trim();
+    int space = s.indexOf(' ');
+    if (space >= 0) {
+      d = dateStringToUnixDate(s.substring(0, space));
+      t = timeStringToUnixDate(s, space + 1);
+    } else {
+      d = dateStringToUnixDate(s);
+      t = 0;
+    }
+    return d * MILLIS_PER_DAY + t;
+  }
+
+  public static long unixDateExtract(TimeUnitRange range, long date) {
+    return julianExtract(range, (int) date + EPOCH_JULIAN);
+  }
+
+  private static int julianExtract(TimeUnitRange range, int julian) {
+    // this shifts the epoch back to astronomical year -4800 instead of the
+    // start of the Christian era in year AD 1 of the proleptic Gregorian
+    // calendar.
+    int j = julian + 32044;
+    int g = j / 146097;
+    int dg = j % 146097;
+    int c = (dg / 36524 + 1) * 3 / 4;
+    int dc = dg - c * 36524;
+    int b = dc / 1461;
+    int db = dc % 1461;
+    int a = (db / 365 + 1) * 3 / 4;
+    int da = db - a * 365;
+
+    // integer number of full years elapsed since March 1, 4801 BC
+    int y = g * 400 + c * 100 + b * 4 + a;
+    // integer number of full months elapsed since the last March 1
+    int m = (da * 5 + 308) / 153 - 2;
+    // number of days elapsed since day 1 of the month
+    int d = da - (m + 4) * 153 / 5 + 122;
+    int year = y - 4800 + (m + 2) / 12;
+    int month = (m + 2) % 12 + 1;
+    int day = d + 1;
+    switch (range) {
+    case YEAR:
+      return year;
+    case MONTH:
+      return month;
+    case DAY:
+      return day;
+    default:
+      throw new AssertionError(range);
+    }
+  }
+
+  /** Resets to zero the "time" part of a timestamp. */
+  public static long resetTime(long timestamp) {
+    int date = (int) (timestamp / MILLIS_PER_DAY);
+    return (long) date * MILLIS_PER_DAY;
+  }
+
+  /** Resets to epoch (1970-01-01) the "date" part of a timestamp. */
+  public static long resetDate(long timestamp) {
+    return floorMod(timestamp, MILLIS_PER_DAY);
+  }
+
+  public static long unixTimestampFloor(TimeUnitRange range, long timestamp) {
+    int date = (int) (timestamp / MILLIS_PER_DAY);
+    final int f = julianDateFloor(range, date + EPOCH_JULIAN, true);
+    return (long) f * MILLIS_PER_DAY;
+  }
+
+  public static long unixDateFloor(TimeUnitRange range, long date) {
+    return julianDateFloor(range, (int) date + EPOCH_JULIAN, true);
+  }
+
+  public static long unixTimestampCeil(TimeUnitRange range, long timestamp) {
+    int date = (int) (timestamp / MILLIS_PER_DAY);
+    final int f = julianDateFloor(range, date + EPOCH_JULIAN, false);
+    return (long) f * MILLIS_PER_DAY;
+  }
+
+  public static long unixDateCeil(TimeUnitRange range, long date) {
+    return julianDateFloor(range, (int) date + EPOCH_JULIAN, true);
+  }
+
+  private static int julianDateFloor(TimeUnitRange range, int julian,
+      boolean floor) {
+    // this shifts the epoch back to astronomical year -4800 instead of the
+    // start of the Christian era in year AD 1 of the proleptic Gregorian
+    // calendar.
+    int j = julian + 32044;
+    int g = j / 146097;
+    int dg = j % 146097;
+    int c = (dg / 36524 + 1) * 3 / 4;
+    int dc = dg - c * 36524;
+    int b = dc / 1461;
+    int db = dc % 1461;
+    int a = (db / 365 + 1) * 3 / 4;
+    int da = db - a * 365;
+
+    // integer number of full years elapsed since March 1, 4801 BC
+    int y = g * 400 + c * 100 + b * 4 + a;
+    // integer number of full months elapsed since the last March 1
+    int m = (da * 5 + 308) / 153 - 2;
+    // number of days elapsed since day 1 of the month
+    int d = da - (m + 4) * 153 / 5 + 122;
+    int year = y - 4800 + (m + 2) / 12;
+    int month = (m + 2) % 12 + 1;
+    int day = d + 1;
+    switch (range) {
+    case YEAR:
+      if (!floor && (month > 1 || day > 1)) {
+        ++year;
+      }
+      return ymdToUnixDate(year, 1, 1);
+    case MONTH:
+      if (!floor && day > 1) {
+        ++month;
+      }
+      return ymdToUnixDate(year, month, 1);
+    default:
+      throw new AssertionError(range);
+    }
+  }
+
+  public static int ymdToUnixDate(int year, int month, int day) {
+    final int julian = ymdToJulian(year, month, day);
+    return julian - EPOCH_JULIAN;
+  }
+
+  public static int ymdToJulian(int year, int month, int day) {
+    int a = (14 - month) / 12;
+    int y = year + 4800 - a;
+    int m = month + 12 * a - 3;
+    int j = day + (153 * m + 2) / 5
+        + 365 * y
+        + y / 4
+        - y / 100
+        + y / 400
+        - 32045;
+    if (j < 2299161) {
+      j = day + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
+    }
+    return j;
+  }
+
+  public static long unixTimestamp(int year, int month, int day, int hour,
+      int minute, int second) {
+    final int date = ymdToUnixDate(year, month, day);
+    return (long) date * MILLIS_PER_DAY
+        + (long) hour * MILLIS_PER_HOUR
+        + (long) minute * MILLIS_PER_MINUTE
+        + (long) second * MILLIS_PER_SECOND;
+  }
+
+  /** Divide, rounding towards negative infinity. */
+  public static long floorDiv(long x, long y) {
+    long r = x / y;
+    // if the signs are different and modulo not zero, round down
+    if ((x ^ y) < 0 && (r * y != x)) {
+      r--;
+    }
+    return r;
+  }
+
+  /** Modulo, always returning a non-negative result. */
+  public static long floorMod(long x, long y) {
+    return x - floorDiv(x, y) * y;
+  }
+
+  //~ Inner Classes ----------------------------------------------------------
+
+  /**
+   * Helper class for {@link DateTimeUtils#parsePrecisionDateTimeLiteral}
+   */
+  public static class PrecisionTime {
+    private final Calendar cal;
+    private final int precision;
+
+    public PrecisionTime(Calendar cal, int precision) {
+      this.cal = cal;
+      this.precision = precision;
+    }
+
+    public Calendar getCalendar() {
+      return cal;
+    }
+
+    public int getPrecision() {
+      return precision;
+    }
+  }
+}
+
+// End DateTimeUtils.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
new file mode 100644
index 0000000..c09373b
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/IteratorCursor.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.util.Cursor}
+ * on top of an {@link Iterator} that
+ * returns a record for each row. The returned record is cached to avoid
+ * multiple computations of current row.
+ *
+ * @param <E> Element type
+ */
+public abstract class IteratorCursor<E> extends PositionedCursor<E> {
+  private Position position = Position.BEFORE_START;
+  private final Iterator<E> iterator;
+  private E current = null;
+
+  /**
+   * Creates an {@code IteratorCursor}.
+   *
+   * @param iterator input iterator
+   */
+  protected IteratorCursor(Iterator<E> iterator) {
+    this.iterator = iterator;
+  }
+
+  public boolean next() {
+    if (iterator.hasNext()) {
+      current = iterator.next();
+      position = Position.OK;
+      return true;
+    }
+    current = null;
+    position = Position.AFTER_END;
+    return false;
+  }
+
+  public void close() {
+    current = null;
+    position = Position.CLOSED;
+    if (iterator instanceof AutoCloseable) {
+      try {
+        ((AutoCloseable) iterator).close();
+      } catch (RuntimeException e) {
+        throw e;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  protected E current() {
+    if (position != Position.OK) {
+      throw new NoSuchElementException();
+    }
+    return current;
+  }
+
+  /** Are we positioned on a valid row? */
+  private enum Position {
+    CLOSED,
+    BEFORE_START,
+    OK,
+    AFTER_END
+  }
+}
+
+// End IteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
new file mode 100644
index 0000000..e2801ec
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/ListIteratorCursor.java
@@ -0,0 +1,43 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Implementation of {@link Cursor} on top of an
+ * {@link java.util.Iterator} that
+ * returns a {@link List} for each row.
+ */
+public class ListIteratorCursor extends IteratorCursor<List<Object>> {
+
+  /**
+   * Creates a RecordEnumeratorCursor.
+   *
+   * @param iterator Iterator
+   */
+  public ListIteratorCursor(Iterator<List<Object>> iterator) {
+    super(iterator);
+  }
+
+  protected Getter createGetter(int ordinal) {
+    return new ListGetter(ordinal);
+  }
+}
+
+// End ListIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
new file mode 100644
index 0000000..9ab6c9c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/MapIteratorCursor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of {@link Cursor} on top of an
+ * {@link java.util.Iterator} that
+ * returns a {@link Map} for each row.
+ *
+ * <p>The Map contains (field, value) pairs.
+ */
+public class MapIteratorCursor extends IteratorCursor<Map<String, Object>> {
+  private final List<String> fieldNames;
+
+  /**
+   * Creates a MapIteratorCursor.
+   *
+   * @param iterator Iterator
+   * @param fieldNames Field names to project
+   */
+  public MapIteratorCursor(Iterator<Map<String, Object>> iterator,
+      List<String> fieldNames) {
+    super(iterator);
+    assert fieldNames != null;
+    this.fieldNames = fieldNames;
+  }
+
+  protected Getter createGetter(int ordinal) {
+    return new MapGetter<String>(fieldNames.get(ordinal));
+  }
+}
+
+// End MapIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
new file mode 100644
index 0000000..3a6a9c6
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/PackageMarker.java
@@ -0,0 +1,37 @@
+/*
+ * 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.util;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is a dummy annotation that forces javac to produce output for
+ * otherwise empty package-info.java.
+ *
+ * <p>The result is maven-compiler-plugin can properly identify the scope of
+ * changed files
+ *
+ * <p>See more details in
+ * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
+ *   maven-compiler-plugin: incremental compilation broken</a>
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface PackageMarker {
+}
+
+// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
new file mode 100644
index 0000000..f60f47d
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/PositionedCursor.java
@@ -0,0 +1,134 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract implementation of {@link org.apache.calcite.avatica.util.Cursor}
+ * that caches its current row.
+ *
+ * @param <T> Element type
+ */
+public abstract class PositionedCursor<T> extends AbstractCursor {
+  /**
+   * Returns the current row.
+   *
+   * @return current row
+   *
+   * @throws java.util.NoSuchElementException if the iteration has no more
+   * elements
+   */
+  protected abstract T current();
+
+  /** Implementation of
+   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
+   * that reads from records that are arrays. */
+  protected class ArrayGetter extends AbstractGetter {
+    protected final int field;
+
+    public ArrayGetter(int field) {
+      this.field = field;
+    }
+
+    public Object getObject() {
+      Object o = ((Object[]) current())[field];
+      wasNull[0] = o == null;
+      return o;
+    }
+  }
+
+  /** Implementation of
+   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
+   * that reads items from a list. */
+  protected class ListGetter extends AbstractGetter {
+    protected final int index;
+
+    public ListGetter(int index) {
+      this.index = index;
+    }
+
+    public Object getObject() {
+      Object o = ((List) current()).get(index);
+      wasNull[0] = o == null;
+      return o;
+    }
+  }
+
+  /** Implementation of
+   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
+   * for records that consist of a single field.
+   *
+   * <p>Each record is represented as an object, and the value of the sole
+   * field is that object. */
+  protected class ObjectGetter extends AbstractGetter {
+    public ObjectGetter(int field) {
+      assert field == 0;
+    }
+
+    public Object getObject() {
+      Object o = current();
+      wasNull[0] = o == null;
+      return o;
+    }
+  }
+
+  /** Implementation of
+   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
+   * that reads fields via reflection. */
+  protected class FieldGetter extends AbstractGetter {
+    protected final Field field;
+
+    public FieldGetter(Field field) {
+      this.field = field;
+    }
+
+    public Object getObject() {
+      Object o;
+      try {
+        o = field.get(current());
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      }
+      wasNull[0] = o == null;
+      return o;
+    }
+  }
+
+  /** Implementation of
+   * {@link org.apache.calcite.avatica.util.AbstractCursor.Getter}
+   * that reads entries from a {@link java.util.Map}. */
+  protected class MapGetter<K> extends AbstractGetter {
+    protected final K key;
+
+    public MapGetter(K key) {
+      this.key = key;
+    }
+
+    public Object getObject() {
+      @SuppressWarnings("unchecked") final Map<K, Object> map =
+          (Map<K, Object>) current();
+      Object o = map.get(key);
+      wasNull[0] = o == null;
+      return o;
+    }
+  }
+}
+
+// End PositionedCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Quoting.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Quoting.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Quoting.java
new file mode 100644
index 0000000..855e4a6
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Quoting.java
@@ -0,0 +1,37 @@
+/*
+ * 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.util;
+
+/** Syntax for quoting identifiers in SQL statements. */
+public enum Quoting {
+  /** Quote identifiers in double-quotes. For example, {@code "my id"}. */
+  DOUBLE_QUOTE("\""),
+
+  /** Quote identifiers in back-quotes. For example, {@code `my id`}. */
+  BACK_TICK("`"),
+
+  /** Quote identifiers in brackets. For example, {@code [my id]}. */
+  BRACKET("[");
+
+  public String string;
+
+  Quoting(String string) {
+    this.string = string;
+  }
+}
+
+// End Quoting.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
new file mode 100644
index 0000000..717247d
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/RecordIteratorCursor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.util.Cursor} on top of an
+ * {@link java.util.Iterator} that
+ * returns a record for each row. The record is a synthetic class whose fields
+ * are all public.
+ *
+ * @param <E> Element type
+ */
+public class RecordIteratorCursor<E> extends IteratorCursor<E> {
+  private final List<Field> fields;
+
+  /**
+   * Creates a RecordIteratorCursor.
+   *
+   * @param iterator Iterator
+   * @param clazz Element type
+   */
+  public RecordIteratorCursor(Iterator<E> iterator, Class<E> clazz) {
+    this(iterator, clazz, Arrays.asList(clazz.getFields()));
+  }
+
+  /**
+   * Creates a RecordIteratorCursor that projects particular fields.
+   *
+   * @param iterator Iterator
+   * @param clazz Element type
+   * @param fields Fields to project
+   */
+  public RecordIteratorCursor(Iterator<E> iterator, Class<E> clazz,
+      List<Field> fields) {
+    super(iterator);
+    this.fields = fields;
+  }
+
+  protected Getter createGetter(int ordinal) {
+    return new FieldGetter(fields.get(ordinal));
+  }
+}
+
+// End RecordIteratorCursor.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spacer.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spacer.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spacer.java
new file mode 100644
index 0000000..cc0a097
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spacer.java
@@ -0,0 +1,80 @@
+/*
+ * 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.util;
+
+/**
+ * Efficiently writes strings of spaces.
+ */
+public class Spacer {
+  private int n;
+
+  /** Creates a Spacer with zero spaces. */
+  public Spacer() {
+    this(0);
+  }
+
+  /** Creates a Spacer with a given number of spaces. */
+  public Spacer(int n) {
+    set(n);
+  }
+
+  /** Sets the current number of spaces. */
+  public Spacer set(int n) {
+    this.n = n;
+    return this;
+  }
+
+  /** Returns the current number of spaces. */
+  public int get() {
+    return n;
+  }
+
+  /** Increases the current number of spaces by {@code n}. */
+  public Spacer add(int n) {
+    return set(this.n + n);
+  }
+
+  /** Reduces the current number of spaces by {@code n}. */
+  public Spacer subtract(int n) {
+    return set(this.n - n);
+  }
+
+  /** Returns a string of the current number of spaces. */
+  public String toString() {
+    return Spaces.of(n);
+  }
+
+  /** Appends current number of spaces to a {@link StringBuilder}. */
+  public StringBuilder spaces(StringBuilder buf) {
+    return Spaces.append(buf, n);
+  }
+
+  /** Returns a string that is padded on the right with spaces to the current
+   * length. */
+  public String padRight(String string) {
+    Spaces.padRight(string, n);
+    final int x = n - string.length();
+    if (x <= 0) {
+      return string;
+    }
+    // Replacing StringBuffer with String would hurt performance.
+    //noinspection StringBufferReplaceableByString
+    return Spaces.append(new StringBuilder(string), x).toString();
+  }
+}
+
+// End Spacer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spaces.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spaces.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spaces.java
new file mode 100644
index 0000000..6469400
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Spaces.java
@@ -0,0 +1,185 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/** Utilities for creating strings of spaces. */
+public class Spaces {
+  /** It doesn't look like this list is ever updated. But it is - when a call to
+   * to {@link SpaceList#get} causes an {@link IndexOutOfBoundsException}. */
+  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+  private static final List<String> SPACE_LIST = new SpaceList();
+
+  /** The longest possible string of spaces. Fine as long as you don't try
+   * to print it.
+   *
+   * <p>Use with {@link StringBuilder#append(CharSequence, int, int)} to
+   * append spaces without doing memory allocation.</p>
+   */
+  public static final CharSequence MAX = sequence(Integer.MAX_VALUE);
+
+  // Utility class. Do not instantiate.
+  private Spaces() {}
+
+  /** Creates a sequence of {@code n} spaces. */
+  public static CharSequence sequence(int n) {
+    return new SpaceString(n);
+  }
+
+  /** Returns a string of {@code n} spaces. */
+  public static String of(int n) {
+    return SPACE_LIST.get(n);
+  }
+
+  /** Appends {@code n} spaces to an {@link Appendable}. */
+  public static Appendable append(Appendable buf, int n) throws IOException {
+    buf.append(MAX, 0, n);
+    return buf;
+  }
+
+  /** Appends {@code n} spaces to a {@link PrintWriter}. */
+  public static PrintWriter append(PrintWriter pw, int n) {
+    pw.append(MAX, 0, n);
+    return pw;
+  }
+
+  /** Appends {@code n} spaces to a {@link StringWriter}. */
+  public static StringWriter append(StringWriter pw, int n) {
+    pw.append(MAX, 0, n);
+    return pw;
+  }
+
+  /** Appends {@code n} spaces to a {@link StringBuilder}. */
+  public static StringBuilder append(StringBuilder buf, int n) {
+    buf.append(MAX, 0, n);
+    return buf;
+  }
+
+  /** Appends {@code n} spaces to a {@link StringBuffer}. */
+  public static StringBuffer append(StringBuffer buf, int n) {
+    buf.append(MAX, 0, n);
+    return buf;
+  }
+
+  /** Returns a string that is padded on the right with spaces to the given
+   * length. */
+  public static String padRight(String string, int n) {
+    final int x = n - string.length();
+    if (x <= 0) {
+      return string;
+    }
+    // Replacing StringBuffer with String would hurt performance.
+    //noinspection StringBufferReplaceableByString
+    return append(new StringBuilder(string), x).toString();
+  }
+
+  /** Returns a string that is padded on the left with spaces to the given
+   * length. */
+  public static String padLeft(String string, int n) {
+    final int x = n - string.length();
+    if (x <= 0) {
+      return string;
+    }
+    // Replacing StringBuffer with String would hurt performance.
+    //noinspection StringBufferReplaceableByString
+    return append(new StringBuilder(), x).append(string).toString();
+  }
+
+  /** A string of spaces. */
+  private static class SpaceString implements CharSequence {
+    private final int length;
+
+    private SpaceString(int length) {
+      this.length = length;
+    }
+
+    // Do not override equals and hashCode to be like String. CharSequence does
+    // not require it.
+
+    @SuppressWarnings("NullableProblems")
+    @Override public String toString() {
+      return of(length);
+    }
+
+    public int length() {
+      return length;
+    }
+
+    public char charAt(int index) {
+      return ' ';
+    }
+
+    public CharSequence subSequence(int start, int end) {
+      return new SpaceString(end - start);
+    }
+  }
+
+  /** List whose {@code i}th entry is a string consisting of {@code i} spaces.
+   * It populates itself the first time you ask for a particular string, and
+   * caches the result. */
+  private static class SpaceList extends CopyOnWriteArrayList<String> {
+    @Override public String get(int index) {
+      for (;;) {
+        try {
+          return super.get(index);
+        } catch (IndexOutOfBoundsException e) {
+          if (index < 0) {
+            throw e;
+          }
+          populate(Math.max(16, index + 1));
+        }
+      }
+    }
+
+    /**
+     * Populates this list with all prefix strings of a given string. All
+     * of the prefix strings share the same backing array of chars.
+     */
+    private synchronized void populate(int newSize) {
+      final int size = size();
+      if (newSize <= size) {
+        return;
+      }
+      final char[] chars = new char[newSize];
+      Arrays.fill(chars, ' ');
+      final int length = newSize - size;
+      final int offset = size;
+
+      // addAll is much more efficient than repeated add for
+      // CopyOnWriteArrayList
+      addAll(
+          new AbstractList<String>() {
+            public String get(int index) {
+              return new String(chars, 0, offset + index);
+            }
+
+            public int size() {
+              return length;
+            }
+          });
+    }
+  }
+}
+
+// End Spaces.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/StructImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
new file mode 100644
index 0000000..b25fce6
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/StructImpl.java
@@ -0,0 +1,79 @@
+/*
+ * 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.util;
+
+import org.apache.calcite.avatica.ColumnMetaData;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Struct;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/** Implementation of JDBC {@link Struct}. */
+public class StructImpl implements Struct {
+  private final List list;
+
+  public StructImpl(List list) {
+    this.list = list;
+  }
+
+  @Override public String toString() {
+    final Iterator iterator = list.iterator();
+    if (!iterator.hasNext()) {
+      return "{}";
+    }
+    final StringBuilder buf = new StringBuilder("{");
+    for (;;) {
+      append(buf, iterator.next());
+      if (!iterator.hasNext()) {
+        return buf.append("}").toString();
+      }
+      buf.append(", ");
+    }
+  }
+
+  @Override public String getSQLTypeName() throws SQLException {
+    return "ROW";
+  }
+
+  @Override public Object[] getAttributes() throws SQLException {
+    return list.toArray();
+  }
+
+  @Override public Object[] getAttributes(Map<String, Class<?>> map)
+      throws SQLException {
+    throw new UnsupportedOperationException(); // TODO
+  }
+
+  private void append(StringBuilder buf, Object o) {
+    if (o == null) {
+      buf.append("null");
+    } else {
+      buf.append(o);
+    }
+  }
+
+  /** Factory that can create a result set based on a list of values. */
+  public interface Factory {
+    ResultSet create(ColumnMetaData.AvaticaType elementType,
+        Iterable<Object> iterable);
+  }
+}
+
+// End StructImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
new file mode 100644
index 0000000..b249232
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
@@ -0,0 +1,75 @@
+/*
+ * 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.util;
+
+import java.math.BigDecimal;
+
+/**
+ * Enumeration of time units used to construct an interval.
+ */
+public enum TimeUnit {
+  YEAR(true, ' ', 12 /* months */, null),
+  MONTH(true, '-', 1 /* months */, BigDecimal.valueOf(12)),
+  DAY(false, '-', DateTimeUtils.MILLIS_PER_DAY, null),
+  HOUR(false, ' ', DateTimeUtils.MILLIS_PER_HOUR, BigDecimal.valueOf(24)),
+  MINUTE(false, ':', DateTimeUtils.MILLIS_PER_MINUTE, BigDecimal.valueOf(60)),
+  SECOND(false, ':', DateTimeUtils.MILLIS_PER_SECOND, BigDecimal.valueOf(60)),
+
+  /** Unlike the other units, MILLISECOND may not be the unit of a SQL interval.
+   * Still, it is convenient to use it internally, when converting to and from
+   * UNIX timestamps. */
+  MILLISECOND(false, '.', 1, BigDecimal.valueOf(1));
+
+  public final boolean yearMonth;
+  public final char separator;
+  public final long multiplier;
+  private final BigDecimal limit;
+
+  private static final TimeUnit[] CACHED_VALUES = values();
+
+  TimeUnit(boolean yearMonth, char separator, long multiplier,
+      BigDecimal limit) {
+    this.yearMonth = yearMonth;
+    this.separator = separator;
+    this.multiplier = multiplier;
+    this.limit = limit;
+  }
+
+  /**
+   * Returns the TimeUnit associated with an ordinal. The value returned
+   * is null if the ordinal is not a member of the TimeUnit enumeration.
+   */
+  public static TimeUnit getValue(int ordinal) {
+    return ordinal < 0 || ordinal >= CACHED_VALUES.length
+        ? null
+        : CACHED_VALUES[ordinal];
+  }
+
+  /**
+   * Returns whether a given value is valid for a field of this time unit.
+   *
+   * @param field Field value
+   * @return Whether value
+   */
+  public boolean isValidValue(BigDecimal field) {
+    return field.compareTo(BigDecimal.ZERO) >= 0
+        && (limit == null
+        || field.compareTo(limit) < 0);
+  }
+}
+
+// End TimeUnit.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
new file mode 100644
index 0000000..4d9b322
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
@@ -0,0 +1,107 @@
+/*
+ * 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.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/** A range of time units. The first is more significant than the
+ * other (e.g. year-to-day) or the same as the other (e.g. month). */
+public enum TimeUnitRange {
+  YEAR(TimeUnit.YEAR, null),
+  YEAR_TO_MONTH(TimeUnit.YEAR, TimeUnit.MONTH),
+  MONTH(TimeUnit.MONTH, null),
+  DAY(TimeUnit.DAY, null),
+  DAY_TO_HOUR(TimeUnit.DAY, TimeUnit.HOUR),
+  DAY_TO_MINUTE(TimeUnit.DAY, TimeUnit.MINUTE),
+  DAY_TO_SECOND(TimeUnit.DAY, TimeUnit.SECOND),
+  HOUR(TimeUnit.HOUR, null),
+  HOUR_TO_MINUTE(TimeUnit.HOUR, TimeUnit.MINUTE),
+  HOUR_TO_SECOND(TimeUnit.HOUR, TimeUnit.SECOND),
+  MINUTE(TimeUnit.MINUTE, null),
+  MINUTE_TO_SECOND(TimeUnit.MINUTE, TimeUnit.SECOND),
+  SECOND(TimeUnit.SECOND, null);
+
+  public final TimeUnit startUnit;
+  public final TimeUnit endUnit;
+
+  private static final Map<Pair<TimeUnit>, TimeUnitRange> MAP = createMap();
+
+  /**
+   * Creates a TimeUnitRange.
+   *
+   * @param startUnit Start time unit
+   * @param endUnit   End time unit
+   */
+  TimeUnitRange(TimeUnit startUnit, TimeUnit endUnit) {
+    assert startUnit != null;
+    this.startUnit = startUnit;
+    this.endUnit = endUnit;
+  }
+
+  /**
+   * Returns a {@code TimeUnitRange} with a given start and end unit.
+   *
+   * @param startUnit Start unit
+   * @param endUnit   End unit
+   * @return Time unit range, or null if not valid
+   */
+  public static TimeUnitRange of(TimeUnit startUnit, TimeUnit endUnit) {
+    return MAP.get(new Pair<>(startUnit, endUnit));
+  }
+
+  private static Map<Pair<TimeUnit>, TimeUnitRange> createMap() {
+    Map<Pair<TimeUnit>, TimeUnitRange> map = new HashMap<>();
+    for (TimeUnitRange value : values()) {
+      map.put(new Pair<>(value.startUnit, value.endUnit), value);
+    }
+    return Collections.unmodifiableMap(map);
+  }
+
+  /** Whether this is in the YEAR-TO-MONTH family of intervals. */
+  public boolean monthly() {
+    return ordinal() <= MONTH.ordinal();
+  }
+
+  /** Immutable pair of values of the same type. */
+  private static class Pair<E> {
+    final E left;
+    final E right;
+
+    private Pair(E left, E right) {
+      this.left = left;
+      this.right = right;
+    }
+
+    @Override public int hashCode() {
+      int k = (left == null) ? 0 : left.hashCode();
+      int k1 = (right == null) ? 0 : right.hashCode();
+      return ((k << 4) | k) ^ k1;
+    }
+
+    @Override public boolean equals(Object obj) {
+      return obj == this
+          || obj instanceof Pair
+          && Objects.equals(left, ((Pair) obj).left)
+          && Objects.equals(right, ((Pair) obj).right);
+    }
+  }
+}
+
+// End TimeUnitRange.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
new file mode 100644
index 0000000..8daee60
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/UnsynchronizedBuffer.java
@@ -0,0 +1,152 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A utility class for reading and writing bytes to byte buffers without synchronization. A
+ * reduced variant taken from Apache Accumulo. This class is <b>not</b> thread-safe by design.
+ * It is up to the caller to guarantee mutual exclusion as necessary.
+ */
+public class UnsynchronizedBuffer extends OutputStream {
+  // Anything larger than 64K, reap the backing buffer
+  private static final int LARGE_BUFFER_SIZE = 1024 * 64;
+
+  final int initialCapacity;
+  int offset = 0;
+  byte[] data;
+
+  /**
+   * Creates a new writer.
+   */
+  public UnsynchronizedBuffer() {
+    this(4096);
+  }
+
+  /**
+   * Creates a new writer.
+   *
+   * @param initialCapacity initial byte capacity
+   */
+  public UnsynchronizedBuffer(int initialCapacity) {
+    this.initialCapacity = initialCapacity;
+    data = new byte[initialCapacity];
+  }
+
+  private void reserve(int l) {
+    if (offset + l > data.length) {
+      int newSize = UnsynchronizedBuffer.nextArraySize(offset + l);
+
+      byte[] newData = new byte[newSize];
+      System.arraycopy(data, 0, newData, 0, offset);
+      data = newData;
+    }
+
+  }
+
+  /**
+   * Adds bytes to this writer's buffer.
+   *
+   * @param bytes byte array
+   * @param off offset into array to start copying bytes
+   * @param length number of bytes to add
+   * @throws IndexOutOfBoundsException if off or length are invalid
+   */
+  public void write(byte[] bytes, int off, int length) {
+    reserve(length);
+    System.arraycopy(bytes, off, data, offset, length);
+    offset += length;
+  }
+
+  @Override public void write(int b) throws IOException {
+    reserve(1);
+    data[offset] = (byte) b;
+    offset++;
+  }
+
+  /**
+   * Gets (a copy of) the contents of this writer's buffer.
+   *
+   * @return byte buffer contents
+   */
+  public byte[] toArray() {
+    byte[] ret = new byte[offset];
+    System.arraycopy(data, 0, ret, 0, offset);
+    return ret;
+  }
+
+  /**
+   * Resets the internal pointer into the buffer.
+   */
+  public void reset() {
+    offset = 0;
+    if (data.length >= LARGE_BUFFER_SIZE) {
+      data = new byte[this.initialCapacity];
+    }
+  }
+
+  /**
+   * @return The current offset into the backing array.
+   */
+  public int getOffset() {
+    return offset;
+  }
+
+  /**
+   * @return The current length of the backing array.
+   */
+  public long getSize() {
+    return data.length;
+  }
+
+  /**
+   * Determines what next array size should be by rounding up to next power of two.
+   *
+   * @param i current array size
+   * @return next array size
+   * @throws IllegalArgumentException if i is negative
+   */
+  public static int nextArraySize(int i) {
+    if (i < 0) {
+      throw new IllegalArgumentException();
+    }
+
+    if (i > (1 << 30)) {
+      return Integer.MAX_VALUE; // this is the next power of 2 minus one... a special case
+    }
+
+    if (i == 0) {
+      return 1;
+    }
+
+    // round up to next power of two
+    int ret = i;
+    ret--;
+    ret |= ret >> 1;
+    ret |= ret >> 2;
+    ret |= ret >> 4;
+    ret |= ret >> 8;
+    ret |= ret >> 16;
+    ret++;
+
+    return ret;
+  }
+}
+
+// End UnsynchronizedBuffer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/package-info.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/package-info.java
new file mode 100644
index 0000000..eab457c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * Avatica utilities.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.util;
+
+// End package-info.java


[40/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Common.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Common.java b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Common.java
new file mode 100644
index 0000000..7d5cef9
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Common.java
@@ -0,0 +1,17128 @@
+/*
+ * 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.
+ */
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: common.proto
+
+package org.apache.calcite.avatica.proto;
+
+@SuppressWarnings({"unused", "rawtypes"}) public final class Common {
+  private Common() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  /**
+   * Protobuf enum {@code StatementType}
+   *
+   * <pre>
+   * Has to be consistent with Meta.StatementType
+   * </pre>
+   */
+  public enum StatementType
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>SELECT = 0;</code>
+     */
+    SELECT(0, 0),
+    /**
+     * <code>INSERT = 1;</code>
+     */
+    INSERT(1, 1),
+    /**
+     * <code>UPDATE = 2;</code>
+     */
+    UPDATE(2, 2),
+    /**
+     * <code>DELETE = 3;</code>
+     */
+    DELETE(3, 3),
+    /**
+     * <code>UPSERT = 4;</code>
+     */
+    UPSERT(4, 4),
+    /**
+     * <code>MERGE = 5;</code>
+     */
+    MERGE(5, 5),
+    /**
+     * <code>OTHER_DML = 6;</code>
+     */
+    OTHER_DML(6, 6),
+    /**
+     * <code>CREATE = 7;</code>
+     */
+    CREATE(7, 7),
+    /**
+     * <code>DROP = 8;</code>
+     */
+    DROP(8, 8),
+    /**
+     * <code>ALTER = 9;</code>
+     */
+    ALTER(9, 9),
+    /**
+     * <code>OTHER_DDL = 10;</code>
+     */
+    OTHER_DDL(10, 10),
+    /**
+     * <code>CALL = 11;</code>
+     */
+    CALL(11, 11),
+    UNRECOGNIZED(-1, -1),
+    ;
+
+    /**
+     * <code>SELECT = 0;</code>
+     */
+    public static final int SELECT_VALUE = 0;
+    /**
+     * <code>INSERT = 1;</code>
+     */
+    public static final int INSERT_VALUE = 1;
+    /**
+     * <code>UPDATE = 2;</code>
+     */
+    public static final int UPDATE_VALUE = 2;
+    /**
+     * <code>DELETE = 3;</code>
+     */
+    public static final int DELETE_VALUE = 3;
+    /**
+     * <code>UPSERT = 4;</code>
+     */
+    public static final int UPSERT_VALUE = 4;
+    /**
+     * <code>MERGE = 5;</code>
+     */
+    public static final int MERGE_VALUE = 5;
+    /**
+     * <code>OTHER_DML = 6;</code>
+     */
+    public static final int OTHER_DML_VALUE = 6;
+    /**
+     * <code>CREATE = 7;</code>
+     */
+    public static final int CREATE_VALUE = 7;
+    /**
+     * <code>DROP = 8;</code>
+     */
+    public static final int DROP_VALUE = 8;
+    /**
+     * <code>ALTER = 9;</code>
+     */
+    public static final int ALTER_VALUE = 9;
+    /**
+     * <code>OTHER_DDL = 10;</code>
+     */
+    public static final int OTHER_DDL_VALUE = 10;
+    /**
+     * <code>CALL = 11;</code>
+     */
+    public static final int CALL_VALUE = 11;
+
+
+    public final int getNumber() {
+      if (index == -1) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    public static StatementType valueOf(int value) {
+      switch (value) {
+        case 0: return SELECT;
+        case 1: return INSERT;
+        case 2: return UPDATE;
+        case 3: return DELETE;
+        case 4: return UPSERT;
+        case 5: return MERGE;
+        case 6: return OTHER_DML;
+        case 7: return CREATE;
+        case 8: return DROP;
+        case 9: return ALTER;
+        case 10: return OTHER_DDL;
+        case 11: return CALL;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<StatementType>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        StatementType> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<StatementType>() {
+            public StatementType findValueByNumber(int number) {
+              return StatementType.valueOf(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(index);
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(0);
+    }
+
+    private static final StatementType[] VALUES = values();
+
+    public static StatementType valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int index;
+    private final int value;
+
+    private StatementType(int index, int value) {
+      this.index = index;
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:StatementType)
+  }
+
+  /**
+   * Protobuf enum {@code Rep}
+   */
+  public enum Rep
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>PRIMITIVE_BOOLEAN = 0;</code>
+     */
+    PRIMITIVE_BOOLEAN(0, 0),
+    /**
+     * <code>PRIMITIVE_BYTE = 1;</code>
+     */
+    PRIMITIVE_BYTE(1, 1),
+    /**
+     * <code>PRIMITIVE_CHAR = 2;</code>
+     */
+    PRIMITIVE_CHAR(2, 2),
+    /**
+     * <code>PRIMITIVE_SHORT = 3;</code>
+     */
+    PRIMITIVE_SHORT(3, 3),
+    /**
+     * <code>PRIMITIVE_INT = 4;</code>
+     */
+    PRIMITIVE_INT(4, 4),
+    /**
+     * <code>PRIMITIVE_LONG = 5;</code>
+     */
+    PRIMITIVE_LONG(5, 5),
+    /**
+     * <code>PRIMITIVE_FLOAT = 6;</code>
+     */
+    PRIMITIVE_FLOAT(6, 6),
+    /**
+     * <code>PRIMITIVE_DOUBLE = 7;</code>
+     */
+    PRIMITIVE_DOUBLE(7, 7),
+    /**
+     * <code>BOOLEAN = 8;</code>
+     */
+    BOOLEAN(8, 8),
+    /**
+     * <code>BYTE = 9;</code>
+     */
+    BYTE(9, 9),
+    /**
+     * <code>CHARACTER = 10;</code>
+     */
+    CHARACTER(10, 10),
+    /**
+     * <code>SHORT = 11;</code>
+     */
+    SHORT(11, 11),
+    /**
+     * <code>INTEGER = 12;</code>
+     */
+    INTEGER(12, 12),
+    /**
+     * <code>LONG = 13;</code>
+     */
+    LONG(13, 13),
+    /**
+     * <code>FLOAT = 14;</code>
+     */
+    FLOAT(14, 14),
+    /**
+     * <code>DOUBLE = 15;</code>
+     */
+    DOUBLE(15, 15),
+    /**
+     * <code>BIG_INTEGER = 25;</code>
+     */
+    BIG_INTEGER(16, 25),
+    /**
+     * <code>BIG_DECIMAL = 26;</code>
+     */
+    BIG_DECIMAL(17, 26),
+    /**
+     * <code>JAVA_SQL_TIME = 16;</code>
+     */
+    JAVA_SQL_TIME(18, 16),
+    /**
+     * <code>JAVA_SQL_TIMESTAMP = 17;</code>
+     */
+    JAVA_SQL_TIMESTAMP(19, 17),
+    /**
+     * <code>JAVA_SQL_DATE = 18;</code>
+     */
+    JAVA_SQL_DATE(20, 18),
+    /**
+     * <code>JAVA_UTIL_DATE = 19;</code>
+     */
+    JAVA_UTIL_DATE(21, 19),
+    /**
+     * <code>BYTE_STRING = 20;</code>
+     */
+    BYTE_STRING(22, 20),
+    /**
+     * <code>STRING = 21;</code>
+     */
+    STRING(23, 21),
+    /**
+     * <code>NUMBER = 22;</code>
+     */
+    NUMBER(24, 22),
+    /**
+     * <code>OBJECT = 23;</code>
+     */
+    OBJECT(25, 23),
+    /**
+     * <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),
+    ;
+
+    /**
+     * <code>PRIMITIVE_BOOLEAN = 0;</code>
+     */
+    public static final int PRIMITIVE_BOOLEAN_VALUE = 0;
+    /**
+     * <code>PRIMITIVE_BYTE = 1;</code>
+     */
+    public static final int PRIMITIVE_BYTE_VALUE = 1;
+    /**
+     * <code>PRIMITIVE_CHAR = 2;</code>
+     */
+    public static final int PRIMITIVE_CHAR_VALUE = 2;
+    /**
+     * <code>PRIMITIVE_SHORT = 3;</code>
+     */
+    public static final int PRIMITIVE_SHORT_VALUE = 3;
+    /**
+     * <code>PRIMITIVE_INT = 4;</code>
+     */
+    public static final int PRIMITIVE_INT_VALUE = 4;
+    /**
+     * <code>PRIMITIVE_LONG = 5;</code>
+     */
+    public static final int PRIMITIVE_LONG_VALUE = 5;
+    /**
+     * <code>PRIMITIVE_FLOAT = 6;</code>
+     */
+    public static final int PRIMITIVE_FLOAT_VALUE = 6;
+    /**
+     * <code>PRIMITIVE_DOUBLE = 7;</code>
+     */
+    public static final int PRIMITIVE_DOUBLE_VALUE = 7;
+    /**
+     * <code>BOOLEAN = 8;</code>
+     */
+    public static final int BOOLEAN_VALUE = 8;
+    /**
+     * <code>BYTE = 9;</code>
+     */
+    public static final int BYTE_VALUE = 9;
+    /**
+     * <code>CHARACTER = 10;</code>
+     */
+    public static final int CHARACTER_VALUE = 10;
+    /**
+     * <code>SHORT = 11;</code>
+     */
+    public static final int SHORT_VALUE = 11;
+    /**
+     * <code>INTEGER = 12;</code>
+     */
+    public static final int INTEGER_VALUE = 12;
+    /**
+     * <code>LONG = 13;</code>
+     */
+    public static final int LONG_VALUE = 13;
+    /**
+     * <code>FLOAT = 14;</code>
+     */
+    public static final int FLOAT_VALUE = 14;
+    /**
+     * <code>DOUBLE = 15;</code>
+     */
+    public static final int DOUBLE_VALUE = 15;
+    /**
+     * <code>BIG_INTEGER = 25;</code>
+     */
+    public static final int BIG_INTEGER_VALUE = 25;
+    /**
+     * <code>BIG_DECIMAL = 26;</code>
+     */
+    public static final int BIG_DECIMAL_VALUE = 26;
+    /**
+     * <code>JAVA_SQL_TIME = 16;</code>
+     */
+    public static final int JAVA_SQL_TIME_VALUE = 16;
+    /**
+     * <code>JAVA_SQL_TIMESTAMP = 17;</code>
+     */
+    public static final int JAVA_SQL_TIMESTAMP_VALUE = 17;
+    /**
+     * <code>JAVA_SQL_DATE = 18;</code>
+     */
+    public static final int JAVA_SQL_DATE_VALUE = 18;
+    /**
+     * <code>JAVA_UTIL_DATE = 19;</code>
+     */
+    public static final int JAVA_UTIL_DATE_VALUE = 19;
+    /**
+     * <code>BYTE_STRING = 20;</code>
+     */
+    public static final int BYTE_STRING_VALUE = 20;
+    /**
+     * <code>STRING = 21;</code>
+     */
+    public static final int STRING_VALUE = 21;
+    /**
+     * <code>NUMBER = 22;</code>
+     */
+    public static final int NUMBER_VALUE = 22;
+    /**
+     * <code>OBJECT = 23;</code>
+     */
+    public static final int OBJECT_VALUE = 23;
+    /**
+     * <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() {
+      if (index == -1) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    public static Rep valueOf(int value) {
+      switch (value) {
+        case 0: return PRIMITIVE_BOOLEAN;
+        case 1: return PRIMITIVE_BYTE;
+        case 2: return PRIMITIVE_CHAR;
+        case 3: return PRIMITIVE_SHORT;
+        case 4: return PRIMITIVE_INT;
+        case 5: return PRIMITIVE_LONG;
+        case 6: return PRIMITIVE_FLOAT;
+        case 7: return PRIMITIVE_DOUBLE;
+        case 8: return BOOLEAN;
+        case 9: return BYTE;
+        case 10: return CHARACTER;
+        case 11: return SHORT;
+        case 12: return INTEGER;
+        case 13: return LONG;
+        case 14: return FLOAT;
+        case 15: return DOUBLE;
+        case 25: return BIG_INTEGER;
+        case 26: return BIG_DECIMAL;
+        case 16: return JAVA_SQL_TIME;
+        case 17: return JAVA_SQL_TIMESTAMP;
+        case 18: return JAVA_SQL_DATE;
+        case 19: return JAVA_UTIL_DATE;
+        case 20: return BYTE_STRING;
+        case 21: return STRING;
+        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;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<Rep>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        Rep> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<Rep>() {
+            public Rep findValueByNumber(int number) {
+              return Rep.valueOf(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(index);
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(1);
+    }
+
+    private static final Rep[] VALUES = values();
+
+    public static Rep valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int index;
+    private final int value;
+
+    private Rep(int index, int value) {
+      this.index = index;
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:Rep)
+  }
+
+  /**
+   * Protobuf enum {@code Severity}
+   *
+   * <pre>
+   * The severity of some unexpected outcome to an operation.
+   * Protobuf enum values must be unique across all other enums
+   * </pre>
+   */
+  public enum Severity
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>UNKNOWN_SEVERITY = 0;</code>
+     */
+    UNKNOWN_SEVERITY(0, 0),
+    /**
+     * <code>FATAL_SEVERITY = 1;</code>
+     */
+    FATAL_SEVERITY(1, 1),
+    /**
+     * <code>ERROR_SEVERITY = 2;</code>
+     */
+    ERROR_SEVERITY(2, 2),
+    /**
+     * <code>WARNING_SEVERITY = 3;</code>
+     */
+    WARNING_SEVERITY(3, 3),
+    UNRECOGNIZED(-1, -1),
+    ;
+
+    /**
+     * <code>UNKNOWN_SEVERITY = 0;</code>
+     */
+    public static final int UNKNOWN_SEVERITY_VALUE = 0;
+    /**
+     * <code>FATAL_SEVERITY = 1;</code>
+     */
+    public static final int FATAL_SEVERITY_VALUE = 1;
+    /**
+     * <code>ERROR_SEVERITY = 2;</code>
+     */
+    public static final int ERROR_SEVERITY_VALUE = 2;
+    /**
+     * <code>WARNING_SEVERITY = 3;</code>
+     */
+    public static final int WARNING_SEVERITY_VALUE = 3;
+
+
+    public final int getNumber() {
+      if (index == -1) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    public static Severity valueOf(int value) {
+      switch (value) {
+        case 0: return UNKNOWN_SEVERITY;
+        case 1: return FATAL_SEVERITY;
+        case 2: return ERROR_SEVERITY;
+        case 3: return WARNING_SEVERITY;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<Severity>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        Severity> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<Severity>() {
+            public Severity findValueByNumber(int number) {
+              return Severity.valueOf(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(index);
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(2);
+    }
+
+    private static final Severity[] VALUES = values();
+
+    public static Severity valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int index;
+    private final int value;
+
+    private Severity(int index, int value) {
+      this.index = index;
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:Severity)
+  }
+
+  /**
+   * Protobuf enum {@code MetaDataOperation}
+   *
+   * <pre>
+   * Enumeration corresponding to DatabaseMetaData operations
+   * </pre>
+   */
+  public enum MetaDataOperation
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>GET_ATTRIBUTES = 0;</code>
+     */
+    GET_ATTRIBUTES(0, 0),
+    /**
+     * <code>GET_BEST_ROW_IDENTIFIER = 1;</code>
+     */
+    GET_BEST_ROW_IDENTIFIER(1, 1),
+    /**
+     * <code>GET_CATALOGS = 2;</code>
+     */
+    GET_CATALOGS(2, 2),
+    /**
+     * <code>GET_CLIENT_INFO_PROPERTIES = 3;</code>
+     */
+    GET_CLIENT_INFO_PROPERTIES(3, 3),
+    /**
+     * <code>GET_COLUMN_PRIVILEGES = 4;</code>
+     */
+    GET_COLUMN_PRIVILEGES(4, 4),
+    /**
+     * <code>GET_COLUMNS = 5;</code>
+     */
+    GET_COLUMNS(5, 5),
+    /**
+     * <code>GET_CROSS_REFERENCE = 6;</code>
+     */
+    GET_CROSS_REFERENCE(6, 6),
+    /**
+     * <code>GET_EXPORTED_KEYS = 7;</code>
+     */
+    GET_EXPORTED_KEYS(7, 7),
+    /**
+     * <code>GET_FUNCTION_COLUMNS = 8;</code>
+     */
+    GET_FUNCTION_COLUMNS(8, 8),
+    /**
+     * <code>GET_FUNCTIONS = 9;</code>
+     */
+    GET_FUNCTIONS(9, 9),
+    /**
+     * <code>GET_IMPORTED_KEYS = 10;</code>
+     */
+    GET_IMPORTED_KEYS(10, 10),
+    /**
+     * <code>GET_INDEX_INFO = 11;</code>
+     */
+    GET_INDEX_INFO(11, 11),
+    /**
+     * <code>GET_PRIMARY_KEYS = 12;</code>
+     */
+    GET_PRIMARY_KEYS(12, 12),
+    /**
+     * <code>GET_PROCEDURE_COLUMNS = 13;</code>
+     */
+    GET_PROCEDURE_COLUMNS(13, 13),
+    /**
+     * <code>GET_PROCEDURES = 14;</code>
+     */
+    GET_PROCEDURES(14, 14),
+    /**
+     * <code>GET_PSEUDO_COLUMNS = 15;</code>
+     */
+    GET_PSEUDO_COLUMNS(15, 15),
+    /**
+     * <code>GET_SCHEMAS = 16;</code>
+     */
+    GET_SCHEMAS(16, 16),
+    /**
+     * <code>GET_SCHEMAS_WITH_ARGS = 17;</code>
+     */
+    GET_SCHEMAS_WITH_ARGS(17, 17),
+    /**
+     * <code>GET_SUPER_TABLES = 18;</code>
+     */
+    GET_SUPER_TABLES(18, 18),
+    /**
+     * <code>GET_SUPER_TYPES = 19;</code>
+     */
+    GET_SUPER_TYPES(19, 19),
+    /**
+     * <code>GET_TABLE_PRIVILEGES = 20;</code>
+     */
+    GET_TABLE_PRIVILEGES(20, 20),
+    /**
+     * <code>GET_TABLES = 21;</code>
+     */
+    GET_TABLES(21, 21),
+    /**
+     * <code>GET_TABLE_TYPES = 22;</code>
+     */
+    GET_TABLE_TYPES(22, 22),
+    /**
+     * <code>GET_TYPE_INFO = 23;</code>
+     */
+    GET_TYPE_INFO(23, 23),
+    /**
+     * <code>GET_UDTS = 24;</code>
+     */
+    GET_UDTS(24, 24),
+    /**
+     * <code>GET_VERSION_COLUMNS = 25;</code>
+     */
+    GET_VERSION_COLUMNS(25, 25),
+    UNRECOGNIZED(-1, -1),
+    ;
+
+    /**
+     * <code>GET_ATTRIBUTES = 0;</code>
+     */
+    public static final int GET_ATTRIBUTES_VALUE = 0;
+    /**
+     * <code>GET_BEST_ROW_IDENTIFIER = 1;</code>
+     */
+    public static final int GET_BEST_ROW_IDENTIFIER_VALUE = 1;
+    /**
+     * <code>GET_CATALOGS = 2;</code>
+     */
+    public static final int GET_CATALOGS_VALUE = 2;
+    /**
+     * <code>GET_CLIENT_INFO_PROPERTIES = 3;</code>
+     */
+    public static final int GET_CLIENT_INFO_PROPERTIES_VALUE = 3;
+    /**
+     * <code>GET_COLUMN_PRIVILEGES = 4;</code>
+     */
+    public static final int GET_COLUMN_PRIVILEGES_VALUE = 4;
+    /**
+     * <code>GET_COLUMNS = 5;</code>
+     */
+    public static final int GET_COLUMNS_VALUE = 5;
+    /**
+     * <code>GET_CROSS_REFERENCE = 6;</code>
+     */
+    public static final int GET_CROSS_REFERENCE_VALUE = 6;
+    /**
+     * <code>GET_EXPORTED_KEYS = 7;</code>
+     */
+    public static final int GET_EXPORTED_KEYS_VALUE = 7;
+    /**
+     * <code>GET_FUNCTION_COLUMNS = 8;</code>
+     */
+    public static final int GET_FUNCTION_COLUMNS_VALUE = 8;
+    /**
+     * <code>GET_FUNCTIONS = 9;</code>
+     */
+    public static final int GET_FUNCTIONS_VALUE = 9;
+    /**
+     * <code>GET_IMPORTED_KEYS = 10;</code>
+     */
+    public static final int GET_IMPORTED_KEYS_VALUE = 10;
+    /**
+     * <code>GET_INDEX_INFO = 11;</code>
+     */
+    public static final int GET_INDEX_INFO_VALUE = 11;
+    /**
+     * <code>GET_PRIMARY_KEYS = 12;</code>
+     */
+    public static final int GET_PRIMARY_KEYS_VALUE = 12;
+    /**
+     * <code>GET_PROCEDURE_COLUMNS = 13;</code>
+     */
+    public static final int GET_PROCEDURE_COLUMNS_VALUE = 13;
+    /**
+     * <code>GET_PROCEDURES = 14;</code>
+     */
+    public static final int GET_PROCEDURES_VALUE = 14;
+    /**
+     * <code>GET_PSEUDO_COLUMNS = 15;</code>
+     */
+    public static final int GET_PSEUDO_COLUMNS_VALUE = 15;
+    /**
+     * <code>GET_SCHEMAS = 16;</code>
+     */
+    public static final int GET_SCHEMAS_VALUE = 16;
+    /**
+     * <code>GET_SCHEMAS_WITH_ARGS = 17;</code>
+     */
+    public static final int GET_SCHEMAS_WITH_ARGS_VALUE = 17;
+    /**
+     * <code>GET_SUPER_TABLES = 18;</code>
+     */
+    public static final int GET_SUPER_TABLES_VALUE = 18;
+    /**
+     * <code>GET_SUPER_TYPES = 19;</code>
+     */
+    public static final int GET_SUPER_TYPES_VALUE = 19;
+    /**
+     * <code>GET_TABLE_PRIVILEGES = 20;</code>
+     */
+    public static final int GET_TABLE_PRIVILEGES_VALUE = 20;
+    /**
+     * <code>GET_TABLES = 21;</code>
+     */
+    public static final int GET_TABLES_VALUE = 21;
+    /**
+     * <code>GET_TABLE_TYPES = 22;</code>
+     */
+    public static final int GET_TABLE_TYPES_VALUE = 22;
+    /**
+     * <code>GET_TYPE_INFO = 23;</code>
+     */
+    public static final int GET_TYPE_INFO_VALUE = 23;
+    /**
+     * <code>GET_UDTS = 24;</code>
+     */
+    public static final int GET_UDTS_VALUE = 24;
+    /**
+     * <code>GET_VERSION_COLUMNS = 25;</code>
+     */
+    public static final int GET_VERSION_COLUMNS_VALUE = 25;
+
+
+    public final int getNumber() {
+      if (index == -1) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    public static MetaDataOperation valueOf(int value) {
+      switch (value) {
+        case 0: return GET_ATTRIBUTES;
+        case 1: return GET_BEST_ROW_IDENTIFIER;
+        case 2: return GET_CATALOGS;
+        case 3: return GET_CLIENT_INFO_PROPERTIES;
+        case 4: return GET_COLUMN_PRIVILEGES;
+        case 5: return GET_COLUMNS;
+        case 6: return GET_CROSS_REFERENCE;
+        case 7: return GET_EXPORTED_KEYS;
+        case 8: return GET_FUNCTION_COLUMNS;
+        case 9: return GET_FUNCTIONS;
+        case 10: return GET_IMPORTED_KEYS;
+        case 11: return GET_INDEX_INFO;
+        case 12: return GET_PRIMARY_KEYS;
+        case 13: return GET_PROCEDURE_COLUMNS;
+        case 14: return GET_PROCEDURES;
+        case 15: return GET_PSEUDO_COLUMNS;
+        case 16: return GET_SCHEMAS;
+        case 17: return GET_SCHEMAS_WITH_ARGS;
+        case 18: return GET_SUPER_TABLES;
+        case 19: return GET_SUPER_TYPES;
+        case 20: return GET_TABLE_PRIVILEGES;
+        case 21: return GET_TABLES;
+        case 22: return GET_TABLE_TYPES;
+        case 23: return GET_TYPE_INFO;
+        case 24: return GET_UDTS;
+        case 25: return GET_VERSION_COLUMNS;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<MetaDataOperation>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        MetaDataOperation> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<MetaDataOperation>() {
+            public MetaDataOperation findValueByNumber(int number) {
+              return MetaDataOperation.valueOf(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(index);
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(3);
+    }
+
+    private static final MetaDataOperation[] VALUES = values();
+
+    public static MetaDataOperation valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int index;
+    private final int value;
+
+    private MetaDataOperation(int index, int value) {
+      this.index = index;
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:MetaDataOperation)
+  }
+
+  /**
+   * Protobuf enum {@code StateType}
+   */
+  public enum StateType
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>SQL = 0;</code>
+     */
+    SQL(0, 0),
+    /**
+     * <code>METADATA = 1;</code>
+     */
+    METADATA(1, 1),
+    UNRECOGNIZED(-1, -1),
+    ;
+
+    /**
+     * <code>SQL = 0;</code>
+     */
+    public static final int SQL_VALUE = 0;
+    /**
+     * <code>METADATA = 1;</code>
+     */
+    public static final int METADATA_VALUE = 1;
+
+
+    public final int getNumber() {
+      if (index == -1) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    public static StateType valueOf(int value) {
+      switch (value) {
+        case 0: return SQL;
+        case 1: return METADATA;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<StateType>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        StateType> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<StateType>() {
+            public StateType findValueByNumber(int number) {
+              return StateType.valueOf(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(index);
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(4);
+    }
+
+    private static final StateType[] VALUES = values();
+
+    public static StateType valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int index;
+    private final int value;
+
+    private StateType(int index, int value) {
+      this.index = index;
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:StateType)
+  }
+
+  public interface ConnectionPropertiesOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:ConnectionProperties)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional bool is_dirty = 1;</code>
+     */
+    boolean getIsDirty();
+
+    /**
+     * <code>optional bool auto_commit = 2;</code>
+     */
+    boolean getAutoCommit();
+
+    /**
+     * <code>optional bool has_auto_commit = 7;</code>
+     *
+     * <pre>
+     * field is a Boolean, need to discern null and default value
+     * </pre>
+     */
+    boolean getHasAutoCommit();
+
+    /**
+     * <code>optional bool read_only = 3;</code>
+     */
+    boolean getReadOnly();
+
+    /**
+     * <code>optional bool has_read_only = 8;</code>
+     *
+     * <pre>
+     * field is a Boolean, need to discern null and default value
+     * </pre>
+     */
+    boolean getHasReadOnly();
+
+    /**
+     * <code>optional uint32 transaction_isolation = 4;</code>
+     */
+    int getTransactionIsolation();
+
+    /**
+     * <code>optional string catalog = 5;</code>
+     */
+    java.lang.String getCatalog();
+    /**
+     * <code>optional string catalog = 5;</code>
+     */
+    com.google.protobuf.ByteString
+        getCatalogBytes();
+
+    /**
+     * <code>optional string schema = 6;</code>
+     */
+    java.lang.String getSchema();
+    /**
+     * <code>optional string schema = 6;</code>
+     */
+    com.google.protobuf.ByteString
+        getSchemaBytes();
+  }
+  /**
+   * Protobuf type {@code ConnectionProperties}
+   *
+   * <pre>
+   * Details about a connection
+   * </pre>
+   */
+  public  static final class ConnectionProperties extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:ConnectionProperties)
+      ConnectionPropertiesOrBuilder {
+    // Use ConnectionProperties.newBuilder() to construct.
+    private ConnectionProperties(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private ConnectionProperties() {
+      isDirty_ = false;
+      autoCommit_ = false;
+      hasAutoCommit_ = false;
+      readOnly_ = false;
+      hasReadOnly_ = false;
+      transactionIsolation_ = 0;
+      catalog_ = "";
+      schema_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private ConnectionProperties(
+        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: {
+
+              isDirty_ = input.readBool();
+              break;
+            }
+            case 16: {
+
+              autoCommit_ = input.readBool();
+              break;
+            }
+            case 24: {
+
+              readOnly_ = input.readBool();
+              break;
+            }
+            case 32: {
+
+              transactionIsolation_ = input.readUInt32();
+              break;
+            }
+            case 42: {
+              String s = input.readStringRequireUtf8();
+
+              catalog_ = s;
+              break;
+            }
+            case 50: {
+              String s = input.readStringRequireUtf8();
+
+              schema_ = s;
+              break;
+            }
+            case 56: {
+
+              hasAutoCommit_ = input.readBool();
+              break;
+            }
+            case 64: {
+
+              hasReadOnly_ = 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_ConnectionProperties_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Common.ConnectionProperties.class, org.apache.calcite.avatica.proto.Common.ConnectionProperties.Builder.class);
+    }
+
+    public static final int IS_DIRTY_FIELD_NUMBER = 1;
+    private boolean isDirty_;
+    /**
+     * <code>optional bool is_dirty = 1;</code>
+     */
+    public boolean getIsDirty() {
+      return isDirty_;
+    }
+
+    public static final int AUTO_COMMIT_FIELD_NUMBER = 2;
+    private boolean autoCommit_;
+    /**
+     * <code>optional bool auto_commit = 2;</code>
+     */
+    public boolean getAutoCommit() {
+      return autoCommit_;
+    }
+
+    public static final int HAS_AUTO_COMMIT_FIELD_NUMBER = 7;
+    private boolean hasAutoCommit_;
+    /**
+     * <code>optional bool has_auto_commit = 7;</code>
+     *
+     * <pre>
+     * field is a Boolean, need to discern null and default value
+     * </pre>
+     */
+    public boolean getHasAutoCommit() {
+      return hasAutoCommit_;
+    }
+
+    public static final int READ_ONLY_FIELD_NUMBER = 3;
+    private boolean readOnly_;
+    /**
+     * <code>optional bool read_only = 3;</code>
+     */
+    public boolean getReadOnly() {
+      return readOnly_;
+    }
+
+    public static final int HAS_READ_ONLY_FIELD_NUMBER = 8;
+    private boolean hasReadOnly_;
+    /**
+     * <code>optional bool has_read_only = 8;</code>
+     *
+     * <pre>
+     * field is a Boolean, need to discern null and default value
+     * </pre>
+     */
+    public boolean getHasReadOnly() {
+      return hasReadOnly_;
+    }
+
+    public static final int TRANSACTION_ISOLATION_FIELD_NUMBER = 4;
+    private int transactionIsolation_;
+    /**
+     * <code>optional uint32 transaction_isolation = 4;</code>
+     */
+    public int getTransactionIsolation() {
+      return transactionIsolation_;
+    }
+
+    public static final int CATALOG_FIELD_NUMBER = 5;
+    private volatile java.lang.Object catalog_;
+    /**
+     * <code>optional string catalog = 5;</code>
+     */
+    public java.lang.String getCatalog() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        catalog_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string catalog = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getCatalogBytes() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        catalog_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int SCHEMA_FIELD_NUMBER = 6;
+    private volatile java.lang.Object schema_;
+    /**
+     * <code>optional string schema = 6;</code>
+     */
+    public java.lang.String getSchema() {
+      java.lang.Object ref = schema_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        schema_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string schema = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getSchemaBytes() {
+      java.lang.Object ref = schema_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        schema_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 {
+      if (isDirty_ != false) {
+        output.writeBool(1, isDirty_);
+      }
+      if (autoCommit_ != false) {
+        output.writeBool(2, autoCommit_);
+      }
+      if (readOnly_ != false) {
+        output.writeBool(3, readOnly_);
+      }
+      if (transactionIsolation_ != 0) {
+        output.writeUInt32(4, transactionIsolation_);
+      }
+      if (!getCatalogBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 5, catalog_);
+      }
+      if (!getSchemaBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 6, schema_);
+      }
+      if (hasAutoCommit_ != false) {
+        output.writeBool(7, hasAutoCommit_);
+      }
+      if (hasReadOnly_ != false) {
+        output.writeBool(8, hasReadOnly_);
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (isDirty_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(1, isDirty_);
+      }
+      if (autoCommit_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(2, autoCommit_);
+      }
+      if (readOnly_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(3, readOnly_);
+      }
+      if (transactionIsolation_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(4, transactionIsolation_);
+      }
+      if (!getCatalogBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(5, catalog_);
+      }
+      if (!getSchemaBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(6, schema_);
+      }
+      if (hasAutoCommit_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(7, hasAutoCommit_);
+      }
+      if (hasReadOnly_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(8, hasReadOnly_);
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties 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 ConnectionProperties}
+     *
+     * <pre>
+     * Details about a connection
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:ConnectionProperties)
+        org.apache.calcite.avatica.proto.Common.ConnectionPropertiesOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Common.ConnectionProperties.class, org.apache.calcite.avatica.proto.Common.ConnectionProperties.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Common.ConnectionProperties.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        isDirty_ = false;
+
+        autoCommit_ = false;
+
+        hasAutoCommit_ = false;
+
+        readOnly_ = false;
+
+        hasReadOnly_ = false;
+
+        transactionIsolation_ = 0;
+
+        catalog_ = "";
+
+        schema_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Common.ConnectionProperties.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ConnectionProperties build() {
+        org.apache.calcite.avatica.proto.Common.ConnectionProperties result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.ConnectionProperties buildPartial() {
+        org.apache.calcite.avatica.proto.Common.ConnectionProperties result = new org.apache.calcite.avatica.proto.Common.ConnectionProperties(this);
+        result.isDirty_ = isDirty_;
+        result.autoCommit_ = autoCommit_;
+        result.hasAutoCommit_ = hasAutoCommit_;
+        result.readOnly_ = readOnly_;
+        result.hasReadOnly_ = hasReadOnly_;
+        result.transactionIsolation_ = transactionIsolation_;
+        result.catalog_ = catalog_;
+        result.schema_ = schema_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Common.ConnectionProperties) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Common.ConnectionProperties)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Common.ConnectionProperties other) {
+        if (other == org.apache.calcite.avatica.proto.Common.ConnectionProperties.getDefaultInstance()) return this;
+        if (other.getIsDirty() != false) {
+          setIsDirty(other.getIsDirty());
+        }
+        if (other.getAutoCommit() != false) {
+          setAutoCommit(other.getAutoCommit());
+        }
+        if (other.getHasAutoCommit() != false) {
+          setHasAutoCommit(other.getHasAutoCommit());
+        }
+        if (other.getReadOnly() != false) {
+          setReadOnly(other.getReadOnly());
+        }
+        if (other.getHasReadOnly() != false) {
+          setHasReadOnly(other.getHasReadOnly());
+        }
+        if (other.getTransactionIsolation() != 0) {
+          setTransactionIsolation(other.getTransactionIsolation());
+        }
+        if (!other.getCatalog().isEmpty()) {
+          catalog_ = other.catalog_;
+          onChanged();
+        }
+        if (!other.getSchema().isEmpty()) {
+          schema_ = other.schema_;
+          onChanged();
+        }
+        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.ConnectionProperties parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Common.ConnectionProperties) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private boolean isDirty_ ;
+      /**
+       * <code>optional bool is_dirty = 1;</code>
+       */
+      public boolean getIsDirty() {
+        return isDirty_;
+      }
+      /**
+       * <code>optional bool is_dirty = 1;</code>
+       */
+      public Builder setIsDirty(boolean value) {
+        
+        isDirty_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool is_dirty = 1;</code>
+       */
+      public Builder clearIsDirty() {
+        
+        isDirty_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean autoCommit_ ;
+      /**
+       * <code>optional bool auto_commit = 2;</code>
+       */
+      public boolean getAutoCommit() {
+        return autoCommit_;
+      }
+      /**
+       * <code>optional bool auto_commit = 2;</code>
+       */
+      public Builder setAutoCommit(boolean value) {
+        
+        autoCommit_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool auto_commit = 2;</code>
+       */
+      public Builder clearAutoCommit() {
+        
+        autoCommit_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean hasAutoCommit_ ;
+      /**
+       * <code>optional bool has_auto_commit = 7;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public boolean getHasAutoCommit() {
+        return hasAutoCommit_;
+      }
+      /**
+       * <code>optional bool has_auto_commit = 7;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public Builder setHasAutoCommit(boolean value) {
+        
+        hasAutoCommit_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool has_auto_commit = 7;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public Builder clearHasAutoCommit() {
+        
+        hasAutoCommit_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean readOnly_ ;
+      /**
+       * <code>optional bool read_only = 3;</code>
+       */
+      public boolean getReadOnly() {
+        return readOnly_;
+      }
+      /**
+       * <code>optional bool read_only = 3;</code>
+       */
+      public Builder setReadOnly(boolean value) {
+        
+        readOnly_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool read_only = 3;</code>
+       */
+      public Builder clearReadOnly() {
+        
+        readOnly_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean hasReadOnly_ ;
+      /**
+       * <code>optional bool has_read_only = 8;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public boolean getHasReadOnly() {
+        return hasReadOnly_;
+      }
+      /**
+       * <code>optional bool has_read_only = 8;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public Builder setHasReadOnly(boolean value) {
+        
+        hasReadOnly_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool has_read_only = 8;</code>
+       *
+       * <pre>
+       * field is a Boolean, need to discern null and default value
+       * </pre>
+       */
+      public Builder clearHasReadOnly() {
+        
+        hasReadOnly_ = false;
+        onChanged();
+        return this;
+      }
+
+      private int transactionIsolation_ ;
+      /**
+       * <code>optional uint32 transaction_isolation = 4;</code>
+       */
+      public int getTransactionIsolation() {
+        return transactionIsolation_;
+      }
+      /**
+       * <code>optional uint32 transaction_isolation = 4;</code>
+       */
+      public Builder setTransactionIsolation(int value) {
+        
+        transactionIsolation_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional uint32 transaction_isolation = 4;</code>
+       */
+      public Builder clearTransactionIsolation() {
+        
+        transactionIsolation_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object catalog_ = "";
+      /**
+       * <code>optional string catalog = 5;</code>
+       */
+      public java.lang.String getCatalog() {
+        java.lang.Object ref = catalog_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          catalog_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 5;</code>
+       */
+      public com.google.protobuf.ByteString
+          getCatalogBytes() {
+        java.lang.Object ref = catalog_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          catalog_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 5;</code>
+       */
+      public Builder setCatalog(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 5;</code>
+       */
+      public Builder clearCatalog() {
+        
+        catalog_ = getDefaultInstance().getCatalog();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 5;</code>
+       */
+      public Builder setCatalogBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object schema_ = "";
+      /**
+       * <code>optional string schema = 6;</code>
+       */
+      public java.lang.String getSchema() {
+        java.lang.Object ref = schema_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          schema_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string schema = 6;</code>
+       */
+      public com.google.protobuf.ByteString
+          getSchemaBytes() {
+        java.lang.Object ref = schema_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          schema_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string schema = 6;</code>
+       */
+      public Builder setSchema(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        schema_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema = 6;</code>
+       */
+      public Builder clearSchema() {
+        
+        schema_ = getDefaultInstance().getSchema();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema = 6;</code>
+       */
+      public Builder setSchemaBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        schema_ = value;
+        onChanged();
+        return this;
+      }
+      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:ConnectionProperties)
+    }
+
+    // @@protoc_insertion_point(class_scope:ConnectionProperties)
+    private static final org.apache.calcite.avatica.proto.Common.ConnectionProperties DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Common.ConnectionProperties();
+    }
+
+    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<ConnectionProperties>
+        PARSER = new com.google.protobuf.AbstractParser<ConnectionProperties>() {
+      public ConnectionProperties parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new ConnectionProperties(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<ConnectionProperties> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ConnectionProperties> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface StatementHandleOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:StatementHandle)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+
+    /**
+     * <code>optional uint32 id = 2;</code>
+     */
+    int getId();
+
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    boolean hasSignature();
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.Signature getSignature();
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder();
+  }
+  /**
+   * Protobuf type {@code StatementHandle}
+   *
+   * <pre>
+   * Statement handle
+   * </pre>
+   */
+  public  static final class StatementHandle extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:StatementHandle)
+      StatementHandleOrBuilder {
+    // Use StatementHandle.newBuilder() to construct.
+    private StatementHandle(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private StatementHandle() {
+      connectionId_ = "";
+      id_ = 0;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private StatementHandle(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              break;
+            }
+            case 16: {
+
+              id_ = input.readUInt32();
+              break;
+            }
+            case 26: {
+              org.apache.calcite.avatica.proto.Common.Signature.Builder subBuilder = null;
+              if (signature_ != null) {
+                subBuilder = signature_.toBuilder();
+              }
+              signature_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Signature.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(signature_);
+                signature_ = subBuilder.buildPartial();
+              }
+
+              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_StatementHandle_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Common.StatementHandle.class, org.apache.calcite.avatica.proto.Common.StatementHandle.Builder.class);
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int ID_FIELD_NUMBER = 2;
+    private int id_;
+    /**
+     * <code>optional uint32 id = 2;</code>
+     */
+    public int getId() {
+      return id_;
+    }
+
+    public static final int SIGNATURE_FIELD_NUMBER = 3;
+    private org.apache.calcite.avatica.proto.Common.Signature signature_;
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    public boolean hasSignature() {
+      return signature_ != null;
+    }
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
+      return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+    }
+    /**
+     * <code>optional .Signature signature = 3;</code>
+     */
+    public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
+      return getSignature();
+    }
+
+    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 {
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
+      }
+      if (id_ != 0) {
+        output.writeUInt32(2, id_);
+      }
+      if (signature_ != null) {
+        output.writeMessage(3, getSignature());
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
+      }
+      if (id_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(2, id_);
+      }
+      if (signature_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getSignature());
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle 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 StatementHandle}
+     *
+     * <pre>
+     * Statement handle
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:StatementHandle)
+        org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Common.StatementHandle.class, org.apache.calcite.avatica.proto.Common.StatementHandle.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Common.StatementHandle.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        connectionId_ = "";
+
+        id_ = 0;
+
+        if (signatureBuilder_ == null) {
+          signature_ = null;
+        } else {
+          signature_ = null;
+          signatureBuilder_ = null;
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Common.StatementHandle build() {
+        org.apache.calcite.avatica.proto.Common.StatementHandle result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Common.StatementHandle buildPartial() {
+        org.apache.calcite.avatica.proto.Common.StatementHandle result = new org.apache.calcite.avatica.proto.Common.StatementHandle(this);
+        result.connectionId_ = connectionId_;
+        result.id_ = id_;
+        if (signatureBuilder_ == null) {
+          result.signature_ = signature_;
+        } else {
+          result.signature_ = signatureBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Common.StatementHandle) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Common.StatementHandle)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Common.StatementHandle other) {
+        if (other == org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance()) return this;
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        if (other.getId() != 0) {
+          setId(other.getId());
+        }
+        if (other.hasSignature()) {
+          mergeSignature(other.getSignature());
+        }
+        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.StatementHandle parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Common.StatementHandle) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object connectionId_ = "";
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public java.lang.String getConnectionId() {
+        java.lang.Object ref = connectionId_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          connectionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getConnectionIdBytes() {
+        java.lang.Object ref = connectionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          connectionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder clearConnectionId() {
+        
+        connectionId_ = getDefaultInstance().getConnectionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+
+      private int id_ ;
+      /**
+       * <code>optional uint32 id = 2;</code>
+       */
+      public int getId() {
+        return id_;
+      }
+      /**
+       * <code>optional uint32 id = 2;</code>
+       */
+      public Builder setId(int value) {
+        
+        id_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional uint32 id = 2;</code>
+       */
+      public Builder clearId() {
+        
+        id_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private org.apache.calcite.avatica.proto.Common.Signature signature_ = null;
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> signatureBuilder_;
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public boolean hasSignature() {
+        return signatureBuilder_ != null || signature_ != null;
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
+        if (signatureBuilder_ == null) {
+          return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+        } else {
+          return signatureBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public Builder setSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
+        if (signatureBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          signature_ = value;
+          onChanged();
+        } else {
+          signatureBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public Builder setSignature(
+          org.apache.calcite.avatica.proto.Common.Signature.Builder builderForValue) {
+        if (signatureBuilder_ == null) {
+          signature_ = builderForValue.build();
+          onChanged();
+        } else {
+          signatureBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public Builder mergeSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
+        if (signatureBuilder_ == null) {
+          if (signature_ != null) {
+            signature_ =
+              org.apache.calcite.avatica.proto.Common.Signature.newBuilder(signature_).mergeFrom(value).buildPartial();
+          } else {
+            signature_ = value;
+          }
+          onChanged();
+        } else {
+          signatureBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public Builder clearSignature() {
+        if (signatureBuilder_ == null) {
+          signature_ = null;
+          onChanged();
+        } else {
+          signature_ = null;
+          signatureBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.Signature.Builder getSignatureBuilder() {
+        
+        onChanged();
+        return getSignatureFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
+        if (signatureBuilder_ != null) {
+          return signatureBuilder_.getMessageOrBuilder();
+        } else {
+          return signature_ == null ?
+              org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
+        }
+      }
+      /**
+       * <code>optional .Signature signature = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> 
+          getSignatureFieldBuilder() {
+        if (signatureBuilder_ == null) {
+          signatureBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder>(
+                  getSignature(),
+                  getParentForChildren(),
+                  isClean());
+          signature_ = null;
+        }
+        return signatureBuilder_;
+      }
+      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:StatementHandle)
+    }
+
+    // @@protoc_insertion_point(class_scope:StatementHandle)
+    private static final org.apache.calcite.avatica.proto.Common.StatementHandle DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Common.StatementHandle();
+    }
+
+    public static org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<StatementHandle>
+        PARSER = new com.google.protobuf.AbstractParser<StatementHandle>() {
+      public StatementHandle parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new StatementHandle(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<StatementHandle> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<StatementHandle> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SignatureOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:Signature)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .ColumnMetaData columns = 1;</code>
+     */
+    java.util.List<org.apache.calcite.avatica.proto.Common.ColumnMetaData> 
+        getColumnsList();
+    /**
+     * <code>repeated .ColumnMetaData columns = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.ColumnMetaData getColumns(int index);
+    /**
+     * <code>repeated .ColumnMetaData columns = 1;</code>
+     */
+    int getColumnsCount();
+    /**
+     * <code>repeated .ColumnMetaData columns = 1;</code>
+     */
+    java.util.List<? extends org.apache.calcite.avatica.proto.Common.ColumnMetaDataOrBuilder> 
+        getColumnsOrBuilderList();
+    /**
+     * <code>repeated .ColumnMetaData columns = 1;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.ColumnMetaDataOrBuilder getColumnsOrBuilder(
+        int index);
+
+    /**
+     * <code>optional string sql = 2;</code>
+     */
+    java.lang.String getSql();
+    /**
+     * <code>optional string sql = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getSqlBytes();
+
+    /**
+     * <code>repeated .AvaticaParameter parameters = 3;</code>
+     */
+    java.util.List<org.apache.calcite.avatica.proto.Common.AvaticaParameter> 
+        getParametersList();
+    /**
+     * <code>repeated .AvaticaParameter parameters = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.AvaticaParameter getParameters(int index);
+    /**
+     * <code>repeated .AvaticaParameter parameters = 3;</code>
+     */
+    int getParametersCount();
+    /**
+     * <code>repeated .AvaticaParameter parameters = 3;</code>
+     */
+    java.util.List<? extends org.apache.calcite.avatica.proto.Common.AvaticaParameterOrBuilder> 
+        getParametersOrBuilderList();
+    /**
+     * <code>repeated .AvaticaParameter parameters = 3;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.AvaticaParameterOrBuilder getParametersOrBuilder(
+        int index);
+
+    /**
+     * <code>optional .CursorFactory cursor_factory = 4;</code>
+     */
+    boolean hasCursorFactory();
+    /**
+     * <code>optional .CursorFactory cursor_factory = 4;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.CursorFactory getCursorFactory();
+    /**
+     * <code>optional .CursorFactory cursor_factory = 4;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.CursorFactoryOrBuilder getCursorFactoryOrBuilder();
+
+    /**
+     * <code>optional .StatementType statementType = 5;</code>
+     */
+    int getStatementTypeValue();
+    /**
+     * <code>optional .StatementType statementType = 5;</code>
+     */
+    org.apache.calcite.avatica.proto.Common.StatementType getStatementType();
+  }
+  /**
+   * Protobuf type {@code Signature}
+   *
+   * <pre>
+   * Results of preparing a statement
+   * </pre>
+   */
+  public  static final class Signature extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:Signature)
+      SignatureOrBuilder {
+    // Use Signature.newBuilder() to construct.
+    private Signature(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private Signature() {
+      columns_ = java.util.Collections.emptyList();
+      sql_ = "";
+      parameters_ = java.util.Collections.emptyList();
+      statementType_ = 0;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownF

<TRUNCATED>

[33/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/util/Base64.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/Base64.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Base64.java
new file mode 100644
index 0000000..f6af109
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/Base64.java
@@ -0,0 +1,2087 @@
+/*
+ * 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.util;
+
+//CHECKSTYLE: OFF
+
+/**
+ * <p>Encodes and decodes to and from Base64 notation.</p>
+ * <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
+ *
+ * <p>Example:</p>
+ *
+ * <code>String encoded = Base64.encode( myByteArray );</code>
+ * <br>
+ * <code>byte[] myByteArray = Base64.decode( encoded );</code>
+ *
+ * <p>The <tt>options</tt> parameter, which appears in a few places, is used to pass 
+ * several pieces of information to the encoder. In the "higher level" methods such as 
+ * encodeBytes( bytes, options ) the options parameter can be used to indicate such 
+ * things as first gzipping the bytes before encoding them, not inserting linefeeds,
+ * and encoding using the URL-safe and Ordered dialects.</p>
+ *
+ * <p>Note, according to <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>,
+ * Section 2.1, implementations should not add line feeds unless explicitly told
+ * to do so. I've got Base64 set to this behavior now, although earlier versions
+ * broke lines by default.</p>
+ *
+ * <p>The constants defined in Base64 can be OR-ed together to combine options, so you 
+ * might make a call like this:</p>
+ *
+ * <code>String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES );</code>
+ * <p>to compress the data before encoding it and then making the output have newline characters.</p>
+ * <p>Also...</p>
+ * <code>String encoded = Base64.encodeBytes( crazyString.getBytes() );</code>
+ *
+ *
+ *
+ * <p>
+ * Change Log:
+ * </p>
+ * <ul>
+ *  <li>v2.3.7 - Fixed subtle bug when base 64 input stream contained the
+ *   value 01111111, which is an invalid base 64 character but should not
+ *   throw an ArrayIndexOutOfBoundsException either. Led to discovery of
+ *   mishandling (or potential for better handling) of other bad input
+ *   characters. You should now get an IOException if you try decoding
+ *   something that has bad characters in it.</li>
+ *  <li>v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded
+ *   string ended in the last column; the buffer was not properly shrunk and
+ *   contained an extra (null) byte that made it into the string.</li>
+ *  <li>v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size
+ *   was wrong for files of size 31, 34, and 37 bytes.</li>
+ *  <li>v2.3.4 - Fixed bug when working with gzipped streams whereby flushing
+ *   the Base64.OutputStream closed the Base64 encoding (by padding with equals
+ *   signs) too soon. Also added an option to suppress the automatic decoding
+ *   of gzipped streams. Also added experimental support for specifying a
+ *   class loader when using the
+ *   {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)}
+ *   method.</li>
+ *  <li>v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java
+ *   footprint with its CharEncoders and so forth. Fixed some javadocs that were
+ *   inconsistent. Removed imports and specified things like java.io.IOException
+ *   explicitly inline.</li>
+ *  <li>v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the
+ *   final encoded data will be so that the code doesn't have to create two output
+ *   arrays: an oversized initial one and then a final, exact-sized one. Big win
+ *   when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not
+ *   using the gzip options which uses a different mechanism with streams and stuff).</li>
+ *  <li>v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some
+ *   similar helper methods to be more efficient with memory by not returning a
+ *   String but just a byte array.</li>
+ *  <li>v2.3 - <strong>This is not a drop-in replacement!</strong> This is two years of comments
+ *   and bug fixes queued up and finally executed. Thanks to everyone who sent
+ *   me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else.
+ *   Much bad coding was cleaned up including throwing exceptions where necessary 
+ *   instead of returning null values or something similar. Here are some changes
+ *   that may affect you:
+ *   <ul>
+ *    <li><em>Does not break lines, by default.</em> This is to keep in compliance with
+ *      <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>.</li>
+ *    <li><em>Throws exceptions instead of returning null values.</em> Because some operations
+ *      (especially those that may permit the GZIP option) use IO streams, there
+ *      is a possiblity of an java.io.IOException being thrown. After some discussion and
+ *      thought, I've changed the behavior of the methods to throw java.io.IOExceptions
+ *      rather than return null if ever there's an error. I think this is more
+ *      appropriate, though it will require some changes to your code. Sorry,
+ *      it should have been done this way to begin with.</li>
+ *    <li><em>Removed all references to System.out, System.err, and the like.</em>
+ *      Shame on me. All I can say is sorry they were ever there.</li>
+ *    <li><em>Throws NullPointerExceptions and IllegalArgumentExceptions</em> as needed
+ *      such as when passed arrays are null or offsets are invalid.</li>
+ *    <li>Cleaned up as much javadoc as I could to avoid any javadoc warnings.
+ *      This was especially annoying before for people who were thorough in their
+ *      own projects and then had gobs of javadoc warnings on this file.</li>
+ *   </ul>
+ *  <li>v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug
+ *   when using very small files (~&lt; 40 bytes).</li>
+ *  <li>v2.2 - Added some helper methods for encoding/decoding directly from
+ *   one file to the next. Also added a main() method to support command line
+ *   encoding/decoding from one file to the next. Also added these Base64 dialects:
+ *   <ol>
+ *   <li>The default is RFC3548 format.</li>
+ *   <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
+ *   URL and file name friendly format as described in Section 4 of RFC3548.
+ *   http://www.faqs.org/rfcs/rfc3548.html</li>
+ *   <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
+ *   URL and file name friendly format that preserves lexical ordering as described
+ *   in http://www.faqs.org/qa/rfcc-1940.html</li>
+ *   </ol>
+ *   Special thanks to Jim Kellerman at <a href="http://www.powerset.com/">http://www.powerset.com/</a>
+ *   for contributing the new Base64 dialects.
+ *  </li>
+ *
+ *  <li>v2.1 - Cleaned up javadoc comments and unused variables and methods. Added
+ *   some convenience methods for reading and writing to and from files.</li>
+ *  <li>v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems
+ *   with other encodings (like EBCDIC).</li>
+ *  <li>v2.0.1 - Fixed an error when decoding a single byte, that is, when the
+ *   encoded data was a single byte.</li>
+ *  <li>v2.0 - I got rid of methods that used booleans to set options. 
+ *   Now everything is more consolidated and cleaner. The code now detects
+ *   when data that's being decoded is gzip-compressed and will decompress it
+ *   automatically. Generally things are cleaner. You'll probably have to
+ *   change some method calls that you were making to support the new
+ *   options format (<tt>int</tt>s that you "OR" together).</li>
+ *  <li>v1.5.1 - Fixed bug when decompressing and decoding to a             
+ *   byte[] using <tt>decode( String s, boolean gzipCompressed )</tt>.      
+ *   Added the ability to "suspend" encoding in the Output Stream so        
+ *   you can turn on and off the encoding if you need to embed base64       
+ *   data in an otherwise "normal" stream (like an XML file).</li>  
+ *  <li>v1.5 - Output stream pases on flush() command but doesn't do anything itself.
+ *      This helps when using GZIP streams.
+ *      Added the ability to GZip-compress objects before encoding them.</li>
+ *  <li>v1.4 - Added helper methods to read/write files.</li>
+ *  <li>v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.</li>
+ *  <li>v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream
+ *      where last buffer being read, if not completely full, was not returned.</li>
+ *  <li>v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.</li>
+ *  <li>v1.3.3 - Fixed I/O streams which were totally messed up.</li>
+ * </ul>
+ *
+ * <p>
+ * I am placing this code in the Public Domain. Do with it as you will.
+ * This software comes with no guarantees or warranties but with
+ * plenty of well-wishing instead!
+ * Please visit <a href="http://iharder.net/base64">http://iharder.net/base64</a>
+ * periodically to check for updates or to contribute improvements.
+ * </p>
+ *
+ * @author Robert Harder
+ * @author rob@iharder.net
+ * @version 2.3.7
+ */
+public class Base64
+{
+    
+/* ********  P U B L I C   F I E L D S  ******** */
+
+
+  /** No options specified. Value is zero. */
+  public final static int NO_OPTIONS = 0;
+
+  /** Specify encoding in first bit. Value is one. */
+  public final static int ENCODE = 1;
+
+
+  /** Specify decoding in first bit. Value is zero. */
+  public final static int DECODE = 0;
+
+
+  /** Specify that data should be gzip-compressed in second bit. Value is two. */
+  public final static int GZIP = 2;
+
+  /** Specify that gzipped data should <em>not</em> be automatically gunzipped. */
+  public final static int DONT_GUNZIP = 4;
+
+
+  /** Do break lines when encoding. Value is 8. */
+  public final static int DO_BREAK_LINES = 8;
+
+  /**
+   * Encode using Base64-like encoding that is URL- and Filename-safe as described
+   * in Section 4 of RFC3548:
+   * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+   * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
+   * or at the very least should not be called Base64 without also specifying that is
+   * was encoded using the URL- and Filename-safe dialect.
+   */
+  public final static int URL_SAFE = 16;
+
+
+  /**
+   * Encode using the special "ordered" dialect of Base64 described here:
+   * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+   */
+  public final static int ORDERED = 32;
+    
+    
+/* ********  P R I V A T E   F I E L D S  ******** */
+
+
+  /** Maximum line length (76) of Base64 output. */
+  private final static int MAX_LINE_LENGTH = 76;
+
+
+  /** The equals sign (=) as a byte. */
+  private final static byte EQUALS_SIGN = (byte)'=';
+
+
+  /** The new line character (\n) as a byte. */
+  private final static byte NEW_LINE = (byte)'\n';
+
+
+  /** Preferred encoding. */
+  private final static String PREFERRED_ENCODING = "US-ASCII";
+
+
+  private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
+  private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
+
+
+/* ********  S T A N D A R D   B A S E 6 4   A L P H A B E T  ******** */
+
+  /** The 64 valid Base64 values. */
+    /* Host platform me be something funny like EBCDIC, so we hardcode these values. */
+  private final static byte[] _STANDARD_ALPHABET = {
+      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
+      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
+  };
+
+
+  /**
+   * Translates a Base64 value to either its 6-bit reconstruction value
+   * or a negative number indicating some other meaning.
+   **/
+  private final static byte[] _STANDARD_DECODABET = {
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+      -5,-5,                                      // Whitespace: Tab and Linefeed
+      -9,-9,                                      // Decimal 11 - 12
+      -5,                                         // Whitespace: Carriage Return
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+      -5,                                         // Whitespace: Space
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+      62,                                         // Plus sign at decimal 43
+      -9,-9,-9,                                   // Decimal 44 - 46
+      63,                                         // Slash at decimal 47
+      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
+      -9,-9,-9,                                   // Decimal 58 - 60
+      -1,                                         // Equals sign at decimal 61
+      -9,-9,-9,                                      // Decimal 62 - 64
+      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
+      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
+      -9,-9,-9,-9,-9,-9,                          // Decimal 91 - 96
+      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
+      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
+      -9,-9,-9,-9,-9                              // Decimal 123 - 127
+      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,       // Decimal 128 - 139
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255
+  };
+
+
+/* ********  U R L   S A F E   B A S E 6 4   A L P H A B E T  ******** */
+
+  /**
+   * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
+   * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+   * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
+   */
+  private final static byte[] _URL_SAFE_ALPHABET = {
+      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
+      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_'
+  };
+
+  /**
+   * Used in decoding URL- and Filename-safe dialects of Base64.
+   */
+  private final static byte[] _URL_SAFE_DECODABET = {
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+      -5,-5,                                      // Whitespace: Tab and Linefeed
+      -9,-9,                                      // Decimal 11 - 12
+      -5,                                         // Whitespace: Carriage Return
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+      -5,                                         // Whitespace: Space
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+      -9,                                         // Plus sign at decimal 43
+      -9,                                         // Decimal 44
+      62,                                         // Minus sign at decimal 45
+      -9,                                         // Decimal 46
+      -9,                                         // Slash at decimal 47
+      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
+      -9,-9,-9,                                   // Decimal 58 - 60
+      -1,                                         // Equals sign at decimal 61
+      -9,-9,-9,                                   // Decimal 62 - 64
+      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
+      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
+      -9,-9,-9,-9,                                // Decimal 91 - 94
+      63,                                         // Underscore at decimal 95
+      -9,                                         // Decimal 96
+      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
+      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
+      -9,-9,-9,-9,-9                              // Decimal 123 - 127
+      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 128 - 139
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 
+  };
+
+
+
+/* ********  O R D E R E D   B A S E 6 4   A L P H A B E T  ******** */
+
+  /**
+   * I don't get the point of this technique, but someone requested it,
+   * and it is described here:
+   * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+   */
+  private final static byte[] _ORDERED_ALPHABET = {
+      (byte)'-',
+      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4',
+      (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9',
+      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+      (byte)'_',
+      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'
+  };
+
+  /**
+   * Used in decoding the "ordered" dialect of Base64.
+   */
+  private final static byte[] _ORDERED_DECODABET = {
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+      -5,-5,                                      // Whitespace: Tab and Linefeed
+      -9,-9,                                      // Decimal 11 - 12
+      -5,                                         // Whitespace: Carriage Return
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+      -5,                                         // Whitespace: Space
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+      -9,                                         // Plus sign at decimal 43
+      -9,                                         // Decimal 44
+      0,                                          // Minus sign at decimal 45
+      -9,                                         // Decimal 46
+      -9,                                         // Slash at decimal 47
+      1,2,3,4,5,6,7,8,9,10,                       // Numbers zero through nine
+      -9,-9,-9,                                   // Decimal 58 - 60
+      -1,                                         // Equals sign at decimal 61
+      -9,-9,-9,                                   // Decimal 62 - 64
+      11,12,13,14,15,16,17,18,19,20,21,22,23,     // Letters 'A' through 'M'
+      24,25,26,27,28,29,30,31,32,33,34,35,36,     // Letters 'N' through 'Z'
+      -9,-9,-9,-9,                                // Decimal 91 - 94
+      37,                                         // Underscore at decimal 95
+      -9,                                         // Decimal 96
+      38,39,40,41,42,43,44,45,46,47,48,49,50,     // Letters 'a' through 'm'
+      51,52,53,54,55,56,57,58,59,60,61,62,63,     // Letters 'n' through 'z'
+      -9,-9,-9,-9,-9                                 // Decimal 123 - 127
+      ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 128 - 139
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255
+  };
+
+
+/* ********  D E T E R M I N E   W H I C H   A L H A B E T  ******** */
+
+
+  /**
+   * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
+   * the options specified.
+   * It's possible, though silly, to specify ORDERED <b>and</b> URLSAFE
+   * in which case one of them will be picked, though there is
+   * no guarantee as to which one will be picked.
+   */
+  private final static byte[] getAlphabet( int options ) {
+    if ((options & URL_SAFE) == URL_SAFE) {
+      return _URL_SAFE_ALPHABET;
+    } else if ((options & ORDERED) == ORDERED) {
+      return _ORDERED_ALPHABET;
+    } else {
+      return _STANDARD_ALPHABET;
+    }
+  } // end getAlphabet
+
+
+  /**
+   * Returns one of the _SOMETHING_DECODABET byte arrays depending on
+   * the options specified.
+   * It's possible, though silly, to specify ORDERED and URL_SAFE
+   * in which case one of them will be picked, though there is
+   * no guarantee as to which one will be picked.
+   */
+  private final static byte[] getDecodabet( int options ) {
+    if( (options & URL_SAFE) == URL_SAFE) {
+      return _URL_SAFE_DECODABET;
+    } else if ((options & ORDERED) == ORDERED) {
+      return _ORDERED_DECODABET;
+    } else {
+      return _STANDARD_DECODABET;
+    }
+  } // end getAlphabet
+
+
+
+  /** Defeats instantiation. */
+  private Base64(){}
+    
+
+    
+    
+/* ********  E N C O D I N G   M E T H O D S  ******** */
+
+
+  /**
+   * Encodes up to the first three bytes of array <var>threeBytes</var>
+   * and returns a four-byte array in Base64 notation.
+   * The actual number of significant bytes in your array is
+   * given by <var>numSigBytes</var>.
+   * The array <var>threeBytes</var> needs only be as big as
+   * <var>numSigBytes</var>.
+   * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
+   *
+   * @param b4 A reusable byte array to reduce array instantiation
+   * @param threeBytes the array to convert
+   * @param numSigBytes the number of significant bytes in your array
+   * @return four byte array in Base64 notation.
+   * @since 1.5.1
+   */
+  private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) {
+    encode3to4( threeBytes, 0, numSigBytes, b4, 0, options );
+    return b4;
+  }   // end encode3to4
+
+
+  /**
+   * <p>Encodes up to three bytes of the array <var>source</var>
+   * and writes the resulting four Base64 bytes to <var>destination</var>.
+   * The source and destination arrays can be manipulated
+   * anywhere along their length by specifying
+   * <var>srcOffset</var> and <var>destOffset</var>.
+   * This method does not check to make sure your arrays
+   * are large enough to accomodate <var>srcOffset</var> + 3 for
+   * the <var>source</var> array or <var>destOffset</var> + 4 for
+   * the <var>destination</var> array.
+   * The actual number of significant bytes in your array is
+   * given by <var>numSigBytes</var>.</p>
+   * <p>This is the lowest level of the encoding methods with
+   * all possible parameters.</p>
+   *
+   * @param source the array to convert
+   * @param srcOffset the index where conversion begins
+   * @param numSigBytes the number of significant bytes in your array
+   * @param destination the array to hold the conversion
+   * @param destOffset the index where output will be put
+   * @return the <var>destination</var> array
+   * @since 1.3
+   */
+  private static byte[] encode3to4(
+      byte[] source, int srcOffset, int numSigBytes,
+      byte[] destination, int destOffset, int options ) {
+
+    byte[] ALPHABET = getAlphabet( options );
+
+    //           1         2         3
+    // 01234567890123456789012345678901 Bit position
+    // --------000000001111111122222222 Array position from threeBytes
+    // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
+    //          >>18  >>12  >> 6  >> 0  Right shift necessary
+    //                0x3f  0x3f  0x3f  Additional AND
+
+    // Create buffer with zero-padding if there are only one or two
+    // significant bytes passed in the array.
+    // We have to shift left 24 in order to flush out the 1's that appear
+    // when Java treats a value as negative that is cast from a byte to an int.
+    int inBuff =   ( numSigBytes > 0 ? ((source[ srcOffset     ] << 24) >>>  8) : 0 )
+        | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
+        | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
+
+    switch( numSigBytes )
+    {
+    case 3:
+      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+      destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
+      destination[ destOffset + 3 ] = ALPHABET[ (inBuff       ) & 0x3f ];
+      return destination;
+
+    case 2:
+      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+      destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
+      destination[ destOffset + 3 ] = EQUALS_SIGN;
+      return destination;
+
+    case 1:
+      destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+      destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+      destination[ destOffset + 2 ] = EQUALS_SIGN;
+      destination[ destOffset + 3 ] = EQUALS_SIGN;
+      return destination;
+
+    default:
+      return destination;
+    }   // end switch
+  }   // end encode3to4
+
+
+
+  /**
+   * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
+   * writing it to the <code>encoded</code> ByteBuffer.
+   * This is an experimental feature. Currently it does not
+   * pass along any options (such as {@link #DO_BREAK_LINES}
+   * or {@link #GZIP}.
+   *
+   * @param raw input buffer
+   * @param encoded output buffer
+   * @since 2.3
+   */
+  public static void encode( java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded ){
+    byte[] raw3 = new byte[3];
+    byte[] enc4 = new byte[4];
+
+    while( raw.hasRemaining() ){
+      int rem = Math.min(3,raw.remaining());
+      raw.get(raw3,0,rem);
+      Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
+      encoded.put(enc4);
+    }   // end input remaining
+  }
+
+
+  /**
+   * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
+   * writing it to the <code>encoded</code> CharBuffer.
+   * This is an experimental feature. Currently it does not
+   * pass along any options (such as {@link #DO_BREAK_LINES}
+   * or {@link #GZIP}.
+   *
+   * @param raw input buffer
+   * @param encoded output buffer
+   * @since 2.3
+   */
+  public static void encode( java.nio.ByteBuffer raw, java.nio.CharBuffer encoded ){
+    byte[] raw3 = new byte[3];
+    byte[] enc4 = new byte[4];
+
+    while( raw.hasRemaining() ){
+      int rem = Math.min(3,raw.remaining());
+      raw.get(raw3,0,rem);
+      Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
+      for( int i = 0; i < 4; i++ ){
+        encoded.put( (char)(enc4[i] & 0xFF) );
+      }
+    }   // end input remaining
+  }
+
+
+
+
+  /**
+   * Serializes an object and returns the Base64-encoded
+   * version of that serialized object.
+   *
+   * <p>As of v 2.3, if the object
+   * cannot be serialized or there is another error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned a null value, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * The object is not GZip-compressed before being encoded.
+   *
+   * @param serializableObject The object to encode
+   * @return The Base64-encoded object
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if serializedObject is null
+   * @since 1.4
+   */
+  public static String encodeObject( java.io.Serializable serializableObject )
+      throws java.io.IOException {
+    return encodeObject( serializableObject, NO_OPTIONS );
+  }   // end encodeObject
+
+
+
+  /**
+   * Serializes an object and returns the Base64-encoded
+   * version of that serialized object.
+   *
+   * <p>As of v 2.3, if the object
+   * cannot be serialized or there is another error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned a null value, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * The object is not GZip-compressed before being encoded.
+   * <p>
+   * Example options:<pre>
+   *   GZIP: gzip-compresses object before encoding it.
+   *   DO_BREAK_LINES: break lines at 76 characters
+   * </pre>
+   * <p>
+   * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
+   * <p>
+   * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+   *
+   * @param serializableObject The object to encode
+   * @param options Specified options
+   * @return The Base64-encoded object
+   * @see Base64#GZIP
+   * @see Base64#DO_BREAK_LINES
+   * @throws java.io.IOException if there is an error
+   * @since 2.0
+   */
+  public static String encodeObject( java.io.Serializable serializableObject, int options )
+      throws java.io.IOException {
+
+    if( serializableObject == null ){
+      throw new NullPointerException( "Cannot serialize a null object." );
+    }   // end if: null
+
+    // Streams
+    java.io.ByteArrayOutputStream  baos  = null;
+    java.io.OutputStream           b64os = null;
+    java.util.zip.GZIPOutputStream gzos  = null;
+    java.io.ObjectOutputStream     oos   = null;
+
+
+    try {
+      // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
+      baos  = new java.io.ByteArrayOutputStream();
+      b64os = new Base64.OutputStream( baos, ENCODE | options );
+      if( (options & GZIP) != 0 ){
+        // Gzip
+        gzos = new java.util.zip.GZIPOutputStream(b64os);
+        oos = new java.io.ObjectOutputStream( gzos );
+      } else {
+        // Not gzipped
+        oos = new java.io.ObjectOutputStream( b64os );
+      }
+      oos.writeObject( serializableObject );
+    }   // end try
+    catch( java.io.IOException e ) {
+      // Catch it and then throw it immediately so that
+      // the finally{} block is called for cleanup.
+      throw e;
+    }   // end catch
+    finally {
+      try{ oos.close();   } catch( Exception e ){}
+      try{ gzos.close();  } catch( Exception e ){}
+      try{ b64os.close(); } catch( Exception e ){}
+      try{ baos.close();  } catch( Exception e ){}
+    }   // end finally
+
+    // Return value according to relevant encoding.
+    try {
+      return new String( baos.toByteArray(), PREFERRED_ENCODING );
+    }   // end try
+    catch (java.io.UnsupportedEncodingException uue){
+      // Fall back to some Java default
+      return new String( baos.toByteArray() );
+    }   // end catch
+
+  }   // end encode
+
+
+
+  /**
+   * Encodes a byte array into Base64 notation.
+   * Does not GZip-compress data.
+   *
+   * @param source The data to convert
+   * @return The data in Base64-encoded form
+   * @throws NullPointerException if source array is null
+   * @since 1.4
+   */
+  public static String encodeBytes( byte[] source ) {
+    // Since we're not going to have the GZIP encoding turned on,
+    // we're not going to have an java.io.IOException thrown, so
+    // we should not force the user to have to catch it.
+    String encoded = null;
+    try {
+      encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
+    } catch (java.io.IOException ex) {
+      assert false : ex.getMessage();
+    }   // end catch
+    assert encoded != null;
+    return encoded;
+  }   // end encodeBytes
+
+
+
+  /**
+   * Encodes a byte array into Base64 notation.
+   * <p>
+   * Example options:<pre>
+   *   GZIP: gzip-compresses object before encoding it.
+   *   DO_BREAK_LINES: break lines at 76 characters
+   *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+   * </pre>
+   * <p>
+   * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+   * <p>
+   * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+   *
+   *
+   * <p>As of v 2.3, if there is an error with the GZIP stream,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned a null value, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   *
+   * @param source The data to convert
+   * @param options Specified options
+   * @return The Base64-encoded data as a String
+   * @see Base64#GZIP
+   * @see Base64#DO_BREAK_LINES
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if source array is null
+   * @since 2.0
+   */
+  public static String encodeBytes( byte[] source, int options ) throws java.io.IOException {
+    return encodeBytes( source, 0, source.length, options );
+  }   // end encodeBytes
+
+
+  /**
+   * Encodes a byte array into Base64 notation.
+   * Does not GZip-compress data.
+   *
+   * <p>As of v 2.3, if there is an error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned a null value, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   *
+   * @param source The data to convert
+   * @param off Offset in array where conversion should begin
+   * @param len Length of data to convert
+   * @return The Base64-encoded data as a String
+   * @throws NullPointerException if source array is null
+   * @throws IllegalArgumentException if source array, offset, or length are invalid
+   * @since 1.4
+   */
+  public static String encodeBytes( byte[] source, int off, int len ) {
+    // Since we're not going to have the GZIP encoding turned on,
+    // we're not going to have an java.io.IOException thrown, so
+    // we should not force the user to have to catch it.
+    String encoded = null;
+    try {
+      encoded = encodeBytes( source, off, len, NO_OPTIONS );
+    } catch (java.io.IOException ex) {
+      assert false : ex.getMessage();
+    }   // end catch
+    assert encoded != null;
+    return encoded;
+  }   // end encodeBytes
+
+
+
+  /**
+   * Encodes a byte array into Base64 notation.
+   * <p>
+   * Example options:<pre>
+   *   GZIP: gzip-compresses object before encoding it.
+   *   DO_BREAK_LINES: break lines at 76 characters
+   *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+   * </pre>
+   * <p>
+   * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+   * <p>
+   * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+   *
+   *
+   * <p>As of v 2.3, if there is an error with the GZIP stream,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned a null value, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   *
+   * @param source The data to convert
+   * @param off Offset in array where conversion should begin
+   * @param len Length of data to convert
+   * @param options Specified options
+   * @return The Base64-encoded data as a String
+   * @see Base64#GZIP
+   * @see Base64#DO_BREAK_LINES
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if source array is null
+   * @throws IllegalArgumentException if source array, offset, or length are invalid
+   * @since 2.0
+   */
+  public static String encodeBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
+    byte[] encoded = encodeBytesToBytes( source, off, len, options );
+
+    // Return value according to relevant encoding.
+    try {
+      return new String( encoded, PREFERRED_ENCODING );
+    }   // end try
+    catch (java.io.UnsupportedEncodingException uue) {
+      return new String( encoded );
+    }   // end catch
+
+  }   // end encodeBytes
+
+
+
+
+  /**
+   * Similar to {@link #encodeBytes(byte[])} but returns
+   * a byte array instead of instantiating a String. This is more efficient
+   * if you're working with I/O streams and have large data sets to encode.
+   *
+   *
+   * @param source The data to convert
+   * @return The Base64-encoded data as a byte[] (of ASCII characters)
+   * @throws NullPointerException if source array is null
+   * @since 2.3.1
+   */
+  public static byte[] encodeBytesToBytes( byte[] source ) {
+    byte[] encoded = null;
+    try {
+      encoded = encodeBytesToBytes( source, 0, source.length, Base64.NO_OPTIONS );
+    } catch( java.io.IOException ex ) {
+      assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
+    }
+    return encoded;
+  }
+
+
+  /**
+   * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns
+   * a byte array instead of instantiating a String. This is more efficient
+   * if you're working with I/O streams and have large data sets to encode.
+   *
+   *
+   * @param source The data to convert
+   * @param off Offset in array where conversion should begin
+   * @param len Length of data to convert
+   * @param options Specified options
+   * @return The Base64-encoded data as a String
+   * @see Base64#GZIP
+   * @see Base64#DO_BREAK_LINES
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if source array is null
+   * @throws IllegalArgumentException if source array, offset, or length are invalid
+   * @since 2.3.1
+   */
+  public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
+
+    if( source == null ){
+      throw new NullPointerException( "Cannot serialize a null array." );
+    }   // end if: null
+
+    if( off < 0 ){
+      throw new IllegalArgumentException( "Cannot have negative offset: " + off );
+    }   // end if: off < 0
+
+    if( len < 0 ){
+      throw new IllegalArgumentException( "Cannot have length offset: " + len );
+    }   // end if: len < 0
+
+    if( off + len > source.length  ){
+      throw new IllegalArgumentException(
+          String.format( "Cannot have offset of %d and length of %d with array of length %d", off,len,source.length));
+    }   // end if: off < 0
+
+
+
+    // Compress?
+    if( (options & GZIP) != 0 ) {
+      java.io.ByteArrayOutputStream  baos  = null;
+      java.util.zip.GZIPOutputStream gzos  = null;
+      Base64.OutputStream            b64os = null;
+
+      try {
+        // GZip -> Base64 -> ByteArray
+        baos = new java.io.ByteArrayOutputStream();
+        b64os = new Base64.OutputStream( baos, ENCODE | options );
+        gzos  = new java.util.zip.GZIPOutputStream( b64os );
+
+        gzos.write( source, off, len );
+        gzos.close();
+      }   // end try
+      catch( java.io.IOException e ) {
+        // Catch it and then throw it immediately so that
+        // the finally{} block is called for cleanup.
+        throw e;
+      }   // end catch
+      finally {
+        try{ gzos.close();  } catch( Exception e ){}
+        try{ b64os.close(); } catch( Exception e ){}
+        try{ baos.close();  } catch( Exception e ){}
+      }   // end finally
+
+      return baos.toByteArray();
+    }   // end if: compress
+
+    // Else, don't compress. Better not to use streams at all then.
+    else {
+      boolean breakLines = (options & DO_BREAK_LINES) != 0;
+
+      //int    len43   = len * 4 / 3;
+      //byte[] outBuff = new byte[   ( len43 )                      // Main 4:3
+      //                           + ( (len % 3) > 0 ? 4 : 0 )      // Account for padding
+      //                           + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
+      // Try to determine more precisely how big the array needs to be.
+      // If we get it right, we don't have to do an array copy, and
+      // we save a bunch of memory.
+      int encLen = ( len / 3 ) * 4 + ( len % 3 > 0 ? 4 : 0 ); // Bytes needed for actual encoding
+      if( breakLines ){
+        encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
+      }
+      byte[] outBuff = new byte[ encLen ];
+
+
+      int d = 0;
+      int e = 0;
+      int len2 = len - 2;
+      int lineLength = 0;
+      for( ; d < len2; d+=3, e+=4 ) {
+        encode3to4( source, d+off, 3, outBuff, e, options );
+
+        lineLength += 4;
+        if( breakLines && lineLength >= MAX_LINE_LENGTH )
+        {
+          outBuff[e+4] = NEW_LINE;
+          e++;
+          lineLength = 0;
+        }   // end if: end of line
+      }   // en dfor: each piece of array
+
+      if( d < len ) {
+        encode3to4( source, d+off, len - d, outBuff, e, options );
+        e += 4;
+      }   // end if: some padding needed
+
+
+      // Only resize array if we didn't guess it right.
+      if( e <= outBuff.length - 1 ){
+        // If breaking lines and the last byte falls right at
+        // the line length (76 bytes per line), there will be
+        // one extra byte, and the array will need to be resized.
+        // Not too bad of an estimate on array size, I'd say.
+        byte[] finalOut = new byte[e];
+        System.arraycopy(outBuff,0, finalOut,0,e);
+        //System.err.println("Having to resize array from " + outBuff.length + " to " + e );
+        return finalOut;
+      } else {
+        //System.err.println("No need to resize array.");
+        return outBuff;
+      }
+
+    }   // end else: don't compress
+
+  }   // end encodeBytesToBytes
+    
+
+    
+    
+    
+/* ********  D E C O D I N G   M E T H O D S  ******** */
+
+
+  /**
+   * Decodes four bytes from array <var>source</var>
+   * and writes the resulting bytes (up to three of them)
+   * to <var>destination</var>.
+   * The source and destination arrays can be manipulated
+   * anywhere along their length by specifying
+   * <var>srcOffset</var> and <var>destOffset</var>.
+   * This method does not check to make sure your arrays
+   * are large enough to accomodate <var>srcOffset</var> + 4 for
+   * the <var>source</var> array or <var>destOffset</var> + 3 for
+   * the <var>destination</var> array.
+   * This method returns the actual number of bytes that
+   * were converted from the Base64 encoding.
+   * <p>This is the lowest level of the decoding methods with
+   * all possible parameters.</p>
+   *
+   *
+   * @param source the array to convert
+   * @param srcOffset the index where conversion begins
+   * @param destination the array to hold the conversion
+   * @param destOffset the index where output will be put
+   * @param options alphabet type is pulled from this (standard, url-safe, ordered)
+   * @return the number of decoded bytes converted
+   * @throws NullPointerException if source or destination arrays are null
+   * @throws IllegalArgumentException if srcOffset or destOffset are invalid
+   *         or there is not enough room in the array.
+   * @since 1.3
+   */
+  private static int decode4to3(
+      byte[] source, int srcOffset,
+      byte[] destination, int destOffset, int options ) {
+
+    // Lots of error checking and exception throwing
+    if( source == null ){
+      throw new NullPointerException( "Source array was null." );
+    }   // end if
+    if( destination == null ){
+      throw new NullPointerException( "Destination array was null." );
+    }   // end if
+    if( srcOffset < 0 || srcOffset + 3 >= source.length ){
+      throw new IllegalArgumentException( String.format(
+          "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset ) );
+    }   // end if
+    if( destOffset < 0 || destOffset +2 >= destination.length ){
+      throw new IllegalArgumentException( String.format(
+          "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset ) );
+    }   // end if
+
+
+    byte[] DECODABET = getDecodabet( options );
+
+    // Example: Dk==
+    if( source[ srcOffset + 2] == EQUALS_SIGN ) {
+      // Two ways to do the same thing. Don't know which way I like best.
+      //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )
+      //              | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
+      int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] & 0xFF ) << 18 )
+          | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 );
+
+      destination[ destOffset ] = (byte)( outBuff >>> 16 );
+      return 1;
+    }
+
+    // Example: DkL=
+    else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) {
+      // Two ways to do the same thing. Don't know which way I like best.
+      //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+      //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+      //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
+      int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
+          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6 );
+
+      destination[ destOffset     ] = (byte)( outBuff >>> 16 );
+      destination[ destOffset + 1 ] = (byte)( outBuff >>>  8 );
+      return 2;
+    }
+
+    // Example: DkLE
+    else {
+      // Two ways to do the same thing. Don't know which way I like best.
+      //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+      //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+      //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
+      //              | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
+      int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
+          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6)
+          | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF )      );
+
+
+      destination[ destOffset     ] = (byte)( outBuff >> 16 );
+      destination[ destOffset + 1 ] = (byte)( outBuff >>  8 );
+      destination[ destOffset + 2 ] = (byte)( outBuff       );
+
+      return 3;
+    }
+  }   // end decodeToBytes
+
+
+
+
+
+  /**
+   * Low-level access to decoding ASCII characters in
+   * the form of a byte array. <strong>Ignores GUNZIP option, if
+   * it's set.</strong> This is not generally a recommended method,
+   * although it is used internally as part of the decoding process.
+   * Special case: if len = 0, an empty array is returned. Still,
+   * if you need more speed and reduced memory footprint (and aren't
+   * gzipping), consider this method.
+   *
+   * @param source The Base64 encoded data
+   * @return decoded data
+   * @since 2.3.1
+   */
+  public static byte[] decode( byte[] source )
+      throws java.io.IOException {
+    byte[] decoded = null;
+//        try {
+    decoded = decode( source, 0, source.length, Base64.NO_OPTIONS );
+//        } catch( java.io.IOException ex ) {
+//            assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
+//        }
+    return decoded;
+  }
+
+
+
+  /**
+   * Low-level access to decoding ASCII characters in
+   * the form of a byte array. <strong>Ignores GUNZIP option, if
+   * it's set.</strong> This is not generally a recommended method,
+   * although it is used internally as part of the decoding process.
+   * Special case: if len = 0, an empty array is returned. Still,
+   * if you need more speed and reduced memory footprint (and aren't
+   * gzipping), consider this method.
+   *
+   * @param source The Base64 encoded data
+   * @param off    The offset of where to begin decoding
+   * @param len    The length of characters to decode
+   * @param options Can specify options such as alphabet type to use
+   * @return decoded data
+   * @throws java.io.IOException If bogus characters exist in source data
+   * @since 1.3
+   */
+  public static byte[] decode( byte[] source, int off, int len, int options )
+      throws java.io.IOException {
+
+    // Lots of error checking and exception throwing
+    if( source == null ){
+      throw new NullPointerException( "Cannot decode null source array." );
+    }   // end if
+    if( off < 0 || off + len > source.length ){
+      throw new IllegalArgumentException( String.format(
+          "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) );
+    }   // end if
+
+    if( len == 0 ){
+      return new byte[0];
+    }else if( len < 4 ){
+      throw new IllegalArgumentException(
+          "Base64-encoded string must have at least four characters, but length specified was " + len );
+    }   // end if
+
+    byte[] DECODABET = getDecodabet( options );
+
+    int    len34   = len * 3 / 4;       // Estimate on array size
+    byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output
+    int    outBuffPosn = 0;             // Keep track of where we're writing
+
+    byte[] b4        = new byte[4];     // Four byte buffer from source, eliminating white space
+    int    b4Posn    = 0;               // Keep track of four byte input buffer
+    int    i         = 0;               // Source array counter
+    byte   sbiDecode = 0;               // Special value from DECODABET
+
+    for( i = off; i < off+len; i++ ) {  // Loop through source
+
+      sbiDecode = DECODABET[ source[i]&0xFF ];
+
+      // White space, Equals sign, or legit Base64 character
+      // Note the values such as -5 and -9 in the
+      // DECODABETs at the top of the file.
+      if( sbiDecode >= WHITE_SPACE_ENC )  {
+        if( sbiDecode >= EQUALS_SIGN_ENC ) {
+          b4[ b4Posn++ ] = source[i];         // Save non-whitespace
+          if( b4Posn > 3 ) {                  // Time to decode?
+            outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options );
+            b4Posn = 0;
+
+            // If that was the equals sign, break out of 'for' loop
+            if( source[i] == EQUALS_SIGN ) {
+              break;
+            }   // end if: equals sign
+          }   // end if: quartet built
+        }   // end if: equals sign or better
+      }   // end if: white space, equals sign or better
+      else {
+        // There's a bad input character in the Base64 stream.
+        throw new java.io.IOException( String.format(
+            "Bad Base64 input character decimal %d in array position %d", ((int)source[i])&0xFF, i ) );
+      }   // end else:
+    }   // each input character
+
+    byte[] out = new byte[ outBuffPosn ];
+    System.arraycopy( outBuff, 0, out, 0, outBuffPosn );
+    return out;
+  }   // end decode
+
+
+
+
+  /**
+   * Decodes data from Base64 notation, automatically
+   * detecting gzip-compressed data and decompressing it.
+   *
+   * @param s the string to decode
+   * @return the decoded data
+   * @throws java.io.IOException If there is a problem
+   * @since 1.4
+   */
+  public static byte[] decode( String s ) throws java.io.IOException {
+    return decode( s, NO_OPTIONS );
+  }
+
+
+
+  /**
+   * Decodes data from Base64 notation, automatically
+   * detecting gzip-compressed data and decompressing it.
+   *
+   * @param s the string to decode
+   * @param options encode options such as URL_SAFE
+   * @return the decoded data
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if <tt>s</tt> is null
+   * @since 1.4
+   */
+  public static byte[] decode( String s, int options ) throws java.io.IOException {
+
+    if( s == null ){
+      throw new NullPointerException( "Input string was null." );
+    }   // end if
+
+    byte[] bytes;
+    try {
+      bytes = s.getBytes( PREFERRED_ENCODING );
+    }   // end try
+    catch( java.io.UnsupportedEncodingException uee ) {
+      bytes = s.getBytes();
+    }   // end catch
+    //</change>
+
+    // Decode
+    bytes = decode( bytes, 0, bytes.length, options );
+
+    // Check to see if it's gzip-compressed
+    // GZIP Magic Two-Byte Number: 0x8b1f (35615)
+    boolean dontGunzip = (options & DONT_GUNZIP) != 0;
+    if( (bytes != null) && (bytes.length >= 4) && (!dontGunzip) ) {
+
+      int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
+      if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head )  {
+        java.io.ByteArrayInputStream  bais = null;
+        java.util.zip.GZIPInputStream gzis = null;
+        java.io.ByteArrayOutputStream baos = null;
+        byte[] buffer = new byte[2048];
+        int    length = 0;
+
+        try {
+          baos = new java.io.ByteArrayOutputStream();
+          bais = new java.io.ByteArrayInputStream( bytes );
+          gzis = new java.util.zip.GZIPInputStream( bais );
+
+          while( ( length = gzis.read( buffer ) ) >= 0 ) {
+            baos.write(buffer,0,length);
+          }   // end while: reading input
+
+          // No error? Get new bytes.
+          bytes = baos.toByteArray();
+
+        }   // end try
+        catch( java.io.IOException e ) {
+          e.printStackTrace();
+          // Just return originally-decoded bytes
+        }   // end catch
+        finally {
+          try{ baos.close(); } catch( Exception e ){}
+          try{ gzis.close(); } catch( Exception e ){}
+          try{ bais.close(); } catch( Exception e ){}
+        }   // end finally
+
+      }   // end if: gzipped
+    }   // end if: bytes.length >= 2
+
+    return bytes;
+  }   // end decode
+
+
+
+  /**
+   * Attempts to decode Base64 data and deserialize a Java
+   * Object within. Returns <tt>null</tt> if there was an error.
+   *
+   * @param encodedObject The Base64 data to decode
+   * @return The decoded and deserialized object
+   * @throws NullPointerException if encodedObject is null
+   * @throws java.io.IOException if there is a general error
+   * @throws ClassNotFoundException if the decoded object is of a
+   *         class that cannot be found by the JVM
+   * @since 1.5
+   */
+  public static Object decodeToObject( String encodedObject )
+      throws java.io.IOException, java.lang.ClassNotFoundException {
+    return decodeToObject(encodedObject,NO_OPTIONS,null);
+  }
+
+
+  /**
+   * Attempts to decode Base64 data and deserialize a Java
+   * Object within. Returns <tt>null</tt> if there was an error.
+   * If <tt>loader</tt> is not null, it will be the class loader
+   * used when deserializing.
+   *
+   * @param encodedObject The Base64 data to decode
+   * @param options Various parameters related to decoding
+   * @param loader Optional class loader to use in deserializing classes.
+   * @return The decoded and deserialized object
+   * @throws NullPointerException if encodedObject is null
+   * @throws java.io.IOException if there is a general error
+   * @throws ClassNotFoundException if the decoded object is of a
+   *         class that cannot be found by the JVM
+   * @since 2.3.4
+   */
+  public static Object decodeToObject(
+      String encodedObject, int options, final ClassLoader loader )
+      throws java.io.IOException, java.lang.ClassNotFoundException {
+
+    // Decode and gunzip if necessary
+    byte[] objBytes = decode( encodedObject, options );
+
+    java.io.ByteArrayInputStream  bais = null;
+    java.io.ObjectInputStream     ois  = null;
+    Object obj = null;
+
+    try {
+      bais = new java.io.ByteArrayInputStream( objBytes );
+
+      // If no custom class loader is provided, use Java's builtin OIS.
+      if( loader == null ){
+        ois  = new java.io.ObjectInputStream( bais );
+      }   // end if: no loader provided
+
+      // Else make a customized object input stream that uses
+      // the provided class loader.
+      else {
+        ois = new java.io.ObjectInputStream(bais){
+          @Override
+          public Class<?> resolveClass(java.io.ObjectStreamClass streamClass)
+              throws java.io.IOException, ClassNotFoundException {
+            Class c = Class.forName(streamClass.getName(), false, loader);
+            if( c == null ){
+              return super.resolveClass(streamClass);
+            } else {
+              return c;   // Class loader knows of this class.
+            }   // end else: not null
+          }   // end resolveClass
+        };  // end ois
+      }   // end else: no custom class loader
+
+      obj = ois.readObject();
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e;    // Catch and throw in order to execute finally{}
+    }   // end catch
+    catch( java.lang.ClassNotFoundException e ) {
+      throw e;    // Catch and throw in order to execute finally{}
+    }   // end catch
+    finally {
+      try{ bais.close(); } catch( Exception e ){}
+      try{ ois.close();  } catch( Exception e ){}
+    }   // end finally
+
+    return obj;
+  }   // end decodeObject
+
+
+
+  /**
+   * Convenience method for encoding data to a file.
+   *
+   * <p>As of v 2.3, if there is a error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned false, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * @param dataToEncode byte array of data to encode in base64 form
+   * @param filename Filename for saving encoded data
+   * @throws java.io.IOException if there is an error
+   * @throws NullPointerException if dataToEncode is null
+   * @since 2.1
+   */
+  public static void encodeToFile( byte[] dataToEncode, String filename )
+      throws java.io.IOException {
+
+    if( dataToEncode == null ){
+      throw new NullPointerException( "Data to encode was null." );
+    }   // end iff
+
+    Base64.OutputStream bos = null;
+    try {
+      bos = new Base64.OutputStream(
+          new java.io.FileOutputStream( filename ), Base64.ENCODE );
+      bos.write( dataToEncode );
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and throw to execute finally{} block
+    }   // end catch: java.io.IOException
+    finally {
+      try{ bos.close(); } catch( Exception e ){}
+    }   // end finally
+
+  }   // end encodeToFile
+
+
+  /**
+   * Convenience method for decoding data to a file.
+   *
+   * <p>As of v 2.3, if there is a error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned false, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * @param dataToDecode Base64-encoded data as a string
+   * @param filename Filename for saving decoded data
+   * @throws java.io.IOException if there is an error
+   * @since 2.1
+   */
+  public static void decodeToFile( String dataToDecode, String filename )
+      throws java.io.IOException {
+
+    Base64.OutputStream bos = null;
+    try{
+      bos = new Base64.OutputStream(
+          new java.io.FileOutputStream( filename ), Base64.DECODE );
+      bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and throw to execute finally{} block
+    }   // end catch: java.io.IOException
+    finally {
+      try{ bos.close(); } catch( Exception e ){}
+    }   // end finally
+
+  }   // end decodeToFile
+
+
+
+
+  /**
+   * Convenience method for reading a base64-encoded
+   * file and decoding it.
+   *
+   * <p>As of v 2.3, if there is a error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned false, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * @param filename Filename for reading encoded data
+   * @return decoded byte array
+   * @throws java.io.IOException if there is an error
+   * @since 2.1
+   */
+  public static byte[] decodeFromFile( String filename )
+      throws java.io.IOException {
+
+    byte[] decodedData = null;
+    Base64.InputStream bis = null;
+    try
+    {
+      // Set up some useful variables
+      java.io.File file = new java.io.File( filename );
+      byte[] buffer = null;
+      int length   = 0;
+      int numBytes = 0;
+
+      // Check for size of file
+      if( file.length() > Integer.MAX_VALUE )
+      {
+        throw new java.io.IOException( "File is too big for this convenience method (" + file.length() + " bytes)." );
+      }   // end if: file too big for int index
+      buffer = new byte[ (int)file.length() ];
+
+      // Open a stream
+      bis = new Base64.InputStream(
+          new java.io.BufferedInputStream(
+              new java.io.FileInputStream( file ) ), Base64.DECODE );
+
+      // Read until done
+      while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
+        length += numBytes;
+      }   // end while
+
+      // Save in a variable to return
+      decodedData = new byte[ length ];
+      System.arraycopy( buffer, 0, decodedData, 0, length );
+
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and release to execute finally{}
+    }   // end catch: java.io.IOException
+    finally {
+      try{ bis.close(); } catch( Exception e) {}
+    }   // end finally
+
+    return decodedData;
+  }   // end decodeFromFile
+
+
+
+  /**
+   * Convenience method for reading a binary file
+   * and base64-encoding it.
+   *
+   * <p>As of v 2.3, if there is a error,
+   * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+   * In earlier versions, it just returned false, but
+   * in retrospect that's a pretty poor way to handle it.</p>
+   *
+   * @param filename Filename for reading binary data
+   * @return base64-encoded string
+   * @throws java.io.IOException if there is an error
+   * @since 2.1
+   */
+  public static String encodeFromFile( String filename )
+      throws java.io.IOException {
+
+    String encodedData = null;
+    Base64.InputStream bis = null;
+    try
+    {
+      // Set up some useful variables
+      java.io.File file = new java.io.File( filename );
+      byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4+1),40) ]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5)
+      int length   = 0;
+      int numBytes = 0;
+
+      // Open a stream
+      bis = new Base64.InputStream(
+          new java.io.BufferedInputStream(
+              new java.io.FileInputStream( file ) ), Base64.ENCODE );
+
+      // Read until done
+      while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) {
+        length += numBytes;
+      }   // end while
+
+      // Save in a variable to return
+      encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
+
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and release to execute finally{}
+    }   // end catch: java.io.IOException
+    finally {
+      try{ bis.close(); } catch( Exception e) {}
+    }   // end finally
+
+    return encodedData;
+  }   // end encodeFromFile
+
+  /**
+   * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
+   *
+   * @param infile Input file
+   * @param outfile Output file
+   * @throws java.io.IOException if there is an error
+   * @since 2.2
+   */
+  public static void encodeFileToFile( String infile, String outfile )
+      throws java.io.IOException {
+
+    String encoded = Base64.encodeFromFile( infile );
+    java.io.OutputStream out = null;
+    try{
+      out = new java.io.BufferedOutputStream(
+          new java.io.FileOutputStream( outfile ) );
+      out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and release to execute finally{}
+    }   // end catch
+    finally {
+      try { out.close(); }
+      catch( Exception ex ){}
+    }   // end finally
+  }   // end encodeFileToFile
+
+
+  /**
+   * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
+   *
+   * @param infile Input file
+   * @param outfile Output file
+   * @throws java.io.IOException if there is an error
+   * @since 2.2
+   */
+  public static void decodeFileToFile( String infile, String outfile )
+      throws java.io.IOException {
+
+    byte[] decoded = Base64.decodeFromFile( infile );
+    java.io.OutputStream out = null;
+    try{
+      out = new java.io.BufferedOutputStream(
+          new java.io.FileOutputStream( outfile ) );
+      out.write( decoded );
+    }   // end try
+    catch( java.io.IOException e ) {
+      throw e; // Catch and release to execute finally{}
+    }   // end catch
+    finally {
+      try { out.close(); }
+      catch( Exception ex ){}
+    }   // end finally
+  }   // end decodeFileToFile
+    
+    
+    /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
+
+
+
+  /**
+   * A {@link Base64.InputStream} will read data from another
+   * <tt>java.io.InputStream</tt>, given in the constructor,
+   * and encode/decode to/from Base64 notation on the fly.
+   *
+   * @see Base64
+   * @since 1.3
+   */
+  public static class InputStream extends java.io.FilterInputStream {
+
+    private boolean encode;         // Encoding or decoding
+    private int     position;       // Current position in the buffer
+    private byte[]  buffer;         // Small buffer holding converted data
+    private int     bufferLength;   // Length of buffer (3 or 4)
+    private int     numSigBytes;    // Number of meaningful bytes in the buffer
+    private int     lineLength;
+    private boolean breakLines;     // Break lines at less than 80 characters
+    private int     options;        // Record options used to create the stream.
+    private byte[]  decodabet;      // Local copies to avoid extra method calls
+
+
+    /**
+     * Constructs a {@link Base64.InputStream} in DECODE mode.
+     *
+     * @param in the <tt>java.io.InputStream</tt> from which to read data.
+     * @since 1.3
+     */
+    public InputStream( java.io.InputStream in ) {
+      this( in, DECODE );
+    }   // end constructor
+
+
+    /**
+     * Constructs a {@link Base64.InputStream} in
+     * either ENCODE or DECODE mode.
+     * <p>
+     * Valid options:<pre>
+     *   ENCODE or DECODE: Encode or Decode as data is read.
+     *   DO_BREAK_LINES: break lines at 76 characters
+     *     (only meaningful when encoding)
+     * </pre>
+     * <p>
+     * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
+     *
+     *
+     * @param in the <tt>java.io.InputStream</tt> from which to read data.
+     * @param options Specified options
+     * @see Base64#ENCODE
+     * @see Base64#DECODE
+     * @see Base64#DO_BREAK_LINES
+     * @since 2.0
+     */
+    public InputStream( java.io.InputStream in, int options ) {
+
+      super( in );
+      this.options      = options; // Record for later
+      this.breakLines   = (options & DO_BREAK_LINES) > 0;
+      this.encode       = (options & ENCODE) > 0;
+      this.bufferLength = encode ? 4 : 3;
+      this.buffer       = new byte[ bufferLength ];
+      this.position     = -1;
+      this.lineLength   = 0;
+      this.decodabet    = getDecodabet(options);
+    }   // end constructor
+
+    /**
+     * Reads enough of the input stream to convert
+     * to/from Base64 and returns the next byte.
+     *
+     * @return next byte
+     * @since 1.3
+     */
+    @Override
+    public int read() throws java.io.IOException  {
+
+      // Do we need to get data?
+      if( position < 0 ) {
+        if( encode ) {
+          byte[] b3 = new byte[3];
+          int numBinaryBytes = 0;
+          for( int i = 0; i < 3; i++ ) {
+            int b = in.read();
+
+            // If end of stream, b is -1.
+            if( b >= 0 ) {
+              b3[i] = (byte)b;
+              numBinaryBytes++;
+            } else {
+              break; // out of for loop
+            }   // end else: end of stream
+
+          }   // end for: each needed input byte
+
+          if( numBinaryBytes > 0 ) {
+            encode3to4( b3, 0, numBinaryBytes, buffer, 0, options );
+            position = 0;
+            numSigBytes = 4;
+          }   // end if: got data
+          else {
+            return -1;  // Must be end of stream
+          }   // end else
+        }   // end if: encoding
+
+        // Else decoding
+        else {
+          byte[] b4 = new byte[4];
+          int i = 0;
+          for( i = 0; i < 4; i++ ) {
+            // Read four "meaningful" bytes:
+            int b = 0;
+            do{ b = in.read(); }
+            while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC );
+
+            if( b < 0 ) {
+              break; // Reads a -1 if end of stream
+            }   // end if: end of stream
+
+            b4[i] = (byte)b;
+          }   // end for: each needed input byte
+
+          if( i == 4 ) {
+            numSigBytes = decode4to3( b4, 0, buffer, 0, options );
+            position = 0;
+          }   // end if: got four characters
+          else if( i == 0 ){
+            return -1;
+          }   // end else if: also padded correctly
+          else {
+            // Must have broken out from above.
+            throw new java.io.IOException( "Improperly padded Base64 input." );
+          }   // end
+
+        }   // end else: decode
+      }   // end else: get data
+
+      // Got data?
+      if( position >= 0 ) {
+        // End of relevant data?
+        if( /*!encode &&*/ position >= numSigBytes ){
+          return -1;
+        }   // end if: got data
+
+        if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) {
+          lineLength = 0;
+          return '\n';
+        }   // end if
+        else {
+          lineLength++;   // This isn't important when decoding
+          // but throwing an extra "if" seems
+          // just as wasteful.
+
+          int b = buffer[ position++ ];
+
+          if( position >= bufferLength ) {
+            position = -1;
+          }   // end if: end
+
+          return b & 0xFF; // This is how you "cast" a byte that's
+          // intended to be unsigned.
+        }   // end else
+      }   // end if: position >= 0
+
+      // Else error
+      else {
+        throw new java.io.IOException( "Error in Base64 code reading stream." );
+      }   // end else
+    }   // end read
+
+
+    /**
+     * Calls {@link #read()} repeatedly until the end of stream
+     * is reached or <var>len</var> bytes are read.
+     * Returns number of bytes read into array or -1 if
+     * end of stream is encountered.
+     *
+     * @param dest array to hold values
+     * @param off offset for array
+     * @param len max number of bytes to read into array
+     * @return bytes read into array or -1 if end of stream is encountered.
+     * @since 1.3
+     */
+    @Override
+    public int read( byte[] dest, int off, int len )
+        throws java.io.IOException {
+      int i;
+      int b;
+      for( i = 0; i < len; i++ ) {
+        b = read();
+
+        if( b >= 0 ) {
+          dest[off + i] = (byte) b;
+        }
+        else if( i == 0 ) {
+          return -1;
+        }
+        else {
+          break; // Out of 'for' loop
+        } // Out of 'for' loop
+      }   // end for: each byte read
+      return i;
+    }   // end read
+
+  }   // end inner class InputStream
+    
+    
+    
+    
+    
+    
+    /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
+
+
+
+  /**
+   * A {@link Base64.OutputStream} will write data to another
+   * <tt>java.io.OutputStream</tt>, given in the constructor,
+   * and encode/decode to/from Base64 notation on the fly.
+   *
+   * @see Base64
+   * @since 1.3
+   */
+  public static class OutputStream extends java.io.FilterOutputStream {
+
+    private boolean encode;
+    private int     position;
+    private byte[]  buffer;
+    private int     bufferLength;
+    private int     lineLength;
+    private boolean breakLines;
+    private byte[]  b4;         // Scratch used in a few places
+    private boolean suspendEncoding;
+    private int     options;    // Record for later
+    private byte[]  decodabet;  // Local copies to avoid extra method calls
+
+    /**
+     * Constructs a {@link Base64.OutputStream} in ENCODE mode.
+     *
+     * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
+     * @since 1.3
+     */
+    public OutputStream( java.io.OutputStream out ) {
+      this( out, ENCODE );
+    }   // end constructor
+
+
+    /**
+     * Constructs a {@link Base64.OutputStream} in
+     * either ENCODE or DECODE mode.
+     * <p>
+     * Valid options:<pre>
+     *   ENCODE or DECODE: Encode or Decode as data is read.
+     *   DO_BREAK_LINES: don't break lines at 76 characters
+     *     (only meaningful when encoding)
+     * </pre>
+     * <p>
+     * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
+     *
+     * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
+     * @param options Specified options.
+     * @see Base64#ENCODE
+     * @see Base64#DECODE
+     * @see Base64#DO_BREAK_LINES
+     * @since 1.3
+     */
+    public OutputStream( java.io.OutputStream out, int options ) {
+      super( out );
+      this.breakLines   = (options & DO_BREAK_LINES) != 0;
+      this.encode       = (options & ENCODE) != 0;
+      this.bufferLength = encode ? 3 : 4;
+      this.buffer       = new byte[ bufferLength ];
+      this.position     = 0;
+      this.lineLength   = 0;
+      this.suspendEncoding = false;
+      this.b4           = new byte[4];
+      this.options      = options;
+      this.decodabet    = getDecodabet(options);
+    }   // end constructor
+
+
+    /**
+     * Writes the byte to the output stream after
+     * converting to/from Base64 notation.
+     * When encoding, bytes are buffered three
+     * at a time before the output stream actually
+     * gets a write() call.
+     * When decoding, bytes are buffered four
+     * at a time.
+     *
+     * @param theByte the byte to write
+     * @since 1.3
+     */
+    @Override
+    public void write(int theByte)
+        throws java.io.IOException {
+      // Encoding suspended?
+      if( suspendEncoding ) {
+        this.out.write( theByte );
+        return;
+      }   // end if: supsended
+
+      // Encode?
+      if( encode ) {
+        buffer[ position++ ] = (byte)theByte;
+        if( position >= bufferLength ) { // Enough to encode.
+
+          this.out.write( encode3to4( b4, buffer, bufferLength, options ) );
+
+          lineLength += 4;
+          if( breakLines && lineLength >= MAX_LINE_LENGTH ) {
+            this.out.write( NEW_LINE );
+            lineLength = 0;
+          }   // end if: end of line
+
+          position = 0;
+        }   // end if: enough to output
+      }   // end if: encoding
+
+      // Else, Decoding
+      else {
+        // Meaningful Base64 character?
+        if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) {
+          buffer[ position++ ] = (byte)theByte;
+          if( position >= bufferLength ) { // Enough to output.
+
+            int len = Base64.decode4to3( buffer, 0, b4, 0, options );
+            out.write( b4, 0, len );
+            position = 0;
+          }   // end if: enough to output
+        }   // end if: meaningful base64 character
+        else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) {
+          throw new java.io.IOException( "Invalid character in Base64 data." );
+        }   // end else: not white space either
+      }   // end else: decoding
+    }   // end write
+
+
+
+    /**
+     * Calls {@link #write(int)} repeatedly until <var>len</var>
+     * bytes are written.
+     *
+     * @param theBytes array from which to read bytes
+     * @param off offset for array
+     * @param len max number of bytes to read into array
+     * @since 1.3
+     */
+    @Override
+    public void write( byte[] theBytes, int off, int len )
+        throws java.io.IOException {
+      // Encoding suspended?
+      if( suspendEncoding ) {
+        this.out.write( theBytes, off, len );
+        return;
+      }   // end if: supsended
+
+      for( int i = 0; i < len; i++ ) {
+        write( theBytes[ off + i ] );
+      }   // end for: each byte written
+
+    }   // end write
+
+
+
+    /**
+     * Method added by PHIL. [Thanks, PHIL. -Rob]
+     * This pads the buffer without closing the stream.
+     * @throws java.io.IOException  if there's an error.
+     */
+    public void flushBase64() throws java.io.IOException  {
+      if( position > 0 ) {
+        if( encode ) {
+          out.write( encode3to4( b4, buffer, position, options ) );
+          position = 0;
+        }   // end if: encoding
+        else {
+          throw new java.io.IOException( "Base64 input not properly padded." );
+        }   // end else: decoding
+      }   // end if: buffer partially full
+
+    }   // end flush
+
+
+    /**
+     * Flushes and closes (I think, in the superclass) the stream.
+     *
+     * @since 1.3
+     */
+    @Override
+    public void close() throws java.io.IOException {
+      // 1. Ensure that pending characters are written
+      flushBase64();
+
+      // 2. Actually close the stream
+      // Base class both flushes and closes.
+      super.close();
+
+      buffer = null;
+      out    = null;
+    }   // end close
+
+
+
+    /**
+     * Suspends encoding of the stream.
+     * May be helpful if you need to embed a piece of
+     * base64-encoded data in a stream.
+     *
+     * @throws java.io.IOException  if there's an error flushing
+     * @since 1.5.1
+     */
+    public void suspendEncoding() throws java.io.IOException  {
+      flushBase64();
+      this.suspendEncoding = true;
+    }   // end suspendEncoding
+
+
+    /**
+     * Resumes encoding of the stream.
+     * May be helpful if you need to embed a piece of
+     * base64-encoded data in a stream.
+     *
+     * @since 1.5.1
+     */
+    public void resumeEncoding() {
+      this.suspendEncoding = false;
+    }   // end resumeEncoding
+
+
+
+  }   // end inner class OutputStream
+
+
+}   // end class Base64
+
+//CHECKSTYLE: ON
+
+// End Base64.java


[12/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/InternalProperty.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/InternalProperty.java b/avatica/src/main/java/org/apache/calcite/avatica/InternalProperty.java
deleted file mode 100644
index a5a3852..0000000
--- a/avatica/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/blob/5cee486f/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
deleted file mode 100644
index 4cc460c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
+++ /dev/null
@@ -1,1272 +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 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.ByteString;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-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
-   */
-  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      long maxRowCount, PrepareCallback callback) 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
-   */
-  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
-      long maxRowCount) 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. */
-  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-set 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. Analogy 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. Analogy to
-   * {@link Connection#rollback()};
-   *
-   * @param ch A reference to the real JDBC Connection.
-   */
-  void rollback(ConnectionHandle ch);
-
-  /** Sync 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);
-
-    public final Class<?> type;
-    public final Object defaultValue;
-    public final Method method;
-
-    <T> DatabaseProperty(T defaultValue) {
-      this.defaultValue = defaultValue;
-      final String methodName = AvaticaUtils.toCamelCase(name());
-      try {
-        this.method = DatabaseMetaData.class.getMethod(methodName);
-      } catch (NoSuchMethodException e) {
-        throw new RuntimeException(e);
-      }
-      this.type = AvaticaUtils.box(method.getReturnType());
-      assert 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;
-    }
-  }
-
-  /** 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") int 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) {
-                columnBuilder.addArrayValue(serializeScalar(listItem));
-              }
-            } else {
-              // The default value, but still explicit.
-              columnBuilder.setHasArrayValue(false);
-              // Only one value for this column, a scalar.
-              columnBuilder.setScalarValue(serializeScalar(element));
-            }
-
-            // 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();
-
-      // 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);
-      } 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(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.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(getScalarValue(columnValue));
-        }
-        return array;
-      } else {
-        return getScalarValue(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(getScalarValue(arrayValue));
-        }
-        return array;
-      } else {
-        // Scalar
-        return getScalarValue(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 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 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() {
-      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. */
-  class ConnectionHandle {
-    public final String id;
-
-    @Override public String toString() {
-      return id;
-    }
-
-    @JsonCreator
-    public ConnectionHandle(@JsonProperty("id") String id) {
-      this.id = id;
-    }
-  }
-
-  /** Statement handle. */
-  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

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
deleted file mode 100644
index 7bb99fc..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
+++ /dev/null
@@ -1,961 +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.remote.TypedValue;
-import org.apache.calcite.avatica.util.ArrayIteratorCursor;
-import org.apache.calcite.avatica.util.Cursor;
-import org.apache.calcite.avatica.util.IteratorCursor;
-import org.apache.calcite.avatica.util.ListIteratorCursor;
-import org.apache.calcite.avatica.util.MapIteratorCursor;
-import org.apache.calcite.avatica.util.RecordIteratorCursor;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-/**
- * Basic implementation of {@link Meta}.
- *
- * <p>Each sub-class must implement the two remaining abstract methods,
- * {@link #prepare} and
- * {@link #prepareAndExecute}.
- * It should also override metadata methods such as {@link #getCatalogs(Meta.ConnectionHandle)} and
- * {@link #getTables} for the element types for which it has instances; the
- * default metadata methods return empty collections.
- */
-public abstract class MetaImpl implements Meta {
-  /** The {@link AvaticaConnection} backing {@code this}. */
-  protected final AvaticaConnection connection;
-  /** Represents the various states specific to {@link #connection}.
-   *
-   * <p>Note: this instance is used recursively with {@link #connection}'s getter and setter
-   * methods.</p>
-   */
-  protected final ConnectionPropertiesImpl connProps;
-
-  public MetaImpl(AvaticaConnection connection) {
-    this.connection = connection;
-    this.connProps = new ConnectionPropertiesImpl();
-  }
-
-  /** Uses a {@link org.apache.calcite.avatica.Meta.CursorFactory} to convert
-   * an {@link Iterable} into a
-   * {@link org.apache.calcite.avatica.util.Cursor}. */
-  public static Cursor createCursor(CursorFactory cursorFactory,
-      Iterable<Object> iterable) {
-    switch (cursorFactory.style) {
-    case OBJECT:
-      return new IteratorCursor<Object>(iterable.iterator()) {
-        protected Getter createGetter(int ordinal) {
-          return new ObjectGetter(ordinal);
-        }
-      };
-    case ARRAY:
-      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
-          (Iterable<Object[]>) (Iterable) iterable;
-      return new ArrayIteratorCursor(iterable1.iterator());
-    case RECORD:
-      @SuppressWarnings("unchecked") final Class<Object> clazz =
-          cursorFactory.clazz;
-      return new RecordIteratorCursor<Object>(iterable.iterator(), clazz);
-    case RECORD_PROJECTION:
-      @SuppressWarnings("unchecked") final Class<Object> clazz2 =
-          cursorFactory.clazz;
-      return new RecordIteratorCursor<Object>(iterable.iterator(), clazz2,
-          cursorFactory.fields);
-    case LIST:
-      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
-          (Iterable<List<Object>>) (Iterable) iterable;
-      return new ListIteratorCursor(iterable2.iterator());
-    case MAP:
-      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
-          iterable3 =
-          (Iterable<Map<String, Object>>) (Iterable) iterable;
-      return new MapIteratorCursor(iterable3.iterator(),
-          cursorFactory.fieldNames);
-    default:
-      throw new AssertionError("unknown style: " + cursorFactory.style);
-    }
-  }
-
-  public static List<List<Object>> collect(CursorFactory cursorFactory,
-      final Iterator<Object> iterator, List<List<Object>> list) {
-    final Iterable<Object> iterable = new Iterable<Object>() {
-      public Iterator<Object> iterator() {
-        return iterator;
-      }
-    };
-    return collect(cursorFactory, iterable, list);
-  }
-
-  public static List<List<Object>> collect(CursorFactory cursorFactory,
-      Iterable<Object> iterable, final List<List<Object>> list) {
-    switch (cursorFactory.style) {
-    case OBJECT:
-      for (Object o : iterable) {
-        list.add(Collections.singletonList(o));
-      }
-      return list;
-    case ARRAY:
-      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
-          (Iterable<Object[]>) (Iterable) iterable;
-      for (Object[] objects : iterable1) {
-        list.add(Arrays.asList(objects));
-      }
-      return list;
-    case RECORD:
-    case RECORD_PROJECTION:
-      final Field[] fields;
-      switch (cursorFactory.style) {
-      case RECORD:
-        fields = cursorFactory.clazz.getFields();
-        break;
-      default:
-        fields = cursorFactory.fields.toArray(
-            new Field[cursorFactory.fields.size()]);
-      }
-      for (Object o : iterable) {
-        final Object[] objects = new Object[fields.length];
-        for (int i = 0; i < fields.length; i++) {
-          Field field = fields[i];
-          try {
-            objects[i] = field.get(o);
-          } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
-          }
-        }
-        list.add(Arrays.asList(objects));
-      }
-      return list;
-    case LIST:
-      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
-          (Iterable<List<Object>>) (Iterable) iterable;
-      for (List<Object> objects : iterable2) {
-        list.add(objects);
-      }
-      return list;
-    case MAP:
-      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
-          iterable3 =
-          (Iterable<Map<String, Object>>) (Iterable) iterable;
-      for (Map<String, Object> map : iterable3) {
-        final List<Object> objects = new ArrayList<Object>();
-        for (String fieldName : cursorFactory.fieldNames) {
-          objects.add(map.get(fieldName));
-        }
-        list.add(objects);
-      }
-      return list;
-    default:
-      throw new AssertionError("unknown style: " + cursorFactory.style);
-    }
-  }
-
-  @Override public void openConnection(ConnectionHandle ch, Map<String, String> info) {
-    // dummy implementation, connection is already created at this point
-  }
-
-  @Override public void closeConnection(ConnectionHandle ch) {
-    // TODO: implement
-    //
-    // lots of Calcite tests break with this simple implementation,
-    // requires investigation
-
-//    try {
-//      connection.close();
-//    } catch (SQLException e) {
-//      throw new RuntimeException(e);
-//    }
-  }
-
-  @Override public ConnectionProperties connectionSync(ConnectionHandle ch,
-      ConnectionProperties connProps) {
-    this.connProps.merge(connProps);
-    this.connProps.setDirty(false);
-    return this.connProps;
-  }
-
-  public StatementHandle createStatement(ConnectionHandle ch) {
-    return new StatementHandle(ch.id, connection.statementCount++, null);
-  }
-
-  /** Creates an empty result set. Useful for JDBC metadata methods that are
-   * not implemented or which query entities that are not supported (e.g.
-   * triggers in Lingual). */
-  protected <E> MetaResultSet createEmptyResultSet(final Class<E> clazz) {
-    return createResultSet(Collections.<String, Object>emptyMap(),
-        fieldMetaData(clazz).columns,
-        CursorFactory.deduce(fieldMetaData(clazz).columns, null),
-        Frame.EMPTY);
-  }
-
-  public static ColumnMetaData columnMetaData(String name, int index,
-      Class<?> type) {
-    TypeInfo pair = TypeInfo.m.get(type);
-    ColumnMetaData.Rep rep =
-        ColumnMetaData.Rep.VALUE_MAP.get(type);
-    ColumnMetaData.AvaticaType scalarType =
-        ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
-    return new ColumnMetaData(
-        index, false, true, false, false,
-        pair.primitive
-            ? DatabaseMetaData.columnNullable
-            : DatabaseMetaData.columnNoNulls,
-        true, -1, name, name, null,
-        0, 0, null, null, scalarType, true, false, false,
-        scalarType.columnClassName());
-  }
-
-  protected static ColumnMetaData.StructType fieldMetaData(Class clazz) {
-    final List<ColumnMetaData> list = new ArrayList<ColumnMetaData>();
-    for (Field field : clazz.getFields()) {
-      if (Modifier.isPublic(field.getModifiers())
-          && !Modifier.isStatic(field.getModifiers())) {
-        list.add(
-            columnMetaData(
-                AvaticaUtils.camelToUpper(field.getName()),
-                list.size() + 1, field.getType()));
-      }
-    }
-    return ColumnMetaData.struct(list);
-  }
-
-  protected MetaResultSet createResultSet(
-      Map<String, Object> internalParameters, List<ColumnMetaData> columns,
-      CursorFactory cursorFactory, Frame firstFrame) {
-    try {
-      final AvaticaStatement statement = connection.createStatement();
-      final Signature signature =
-          new Signature(columns, "", Collections.<AvaticaParameter>emptyList(),
-              internalParameters, cursorFactory, Meta.StatementType.SELECT);
-      return MetaResultSet.create(connection.id, statement.getId(), true,
-          signature, firstFrame);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /** An object that has a name. */
-  public interface Named {
-    @JsonIgnore String getName();
-  }
-
-  /** Metadata describing a column. */
-  public static class MetaColumn implements Named {
-    public final String tableCat;
-    public final String tableSchem;
-    public final String tableName;
-    public final String columnName;
-    public final int dataType;
-    public final String typeName;
-    public final int columnSize;
-    public final String bufferLength = null;
-    public final Integer decimalDigits;
-    public final int numPrecRadix;
-    public final int nullable;
-    public final String remarks = null;
-    public final String columnDef = null;
-    public final String sqlDataType = null;
-    public final String sqlDatetimeSub = null;
-    public final int charOctetLength;
-    public final int ordinalPosition;
-    public final String isNullable;
-    public final String scopeCatalog = null;
-    public final String scopeSchema = null;
-    public final String scopeTable = null;
-    public final String sourceDataType = null;
-    public final String isAutoincrement = null;
-    public final String isGeneratedcolumn = null;
-
-    public MetaColumn(
-        String tableCat,
-        String tableSchem,
-        String tableName,
-        String columnName,
-        int dataType,
-        String typeName,
-        int columnSize,
-        Integer decimalDigits,
-        int numPrecRadix,
-        int nullable,
-        int charOctetLength,
-        int ordinalPosition,
-        String isNullable) {
-      this.tableCat = tableCat;
-      this.tableSchem = tableSchem;
-      this.tableName = tableName;
-      this.columnName = columnName;
-      this.dataType = dataType;
-      this.typeName = typeName;
-      this.columnSize = columnSize;
-      this.decimalDigits = decimalDigits;
-      this.numPrecRadix = numPrecRadix;
-      this.nullable = nullable;
-      this.charOctetLength = charOctetLength;
-      this.ordinalPosition = ordinalPosition;
-      this.isNullable = isNullable;
-    }
-
-    public String getName() {
-      return columnName;
-    }
-  }
-
-  /** Metadata describing a TypeInfo. */
-
-  /** Metadata describing a table. */
-  public static class MetaTable implements Named {
-    public final String tableCat;
-    public final String tableSchem;
-    public final String tableName;
-    public final String tableType;
-    public final String remarks = null;
-    public final String typeCat = null;
-    public final String typeSchem = null;
-    public final String typeName = null;
-    public final String selfReferencingColName = null;
-    public final String refGeneration = null;
-
-    public MetaTable(String tableCat,
-        String tableSchem,
-        String tableName,
-        String tableType) {
-      this.tableCat = tableCat;
-      this.tableSchem = tableSchem;
-      this.tableName = tableName;
-      this.tableType = tableType;
-    }
-
-    public String getName() {
-      return tableName;
-    }
-  }
-
-  /** Metadata describing a schema. */
-  public static class MetaSchema implements Named {
-    public final String tableCatalog;
-    public final String tableSchem;
-
-    public MetaSchema(
-        String tableCatalog,
-        String tableSchem) {
-      this.tableCatalog = tableCatalog;
-      this.tableSchem = tableSchem;
-    }
-
-    public String getName() {
-      return tableSchem;
-    }
-  }
-
-  /** Metadata describing a catalog. */
-  public static class MetaCatalog implements Named {
-    public final String tableCat;
-
-    public MetaCatalog(
-        String tableCatalog) {
-      this.tableCat = tableCatalog;
-    }
-
-    public String getName() {
-      return tableCat;
-    }
-  }
-
-  /** Metadata describing a table type. */
-  public static class MetaTableType {
-    public final String tableType;
-
-    public MetaTableType(String tableType) {
-      this.tableType = tableType;
-    }
-  }
-
-  /** Metadata describing a procedure. */
-  public static class MetaProcedure {
-  }
-
-  /** Metadata describing a procedure column. */
-  public static class MetaProcedureColumn {
-  }
-
-  /** Metadata describing a column privilege. */
-  public static class MetaColumnPrivilege {
-  }
-
-  /** Metadata describing a table privilege. */
-  public static class MetaTablePrivilege {
-  }
-
-  /** Metadata describing the best identifier for a row. */
-  public static class MetaBestRowIdentifier {
-  }
-
-  /** Metadata describing a version column. */
-  public static class MetaVersionColumn {
-    public final short scope;
-    public final String columnName;
-    public final int dataType;
-    public final String typeName;
-    public final int columnSize;
-    public final int bufferLength;
-    public final short decimalDigits;
-    public final short pseudoColumn;
-
-    MetaVersionColumn(short scope, String columnName, int dataType,
-        String typeName, int columnSize, int bufferLength, short decimalDigits,
-        short pseudoColumn) {
-      this.scope = scope;
-      this.columnName = columnName;
-      this.dataType = dataType;
-      this.typeName = typeName;
-      this.columnSize = columnSize;
-      this.bufferLength = bufferLength;
-      this.decimalDigits = decimalDigits;
-      this.pseudoColumn = pseudoColumn;
-    }
-  }
-
-  /** Metadata describing a primary key. */
-  public static class MetaPrimaryKey {
-    public final String tableCat;
-    public final String tableSchem;
-    public final String tableName;
-    public final String columnName;
-    public final short keySeq;
-    public final String pkName;
-
-    MetaPrimaryKey(String tableCat, String tableSchem, String tableName,
-        String columnName, short keySeq, String pkName) {
-      this.tableCat = tableCat;
-      this.tableSchem = tableSchem;
-      this.tableName = tableName;
-      this.columnName = columnName;
-      this.keySeq = keySeq;
-      this.pkName = pkName;
-    }
-  }
-
-  /** Metadata describing an imported key. */
-  public static class MetaImportedKey {
-  }
-
-  /** Metadata describing an exported key. */
-  public static class MetaExportedKey {
-  }
-
-  /** Metadata describing a cross reference. */
-  public static class MetaCrossReference {
-  }
-
-  /** Metadata describing type info. */
-  public static class MetaTypeInfo implements Named {
-    public final String typeName;
-    public final int dataType;
-    public final int precision;
-    public final String literalPrefix;
-    public final String literalSuffix;
-    //TODO: Add create parameter for type on DDL
-    public final String createParams = null;
-    public final int nullable;
-    public final boolean caseSensitive;
-    public final int searchable;
-    public final boolean unsignedAttribute;
-    public final boolean fixedPrecScale;
-    public final boolean autoIncrement;
-    public final String localTypeName;
-    public final int minimumScale;
-    public final int maximumScale;
-    public final int sqlDataType = 0;
-    public final int sqlDatetimeSub = 0;
-    public final Integer numPrecRadix; //nullable int
-
-    public MetaTypeInfo(
-        String typeName,
-        int dataType,
-        int precision,
-        String literalPrefix,
-        String literalSuffix,
-        int nullable,
-        boolean caseSensitive,
-        int searchable,
-        boolean unsignedAttribute,
-        boolean fixedPrecScale,
-        boolean autoIncrement,
-        int minimumScale,
-        int maximumScale,
-        int numPrecRadix) {
-      this.typeName = typeName;
-      this.dataType = dataType;
-      this.precision = precision;
-      this.literalPrefix = literalPrefix;
-      this.literalSuffix = literalSuffix;
-      this.nullable = nullable;
-      this.caseSensitive = caseSensitive;
-      this.searchable = searchable;
-      this.unsignedAttribute = unsignedAttribute;
-      this.fixedPrecScale = fixedPrecScale;
-      this.autoIncrement = autoIncrement;
-      this.localTypeName = typeName;
-      // Make min to be 0 instead of -1
-      this.minimumScale = minimumScale == -1 ? 0 : minimumScale;
-      this.maximumScale = maximumScale == -1 ? 0 : maximumScale;
-      this.numPrecRadix = numPrecRadix == 0 ? null : numPrecRadix;
-    }
-
-    public String getName() {
-      return typeName;
-    }
-  }
-
-  /** Metadata describing index info. */
-  public static class MetaIndexInfo {
-  }
-
-  /** Metadata describing a user-defined type. */
-  public static class MetaUdt {
-  }
-
-  /** Metadata describing a super-type. */
-  public static class MetaSuperType {
-  }
-
-  /** Metadata describing an attribute. */
-  public static class MetaAttribute {
-  }
-
-  /** Metadata describing a client info property. */
-  public static class MetaClientInfoProperty {
-  }
-
-  /** Metadata describing a function. */
-  public static class MetaFunction {
-  }
-
-  /** Metadata describing a function column. */
-  public static class MetaFunctionColumn {
-  }
-
-  /** Metadata describing a pseudo column. */
-  public static class MetaPseudoColumn {
-  }
-
-  /** Metadata describing a super-table. */
-  public static class MetaSuperTable {
-  }
-
-  public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
-    return Collections.emptyMap();
-  }
-
-  public MetaResultSet getTables(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      List<String> typeList) {
-    return createEmptyResultSet(MetaTable.class);
-  }
-
-  public MetaResultSet getColumns(ConnectionHandle ch, String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      Pat columnNamePattern) {
-    return createEmptyResultSet(MetaColumn.class);
-  }
-
-  public MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat schemaPattern) {
-    return createEmptyResultSet(MetaSchema.class);
-  }
-
-  public MetaResultSet getCatalogs(ConnectionHandle ch) {
-    return createEmptyResultSet(MetaCatalog.class);
-  }
-
-  public MetaResultSet getTableTypes(ConnectionHandle ch) {
-    return createEmptyResultSet(MetaTableType.class);
-  }
-
-  public MetaResultSet getProcedures(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat procedureNamePattern) {
-    return createEmptyResultSet(MetaProcedure.class);
-  }
-
-  public MetaResultSet getProcedureColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat procedureNamePattern,
-      Pat columnNamePattern) {
-    return createEmptyResultSet(MetaProcedureColumn.class);
-  }
-
-  public MetaResultSet getColumnPrivileges(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table,
-      Pat columnNamePattern) {
-    return createEmptyResultSet(MetaColumnPrivilege.class);
-  }
-
-  public MetaResultSet getTablePrivileges(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern) {
-    return createEmptyResultSet(MetaTablePrivilege.class);
-  }
-
-  public MetaResultSet getBestRowIdentifier(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table,
-      int scope,
-      boolean nullable) {
-    return createEmptyResultSet(MetaBestRowIdentifier.class);
-  }
-
-  public MetaResultSet getVersionColumns(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table) {
-    return createEmptyResultSet(MetaVersionColumn.class);
-  }
-
-  public MetaResultSet getPrimaryKeys(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table) {
-    return createEmptyResultSet(MetaPrimaryKey.class);
-  }
-
-  public MetaResultSet getImportedKeys(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table) {
-    return createEmptyResultSet(MetaImportedKey.class);
-  }
-
-  public MetaResultSet getExportedKeys(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table) {
-    return createEmptyResultSet(MetaExportedKey.class);
-  }
-
-  public MetaResultSet getCrossReference(ConnectionHandle ch,
-      String parentCatalog,
-      String parentSchema,
-      String parentTable,
-      String foreignCatalog,
-      String foreignSchema,
-      String foreignTable) {
-    return createEmptyResultSet(MetaCrossReference.class);
-  }
-
-  public MetaResultSet getTypeInfo(ConnectionHandle ch) {
-    return createEmptyResultSet(MetaTypeInfo.class);
-  }
-
-  public MetaResultSet getIndexInfo(ConnectionHandle ch,
-      String catalog,
-      String schema,
-      String table,
-      boolean unique,
-      boolean approximate) {
-    return createEmptyResultSet(MetaIndexInfo.class);
-  }
-
-  public MetaResultSet getUDTs(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern,
-      int[] types) {
-    return createEmptyResultSet(MetaUdt.class);
-  }
-
-  public MetaResultSet getSuperTypes(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern) {
-    return createEmptyResultSet(MetaSuperType.class);
-  }
-
-  public MetaResultSet getSuperTables(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern) {
-    return createEmptyResultSet(MetaSuperTable.class);
-  }
-
-  public MetaResultSet getAttributes(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat typeNamePattern,
-      Pat attributeNamePattern) {
-    return createEmptyResultSet(MetaAttribute.class);
-  }
-
-  public MetaResultSet getClientInfoProperties(ConnectionHandle ch) {
-    return createEmptyResultSet(MetaClientInfoProperty.class);
-  }
-
-  public MetaResultSet getFunctions(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat functionNamePattern) {
-    return createEmptyResultSet(MetaFunction.class);
-  }
-
-  public MetaResultSet getFunctionColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat functionNamePattern,
-      Pat columnNamePattern) {
-    return createEmptyResultSet(MetaFunctionColumn.class);
-  }
-
-  public MetaResultSet getPseudoColumns(ConnectionHandle ch,
-      String catalog,
-      Pat schemaPattern,
-      Pat tableNamePattern,
-      Pat columnNamePattern) {
-    return createEmptyResultSet(MetaPseudoColumn.class);
-  }
-
-  @Override public Iterable<Object> createIterable(StatementHandle handle, QueryState state,
-      Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
-    if (firstFrame != null && firstFrame.done) {
-      return firstFrame.rows;
-    }
-    AvaticaStatement stmt;
-    try {
-      stmt = connection.lookupStatement(handle);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-    return new FetchIterable(stmt, state,
-        firstFrame, parameterValues);
-  }
-
-  public Frame fetch(AvaticaStatement stmt, List<TypedValue> parameterValues,
-      long offset, int fetchMaxRowCount) throws NoSuchStatementException, MissingResultsException {
-    return null;
-  }
-
-  /** Information about a type. */
-  private static class TypeInfo {
-    private static Map<Class<?>, TypeInfo> m =
-        new HashMap<Class<?>, TypeInfo>();
-    static {
-      put(boolean.class, true, Types.BOOLEAN, "BOOLEAN");
-      put(Boolean.class, false, Types.BOOLEAN, "BOOLEAN");
-      put(byte.class, true, Types.TINYINT, "TINYINT");
-      put(Byte.class, false, Types.TINYINT, "TINYINT");
-      put(short.class, true, Types.SMALLINT, "SMALLINT");
-      put(Short.class, false, Types.SMALLINT, "SMALLINT");
-      put(int.class, true, Types.INTEGER, "INTEGER");
-      put(Integer.class, false, Types.INTEGER, "INTEGER");
-      put(long.class, true, Types.BIGINT, "BIGINT");
-      put(Long.class, false, Types.BIGINT, "BIGINT");
-      put(float.class, true, Types.FLOAT, "FLOAT");
-      put(Float.class, false, Types.FLOAT, "FLOAT");
-      put(double.class, true, Types.DOUBLE, "DOUBLE");
-      put(Double.class, false, Types.DOUBLE, "DOUBLE");
-      put(String.class, false, Types.VARCHAR, "VARCHAR");
-      put(java.sql.Date.class, false, Types.DATE, "DATE");
-      put(Time.class, false, Types.TIME, "TIME");
-      put(Timestamp.class, false, Types.TIMESTAMP, "TIMESTAMP");
-    }
-
-    private final boolean primitive;
-    private final int sqlType;
-    private final String sqlTypeName;
-
-    public TypeInfo(boolean primitive, int sqlType, String sqlTypeName) {
-      this.primitive = primitive;
-      this.sqlType = sqlType;
-      this.sqlTypeName = sqlTypeName;
-    }
-
-    static void put(Class clazz, boolean primitive, int sqlType,
-        String sqlTypeName) {
-      m.put(clazz, new TypeInfo(primitive, sqlType, sqlTypeName));
-    }
-  }
-
-  /** Iterator that never returns any elements. */
-  private static class EmptyIterator implements Iterator<Object> {
-    public static final Iterator<Object> INSTANCE = new EmptyIterator();
-
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-
-    public boolean hasNext() {
-      return false;
-    }
-
-    public Object next() {
-      throw new NoSuchElementException();
-    }
-  }
-
-  /** Iterable that yields an iterator over rows coming from a sequence of
-   * {@link Meta.Frame}s. */
-  private class FetchIterable implements Iterable<Object> {
-    private final AvaticaStatement stmt;
-    private final QueryState state;
-    private final Frame firstFrame;
-    private final List<TypedValue> parameterValues;
-
-    public FetchIterable(AvaticaStatement stmt, QueryState state, Frame firstFrame,
-        List<TypedValue> parameterValues) {
-      this.stmt = stmt;
-      this.state = state;
-      this.firstFrame = firstFrame;
-      this.parameterValues = parameterValues;
-    }
-
-    public Iterator<Object> iterator() {
-      return new FetchIterator(stmt, state, firstFrame, parameterValues);
-    }
-  }
-
-  /** Iterator over rows coming from a sequence of {@link Meta.Frame}s. */
-  private class FetchIterator implements Iterator<Object> {
-    private final AvaticaStatement stmt;
-    private final QueryState state;
-    private Frame frame;
-    private Iterator<Object> rows;
-    private List<TypedValue> parameterValues;
-    private List<TypedValue> originalParameterValues;
-    private long currentOffset = 0;
-
-    public FetchIterator(AvaticaStatement stmt, QueryState state, Frame firstFrame,
-        List<TypedValue> parameterValues) {
-      this.stmt = stmt;
-      this.state = state;
-      this.parameterValues = parameterValues;
-      this.originalParameterValues = parameterValues;
-      if (firstFrame == null) {
-        frame = Frame.MORE;
-        rows = EmptyIterator.INSTANCE;
-      } else {
-        frame = firstFrame;
-        rows = firstFrame.rows.iterator();
-      }
-      moveNext();
-    }
-
-    public void remove() {
-      throw new UnsupportedOperationException("remove");
-    }
-
-    public boolean hasNext() {
-      return rows != null;
-    }
-
-    public Object next() {
-      if (rows == null) {
-        throw new NoSuchElementException();
-      }
-      final Object o = rows.next();
-      currentOffset++;
-      moveNext();
-      return o;
-    }
-
-    private void moveNext() {
-      for (;;) {
-        if (rows.hasNext()) {
-          break;
-        }
-        if (frame.done) {
-          rows = null;
-          break;
-        }
-        try {
-          // currentOffset updated after element is read from `rows` iterator
-          frame = fetch(stmt.handle, currentOffset, AvaticaStatement.DEFAULT_FETCH_SIZE);
-        } catch (NoSuchStatementException e) {
-          resetStatement();
-          // re-fetch the batch where we left off
-          continue;
-        } catch (MissingResultsException e) {
-          try {
-            // We saw the statement, but it didnt' have a resultset initialized. So, reset it.
-            if (!stmt.syncResults(state, currentOffset)) {
-              // This returned false, so there aren't actually any more results to iterate over
-              frame = null;
-              rows = null;
-              break;
-            }
-            // syncResults returning true means we need to fetch those results
-          } catch (NoSuchStatementException e1) {
-            // Tried to reset the result set, but lost the statement, save a loop before retrying.
-            resetStatement();
-            // Will just loop back around to a MissingResultsException, but w/e recursion
-          }
-          // Kick back to the top to try to fetch again (in both branches)
-          continue;
-        }
-        parameterValues = null; // don't execute next time
-        if (frame == null) {
-          rows = null;
-          break;
-        }
-        // It is valid for rows to be empty, so we go around the loop again to
-        // check
-        rows = frame.rows.iterator();
-      }
-    }
-
-    private void resetStatement() {
-      // If we have to reset the statement, we need to reset the parameterValues too
-      parameterValues = originalParameterValues;
-      // Defer to the statement to reset itself
-      stmt.resetStatement();
-    }
-  }
-
-  /** Returns whether a list of parameter values has any null elements. */
-  public static boolean checkParameterValueHasNull(List<TypedValue> parameterValues) {
-    for (TypedValue x : parameterValues) {
-      if (x == null) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-// End MetaImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/MissingResultsException.java b/avatica/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
deleted file mode 100644
index 7746769..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/MissingResultsException.java
+++ /dev/null
@@ -1,41 +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.Meta.StatementHandle;
-
-import java.sql.ResultSet;
-
-/**
- * An Exception which denotes that a cached Statement is present but has no {@link ResultSet}.
- */
-public class MissingResultsException extends Exception {
-
-  private static final long serialVersionUID = 1L;
-
-  private final StatementHandle handle;
-
-  public MissingResultsException(StatementHandle handle) {
-    this.handle = handle;
-  }
-
-  public StatementHandle getHandle() {
-    return handle;
-  }
-}
-
-// End MissingResultsException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java b/avatica/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
deleted file mode 100644
index b5a940d..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/NoSuchConnectionException.java
+++ /dev/null
@@ -1,37 +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;
-
-/**
- * An Exception that denotes that the given Connection is not cached.
- */
-public class NoSuchConnectionException extends RuntimeException {
-
-  private static final long serialVersionUID = 1L;
-
-  private final String connectionId;
-
-  public NoSuchConnectionException(String connectionId) {
-    this.connectionId = connectionId;
-  }
-
-  public String getConnectionId() {
-    return connectionId;
-  }
-}
-
-// End NoSuchConnectionException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java b/avatica/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
deleted file mode 100644
index 321011b..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/NoSuchStatementException.java
+++ /dev/null
@@ -1,39 +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.Meta.StatementHandle;
-
-/**
- * An Exception that denotes that the given Statement is not cached.
- */
-public class NoSuchStatementException extends Exception {
-
-  private static final long serialVersionUID = 1L;
-
-  private final StatementHandle stmtHandle;
-
-  public NoSuchStatementException(StatementHandle stmtHandle) {
-    this.stmtHandle = stmtHandle;
-  }
-
-  public StatementHandle getStatementHandle() {
-    return stmtHandle;
-  }
-}
-
-// End NoSuchStatementException.java


[39/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
new file mode 100644
index 0000000..6d34757
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
@@ -0,0 +1,12327 @@
+/*
+ * 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.
+ */
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: requests.proto
+
+package org.apache.calcite.avatica.proto;
+
+@SuppressWarnings({"unused", "rawtypes"}) public final class Requests {
+  private Requests() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface CatalogsRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:CatalogsRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+  }
+  /**
+   * Protobuf type {@code CatalogsRequest}
+   *
+   * <pre>
+   * Request for Meta#getCatalogs()
+   * </pre>
+   */
+  public  static final class CatalogsRequest extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:CatalogsRequest)
+      CatalogsRequestOrBuilder {
+    // Use CatalogsRequest.newBuilder() to construct.
+    private CatalogsRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private CatalogsRequest() {
+      connectionId_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private CatalogsRequest(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              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.Requests.internal_static_CatalogsRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Requests.CatalogsRequest.class, org.apache.calcite.avatica.proto.Requests.CatalogsRequest.Builder.class);
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 {
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest 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.Requests.CatalogsRequest 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 CatalogsRequest}
+     *
+     * <pre>
+     * Request for Meta#getCatalogs()
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:CatalogsRequest)
+        org.apache.calcite.avatica.proto.Requests.CatalogsRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Requests.CatalogsRequest.class, org.apache.calcite.avatica.proto.Requests.CatalogsRequest.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Requests.CatalogsRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        connectionId_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_CatalogsRequest_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Requests.CatalogsRequest.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest build() {
+        org.apache.calcite.avatica.proto.Requests.CatalogsRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.CatalogsRequest buildPartial() {
+        org.apache.calcite.avatica.proto.Requests.CatalogsRequest result = new org.apache.calcite.avatica.proto.Requests.CatalogsRequest(this);
+        result.connectionId_ = connectionId_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Requests.CatalogsRequest) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Requests.CatalogsRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.CatalogsRequest other) {
+        if (other == org.apache.calcite.avatica.proto.Requests.CatalogsRequest.getDefaultInstance()) return this;
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        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.Requests.CatalogsRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Requests.CatalogsRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object connectionId_ = "";
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public java.lang.String getConnectionId() {
+        java.lang.Object ref = connectionId_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          connectionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getConnectionIdBytes() {
+        java.lang.Object ref = connectionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          connectionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder clearConnectionId() {
+        
+        connectionId_ = getDefaultInstance().getConnectionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      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:CatalogsRequest)
+    }
+
+    // @@protoc_insertion_point(class_scope:CatalogsRequest)
+    private static final org.apache.calcite.avatica.proto.Requests.CatalogsRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.CatalogsRequest();
+    }
+
+    public static org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<CatalogsRequest>
+        PARSER = new com.google.protobuf.AbstractParser<CatalogsRequest>() {
+      public CatalogsRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new CatalogsRequest(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<CatalogsRequest> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CatalogsRequest> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Requests.CatalogsRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface DatabasePropertyRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:DatabasePropertyRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+  }
+  /**
+   * Protobuf type {@code DatabasePropertyRequest}
+   *
+   * <pre>
+   * Request for Meta#getDatabaseProperties()
+   * </pre>
+   */
+  public  static final class DatabasePropertyRequest extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:DatabasePropertyRequest)
+      DatabasePropertyRequestOrBuilder {
+    // Use DatabasePropertyRequest.newBuilder() to construct.
+    private DatabasePropertyRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private DatabasePropertyRequest() {
+      connectionId_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private DatabasePropertyRequest(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              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.Requests.internal_static_DatabasePropertyRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.class, org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.Builder.class);
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 {
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest 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.Requests.DatabasePropertyRequest 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 DatabasePropertyRequest}
+     *
+     * <pre>
+     * Request for Meta#getDatabaseProperties()
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:DatabasePropertyRequest)
+        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.class, org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        connectionId_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_DatabasePropertyRequest_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest build() {
+        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest buildPartial() {
+        org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest result = new org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest(this);
+        result.connectionId_ = connectionId_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest other) {
+        if (other == org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest.getDefaultInstance()) return this;
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        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.Requests.DatabasePropertyRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object connectionId_ = "";
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public java.lang.String getConnectionId() {
+        java.lang.Object ref = connectionId_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          connectionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getConnectionIdBytes() {
+        java.lang.Object ref = connectionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          connectionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder clearConnectionId() {
+        
+        connectionId_ = getDefaultInstance().getConnectionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 1;</code>
+       */
+      public Builder setConnectionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      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:DatabasePropertyRequest)
+    }
+
+    // @@protoc_insertion_point(class_scope:DatabasePropertyRequest)
+    private static final org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest();
+    }
+
+    public static org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<DatabasePropertyRequest>
+        PARSER = new com.google.protobuf.AbstractParser<DatabasePropertyRequest>() {
+      public DatabasePropertyRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new DatabasePropertyRequest(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<DatabasePropertyRequest> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DatabasePropertyRequest> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SchemasRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:SchemasRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    java.lang.String getCatalog();
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getCatalogBytes();
+
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    java.lang.String getSchemaPattern();
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getSchemaPatternBytes();
+
+    /**
+     * <code>optional string connection_id = 3;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+  }
+  /**
+   * Protobuf type {@code SchemasRequest}
+   *
+   * <pre>
+   * Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
+   * </pre>
+   */
+  public  static final class SchemasRequest extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:SchemasRequest)
+      SchemasRequestOrBuilder {
+    // Use SchemasRequest.newBuilder() to construct.
+    private SchemasRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private SchemasRequest() {
+      catalog_ = "";
+      schemaPattern_ = "";
+      connectionId_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private SchemasRequest(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              catalog_ = s;
+              break;
+            }
+            case 18: {
+              String s = input.readStringRequireUtf8();
+
+              schemaPattern_ = s;
+              break;
+            }
+            case 26: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              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.Requests.internal_static_SchemasRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Requests.SchemasRequest.class, org.apache.calcite.avatica.proto.Requests.SchemasRequest.Builder.class);
+    }
+
+    public static final int CATALOG_FIELD_NUMBER = 1;
+    private volatile java.lang.Object catalog_;
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    public java.lang.String getCatalog() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        catalog_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getCatalogBytes() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        catalog_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int SCHEMA_PATTERN_FIELD_NUMBER = 2;
+    private volatile java.lang.Object schemaPattern_;
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    public java.lang.String getSchemaPattern() {
+      java.lang.Object ref = schemaPattern_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        schemaPattern_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getSchemaPatternBytes() {
+      java.lang.Object ref = schemaPattern_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        schemaPattern_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 3;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 3;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 {
+      if (!getCatalogBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, catalog_);
+      }
+      if (!getSchemaPatternBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 2, schemaPattern_);
+      }
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 3, connectionId_);
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getCatalogBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, catalog_);
+      }
+      if (!getSchemaPatternBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, schemaPattern_);
+      }
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(3, connectionId_);
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest 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.Requests.SchemasRequest 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 SchemasRequest}
+     *
+     * <pre>
+     * Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:SchemasRequest)
+        org.apache.calcite.avatica.proto.Requests.SchemasRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Requests.SchemasRequest.class, org.apache.calcite.avatica.proto.Requests.SchemasRequest.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Requests.SchemasRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        catalog_ = "";
+
+        schemaPattern_ = "";
+
+        connectionId_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_SchemasRequest_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Requests.SchemasRequest.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.SchemasRequest build() {
+        org.apache.calcite.avatica.proto.Requests.SchemasRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.SchemasRequest buildPartial() {
+        org.apache.calcite.avatica.proto.Requests.SchemasRequest result = new org.apache.calcite.avatica.proto.Requests.SchemasRequest(this);
+        result.catalog_ = catalog_;
+        result.schemaPattern_ = schemaPattern_;
+        result.connectionId_ = connectionId_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Requests.SchemasRequest) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Requests.SchemasRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.SchemasRequest other) {
+        if (other == org.apache.calcite.avatica.proto.Requests.SchemasRequest.getDefaultInstance()) return this;
+        if (!other.getCatalog().isEmpty()) {
+          catalog_ = other.catalog_;
+          onChanged();
+        }
+        if (!other.getSchemaPattern().isEmpty()) {
+          schemaPattern_ = other.schemaPattern_;
+          onChanged();
+        }
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        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.Requests.SchemasRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Requests.SchemasRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object catalog_ = "";
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public java.lang.String getCatalog() {
+        java.lang.Object ref = catalog_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          catalog_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getCatalogBytes() {
+        java.lang.Object ref = catalog_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          catalog_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder setCatalog(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder clearCatalog() {
+        
+        catalog_ = getDefaultInstance().getCatalog();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder setCatalogBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object schemaPattern_ = "";
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public java.lang.String getSchemaPattern() {
+        java.lang.Object ref = schemaPattern_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          schemaPattern_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getSchemaPatternBytes() {
+        java.lang.Object ref = schemaPattern_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          schemaPattern_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder setSchemaPattern(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        schemaPattern_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder clearSchemaPattern() {
+        
+        schemaPattern_ = getDefaultInstance().getSchemaPattern();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder setSchemaPatternBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        schemaPattern_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object connectionId_ = "";
+      /**
+       * <code>optional string connection_id = 3;</code>
+       */
+      public java.lang.String getConnectionId() {
+        java.lang.Object ref = connectionId_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          connectionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getConnectionIdBytes() {
+        java.lang.Object ref = connectionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          connectionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string connection_id = 3;</code>
+       */
+      public Builder setConnectionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 3;</code>
+       */
+      public Builder clearConnectionId() {
+        
+        connectionId_ = getDefaultInstance().getConnectionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string connection_id = 3;</code>
+       */
+      public Builder setConnectionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        connectionId_ = value;
+        onChanged();
+        return this;
+      }
+      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:SchemasRequest)
+    }
+
+    // @@protoc_insertion_point(class_scope:SchemasRequest)
+    private static final org.apache.calcite.avatica.proto.Requests.SchemasRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Requests.SchemasRequest();
+    }
+
+    public static org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SchemasRequest>
+        PARSER = new com.google.protobuf.AbstractParser<SchemasRequest>() {
+      public SchemasRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new SchemasRequest(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<SchemasRequest> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SchemasRequest> getParserForType() {
+      return PARSER;
+    }
+
+    public org.apache.calcite.avatica.proto.Requests.SchemasRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface TablesRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:TablesRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    java.lang.String getCatalog();
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getCatalogBytes();
+
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    java.lang.String getSchemaPattern();
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getSchemaPatternBytes();
+
+    /**
+     * <code>optional string table_name_pattern = 3;</code>
+     */
+    java.lang.String getTableNamePattern();
+    /**
+     * <code>optional string table_name_pattern = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getTableNamePatternBytes();
+
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    com.google.protobuf.ProtocolStringList
+        getTypeListList();
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    int getTypeListCount();
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    java.lang.String getTypeList(int index);
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    com.google.protobuf.ByteString
+        getTypeListBytes(int index);
+
+    /**
+     * <code>optional bool has_type_list = 6;</code>
+     *
+     * <pre>
+     * Having an empty type_list is distinct from a null type_list
+     * </pre>
+     */
+    boolean getHasTypeList();
+
+    /**
+     * <code>optional string connection_id = 7;</code>
+     */
+    java.lang.String getConnectionId();
+    /**
+     * <code>optional string connection_id = 7;</code>
+     */
+    com.google.protobuf.ByteString
+        getConnectionIdBytes();
+  }
+  /**
+   * Protobuf type {@code TablesRequest}
+   *
+   * <pre>
+   * Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
+   *   org.apache.calcite.avatica.Meta.Pat, java.util.List)
+   * </pre>
+   */
+  public  static final class TablesRequest extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:TablesRequest)
+      TablesRequestOrBuilder {
+    // Use TablesRequest.newBuilder() to construct.
+    private TablesRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+    }
+    private TablesRequest() {
+      catalog_ = "";
+      schemaPattern_ = "";
+      tableNamePattern_ = "";
+      typeList_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      hasTypeList_ = false;
+      connectionId_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private TablesRequest(
+        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 10: {
+              String s = input.readStringRequireUtf8();
+
+              catalog_ = s;
+              break;
+            }
+            case 18: {
+              String s = input.readStringRequireUtf8();
+
+              schemaPattern_ = s;
+              break;
+            }
+            case 26: {
+              String s = input.readStringRequireUtf8();
+
+              tableNamePattern_ = s;
+              break;
+            }
+            case 34: {
+              String s = input.readStringRequireUtf8();
+              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+                typeList_ = new com.google.protobuf.LazyStringArrayList();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              typeList_.add(s);
+              break;
+            }
+            case 48: {
+
+              hasTypeList_ = input.readBool();
+              break;
+            }
+            case 58: {
+              String s = input.readStringRequireUtf8();
+
+              connectionId_ = s;
+              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 {
+        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+          typeList_ = typeList_.getUnmodifiableView();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Requests.TablesRequest.class, org.apache.calcite.avatica.proto.Requests.TablesRequest.Builder.class);
+    }
+
+    private int bitField0_;
+    public static final int CATALOG_FIELD_NUMBER = 1;
+    private volatile java.lang.Object catalog_;
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    public java.lang.String getCatalog() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        catalog_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string catalog = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getCatalogBytes() {
+      java.lang.Object ref = catalog_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        catalog_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int SCHEMA_PATTERN_FIELD_NUMBER = 2;
+    private volatile java.lang.Object schemaPattern_;
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    public java.lang.String getSchemaPattern() {
+      java.lang.Object ref = schemaPattern_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        schemaPattern_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string schema_pattern = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getSchemaPatternBytes() {
+      java.lang.Object ref = schemaPattern_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        schemaPattern_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int TABLE_NAME_PATTERN_FIELD_NUMBER = 3;
+    private volatile java.lang.Object tableNamePattern_;
+    /**
+     * <code>optional string table_name_pattern = 3;</code>
+     */
+    public java.lang.String getTableNamePattern() {
+      java.lang.Object ref = tableNamePattern_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        tableNamePattern_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string table_name_pattern = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTableNamePatternBytes() {
+      java.lang.Object ref = tableNamePattern_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        tableNamePattern_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int TYPE_LIST_FIELD_NUMBER = 4;
+    private com.google.protobuf.LazyStringList typeList_;
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    public com.google.protobuf.ProtocolStringList
+        getTypeListList() {
+      return typeList_;
+    }
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    public int getTypeListCount() {
+      return typeList_.size();
+    }
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    public java.lang.String getTypeList(int index) {
+      return typeList_.get(index);
+    }
+    /**
+     * <code>repeated string type_list = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTypeListBytes(int index) {
+      return typeList_.getByteString(index);
+    }
+
+    public static final int HAS_TYPE_LIST_FIELD_NUMBER = 6;
+    private boolean hasTypeList_;
+    /**
+     * <code>optional bool has_type_list = 6;</code>
+     *
+     * <pre>
+     * Having an empty type_list is distinct from a null type_list
+     * </pre>
+     */
+    public boolean getHasTypeList() {
+      return hasTypeList_;
+    }
+
+    public static final int CONNECTION_ID_FIELD_NUMBER = 7;
+    private volatile java.lang.Object connectionId_;
+    /**
+     * <code>optional string connection_id = 7;</code>
+     */
+    public java.lang.String getConnectionId() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        connectionId_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>optional string connection_id = 7;</code>
+     */
+    public com.google.protobuf.ByteString
+        getConnectionIdBytes() {
+      java.lang.Object ref = connectionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        connectionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 {
+      if (!getCatalogBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 1, catalog_);
+      }
+      if (!getSchemaPatternBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 2, schemaPattern_);
+      }
+      if (!getTableNamePatternBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 3, tableNamePattern_);
+      }
+      for (int i = 0; i < typeList_.size(); i++) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 4, typeList_.getRaw(i));
+      }
+      if (hasTypeList_ != false) {
+        output.writeBool(6, hasTypeList_);
+      }
+      if (!getConnectionIdBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessage.writeString(output, 7, connectionId_);
+      }
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getCatalogBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, catalog_);
+      }
+      if (!getSchemaPatternBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, schemaPattern_);
+      }
+      if (!getTableNamePatternBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(3, tableNamePattern_);
+      }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < typeList_.size(); i++) {
+          dataSize += computeStringSizeNoTag(typeList_.getRaw(i));
+        }
+        size += dataSize;
+        size += 1 * getTypeListList().size();
+      }
+      if (hasTypeList_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(6, hasTypeList_);
+      }
+      if (!getConnectionIdBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessage.computeStringSize(7, connectionId_);
+      }
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Requests.TablesRequest 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.Requests.TablesRequest 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 TablesRequest}
+     *
+     * <pre>
+     * Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
+     *   org.apache.calcite.avatica.Meta.Pat, java.util.List)
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:TablesRequest)
+        org.apache.calcite.avatica.proto.Requests.TablesRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.calcite.avatica.proto.Requests.TablesRequest.class, org.apache.calcite.avatica.proto.Requests.TablesRequest.Builder.class);
+      }
+
+      // Construct using org.apache.calcite.avatica.proto.Requests.TablesRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        catalog_ = "";
+
+        schemaPattern_ = "";
+
+        tableNamePattern_ = "";
+
+        typeList_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        hasTypeList_ = false;
+
+        connectionId_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.calcite.avatica.proto.Requests.internal_static_TablesRequest_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.TablesRequest getDefaultInstanceForType() {
+        return org.apache.calcite.avatica.proto.Requests.TablesRequest.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.TablesRequest build() {
+        org.apache.calcite.avatica.proto.Requests.TablesRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Requests.TablesRequest buildPartial() {
+        org.apache.calcite.avatica.proto.Requests.TablesRequest result = new org.apache.calcite.avatica.proto.Requests.TablesRequest(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        result.catalog_ = catalog_;
+        result.schemaPattern_ = schemaPattern_;
+        result.tableNamePattern_ = tableNamePattern_;
+        if (((bitField0_ & 0x00000008) == 0x00000008)) {
+          typeList_ = typeList_.getUnmodifiableView();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        }
+        result.typeList_ = typeList_;
+        result.hasTypeList_ = hasTypeList_;
+        result.connectionId_ = connectionId_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.calcite.avatica.proto.Requests.TablesRequest) {
+          return mergeFrom((org.apache.calcite.avatica.proto.Requests.TablesRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.calcite.avatica.proto.Requests.TablesRequest other) {
+        if (other == org.apache.calcite.avatica.proto.Requests.TablesRequest.getDefaultInstance()) return this;
+        if (!other.getCatalog().isEmpty()) {
+          catalog_ = other.catalog_;
+          onChanged();
+        }
+        if (!other.getSchemaPattern().isEmpty()) {
+          schemaPattern_ = other.schemaPattern_;
+          onChanged();
+        }
+        if (!other.getTableNamePattern().isEmpty()) {
+          tableNamePattern_ = other.tableNamePattern_;
+          onChanged();
+        }
+        if (!other.typeList_.isEmpty()) {
+          if (typeList_.isEmpty()) {
+            typeList_ = other.typeList_;
+            bitField0_ = (bitField0_ & ~0x00000008);
+          } else {
+            ensureTypeListIsMutable();
+            typeList_.addAll(other.typeList_);
+          }
+          onChanged();
+        }
+        if (other.getHasTypeList() != false) {
+          setHasTypeList(other.getHasTypeList());
+        }
+        if (!other.getConnectionId().isEmpty()) {
+          connectionId_ = other.connectionId_;
+          onChanged();
+        }
+        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.Requests.TablesRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.calcite.avatica.proto.Requests.TablesRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object catalog_ = "";
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public java.lang.String getCatalog() {
+        java.lang.Object ref = catalog_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          catalog_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getCatalogBytes() {
+        java.lang.Object ref = catalog_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          catalog_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder setCatalog(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder clearCatalog() {
+        
+        catalog_ = getDefaultInstance().getCatalog();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string catalog = 1;</code>
+       */
+      public Builder setCatalogBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        catalog_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object schemaPattern_ = "";
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public java.lang.String getSchemaPattern() {
+        java.lang.Object ref = schemaPattern_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          schemaPattern_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getSchemaPatternBytes() {
+        java.lang.Object ref = schemaPattern_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          schemaPattern_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder setSchemaPattern(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        schemaPattern_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder clearSchemaPattern() {
+        
+        schemaPattern_ = getDefaultInstance().getSchemaPattern();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string schema_pattern = 2;</code>
+       */
+      public Builder setSchemaPatternBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        schemaPattern_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object tableNamePattern_ = "";
+      /**
+       * <code>optional string table_name_pattern = 3;</code>
+       */
+      public java.lang.String getTableNamePattern() {
+        java.lang.Object ref = tableNamePattern_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          tableNamePattern_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string table_name_pattern = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTableNamePatternBytes() {
+        java.lang.Object ref = tableNamePattern_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          tableNamePattern_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string table_name_pattern = 3;</code>
+       */
+      public Builder setTableNamePattern(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        tableNamePattern_ = value;
+        onChanged();
+        return this;
+      }


<TRUNCATED>

[26/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
new file mode 100644
index 0000000..ff27d05
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
@@ -0,0 +1,170 @@
+/*
+ * 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.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Statement;
+import java.util.Objects;
+
+/**
+ * All we know about a statement. Encapsulates a {@link ResultSet}.
+ */
+public class StatementInfo {
+  private volatile Boolean relativeSupported = null;
+
+  final Statement statement; // sometimes a PreparedStatement
+  private ResultSet resultSet;
+  private long position = 0;
+
+  // True when setResultSet(ResultSet) is called to let us determine the difference between
+  // a null ResultSet (from an update) from the lack of a ResultSet.
+  private boolean resultsInitialized = false;
+
+  public StatementInfo(Statement statement) {
+    this.statement = Objects.requireNonNull(statement);
+  }
+
+  // Visible for testing
+  void setPosition(long position) {
+    this.position = position;
+  }
+
+  // Visible for testing
+  long getPosition() {
+    return this.position;
+  }
+
+  /**
+   * Set a ResultSet on this object.
+   *
+   * @param resultSet The current ResultSet
+   */
+  public void setResultSet(ResultSet resultSet) {
+    resultsInitialized = true;
+    this.resultSet = resultSet;
+  }
+
+  /**
+   * @return The {@link ResultSet} for this Statement, may be null.
+   */
+  public ResultSet getResultSet() {
+    return this.resultSet;
+  }
+
+  /**
+   * @return True if {@link #setResultSet(ResultSet)} was ever invoked.
+   */
+  public boolean isResultSetInitialized() {
+    return resultsInitialized;
+  }
+
+  /**
+   * @see ResultSet#next()
+   */
+  public boolean next() throws SQLException {
+    return _next(resultSet);
+  }
+
+  boolean _next(ResultSet results) throws SQLException {
+    boolean ret = results.next();
+    position++;
+    return ret;
+  }
+
+  /**
+   * Consumes <code>offset - position</code> elements from the {@link ResultSet}.
+   *
+   * @param offset The offset to advance to
+   * @return True if the resultSet was advanced to the current point, false if insufficient rows
+   *      were present to advance to the requested offset.
+   */
+  public boolean advanceResultSetToOffset(ResultSet results, long offset) throws SQLException {
+    if (offset < 0 || offset < position) {
+      throw new IllegalArgumentException("Offset should be "
+        + " non-negative and not less than the current position. " + offset + ", " + position);
+    }
+    if (position >= offset) {
+      return true;
+    }
+
+    if (null == relativeSupported) {
+      Boolean moreResults = null;
+      synchronized (this) {
+        if (null == relativeSupported) {
+          try {
+            moreResults = advanceByRelative(results, offset);
+            relativeSupported = true;
+          } catch (SQLFeatureNotSupportedException e) {
+            relativeSupported = false;
+          }
+        }
+      }
+
+      if (null != moreResults) {
+        // We figured out whether or not relative is supported.
+        // Make sure we actually do the necessary work.
+        if (!relativeSupported) {
+          // We avoided calling advanceByNext in the synchronized block earlier.
+          moreResults = advanceByNext(results, offset);
+        }
+
+        return moreResults;
+      }
+
+      // Another thread updated the RELATIVE_SUPPORTED before we did, fall through.
+    }
+
+    if (relativeSupported) {
+      return advanceByRelative(results, offset);
+    } else {
+      return advanceByNext(results, offset);
+    }
+  }
+
+  private boolean advanceByRelative(ResultSet results, long offset) throws SQLException {
+    long diff = offset - position;
+    while (diff > Integer.MAX_VALUE) {
+      if (!results.relative(Integer.MAX_VALUE)) {
+        // Avoid updating position until relative succeeds.
+        position += Integer.MAX_VALUE;
+        return false;
+      }
+      // Avoid updating position until relative succeeds.
+      position += Integer.MAX_VALUE;
+      diff -= Integer.MAX_VALUE;
+    }
+    boolean ret = results.relative((int) diff);
+    // Make sure we only update the position after successfully calling relative(int).
+    position += diff;
+    return ret;
+  }
+
+  private boolean advanceByNext(ResultSet results, long offset) throws SQLException {
+    while (position < offset) {
+      // Advance while maintaining `position`
+      if (!_next(results)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+}
+
+// End StatementInfo.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
new file mode 100644
index 0000000..8b8fb76
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/** Implements an Avatica provider on top of an existing JDBC data source. */
+package org.apache.calcite.avatica.jdbc;
+
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
new file mode 100644
index 0000000..42b13c9
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
@@ -0,0 +1,32 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.eclipse.jetty.server.Handler;
+
+/**
+ * A custom interface that extends the Jetty interface to enable extra control within Avatica.
+ */
+public interface AvaticaHandler extends Handler {
+
+  void setServerRpcMetadata(RpcMetadataResponse metadata);
+
+}
+
+// End AvaticaHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
new file mode 100644
index 0000000..34a9333
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
@@ -0,0 +1,127 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
+import org.apache.calcite.avatica.remote.JsonHandler;
+import org.apache.calcite.avatica.remote.Service;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Jetty handler that executes Avatica JSON request-responses.
+ */
+public class AvaticaJsonHandler extends AbstractHandler implements MetricsAwareAvaticaHandler {
+  private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
+
+  final Service service;
+  final JsonHandler jsonHandler;
+
+  final MetricsSystem metrics;
+  final Timer requestTimer;
+
+  final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
+
+  public AvaticaJsonHandler(Service service) {
+    this(service, NoopMetricsSystem.getInstance());
+  }
+
+  public AvaticaJsonHandler(Service service, MetricsSystem metrics) {
+    this.service = Objects.requireNonNull(service);
+    this.metrics = Objects.requireNonNull(metrics);
+    // Avatica doesn't have a Guava dependency
+    this.jsonHandler = new JsonHandler(service, this.metrics);
+
+    // Metrics
+    this.requestTimer = this.metrics.getTimer(
+        concat(AvaticaJsonHandler.class, MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
+
+    this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
+      @Override public UnsynchronizedBuffer initialValue() {
+        return new UnsynchronizedBuffer();
+      }
+    };
+  }
+
+  public void handle(String target, Request baseRequest,
+      HttpServletRequest request, HttpServletResponse response)
+      throws IOException, ServletException {
+    try (final Context ctx = requestTimer.start()) {
+      response.setContentType("application/json;charset=utf-8");
+      response.setStatus(HttpServletResponse.SC_OK);
+      if (request.getMethod().equals("POST")) {
+        // First look for a request in the header, then look in the body.
+        // The latter allows very large requests without hitting HTTP 413.
+        String rawRequest = request.getHeader("request");
+        if (rawRequest == null) {
+          // Avoid a new buffer creation for every HTTP request
+          final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
+          try (ServletInputStream inputStream = request.getInputStream()) {
+            rawRequest = AvaticaUtils.readFully(inputStream, buffer);
+          } finally {
+            // Reset the offset into the buffer after we're done
+            buffer.reset();
+          }
+        }
+        final String jsonRequest =
+            new String(rawRequest.getBytes("ISO-8859-1"), "UTF-8");
+        LOG.trace("request: {}", jsonRequest);
+
+        final HandlerResponse<String> jsonResponse = jsonHandler.apply(jsonRequest);
+        LOG.trace("response: {}", jsonResponse);
+        baseRequest.setHandled(true);
+        // Set the status code and write out the response.
+        response.setStatus(jsonResponse.getStatusCode());
+        response.getWriter().println(jsonResponse.getResponse());
+      }
+    }
+  }
+
+  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
+    // Set the metadata for the normal service calls
+    service.setRpcMetadata(metadata);
+    // Also add it to the handler to include with exceptions
+    jsonHandler.setRpcMetadata(metadata);
+  }
+
+  @Override public MetricsSystem getMetrics() {
+    return metrics;
+  }
+}
+
+// End AvaticaJsonHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
new file mode 100644
index 0000000..27e73de
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
@@ -0,0 +1,121 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
+import org.apache.calcite.avatica.remote.MetricsHelper;
+import org.apache.calcite.avatica.remote.ProtobufHandler;
+import org.apache.calcite.avatica.remote.ProtobufTranslation;
+import org.apache.calcite.avatica.remote.ProtobufTranslationImpl;
+import org.apache.calcite.avatica.remote.Service;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Jetty handler that executes Avatica JSON request-responses.
+ */
+public class AvaticaProtobufHandler extends AbstractHandler implements MetricsAwareAvaticaHandler {
+  private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
+
+  private final Service service;
+  private final ProtobufHandler pbHandler;
+  private final ProtobufTranslation protobufTranslation;
+  private final MetricsSystem metrics;
+  private final Timer requestTimer;
+
+  final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
+
+  public AvaticaProtobufHandler(Service service) {
+    this(service, NoopMetricsSystem.getInstance());
+  }
+
+  public AvaticaProtobufHandler(Service service, MetricsSystem metrics) {
+    this.service = Objects.requireNonNull(service);
+    this.metrics = Objects.requireNonNull(metrics);
+
+    this.requestTimer = this.metrics.getTimer(
+        MetricsHelper.concat(AvaticaProtobufHandler.class,
+            MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
+
+    this.protobufTranslation = new ProtobufTranslationImpl();
+    this.pbHandler = new ProtobufHandler(service, protobufTranslation, metrics);
+
+    this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
+      @Override public UnsynchronizedBuffer initialValue() {
+        return new UnsynchronizedBuffer();
+      }
+    };
+  }
+
+  public void handle(String target, Request baseRequest,
+      HttpServletRequest request, HttpServletResponse response)
+      throws IOException, ServletException {
+    try (final Context ctx = this.requestTimer.start()) {
+      response.setContentType("application/octet-stream;charset=utf-8");
+      response.setStatus(HttpServletResponse.SC_OK);
+      if (request.getMethod().equals("POST")) {
+        byte[] requestBytes;
+        // Avoid a new buffer creation for every HTTP request
+        final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
+        try (ServletInputStream inputStream = request.getInputStream()) {
+          requestBytes = AvaticaUtils.readFullyToBytes(inputStream, buffer);
+        } finally {
+          buffer.reset();
+        }
+
+        HandlerResponse<byte[]> handlerResponse = pbHandler.apply(requestBytes);
+
+        baseRequest.setHandled(true);
+        response.setStatus(handlerResponse.getStatusCode());
+        response.getOutputStream().write(handlerResponse.getResponse());
+      }
+    }
+  }
+
+  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
+    // Set the metadata for the normal service calls
+    service.setRpcMetadata(metadata);
+    // Also add it to the handler to include with exceptions
+    pbHandler.setRpcMetadata(metadata);
+  }
+
+  @Override public MetricsSystem getMetrics() {
+    return this.metrics;
+  }
+
+}
+
+// End AvaticaProtobufHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
new file mode 100644
index 0000000..a574985
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
@@ -0,0 +1,116 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * An AvaticaHandler implementation that delegates to a provided Jetty Handler instance.
+ *
+ * <p>This implementation provides a no-op implementation for
+ * {@link #setServerRpcMetadata(org.apache.calcite.avatica.remote.Service.RpcMetadataResponse)}.
+ *
+ * Does not implement {@link MetricsAwareAvaticaHandler} as this implementation is only presented
+ * for backwards compatibility.
+ */
+public class DelegatingAvaticaHandler implements AvaticaHandler {
+  private static final Logger LOG = LoggerFactory.getLogger(DelegatingAvaticaHandler.class);
+
+  private final Handler handler;
+
+  public DelegatingAvaticaHandler(Handler handler) {
+    this.handler = Objects.requireNonNull(handler);
+  }
+
+  @Override public void handle(String target, Request baseRequest, HttpServletRequest request,
+      HttpServletResponse response) throws IOException, ServletException {
+    handler.handle(target, baseRequest, request, response);
+  }
+
+  @Override public void setServer(Server server) {
+    handler.setServer(server);
+  }
+
+  @Override public Server getServer() {
+    return handler.getServer();
+  }
+
+  @Override public void destroy() {
+    handler.destroy();
+  }
+
+  @Override public void start() throws Exception {
+    handler.start();
+  }
+
+  @Override public void stop() throws Exception {
+    handler.stop();
+  }
+
+  @Override public boolean isRunning() {
+    return handler.isRunning();
+  }
+
+  @Override public boolean isStarted() {
+    return handler.isStarted();
+  }
+
+  @Override public boolean isStarting() {
+    return handler.isStarting();
+  }
+
+  @Override public boolean isStopping() {
+    return handler.isStopping();
+  }
+
+  @Override public boolean isStopped() {
+    return handler.isStopped();
+  }
+
+  @Override public boolean isFailed() {
+    return handler.isFailed();
+  }
+
+  @Override public void addLifeCycleListener(Listener listener) {
+    handler.addLifeCycleListener(listener);
+  }
+
+  @Override public void removeLifeCycleListener(Listener listener) {
+    handler.removeLifeCycleListener(listener);
+  }
+
+  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
+    LOG.warn("Setting RpcMetadata is not implemented for DelegatingAvaticaHandler");
+  }
+
+}
+
+// End DelegatingAvaticaHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
new file mode 100644
index 0000000..b1fcb40
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
@@ -0,0 +1,115 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
+import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
+import org.apache.calcite.avatica.metrics.MetricsSystemLoader;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
+import org.apache.calcite.avatica.remote.Driver;
+import org.apache.calcite.avatica.remote.Service;
+
+import org.eclipse.jetty.server.Handler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.ServiceLoader;
+
+/**
+ * Factory that instantiates the desired implementation, typically differing on the method
+ * used to serialize messages, for use in the Avatica server.
+ */
+public class HandlerFactory {
+  private static final Logger LOG = LoggerFactory.getLogger(HandlerFactory.class);
+
+  /**
+   * Constructs the desired implementation for the given serialization method with metrics.
+   *
+   * @param service The underlying {@link Service}.
+   * @param serialization The desired message serialization.
+   * @return The {@link Handler}.
+   */
+  public Handler getHandler(Service service, Driver.Serialization serialization) {
+    return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance());
+  }
+
+  /**
+   * Constructs the desired implementation for the given serialization method with metrics.
+   *
+   * @param service The underlying {@link Service}.
+   * @param serialization The desired message serialization.
+   * @param metricsConfig Configuration for the {@link MetricsSystem}.
+   * @return The {@link Handler}.
+   */
+  public Handler getHandler(Service service, Driver.Serialization serialization,
+      MetricsSystemConfiguration<?> metricsConfig) {
+    MetricsSystem metrics = MetricsSystemLoader.load(Objects.requireNonNull(metricsConfig));
+
+    switch (serialization) {
+    case JSON:
+      return new AvaticaJsonHandler(service, metrics);
+    case PROTOBUF:
+      return new AvaticaProtobufHandler(service, metrics);
+    default:
+      throw new IllegalArgumentException("Unknown Avatica handler for " + serialization.name());
+    }
+  }
+
+  /**
+   * Load a {@link MetricsSystem} using ServiceLoader to create a {@link MetricsSystemFactory}.
+   *
+   * @param config State to pass to the factory for initialization.
+   * @return A {@link MetricsSystem} instance.
+   */
+  MetricsSystem loadMetricsSystem(MetricsSystemConfiguration<?> config) {
+    ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class);
+    List<MetricsSystemFactory> availableFactories = new ArrayList<>();
+    for (MetricsSystemFactory factory : loader) {
+      availableFactories.add(factory);
+    }
+
+    if (1 == availableFactories.size()) {
+      // One and only one instance -- what we want
+      MetricsSystemFactory factory = availableFactories.get(0);
+      LOG.info("Loaded MetricsSystem {}", factory.getClass());
+      return factory.create(config);
+    } else if (availableFactories.isEmpty()) {
+      // None-provided default to no metrics
+      LOG.info("No metrics implementation available on classpath. Using No-op implementation");
+      return NoopMetricsSystem.getInstance();
+    } else {
+      // Tell the user they're doing something wrong, and choose the first impl.
+      StringBuilder sb = new StringBuilder();
+      for (MetricsSystemFactory factory : availableFactories) {
+        if (sb.length() > 0) {
+          sb.append(", ");
+        }
+        sb.append(factory.getClass());
+      }
+      LOG.warn("Found multiple MetricsSystemFactory implementations: {}."
+          + " Using No-op implementation", sb);
+      return NoopMetricsSystem.getInstance();
+    }
+  }
+}
+
+// End HandlerFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
new file mode 100644
index 0000000..c81e899
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
@@ -0,0 +1,168 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Avatica HTTP server.
+ *
+ * <p>If you need to change the server's configuration, override the
+ * {@link #configureConnector(ServerConnector, int)} method in a derived class.
+ */
+public class HttpServer {
+  private static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);
+
+  private Server server;
+  private int port = -1;
+  private final AvaticaHandler handler;
+
+  @Deprecated
+  public HttpServer(Handler handler) {
+    this(wrapJettyHandler(handler));
+  }
+
+  public HttpServer(AvaticaHandler handler) {
+    this(0, handler);
+  }
+
+  @Deprecated
+  public HttpServer(int port, Handler handler) {
+    this(port, wrapJettyHandler(handler));
+  }
+
+  public HttpServer(int port, AvaticaHandler handler) {
+    this.port = port;
+    this.handler = handler;
+  }
+
+  private static AvaticaHandler wrapJettyHandler(Handler handler) {
+    if (handler instanceof AvaticaHandler) {
+      return (AvaticaHandler) handler;
+    }
+    // Backwards compatibility, noop's the AvaticaHandler interface
+    return new DelegatingAvaticaHandler(handler);
+  }
+
+  public void start() {
+    if (server != null) {
+      throw new RuntimeException("Server is already started");
+    }
+
+    final QueuedThreadPool threadPool = new QueuedThreadPool();
+    threadPool.setDaemon(true);
+    server = new Server(threadPool);
+    server.manage(threadPool);
+
+    final ServerConnector connector = configureConnector(new ServerConnector(server), port);
+
+    server.setConnectors(new Connector[] { connector });
+
+    final HandlerList handlerList = new HandlerList();
+    handlerList.setHandlers(new Handler[] { handler, new DefaultHandler() });
+    server.setHandler(handlerList);
+    try {
+      server.start();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    port = connector.getLocalPort();
+
+    LOG.info("Service listening on port {}.", getPort());
+
+    // Set the information about the address for this server
+    try {
+      this.handler.setServerRpcMetadata(createRpcServerMetadata(connector));
+    } catch (UnknownHostException e) {
+      // Failed to do the DNS lookup, bail out.
+      throw new RuntimeException(e);
+    }
+  }
+
+  private RpcMetadataResponse createRpcServerMetadata(ServerConnector connector) throws
+      UnknownHostException {
+    String host = connector.getHost();
+    if (null == host) {
+      // "null" means binding to all interfaces, we need to pick one so the client gets a real
+      // address and not "0.0.0.0" or similar.
+      host = InetAddress.getLocalHost().getHostName();
+    }
+
+    final int port = connector.getLocalPort();
+
+    return new RpcMetadataResponse(String.format("%s:%d", host, port));
+  }
+
+  /**
+   * Configures the server connector.
+   *
+   * <p>The default configuration sets a timeout of 1 minute and disables
+   * TCP linger time.
+   *
+   * <p>To change the configuration, override this method in a derived class.
+   * The overriding method must call its super method.
+   *
+   * @param connector connector to be configured
+   * @param port port number handed over in constructor
+   */
+  protected ServerConnector configureConnector(ServerConnector connector, int port) {
+    connector.setIdleTimeout(60 * 1000);
+    connector.setSoLingerTime(-1);
+    connector.setPort(port);
+    return connector;
+  }
+
+  public void stop() {
+    if (server == null) {
+      throw new RuntimeException("Server is already stopped");
+    }
+
+    LOG.info("Service terminating.");
+    try {
+      final Server server1 = server;
+      port = -1;
+      server = null;
+      server1.stop();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void join() throws InterruptedException {
+    server.join();
+  }
+
+  public int getPort() {
+    return port;
+  }
+}
+
+// End HttpServer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
new file mode 100644
index 0000000..8b05931
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
@@ -0,0 +1,100 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.remote.LocalService;
+import org.apache.calcite.avatica.remote.Service;
+
+import org.eclipse.jetty.server.handler.AbstractHandler;
+
+import java.util.Arrays;
+
+/**
+ * Jetty handler that executes Avatica JSON request-responses.
+ */
+public class Main {
+  private Main() {}
+
+  public static void main(String[] args)
+      throws InterruptedException, ClassNotFoundException,
+      IllegalAccessException, InstantiationException {
+    HttpServer server = start(args);
+    server.join();
+  }
+
+  /**
+   * Factory that instantiates Jetty Handlers
+   */
+  public interface HandlerFactory {
+    AbstractHandler createHandler(Service service);
+  }
+
+  private static final HandlerFactory JSON_HANDLER_FACTORY = new HandlerFactory() {
+    public AbstractHandler createHandler(Service service) {
+      return new AvaticaJsonHandler(service);
+    }
+  };
+
+  /**
+   * Creates and starts an {@link HttpServer} using JSON POJO serialization of requests/responses.
+   *
+   * <p>Arguments are as follows:
+   * <ul>
+   *   <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
+   *       name
+   *   <li>args[1+]: arguments passed along to
+   *   {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
+   * </ul>
+   *
+   * @param args Command-line arguments
+   */
+  public static HttpServer start(String[] args) throws ClassNotFoundException,
+         InstantiationException, IllegalAccessException {
+    return start(args, 8765, JSON_HANDLER_FACTORY);
+  }
+
+  /**
+   * Creates and starts an {@link HttpServer} using the given factory to create the Handler.
+   *
+   * <p>Arguments are as follows:
+   * <ul>
+   *   <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
+   *       name
+   *   <li>args[1+]: arguments passed along to
+   *   {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
+   * </ul>
+   *
+   * @param args Command-line arguments
+   * @param port Server port to bind
+   * @param handlerFactory Factory to create the handler used by the server
+   */
+  public static HttpServer start(String[] args, int port, HandlerFactory handlerFactory)
+      throws ClassNotFoundException, InstantiationException,
+      IllegalAccessException {
+    String factoryClassName = args[0];
+    Class<?> factoryClass = Class.forName(factoryClassName);
+    Meta.Factory factory = (Meta.Factory) factoryClass.newInstance();
+    Meta meta = factory.create(Arrays.asList(args).subList(1, args.length));
+    Service service = new LocalService(meta);
+    HttpServer server = new HttpServer(port, handlerFactory.createHandler(service));
+    server.start();
+    return server;
+  }
+}
+
+// End Main.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
new file mode 100644
index 0000000..0914dbd
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
@@ -0,0 +1,43 @@
+/*
+ * 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.server;
+
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+
+/**
+ * An {@link AvaticaHandler} that is capable of collecting metrics.
+ */
+public interface MetricsAwareAvaticaHandler extends AvaticaHandler {
+
+  /**
+   * General prefix for all metrics in a handler.
+   */
+  String HANDLER_PREFIX = "Handler.";
+
+  /**
+   * Name for timing requests from users
+   */
+  String REQUEST_TIMER_NAME = HANDLER_PREFIX + "RequestTimings";
+
+  /**
+   * @return An instance of the {@link MetricsSystem} for this AvaticaHandler.
+   */
+  MetricsSystem getMetrics();
+
+}
+
+// End MetricsAwareAvaticaHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/main/java/org/apache/calcite/avatica/server/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/package-info.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/package-info.java
new file mode 100644
index 0000000..f2b8728
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/server/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Avatica server that listens for HTTP requests.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.server;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java b/avatica/server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
new file mode 100644
index 0000000..ba4c5b8
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
@@ -0,0 +1,55 @@
+/*
+ * 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 net.hydromatic.scott.data.hsqldb.ScottHsqldb;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+/** Information necessary to create a JDBC connection. Specify one to run
+ * tests against a different database. (hsqldb is the default.) */
+public class ConnectionSpec {
+  public final String url;
+  public final String username;
+  public final String password;
+  public final String driver;
+
+  // CALCITE-687 HSQLDB seems to fail oddly when multiple tests are run concurrently
+  private static final ReentrantLock HSQLDB_LOCK = new ReentrantLock();
+
+  public ConnectionSpec(String url, String username, String password,
+      String driver) {
+    this.url = url;
+    this.username = username;
+    this.password = password;
+    this.driver = driver;
+  }
+
+  public static final ConnectionSpec HSQLDB =
+      new ConnectionSpec(ScottHsqldb.URI, ScottHsqldb.USER,
+          ScottHsqldb.PASSWORD, "org.hsqldb.jdbcDriver");
+
+  /**
+   * Return a lock used for controlling concurrent access to the database as it has been observed
+   * that concurrent access is causing problems with HSQLDB.
+   */
+  public static ReentrantLock getDatabaseLock() {
+    return HSQLDB_LOCK;
+  }
+}
+
+// End ConnectionSpec.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
new file mode 100644
index 0000000..9749ef6
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.remote.MockJsonService;
+import org.apache.calcite.avatica.remote.MockProtobufService.MockProtobufServiceFactory;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * RemoteDriver tests that use a Mock implementation of a Connection.
+ */
+@RunWith(Parameterized.class)
+public class RemoteDriverMockTest {
+  public static final String MJS = MockJsonService.Factory.class.getName();
+  public static final String MPBS = MockProtobufServiceFactory.class.getName();
+
+  private static Connection mjs() throws SQLException {
+    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + MJS);
+  }
+
+  private static Connection mpbs() throws SQLException {
+    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + MPBS);
+  }
+
+  @Parameters
+  public static List<Object[]> parameters() {
+    List<Object[]> parameters = new ArrayList<>();
+
+    parameters.add(new Object[] {new Callable<Connection>() {
+      public Connection call() throws SQLException {
+        return mjs();
+      }
+    } });
+
+    parameters.add(new Object[] {new Callable<Connection>() {
+      public Connection call() throws SQLException {
+        return mpbs();
+      }
+    } });
+
+    return parameters;
+  }
+
+  private final Callable<Connection> connectionFunctor;
+
+  public RemoteDriverMockTest(Callable<Connection> functor) {
+    this.connectionFunctor = functor;
+  }
+
+  private Connection getMockConnection() {
+    try {
+      return connectionFunctor.call();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Test public void testRegister() throws Exception {
+    final Connection connection = getMockConnection();
+    assertThat(connection.isClosed(), is(false));
+    connection.close();
+    assertThat(connection.isClosed(), is(true));
+  }
+
+  @Test public void testSchemas() throws Exception {
+    final Connection connection = getMockConnection();
+    final ResultSet resultSet =
+        connection.getMetaData().getSchemas(null, null);
+    assertFalse(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertTrue(metaData.getColumnCount() >= 2);
+    assertEquals("TABLE_CATALOG", metaData.getColumnName(1));
+    assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
+    resultSet.close();
+    connection.close();
+  }
+
+  @Test public void testTables() throws Exception {
+    final Connection connection = getMockConnection();
+    final ResultSet resultSet =
+        connection.getMetaData().getTables(null, null, null, new String[0]);
+    assertFalse(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertTrue(metaData.getColumnCount() >= 3);
+    assertEquals("TABLE_CAT", metaData.getColumnName(1));
+    assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
+    assertEquals("TABLE_NAME", metaData.getColumnName(3));
+    resultSet.close();
+    connection.close();
+  }
+
+  @Ignore
+  @Test public void testNoFactory() throws Exception {
+    final Connection connection =
+        DriverManager.getConnection("jdbc:avatica:remote:");
+    assertThat(connection.isClosed(), is(false));
+    final ResultSet resultSet = connection.getMetaData().getSchemas();
+    assertFalse(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
+    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
+    resultSet.close();
+    connection.close();
+    assertThat(connection.isClosed(), is(true));
+  }
+
+  @Ignore
+  @Test public void testCatalogsMock() throws Exception {
+    final Connection connection = getMockConnection();
+    assertThat(connection.isClosed(), is(false));
+    final ResultSet resultSet = connection.getMetaData().getSchemas();
+    assertFalse(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
+    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
+    resultSet.close();
+    connection.close();
+    assertThat(connection.isClosed(), is(true));
+  }
+
+  @Ignore
+  @Test public void testStatementExecuteQueryMock() throws Exception {
+    checkStatementExecuteQuery(getMockConnection(), false);
+  }
+
+  @Ignore
+  @Test public void testPrepareExecuteQueryMock() throws Exception {
+    checkStatementExecuteQuery(getMockConnection(), true);
+  }
+
+  private void checkStatementExecuteQuery(Connection connection,
+      boolean prepare) throws SQLException {
+    final String sql = "select * from (\n"
+        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
+    final Statement statement;
+    final ResultSet resultSet;
+    final ParameterMetaData parameterMetaData;
+    if (prepare) {
+      final PreparedStatement ps = connection.prepareStatement(sql);
+      statement = ps;
+      parameterMetaData = ps.getParameterMetaData();
+      resultSet = ps.executeQuery();
+    } else {
+      statement = connection.createStatement();
+      parameterMetaData = null;
+      resultSet = statement.executeQuery(sql);
+    }
+    if (parameterMetaData != null) {
+      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
+    }
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("C1", metaData.getColumnName(1));
+    assertEquals("C2", metaData.getColumnName(2));
+    assertTrue(resultSet.next());
+    assertTrue(resultSet.next());
+    assertTrue(resultSet.next());
+    assertFalse(resultSet.next());
+    resultSet.close();
+    statement.close();
+    connection.close();
+  }
+
+  @Test public void testResultSetsFinagled() throws Exception {
+    // These values specified in MockJsonService
+    final String table = "my_table";
+    final long value = 10;
+
+    final Connection connection = getMockConnection();
+    // Not an accurate ResultSet per JDBC, but close enough for testing.
+    ResultSet results = connection.getMetaData().getColumns(null, null, table, null);
+    assertTrue(results.next());
+    assertEquals(table, results.getString(1));
+    assertEquals(value, results.getLong(2));
+  }
+
+}
+
+// End RemoteDriverMockTest.java


[13/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
deleted file mode 100644
index a999f19..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
+++ /dev/null
@@ -1,329 +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.util.UnsynchronizedBuffer;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Field;
-import java.nio.charset.StandardCharsets;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.AbstractList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/** Avatica utilities. */
-public class AvaticaUtils {
-  private static final Map<Class, Class> BOX;
-
-  private static final MethodHandle SET_LARGE_MAX_ROWS =
-      method(void.class, Statement.class, "setLargeMaxRows", long.class);
-  private static final MethodHandle GET_LARGE_MAX_ROWS =
-      method(long.class, Statement.class, "getLargeMaxRows");
-  private static final MethodHandle GET_LARGE_UPDATE_COUNT =
-      method(void.class, Statement.class, "getLargeUpdateCount");
-
-  private static final Set<String> UNIQUE_STRINGS = new HashSet<>();
-
-  private static final ThreadLocal<byte[]> PER_THREAD_BUFFER  = new ThreadLocal<byte[]>() {
-    @Override protected byte[] initialValue() {
-      return new byte[4096];
-    }
-  };
-
-  private AvaticaUtils() {}
-
-  static {
-    BOX = new HashMap<>();
-    BOX.put(boolean.class, Boolean.class);
-    BOX.put(byte.class, Byte.class);
-    BOX.put(char.class, Character.class);
-    BOX.put(short.class, Short.class);
-    BOX.put(int.class, Integer.class);
-    BOX.put(long.class, Long.class);
-    BOX.put(float.class, Float.class);
-    BOX.put(double.class, Double.class);
-  }
-
-  private static MethodHandle method(Class returnType, Class targetType,
-      String name, Class... argTypes) {
-    final MethodHandles.Lookup lookup = MethodHandles.lookup();
-    try {
-      return lookup.findVirtual(targetType, name,
-          MethodType.methodType(returnType, targetType, argTypes));
-    } catch (NoSuchMethodException e) {
-      return null;
-    } catch (IllegalAccessException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /**
-   * Does nothing with its argument. Call this method when you have a value
-   * you are not interested in, but you don't want the compiler to warn that
-   * you are not using it.
-   */
-  public static void discard(Object o) {
-    if (false) {
-      discard(o);
-    }
-  }
-
-  /**
-   * Adapts a primitive array into a {@link List}. For example,
-   * {@code asList(new double[2])} returns a {@code List&lt;Double&gt;}.
-   */
-  public static List<?> primitiveList(final Object array) {
-    // REVIEW: A per-type list might be more efficient. (Or might not.)
-    return new AbstractList() {
-      public Object get(int index) {
-        return java.lang.reflect.Array.get(array, index);
-      }
-
-      public int size() {
-        return java.lang.reflect.Array.getLength(array);
-      }
-    };
-  }
-
-  /**
-   * Converts a camelCase name into an upper-case underscore-separated name.
-   * For example, {@code camelToUpper("myJdbcDriver")} returns
-   * "MY_JDBC_DRIVER".
-   */
-  public static String camelToUpper(String name) {
-    StringBuilder buf = new StringBuilder();
-    for (int i = 0; i < name.length(); i++) {
-      char c = name.charAt(i);
-      if (Character.isUpperCase(c)) {
-        buf.append('_');
-      } else {
-        c = Character.toUpperCase(c);
-      }
-      buf.append(c);
-    }
-    return buf.toString();
-  }
-
-  /**
-   * Converts an underscore-separated name into a camelCase name.
-   * For example, {@code uncamel("MY_JDBC_DRIVER")} returns "myJdbcDriver".
-   */
-  public static String toCamelCase(String name) {
-    StringBuilder buf = new StringBuilder();
-    int nextUpper = -1;
-    for (int i = 0; i < name.length(); i++) {
-      char c = name.charAt(i);
-      if (c == '_') {
-        nextUpper = i + 1;
-        continue;
-      }
-      if (nextUpper == i) {
-        c = Character.toUpperCase(c);
-      } else {
-        c = Character.toLowerCase(c);
-      }
-      buf.append(c);
-    }
-    return buf.toString();
-  }
-
-  /** Returns the boxed class. For example, {@code box(int.class)}
-   * returns {@code java.lang.Integer}. */
-  public static Class box(Class clazz) {
-    if (clazz.isPrimitive()) {
-      return BOX.get(clazz);
-    }
-    return clazz;
-  }
-
-  /** Creates an instance of a plugin class. First looks for a static
-   * member called INSTANCE, then calls a public default constructor.
-   *
-   * <p>If className contains a "#" instead looks for a static field.
-   *
-   * @param pluginClass Class (or interface) to instantiate
-   * @param className Name of implementing class
-   * @param <T> Class
-   * @return Plugin instance
-   */
-  public static <T> T instantiatePlugin(Class<T> pluginClass,
-      String className) {
-    try {
-      // Given a static field, say "com.example.MyClass#FOO_INSTANCE", return
-      // the value of that static field.
-      if (className.contains("#")) {
-        try {
-          int i = className.indexOf('#');
-          String left = className.substring(0, i);
-          String right = className.substring(i + 1);
-          //noinspection unchecked
-          final Class<T> clazz = (Class) Class.forName(left);
-          final Field field;
-          field = clazz.getField(right);
-          return pluginClass.cast(field.get(null));
-        } catch (NoSuchFieldException e) {
-          // ignore
-        }
-      }
-      //noinspection unchecked
-      final Class<T> clazz = (Class) Class.forName(className);
-      assert pluginClass.isAssignableFrom(clazz);
-      try {
-        // We assume that if there is an INSTANCE field it is static and
-        // has the right type.
-        final Field field = clazz.getField("INSTANCE");
-        return pluginClass.cast(field.get(null));
-      } catch (NoSuchFieldException e) {
-        // ignore
-      }
-      return clazz.newInstance();
-    } catch (Exception e) {
-      throw new RuntimeException("Property '" + className
-          + "' not valid for plugin type " + pluginClass.getName(), e);
-    }
-  }
-
-  /** Reads the contents of an input stream and returns as a string. */
-  public static String readFully(InputStream inputStream) throws IOException {
-    return readFully(inputStream, new UnsynchronizedBuffer(1024));
-  }
-
-  /** Reads the contents of an input stream and returns as a string. */
-  public static String readFully(InputStream inputStream, UnsynchronizedBuffer buffer)
-      throws IOException {
-    // Variant that lets us use a pooled Buffer
-    final byte[] bytes = _readFully(inputStream, buffer);
-    return new String(bytes, 0, bytes.length, StandardCharsets.UTF_8);
-  }
-
-  /** Reads the contents of an input stream and returns as a string. */
-  public static byte[] readFullyToBytes(InputStream inputStream) throws IOException {
-    return readFullyToBytes(inputStream, new UnsynchronizedBuffer(1024));
-  }
-
-  /** Reads the contents of an input stream and returns as a string. */
-  public static byte[] readFullyToBytes(InputStream inputStream, UnsynchronizedBuffer buffer)
-      throws IOException {
-    // Variant that lets us use a pooled Buffer
-    return _readFully(inputStream, buffer);
-  }
-
-  /**
-   * Reads the contents of an input stream and returns a byte array.
-   *
-   * @param inputStream the input to read from.
-   * @return A byte array whose length is equal to the number of bytes contained.
-   */
-  static byte[] _readFully(InputStream inputStream, UnsynchronizedBuffer buffer)
-      throws IOException {
-    final byte[] bytes = PER_THREAD_BUFFER.get();
-    for (;;) {
-      int count = inputStream.read(bytes, 0, bytes.length);
-      if (count < 0) {
-        break;
-      }
-      buffer.write(bytes, 0, count);
-    }
-    return buffer.toArray();
-  }
-
-  /** Invokes {@code Statement#setLargeMaxRows}, falling back on
-   * {@link Statement#setMaxRows(int)} if the method does not exist (before
-   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
-  public static void setLargeMaxRows(Statement statement, long n)
-      throws SQLException {
-    if (SET_LARGE_MAX_ROWS != null) {
-      try {
-        // Call Statement.setLargeMaxRows
-        SET_LARGE_MAX_ROWS.invokeExact(n);
-        return;
-      } catch (UnsupportedOperationException e) {
-        // ignore, and fall through to call Statement.setMaxRows
-      } catch (Error | RuntimeException | SQLException e) {
-        throw e;
-      } catch (Throwable e) {
-        throw new RuntimeException(e);
-      }
-    }
-    int i = (int) Math.max(Math.min(n, Integer.MAX_VALUE), Integer.MIN_VALUE);
-    statement.setMaxRows(i);
-  }
-
-  /** Invokes {@code Statement#getLargeMaxRows}, falling back on
-   * {@link Statement#getMaxRows()} if the method does not exist (before
-   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
-  public static long getLargeMaxRows(Statement statement) throws SQLException {
-    if (GET_LARGE_MAX_ROWS != null) {
-      try {
-        // Call Statement.getLargeMaxRows
-        return (long) GET_LARGE_MAX_ROWS.invokeExact();
-      } catch (UnsupportedOperationException e) {
-        // ignore, and fall through to call Statement.getMaxRows
-      } catch (Error | RuntimeException | SQLException e) {
-        throw e;
-      } catch (Throwable e) {
-        throw new RuntimeException(e);
-      }
-    }
-    return statement.getMaxRows();
-  }
-
-  /** Invokes {@code Statement#getLargeUpdateCount}, falling back on
-   * {@link Statement#getUpdateCount()} if the method does not exist (before
-   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
-  public static long getLargeUpdateCount(Statement statement)
-      throws SQLException {
-    if (GET_LARGE_UPDATE_COUNT != null) {
-      try {
-        // Call Statement.getLargeUpdateCount
-        return (long) GET_LARGE_UPDATE_COUNT.invokeExact();
-      } catch (UnsupportedOperationException e) {
-        // ignore, and fall through to call Statement.getUpdateCount
-      } catch (Error | RuntimeException | SQLException e) {
-        throw e;
-      } catch (Throwable e) {
-        throw new RuntimeException(e);
-      }
-    }
-    return statement.getUpdateCount();
-  }
-
-  /** Generates a string that is unique in the execution of the JVM.
-   * It is used by tests to ensure that they create distinct temporary tables.
-   * The strings are never thrown away, so don't put too much in there!
-   * Thread safe. */
-  public static String unique(String base) {
-    synchronized (UNIQUE_STRINGS) {
-      String s = base;
-      while (!UNIQUE_STRINGS.add(s)) {
-        s = base + "_" + UNIQUE_STRINGS.size();
-      }
-      return s;
-    }
-  }
-}
-
-// End AvaticaUtils.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java b/avatica/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
deleted file mode 100644
index 086ae4a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/BuiltInConnectionProperty.java
+++ /dev/null
@@ -1,103 +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.remote.AvaticaHttpClientFactoryImpl;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import static org.apache.calcite.avatica.ConnectionConfigImpl.PropEnv;
-import static org.apache.calcite.avatica.ConnectionConfigImpl.parse;
-
-/**
- * Enumeration of Avatica's built-in connection properties.
- */
-public enum BuiltInConnectionProperty implements ConnectionProperty {
-  /** Factory. */
-  FACTORY("factory", Type.PLUGIN, null, false),
-
-  /** Name of initial schema. */
-  SCHEMA("schema", Type.STRING, null, false),
-
-  /** Time zone, for example 'gmt-3'. Default is the JVM's time zone. */
-  TIME_ZONE("timeZone", Type.STRING, null, false),
-
-  /** Remote URL. */
-  URL("url", Type.STRING, null, false),
-
-  /** Serialization used over remote connections */
-  SERIALIZATION("serialization", Type.STRING, "json", false),
-
-  /** Factory for constructing http clients. */
-  HTTP_CLIENT_FACTORY("httpclient_factory", Type.PLUGIN,
-      AvaticaHttpClientFactoryImpl.class.getName(), false),
-
-  /** HttpClient implementation class name. */
-  HTTP_CLIENT_IMPL("httpclient_impl", Type.STRING, null, false);
-
-  private final String camelName;
-  private final Type type;
-  private final Object defaultValue;
-  private final boolean required;
-
-  /** Deprecated; use {@link #TIME_ZONE}. */
-  @Deprecated // to be removed before 2.0
-  public static final BuiltInConnectionProperty TIMEZONE = TIME_ZONE;
-
-  private static final Map<String, BuiltInConnectionProperty> NAME_TO_PROPS;
-
-  static {
-    NAME_TO_PROPS = new HashMap<>();
-    for (BuiltInConnectionProperty p : BuiltInConnectionProperty.values()) {
-      NAME_TO_PROPS.put(p.camelName.toUpperCase(), p);
-      NAME_TO_PROPS.put(p.name(), p);
-    }
-  }
-
-  BuiltInConnectionProperty(String camelName, Type type, Object defaultValue,
-      boolean required) {
-    this.camelName = camelName;
-    this.type = type;
-    this.defaultValue = defaultValue;
-    this.required = required;
-    assert defaultValue == null || type.valid(defaultValue);
-  }
-
-  public String camelName() {
-    return camelName;
-  }
-
-  public Object defaultValue() {
-    return defaultValue;
-  }
-
-  public Type type() {
-    return type;
-  }
-
-  public boolean required() {
-    return required;
-  }
-
-  public PropEnv wrap(Properties properties) {
-    return new PropEnv(parse(properties, NAME_TO_PROPS), this);
-  }
-}
-
-// End BuiltInConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index bcdc228..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
+++ /dev/null
@@ -1,593 +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.util.ByteString;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-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.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;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Metadata for a column.
- *
- * <p>(Compare with {@link java.sql.ResultSetMetaData}.)
- */
-public class ColumnMetaData {
-  private static final FieldDescriptor CATALOG_NAME_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.CATALOG_NAME_FIELD_NUMBER);
-  private static final FieldDescriptor SCHEMA_NAME_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.SCHEMA_NAME_FIELD_NUMBER);
-  private static final FieldDescriptor LABEL_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.LABEL_FIELD_NUMBER);
-  private static final FieldDescriptor COLUMN_NAME_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.COLUMN_NAME_FIELD_NUMBER);
-  private static final FieldDescriptor TABLE_NAME_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.TABLE_NAME_FIELD_NUMBER);
-  private static final FieldDescriptor COLUMN_CLASS_NAME_DESCRIPTOR = Common.ColumnMetaData
-      .getDescriptor().findFieldByNumber(Common.ColumnMetaData.COLUMN_CLASS_NAME_FIELD_NUMBER);
-
-  public final int ordinal; // 0-based
-  public final boolean autoIncrement;
-  public final boolean caseSensitive;
-  public final boolean searchable;
-  public final boolean currency;
-  public final int nullable;
-  public final boolean signed;
-  public final int displaySize;
-  public final String label;
-  public final String columnName;
-  public final String schemaName;
-  public final int precision;
-  public final int scale;
-  public final String tableName;
-  public final String catalogName;
-  public final boolean readOnly;
-  public final boolean writable;
-  public final boolean definitelyWritable;
-  public final String columnClassName;
-  public final AvaticaType type;
-
-  @JsonCreator
-  public ColumnMetaData(
-      @JsonProperty("ordinal") int ordinal,
-      @JsonProperty("autoIncrement") boolean autoIncrement,
-      @JsonProperty("caseSensitive") boolean caseSensitive,
-      @JsonProperty("searchable") boolean searchable,
-      @JsonProperty("currency") boolean currency,
-      @JsonProperty("nullable") int nullable,
-      @JsonProperty("signed") boolean signed,
-      @JsonProperty("displaySize") int displaySize,
-      @JsonProperty("label") String label,
-      @JsonProperty("columnName") String columnName,
-      @JsonProperty("schemaName") String schemaName,
-      @JsonProperty("precision") int precision,
-      @JsonProperty("scale") int scale,
-      @JsonProperty("tableName") String tableName,
-      @JsonProperty("catalogName") String catalogName,
-      @JsonProperty("type") AvaticaType type,
-      @JsonProperty("readOnly") boolean readOnly,
-      @JsonProperty("writable") boolean writable,
-      @JsonProperty("definitelyWritable") boolean definitelyWritable,
-      @JsonProperty("columnClassName") String columnClassName) {
-    this.ordinal = ordinal;
-    this.autoIncrement = autoIncrement;
-    this.caseSensitive = caseSensitive;
-    this.searchable = searchable;
-    this.currency = currency;
-    this.nullable = nullable;
-    this.signed = signed;
-    this.displaySize = displaySize;
-    this.label = label;
-    // Per the JDBC spec this should be just columnName.
-    // For example, the query
-    //     select 1 as x, c as y from t
-    // should give columns
-    //     (label=x, column=null, table=null)
-    //     (label=y, column=c table=t)
-    // But DbUnit requires every column to have a name. Duh.
-    this.columnName = first(columnName, label);
-    this.schemaName = schemaName;
-    this.precision = precision;
-    this.scale = scale;
-    this.tableName = tableName;
-    this.catalogName = catalogName;
-    this.type = type;
-    this.readOnly = readOnly;
-    this.writable = writable;
-    this.definitelyWritable = definitelyWritable;
-    this.columnClassName = columnClassName;
-  }
-
-  public Common.ColumnMetaData toProto() {
-    Common.ColumnMetaData.Builder builder = Common.ColumnMetaData.newBuilder();
-
-    // Primitive fields (can't be null)
-    builder.setOrdinal(ordinal)
-      .setAutoIncrement(autoIncrement)
-      .setCaseSensitive(caseSensitive)
-      .setSearchable(searchable)
-      .setCurrency(currency)
-      .setNullable(nullable)
-      .setSigned(signed)
-      .setDisplaySize(displaySize)
-      .setPrecision(precision)
-      .setScale(scale)
-      .setReadOnly(readOnly)
-      .setWritable(writable)
-      .setDefinitelyWritable(definitelyWritable);
-
-    // Potentially null fields
-    if (null != label) {
-      builder.setLabel(label);
-    }
-
-    if (null != columnName) {
-      builder.setColumnName(columnName);
-    }
-
-    if (null != schemaName) {
-      builder.setSchemaName(schemaName);
-    }
-
-    if (null != tableName) {
-      builder.setTableName(tableName);
-    }
-
-    if (null != catalogName) {
-      builder.setCatalogName(catalogName);
-    }
-
-    if (null != type) {
-      builder.setType(type.toProto());
-    }
-
-    if (null != columnClassName) {
-      builder.setColumnClassName(columnClassName);
-    }
-
-    return builder.build();
-  }
-
-  public static ColumnMetaData fromProto(Common.ColumnMetaData proto) {
-    AvaticaType nestedType = AvaticaType.fromProto(proto.getType());
-
-    String catalogName = null;
-    if (proto.hasField(CATALOG_NAME_DESCRIPTOR)) {
-      catalogName = proto.getCatalogName();
-    }
-
-    String schemaName = null;
-    if (proto.hasField(SCHEMA_NAME_DESCRIPTOR)) {
-      schemaName = proto.getSchemaName();
-    }
-
-    String label = null;
-    if (proto.hasField(LABEL_DESCRIPTOR)) {
-      label = proto.getLabel();
-    }
-
-    String columnName = null;
-    if (proto.hasField(COLUMN_NAME_DESCRIPTOR)) {
-      columnName = proto.getColumnName();
-    }
-
-    String tableName = null;
-    if (proto.hasField(TABLE_NAME_DESCRIPTOR)) {
-      tableName = proto.getTableName();
-    }
-
-    String columnClassName = null;
-    if (proto.hasField(COLUMN_CLASS_NAME_DESCRIPTOR)) {
-      columnClassName = proto.getColumnClassName();
-    }
-
-    // Recreate the ColumnMetaData
-    return new ColumnMetaData(proto.getOrdinal(), proto.getAutoIncrement(),
-        proto.getCaseSensitive(), proto.getSearchable(), proto.getCurrency(), proto.getNullable(),
-        proto.getSigned(), proto.getDisplaySize(), label, columnName,
-        schemaName, proto.getPrecision(), proto.getScale(), tableName,
-        catalogName, nestedType, proto.getReadOnly(), proto.getWritable(),
-        proto.getDefinitelyWritable(), columnClassName);
-  }
-
-  @Override public int hashCode() {
-    return Objects.hash(autoIncrement, caseSensitive, catalogName,
-        columnClassName, columnName, currency, definitelyWritable, displaySize,
-        label, nullable, ordinal, precision, readOnly, scale, schemaName,
-        searchable, signed, tableName, type, writable);
-  }
-
-  @Override public boolean equals(Object o) {
-    return o == this
-        || o instanceof ColumnMetaData
-        && autoIncrement == ((ColumnMetaData) o).autoIncrement
-        && caseSensitive == ((ColumnMetaData) o).caseSensitive
-        && Objects.equals(catalogName, ((ColumnMetaData) o).catalogName)
-        && Objects.equals(columnClassName, ((ColumnMetaData) o).columnClassName)
-        && Objects.equals(columnName, ((ColumnMetaData) o).columnName)
-        && currency == ((ColumnMetaData) o).currency
-        && definitelyWritable == ((ColumnMetaData) o).definitelyWritable
-        && displaySize == ((ColumnMetaData) o).displaySize
-        && Objects.equals(label, ((ColumnMetaData) o).label)
-        && nullable == ((ColumnMetaData) o).nullable
-        && ordinal == ((ColumnMetaData) o).ordinal
-        && precision == ((ColumnMetaData) o).precision
-        && readOnly == ((ColumnMetaData) o).readOnly
-        && scale == ((ColumnMetaData) o).scale
-        && Objects.equals(schemaName, ((ColumnMetaData) o).schemaName)
-        && searchable == ((ColumnMetaData) o).searchable
-        && signed == ((ColumnMetaData) o).signed
-        && Objects.equals(tableName, ((ColumnMetaData) o).tableName)
-        && Objects.equals(type, ((ColumnMetaData) o).type)
-        && writable == ((ColumnMetaData) o).writable;
-  }
-
-  private static <T> T first(T t0, T t1) {
-    return t0 != null ? t0 : t1;
-  }
-
-  /** Creates a {@link ScalarType}. */
-  public static ScalarType scalar(int type, String typeName, Rep rep) {
-    return new ScalarType(type, typeName, rep);
-  }
-
-  /** Creates a {@link StructType}. */
-  public static StructType struct(List<ColumnMetaData> columns) {
-    return new StructType(columns);
-  }
-
-  /** Creates an {@link ArrayType}. */
-  public static ArrayType array(AvaticaType componentType, String typeName,
-      Rep rep) {
-    return new ArrayType(Types.ARRAY, typeName, rep, componentType);
-  }
-
-  /** Creates a ColumnMetaData for result sets that are not based on a struct
-   * but need to have a single 'field' for purposes of
-   * {@link java.sql.ResultSetMetaData}. */
-  public static ColumnMetaData dummy(AvaticaType type, boolean nullable) {
-    return new ColumnMetaData(
-        0,
-        false,
-        true,
-        false,
-        false,
-        nullable
-            ? DatabaseMetaData.columnNullable
-            : DatabaseMetaData.columnNoNulls,
-        true,
-        -1,
-        null,
-        null,
-        null,
-        -1,
-        -1,
-        null,
-        null,
-        type,
-        true,
-        false,
-        false,
-        type.columnClassName());
-  }
-
-  public ColumnMetaData setRep(Rep rep) {
-    return new ColumnMetaData(ordinal, autoIncrement, caseSensitive, searchable,
-        currency, nullable, signed, displaySize, label, columnName, schemaName,
-        precision, scale, tableName, catalogName, type.setRep(rep), readOnly,
-        writable, definitelyWritable, columnClassName);
-  }
-
-  /** Description of the type used to internally represent a value. For example,
-   * a {@link java.sql.Date} might be represented as a {@link #PRIMITIVE_INT}
-   * if not nullable, or a {@link #JAVA_SQL_DATE}. */
-  public enum Rep {
-    PRIMITIVE_BOOLEAN(boolean.class),
-    PRIMITIVE_BYTE(byte.class),
-    PRIMITIVE_CHAR(char.class),
-    PRIMITIVE_SHORT(short.class),
-    PRIMITIVE_INT(int.class),
-    PRIMITIVE_LONG(long.class),
-    PRIMITIVE_FLOAT(float.class),
-    PRIMITIVE_DOUBLE(double.class),
-    BOOLEAN(Boolean.class),
-    BYTE(Byte.class),
-    CHARACTER(Character.class),
-    SHORT(Short.class),
-    INTEGER(Integer.class),
-    LONG(Long.class),
-    FLOAT(Float.class),
-    DOUBLE(Double.class),
-    JAVA_SQL_TIME(Time.class),
-    JAVA_SQL_TIMESTAMP(Timestamp.class),
-    JAVA_SQL_DATE(java.sql.Date.class),
-    JAVA_UTIL_DATE(java.util.Date.class),
-    BYTE_STRING(ByteString.class),
-    STRING(String.class),
-
-    /** 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;
-
-    public static final Map<Class, Rep> VALUE_MAP;
-
-    static {
-      Map<Class, Rep> builder = new HashMap<>();
-      for (Rep rep : values()) {
-        builder.put(rep.clazz, rep);
-      }
-      VALUE_MAP = Collections.unmodifiableMap(builder);
-    }
-
-    Rep(Class clazz) {
-      this.clazz = clazz;
-    }
-
-    public static Rep of(Type clazz) {
-      //noinspection SuspiciousMethodCalls
-      final Rep rep = VALUE_MAP.get(clazz);
-      return rep != null ? rep : OBJECT;
-    }
-
-    /** Returns the value of a column of this type from a result set. */
-    public Object jdbcGet(ResultSet resultSet, int i) throws SQLException {
-      switch (this) {
-      case PRIMITIVE_BOOLEAN:
-        return resultSet.getBoolean(i);
-      case PRIMITIVE_BYTE:
-        return resultSet.getByte(i);
-      case PRIMITIVE_SHORT:
-        return resultSet.getShort(i);
-      case PRIMITIVE_INT:
-        return resultSet.getInt(i);
-      case PRIMITIVE_LONG:
-        return resultSet.getLong(i);
-      case PRIMITIVE_FLOAT:
-        return resultSet.getFloat(i);
-      case PRIMITIVE_DOUBLE:
-        return resultSet.getDouble(i);
-      case BOOLEAN:
-        final boolean aBoolean = resultSet.getBoolean(i);
-        return resultSet.wasNull() ? null : aBoolean;
-      case BYTE:
-        final byte aByte = resultSet.getByte(i);
-        return resultSet.wasNull() ? null : aByte;
-      case SHORT:
-        final short aShort = resultSet.getShort(i);
-        return resultSet.wasNull() ? null : aShort;
-      case INTEGER:
-        final int anInt = resultSet.getInt(i);
-        return resultSet.wasNull() ? null : anInt;
-      case LONG:
-        final long aLong = resultSet.getLong(i);
-        return resultSet.wasNull() ? null : aLong;
-      case FLOAT:
-        final float aFloat = resultSet.getFloat(i);
-        return resultSet.wasNull() ? null : aFloat;
-      case DOUBLE:
-        final double aDouble = resultSet.getDouble(i);
-        return resultSet.wasNull() ? null : aDouble;
-      case JAVA_SQL_DATE:
-        return resultSet.getDate(i);
-      case JAVA_SQL_TIME:
-        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);
-      }
-    }
-
-    public Common.Rep toProto() {
-      return Common.Rep.valueOf(name());
-    }
-
-    public static Rep fromProto(Common.Rep proto) {
-      return Rep.valueOf(proto.name());
-    }
-  }
-
-  /** Base class for a column type. */
-  @JsonTypeInfo(
-      use = JsonTypeInfo.Id.NAME,
-      property = "type",
-      defaultImpl = ScalarType.class)
-  @JsonSubTypes({
-      @JsonSubTypes.Type(value = ScalarType.class, name = "scalar"),
-      @JsonSubTypes.Type(value = StructType.class, name = "struct"),
-      @JsonSubTypes.Type(value = ArrayType.class, name = "array") })
-  public static class AvaticaType {
-    public final int id;
-    public final String name;
-
-    /** The type of the field that holds the value. Not a JDBC property. */
-    public final Rep rep;
-
-    public AvaticaType(int id, String name, Rep rep) {
-      this.id = id;
-      this.name = Objects.requireNonNull(name);
-      this.rep = Objects.requireNonNull(rep);
-    }
-
-    public String columnClassName() {
-      return SqlType.valueOf(id).boxedClass().getName();
-    }
-
-    public AvaticaType setRep(Rep rep) {
-      throw new UnsupportedOperationException();
-    }
-
-    public Common.AvaticaType toProto() {
-      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder();
-
-      builder.setName(name);
-      builder.setId(id);
-      builder.setRep(rep.toProto());
-
-      return builder.build();
-    }
-
-    public static AvaticaType fromProto(Common.AvaticaType proto) {
-      Common.Rep repProto = proto.getRep();
-      Rep rep = Rep.valueOf(repProto.name());
-      AvaticaType type;
-
-      if (proto.hasComponent()) {
-        // ArrayType
-        // recurse on the type for the array elements
-        AvaticaType nestedType = AvaticaType.fromProto(proto.getComponent());
-        type = ColumnMetaData.array(nestedType, proto.getName(), rep);
-      } else if (proto.getColumnsCount() > 0) {
-        // StructType
-        List<ColumnMetaData> columns = new ArrayList<>(proto.getColumnsCount());
-        for (Common.ColumnMetaData protoColumn : proto.getColumnsList()) {
-          columns.add(ColumnMetaData.fromProto(protoColumn));
-        }
-        type = ColumnMetaData.struct(columns);
-      } else {
-        // ScalarType
-        type = ColumnMetaData.scalar(proto.getId(), proto.getName(), rep);
-      }
-
-      return type;
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(id, name, rep);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof AvaticaType
-          && id == ((AvaticaType) o).id
-          && Objects.equals(name, ((AvaticaType) o).name)
-          && rep == ((AvaticaType) o).rep;
-    }
-  }
-
-  /** Scalar type. */
-  public static class ScalarType extends AvaticaType {
-    @JsonCreator
-    public ScalarType(@JsonProperty("id") int id,
-        @JsonProperty("name") String name,
-        @JsonProperty("rep") Rep rep) {
-      super(id, name, rep);
-    }
-
-    @Override public AvaticaType setRep(Rep rep) {
-      return new ScalarType(id, name, rep);
-    }
-  }
-
-  /** Record type. */
-  public static class StructType extends AvaticaType {
-    public final List<ColumnMetaData> columns;
-
-    @JsonCreator
-    public StructType(List<ColumnMetaData> columns) {
-      super(Types.STRUCT, "STRUCT", ColumnMetaData.Rep.OBJECT);
-      this.columns = columns;
-    }
-
-    @Override public Common.AvaticaType toProto() {
-      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder(super.toProto());
-      for (ColumnMetaData valueType : columns) {
-        builder.addColumns(valueType.toProto());
-      }
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(id, name, rep, columns);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof StructType
-          && super.equals(o)
-          && Objects.equals(columns, ((StructType) o).columns);
-    }
-  }
-
-  /** Array type. */
-  public static class ArrayType extends AvaticaType {
-    public final 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;
-    }
-
-    @Override public Common.AvaticaType toProto() {
-      Common.AvaticaType.Builder builder = Common.AvaticaType.newBuilder(super.toProto());
-
-      builder.setComponent(component.toProto());
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      return Objects.hash(id, name, rep, component);
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ArrayType
-          && super.equals(o)
-          && Objects.equals(component, ((ArrayType) o).component);
-    }
-  }
-}
-
-// End ColumnMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
deleted file mode 100644
index 0145024..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectStringParser.java
+++ /dev/null
@@ -1,391 +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;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * ConnectStringParser is a utility class that parses or creates a JDBC connect
- * string according to the
- * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms722656(v=vs.85).aspx">
- * OLE DB Connection String Syntax</a>.
- *
- * <p>This code was adapted from Mondrian's mondrian.olap.Util class.
- * The primary differences between this and its Mondrian progenitor are:
- *
- * <ul>
- * <li>use of regular {@link Properties} for compatibility with the JDBC API
- * (replaces Mondrian's use of its own order-preserving and case-insensitive
- * PropertyList)</li>
- *
- * <li>ability to pass to {@link #parse} a pre-existing Properties object into
- * which properties are to be parsed, possibly overriding prior values</li>
- *
- * <li>use of {@link SQLException}s rather than unchecked
- * {@link RuntimeException}s</li>
- *
- * <li>static members for parsing and creating connect strings</li>
- *
- * </ul>
- *
- * <p>ConnectStringParser has a private constructor. Callers use the static
- * members:
- *
- * <dl>
- * <dt>{@link #parse(String)}
- * <dd>Parses the connect string into a new Properties object.
- *
- * <dt>{@link #parse(String, Properties)}
- * <dd>Parses the connect string into an existing Properties object.
- *
- * <dt>{@link #getParamString(Properties)}
- * <dd>Returns a param string, quoted and escaped as needed, to represent the
- * supplied name-value pairs.
- * </dl>
- */
-public class ConnectStringParser {
-  //~ Instance fields --------------------------------------------------------
-
-  private final String s;
-  private final int n;
-  private int i;
-  private final StringBuilder nameBuf = new StringBuilder();
-  private final StringBuilder valueBuf = new StringBuilder();
-
-  //~ Constructors -----------------------------------------------------------
-
-  /**
-   * Creates a new connect string parser.
-   *
-   * @param s connect string to parse
-   *
-   * @see #parse(String)
-   * @see #parse(String, Properties)
-   */
-  private ConnectStringParser(String s) {
-    this.s = s;
-    this.i = 0;
-    this.n = s.length();
-  }
-
-  //~ Methods ----------------------------------------------------------------
-
-  /**
-   * Parses the connect string into a new Properties object.
-   *
-   * @param s connect string to parse
-   *
-   * @return properties object with parsed params
-   *
-   * @throws SQLException error parsing name-value pairs
-   */
-  public static Properties parse(String s)
-      throws SQLException {
-    return new ConnectStringParser(s).parseInternal(null);
-  }
-
-  /**
-   * Parses the connect string into an existing Properties object.
-   *
-   * @param s connect string to parse
-   * @param props optional properties object, may be <code>null</code>
-   *
-   * @return properties object with parsed params; if an input <code>
-   * props</code> was supplied, any duplicate properties will have been
-   * replaced by those from the connect string.
-   *
-   * @throws SQLException error parsing name-value pairs
-   */
-  public static Properties parse(String s, Properties props)
-      throws SQLException {
-    return new ConnectStringParser(s).parseInternal(props);
-  }
-
-  /**
-   * Parses the connect string into a Properties object. Note that the string
-   * can only be parsed once. Subsequent calls return empty/unchanged
-   * Properties.
-   *
-   * @param props optional properties object, may be <code>null</code>
-   *
-   * @return properties object with parsed params; if an input <code>
-   * props</code> was supplied, any duplicate properties will have been
-   * replaced by those from the connect string.
-   *
-   * @throws SQLException error parsing name-value pairs
-   */
-  Properties parseInternal(Properties props)
-      throws SQLException {
-    if (props == null) {
-      props = new Properties();
-    }
-    while (i < n) {
-      parsePair(props);
-    }
-    return props;
-  }
-
-  /**
-   * Reads "name=value;" or "name=value&lt;EOF&gt;".
-   *
-   * @throws SQLException error parsing value
-   */
-  void parsePair(Properties props)
-      throws SQLException {
-    String name = parseName();
-    String value;
-    if (i >= n) {
-      value = "";
-    } else if (s.charAt(i) == ';') {
-      i++;
-      value = "";
-    } else {
-      value = parseValue();
-    }
-    props.put(name, value);
-  }
-
-  /**
-   * Reads "name=". Name can contain equals sign if equals sign is doubled.
-   */
-  String parseName() {
-    nameBuf.setLength(0);
-    while (true) {
-      char c = s.charAt(i);
-      switch (c) {
-      case '=':
-        i++;
-        if ((i < n) && ((c = s.charAt(i)) == '=')) {
-          // doubled equals sign; take one of them, and carry on
-          i++;
-          nameBuf.append(c);
-          break;
-        }
-        String name = nameBuf.toString();
-        name = name.trim();
-        return name;
-      case ' ':
-        if (nameBuf.length() == 0) {
-          // ignore preceding spaces
-          i++;
-          break;
-        }
-        // fall through
-      default:
-        nameBuf.append(c);
-        i++;
-        if (i >= n) {
-          return nameBuf.toString().trim();
-        }
-      }
-    }
-  }
-
-  /**
-   * Reads "value;" or "value&lt;EOF&gt;"
-   *
-   * @throws SQLException if find an unterminated quoted value
-   */
-  String parseValue()
-      throws SQLException {
-    char c;
-
-    // skip over leading white space
-    while ((c = s.charAt(i)) == ' ') {
-      i++;
-      if (i >= n) {
-        return "";
-      }
-    }
-    if ((c == '"') || (c == '\'')) {
-      String value = parseQuoted(c);
-
-      // skip over trailing white space
-      while (i < n && s.charAt(i) == ' ') {
-        i++;
-      }
-      if (i >= n) {
-        return value;
-      } else if (s.charAt(i) == ';') {
-        i++;
-        return value;
-      } else {
-        throw new SQLException(
-            "quoted value ended too soon, at position " + i
-                + " in '" + s + "'");
-      }
-    } else {
-      String value;
-      int semi = s.indexOf(';', i);
-      if (semi >= 0) {
-        value = s.substring(i, semi);
-        i = semi + 1;
-      } else {
-        value = s.substring(i);
-        i = n;
-      }
-      return value.trim();
-    }
-  }
-
-  /**
-   * Reads a string quoted by a given character. Occurrences of the quoting
-   * character must be doubled. For example, <code>parseQuoted('"')</code>
-   * reads <code>"a ""new"" string"</code> and returns <code>a "new"
-   * string</code>.
-   *
-   * @throws SQLException if find an unterminated quoted value
-   */
-  String parseQuoted(char q)
-      throws SQLException {
-    char c = s.charAt(i++);
-    if (c != q) {
-      throw new AssertionError("c != q: c=" + c + " q=" + q);
-    }
-    valueBuf.setLength(0);
-    while (i < n) {
-      c = s.charAt(i);
-      if (c == q) {
-        i++;
-        if (i < n) {
-          c = s.charAt(i);
-          if (c == q) {
-            valueBuf.append(c);
-            i++;
-            continue;
-          }
-        }
-        return valueBuf.toString();
-      } else {
-        valueBuf.append(c);
-        i++;
-      }
-    }
-    throw new SQLException(
-        "Connect string '" + s
-            + "' contains unterminated quoted value '"
-            + valueBuf.toString() + "'");
-  }
-
-  /**
-   * Returns a param string, quoted and escaped as needed, to represent the
-   * supplied name-value pairs.
-   *
-   * @param props name-value pairs
-   *
-   * @return param string, never <code>null</code>
-   */
-  public static String getParamString(Properties props) {
-    if (props == null) {
-      return "";
-    }
-
-    StringBuilder buf = new StringBuilder();
-    for (Map.Entry<String, String> entry : toMap(props).entrySet()) {
-      final String name = entry.getKey();
-      final String value = entry.getValue();
-      String quote = "";
-      if (buf.length() > 0) {
-        buf.append(';');
-      }
-
-      // write parameter name
-      if (name.startsWith(" ") || name.endsWith(" ")) {
-        quote = "'";
-        buf.append(quote);
-      }
-      int len = name.length();
-      for (int i = 0; i < len; ++i) {
-        char c = name.charAt(i);
-        if (c == '=') {
-          buf.append('=');
-        }
-        buf.append(c);
-      }
-
-      buf.append(quote); // might be empty
-      quote = "";
-
-      buf.append('=');
-
-      // write parameter value
-      len = value.length();
-      boolean hasSemi = value.indexOf(';') >= 0;
-      boolean hasSQ = value.indexOf('\'') >= 0;
-      boolean hasDQ = value.indexOf('"') >= 0;
-      if (value.startsWith(" ") || value.endsWith(" ")) {
-        quote = "'";
-      } else if (hasSemi || hasSQ || hasDQ) {
-        // try to choose the least painful quote
-        if (value.startsWith("\"")) {
-          quote = "'";
-        } else if (value.startsWith("'")) {
-          quote = "\"";
-        } else {
-          quote = hasSQ ? "\"" : "'";
-        }
-      }
-      char q;
-      if (quote.length() > 0) {
-        buf.append(quote);
-        q = quote.charAt(0);
-      } else {
-        q = '\0';
-      }
-      for (int i = 0; i < len; ++i) {
-        char c = value.charAt(i);
-        if (c == q) {
-          buf.append(q);
-        }
-        buf.append(c);
-      }
-      buf.append(quote); // might be empty
-    }
-
-    return buf.toString();
-  }
-
-  /**
-   * Converts a {@link Properties} object to a <code>{@link Map}&lt;String,
-   * String&gt;</code>.
-   *
-   * <p>This is necessary because {@link Properties} is a dinosaur class. It
-   * ought to extend <code>Map&lt;String,String&gt;</code>, but instead
-   * extends <code>{@link java.util.Hashtable}&lt;Object,Object&gt;</code>.
-   *
-   * <p>Typical usage, to iterate over a {@link Properties}:
-   *
-   * <blockquote>
-   * <code>
-   * Properties properties;<br>
-   * for (Map.Entry&lt;String, String&gt; entry =
-   * Util.toMap(properties).entrySet()) {<br>
-   *   println("key=" + entry.getKey() + ", value=" + entry.getValue());<br>
-   * }
-   * </code>
-   * </blockquote>
-   */
-  public static Map<String, String> toMap(
-      final Properties properties) {
-    //noinspection unchecked
-    return (Map) properties;
-  }
-}
-
-// End ConnectStringParser.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
deleted file mode 100644
index 8e4790c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfig.java
+++ /dev/null
@@ -1,40 +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.remote.AvaticaHttpClientFactory;
-import org.apache.calcite.avatica.remote.Service;
-
-/**
- * Connection configuration.
- */
-public interface ConnectionConfig {
-  /** @see BuiltInConnectionProperty#SCHEMA */
-  String schema();
-  /** @see BuiltInConnectionProperty#TIME_ZONE */
-  String timeZone();
-  /** @see BuiltInConnectionProperty#FACTORY */
-  Service.Factory factory();
-  /** @see BuiltInConnectionProperty#URL */
-  String url();
-  /** @see BuiltInConnectionProperty#SERIALIZATION */
-  String serialization();
-  AvaticaHttpClientFactory httpClientFactory();
-  String httpClientClass();
-}
-
-// End ConnectionConfig.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
deleted file mode 100644
index bbeefea..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
+++ /dev/null
@@ -1,239 +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.remote.AvaticaHttpClientFactory;
-import org.apache.calcite.avatica.remote.Service;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-
-/** Implementation of {@link ConnectionConfig}. */
-public class ConnectionConfigImpl implements ConnectionConfig {
-  protected final Properties properties;
-
-  public ConnectionConfigImpl(Properties properties) {
-    this.properties = properties;
-  }
-
-  public String schema() {
-    return BuiltInConnectionProperty.SCHEMA.wrap(properties).getString();
-  }
-
-  public String timeZone() {
-    return BuiltInConnectionProperty.TIME_ZONE.wrap(properties).getString();
-  }
-
-  public Service.Factory factory() {
-    return BuiltInConnectionProperty.FACTORY.wrap(properties)
-        .getPlugin(Service.Factory.class, null);
-  }
-
-  public String url() {
-    return BuiltInConnectionProperty.URL.wrap(properties).getString();
-  }
-
-  public String serialization() {
-    return BuiltInConnectionProperty.SERIALIZATION.wrap(properties).getString();
-  }
-
-  public AvaticaHttpClientFactory httpClientFactory() {
-    return BuiltInConnectionProperty.HTTP_CLIENT_FACTORY.wrap(properties)
-        .getPlugin(AvaticaHttpClientFactory.class, null);
-  }
-
-  public String httpClientClass() {
-    return BuiltInConnectionProperty.HTTP_CLIENT_IMPL.wrap(properties).getString();
-  }
-
-  /** Converts a {@link Properties} object containing (name, value)
-   * pairs into a map whose keys are
-   * {@link org.apache.calcite.avatica.InternalProperty} objects.
-   *
-   * <p>Matching is case-insensitive. Throws if a property is not known.
-   * If a property occurs more than once, takes the last occurrence.</p>
-   *
-   * @param properties Properties
-   * @return Map
-   * @throws RuntimeException if a property is not known
-   */
-  public static Map<ConnectionProperty, String> parse(Properties properties,
-      Map<String, ? extends ConnectionProperty> nameToProps) {
-    final Map<ConnectionProperty, String> map =
-        new LinkedHashMap<ConnectionProperty, String>();
-    for (String name : properties.stringPropertyNames()) {
-      final ConnectionProperty connectionProperty =
-          nameToProps.get(name.toUpperCase());
-      if (connectionProperty == null) {
-        // For now, don't throw. It messes up sub-projects.
-        //throw new RuntimeException("Unknown property '" + name + "'");
-        continue;
-      }
-      map.put(connectionProperty, properties.getProperty(name));
-    }
-    return map;
-  }
-
-  /** The combination of a property definition and a map of property values. */
-  public static class PropEnv {
-    final Map<? extends ConnectionProperty, String> map;
-    private final ConnectionProperty property;
-
-    public PropEnv(Map<? extends ConnectionProperty, String> map,
-        ConnectionProperty property) {
-      this.map = map;
-      this.property = property;
-    }
-
-    private <T> T get_(Converter<T> converter, String defaultValue) {
-      final String s = map.get(property);
-      if (s != null) {
-        return converter.apply(property, s);
-      }
-      return converter.apply(property, defaultValue);
-    }
-
-    /** Returns the string value of this property, or null if not specified and
-     * no default. */
-    public String getString() {
-      return getString((String) property.defaultValue());
-    }
-
-    /** Returns the string value of this property, or null if not specified and
-     * no default. */
-    public String getString(String defaultValue) {
-      assert property.type() == ConnectionProperty.Type.STRING;
-      return get_(IDENTITY_CONVERTER, defaultValue);
-    }
-
-    /** Returns the boolean value of this property. Throws if not set and no
-     * default. */
-    public boolean getBoolean() {
-      return getBoolean((Boolean) property.defaultValue());
-    }
-
-    /** Returns the boolean value of this property. Throws if not set and no
-     * default. */
-    public boolean getBoolean(boolean defaultValue) {
-      assert property.type() == ConnectionProperty.Type.BOOLEAN;
-      return get_(BOOLEAN_CONVERTER, Boolean.toString(defaultValue));
-    }
-
-    /** Returns the enum value of this property. Throws if not set and no
-     * default. */
-    public <E extends Enum<E>> E getEnum(Class<E> enumClass) {
-      //noinspection unchecked
-      return getEnum(enumClass, (E) property.defaultValue());
-    }
-
-    /** Returns the enum value of this property. Throws if not set and no
-     * default. */
-    public <E extends Enum<E>> E getEnum(Class<E> enumClass, E defaultValue) {
-      assert property.type() == ConnectionProperty.Type.ENUM;
-      //noinspection unchecked
-      return get_(enumConverter(enumClass), defaultValue.name());
-    }
-
-    /** Returns an instance of a plugin.
-     *
-     * <p>Throws if not set and no default.
-     * Also throws if the class does not implement the required interface,
-     * or if it does not have a public default constructor or an public static
-     * field called {@code #INSTANCE}. */
-    public <T> T getPlugin(Class<T> pluginClass, T defaultInstance) {
-      return getPlugin(pluginClass, (String) property.defaultValue(),
-          defaultInstance);
-    }
-
-    /** Returns an instance of a plugin, using a given class name if none is
-     * set.
-     *
-     * <p>Throws if not set and no default.
-     * Also throws if the class does not implement the required interface,
-     * or if it does not have a public default constructor or an public static
-     * field called {@code #INSTANCE}. */
-    public <T> T getPlugin(Class<T> pluginClass, String defaultClassName,
-        T defaultInstance) {
-      assert property.type() == ConnectionProperty.Type.PLUGIN;
-      return get_(pluginConverter(pluginClass, defaultInstance),
-          defaultClassName);
-    }
-  }
-
-  /** Callback to parse a property from string to its native type. */
-  public interface Converter<T> {
-    T apply(ConnectionProperty connectionProperty, String s);
-  }
-
-  public static final Converter<Boolean> BOOLEAN_CONVERTER =
-      new Converter<Boolean>() {
-        public Boolean apply(ConnectionProperty connectionProperty, String s) {
-          if (s == null) {
-            throw new RuntimeException("Required property '"
-                + connectionProperty.camelName() + "' not specified");
-          }
-          return Boolean.parseBoolean(s);
-        }
-      };
-
-  public static final Converter<String> IDENTITY_CONVERTER =
-      new Converter<String>() {
-        public String apply(ConnectionProperty connectionProperty, String s) {
-          return s;
-        }
-      };
-
-  public static <E extends Enum> Converter<E> enumConverter(
-      final Class<E> enumClass) {
-    return new Converter<E>() {
-      public E apply(ConnectionProperty connectionProperty, String s) {
-        if (s == null) {
-          throw new RuntimeException("Required property '"
-              + connectionProperty.camelName() + "' not specified");
-        }
-        try {
-          return (E) Enum.valueOf(enumClass, s);
-        } catch (IllegalArgumentException e) {
-          throw new RuntimeException("Property '" + s + "' not valid for enum "
-              + enumClass.getName());
-        }
-      }
-    };
-  }
-
-  public static <T> Converter<T> pluginConverter(final Class<T> pluginClass,
-      final T defaultInstance) {
-    return new Converter<T>() {
-      public T apply(ConnectionProperty connectionProperty, String s) {
-        if (s == null) {
-          if (defaultInstance != null) {
-            return defaultInstance;
-          }
-          if (!connectionProperty.required()) {
-            return null;
-          }
-          throw new RuntimeException("Required property '"
-              + connectionProperty.camelName() + "' not specified");
-        }
-        return AvaticaUtils.instantiatePlugin(pluginClass, s);
-      }
-    };
-  }
-}
-
-// End ConnectionConfigImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
deleted file mode 100644
index c147ecc..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionPropertiesImpl.java
+++ /dev/null
@@ -1,279 +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 com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Objects;
-
-/** Concrete implementation of {@link Meta.ConnectionProperties}. Provides additional state
- * tracking to enable {@code RemoteMeta} to lazily push changes up to a query server.
- *
- * <p>{@code Meta} instances should probably hold authority on the {@code isDirty}
- * flag because {@code AvaticaConnection} instances have no way of knowing if they're local or
- * remote.
- */
-public class ConnectionPropertiesImpl implements Meta.ConnectionProperties {
-  private static final FieldDescriptor CATALOG_DESCRIPTOR = Common.ConnectionProperties
-      .getDescriptor().findFieldByNumber(Common.ConnectionProperties.CATALOG_FIELD_NUMBER);
-  private static final FieldDescriptor SCHEMA_DESCRIPTOR = Common.ConnectionProperties
-      .getDescriptor().findFieldByNumber(Common.ConnectionProperties.SCHEMA_FIELD_NUMBER);
-  private static final FieldDescriptor TRANSACTION_ISOLATION_DESCRIPTOR = Common
-      .ConnectionProperties.getDescriptor().findFieldByNumber(
-          Common.ConnectionProperties.TRANSACTION_ISOLATION_FIELD_NUMBER);
-
-  private boolean isDirty = false;
-  private Boolean autoCommit;
-  private Boolean readOnly;
-  private Integer transactionIsolation;
-  private String catalog;
-  private String schema;
-
-  // TODO: replace with Meta.ConnectionProperties$EMPTY instance?
-  public ConnectionPropertiesImpl() {}
-
-  public ConnectionPropertiesImpl(Connection conn) throws SQLException {
-    this(conn.getAutoCommit(), conn.isReadOnly(), conn.getTransactionIsolation(),
-        conn.getCatalog(), conn.getSchema());
-  }
-
-  @JsonCreator
-  public ConnectionPropertiesImpl(
-      @JsonProperty("autoCommit") Boolean autoCommit,
-      @JsonProperty("readOnly") Boolean readOnly,
-      @JsonProperty("transactionIsolation") Integer transactionIsolation,
-      @JsonProperty("catalog") String catalog,
-      @JsonProperty("schema") String schema) {
-    this.autoCommit = autoCommit;
-    this.readOnly = readOnly;
-    this.transactionIsolation = transactionIsolation;
-    this.catalog = catalog;
-    this.schema = schema;
-  }
-
-  public ConnectionPropertiesImpl setDirty(boolean val) {
-    this.isDirty = val;
-    return this;
-  }
-
-  public boolean isDirty() {
-    return this.isDirty;
-  }
-
-  @Override public boolean isEmpty() {
-    return autoCommit == null && readOnly == null && transactionIsolation == null
-        && catalog == null && schema == null;
-  }
-
-  /** Overwrites fields in {@code this} with any non-null fields in {@code that}. Sets
-   * {@code isDirty} if any fields are changed.
-   *
-   * @return {@code this}
-   */
-  @Override public ConnectionPropertiesImpl merge(Meta.ConnectionProperties that) {
-    if (this == that) {
-      return this;
-    }
-    if (that.isAutoCommit() != null && this.autoCommit != that.isAutoCommit()) {
-      this.autoCommit = that.isAutoCommit();
-      this.isDirty = true;
-    }
-    if (that.isReadOnly() != null && this.readOnly != that.isReadOnly()) {
-      this.readOnly = that.isReadOnly();
-      this.isDirty = true;
-    }
-    if (that.getTransactionIsolation() != null
-        && !that.getTransactionIsolation().equals(this.transactionIsolation)) {
-      this.transactionIsolation = that.getTransactionIsolation();
-      this.isDirty = true;
-    }
-    if (that.getCatalog() != null && !that.getCatalog().equalsIgnoreCase(this.catalog)) {
-      this.catalog = that.getCatalog();
-      this.isDirty = true;
-    }
-    if (that.getSchema() != null && !that.getSchema().equalsIgnoreCase(this.schema)) {
-      this.schema = that.getSchema();
-      this.isDirty = true;
-    }
-    return this;
-  }
-
-  /** Sets {@code autoCommit} status and flag as dirty.
-   *
-   * @return {@code this}
-   */
-  @Override public Meta.ConnectionProperties setAutoCommit(boolean val) {
-    this.autoCommit = val;
-    this.isDirty = true;
-    return this;
-  }
-
-  @Override public Boolean isAutoCommit() {
-    return this.autoCommit;
-  }
-
-  /** Sets {@code readOnly} status and flag as dirty.
-   *
-   * @return {@code this}
-   */
-  @Override public Meta.ConnectionProperties setReadOnly(boolean val) {
-    this.readOnly = val;
-    this.isDirty = true;
-    return this;
-  }
-
-  @Override public Boolean isReadOnly() {
-    return this.readOnly;
-  }
-
-  /** Sets {@code transactionIsolation} status and flag as dirty.
-   *
-   * @return {@code this}
-   */
-  @Override public Meta.ConnectionProperties setTransactionIsolation(int val) {
-    this.transactionIsolation = val;
-    this.isDirty = true;
-    return this;
-  }
-
-  public Integer getTransactionIsolation() {
-    return this.transactionIsolation;
-  }
-
-  /** Sets {@code catalog} and flag as dirty.
-   *
-   * @return {@code this}
-   */
-  @Override public Meta.ConnectionProperties setCatalog(String val) {
-    this.catalog = val;
-    this.isDirty = true;
-    return this;
-  }
-
-  @Override public String getCatalog() {
-    return this.catalog;
-  }
-
-  /** Sets {@code schema} and flag as dirty.
-   *
-   * @return {@code this}
-   */
-  @Override public Meta.ConnectionProperties setSchema(String val) {
-    this.schema = val;
-    this.isDirty = true;
-    return this;
-  }
-
-  public String getSchema() {
-    return this.schema;
-  }
-
-  @Override public int hashCode() {
-    return Objects.hash(autoCommit, catalog, isDirty, readOnly, schema,
-        transactionIsolation);
-  }
-
-  @Override public boolean equals(Object o) {
-    return o == this
-        || o instanceof ConnectionPropertiesImpl
-        && Objects.equals(autoCommit, ((ConnectionPropertiesImpl) o).autoCommit)
-        && Objects.equals(catalog, ((ConnectionPropertiesImpl) o).catalog)
-        && isDirty == ((ConnectionPropertiesImpl) o).isDirty
-        && Objects.equals(readOnly, ((ConnectionPropertiesImpl) o).readOnly)
-        && Objects.equals(schema, ((ConnectionPropertiesImpl) o).schema)
-        && Objects.equals(transactionIsolation,
-            ((ConnectionPropertiesImpl) o).transactionIsolation);
-  }
-
-  public Common.ConnectionProperties toProto() {
-    Common.ConnectionProperties.Builder builder = Common.ConnectionProperties.newBuilder();
-
-    if (null != autoCommit) {
-      builder.setHasAutoCommit(true);
-      builder.setAutoCommit(autoCommit.booleanValue());
-    } else {
-      // Be explicit to avoid default value confusion
-      builder.setHasAutoCommit(false);
-    }
-
-    if (null != catalog) {
-      builder.setCatalog(catalog);
-    }
-
-    builder.setIsDirty(isDirty);
-
-    if (null != readOnly) {
-      builder.setHasReadOnly(true);
-      builder.setReadOnly(readOnly.booleanValue());
-    } else {
-      // Be explicit to avoid default value confusion
-      builder.setHasReadOnly(false);
-    }
-
-    if (null != schema) {
-      builder.setSchema(schema);
-    }
-
-    if (null != transactionIsolation) {
-      builder.setTransactionIsolation(transactionIsolation.intValue());
-    }
-
-    return builder.build();
-  }
-
-  public static ConnectionPropertiesImpl fromProto(Common.ConnectionProperties proto) {
-    String catalog = null;
-    if (proto.hasField(CATALOG_DESCRIPTOR)) {
-      catalog = proto.getCatalog();
-    }
-
-    String schema = null;
-    if (proto.hasField(SCHEMA_DESCRIPTOR)) {
-      schema = proto.getSchema();
-    }
-
-    Boolean autoCommit = null;
-    if (proto.getHasAutoCommit()) {
-      autoCommit = Boolean.valueOf(proto.getAutoCommit());
-    }
-
-    Boolean readOnly = null;
-    if (proto.getHasReadOnly()) {
-      readOnly = Boolean.valueOf(proto.getReadOnly());
-    }
-
-    Integer transactionIsolation = null;
-    if (proto.hasField(TRANSACTION_ISOLATION_DESCRIPTOR)) {
-      transactionIsolation = Integer.valueOf(proto.getTransactionIsolation());
-    }
-
-    ConnectionPropertiesImpl impl = new ConnectionPropertiesImpl(autoCommit, readOnly,
-        transactionIsolation, catalog, schema);
-
-    impl.setDirty(proto.getIsDirty());
-
-    return impl;
-  }
-}
-
-// End ConnectionPropertiesImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
deleted file mode 100644
index d380d80..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionProperty.java
+++ /dev/null
@@ -1,69 +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.util.Properties;
-
-/**
- * Definition of a property that may be specified on the JDBC connect string.
- * {@link BuiltInConnectionProperty} enumerates built-in properties, but
- * there may be others; the list is not closed.
- */
-public interface ConnectionProperty {
-  /** The name of this property. (E.g. "MATERIALIZATIONS_ENABLED".) */
-  String name();
-
-  /** The name of this property in camel-case.
-   * (E.g. "materializationsEnabled".) */
-  String camelName();
-
-  /** Returns the default value of this property. The type must match its data
-   * type. */
-  Object defaultValue();
-
-  /** Returns the data type of this property. */
-  Type type();
-
-  /** Wraps this property with a properties object from which its value can be
-   * obtained when needed. */
-  ConnectionConfigImpl.PropEnv wrap(Properties properties);
-
-  /** Whether the property is mandatory. */
-  boolean required();
-
-  /** Data type of property. */
-  enum Type {
-    BOOLEAN,
-    STRING,
-    ENUM,
-    PLUGIN;
-
-    public boolean valid(Object defaultValue) {
-      switch (this) {
-      case BOOLEAN:
-        return defaultValue instanceof Boolean;
-      case STRING:
-      case PLUGIN:
-        return defaultValue instanceof String;
-      default:
-        return defaultValue instanceof Enum;
-      }
-    }
-  }
-}
-
-// End ConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/DriverVersion.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/DriverVersion.java b/avatica/src/main/java/org/apache/calcite/avatica/DriverVersion.java
deleted file mode 100644
index 15c966a..0000000
--- a/avatica/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/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/Handler.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Handler.java b/avatica/src/main/java/org/apache/calcite/avatica/Handler.java
deleted file mode 100644
index 831e66d..0000000
--- a/avatica/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/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/HandlerImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/HandlerImpl.java
deleted file mode 100644
index c2e6c1a..0000000
--- a/avatica/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/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/Helper.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Helper.java b/avatica/src/main/java/org/apache/calcite/avatica/Helper.java
deleted file mode 100644
index 27c6056..0000000
--- a/avatica/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


[53/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/stream.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/stream.md b/avatica/site/_docs/stream.md
deleted file mode 100644
index f66fbce..0000000
--- a/avatica/site/_docs/stream.md
+++ /dev/null
@@ -1,1023 +0,0 @@
----
-layout: docs
-title: Streaming
-permalink: /docs/stream.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Calcite has extended SQL and relational algebra in order to support
-streaming queries.
-
-* TOC
-{:toc}
-
-## Introduction
-
-Streams are collections to records that flow continuously, and forever.
-Unlike tables, they are not typically stored on disk, but flow over the
-network and are held for short periods of time in memory.
-
-Streams complement tables because they represent what is happening in the
-present and future of the enterprise whereas tables represent the past.
-It is very common for a stream to be archived into a table.
-
-Like tables, you often want to query streams in a high-level language
-based on relational algebra, validated according to a schema, and optimized
-to take advantage of available resources and algorithms.
-
-Calcite's SQL is an extension to standard SQL, not another 'SQL-like' language.
-The distinction is important, for several reasons:
-
-* Streaming SQL is easy to learn for anyone who knows regular SQL.
-* The semantics are clear, because we aim to produce the same results on a
-  stream as if the same data were in a table.
-* You can write queries that combine streams and tables (or the history of
-  a stream, which is basically an in-memory table).
-* Lots of existing tools can generate standard SQL.
-
-If you don't use the `STREAM` keyword, you are back in regular
-standard SQL.
-
-## An example schema
-
-Our streaming SQL examples use the following schema:
-
-* `Orders (rowtime, productId, orderId, units)` - a stream and a table
-* `Products (rowtime, productId, name)` - a table
-* `Shipments (rowtime, orderId)` - a stream
-
-## A simple query
-
-Let's start with the simplest streaming query:
-
-{% highlight sql %}
-SELECT STREAM *
-FROM Orders;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 10:17:00 |        30 |       5 |     4
- 10:17:05 |        10 |       6 |     1
- 10:18:05 |        20 |       7 |     2
- 10:18:07 |        30 |       8 |    20
- 11:02:00 |        10 |       9 |     6
- 11:04:00 |        10 |      10 |     1
- 11:09:30 |        40 |      11 |    12
- 11:24:11 |        10 |      12 |     4
-{% endhighlight %}
-
-This query reads all columns and rows from the `Orders` stream.
-Like any streaming query, it never terminates. It outputs a record whenever
-a record arrives in `Orders`.
-
-Type `Control-C` to terminate the query.
-
-The `STREAM` keyword is the main extension in streaming SQL. It tells the
-system that you are interested in incoming orders, not existing ones. The query
-
-{% highlight sql %}
-SELECT *
-FROM Orders;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 08:30:00 |        10 |       1 |     3
- 08:45:10 |        20 |       2 |     1
- 09:12:21 |        10 |       3 |    10
- 09:27:44 |        30 |       4 |     2
-
-4 records returned.
-{% endhighlight %}
-
-is also valid, but will print out all existing orders and then terminate. We
-call it a *relational* query, as opposed to *streaming*. It has traditional
-SQL semantics.
-
-`Orders` is special, in that it has both a stream and a table. If you try to run
-a streaming query on a table, or a relational query on a stream, Calcite gives
-an error:
-
-{% highlight sql %}
-SELECT * FROM Shipments;
-
-ERROR: Cannot convert stream 'SHIPMENTS' to a table
-
-SELECT STREAM * FROM Products;
-
-ERROR: Cannot convert table 'PRODUCTS' to a stream
-{% endhighlight %}
-
-# Filtering rows
-
-Just as in regular SQL, you use a `WHERE` clause to filter rows:
-
-{% highlight sql %}
-SELECT STREAM *
-FROM Orders
-WHERE units > 3;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 10:17:00 |        30 |       5 |     4
- 10:18:07 |        30 |       8 |    20
- 11:02:00 |        10 |       9 |     6
- 11:09:30 |        40 |      11 |    12
- 11:24:11 |        10 |      12 |     4
-{% endhighlight %}
-
-# Projecting expressions
-
-Use expressions in the `SELECT` clause to choose which columns to return or
-compute expressions:
-
-{% highlight sql %}
-SELECT STREAM rowtime,
-  'An order for ' || units || ' '
-    || CASE units WHEN 1 THEN 'unit' ELSE 'units' END
-    || ' of product #' || productId AS description
-FROM Orders;
-
-  rowtime | description
-----------+---------------------------------------
- 10:17:00 | An order for 4 units of product #30
- 10:17:05 | An order for 1 unit of product #10
- 10:18:05 | An order for 2 units of product #20
- 10:18:07 | An order for 20 units of product #30
- 11:02:00 | An order by 6 units of product #10
- 11:04:00 | An order by 1 unit of product #10
- 11:09:30 | An order for 12 units of product #40
- 11:24:11 | An order by 4 units of product #10
-{% endhighlight %}
-
-We recommend that you always include the `rowtime` column in the `SELECT`
-clause. Having a sorted timestamp in each stream and streaming query makes it
-possible to do advanced calculations later, such as `GROUP BY` and `JOIN`.
-
-# Tumbling windows
-
-There are several ways to compute aggregate functions on streams. The
-differences are:
-
-* How many rows come out for each row in?
-* Does each incoming value appear in one total, or more?
-* What defines the "window", the set of rows that contribute to a given output row?
-* Is the result a stream or a relation?
-
-There are various window types:
-
-* tumbling window (GROUP BY)
-* hopping window (multi GROUP BY)
-* sliding window (window functions)
-* cascading window (window functions)
-
-and the following diagram shows the kinds of query in which to use them:
-
-![Window types]({{ site.baseurl }}/img/window-types.png)
-
-First we'll look a *tumbling window*, which is defined by a streaming
-`GROUP BY`. Here is an example:
-
-{% highlight sql %}
-SELECT STREAM CEIL(rowtime TO HOUR) AS rowtime,
-  productId,
-  COUNT(*) AS c,
-  SUM(units) AS units
-FROM Orders
-GROUP BY CEIL(rowtime TO HOUR), productId;
-
-  rowtime | productId |       c | units
-----------+-----------+---------+-------
- 11:00:00 |        30 |       2 |    24
- 11:00:00 |        10 |       1 |     1
- 11:00:00 |        20 |       1 |     7
- 12:00:00 |        10 |       3 |    11
- 12:00:00 |        40 |       1 |    12
-{% endhighlight %}
-
-The result is a stream. At 11 o'clock, Calcite emits a sub-total for every
-`productId` that had an order since 10 o'clock, timestamped 11 o'clock.
-At 12 o'clock, it will emit
-the orders that occurred between 11:00 and 12:00. Each input row contributes to
-only one output row.
-
-How did Calcite know that the 10:00:00 sub-totals were complete at 11:00:00,
-so that it could emit them? It knows that `rowtime` is increasing, and it knows
-that `CEIL(rowtime TO HOUR)` is also increasing. So, once it has seen a row
-at or after 11:00:00, it will never see a row that will contribute to a 10:00:00
-total.
-
-A column or expression that is increasing or decreasing is said to be
-*monotonic*.
-
-If column or expression has values that are slightly out of order,
-and the stream has a mechanism (such as punctuation or watermarks)
-to declare that a particular value will never be seen again, then
-the column or expression is said to be *quasi-monotonic*.
-
-Without a monotonic or quasi-monotonic expression in the `GROUP BY` clause,
-Calcite is
-not able to make progress, and it will not allow the query:
-
-{% highlight sql %}
-SELECT STREAM productId,
-  COUNT(*) AS c,
-  SUM(units) AS units
-FROM Orders
-GROUP BY productId;
-
-ERROR: Streaming aggregation requires at least one monotonic expression in GROUP BY clause
-{% endhighlight %}
-
-Monotonic and quasi-monotonic columns need to be declared in the schema.
-The monotonicity is
-enforced when records enter the stream and assumed by queries that read from
-that stream. We recommend that you give each stream a timestamp column called
-`rowtime`, but you can declare others to be monotonic, `orderId`, for example.
-
-We discuss punctuation, watermarks, and other ways of making progress
-<a href="#punctuation">below</a>.
-
-# Tumbling windows, improved
-
-The previous example of tumbling windows was easy to write because the window
-was one hour. For intervals that are not a whole time unit, say 2 hours or
-2 hours and 17 minutes, you cannot use `CEIL`, and the expression gets more
-complicated.
-
-Calcite supports an alternative syntax for tumbling windows:
-
-{% highlight sql %}
-SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
-  productId,
-  COUNT(*) AS c,
-  SUM(units) AS units
-FROM Orders
-GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;
-
-  rowtime | productId |       c | units
-----------+-----------+---------+-------
- 11:00:00 |        30 |       2 |    24
- 11:00:00 |        10 |       1 |     1
- 11:00:00 |        20 |       1 |     7
- 12:00:00 |        10 |       3 |    11
- 12:00:00 |        40 |       1 |    12
-{% endhighlight %}
-
-As you can see, it returns the same results as the previous query. The `TUMBLE`
-function returns a grouping key that is the same for all the rows that will end
-up in a given summary row; the `TUMBLE_END` function takes the same arguments
-and returns the time at which that window ends;
-there is also a `TUMBLE_START` function.
-
-`TUMBLE` has an optional parameter to align the window.
-In the following example,
-we use a 30 minute interval and 0:12 as the alignment time,
-so the query emits summaries at 12 and 42 minutes past each hour:
-
-{% highlight sql %}
-SELECT STREAM
-  TUMBLE_END(rowtime, INTERVAL '30' MINUTE, TIME '0:12') AS rowtime,
-  productId,
-  COUNT(*) AS c,
-  SUM(units) AS units
-FROM Orders
-GROUP BY TUMBLE(rowtime, INTERVAL '30' MINUTE, TIME '0:12'),
-  productId;
-
-  rowtime | productId |       c | units
-----------+-----------+---------+-------
- 10:42:00 |        30 |       2 |    24
- 10:42:00 |        10 |       1 |     1
- 10:42:00 |        20 |       1 |     7
- 11:12:00 |        10 |       2 |     7
- 11:12:00 |        40 |       1 |    12
- 11:42:00 |        10 |       1 |     4
-{% endhighlight %}
-
-# Hopping windows
-
-Hopping windows are a generalization of tumbling windows that allow data to
-be kept in a window for a longer than the emit interval.
-
-For example, the following query emits a row timestamped 11:00 containing data
-from 08:00 to 11:00 (or 10:59.9 if we're being pedantic),
-and a row timestamped 12:00 containing data from 09:00
-to 12:00.
-
-{% highlight sql %}
-SELECT STREAM
-  HOP_END(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR) AS rowtime,
-  COUNT(*) AS c,
-  SUM(units) AS units
-FROM Orders
-GROUP BY HOP(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR);
-
-  rowtime |        c | units
-----------+----------+-------
- 11:00:00 |        4 |    27
- 12:00:00 |        8 |    50
-{% endhighlight %}
-
-In this query, because the retain period is 3 times the emit period, every input
-row contributes to exactly 3 output rows. Imagine that the `HOP` function
-generates a collection of group keys for incoming row, and places its values
-in the accumulators of each of those group keys. For example,
-`HOP(10:18:00, INTERVAL '1' HOUR, INTERVAL '3')` generates 3 periods
-
-```[08:00, 09:00)
-[09:00, 10:00)
-[10:00, 11:00)
-```
-
-This raises the possibility of allowing user-defined partitioning functions
-for users who are not happy with the built-in functions `HOP` and `TUMBLE`.
-
-We can build complex complex expressions such as an exponentially decaying
-moving average:
-
-{% highlight sql %}
-SELECT STREAM HOP_END(rowtime),
-  productId,
-  SUM(unitPrice * EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))
-   / SUM(EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))
-FROM Orders
-GROUP BY HOP(rowtime, INTERVAL '1' SECOND, INTERVAL '1' HOUR),
-  productId
-{% endhighlight %}
-
-Emits:
-
-* a row at `11:00:00` containing rows in `[10:00:00, 11:00:00)`;
-* a row at `11:00:01` containing rows in `[10:00:01, 11:00:01)`.
-
-The expression weighs recent orders more heavily than older orders.
-Extending the window from 1 hour to 2 hours or 1 year would have
-virtually no effect on the accuracy of the result (but use more memory
-and compute).
-
-Note that we use `HOP_START` inside an aggregate function (`SUM`) because it
-is a value that is constant for all rows within a sub-total. This
-would not be allowed for typical aggregate functions (`SUM`, `COUNT`
-etc.).
-
-If you are familiar with `GROUPING SETS`, you may notice that partitioning
-functions can be seen as a generalization of `GROUPING SETS`, in that they
-allow an input row to contribute to multiple sub-totals.
-The auxiliary functions for `GROUPING SETS`,
-such as `GROUPING()` and `GROUP_ID`,
-can be used inside aggregate functions, so it is not surprising that
-`HOP_START` and `HOP_END` can be used in the same way.
-
-# GROUPING SETS
-
-`GROUPING SETS` is valid for a streaming query provided that every
-grouping set contains a monotonic or quasi-monotonic expression.
-
-`CUBE` and `ROLLUP` are not valid for streaming query, because they will
-produce at least one grouping set that aggregates everything (like
-`GROUP BY ()`).
-
-# Filtering after aggregation
-
-As in standard SQL, you can apply a `HAVING` clause to filter rows emitted by
-a streaming `GROUP BY`:
-
-{% highlight sql %}
-SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
-  productId
-FROM Orders
-GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId
-HAVING COUNT(*) > 2 OR SUM(units) > 10;
-
-  rowtime | productId
-----------+-----------
- 10:00:00 |        30
- 11:00:00 |        10
- 11:00:00 |        40
-{% endhighlight %}
-
-# Sub-queries, views and SQL's closure property
-
-The previous `HAVING` query can be expressed using a `WHERE` clause on a
-sub-query:
-
-{% highlight sql %}
-SELECT STREAM rowtime, productId
-FROM (
-  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
-    productId,
-    COUNT(*) AS c,
-    SUM(units) AS su
-  FROM Orders
-  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId)
-WHERE c > 2 OR su > 10;
-
-  rowtime | productId
-----------+-----------
- 10:00:00 |        30
- 11:00:00 |        10
- 11:00:00 |        40
-{% endhighlight %}
-
-`HAVING` was introduced in the early days of SQL, when a way was needed to
-perform a filter *after* aggregation. (Recall that `WHERE` filters rows before
-they enter the `GROUP BY` clause.)
-
-Since then, SQL has become a mathematically closed language, which means that
-any operation you can perform on a table can also perform on a query.
-
-The *closure property* of SQL is extremely powerful. Not only does it render
-`HAVING` obsolete (or, at least, reduce it to syntactic sugar), it makes views
-possible:
-
-{% highlight sql %}
-CREATE VIEW HourlyOrderTotals (rowtime, productId, c, su) AS
-  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR),
-    productId,
-    COUNT(*),
-    SUM(units)
-  FROM Orders
-  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;
-
-SELECT STREAM rowtime, productId
-FROM HourlyOrderTotals
-WHERE c > 2 OR su > 10;
-
-  rowtime | productId
-----------+-----------
- 10:00:00 |        30
- 11:00:00 |        10
- 11:00:00 |        40
-{% endhighlight %}
-
-Sub-queries in the `FROM` clause are sometimes referred to as "inline views",
-but really, they are more fundamental than views. Views are just a convenient
-way to carve your SQL into manageable chunks by giving the pieces names and
-storing them in the metadata repository.
-
-Many people find that nested queries and views are even more useful on streams
-than they are on relations. Streaming queries are pipelines of
-operators all running continuously, and often those pipelines get quite long.
-Nested queries and views help to express and manage those pipelines.
-
-And, by the way, a `WITH` clause can accomplish the same as a sub-query or
-a view:
-
-{% highlight sql %}
-WITH HourlyOrderTotals (rowtime, productId, c, su) AS (
-  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR),
-    productId,
-    COUNT(*),
-    SUM(units)
-  FROM Orders
-  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId)
-SELECT STREAM rowtime, productId
-FROM HourlyOrderTotals
-WHERE c > 2 OR su > 10;
-
-  rowtime | productId
-----------+-----------
- 10:00:00 |        30
- 11:00:00 |        10
- 11:00:00 |        40
-{% endhighlight %}
-
-# Converting between streams and relations
-
-Look back at the definition of the `HourlyOrderTotals` view.
-Is the view a stream or a relation?
-
-It does not contain the `STREAM` keyword, so it is a relation.
-However, it is a relation that can be converted into a stream.
-
-You can use it in both relational and streaming queries:
-
-{% highlight sql %}
-# A relation; will query the historic Orders table.
-# Returns the largest number of product #10 ever sold in one hour.
-SELECT max(su)
-FROM HourlyOrderTotals
-WHERE productId = 10;
-
-# A stream; will query the Orders stream.
-# Returns every hour in which at least one product #10 was sold.
-SELECT STREAM rowtime
-FROM HourlyOrderTotals
-WHERE productId = 10;
-{% endhighlight %}
-
-This approach is not limited to views and sub-queries.
-Following the approach set out in CQL [<a href="#ref1">1</a>], every query
-in streaming SQL is defined as a relational query and converted to a stream
-using the `STREAM` keyword in the top-most `SELECT`.
-
-If the `STREAM` keyword is present in sub-queries or view definitions, it has no
-effect.
-
-At query preparation time, Calcite figures out whether the relations referenced
-in the query can be converted to streams or historical relations.
-
-Sometimes a stream makes available some of its history (say the last 24 hours of
-data in an Apache Kafka [<a href="#ref2">2</a>] topic)
-but not all. At run time, Calcite figures out whether there is sufficient
-history to run the query, and if not, gives an error.
-
-# The "pie chart" problem: Relational queries on streams
-
-One particular case where you need to convert a stream to a relation
-occurs in what I call the "pie chart problem". Imagine that you need to
-write a web page with a chart, like the following, that summarizes the
-number of orders for each product over the last hour.
-
-![Pie chart]({{ site.baseurl }}/img/pie-chart.png)
-
-But the `Orders` stream only contains a few records, not an hour's summary.
-We need to run a relational query on the history of the stream:
-
-{% highlight sql %}
-SELECT productId, count(*)
-FROM Orders
-WHERE rowtime BETWEEN current_timestamp - INTERVAL '1' HOUR
-              AND current_timestamp;
-{% endhighlight %}
-
-If the history of the `Orders` stream is being spooled to the `Orders` table,
-we can answer the query, albeit at a high cost. Better, if we can tell the
-system to materialize one hour summary into a table,
-maintain it continuously as the stream flows,
-and automatically rewrite queries to use the table.
-
-# Sorting
-
-The story for `ORDER BY` is similar to `GROUP BY`.
-The syntax looks like regular SQL, but Calcite must be sure that it can deliver
-timely results. It therefore requires a monotonic expression on the leading edge
-of your `ORDER BY` key.
-
-{% highlight sql %}
-SELECT STREAM CEIL(rowtime TO hour) AS rowtime, productId, orderId, units
-FROM Orders
-ORDER BY CEIL(rowtime TO hour) ASC, units DESC;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 10:00:00 |        30 |       8 |    20
- 10:00:00 |        30 |       5 |     4
- 10:00:00 |        20 |       7 |     2
- 10:00:00 |        10 |       6 |     1
- 11:00:00 |        40 |      11 |    12
- 11:00:00 |        10 |       9 |     6
- 11:00:00 |        10 |      12 |     4
- 11:00:00 |        10 |      10 |     1
-{% endhighlight %}
-
-Most queries will return results in the order that they were inserted,
-because the engine is using streaming algorithms, but you should not rely on it.
-For example, consider this:
-
-{% highlight sql %}
-SELECT STREAM *
-FROM Orders
-WHERE productId = 10
-UNION ALL
-SELECT STREAM *
-FROM Orders
-WHERE productId = 30;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 10:17:05 |        10 |       6 |     1
- 10:17:00 |        30 |       5 |     4
- 10:18:07 |        30 |       8 |    20
- 11:02:00 |        10 |       9 |     6
- 11:04:00 |        10 |      10 |     1
- 11:24:11 |        10 |      12 |     4
-{% endhighlight %}
-
-The rows with `productId` = 30 are apparently out of order, probably because
-the `Orders` stream was partitioned on `productId` and the partitioned streams
-sent their data at different times.
-
-If you require a particular ordering, add an explicit `ORDER BY`:
-
-{% highlight sql %}
-SELECT STREAM *
-FROM Orders
-WHERE productId = 10
-UNION ALL
-SELECT STREAM *
-FROM Orders
-WHERE productId = 30
-ORDER BY rowtime;
-
-  rowtime | productId | orderId | units
-----------+-----------+---------+-------
- 10:17:00 |        30 |       5 |     4
- 10:17:05 |        10 |       6 |     1
- 10:18:07 |        30 |       8 |    20
- 11:02:00 |        10 |       9 |     6
- 11:04:00 |        10 |      10 |     1
- 11:24:11 |        10 |      12 |     4
-{% endhighlight %}
-
-Calcite will probably implement the `UNION ALL` by merging using `rowtime`,
-which is only slightly less efficient.
-
-You only need to add an `ORDER BY` to the outermost query. If you need to,
-say, perform `GROUP BY` after a `UNION ALL`, Calcite will add an `ORDER BY`
-implicitly, in order to make the GROUP BY algorithm possible.
-
-# Table constructor
-
-The `VALUES` clause creates an inline table with a given set of rows.
-
-Streaming is disallowed. The set of rows never changes, and therefore a stream
-would never return any rows.
-
-{% highlight sql %}
-> SELECT STREAM * FROM (VALUES (1, 'abc'));
-
-ERROR: Cannot stream VALUES
-{% endhighlight %}
-
-# Sliding windows
-
-Standard SQL features so-called "analytic functions" that can be used in the
-`SELECT` clause. Unlike `GROUP BY`, these do not collapse records. For each
-record that goes in, one record comes out. But the aggregate function is based
-on a window of many rows.
-
-Let's look at an example.
-
-{% highlight sql %}
-SELECT STREAM rowtime,
-  productId,
-  units,
-  SUM(units) OVER (ORDER BY rowtime RANGE INTERVAL '1' HOUR PRECEDING) unitsLastHour
-FROM Orders;
-{% endhighlight %}
-
-The feature packs a lot of power with little effort. You can have multiple
-functions in the `SELECT` clause, based on multiple window specifications.
-
-The following example returns orders whose average order size over the last
-10 minutes is greater than the average order size for the last week.
-
-{% highlight sql %}
-SELECT STREAM *
-FROM (
-  SELECT STREAM rowtime,
-    productId,
-    units,
-    AVG(units) OVER product (RANGE INTERVAL '10' MINUTE PRECEDING) AS m10,
-    AVG(units) OVER product (RANGE INTERVAL '7' DAY PRECEDING) AS d7
-  FROM Orders
-  WINDOW product AS (
-    ORDER BY rowtime
-    PARTITION BY productId))
-WHERE m10 > d7;
-{% endhighlight %}
-
-For conciseness, here we use a syntax where you partially define a window
-using a `WINDOW` clause and then refine the window in each `OVER` clause.
-You could also define all windows in the `WINDOW` clause, or all windows inline,
-if you wish.
-
-But the real power goes beyond syntax. Behind the scenes, this query is
-maintaining two tables, and adding and removing values from sub-totals using
-with FIFO queues. But you can access those tables without introducing a join
-into the query.
-
-Some other features of the windowed aggregation syntax:
-
-* You can define windows based on row count.
-* The window can reference rows that have not yet arrived.
-  (The stream will wait until they have arrived).
-* You can compute order-dependent functions such as `RANK` and median.
-
-# Cascading windows
-
-What if we want a query that returns a result for every record, like a
-sliding window, but resets totals on a fixed time period, like a
-tumbling window? Such a pattern is called a *cascading window*. Here
-is an example:
-
-{% highlight sql %}
-SELECT STREAM rowtime,
-  productId,
-  units,
-  SUM(units) OVER (PARTITION BY FLOOR(rowtime TO HOUR)) AS unitsSinceTopOfHour
-FROM Orders;
-{% endhighlight %}
-
-It looks similar to a sliding window query, but the monotonic
-expression occurs within the `PARTITION BY` clause of the window. As
-the rowtime moves from from 10:59:59 to 11:00:00,
-`FLOOR(rowtime TO HOUR)` changes from 10:00:00 to 11:00:00,
-and therefore a new partition starts.
-The first row to arrive in the new hour will start a
-new total; the second row will have a total that consists of two rows,
-and so on.
-
-Calcite knows that the old partition will never be used again, so
-removes all sub-totals for that partition from its internal storage.
-
-Analytic functions that using cascading and sliding windows can be
-combined in the same query.
-
-# Joining streams to tables
-
-There are two kinds of join where streams are concerned: stream-to-table
-join and stream-to-stream join.
-
-A stream-to-table join is straightforward if the contents of the table
-are not changing. This query enriches a stream of orders with
-each product's list price:
-
-{% highlight sql %}
-SELECT STREAM o.rowtime, o.productId, o.orderId, o.units,
-  p.name, p.unitPrice
-FROM Orders AS o
-JOIN Products AS p
-  ON o.productId = p.productId;
-
-  rowtime | productId | orderId | units | name   | unitPrice
-----------+-----------+---------+-------+ -------+-----------
- 10:17:00 |        30 |       5 |     4 | Cheese |        17
- 10:17:05 |        10 |       6 |     1 | Beer   |      0.25
- 10:18:05 |        20 |       7 |     2 | Wine   |         6
- 10:18:07 |        30 |       8 |    20 | Cheese |        17
- 11:02:00 |        10 |       9 |     6 | Beer   |      0.25
- 11:04:00 |        10 |      10 |     1 | Beer   |      0.25
- 11:09:30 |        40 |      11 |    12 | Bread  |       100
- 11:24:11 |        10 |      12 |     4 | Beer   |      0.25
-{% endhighlight %}
-
-What should happen if the table is changing? For example,
-suppose the unit price of product 10 is increased to 0.35 at 11:00.
-Orders placed before 11:00 should have the old price, and orders
-placed after 11:00 should reflect the new price.
-
-One way to implement this is to have a table that keeps every version
-with a start and end effective date, `ProductVersions` in the following
-example:
-
-{% highlight sql %}
-SELECT STREAM *
-FROM Orders AS o
-JOIN ProductVersions AS p
-  ON o.productId = p.productId
-  AND o.rowtime BETWEEN p.startDate AND p.endDate
-
-  rowtime | productId | orderId | units | productId1 |   name | unitPrice
-----------+-----------+---------+-------+ -----------+--------+-----------
- 10:17:00 |        30 |       5 |     4 |         30 | Cheese |        17
- 10:17:05 |        10 |       6 |     1 |         10 | Beer   |      0.25
- 10:18:05 |        20 |       7 |     2 |         20 | Wine   |         6
- 10:18:07 |        30 |       8 |    20 |         30 | Cheese |        17
- 11:02:00 |        10 |       9 |     6 |         10 | Beer   |      0.35
- 11:04:00 |        10 |      10 |     1 |         10 | Beer   |      0.35
- 11:09:30 |        40 |      11 |    12 |         40 | Bread  |       100
- 11:24:11 |        10 |      12 |     4 |         10 | Beer   |      0.35
-{% endhighlight %}
-
-The other way to implement this is to use a database with temporal support
-(the ability to find the contents of the database as it was at any moment
-in the past), and the system needs to know that the `rowtime` column of
-the `Orders` stream corresponds to the transaction timestamp of the
-`Products` table.
-
-For many applications, it is not worth the cost and effort of temporal
-support or a versioned table. It is acceptable to the application that
-the query gives different results when replayed: in this example, on replay,
-all orders of product 10 are assigned the later unit price, 0.35.
-
-# Joining streams to streams
-
-It makes sense to join two streams if the join condition somehow forces
-them to remain a finite distance from one another. In the following query,
-the ship date is within one hour of the order date:
-
-{% highlight sql %}
-SELECT STREAM o.rowtime, o.productId, o.orderId, s.rowtime AS shipTime
-FROM Orders AS o
-JOIN Shipments AS s
-  ON o.orderId = p.orderId
-  AND s.rowtime BETWEEN o.rowtime AND o.rowtime + INTERVAL '1' HOUR;
-
-  rowtime | productId | orderId | shipTime
-----------+-----------+---------+----------
- 10:17:00 |        30 |       5 | 10:55:00
- 10:17:05 |        10 |       6 | 10:20:00
- 11:02:00 |        10 |       9 | 11:58:00
- 11:24:11 |        10 |      12 | 11:44:00
-{% endhighlight %}
-
-Note that quite a few orders do not appear, because they did not ship
-within an hour. By the time the system receives order 10, timestamped 11:24:11,
-it has already removed orders up to and including order 8, timestamped 10:18:07,
-from its hash table.
-
-As you can see, the "lock step", tying together monotonic or quasi-monotonic
-columns of the two streams, is necessary for the system to make progress.
-It will refuse to execute a query if it cannot deduce a lock step.
-
-# DML
-
-It's not only queries that make sense against streams;
-it also makes sense to run DML statements (`INSERT`, `UPDATE`, `DELETE`,
-and also their rarer cousins `UPSERT` and `REPLACE`) against streams.
-
-DML is useful because it allows you do materialize streams
-or tables based on streams,
-and therefore save effort when values are used often.
-
-Consider how streaming applications often consist of pipelines of queries,
-each query transforming input stream(s) to output stream(s).
-The component of a pipeline can be a view:
-
-{% highlight sql %}
-CREATE VIEW LargeOrders AS
-SELECT STREAM * FROM Orders WHERE units > 1000;
-{% endhighlight %}
-
-or a standing `INSERT` statement:
-
-{% highlight sql %}
-INSERT INTO LargeOrders
-SELECT STREAM * FROM Orders WHERE units > 1000;
-{% endhighlight %}
-
-These look similar, and in both cases the next step(s) in the pipeline
-can read from `LargeOrders` without worrying how it was populated.
-There is a difference in efficiency: the `INSERT` statement does the 
-same work no matter how many consumers there are; the view does work
-proportional to the number of consumers, and in particular, does no 
-work if there are no consumers.
-
-Other forms of DML make sense for streams. For example, the following
-standing `UPSERT` statement maintains a table that materializes a summary
-of the last hour of orders:
-
-{% highlight sql %}
-UPSERT INTO OrdersSummary
-SELECT STREAM productId,
-  COUNT(*) OVER lastHour AS c
-FROM Orders
-WINDOW lastHour AS (
-  PARTITION BY productId
-  ORDER BY rowtime
-  RANGE INTERVAL '1' HOUR PRECEDING)
-{% endhighlight %}
-
-# Punctuation
-
-Punctuation[<a href="#ref5">5</a>] allows a stream query to make progress
-even if there are not enough values in a monotonic key to push the results out.
-
-(I prefer the term "rowtime bounds",
-and watermarks[<a href="#ref6">6</a>] are a related concept,
-but for these purposes, punctuation will suffice.)
-
-If a stream has punctuation enabled then it may not be sorted but is
-nevertheless sortable. So, for the purposes of semantics, it is sufficient
-to work in terms of sorted streams.
-
-By the way, an out-of-order stream is also sortable if it is *t-sorted*
-(i.e. every record is guaranteed to arrive within *t* seconds of its
-timestamp) or *k-sorted* (i.e. every record is guaranteed to be no more
-than *k* positions out of order). So queries on these streams can be
-planned similarly to queries on streams with punctuation.
-
-And, we often want to aggregate over attributes that are not
-time-based but are nevertheless monotonic. "The number of times a team
-has shifted between winning-state and losing-state" is one such
-monotonic attribute. The system needs to figure out for itself that it
-is safe to aggregate over such an attribute; punctuation does not add
-any extra information.
-
-I have in mind some metadata (cost metrics) for the planner:
-
-1. Is this stream sorted on a given attribute (or attributes)?
-2. Is it possible to sort the stream on a given attribute? (For finite
-   relations, the answer is always "yes"; for streams it depends on the
-   existence of punctuation, or linkage between the attributes and the
-   sort key.)
-3. What latency do we need to introduce in order to perform that sort?
-4. What is the cost (in CPU, memory etc.) of performing that sort?
-
-We already have (1), in [BuiltInMetadata.Collation]({{ site.apiRoot }}/org/apache/calcite/rel/metadata/BuiltInMetadata.Collation.html).
-For (2), the answer is always "true" for finite relations.
-But we'll need to implement (2), (3) and (4) for streams.
-
-# State of the stream
-
-Not all concepts in this article have been implemented in Calcite.
-And others may be implemented in Calcite but not in a particular adapter
-such as SamzaSQL [<a href="#ref3">3</a>] [<a href="#ref4">4</a>].
-
-## Implemented
-
-* Streaming `SELECT`, `WHERE`, `GROUP BY`, `HAVING`, `UNION ALL`, `ORDER BY`
-* `FLOOR` and `CEIL` functions
-* Monotonicity
-* Streaming `VALUES` is disallowed
-
-## Not implemented
-
-The following features are presented in this document as if Calcite
-supports them, but in fact it does not (yet). Full support means
-that the reference implementation supports the feature (including
-negative cases) and the TCK tests it.
-
-* Stream-to-stream `JOIN`
-* Stream-to-table `JOIN`
-* Stream on view
-* Streaming `UNION ALL` with `ORDER BY` (merge)
-* Relational query on stream
-* Streaming windowed aggregation (sliding and cascading windows)
-* Check that `STREAM` in sub-queries and views is ignored
-* Check that streaming `ORDER BY` cannot have `OFFSET` or `LIMIT`
-* Limited history; at run time, check that there is sufficient history
-  to run the query.
-* [Quasi-monotonicity](https://issues.apache.org/jira/browse/CALCITE-1096)
-* `HOP` and `TUMBLE` (and auxiliary `HOP_START`, `HOP_END`,
-  `TUMBLE_START`, `TUMBLE_END`) functions
-
-## To do in this document
-
-* Re-visit whether you can stream `VALUES`
-* `OVER` clause to define window on stream
-* Consider whether to allow `CUBE` and `ROLLUP` in streaming queries,
-  with an understanding that some levels of aggregation will never complete
-  (because they have no monotonic expressions) and thus will never be emitted.
-* Fix the `UPSERT` example to remove records for products that have not
-  occurred in the last hour.
-* DML that outputs to multiple streams; perhaps an extension to the standard
-  `REPLACE` statement. 
-
-# Functions
-
-The following functions are not present in standard SQL
-but are defined in streaming SQL.
-
-Scalar functions:
-
-* `FLOOR(dateTime TO intervalType)` rounds a date, time or timestamp value
-  down to a given interval type
-* `CEIL(dateTime TO intervalType)` rounds a date, time or timestamp value
-  up to a given interval type
-
-Partitioning functions:
-
-* `HOP(t, emit, retain)` returns a collection of group keys for a row
-  to be part of a hopping window
-* `HOP(t, emit, retain, align)` returns a collection of group keys for a row
-  to be part of a hopping window with a given alignment
-* `TUMBLE(t, emit)` returns a group key for a row
-  to be part of a tumbling window
-* `TUMBLE(t, emit, align)` returns a group key for a row
-  to be part of a tumbling window with a given alignment
-
-`TUMBLE(t, e)` is equivalent to `TUMBLE(t, e, TIME '00:00:00')`.
-
-`TUMBLE(t, e, a)` is equivalent to `HOP(t, e, e, a)`.
-
-`HOP(t, e, r)` is equivalent to `HOP(t, e, r, TIME '00:00:00')`.
-
-# References
-
-* [<a name="ref1">1</a>]
-  <a href="http://ilpubs.stanford.edu:8090/758/">Arvind Arasu, Shivnath Babu,
-  and Jennifer Widom (2003) The CQL Continuous Query
-  Language: Semantic Foundations and Query Execution</a>.
-* [<a name="ref2">2</a>]
-  <a href="http://kafka.apache.org/documentation.html">Apache Kafka</a>.
-* [<a name="ref3">3</a>] <a href="http://samza.apache.org">Apache Samza</a>.
-* [<a name="ref4">4</a>] <a href="https://github.com/milinda/samza-sql">SamzaSQL</a>.
-* [<a name="ref5">5</a>]
-  <a href="http://www.whitworth.edu/academic/department/mathcomputerscience/faculty/tuckerpeter/pdf/117896_final.pdf">Peter
-  A. Tucker, David Maier, Tim Sheard, and Leonidas Fegaras (2003) Exploiting
-  Punctuation Semantics in Continuous Data Streams</a>.
-* [<a name="ref6">6</a>]
-  <a href="http://research.google.com/pubs/pub41378.html">Tyler Akidau,
-  Alex Balikov, Kaya Bekiroglu, Slava Chernyak, Josh Haberman, Reuven Lax,
-  Sam McVeety, Daniel Mills, Paul Nordstrom, and Sam Whittle (2013)
-  MillWheel: Fault-Tolerant Stream Processing at Internet Scale</a>.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/tutorial.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/tutorial.md b/avatica/site/_docs/tutorial.md
deleted file mode 100644
index 73f8f8f..0000000
--- a/avatica/site/_docs/tutorial.md
+++ /dev/null
@@ -1,760 +0,0 @@
----
-layout: docs
-title: Tutorial
-permalink: /docs/tutorial.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-This is a step-by-step tutorial that shows how to build and connect to
-Calcite. It uses a simple adapter that makes a directory of CSV files
-appear to be a schema containing tables. Calcite does the rest, and
-provides a full SQL interface.
-
-Calcite-example-CSV is a fully functional adapter for
-Calcite that reads
-text files in
-<a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV
-(comma-separated values)</a> format. It is remarkable that a couple of
-hundred lines of Java code are sufficient to provide full SQL query
-capability.
-
-CSV also serves as a template for building adapters to other
-data formats. Even though there are not many lines of code, it covers
-several important concepts:
-
-* user-defined schema using SchemaFactory and Schema interfaces;
-* declaring schemas in a model JSON file;
-* declaring views in a model JSON file;
-* user-defined table using the Table interface;
-* determining the record type of a table;
-* a simple implementation of Table, using the ScannableTable interface, that
-  enumerates all rows directly;
-* a more advanced implementation that implements FilterableTable, and can
-  filter out rows according to simple predicates;
-* advanced implementation of Table, using TranslatableTable, that translates
-  to relational operators using planner rules.
-
-## Download and build
-
-You need Java (1.7 or higher; 1.8 preferred), git and maven (3.2.1 or later).
-
-{% highlight bash %}
-$ git clone https://github.com/apache/calcite.git
-$ cd calcite
-$ mvn install -DskipTests -Dcheckstyle.skip=true
-$ cd example/csv
-{% endhighlight %}
-
-## First queries
-
-Now let's connect to Calcite using
-<a href="https://github.com/julianhyde/sqlline">sqlline</a>, a SQL shell
-that is included in this project.
-
-{% highlight bash %}
-$ ./sqlline
-sqlline> !connect jdbc:calcite:model=target/test-classes/model.json admin admin
-{% endhighlight %}
-
-(If you are running Windows, the command is `sqlline.bat`.)
-
-Execute a metadata query:
-
-{% highlight bash %}
-sqlline> !tables
-+------------+--------------+-------------+---------------+----------+------+
-| TABLE_CAT  | TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | REMARKS  | TYPE |
-+------------+--------------+-------------+---------------+----------+------+
-| null       | SALES        | DEPTS       | TABLE         | null     | null |
-| null       | SALES        | EMPS        | TABLE         | null     | null |
-| null       | SALES        | HOBBIES     | TABLE         | null     | null |
-| null       | metadata     | COLUMNS     | SYSTEM_TABLE  | null     | null |
-| null       | metadata     | TABLES      | SYSTEM_TABLE  | null     | null |
-+------------+--------------+-------------+---------------+----------+------+
-{% endhighlight %}
-
-(JDBC experts, note: sqlline's <code>!tables</code> command is just executing
-<a href="http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><code>DatabaseMetaData.getTables()</code></a>
-behind the scenes.
-It has other commands to query JDBC metadata, such as <code>!columns</code> and <code>!describe</code>.)
-
-As you can see there are 5 tables in the system: tables
-<code>EMPS</code>, <code>DEPTS</code> and <code>HOBBIES</code> in the current
-<code>SALES</code> schema, and <code>COLUMNS</code> and
-<code>TABLES</code> in the system <code>metadata</code> schema. The
-system tables are always present in Calcite, but the other tables are
-provided by the specific implementation of the schema; in this case,
-the <code>EMPS</code> and <code>DEPTS</code> tables are based on the
-<code>EMPS.csv</code> and <code>DEPTS.csv</code> files in the
-<code>target/test-classes</code> directory.
-
-Let's execute some queries on those tables, to show that Calcite is providing
-a full implementation of SQL. First, a table scan:
-
-{% highlight bash %}
-sqlline> SELECT * FROM emps;
-+--------+--------+---------+---------+----------------+--------+-------+---+
-| EMPNO  |  NAME  | DEPTNO  | GENDER  |      CITY      | EMPID  |  AGE  | S |
-+--------+--------+---------+---------+----------------+--------+-------+---+
-| 100    | Fred   | 10      |         |                | 30     | 25    | t |
-| 110    | Eric   | 20      | M       | San Francisco  | 3      | 80    | n |
-| 110    | John   | 40      | M       | Vancouver      | 2      | null  | f |
-| 120    | Wilma  | 20      | F       |                | 1      | 5     | n |
-| 130    | Alice  | 40      | F       | Vancouver      | 2      | null  | f |
-+--------+--------+---------+---------+----------------+--------+-------+---+
-{% endhighlight %}
-
-Now JOIN and GROUP BY:
-
-{% highlight bash %}
-sqlline> SELECT d.name, COUNT(*)
-. . . .> FROM emps AS e JOIN depts AS d ON e.deptno = d.deptno
-. . . .> GROUP BY d.name;
-+------------+---------+
-|    NAME    | EXPR$1  |
-+------------+---------+
-| Sales      | 1       |
-| Marketing  | 2       |
-+------------+---------+
-{% endhighlight %}
-
-Last, the VALUES operator generates a single row, and is a convenient
-way to test expressions and SQL built-in functions:
-
-{% highlight bash %}
-sqlline> VALUES CHAR_LENGTH('Hello, ' || 'world!');
-+---------+
-| EXPR$0  |
-+---------+
-| 13      |
-+---------+
-{% endhighlight %}
-
-Calcite has many other SQL features. We don't have time to cover them
-here. Write some more queries to experiment.
-
-## Schema discovery
-
-Now, how did Calcite find these tables? Remember, core Calcite does not
-know anything about CSV files. (As a "database without a storage
-layer", Calcite doesn't know about any file formats.) Calcite knows about
-those tables because we told it to run code in the calcite-example-csv
-project.
-
-There are a couple of steps in that chain. First, we define a schema
-based on a schema factory class in a model file. Then the schema
-factory creates a schema, and the schema creates several tables, each
-of which knows how to get data by scanning a CSV file. Last, after
-Calcite has parsed the query and planned it to use those tables, Calcite
-invokes the tables to read the data as the query is being
-executed. Now let's look at those steps in more detail.
-
-On the JDBC connect string we gave the path of a model in JSON
-format. Here is the model:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'SALES',
-  schemas: [
-    {
-      name: 'SALES',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
-      operand: {
-        directory: 'target/test-classes/sales'
-      }
-    }
-  ]
-}
-{% endhighlight %}
-
-The model defines a single schema called 'SALES'. The schema is
-powered by a plugin class,
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java">org.apache.calcite.adapter.csv.CsvSchemaFactory</a>,
-which is part of the
-calcite-example-csv project and implements the Calcite interface
-<a href="{{ site.apiRoot }}/org/apache/calcite/schema/SchemaFactory.html">SchemaFactory</a>.
-Its <code>create</code> method instantiates a
-schema, passing in the <code>directory</code> argument from the model file:
-
-{% highlight java %}
-public Schema create(SchemaPlus parentSchema, String name,
-    Map<String, Object> operand) {
-  String directory = (String) operand.get("directory");
-  String flavorName = (String) operand.get("flavor");
-  CsvTable.Flavor flavor;
-  if (flavorName == null) {
-    flavor = CsvTable.Flavor.SCANNABLE;
-  } else {
-    flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase());
-  }
-  return new CsvSchema(
-      new File(directory),
-      flavor);
-}
-{% endhighlight %}
-
-Driven by the model, the schema factory instantiates a single schema
-called 'SALES'.  The schema is an instance of
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java">org.apache.calcite.adapter.csv.CsvSchema</a>
-and implements the Calcite interface
-<a href="{{ site.apiRoot }}/org/apache/calcite/schema/Schema.html">Schema</a>.
-
-A schema's job is to produce a list of tables. (It can also list sub-schemas and
-table-functions, but these are advanced features and calcite-example-csv does
-not support them.) The tables implement Calcite's
-<a href="{{ site.apiRoot }}/org/apache/calcite/schema/Table.html">Table</a>
-interface. <code>CsvSchema</code> produces tables that are instances of
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTable.java">CsvTable</a>
-and its sub-classes.
-
-Here is the relevant code from <code>CsvSchema</code>, overriding the
-<code><a href="{{ site.apiRoot }}/org/apache/calcite/schema/impl/AbstractSchema.html#getTableMap()">getTableMap()</a></code>
-method in the <code>AbstractSchema</code> base class.
-
-{% highlight java %}
-protected Map<String, Table> getTableMap() {
-  // Look for files in the directory ending in ".csv", ".csv.gz", ".json",
-  // ".json.gz".
-  File[] files = directoryFile.listFiles(
-      new FilenameFilter() {
-        public boolean accept(File dir, String name) {
-          final String nameSansGz = trim(name, ".gz");
-          return nameSansGz.endsWith(".csv")
-              || nameSansGz.endsWith(".json");
-        }
-      });
-  if (files == null) {
-    System.out.println("directory " + directoryFile + " not found");
-    files = new File[0];
-  }
-  // Build a map from table name to table; each file becomes a table.
-  final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
-  for (File file : files) {
-    String tableName = trim(file.getName(), ".gz");
-    final String tableNameSansJson = trimOrNull(tableName, ".json");
-    if (tableNameSansJson != null) {
-      JsonTable table = new JsonTable(file);
-      builder.put(tableNameSansJson, table);
-      continue;
-    }
-    tableName = trim(tableName, ".csv");
-    final Table table = createTable(file);
-    builder.put(tableName, table);
-  }
-  return builder.build();
-}
-
-/** Creates different sub-type of table based on the "flavor" attribute. */
-private Table createTable(File file) {
-  switch (flavor) {
-  case TRANSLATABLE:
-    return new CsvTranslatableTable(file, null);
-  case SCANNABLE:
-    return new CsvScannableTable(file, null);
-  case FILTERABLE:
-    return new CsvFilterableTable(file, null);
-  default:
-    throw new AssertionError("Unknown flavor " + flavor);
-  }
-}
-{% endhighlight %}
-
-The schema scans the directory and finds all files whose name ends
-with ".csv" and creates tables for them. In this case, the directory
-is <code>target/test-classes/sales</code> and contains files
-<code>EMPS.csv</code> and <code>DEPTS.csv</code>, which these become
-the tables <code>EMPS</code> and <code>DEPTS</code>.
-
-## Tables and views in schemas
-
-Note how we did not need to define any tables in the model; the schema
-generated the tables automatically.
-
-You can define extra tables,
-beyond those that are created automatically,
-using the <code>tables</code> property of a schema.
-
-Let's see how to create
-an important and useful type of table, namely a view.
-
-A view looks like a table when you are writing a query, but it doesn't store data.
-It derives its result by executing a query.
-The view is expanded while the query is being planned, so the query planner
-can often perform optimizations like removing expressions from the SELECT
-clause that are not used in the final result.
-
-Here is a schema that defines a view:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'SALES',
-  schemas: [
-    {
-      name: 'SALES',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
-      operand: {
-        directory: 'target/test-classes/sales'
-      },
-      tables: [
-        {
-          name: 'FEMALE_EMPS',
-          type: 'view',
-          sql: 'SELECT * FROM emps WHERE gender = \'F\''
-        }
-      ]
-    }
-  ]
-}
-{% endhighlight %}
-
-The line <code>type: 'view'</code> tags <code>FEMALE_EMPS</code> as a view,
-as opposed to a regular table or a custom table.
-Note that single-quotes within the view definition are escaped using a
-back-slash, in the normal way for JSON.
-
-JSON doesn't make it easy to author long strings, so Calcite supports an
-alternative syntax. If your view has a long SQL statement, you can instead
-supply a list of lines rather than a single string:
-
-{% highlight json %}
-{
-  name: 'FEMALE_EMPS',
-  type: 'view',
-  sql: [
-    'SELECT * FROM emps',
-    'WHERE gender = \'F\''
-  ]
-}
-{% endhighlight %}
-
-Now we have defined a view, we can use it in queries just as if it were a table:
-
-{% highlight sql %}
-sqlline> SELECT e.name, d.name FROM female_emps AS e JOIN depts AS d on e.deptno = d.deptno;
-+--------+------------+
-|  NAME  |    NAME    |
-+--------+------------+
-| Wilma  | Marketing  |
-+--------+------------+
-{% endhighlight %}
-
-## Custom tables
-
-Custom tables are tables whose implementation is driven by user-defined code.
-They don't need to live in a custom schema.
-
-There is an example in <code>model-with-custom-table.json</code>:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'CUSTOM_TABLE',
-  schemas: [
-    {
-      name: 'CUSTOM_TABLE',
-      tables: [
-        {
-          name: 'EMPS',
-          type: 'custom',
-          factory: 'org.apache.calcite.adapter.csv.CsvTableFactory',
-          operand: {
-            file: 'target/test-classes/sales/EMPS.csv.gz',
-            flavor: "scannable"
-          }
-        }
-      ]
-    }
-  ]
-}
-{% endhighlight %}
-
-We can query the table in the usual way:
-
-{% highlight sql %}
-sqlline> !connect jdbc:calcite:model=target/test-classes/model-with-custom-table.json admin admin
-sqlline> SELECT empno, name FROM custom_table.emps;
-+--------+--------+
-| EMPNO  |  NAME  |
-+--------+--------+
-| 100    | Fred   |
-| 110    | Eric   |
-| 110    | John   |
-| 120    | Wilma  |
-| 130    | Alice  |
-+--------+--------+
-{% endhighlight %}
-
-The schema is a regular one, and contains a custom table powered by
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableFactory.java">org.apache.calcite.adapter.csv.CsvTableFactory</a>,
-which implements the Calcite interface
-<a href="{{ site.apiRoot }}/org/apache/calcite/schema/TableFactory.html">TableFactory</a>.
-Its <code>create</code> method instantiates a <code>CsvScannableTable</code>,
-passing in the <code>file</code> argument from the model file:
-
-{% highlight java %}
-public CsvTable create(SchemaPlus schema, String name,
-    Map<String, Object> map, RelDataType rowType) {
-  String fileName = (String) map.get("file");
-  final File file = new File(fileName);
-  final RelProtoDataType protoRowType =
-      rowType != null ? RelDataTypeImpl.proto(rowType) : null;
-  return new CsvScannableTable(file, protoRowType);
-}
-{% endhighlight %}
-
-Implementing a custom table is often a simpler alternative to implementing
-a custom schema. Both approaches might end up creating a similar implementation
-of the <code>Table</code> interface, but for the custom table you don't
-need to implement metadata discovery. (<code>CsvTableFactory</code>
-creates a <code>CsvScannableTable</code>, just as <code>CsvSchema</code> does,
-but the table implementation does not scan the filesystem for .csv files.)
-
-Custom tables require more work for the author of the model (the author
-needs to specify each table and its file explicitly) but also give the author
-more control (say, providing different parameters for each table).
-
-## Comments in models
-
-Models can include comments using `/* ... */` and `//` syntax:
-
-{% highlight json %}
-{
-  version: '1.0',
-  /* Multi-line
-     comment. */
-  defaultSchema: 'CUSTOM_TABLE',
-  // Single-line comment.
-  schemas: [
-    ..
-  ]
-}
-{% endhighlight %}
-
-(Comments are not standard JSON, but are a harmless extension.)
-
-## Optimizing queries using planner rules
-
-The table implementations we have seen so far are fine as long as the tables
-don't contain a great deal of data. But if your customer table has, say, a
-hundred columns and a million rows, you would rather that the system did not
-retrieve all of the data for every query. You would like Calcite to negotiate
-with the adapter and find a more efficient way of accessing the data.
-
-This negotiation is a simple form of query optimization. Calcite supports query
-optimization by adding <i>planner rules</i>. Planner rules operate by
-looking for patterns in the query parse tree (for instance a project on top
-of a certain kind of table), and
-
-Planner rules are also extensible, like schemas and tables. So, if you have a
-data store that you want to access via SQL, you first define a custom table or
-schema, and then you define some rules to make the access efficient.
-
-To see this in action, let's use a planner rule to access
-a subset of columns from a CSV file. Let's run the same query against two very
-similar schemas:
-
-{% highlight sql %}
-sqlline> !connect jdbc:calcite:model=target/test-classes/model.json admin admin
-sqlline> explain plan for select name from emps;
-+-----------------------------------------------------+
-| PLAN                                                |
-+-----------------------------------------------------+
-| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
-|   EnumerableTableAccessRel(table=[[SALES, EMPS]])   |
-+-----------------------------------------------------+
-sqlline> !connect jdbc:calcite:model=target/test-classes/smart.json admin admin
-sqlline> explain plan for select name from emps;
-+-----------------------------------------------------+
-| PLAN                                                |
-+-----------------------------------------------------+
-| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
-|   CsvTableScan(table=[[SALES, EMPS]])               |
-+-----------------------------------------------------+
-{% endhighlight %}
-
-What causes the difference in plan? Let's follow the trail of evidence. In the
-<code>smart.json</code> model file, there is just one extra line:
-
-{% highlight json %}
-flavor: "translatable"
-{% endhighlight %}
-
-This causes a <code>CsvSchema</code> to be created with
-<code>flavor = TRANSLATABLE</code>,
-and its <code>createTable</code> method creates instances of
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTranslatableTable.java">CsvTranslatableTable</a>
-rather than a <code>CsvScannableTable</code>.
-
-<code>CsvTranslatableTable</code> implements the
-<code><a href="{{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html#toRel()">TranslatableTable.toRel()</a></code>
-method to create
-<a href="{{ site.sourceRoot }}/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableScan.java">CsvTableScan</a>.
-Table scans are the leaves of a query operator tree.
-The usual implementation is
-<code><a href="{{ site.apiRoot }}/org/apache/calcite/adapter/enumerable/EnumerableTableScan.html">EnumerableTableScan</a></code>,
-but we have created a distinctive sub-type that will cause rules to fire.
-
-Here is the rule in its entirety:
-
-{% highlight java %}
-public class CsvProjectTableScanRule extends RelOptRule {
-  public static final CsvProjectTableScanRule INSTANCE =
-      new CsvProjectTableScanRule();
-
-  private CsvProjectTableScanRule() {
-    super(
-        operand(Project.class,
-            operand(CsvTableScan.class, none())),
-        "CsvProjectTableScanRule");
-  }
-
-  @Override
-  public void onMatch(RelOptRuleCall call) {
-    final Project project = call.rel(0);
-    final CsvTableScan scan = call.rel(1);
-    int[] fields = getProjectFields(project.getProjects());
-    if (fields == null) {
-      // Project contains expressions more complex than just field references.
-      return;
-    }
-    call.transformTo(
-        new CsvTableScan(
-            scan.getCluster(),
-            scan.getTable(),
-            scan.csvTable,
-            fields));
-  }
-
-  private int[] getProjectFields(List<RexNode> exps) {
-    final int[] fields = new int[exps.size()];
-    for (int i = 0; i < exps.size(); i++) {
-      final RexNode exp = exps.get(i);
-      if (exp instanceof RexInputRef) {
-        fields[i] = ((RexInputRef) exp).getIndex();
-      } else {
-        return null; // not a simple projection
-      }
-    }
-    return fields;
-  }
-}
-{% endhighlight %}
-
-The constructor declares the pattern of relational expressions that will cause
-the rule to fire.
-
-The <code>onMatch</code> method generates a new relational expression and calls
-<code><a href="{{ site.apiRoot }}/org/apache/calcite/plan/RelOptRuleCall.html#transformTo(org.apache.calcite.rel.RelNode)">RelOptRuleCall.transformTo()</a></code>
-to indicate that the rule has fired successfully.
-
-## The query optimization process
-
-There's a lot to say about how clever Calcite's query planner is, but we won't
-say it here. The cleverness is designed to take the burden off you, the writer
-of planner rules.
-
-First, Calcite doesn't fire rules in a prescribed order. The query optimization
-process follows many branches of a branching tree, just like a chess playing
-program examines many possible sequences of moves. If rules A and B both match a
-given section of the query operator tree, then Calcite can fire both.
-
-Second, Calcite uses cost in choosing between plans, but the cost model doesn't
-prevent rules from firing which may seem to be more expensive in the short term.
-
-Many optimizers have a linear optimization scheme. Faced with a choice between
-rule A and rule B, as above, such an optimizer needs to choose immediately. It
-might have a policy such as "apply rule A to the whole tree, then apply rule B
-to the whole tree", or apply a cost-based policy, applying the rule that
-produces the cheaper result.
-
-Calcite doesn't require such compromises.
-This makes it simple to combine various sets of rules.
-If, say you want to combine rules to recognize materialized views with rules to
-read from CSV and JDBC source systems, you just give Calcite the set of all
-rules and tell it to go at it.
-
-Calcite does use a cost model. The cost model decides which plan to ultimately
-use, and sometimes to prune the search tree to prevent the search space from
-exploding, but it never forces you to choose between rule A and rule B. This is
-important, because it avoids falling into local minima in the search space that
-are not actually optimal.
-
-Also (you guessed it) the cost model is pluggable, as are the table and query
-operator statistics it is based upon. But that can be a subject for later.
-
-## JDBC adapter
-
-The JDBC adapter maps a schema in a JDBC data source as a Calcite schema.
-
-For example, this schema reads from a MySQL "foodmart" database:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'FOODMART',
-  schemas: [
-    {
-      name: 'FOODMART',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
-      operand: {
-        jdbcDriver: 'com.mysql.jdbc.Driver',
-        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
-        jdbcUser: 'foodmart',
-        jdbcPassword: 'foodmart'
-      }
-    }
-  ]
-}
-{% endhighlight %}
-
-(The FoodMart database will be familiar to those of you who have used
-the Mondrian OLAP engine, because it is Mondrian's main test data
-set. To load the data set, follow <a
-href="http://mondrian.pentaho.com/documentation/installation.php#2_Set_up_test_data">Mondrian's
-installation instructions</a>.)
-
-<b>Current limitations</b>: The JDBC adapter currently only pushes
-down table scan operations; all other processing (filtering, joins,
-aggregations and so forth) occurs within Calcite. Our goal is to push
-down as much processing as possible to the source system, translating
-syntax, data types and built-in functions as we go. If a Calcite query
-is based on tables from a single JDBC database, in principle the whole
-query should go to that database. If tables are from multiple JDBC
-sources, or a mixture of JDBC and non-JDBC, Calcite will use the most
-efficient distributed query approach that it can.
-
-## The cloning JDBC adapter
-
-The cloning JDBC adapter creates a hybrid database. The data is
-sourced from a JDBC database but is read into in-memory tables the
-first time each table is accessed. Calcite evaluates queries based on
-those in-memory tables, effectively a cache of the database.
-
-For example, the following model reads tables from a MySQL
-"foodmart" database:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'FOODMART_CLONE',
-  schemas: [
-    {
-      name: 'FOODMART_CLONE',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
-      operand: {
-        jdbcDriver: 'com.mysql.jdbc.Driver',
-        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
-        jdbcUser: 'foodmart',
-        jdbcPassword: 'foodmart'
-      }
-    }
-  ]
-}
-{% endhighlight %}
-
-Another technique is to build a clone schema on top of an existing
-schema. You use the <code>source</code> property to reference a schema
-defined earlier in the model, like this:
-
-{% highlight json %}
-{
-  version: '1.0',
-  defaultSchema: 'FOODMART_CLONE',
-  schemas: [
-    {
-      name: 'FOODMART',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
-      operand: {
-        jdbcDriver: 'com.mysql.jdbc.Driver',
-        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
-        jdbcUser: 'foodmart',
-        jdbcPassword: 'foodmart'
-      }
-    },
-    {
-      name: 'FOODMART_CLONE',
-      type: 'custom',
-      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
-      operand: {
-        source: 'FOODMART'
-      }
-    }
-  ]
-}
-{% endhighlight %}
-
-You can use this approach to create a clone schema on any type of
-schema, not just JDBC.
-
-The cloning adapter isn't the be-all and end-all. We plan to develop
-more sophisticated caching strategies, and a more complete and
-efficient implementation of in-memory tables, but for now the cloning
-JDBC adapter shows what is possible and allows us to try out our
-initial implementations.
-
-## Further topics
-
-### Defining a custom schema
-
-(To be written.)
-
-### Modifying data
-
-How to enable DML operations (INSERT, UPDATE and DELETE) on your schema.
-
-(To be written.)
-
-### Calling conventions
-
-(To be written.)
-
-### Statistics and cost
-
-(To be written.)
-
-### Defining and using user-defined functions
-
-(To be written.)
-
-###  Defining tables in a schema
-
-(To be written.)
-
-### Defining custom tables
-
-(To be written.)
-
-### Built-in SQL implementation
-
-How does Calcite implement SQL, if an adapter does not implement all of the core
-relational operators?
-
-(To be written.)
-
-### Table functions
-
-(To be written.)

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_includes/header.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/header.html b/avatica/site/_includes/header.html
index 7d42786..e901cc4 100644
--- a/avatica/site/_includes/header.html
+++ b/avatica/site/_includes/header.html
@@ -5,7 +5,7 @@
   <div class="grid">
     <div class="unit one-third center-on-mobiles">
       <h1>
-        <a href="{{ site.baseurl }}/">
+        <a href="{{ site.baseurl }}/..">
           <span class="sr-only">Apache Calcite</span>
           <img src="{{ site.baseurl }}/img/logo.png" width="226" height="140" alt="Calcite Logo">
         </a>

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_includes/news_contents.html
----------------------------------------------------------------------
diff --git a/avatica/site/_includes/news_contents.html b/avatica/site/_includes/news_contents.html
index d1481e7..09176b8 100644
--- a/avatica/site/_includes/news_contents.html
+++ b/avatica/site/_includes/news_contents.html
@@ -5,7 +5,7 @@
         <a href="{{ site.baseurl }}/news/">All News</a>
       </li>
       <li class="{% if page.title == 'Releases' %}current{% endif %}">
-        <a href="{{ site.baseurl }}/news/releases/">Calcite Releases</a>
+        <a href="{{ site.baseurl }}/news/releases/">Avatica Releases</a>
       </li>
     </ul>
     <h4>Recent Releases</h4>

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md b/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
deleted file mode 100644
index 83f975d..0000000
--- a/avatica/site/_posts/2014-06-27-release-0.8.0-incubating.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-layout: news_item
-date: "2014-06-27 00:00:00 -0800"
-author: jhyde
-version: 0.8
-tag: v0-8
-sha: 3da850a1
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Several new features, including a heuristic rule to plan queries with
-a large number of joins, a number of windowed aggregate functions, and
-new utility, `SqlRun`.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md b/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
deleted file mode 100644
index 7ca65ac..0000000
--- a/avatica/site/_posts/2014-08-19-release-0.9.0-incubating.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-layout: news_item
-date: "2014-08-19 00:00:00 -0800"
-author: jhyde
-version: 0.9.0-incubating
-fullVersion: apache-optiq-0.9.0-incubating
-tag: v0-9-0
-sha: 45e5269b
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-This is the first release under the Apache incubator process.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md b/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
deleted file mode 100644
index bca9113..0000000
--- a/avatica/site/_posts/2014-10-02-release-0.9.1-incubating.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: news_item
-date: "2014-10-02 00:00:00 -0800"
-author: jhyde
-version: 0.9.1-incubating
-tag: v0-9-1
-sha: 68012573
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-This is the first release as Calcite. (The project was previously called Optiq.)

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md b/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
deleted file mode 100644
index 47741c0..0000000
--- a/avatica/site/_posts/2014-11-05-release-0.9.2-incubating.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-layout: news_item
-date: "2014-11-05 00:00:00 -0800"
-author: jhyde
-version: 0.9.2-incubating
-tag: v0-9-2
-sha: 0404fd23
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-A fairly minor release, and last release before we rename all of the
-packages and lots of classes, in what we expect to call 1.0. If you
-have an existing application, it's worth upgrading to this first,
-before you move on to 1.0.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md b/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
deleted file mode 100644
index ad60205..0000000
--- a/avatica/site/_posts/2015-01-31-release-1.0.0-incubating.md
+++ /dev/null
@@ -1,42 +0,0 @@
----
-layout: news_item
-date: "2015-01-31 19:03:07 -0800"
-author: jhyde
-version: 1.0.0-incubating
-tag: v1-0-0
-sha: 2dd83f2
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Calcite's first major release.
-
-Since the previous release we have re-organized the into the `org.apache.calcite`
-namespace. To make migration of your code easier, we have described the
-<a href="https://issues.apache.org/jira/secure/attachment/12681620/mapping.txt">mapping from old to new class names</a>
-as an attachment to
-[<a href="https://issues.apache.org/jira/browse/CALCITE-296">CALCITE-296</a>].
-
-The release adds SQL support for `GROUPING SETS`, `EXTEND`, `UPSERT` and sequences;
-a remote JDBC driver;
-improvements to the planner engine and built-in planner rules;
-improvements to the algorithms that implement the relational algebra,
-including an interpreter that can evaluate queries without compilation;
-and fixes about 30 bugs.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md b/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
deleted file mode 100644
index 327b023..0000000
--- a/avatica/site/_posts/2015-03-13-release-1.1.0-incubating.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-layout: news_item
-date: "2015-03-13 19:03:07 -0800"
-author: jhyde
-version: 1.1.0-incubating
-tag: v1-1-0
-sha: f10ea367
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-This Calcite release makes it possible to exploit physical properties
-of relational expressions to produce more efficient plans, introducing
-collation and distribution as traits, `Exchange` relational operator,
-and several new forms of metadata.
-
-We add experimental support for streaming SQL.
-
-This release drops support for JDK 1.6; Calcite now requires 1.7 or
-later.
-
-We have introduced static `create` methods for many sub-classes of
-`RelNode`. We strongly suggest that you use these rather than
-calling constructors directly.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md b/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
deleted file mode 100644
index 8332063..0000000
--- a/avatica/site/_posts/2015-04-07-release-1.2.0-incubating.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-layout: news_item
-date: "2015-04-07 19:03:07 -0800"
-author: jhyde
-version: 1.2.0-incubating
-tag: v1-2-0
-sha: d60f2aa
-categories: [release]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-A short release, less than a month after 1.1.
-
-There have been many changes to Avatica, hugely improving its coverage of the
-JDBC API and overall robustness. A new provider, `JdbcMeta`, allows
-you to remote an existing JDBC driver.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-606">CALCITE-606</a>]
-improves how the planner propagates traits such as collation and
-distribution among relational expressions.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-613">CALCITE-613</a>]
-and [<a href="https://issues.apache.org/jira/browse/CALCITE-307">CALCITE-307</a>]
-improve implicit and explicit conversions in SQL.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-04-24-new-committers.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-04-24-new-committers.md b/avatica/site/_posts/2015-04-24-new-committers.md
deleted file mode 100644
index 92a2466..0000000
--- a/avatica/site/_posts/2015-04-24-new-committers.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: news_item
-title: "Calcite adds 5 committers"
-date: "2015-04-24 19:03:07 -0800"
-author: jhyde
-categories: [team]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-The Calcite project management committee today added five new
-committers for their work on Calcite. Welcome all!
-
-* Aman Sinha
-* Jesús Camacho-Rodríguez
-* Jinfeng Ni
-* John Pullokkaran
-* Nick Dimiduk

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md b/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
deleted file mode 100644
index b72765f..0000000
--- a/avatica/site/_posts/2015-05-30-release-1.3.0-incubating.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-layout: news_item
-date: "2015-05-30 23:05:37 +0000"
-author: jhyde
-version: 1.3.0-incubating
-categories: [release]
-tag: v1-3-0
-sha: 495f1859
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Mainly bug-fixes, but this release adds support for
-<a href="https://issues.apache.org/jira/browse/CALCITE-505">modifiable views</a>
-and
-<a href="https://issues.apache.org/jira/browse/CALCITE-704">filtered aggregate functions</a>
-and various improvements to Avatica.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-06-05-algebra-builder.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-06-05-algebra-builder.md b/avatica/site/_posts/2015-06-05-algebra-builder.md
deleted file mode 100644
index ddf3377..0000000
--- a/avatica/site/_posts/2015-06-05-algebra-builder.md
+++ /dev/null
@@ -1,87 +0,0 @@
----
-layout: news_item
-title: "Algebra builder"
-date: "2015-06-05 19:29:07 -0800"
-author: jhyde
-categories: ["new features"]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Calcite's foundation is a comprehensive implementation of relational
-algebra (together with transformation rules, cost model, and metadata)
-but to create algebra expressions you had to master a complex API.
-
-We're solving this problem by introducing an
-[algebra builder]({{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html),
-a single class with all the methods you need to build any relational
-expression.
-
-For example,
-
-{% highlight java %}
-final FrameworkConfig config;
-final RelBuilder builder = RelBuilder.create(config);
-final RelNode node = builder
-  .scan("EMP")
-  .aggregate(builder.groupKey("DEPTNO"),
-      builder.count(false, "C"),
-      builder.sum(false, "S", builder.field("SAL")))
-  .filter(
-      builder.call(SqlStdOperatorTable.GREATER_THAN,
-          builder.field("C"),
-          builder.literal(10)))
-  .build();
-System.out.println(RelOptUtil.toString(node));
-{% endhighlight %}
-
-creates the algebra
-
-{% highlight text %}
-LogicalFilter(condition=[>($1, 10)])
-  LogicalAggregate(group=[{7}], C=[COUNT()], S=[SUM($5)])
-    LogicalTableScan(table=[[scott, EMP]])
-{% endhighlight %}
-
-which is equivalent to the SQL
-
-{% highlight sql %}
-SELECT deptno, count(*) AS c, sum(sal) AS s
-FROM emp
-GROUP BY deptno
-HAVING count(*) > 10
-{% endhighlight %}
-
-The [algebra builder documentation]({{ site.baseurl }}/docs/algebra.html) describes the
-full API and has lots of examples.
-
-We're still working on the algebra builder, but plan to release it
-with Calcite 1.4 (see
-[[CALCITE-748](https://issues.apache.org/jira/browse/CALCITE-748)]).
-
-The algebra builder will make some existing tasks easier (such as
-writing planner rules), but will also enable new things, such as
-writing applications directly on top of Calcite, or implementing
-non-SQL query languages. These applications and languages will be able
-to take advantage of Calcite's existing back-ends (including
-Hive-on-Tez, Drill, MongoDB, Splunk, Spark, JDBC data sources) and
-extensive set of query-optimization rules.
-
-If you have questions or comments, please post to the
-[mailing list]({{ site.baseurl }}/develop).

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md b/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
deleted file mode 100644
index b0e1f46..0000000
--- a/avatica/site/_posts/2015-07-31-xldb-best-lightning-talk.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-layout: news_item
-title: "XLDB 2015 best lightning talk"
-date: "2015-07-31 11:53:00 -0800"
-author: jhyde
-categories: ["talks"]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Julian Hyde's talk Apache Calcite: One planner fits all won
-[Best Lightning Talk](http://www.xldb.org/archives/2015/05/best-lightning-talks-selected/)
-at the XLDB-2015 conference (with Eric Tschetter's talk "Sketchy
-Approximations").
-
-XLDB is an annual conference that brings together experts from
-science, industry and academia to find practical solutions to problems
-involving extremely large data sets.
-
-As a result of winning Best Lightning Talk, Julian will get a 30
-minute keynote speaking slot at XLDB-2016.
-
-The talk is available in
-[slides](http://www.slideshare.net/julianhyde/apache-calcite-one-planner-fits-all)
-and [video](https://www.youtube.com/watch?v=5_MyORYjq3w).


[30/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
new file mode 100644
index 0000000..cd8a329
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ColumnMetaData.Rep;
+import org.apache.calcite.avatica.Meta.Signature;
+import org.apache.calcite.avatica.Meta.StatementHandle;
+import org.apache.calcite.avatica.proto.Common.WireMessage;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.remote.Service.Request;
+
+import com.google.protobuf.HBaseZeroCopyByteString;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Protobuf serialization tests.
+ */
+public class ProtobufSerializationTest {
+
+  private Signature getSignature() {
+    return null;
+  }
+
+  private List<TypedValue> getTypedValues() {
+    List<TypedValue> paramValues =
+        Arrays.asList(TypedValue.create(Rep.BOOLEAN.name(), Boolean.TRUE),
+            TypedValue.create(Rep.STRING.name(), "string"));
+    return paramValues;
+  }
+
+  @Test public void testExecuteSerialization() throws Exception {
+    Service.ExecuteRequest executeRequest = new Service.ExecuteRequest(
+        new StatementHandle("connection", 12345, getSignature()), getTypedValues(), 0);
+
+    Requests.ExecuteRequest pbExecuteRequest = executeRequest.serialize();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+    pbExecuteRequest.writeTo(baos);
+
+    byte[] serialized = baos.toByteArray();
+    baos.reset();
+    WireMessage wireMsg = WireMessage.newBuilder().setName(Requests.ExecuteRequest.class.getName())
+        .setWrappedMessage(HBaseZeroCopyByteString.wrap(serialized)).build();
+    wireMsg.writeTo(baos);
+    serialized = baos.toByteArray();
+
+    ProtobufTranslation translator = new ProtobufTranslationImpl();
+
+    Request newRequest = translator.parseRequest(serialized);
+
+    Assert.assertEquals(executeRequest, newRequest);
+  }
+
+}
+
+// End ProtobufSerializationTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufServiceTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufServiceTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufServiceTest.java
new file mode 100644
index 0000000..a29ee34
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufServiceTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.proto.Requests;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test class for ProtobufService.
+ */
+public class ProtobufServiceTest {
+
+  @Test public void testCastProtobufMessage() {
+    final Requests.CommitRequest commitReq =
+        Requests.CommitRequest.newBuilder().setConnectionId("cnxn1").build();
+    final Requests.RollbackRequest rollbackReq =
+        Requests.RollbackRequest.newBuilder().setConnectionId("cnxn1").build();
+
+    assertEquals(commitReq,
+        ProtobufService.castProtobufMessage(commitReq, Requests.CommitRequest.class));
+    assertEquals(rollbackReq,
+        ProtobufService.castProtobufMessage(rollbackReq, Requests.RollbackRequest.class));
+
+    try {
+      ProtobufService.castProtobufMessage(commitReq, Requests.RollbackRequest.class);
+      fail("Should have seen IllegalArgumentException casting CommitRequest into RollbackRequest");
+    } catch (IllegalArgumentException e) {
+      // Expected
+    }
+
+    try {
+      ProtobufService.castProtobufMessage(rollbackReq, Requests.CommitRequest.class);
+      fail("Should have seen IllegalArgumentException casting RollbackRequest into CommitRequest");
+    } catch (IllegalArgumentException e) {
+      // Expected
+    }
+  }
+}
+
+// End ProtobufServiceTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
new file mode 100644
index 0000000..c75bdb0
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
@@ -0,0 +1,376 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.ColumnMetaData.ArrayType;
+import org.apache.calcite.avatica.ColumnMetaData.Rep;
+import org.apache.calcite.avatica.ColumnMetaData.ScalarType;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.Meta.Frame;
+import org.apache.calcite.avatica.Meta.Signature;
+import org.apache.calcite.avatica.Meta.Style;
+import org.apache.calcite.avatica.MetaImpl;
+import org.apache.calcite.avatica.QueryState;
+import org.apache.calcite.avatica.remote.Service.CatalogsRequest;
+import org.apache.calcite.avatica.remote.Service.CloseConnectionRequest;
+import org.apache.calcite.avatica.remote.Service.CloseConnectionResponse;
+import org.apache.calcite.avatica.remote.Service.CloseStatementRequest;
+import org.apache.calcite.avatica.remote.Service.CloseStatementResponse;
+import org.apache.calcite.avatica.remote.Service.ColumnsRequest;
+import org.apache.calcite.avatica.remote.Service.CommitRequest;
+import org.apache.calcite.avatica.remote.Service.CommitResponse;
+import org.apache.calcite.avatica.remote.Service.ConnectionSyncRequest;
+import org.apache.calcite.avatica.remote.Service.ConnectionSyncResponse;
+import org.apache.calcite.avatica.remote.Service.CreateStatementRequest;
+import org.apache.calcite.avatica.remote.Service.CreateStatementResponse;
+import org.apache.calcite.avatica.remote.Service.DatabasePropertyRequest;
+import org.apache.calcite.avatica.remote.Service.DatabasePropertyResponse;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.ExecuteResponse;
+import org.apache.calcite.avatica.remote.Service.FetchRequest;
+import org.apache.calcite.avatica.remote.Service.FetchResponse;
+import org.apache.calcite.avatica.remote.Service.OpenConnectionRequest;
+import org.apache.calcite.avatica.remote.Service.OpenConnectionResponse;
+import org.apache.calcite.avatica.remote.Service.PrepareAndExecuteRequest;
+import org.apache.calcite.avatica.remote.Service.PrepareRequest;
+import org.apache.calcite.avatica.remote.Service.PrepareResponse;
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+import org.apache.calcite.avatica.remote.Service.ResultSetResponse;
+import org.apache.calcite.avatica.remote.Service.RollbackRequest;
+import org.apache.calcite.avatica.remote.Service.RollbackResponse;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+import org.apache.calcite.avatica.remote.Service.SchemasRequest;
+import org.apache.calcite.avatica.remote.Service.SyncResultsRequest;
+import org.apache.calcite.avatica.remote.Service.SyncResultsResponse;
+import org.apache.calcite.avatica.remote.Service.TableTypesRequest;
+import org.apache.calcite.avatica.remote.Service.TablesRequest;
+import org.apache.calcite.avatica.remote.Service.TypeInfoRequest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.sql.DatabaseMetaData;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests serialization of requests and response objects.
+ *
+ * @param <T> The object class being tested
+ */
+@RunWith(Parameterized.class)
+public class ProtobufTranslationImplTest<T> {
+
+  /**
+   * Simple function definition that acts as an identity.
+   *
+   * @param <A> Argument type
+   */
+  private interface IdentityFunction<A> {
+    A apply(A obj) throws IOException;
+  }
+
+  /**
+   * Identity function that accepts a request, serializes it to protobuf, and converts it back.
+   */
+  private static class RequestFunc implements IdentityFunction<Request> {
+    private final ProtobufTranslation translation;
+
+    public RequestFunc(ProtobufTranslation translation) {
+      this.translation = translation;
+    }
+
+    public Request apply(Request request) throws IOException {
+      // Serialize and then re-parse the request
+      return translation.parseRequest(translation.serializeRequest(request));
+    }
+  }
+
+  /**
+   * Identity function that accepts a response, serializes it to protobuf, and converts it back.
+   */
+  private static class ResponseFunc implements IdentityFunction<Response> {
+    private final ProtobufTranslation translation;
+
+    public ResponseFunc(ProtobufTranslation translation) {
+      this.translation = translation;
+    }
+
+    public Response apply(Response response) throws IOException {
+      // Serialize and then re-pare the response
+      return translation.parseResponse(translation.serializeResponse(response));
+    }
+  }
+
+  @Parameters
+  public static List<Object[]> parameters() {
+    List<Object[]> params = new ArrayList<>();
+
+    // The impl we're testing
+    ProtobufTranslationImpl translation = new ProtobufTranslationImpl();
+
+    // Identity transformation for Requests
+    RequestFunc requestFunc = new RequestFunc(translation);
+    // Identity transformation for Responses
+    ResponseFunc responseFunc = new ResponseFunc(translation);
+
+    List<Request> requests = getRequests();
+    List<Request> requestsWithNulls = getRequestsWithNulls();
+    List<Response> responses = getResponses();
+
+    // Requests
+    for (Request request : requests) {
+      params.add(new Object[] {request, requestFunc});
+    }
+
+    // Requests with nulls in parameters
+    for (Request request : requestsWithNulls) {
+      params.add(new Object[] {request, requestFunc});
+    }
+
+    // Responses
+    for (Response response : responses) {
+      params.add(new Object[] {response, responseFunc});
+    }
+
+    return params;
+  }
+
+  /**
+   * Generates a collection of Requests whose serialization will be tested.
+   */
+  private static List<Request> getRequests() {
+    LinkedList<Request> requests = new LinkedList<>();
+
+    requests.add(new CatalogsRequest());
+    requests.add(new DatabasePropertyRequest());
+    requests.add(new SchemasRequest("connectionId", "catalog", "schemaPattern"));
+    requests.add(
+        new TablesRequest("connectionId", "catalog", "schemaPattern", "tableNamePattern",
+            Arrays.asList("STRING", "BOOLEAN", "INT")));
+    requests.add(new TableTypesRequest());
+    requests.add(
+        new ColumnsRequest("connectionId", "catalog", "schemaPattern", "tableNamePattern",
+            "columnNamePattern"));
+    requests.add(new TypeInfoRequest());
+    requests.add(
+        new PrepareAndExecuteRequest("connectionId", Integer.MAX_VALUE, "sql",
+            Long.MAX_VALUE));
+    requests.add(new PrepareRequest("connectionId", "sql", Long.MAX_VALUE));
+
+    List<TypedValue> paramValues =
+        Arrays.asList(TypedValue.create(Rep.BOOLEAN.name(), Boolean.TRUE),
+            TypedValue.create(Rep.STRING.name(), "string"));
+    FetchRequest fetchRequest = new FetchRequest("connectionId", Integer.MAX_VALUE,
+        Long.MAX_VALUE, Integer.MAX_VALUE);
+    requests.add(fetchRequest);
+
+    requests.add(new CreateStatementRequest("connectionId"));
+    requests.add(new CloseStatementRequest("connectionId", Integer.MAX_VALUE));
+    Map<String, String> info = new HashMap<>();
+    info.put("param1", "value1");
+    info.put("param2", "value2");
+    requests.add(new OpenConnectionRequest("connectionId", info));
+    requests.add(new CloseConnectionRequest("connectionId"));
+    requests.add(
+        new ConnectionSyncRequest("connectionId",
+            new ConnectionPropertiesImpl(Boolean.FALSE, Boolean.FALSE,
+                Integer.MAX_VALUE, "catalog", "schema")));
+
+    requests.add(new SyncResultsRequest("connectionId", 12345, getSqlQueryState(), 150));
+    requests.add(new SyncResultsRequest("connectionId2", 54321, getMetadataQueryState1(), 0));
+    requests.add(new SyncResultsRequest("connectionId3", 5, getMetadataQueryState2(), 10));
+
+    requests.add(new CommitRequest("connectionId"));
+    requests.add(new RollbackRequest("connectionId"));
+
+    return requests;
+  }
+
+  private static QueryState getSqlQueryState() {
+    return new QueryState("SELECT * from TABLE");
+  }
+
+  private static QueryState getMetadataQueryState1() {
+    return new QueryState(MetaDataOperation.GET_COLUMNS, new Object[] {
+      "",
+      null,
+      "%",
+      "%"
+    });
+  }
+
+  private static QueryState getMetadataQueryState2() {
+    return new QueryState(MetaDataOperation.GET_CATALOGS, new Object[0]);
+  }
+
+  private static List<Request> getRequestsWithNulls() {
+    LinkedList<Request> requests = new LinkedList<>();
+
+    // We're pretty fast and loose on what can be null.
+    requests.add(new SchemasRequest(null, null, null));
+    // Repeated fields default to an empty list
+    requests.add(new TablesRequest(null, null, null, null, Collections.<String>emptyList()));
+    requests.add(new ColumnsRequest(null, null, null, null, null));
+    requests.add(new PrepareAndExecuteRequest(null, 0, null, 0));
+    requests.add(new PrepareRequest(null, null, 0));
+    requests.add(new CreateStatementRequest(null));
+    requests.add(new CloseStatementRequest(null, 0));
+    requests.add(new OpenConnectionRequest(null, null));
+    requests.add(new CloseConnectionRequest(null));
+    requests.add(new ConnectionSyncRequest(null, null));
+
+    return requests;
+  }
+
+  private static ColumnMetaData getArrayColumnMetaData(ScalarType componentType, int index,
+      String name) {
+    ArrayType arrayType = ColumnMetaData.array(componentType, "Array", Rep.ARRAY);
+    return new ColumnMetaData(
+        index, false, true, false, false, DatabaseMetaData.columnNullable,
+        true, -1, name, name, null,
+        0, 0, null, null, arrayType, true, false, false,
+        "ARRAY");
+  }
+
+  /**
+   * Generates a collection of Responses whose serialization will be tested.
+   */
+  private static List<Response> getResponses() {
+    final RpcMetadataResponse rpcMetadata = new RpcMetadataResponse("localhost:8765");
+    LinkedList<Response> responses = new LinkedList<>();
+
+    // Nested classes (Signature, ColumnMetaData, CursorFactory, etc) are implicitly getting tested)
+
+    // Stub out the metadata for a row
+    ScalarType arrayComponentType = ColumnMetaData.scalar(Types.INTEGER, "integer", Rep.INTEGER);
+    ColumnMetaData arrayColumnMetaData = getArrayColumnMetaData(arrayComponentType, 2, "counts");
+    List<ColumnMetaData> columns =
+        Arrays.asList(MetaImpl.columnMetaData("str", 0, String.class),
+            MetaImpl.columnMetaData("count", 1, Integer.class),
+            arrayColumnMetaData);
+    List<AvaticaParameter> params =
+        Arrays.asList(
+            new AvaticaParameter(false, 10, 0, Types.VARCHAR, "VARCHAR",
+                String.class.getName(), "str"));
+    Meta.CursorFactory cursorFactory = Meta.CursorFactory.create(Style.LIST, Object.class,
+        Arrays.asList("str", "count", "counts"));
+    // The row values
+    List<Object> rows = new ArrayList<>();
+    rows.add(new Object[] {"str_value1", 50, Arrays.asList(1, 2, 3)});
+    rows.add(new Object[] {"str_value2", 100, Arrays.asList(1)});
+
+    // Create the signature and frame using the metadata and values
+    Signature signature = Signature.create(columns, "sql", params, cursorFactory,
+        Meta.StatementType.SELECT);
+    Frame frame = Frame.create(Integer.MAX_VALUE, true, rows);
+
+    // And then create a ResultSetResponse
+    ResultSetResponse results1 = new ResultSetResponse("connectionId", Integer.MAX_VALUE, true,
+        signature, frame, Long.MAX_VALUE, rpcMetadata);
+    responses.add(results1);
+
+    responses.add(new CloseStatementResponse(rpcMetadata));
+
+    ConnectionPropertiesImpl connProps = new ConnectionPropertiesImpl(false, true,
+        Integer.MAX_VALUE, "catalog", "schema");
+    responses.add(new ConnectionSyncResponse(connProps, rpcMetadata));
+
+    responses.add(new OpenConnectionResponse(rpcMetadata));
+    responses.add(new CloseConnectionResponse(rpcMetadata));
+
+    responses.add(new CreateStatementResponse("connectionId", Integer.MAX_VALUE, rpcMetadata));
+
+    Map<Meta.DatabaseProperty, Object> propertyMap = new HashMap<>();
+    for (Meta.DatabaseProperty prop : Meta.DatabaseProperty.values()) {
+      propertyMap.put(prop, prop.defaultValue);
+    }
+    responses.add(new DatabasePropertyResponse(propertyMap, rpcMetadata));
+
+    responses.add(
+        new ExecuteResponse(Arrays.asList(results1, results1, results1), false, rpcMetadata));
+    responses.add(new FetchResponse(frame, false, false, rpcMetadata));
+    responses.add(new FetchResponse(frame, true, true, rpcMetadata));
+    responses.add(new FetchResponse(frame, false, true, rpcMetadata));
+    responses.add(
+        new PrepareResponse(
+            new Meta.StatementHandle("connectionId", Integer.MAX_VALUE, signature),
+            rpcMetadata));
+
+    StringWriter sw = new StringWriter();
+    new Exception().printStackTrace(new PrintWriter(sw));
+    responses.add(
+        new ErrorResponse(Collections.singletonList(sw.toString()), "Test Error Message",
+            ErrorResponse.UNKNOWN_ERROR_CODE, ErrorResponse.UNKNOWN_SQL_STATE,
+            AvaticaSeverity.WARNING, rpcMetadata));
+
+    // No more results, statement not missing
+    responses.add(new SyncResultsResponse(false, false, rpcMetadata));
+    // Missing statement, no results
+    responses.add(new SyncResultsResponse(false, true, rpcMetadata));
+    // More results, no missing statement
+    responses.add(new SyncResultsResponse(true, false, rpcMetadata));
+
+    // Some tests to make sure ErrorResponse doesn't fail.
+    responses.add(new ErrorResponse((List<String>) null, null, 0, null, null, null));
+    responses.add(
+        new ErrorResponse(Arrays.asList("stacktrace1", "stacktrace2"), null, 0, null, null, null));
+
+    responses.add(new CommitResponse());
+    responses.add(new RollbackResponse());
+
+    return responses;
+  }
+
+  private final T object;
+  private final IdentityFunction<T> function;
+
+  public ProtobufTranslationImplTest(T object, IdentityFunction<T> func) {
+    this.object = object;
+    this.function = func;
+  }
+
+  @Test
+  public void testSerialization() throws Exception {
+    // Function acts as opposite sides of the transport.
+    // An object (a request or response) starts on one side
+    // of the transport, serialized, "sent" over the transport
+    // and then reconstituted. The object on either side should
+    // be equivalent.
+    assertEquals(object, this.function.apply(object));
+  }
+}
+
+// End ProtobufTranslationImplTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/remote/TypedValueTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/TypedValueTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/TypedValueTest.java
new file mode 100644
index 0000000..28fe6f6
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/TypedValueTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ColumnMetaData.Rep;
+import org.apache.calcite.avatica.util.ByteString;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test serialization of TypedValue.
+ */
+public class TypedValueTest {
+
+  private void serializeAndEqualityCheck(TypedValue value) {
+    TypedValue copy = TypedValue.fromProto(value.toProto());
+
+    assertEquals(value.type, copy.type);
+    assertEquals(value.value, copy.value);
+  }
+
+  @Test
+  public void testBoolean() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_BOOLEAN, true));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.BOOLEAN, Boolean.TRUE));
+  }
+
+  @Test
+  public void testByte() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_BYTE, (byte) 4));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.BYTE, Byte.valueOf((byte) 4)));
+  }
+
+  @Test
+  public void testShort() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_SHORT, (short) 42));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.SHORT, Short.valueOf((short) 42)));
+  }
+
+  @Test
+  public void testInteger() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_INT, (int) 42000));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.INTEGER, Integer.valueOf((int) 42000)));
+  }
+
+  @Test
+  public void testLong() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_LONG, Long.MAX_VALUE));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.LONG, Long.valueOf(Long.MAX_VALUE)));
+  }
+
+  @Test
+  public void testFloat() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_FLOAT, 3.14159f));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.FLOAT, Float.valueOf(3.14159f)));
+  }
+
+  @Test
+  public void testDouble() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_DOUBLE, Double.MAX_VALUE));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.DOUBLE, Double.valueOf(Double.MAX_VALUE)));
+  }
+
+  @Test
+  public void testChar() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.PRIMITIVE_CHAR, 'c'));
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.CHARACTER, Character.valueOf('c')));
+  }
+
+  @Test
+  public void testString() {
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.STRING, "qwertyasdf"));
+  }
+
+  @Test
+  public void testByteString() {
+    serializeAndEqualityCheck(
+        TypedValue.ofLocal(Rep.BYTE_STRING,
+            new ByteString("qwertyasdf".getBytes(StandardCharsets.UTF_8))));
+  }
+
+  @Test
+  public void testSqlDate() {
+    // days since epoch
+    serializeAndEqualityCheck(TypedValue.ofLocal(Rep.JAVA_SQL_DATE, 25));
+  }
+
+  @Test
+  public void testUtilDate() {
+    serializeAndEqualityCheck(
+        TypedValue.ofLocal(Rep.JAVA_UTIL_DATE, System.currentTimeMillis()));
+  }
+
+  @Test
+  public void testSqlTime() {
+    // millis since epoch
+    serializeAndEqualityCheck(
+        TypedValue.ofLocal(Rep.JAVA_SQL_TIME, 42 * 1024 * 1024));
+  }
+
+  @Test
+  public void testSqlTimestamp() {
+    serializeAndEqualityCheck(
+        TypedValue.ofLocal(Rep.JAVA_SQL_TIMESTAMP, 42L * 1024 * 1024 * 1024));
+  }
+}
+
+// End TypedValueTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaClientRuntimeExceptionTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaClientRuntimeExceptionTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaClientRuntimeExceptionTest.java
new file mode 100644
index 0000000..411f29c
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaClientRuntimeExceptionTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.AvaticaClientRuntimeException;
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link AvaticaClientRuntimeException}.
+ */
+public class AvaticaClientRuntimeExceptionTest {
+
+  @Test public void testGetters() {
+    final String errorMsg = "My error message";
+    final int errorCode = 10;
+    final String sqlState = "abc12";
+    final AvaticaSeverity severity = AvaticaSeverity.ERROR;
+    final List<String> stacktraces = Arrays.asList("my stack trace");
+    final RpcMetadataResponse metadata = new RpcMetadataResponse("localhost:8765");
+    AvaticaClientRuntimeException e = new AvaticaClientRuntimeException(errorMsg, errorCode,
+        sqlState, severity, stacktraces, metadata);
+    assertEquals(errorMsg, e.getMessage());
+    assertEquals(errorCode, e.getErrorCode());
+    assertEquals(severity, e.getSeverity());
+    assertEquals(stacktraces, e.getServerExceptions());
+    assertEquals(metadata, e.getRpcMetadata());
+  }
+
+}
+
+// End AvaticaClientRuntimeExceptionTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSeverityTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSeverityTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSeverityTest.java
new file mode 100644
index 0000000..945f959
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSeverityTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.AvaticaSeverity;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link AvaticaSeverity}.
+ */
+public class AvaticaSeverityTest {
+
+  @Test
+  public void testProtobufSerialization() {
+    for (AvaticaSeverity severity : AvaticaSeverity.values()) {
+      assertEquals(severity, AvaticaSeverity.fromProto(severity.toProto()));
+    }
+  }
+
+}
+
+// End AvaticaSeverityTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSqlExceptionTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSqlExceptionTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSqlExceptionTest.java
new file mode 100644
index 0000000..3d7b5b0
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaSqlExceptionTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.AvaticaSqlException;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link AvaticaSqlException}.
+ */
+public class AvaticaSqlExceptionTest {
+
+  @Test public void testGetters() {
+    final String msg = "My query failed!";
+    final int code = 42;
+    final String sql = "SELECT foo FROM bar;";
+    final String stacktrace = "My Stack Trace";
+    final String server = "localhost:8765";
+
+    AvaticaSqlException e = new AvaticaSqlException(msg, sql, code, Arrays.asList(stacktrace),
+        server);
+    assertTrue(e.getMessage().contains(msg));
+    assertEquals(code, e.getErrorCode());
+    assertEquals(sql, e.getSQLState());
+    assertEquals(1, e.getStackTraces().size());
+    assertEquals(stacktrace, e.getStackTraces().get(0));
+    assertEquals(server, e.getRemoteServer());
+  }
+
+}
+
+// End AvaticaSqlExceptionTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
new file mode 100644
index 0000000..850cbfd
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+
+import org.junit.Test;
+
+import java.math.BigInteger;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit test for Avatica utilities.
+ */
+public class AvaticaUtilsTest {
+  @Test public void testInstantiatePlugin() {
+    final String s =
+        AvaticaUtils.instantiatePlugin(String.class, "java.lang.String");
+    assertThat(s, is(""));
+
+    // No default constructor or INSTANCE member
+    try {
+      final Integer i =
+          AvaticaUtils.instantiatePlugin(Integer.class, "java.lang.Integer");
+      fail("expected error, got " + i);
+    } catch (Throwable e) {
+      assertThat(e.getMessage(),
+          is("Property 'java.lang.Integer' not valid for plugin type java.lang.Integer"));
+    }
+
+    final BigInteger b =
+        AvaticaUtils.instantiatePlugin(BigInteger.class, "java.math.BigInteger#ONE");
+    assertThat(b, is(BigInteger.ONE));
+
+    try {
+      final BigInteger b2 =
+          AvaticaUtils.instantiatePlugin(BigInteger.class,
+              "java.math.BigInteger.ONE");
+      fail("expected error, got " + b2);
+    } catch (Throwable e) {
+      assertThat(e.getMessage(),
+          is("Property 'java.math.BigInteger.ONE' not valid for plugin type java.math.BigInteger"));
+    }
+  }
+
+  /** Unit test for
+   * {@link org.apache.calcite.avatica.AvaticaUtils#unique(java.lang.String)}. */
+  @Test public void testUnique() {
+    // Below, the "probably" comments indicate the strings that will be
+    // generated the first time you run the test.
+    final Set<String> list = new LinkedHashSet<>();
+    list.add(AvaticaUtils.unique("a")); // probably "a"
+    assertThat(list.size(), is(1));
+    list.add(AvaticaUtils.unique("a")); // probably "a_1"
+    assertThat(list.size(), is(2));
+    list.add(AvaticaUtils.unique("b")); // probably "b"
+    assertThat(list.size(), is(3));
+    list.add(AvaticaUtils.unique("a_1")); // probably "a_1_3"
+    assertThat(list.size(), is(4));
+    list.add(AvaticaUtils.unique("A")); // probably "A"
+    assertThat(list.size(), is(5));
+    list.add(AvaticaUtils.unique("a")); // probably "a_5"
+    assertThat(list.size(), is(6));
+  }
+}
+
+// End AvaticaUtilsTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/ConnectStringParserTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/ConnectStringParserTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/ConnectStringParserTest.java
new file mode 100644
index 0000000..cdc8d8a
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/ConnectStringParserTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.ConnectStringParser;
+
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit test for JDBC connect string parser, {@link ConnectStringParser}. The
+ * ConnectStringParser is adapted from code in Mondrian, but most of the tests
+ * below were unfortunately "reinvented" prior to having the Mondrian unit tests
+ * in hand.
+ */
+public class ConnectStringParserTest {
+  /**
+   * Tests simple connect string. Adapted from Mondrian tests.
+   */
+  @Test public void testSimpleStrings() throws Throwable {
+    Properties props = ConnectStringParser.parse("foo=x;bar=y;foo=z");
+    assertEquals(
+        "bar",
+        "y",
+        props.get("bar"));
+    assertNull(
+        "BAR",
+        props.get("BAR")); // case-sensitive, unlike Mondrian
+    assertEquals(
+        "last foo",
+        "z",
+        props.get("foo"));
+    assertNull(
+        "key=\" bar\"",
+        props.get(" bar"));
+    assertNull(
+        "bogus key",
+        props.get("kipper"));
+    assertEquals(
+        "param count",
+        2,
+        props.size());
+
+    String synth = ConnectStringParser.getParamString(props);
+    Properties synthProps = ConnectStringParser.parse(synth);
+    assertEquals("reversible", props, synthProps);
+  }
+
+  /**
+   * Tests complex connect strings. Adapted directly from Mondrian tests.
+   */
+  @Test public void testComplexStrings() throws Throwable {
+    Properties props =
+        ConnectStringParser.parse("normalProp=value;"
+            + "emptyValue=;"
+            + " spaceBeforeProp=abc;"
+            + " spaceBeforeAndAfterProp =def;"
+            + " space in prop = foo bar ;"
+            + "equalsInValue=foo=bar;"
+            + "semiInProp;Name=value;"
+            + " singleQuotedValue = 'single quoted value ending in space ' ;"
+            + " doubleQuotedValue = "
+            + "\"=double quoted value preceded by equals\" ;"
+            + " singleQuotedValueWithSemi = 'one; two';"
+            + " singleQuotedValueWithSpecials = 'one; two \"three''four=five'");
+
+    assertEquals(
+        "param count",
+        11,
+        props.size());
+
+    String value;
+    value = (String) props.get("normalProp");
+    assertEquals("value", value);
+    value = (String) props.get("emptyValue");
+    assertEquals("", value); // empty string, not null!
+    value = (String) props.get("spaceBeforeProp");
+    assertEquals("abc", value);
+    value = (String) props.get("spaceBeforeAndAfterProp");
+    assertEquals("def", value);
+    value = (String) props.get("space in prop");
+    assertEquals(value, "foo bar");
+    value = (String) props.get("equalsInValue");
+    assertEquals("foo=bar", value);
+    value = (String) props.get("semiInProp;Name");
+    assertEquals("value", value);
+    value = (String) props.get("singleQuotedValue");
+    assertEquals("single quoted value ending in space ", value);
+    value = (String) props.get("doubleQuotedValue");
+    assertEquals("=double quoted value preceded by equals", value);
+    value = (String) props.get("singleQuotedValueWithSemi");
+    assertEquals(value, "one; two");
+    value = (String) props.get("singleQuotedValueWithSpecials");
+    assertEquals(value, "one; two \"three'four=five");
+  }
+
+  /**
+   * Tests for specific errors thrown by the parser.
+   */
+  @Test public void testConnectStringErrors() throws Throwable {
+    // force some parsing errors
+    try {
+      ConnectStringParser.parse("key='can't parse'");
+      fail("quoted value ended too soon");
+    } catch (SQLException e) {
+      assertExceptionMatches(e, ".*quoted value ended.*position 9.*");
+    }
+
+    try {
+      ConnectStringParser.parse("key='\"can''t parse\"");
+      fail("unterminated quoted value");
+    } catch (SQLException e) {
+      assertExceptionMatches(e, ".*unterminated quoted value.*");
+    }
+  }
+
+  /**
+   * Tests most of the examples from the <a
+   * href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/oledb/htm/oledbconnectionstringsyntax.asp">
+   * OLE DB spec</a>. Omitted are cases for Window handles, returning multiple
+   * values, and special handling of "Provider" keyword.
+   */
+  @Test public void testOleDbExamples() throws Throwable {
+    // test the parser with examples from OLE DB documentation
+    Quad[] quads = {
+      // {reason for test, key, val, string to parse},
+      new Quad(
+          "printable chars",
+          "Jet OLE DB:System Database", "c:\\system.mda",
+          "Jet OLE DB:System Database=c:\\system.mda"),
+      new Quad(
+          "key embedded semi",
+          "Authentication;Info", "Column 5",
+          "Authentication;Info=Column 5"),
+      new Quad(
+          "key embedded equal",
+          "Verification=Security", "True",
+          "Verification==Security=True"),
+      new Quad(
+          "key many equals",
+          "Many==One", "Valid",
+          "Many====One=Valid"),
+      new Quad(
+          "key too many equal",
+          "TooMany=", "False",
+          "TooMany===False"),
+      new Quad(
+          "value embedded quote and semi",
+          "ExtProps", "Data Source='localhost';Key Two='value 2'",
+          "ExtProps=\"Data Source='localhost';Key Two='value 2'\""),
+      new Quad(
+          "value embedded double quote and semi",
+          "ExtProps", "Integrated Security=\"SSPI\";Key Two=\"value 2\"",
+          "ExtProps='Integrated Security=\"SSPI\";Key Two=\"value 2\"'"),
+      new Quad(
+          "value double quoted",
+          "DataSchema", "\"MyCustTable\"",
+          "DataSchema='\"MyCustTable\"'"),
+      new Quad(
+          "value single quoted",
+          "DataSchema", "'MyCustTable'",
+          "DataSchema=\"'MyCustTable'\""),
+      new Quad(
+          "value double quoted double trouble",
+          "Caption", "\"Company's \"new\" customer\"",
+          "Caption=\"\"\"Company's \"\"new\"\" customer\"\"\""),
+      new Quad(
+          "value single quoted double trouble",
+          "Caption", "\"Company's \"new\" customer\"",
+          "Caption='\"Company''s \"new\" customer\"'"),
+      new Quad(
+          "embedded blanks and trim",
+          "My Keyword", "My Value",
+          " My Keyword = My Value ;MyNextValue=Value"),
+      new Quad(
+          "value single quotes preserve blanks",
+          "My Keyword", " My Value ",
+          " My Keyword =' My Value ';MyNextValue=Value"),
+      new Quad(
+          "value double quotes preserve blanks",
+          "My Keyword", " My Value ",
+          " My Keyword =\" My Value \";MyNextValue=Value"),
+      new Quad(
+          "last redundant key wins",
+          "SomeKey", "NextValue",
+          "SomeKey=FirstValue;SomeKey=NextValue"),
+    };
+    for (Quad quad : quads) {
+      Properties props = ConnectStringParser.parse(quad.str);
+
+      assertEquals(quad.why, quad.val, props.get(quad.key));
+      String synth = ConnectStringParser.getParamString(props);
+
+      try {
+        assertEquals("reversible " + quad.why, quad.str, synth);
+      } catch (Throwable e) {
+        // it's OK that the strings don't match as long as the
+        // two strings parse out the same way and are thus
+        // "semantically reversible"
+        Properties synthProps = ConnectStringParser.parse(synth);
+        assertEquals("equivalent " + quad.why, props, synthProps);
+      }
+    }
+  }
+
+  static void assertExceptionMatches(
+      Throwable e,
+      String expectedPattern) {
+    if (e == null) {
+      fail("Expected an error which matches pattern '" + expectedPattern + "'");
+    }
+    String msg = e.toString();
+    if (!msg.matches(expectedPattern)) {
+      fail("Got a different error '" + msg + "' than expected '"
+          + expectedPattern + "'");
+    }
+  }
+
+  /** Collection of values comprising a test. */
+  static class Quad {
+    private final String why;
+    private final String key;
+    private final String val;
+    private final String str;
+
+    Quad(String why, String key, String val, String str) {
+      this.why = why;
+      this.key = key;
+      this.val = val;
+      this.str = str;
+    }
+  }
+}
+
+// End ConnectStringParserTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
new file mode 100644
index 0000000..57cf60a
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.test;
+
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.Meta.CursorFactory;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.remote.JsonHandler;
+import org.apache.calcite.avatica.remote.JsonService;
+import org.apache.calcite.avatica.remote.LocalJsonService;
+import org.apache.calcite.avatica.remote.Service;
+import org.apache.calcite.avatica.remote.TypedValue;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests JSON encoding/decoding in the remote service.
+ */
+public class JsonHandlerTest {
+
+  private static final Random RANDOM = new Random();
+
+  /**
+   * Implementation of {@link org.apache.calcite.avatica.remote.Service}
+   * that does nothing.
+   */
+  public static class NoopService implements Service {
+    @Override public ResultSetResponse apply(CatalogsRequest request) {
+      return null;
+    }
+
+    @Override public ResultSetResponse apply(SchemasRequest request) {
+      return null;
+    }
+
+    @Override public ResultSetResponse apply(TablesRequest request) {
+      return null;
+    }
+
+    @Override public ResultSetResponse apply(TableTypesRequest request) {
+      return null;
+    }
+
+    @Override public ResultSetResponse apply(TypeInfoRequest request) {
+      return null;
+    }
+
+    @Override public ResultSetResponse apply(ColumnsRequest request) {
+      return null;
+    }
+
+    @Override public PrepareResponse apply(PrepareRequest request) {
+      return null;
+    }
+
+    @Override public ExecuteResponse apply(PrepareAndExecuteRequest request) {
+      return null;
+    }
+
+    @Override public FetchResponse apply(FetchRequest request) {
+      return null;
+    }
+
+    @Override public CreateStatementResponse apply(CreateStatementRequest request) {
+      return null;
+    }
+
+    @Override public CloseStatementResponse apply(CloseStatementRequest request) {
+      return null;
+    }
+
+    @Override public OpenConnectionResponse apply(OpenConnectionRequest request) {
+      return null;
+    }
+
+    @Override public CloseConnectionResponse apply(CloseConnectionRequest request) {
+      return null;
+    }
+
+    @Override public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
+      return null;
+    }
+
+    @Override public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
+      return null;
+    }
+
+    @Override public SyncResultsResponse apply(SyncResultsRequest request) {
+      return null;
+    }
+
+    @Override public ExecuteResponse apply(ExecuteRequest request) {
+      return null;
+    }
+
+    @Override public void setRpcMetadata(RpcMetadataResponse metadata) {}
+
+    @Override public CommitResponse apply(CommitRequest request) {
+      return null;
+    }
+
+    @Override public RollbackResponse apply(RollbackRequest request) {
+      return null;
+    }
+  }
+
+  /**
+   * Instrumented subclass of {@link org.apache.calcite.avatica.test.JsonHandlerTest.NoopService}
+   * that checks the parameter values passed to the "execute" request.
+   *
+   * <p>Note: parameter values for "fetch" request deprecated.
+   */
+  public static class ParameterValuesCheckingService extends NoopService {
+
+    final List<TypedValue> expectedParameterValues;
+
+    public ParameterValuesCheckingService(List<TypedValue> epv) {
+      expectedParameterValues = epv;
+    }
+
+    @Override public ExecuteResponse apply(ExecuteRequest request) {
+      expectedParameterValues.addAll(request.parameterValues);
+
+      final Meta.Signature signature =
+          new Meta.Signature(Collections.<ColumnMetaData>emptyList(),
+              "SELECT 1 FROM VALUE()",
+              Collections.<AvaticaParameter>emptyList(),
+              Collections.<String, Object>emptyMap(),
+              CursorFactory.LIST, Meta.StatementType.SELECT);
+
+      final Service.ResultSetResponse resultSetResponse =
+          new Service.ResultSetResponse(UUID.randomUUID().toString(),
+              RANDOM.nextInt(), false, signature, Meta.Frame.EMPTY, -1L, null);
+
+      return new Service.ExecuteResponse(
+          Collections.singletonList(resultSetResponse), false, null);
+    }
+  }
+
+  @Test public void testExecuteRequestWithNumberParameter() {
+    final List<TypedValue> expectedParameterValues = new ArrayList<>();
+    final Service service = new ParameterValuesCheckingService(expectedParameterValues);
+    final JsonService jsonService = new LocalJsonService(service);
+    final JsonHandler jsonHandler = new JsonHandler(jsonService, NoopMetricsSystem.getInstance());
+
+    final List<TypedValue> parameterValues = Arrays.asList(
+        TypedValue.create("NUMBER", new BigDecimal("123")),
+        TypedValue.create("STRING", "calcite"));
+
+    jsonHandler.apply(
+        "{'request':'execute',"
+        + "'parameterValues':[{'type':'NUMBER','value':123},"
+        + "{'type':'STRING','value':'calcite'}]}");
+    assertThat(expectedParameterValues.size(), is(2));
+    assertThat(expectedParameterValues.get(0), is(parameterValues.get(0)));
+    assertThat(expectedParameterValues.get(1), is(parameterValues.get(1)));
+  }
+}
+
+// End JsonHandlerTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/test/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/package-info.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/package-info.java
new file mode 100644
index 0000000..501bb9f
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Avatica tests.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.test;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/util/NumberAccessorTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/util/NumberAccessorTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/util/NumberAccessorTest.java
new file mode 100644
index 0000000..4f8e51f
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/util/NumberAccessorTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util;
+
+import org.apache.calcite.avatica.util.AbstractCursor.Getter;
+import org.apache.calcite.avatica.util.AbstractCursor.NumberAccessor;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test logic for the NumberAccessor.
+ */
+public class NumberAccessorTest {
+
+  @Test
+  public void testBigDecimalZeroScale() {
+    final BigDecimal orig = new BigDecimal(BigInteger.valueOf(137L), 1);
+    NumberAccessor accessor = new AbstractCursor.NumberAccessor(
+        new Getter() {
+          @Override public Object getObject() {
+            return orig;
+          }
+
+          @Override public boolean wasNull() {
+            return false;
+          }
+        },
+        0);
+
+    assertEquals(orig, accessor.getBigDecimal(0));
+  }
+
+}
+
+// End NumberAccessorTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/test/java/org/apache/calcite/avatica/util/UnsynchronizedBufferTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/util/UnsynchronizedBufferTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/util/UnsynchronizedBufferTest.java
new file mode 100644
index 0000000..a448d3e
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/util/UnsynchronizedBufferTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for the UnsynchronizedBuffer.
+ */
+public class UnsynchronizedBufferTest {
+
+  @Test public void testArrayResizing() {
+    int size = 64;
+    int expected = 128;
+    for (int i = 0; i < 10; i++) {
+      // We keep being one byte short to contain this message
+      int next = UnsynchronizedBuffer.nextArraySize(size + 1);
+      assertEquals(expected, next);
+      size = next;
+      expected *= 2;
+    }
+  }
+}
+
+// End UnsynchronizedBufferTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/pom.xml b/avatica/metrics-dropwizardmetrics3/pom.xml
new file mode 100644
index 0000000..4966c5b
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica-parent</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>calcite-avatica-metrics-dropwizardmetrics3</artifactId>
+  <packaging>jar</packaging>
+  <name>Calcite Avatica Dropwizard Metrics 3</name>
+  <description>An implementation of Avatica Metrics using Dropwizard Metrics.</description>
+
+  <properties>
+    <top.dir>${project.basedir}/..</top.dir>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.calcite</groupId>
+      <artifactId>calcite-avatica-metrics</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.dropwizard.metrics</groupId>
+      <artifactId>metrics-core</artifactId>
+      <!-- Avoid specifying version in dependencyManagement in support of other avatica-metrics impls -->
+      <version>${dropwizard-metrics3.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <versionRange>[2.12.1,)</versionRange>
+                    <goals>
+                      <goal>check</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <!-- Parent module has the same plugin and does the work of
+           generating -sources.jar for each project. But without the
+           plugin declared here, IDEs don't know the sources are
+           available. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>non-root-resources</id>
+            <goals>
+              <goal>process</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
new file mode 100644
index 0000000..4204ebf
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounter.java
@@ -0,0 +1,51 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Counter;
+
+import java.util.Objects;
+
+/**
+ * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Counter}.
+ */
+public class DropwizardCounter implements org.apache.calcite.avatica.metrics.Counter {
+
+  private final Counter counter;
+
+  public DropwizardCounter(Counter counter) {
+    this.counter = Objects.requireNonNull(counter);
+  }
+
+  @Override public void increment() {
+    this.counter.inc();
+  }
+
+  @Override public void increment(long n) {
+    this.counter.inc(n);
+  }
+
+  @Override public void decrement() {
+    this.counter.dec();
+  }
+
+  @Override public void decrement(long n) {
+    this.counter.dec(n);
+  }
+}
+
+// End DropwizardCounter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
new file mode 100644
index 0000000..5f4b776
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGauge.java
@@ -0,0 +1,39 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Gauge;
+
+/**
+ * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Gauge}.
+ *
+ * @param <T> The value the gauge returns.
+ */
+public class DropwizardGauge<T> implements Gauge<T> {
+
+  private final org.apache.calcite.avatica.metrics.Gauge<T> gauge;
+
+  public DropwizardGauge(org.apache.calcite.avatica.metrics.Gauge<T> gauge) {
+    this.gauge = gauge;
+  }
+
+  @Override public T getValue() {
+    return gauge.getValue();
+  }
+}
+
+// End DropwizardGauge.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
new file mode 100644
index 0000000..266f130
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogram.java
@@ -0,0 +1,43 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Histogram;
+
+import java.util.Objects;
+
+/**
+ * Dropwizard metrics implementation of {@link org.apache.calcite.avatica.metrics.Histogram}.
+ */
+public class DropwizardHistogram implements org.apache.calcite.avatica.metrics.Histogram {
+
+  private final Histogram histogram;
+
+  public DropwizardHistogram(Histogram histogram) {
+    this.histogram = Objects.requireNonNull(histogram);
+  }
+
+  @Override public void update(int value) {
+    histogram.update(value);
+  }
+
+  @Override public void update(long value) {
+    histogram.update(value);
+  }
+}
+
+// End DropwizardHistogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
new file mode 100644
index 0000000..ab8fafc
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Meter;
+
+import java.util.Objects;
+
+/**
+ * Dropwizard metrics implementation of {@link org.apache.calcite.avatica.metrics.Meter}.
+ */
+public class DropwizardMeter implements org.apache.calcite.avatica.metrics.Meter {
+
+  private final Meter meter;
+
+  public DropwizardMeter(Meter meter) {
+    this.meter = Objects.requireNonNull(meter);
+  }
+
+  @Override public void mark() {
+    this.meter.mark();
+  }
+
+  @Override public void mark(long count) {
+    this.meter.mark(count);
+  }
+}
+
+// End DropwizardMeter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
new file mode 100644
index 0000000..6aa71b9
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystem.java
@@ -0,0 +1,62 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.Counter;
+import org.apache.calcite.avatica.metrics.Gauge;
+import org.apache.calcite.avatica.metrics.Histogram;
+import org.apache.calcite.avatica.metrics.Meter;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+
+import com.codahale.metrics.MetricRegistry;
+
+import java.util.Objects;
+
+/**
+ * Dropwizard Metrics implementation of {@link MetricsSystem}.
+ */
+public class DropwizardMetricsSystem implements MetricsSystem {
+
+  private final MetricRegistry registry;
+
+  public DropwizardMetricsSystem(MetricRegistry registry) {
+    this.registry = Objects.requireNonNull(registry);
+  }
+
+  @Override public Timer getTimer(String name) {
+    return new DropwizardTimer(registry.timer(name));
+  }
+
+  @Override public Histogram getHistogram(String name) {
+    return new DropwizardHistogram(registry.histogram(name));
+  }
+
+  @Override public Meter getMeter(String name) {
+    return new DropwizardMeter(registry.meter(name));
+  }
+
+  @Override public Counter getCounter(String name) {
+    return new DropwizardCounter(registry.counter(name));
+  }
+
+  @Override public <T> void register(String name, Gauge<T> gauge) {
+    registry.register(name, new DropwizardGauge<T>(gauge));
+  }
+}
+
+// End DropwizardMetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
new file mode 100644
index 0000000..f4c9234
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
+
+import com.codahale.metrics.MetricRegistry;
+
+import java.util.Objects;
+
+/**
+ * A container which provides a {@link MetricRegistry} to a {@link DropwizardMetricsSystem}.
+ */
+public class DropwizardMetricsSystemConfiguration implements
+    MetricsSystemConfiguration<MetricRegistry> {
+
+  private final MetricRegistry registry;
+
+  public DropwizardMetricsSystemConfiguration(MetricRegistry registry) {
+    this.registry = Objects.requireNonNull(registry);
+  }
+
+  @Override public MetricRegistry get() {
+    return registry;
+  }
+}
+
+// End DropwizardMetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
new file mode 100644
index 0000000..1480db6
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
+import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
+
+/**
+ * A {@link MetricsSystemFactory} for {@link DropwizardMetricsSystem}.
+ */
+public class DropwizardMetricsSystemFactory implements MetricsSystemFactory {
+
+  @Override public DropwizardMetricsSystem create(MetricsSystemConfiguration<?> config) {
+    // Verify we got configuration this factory can use
+    if (config instanceof DropwizardMetricsSystemConfiguration) {
+      DropwizardMetricsSystemConfiguration typedConfig =
+          (DropwizardMetricsSystemConfiguration) config;
+
+      return new DropwizardMetricsSystem(typedConfig.get());
+    }
+
+    throw new IllegalStateException("Expected instance of "
+        + DropwizardMetricsSystemConfiguration.class.getName() + " but got "
+        + (null == config ? "null" : config.getClass().getName()));
+  }
+}
+
+// End DropwizardMetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
new file mode 100644
index 0000000..850f9a6
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Timer;
+
+import java.util.Objects;
+
+/**
+ * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Timer}.
+ */
+public class DropwizardTimer implements org.apache.calcite.avatica.metrics.Timer {
+
+  private final Timer timer;
+
+  public DropwizardTimer(Timer timer) {
+    this.timer = Objects.requireNonNull(timer);
+  }
+
+  @Override public DropwizardContext start() {
+    return new DropwizardContext(timer.time());
+  }
+
+  /**
+   * Dropwizard Metrics implementation of {@link org.apache.calcite.avatica.metrics.Timer.Context}
+   */
+  public class DropwizardContext implements org.apache.calcite.avatica.metrics.Timer.Context {
+    private final com.codahale.metrics.Timer.Context context;
+
+    public DropwizardContext(com.codahale.metrics.Timer.Context context) {
+      this.context = Objects.requireNonNull(context);
+    }
+
+    @Override public void close() {
+      this.context.stop();
+    }
+  }
+}
+
+// End DropwizardTimer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
new file mode 100644
index 0000000..f88df93
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/java/org/apache/calcite/avatica/metrics/dropwizard3/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Dropwizard-Metrics (v3) implementation of the Avatica Metrics framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory b/avatica/metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
new file mode 100644
index 0000000..25b64a8
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory
@@ -0,0 +1,2 @@
+org.apache.calcite.avatica.metrics.dropwizard3.DropwizardMetricsSystemFactory
+


[45/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
new file mode 100644
index 0000000..b57f36c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
@@ -0,0 +1,1416 @@
+/*
+ * 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.AvaticaConnection.CallableWithoutException;
+import org.apache.calcite.avatica.remote.MetaDataOperation;
+import org.apache.calcite.avatica.util.Casing;
+import org.apache.calcite.avatica.util.Quoting;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.calcite.avatica.InternalProperty.CASE_SENSITIVE;
+import static org.apache.calcite.avatica.InternalProperty.NULL_SORTING;
+import static org.apache.calcite.avatica.InternalProperty.NullSorting;
+import static org.apache.calcite.avatica.InternalProperty.QUOTED_CASING;
+import static org.apache.calcite.avatica.InternalProperty.QUOTING;
+import static org.apache.calcite.avatica.InternalProperty.UNQUOTED_CASING;
+
+/**
+ * Implementation of {@link java.sql.DatabaseMetaData}
+ * for the Avatica engine.
+ *
+ * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
+ * it is instantiated using {@link AvaticaFactory#newDatabaseMetaData}.</p>
+ */
+public class AvaticaDatabaseMetaData implements DatabaseMetaData {
+  private final AvaticaConnection connection;
+
+  protected  AvaticaDatabaseMetaData(AvaticaConnection connection) {
+    this.connection = connection;
+  }
+
+  // Helper methods
+
+  private NullSorting nullSorting() {
+    return NULL_SORTING.getEnum(getProperties(), NullSorting.class);
+  }
+
+  private Quoting quoting() {
+    return QUOTING.getEnum(getProperties(), Quoting.class);
+  }
+
+  private Casing unquotedCasing() {
+    return UNQUOTED_CASING.getEnum(getProperties(), Casing.class);
+  }
+
+  private Casing quotedCasing() {
+    return QUOTED_CASING.getEnum(getProperties(), Casing.class);
+  }
+
+  private boolean caseSensitive() {
+    return CASE_SENSITIVE.getBoolean(getProperties());
+  }
+
+  // JDBC methods
+
+  public boolean allProceduresAreCallable() throws SQLException {
+    return true;
+  }
+
+  public boolean allTablesAreSelectable() throws SQLException {
+    return true;
+  }
+
+  public String getURL() throws SQLException {
+    return connection.url;
+  }
+
+  public String getUserName() throws SQLException {
+    return connection.info.getProperty("user");
+  }
+
+  public boolean isReadOnly() throws SQLException {
+    return true;
+  }
+
+  public boolean nullsAreSortedHigh() throws SQLException {
+    return nullSorting() == NullSorting.HIGH;
+  }
+
+  public boolean nullsAreSortedLow() throws SQLException {
+    return nullSorting() == NullSorting.LOW;
+  }
+
+  public boolean nullsAreSortedAtStart() throws SQLException {
+    return nullSorting() == NullSorting.START;
+  }
+
+  public boolean nullsAreSortedAtEnd() throws SQLException {
+    return nullSorting() == NullSorting.END;
+  }
+
+  public String getDatabaseProductName() throws SQLException {
+    return connection.driver.version.productName;
+  }
+
+  public String getDatabaseProductVersion() throws SQLException {
+    return connection.driver.version.productVersion;
+  }
+
+  public String getDriverName() throws SQLException {
+    return connection.driver.version.name;
+  }
+
+  public String getDriverVersion() throws SQLException {
+    return connection.driver.version.versionString;
+  }
+
+  public int getDriverMajorVersion() {
+    return connection.driver.getMajorVersion();
+  }
+
+  public int getDriverMinorVersion() {
+    return connection.driver.getMinorVersion();
+  }
+
+  public boolean usesLocalFiles() throws SQLException {
+    return false;
+  }
+
+  public boolean usesLocalFilePerTable() throws SQLException {
+    return false;
+  }
+
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return !caseSensitive() && unquotedCasing() == Casing.UNCHANGED;
+  }
+
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return caseSensitive() && unquotedCasing() == Casing.UNCHANGED;
+  }
+
+  public boolean storesUpperCaseIdentifiers() throws SQLException {
+    return unquotedCasing() == Casing.TO_UPPER;
+  }
+
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return unquotedCasing() == Casing.TO_LOWER;
+  }
+
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return !caseSensitive() && quotedCasing() == Casing.UNCHANGED;
+  }
+
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return caseSensitive() && quotedCasing() == Casing.UNCHANGED;
+  }
+
+  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    return quotedCasing() == Casing.TO_UPPER;
+  }
+
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return quotedCasing() == Casing.TO_LOWER;
+  }
+
+  public String getIdentifierQuoteString() throws SQLException {
+    return quoting().string;
+  }
+
+  private Map<InternalProperty, Object> getProperties() {
+    return connection.properties;
+  }
+
+  public String getSQLKeywords() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<String>() {
+          public String call() {
+            return Meta.DatabaseProperty.GET_S_Q_L_KEYWORDS
+                .getProp(connection.meta, connection.handle, String.class);
+          }
+        });
+  }
+
+  public String getNumericFunctions() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<String>() {
+          public String call() {
+            return Meta.DatabaseProperty.GET_NUMERIC_FUNCTIONS
+                .getProp(connection.meta, connection.handle, String.class);
+          }
+        });
+  }
+
+  public String getStringFunctions() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<String>() {
+          public String call() {
+            return Meta.DatabaseProperty.GET_STRING_FUNCTIONS
+                .getProp(connection.meta, connection.handle, String.class);
+          }
+        });
+  }
+
+  public String getSystemFunctions() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<String>() {
+          public String call() {
+            return Meta.DatabaseProperty.GET_SYSTEM_FUNCTIONS
+                .getProp(connection.meta, connection.handle, String.class);
+          }
+        });
+  }
+
+  public String getTimeDateFunctions() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<String>() {
+          public String call() {
+            return Meta.DatabaseProperty.GET_TIME_DATE_FUNCTIONS
+                .getProp(connection.meta, connection.handle, String.class);
+          }
+        });
+  }
+
+  public String getSearchStringEscape() throws SQLException {
+    return "\\";
+  }
+
+  public String getExtraNameCharacters() throws SQLException {
+    return "";
+  }
+
+  public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsColumnAliasing() throws SQLException {
+    return true;
+  }
+
+  public boolean nullPlusNonNullIsNull() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsConvert() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsConvert(int fromType, int toType) throws SQLException {
+    return false; // TODO: more detail
+  }
+
+  public boolean supportsTableCorrelationNames() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsExpressionsInOrderBy() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsOrderByUnrelated() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsGroupBy() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsGroupByUnrelated() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsGroupByBeyondSelect() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsLikeEscapeClause() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsMultipleResultSets() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsMultipleTransactions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsNonNullableColumns() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsMinimumSQLGrammar() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsCoreSQLGrammar() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsExtendedSQLGrammar() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsANSI92FullSQL() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsOuterJoins() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsFullOuterJoins() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsLimitedOuterJoins() throws SQLException {
+    return true;
+  }
+
+  public String getSchemaTerm() throws SQLException {
+    return "schema";
+  }
+
+  public String getProcedureTerm() throws SQLException {
+    return "procedure";
+  }
+
+  public String getCatalogTerm() throws SQLException {
+    return "catalog";
+  }
+
+  public boolean isCatalogAtStart() throws SQLException {
+    return true;
+  }
+
+  public String getCatalogSeparator() throws SQLException {
+    return ".";
+  }
+
+  public boolean supportsSchemasInDataManipulation() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    return true; // except that we don't support index definitions
+  }
+
+  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    return true; // except that we don't support privilege definitions
+  }
+
+  public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    return true; // except that we don't support index definitions
+  }
+
+  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    return true; // except that we don't support privilege definitions
+  }
+
+  public boolean supportsPositionedDelete() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsPositionedUpdate() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSelectForUpdate() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsStoredProcedures() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSubqueriesInComparisons() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInExists() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInIns() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCorrelatedSubqueries() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsUnion() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsUnionAll() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  public int getMaxBinaryLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxCharLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnsInGroupBy() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnsInIndex() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnsInOrderBy() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnsInSelect() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxColumnsInTable() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxConnections() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxCursorNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxIndexLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxSchemaNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxProcedureNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxCatalogNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxRowSize() throws SQLException {
+    return 0;
+  }
+
+  public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+    return false;
+  }
+
+  public int getMaxStatementLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxStatements() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxTableNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxTablesInSelect() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxUserNameLength() throws SQLException {
+    return 0;
+  }
+
+  public int getDefaultTransactionIsolation() throws SQLException {
+    return connection.invokeWithRetries(
+        new CallableWithoutException<Integer>() {
+          public Integer call() {
+            return Meta.DatabaseProperty.GET_DEFAULT_TRANSACTION_ISOLATION
+                .getProp(connection.meta, connection.handle, Integer.class);
+          }
+        });
+  }
+
+  public boolean supportsTransactions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsTransactionIsolationLevel(int level)
+      throws SQLException {
+    return level == Connection.TRANSACTION_NONE;
+  }
+
+  public boolean supportsDataDefinitionAndDataManipulationTransactions()
+      throws SQLException {
+    return false;
+  }
+
+  public boolean supportsDataManipulationTransactionsOnly()
+      throws SQLException {
+    return true;
+  }
+
+  public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+    return true;
+  }
+
+  public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+    return false;
+  }
+
+  public ResultSet getProcedures(
+      final String catalog,
+      final String schemaPattern,
+      final String procedureNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getProcedures(connection.handle, catalog, pat(schemaPattern),
+                        pat(procedureNamePattern)),
+                    new QueryState(MetaDataOperation.GET_PROCEDURES, catalog, schemaPattern,
+                        procedureNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getProcedureColumns(
+      final String catalog,
+      final String schemaPattern,
+      final String procedureNamePattern,
+      final String columnNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getProcedureColumns(connection.handle, catalog,
+                        pat(schemaPattern), pat(procedureNamePattern), pat(columnNamePattern)),
+                    new QueryState(MetaDataOperation.GET_PROCEDURE_COLUMNS, catalog, schemaPattern,
+                        procedureNamePattern, columnNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getTables(
+      final String catalog,
+      final String schemaPattern,
+      final String tableNamePattern,
+      final String[] types) throws SQLException {
+    final List<String> typeList = types == null ? null : Arrays.asList(types);
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getTables(connection.handle, catalog, pat(schemaPattern),
+                        pat(tableNamePattern), typeList),
+                    new QueryState(MetaDataOperation.GET_TABLES, catalog, schemaPattern,
+                        tableNamePattern, types));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  private static Meta.Pat pat(String schemaPattern) {
+    return Meta.Pat.of(schemaPattern);
+  }
+
+  public ResultSet getSchemas(
+      final String catalog, final String schemaPattern) throws SQLException {
+    // TODO: add a 'catch ... throw new SQLException' logic to this and other
+    // getXxx methods. Right now any error will throw a RuntimeException
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getSchemas(connection.handle, catalog, pat(schemaPattern)),
+                    new QueryState(MetaDataOperation.GET_SCHEMAS_WITH_ARGS, catalog,
+                        schemaPattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getSchemas() throws SQLException {
+    return getSchemas(null, null);
+  }
+
+  public ResultSet getCatalogs() throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(connection.meta.getCatalogs(connection.handle),
+                    new QueryState(MetaDataOperation.GET_CATALOGS));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getTableTypes() throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(connection.meta.getTableTypes(connection.handle),
+                    new QueryState(MetaDataOperation.GET_TABLE_TYPES));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getColumns(
+      final String catalog,
+      final String schemaPattern,
+      final String tableNamePattern,
+      final String columnNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getColumns(connection.handle, catalog, pat(schemaPattern),
+                        pat(tableNamePattern), pat(columnNamePattern)),
+                    new QueryState(MetaDataOperation.GET_COLUMNS, catalog, schemaPattern,
+                        tableNamePattern, columnNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getColumnPrivileges(
+      final String catalog,
+      final String schema,
+      final String table,
+      final String columnNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getColumnPrivileges(connection.handle, catalog, schema, table,
+                        pat(columnNamePattern)),
+                    new QueryState(MetaDataOperation.GET_COLUMN_PRIVILEGES, catalog, schema, table,
+                        columnNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getTablePrivileges(
+      final String catalog,
+      final String schemaPattern,
+      final String tableNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getTablePrivileges(connection.handle, catalog,
+                        pat(schemaPattern), pat(tableNamePattern)),
+                    new QueryState(MetaDataOperation.GET_TABLE_PRIVILEGES, catalog, schemaPattern,
+                        tableNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getBestRowIdentifier(
+      final String catalog,
+      final String schema,
+      final String table,
+      final int scope,
+      final boolean nullable) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getBestRowIdentifier(connection.handle, catalog, schema, table,
+                        scope, nullable),
+                    new QueryState(MetaDataOperation.GET_BEST_ROW_IDENTIFIER, catalog, table, scope,
+                        nullable));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getVersionColumns(
+      final String catalog, final String schema, final String table) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getVersionColumns(connection.handle, catalog, schema, table),
+                    new QueryState(MetaDataOperation.GET_VERSION_COLUMNS, catalog, schema, table));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getPrimaryKeys(
+      final String catalog, final String schema, final String table) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getPrimaryKeys(connection.handle, catalog, schema, table),
+                    new QueryState(MetaDataOperation.GET_PRIMARY_KEYS, catalog, schema, table));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getImportedKeys(
+      final String catalog, final String schema, final String table) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getImportedKeys(connection.handle, catalog, schema, table),
+                    new QueryState(MetaDataOperation.GET_IMPORTED_KEYS, catalog, schema, table));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getExportedKeys(
+      final String catalog, final String schema, final String table) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getExportedKeys(connection.handle, catalog, schema, table),
+                    new QueryState(MetaDataOperation.GET_EXPORTED_KEYS, catalog, schema, table));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getCrossReference(
+      final String parentCatalog,
+      final String parentSchema,
+      final String parentTable,
+      final String foreignCatalog,
+      final String foreignSchema,
+      final String foreignTable) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getCrossReference(connection.handle, parentCatalog,
+                        parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable),
+                    new QueryState(MetaDataOperation.GET_CROSS_REFERENCE, parentCatalog,
+                        parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getTypeInfo() throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(connection.meta.getTypeInfo(connection.handle),
+                    new QueryState(MetaDataOperation.GET_TYPE_INFO));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getIndexInfo(
+      final String catalog,
+      final String schema,
+      final String table,
+      final boolean unique,
+      final boolean approximate) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getIndexInfo(connection.handle, catalog, schema, table, unique,
+                        approximate),
+                    new QueryState(MetaDataOperation.GET_INDEX_INFO, catalog, schema, table, unique,
+                        approximate));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public boolean supportsResultSetType(int type) throws SQLException {
+    return type == ResultSet.TYPE_FORWARD_ONLY;
+  }
+
+  public boolean supportsResultSetConcurrency(
+      int type, int concurrency) throws SQLException {
+    return type == ResultSet.TYPE_FORWARD_ONLY
+        && concurrency == ResultSet.CONCUR_READ_ONLY;
+  }
+
+  public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean ownDeletesAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean ownInsertsAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean othersDeletesAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean othersInsertsAreVisible(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean updatesAreDetected(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean deletesAreDetected(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean insertsAreDetected(int type) throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public boolean supportsBatchUpdates() throws SQLException {
+    return false;
+  }
+
+  public ResultSet getUDTs(
+      final String catalog,
+      final String schemaPattern,
+      final String typeNamePattern,
+      final int[] types) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getUDTs(connection.handle, catalog, pat(schemaPattern),
+                        pat(typeNamePattern), types),
+                    new QueryState(MetaDataOperation.GET_UDTS, catalog, schemaPattern,
+                        typeNamePattern, types));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public Connection getConnection() throws SQLException {
+    return connection;
+  }
+
+  public boolean supportsSavepoints() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsNamedParameters() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsMultipleOpenResults() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsGetGeneratedKeys() throws SQLException {
+    return false;
+  }
+
+  public ResultSet getSuperTypes(
+      final String catalog,
+      final String schemaPattern,
+      final String typeNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getSuperTypes(connection.handle, catalog, pat(schemaPattern),
+                        pat(typeNamePattern)),
+                    new QueryState(MetaDataOperation.GET_SUPER_TYPES, catalog, schemaPattern,
+                        typeNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getSuperTables(
+      final String catalog,
+      final String schemaPattern,
+      final String tableNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getSuperTables(connection.handle, catalog, pat(schemaPattern),
+                        pat(tableNamePattern)),
+                    new QueryState(MetaDataOperation.GET_SUPER_TABLES, catalog, schemaPattern,
+                        tableNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getAttributes(
+      final String catalog,
+      final String schemaPattern,
+      final String typeNamePattern,
+      final String attributeNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getAttributes(connection.handle, catalog, pat(schemaPattern),
+                        pat(typeNamePattern), pat(attributeNamePattern)),
+                    new QueryState(MetaDataOperation.GET_ATTRIBUTES, catalog, schemaPattern,
+                        typeNamePattern, attributeNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public boolean supportsResultSetHoldability(int holdability)
+      throws SQLException {
+    throw connection.helper.todo();
+  }
+
+  public int getResultSetHoldability() {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  public int getDatabaseMajorVersion() throws SQLException {
+    return connection.driver.version.databaseMajorVersion;
+  }
+
+  public int getDatabaseMinorVersion() throws SQLException {
+    return connection.driver.version.databaseMinorVersion;
+  }
+
+  public int getJDBCMajorVersion() throws SQLException {
+    return connection.factory.getJdbcMajorVersion();
+  }
+
+  public int getJDBCMinorVersion() throws SQLException {
+    return connection.factory.getJdbcMinorVersion();
+  }
+
+  public int getSQLStateType() throws SQLException {
+    return sqlStateSQL;
+  }
+
+  public boolean locatorsUpdateCopy() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsStatementPooling() throws SQLException {
+    return false;
+  }
+
+  public RowIdLifetime getRowIdLifetime() throws SQLException {
+    return RowIdLifetime.ROWID_UNSUPPORTED;
+  }
+
+  public boolean supportsStoredFunctionsUsingCallSyntax()
+      throws SQLException {
+    return true;
+  }
+
+  public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+    return false;
+  }
+
+  public ResultSet getClientInfoProperties() throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getClientInfoProperties(connection.handle),
+                    new QueryState(MetaDataOperation.GET_CLIENT_INFO_PROPERTIES));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getFunctions(
+      final String catalog,
+      final String schemaPattern,
+      final String functionNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getFunctions(connection.handle, catalog, pat(schemaPattern),
+                        pat(functionNamePattern)),
+                    new QueryState(MetaDataOperation.GET_FUNCTIONS, catalog, schemaPattern,
+                        functionNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getFunctionColumns(
+      final String catalog,
+      final String schemaPattern,
+      final String functionNamePattern,
+      final String columnNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getFunctionColumns(connection.handle, catalog,
+                        pat(schemaPattern), pat(functionNamePattern), pat(columnNamePattern)),
+                    new QueryState(MetaDataOperation.GET_FUNCTION_COLUMNS, catalog,
+                        schemaPattern, functionNamePattern, columnNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public ResultSet getPseudoColumns(
+      final String catalog,
+      final String schemaPattern,
+      final String tableNamePattern,
+      final String columnNamePattern) throws SQLException {
+    try {
+      return connection.invokeWithRetries(
+          new CallableWithoutException<ResultSet>() {
+            public ResultSet call() {
+              try {
+                return connection.createResultSet(
+                    connection.meta.getPseudoColumns(connection.handle, catalog, pat(schemaPattern),
+                        pat(tableNamePattern), pat(columnNamePattern)),
+                    new QueryState(MetaDataOperation.GET_PSEUDO_COLUMNS, catalog, schemaPattern,
+                        tableNamePattern, columnNamePattern));
+              } catch (SQLException e) {
+                throw new RuntimeException(e);
+              }
+            }
+          });
+    } catch (RuntimeException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof SQLException) {
+        throw (SQLException) cause;
+      }
+      throw e;
+    }
+  }
+
+  public boolean generatedKeyAlwaysReturned() throws SQLException {
+    return false;
+  }
+
+  // implement Wrapper
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (iface.isInstance(this)) {
+      return iface.cast(this);
+    }
+    throw connection.helper.createException(
+        "does not implement '" + iface + "'");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return iface.isInstance(this);
+  }
+}
+
+// End AvaticaDatabaseMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
new file mode 100644
index 0000000..1a2a97f
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.TimeZone;
+
+/**
+ * Factory for JDBC objects.
+ *
+ * <p>There is an implementation for each supported JDBC version.</p>
+ */
+public interface AvaticaFactory {
+  int getJdbcMajorVersion();
+
+  int getJdbcMinorVersion();
+
+  AvaticaConnection newConnection(
+      UnregisteredDriver driver,
+      AvaticaFactory factory,
+      String url,
+      Properties info) throws SQLException;
+
+  AvaticaStatement newStatement(AvaticaConnection connection,
+      /*@Nullable*/ Meta.StatementHandle h, int resultSetType,
+      int resultSetConcurrency, int resultSetHoldability) throws SQLException;
+
+  AvaticaPreparedStatement newPreparedStatement(AvaticaConnection connection,
+      /*@Nullable*/ Meta.StatementHandle h, Meta.Signature signature,
+      int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+      throws SQLException;
+
+  /**
+   * Creates a result set. You will then need to call
+   * {@link AvaticaResultSet#execute()} on it.
+   *
+   * @param statement Statement
+   * @param state The state used to create this result set
+   * @param signature Prepared statement
+   * @param timeZone Time zone
+   * @param firstFrame Frame containing the first (or perhaps only) rows in the
+   *                   result, or null if an execute/fetch is required
+   * @return Result set
+   */
+  AvaticaResultSet newResultSet(AvaticaStatement statement, QueryState state,
+      Meta.Signature signature, TimeZone timeZone, Meta.Frame firstFrame)
+      throws SQLException;
+
+  /**
+   * Creates meta data for the database.
+   *
+   * @return Database meta data
+   */
+  AvaticaDatabaseMetaData newDatabaseMetaData(AvaticaConnection connection);
+
+  /**
+   * Creates meta data for a result set.
+   *
+   * @param statement Statement
+   * @param signature Prepared statement
+   * @return Result set meta data
+   */
+  ResultSetMetaData newResultSetMetaData(AvaticaStatement statement,
+      Meta.Signature signature) throws SQLException;
+}
+
+// End AvaticaFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
new file mode 100644
index 0000000..f410dc8
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
@@ -0,0 +1,256 @@
+/*
+ * 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.InputStream;
+import java.io.Reader;
+import java.sql.NClob;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.util.Properties;
+import java.util.TimeZone;
+
+/**
+ * Implementation of {@link AvaticaFactory} for JDBC 4.1 (corresponds to JDK
+ * 1.7).
+ */
+@SuppressWarnings("UnusedDeclaration")
+class AvaticaJdbc41Factory implements AvaticaFactory {
+  private final int major;
+  private final int minor;
+
+  /** Creates a JDBC factory. */
+  public AvaticaJdbc41Factory() {
+    this(4, 1);
+  }
+
+  /** Creates a JDBC factory with given major/minor version number. */
+  protected AvaticaJdbc41Factory(int major, int minor) {
+    this.major = major;
+    this.minor = minor;
+  }
+
+  public int getJdbcMajorVersion() {
+    return major;
+  }
+
+  public int getJdbcMinorVersion() {
+    return minor;
+  }
+
+  public AvaticaConnection newConnection(
+      UnregisteredDriver driver,
+      AvaticaFactory factory,
+      String url,
+      Properties info) {
+    return new AvaticaJdbc41Connection(driver, factory, url, info);
+  }
+
+  public AvaticaDatabaseMetaData newDatabaseMetaData(
+      AvaticaConnection connection) {
+    return new AvaticaJdbc41DatabaseMetaData(connection);
+  }
+
+  public AvaticaStatement newStatement(AvaticaConnection connection,
+      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
+      int resultSetHoldability) {
+    return new AvaticaJdbc41Statement(connection, h, resultSetType,
+        resultSetConcurrency, resultSetHoldability);
+  }
+
+  public AvaticaPreparedStatement newPreparedStatement(
+      AvaticaConnection connection, Meta.StatementHandle h,
+      Meta.Signature signature, int resultSetType, int resultSetConcurrency,
+      int resultSetHoldability)
+      throws SQLException {
+    return new AvaticaJdbc41PreparedStatement(connection, h, signature,
+        resultSetType, resultSetConcurrency, resultSetHoldability);
+  }
+
+  public AvaticaResultSet newResultSet(AvaticaStatement statement,
+      QueryState state, Meta.Signature signature, TimeZone timeZone, Meta.Frame firstFrame) {
+    final ResultSetMetaData metaData =
+        newResultSetMetaData(statement, signature);
+    return new AvaticaResultSet(statement, state, signature, metaData, timeZone,
+        firstFrame);
+  }
+
+  public AvaticaResultSetMetaData newResultSetMetaData(
+      AvaticaStatement statement, Meta.Signature signature) {
+    return new AvaticaResultSetMetaData(statement, null, signature);
+  }
+
+  /** Implementation of Connection for JDBC 4.1. */
+  private static class AvaticaJdbc41Connection extends AvaticaConnection {
+    AvaticaJdbc41Connection(UnregisteredDriver driver,
+        AvaticaFactory factory,
+        String url,
+        Properties info) {
+      super(driver, factory, url, info);
+    }
+  }
+
+  /** Implementation of Statement for JDBC 4.1. */
+  private static class AvaticaJdbc41Statement extends AvaticaStatement {
+    public AvaticaJdbc41Statement(AvaticaConnection connection,
+        Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
+        int resultSetHoldability) {
+      super(connection, h, resultSetType, resultSetConcurrency,
+          resultSetHoldability);
+    }
+  }
+
+  /** Implementation of PreparedStatement for JDBC 4.1. */
+  private static class AvaticaJdbc41PreparedStatement
+      extends AvaticaPreparedStatement {
+    AvaticaJdbc41PreparedStatement(AvaticaConnection connection,
+        Meta.StatementHandle h, Meta.Signature signature, int resultSetType,
+        int resultSetConcurrency, int resultSetHoldability)
+        throws SQLException {
+      super(connection, h, signature, resultSetType, resultSetConcurrency,
+          resultSetHoldability);
+    }
+
+    public void setRowId(
+        int parameterIndex,
+        RowId x) throws SQLException {
+      getSite(parameterIndex).setRowId(x);
+    }
+
+    public void setNString(
+        int parameterIndex, String value) throws SQLException {
+      getSite(parameterIndex).setNString(value);
+    }
+
+    public void setNCharacterStream(
+        int parameterIndex,
+        Reader value,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setNCharacterStream(value, length);
+    }
+
+    public void setNClob(
+        int parameterIndex,
+        NClob value) throws SQLException {
+      getSite(parameterIndex).setNClob(value);
+    }
+
+    public void setClob(
+        int parameterIndex,
+        Reader reader,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setClob(reader, length);
+    }
+
+    public void setBlob(
+        int parameterIndex,
+        InputStream inputStream,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setBlob(inputStream, length);
+    }
+
+    public void setNClob(
+        int parameterIndex,
+        Reader reader,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setNClob(reader, length);
+    }
+
+    public void setSQLXML(
+        int parameterIndex, SQLXML xmlObject) throws SQLException {
+      getSite(parameterIndex).setSQLXML(xmlObject);
+    }
+
+    public void setAsciiStream(
+        int parameterIndex,
+        InputStream x,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setAsciiStream(x, length);
+    }
+
+    public void setBinaryStream(
+        int parameterIndex,
+        InputStream x,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setBinaryStream(x, length);
+    }
+
+    public void setCharacterStream(
+        int parameterIndex,
+        Reader reader,
+        long length) throws SQLException {
+      getSite(parameterIndex)
+          .setCharacterStream(reader, length);
+    }
+
+    public void setAsciiStream(
+        int parameterIndex, InputStream x) throws SQLException {
+      getSite(parameterIndex).setAsciiStream(x);
+    }
+
+    public void setBinaryStream(
+        int parameterIndex, InputStream x) throws SQLException {
+      getSite(parameterIndex).setBinaryStream(x);
+    }
+
+    public void setCharacterStream(
+        int parameterIndex, Reader reader) throws SQLException {
+      getSite(parameterIndex)
+          .setCharacterStream(reader);
+    }
+
+    public void setNCharacterStream(
+        int parameterIndex, Reader value) throws SQLException {
+      getSite(parameterIndex)
+          .setNCharacterStream(value);
+    }
+
+    public void setClob(
+        int parameterIndex,
+        Reader reader) throws SQLException {
+      getSite(parameterIndex).setClob(reader);
+    }
+
+    public void setBlob(
+        int parameterIndex, InputStream inputStream) throws SQLException {
+      getSite(parameterIndex).setBlob(inputStream);
+    }
+
+    public void setNClob(
+        int parameterIndex, Reader reader) throws SQLException {
+      getSite(parameterIndex).setNClob(reader);
+    }
+  }
+
+  /** Implementation of DatabaseMetaData for JDBC 4.1. */
+  private static class AvaticaJdbc41DatabaseMetaData
+      extends AvaticaDatabaseMetaData {
+    AvaticaJdbc41DatabaseMetaData(AvaticaConnection connection) {
+      super(connection);
+    }
+  }
+}
+
+// End AvaticaJdbc41Factory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
new file mode 100644
index 0000000..3c5a9ab
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
@@ -0,0 +1,135 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Objects;
+
+/**
+ * Metadata for a parameter.
+ */
+public class AvaticaParameter {
+  public final boolean signed;
+  public final int precision;
+  public final int scale;
+  public final int parameterType;
+  public final String typeName;
+  public final String className;
+  public final String name;
+
+  @JsonCreator
+  public AvaticaParameter(
+      @JsonProperty("signed") boolean signed,
+      @JsonProperty("precision") int precision,
+      @JsonProperty("scale") int scale,
+      @JsonProperty("parameterType") int parameterType,
+      @JsonProperty("typeName") String typeName,
+      @JsonProperty("className") String className,
+      @JsonProperty("name") String name) {
+    this.signed = signed;
+    this.precision = precision;
+    this.scale = scale;
+    this.parameterType = parameterType;
+    this.typeName = typeName;
+    this.className = className;
+    this.name = name;
+  }
+
+  public Common.AvaticaParameter toProto() {
+    Common.AvaticaParameter.Builder builder = Common.AvaticaParameter.newBuilder();
+
+    builder.setSigned(signed);
+    builder.setPrecision(precision);
+    builder.setScale(scale);
+    builder.setParameterType(parameterType);
+    builder.setTypeName(typeName);
+    builder.setClassName(className);
+    builder.setName(name);
+
+    return builder.build();
+  }
+
+  public static AvaticaParameter fromProto(Common.AvaticaParameter proto) {
+    return new AvaticaParameter(proto.getSigned(), proto.getPrecision(),
+        proto.getScale(), proto.getParameterType(), proto.getTypeName(),
+        proto.getClassName(), proto.getName());
+  }
+
+  @Override public int hashCode() {
+    return Objects.hash(className, name, parameterType, precision, scale,
+        signed, typeName);
+  }
+
+  @Override public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof AvaticaParameter) {
+      AvaticaParameter other = (AvaticaParameter) obj;
+
+      if (null == className) {
+        if (null != other.className) {
+          return false;
+        }
+      } else if (!className.equals(other.className)) {
+        return false;
+      }
+
+      if (null == name) {
+        if (null != other.name) {
+          return false;
+        }
+      } else if (!name.equals(other.name)) {
+        return false;
+      }
+
+      if (parameterType != other.parameterType) {
+        return false;
+      }
+
+      if (precision != other.precision) {
+        return false;
+      }
+
+      if (scale != other.scale) {
+        return false;
+      }
+
+      if (signed != other.signed) {
+        return false;
+      }
+
+      if (null == typeName) {
+        if (null != other.typeName) {
+          return false;
+        }
+      } else if (!typeName.equals(other.typeName)) {
+        return false;
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+}
+
+// End AvaticaParameter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
new file mode 100644
index 0000000..f3a950a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
@@ -0,0 +1,343 @@
+/*
+ * 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.Meta.Signature;
+import org.apache.calcite.avatica.remote.TypedValue;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Implementation of {@link java.sql.PreparedStatement}
+ * for the Avatica engine.
+ *
+ * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
+ * it is instantiated using {@link AvaticaFactory#newPreparedStatement}.</p>
+ */
+public abstract class AvaticaPreparedStatement
+    extends AvaticaStatement
+    implements PreparedStatement, ParameterMetaData {
+  private final ResultSetMetaData resultSetMetaData;
+  private Calendar calendar;
+  protected final TypedValue[] slots;
+
+  /**
+   * Creates an AvaticaPreparedStatement.
+   *
+   * @param connection Connection
+   * @param h Statement handle
+   * @param signature Result of preparing statement
+   * @param resultSetType Result set type
+   * @param resultSetConcurrency Result set concurrency
+   * @param resultSetHoldability Result set holdability
+   * @throws SQLException If fails due to underlying implementation reasons.
+   */
+  protected AvaticaPreparedStatement(AvaticaConnection connection,
+      Meta.StatementHandle h,
+      Meta.Signature signature,
+      int resultSetType,
+      int resultSetConcurrency,
+      int resultSetHoldability) throws SQLException {
+    super(connection, h, resultSetType, resultSetConcurrency,
+        resultSetHoldability, signature);
+    this.slots = new TypedValue[signature.parameters.size()];
+    this.resultSetMetaData =
+        connection.factory.newResultSetMetaData(this, signature);
+  }
+
+  @Override protected List<TypedValue> getParameterValues() {
+    return Arrays.asList(slots);
+  }
+
+  /** Returns a calendar in the connection's time zone, creating one the first
+   * time this method is called.
+   *
+   * <p>Uses the calendar to offset date-time values when calling methods such
+   * as {@link #setDate(int, Date)}.
+   *
+   * <p>A note on thread-safety. This method does not strictly need to be
+   * {@code synchronized}, because JDBC does not promise thread safety if
+   * different threads are accessing the same statement, or even different
+   * objects within a particular connection.
+   *
+   * <p>The calendar returned is to be used only within this statement, and
+   * JDBC only allows access to a statement from within one thread, so
+   * therefore does not need to be synchronized when accessed.
+   */
+  protected synchronized Calendar getCalendar() {
+    if (calendar == null) {
+      calendar = Calendar.getInstance(connection.getTimeZone());
+    }
+    return calendar;
+  }
+
+  // implement PreparedStatement
+
+  public ResultSet executeQuery() throws SQLException {
+    this.updateCount = -1;
+    final Signature sig = getSignature();
+    return getConnection().executeQueryInternal(this, sig, null,
+        new QueryState(sig.sql), false);
+  }
+
+  public ParameterMetaData getParameterMetaData() throws SQLException {
+    return this;
+  }
+
+  public final int executeUpdate() throws SQLException {
+    return (int) executeLargeUpdate();
+  }
+
+  public long executeLargeUpdate() throws SQLException {
+    getConnection().executeQueryInternal(this, null, null,
+        new QueryState(getSignature().sql), true);
+    return updateCount;
+  }
+
+  public void setNull(int parameterIndex, int sqlType) throws SQLException {
+    getSite(parameterIndex).setNull(sqlType);
+  }
+
+  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+    getSite(parameterIndex).setBoolean(x);
+  }
+
+  public void setByte(int parameterIndex, byte x) throws SQLException {
+    getSite(parameterIndex).setByte(x);
+  }
+
+  public void setShort(int parameterIndex, short x) throws SQLException {
+    getSite(parameterIndex).setShort(x);
+  }
+
+  public void setInt(int parameterIndex, int x) throws SQLException {
+    getSite(parameterIndex).setInt(x);
+  }
+
+  public void setLong(int parameterIndex, long x) throws SQLException {
+    getSite(parameterIndex).setLong(x);
+  }
+
+  public void setFloat(int parameterIndex, float x) throws SQLException {
+    getSite(parameterIndex).setFloat(x);
+  }
+
+  public void setDouble(int parameterIndex, double x) throws SQLException {
+    getSite(parameterIndex).setDouble(x);
+  }
+
+  public void setBigDecimal(int parameterIndex, BigDecimal x)
+      throws SQLException {
+    getSite(parameterIndex).setBigDecimal(x);
+  }
+
+  public void setString(int parameterIndex, String x) throws SQLException {
+    getSite(parameterIndex).setString(x);
+  }
+
+  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+    getSite(parameterIndex).setBytes(x);
+  }
+
+  public void setAsciiStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {
+    getSite(parameterIndex).setAsciiStream(x, length);
+  }
+
+  public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {
+    getSite(parameterIndex).setUnicodeStream(x, length);
+  }
+
+  public void setBinaryStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {
+    getSite(parameterIndex).setBinaryStream(x, length);
+  }
+
+  public void clearParameters() throws SQLException {
+    for (int i = 0; i < slots.length; i++) {
+      slots[i] = null;
+    }
+  }
+
+  public void setObject(int parameterIndex, Object x, int targetSqlType)
+      throws SQLException {
+    getSite(parameterIndex).setObject(x, targetSqlType);
+  }
+
+  public void setObject(int parameterIndex, Object x) throws SQLException {
+    getSite(parameterIndex).setObject(x);
+  }
+
+  public boolean execute() throws SQLException {
+    this.updateCount = -1;
+    // We don't know if this is actually an update or a query, so call it a query so we pass the
+    // Signature to the server.
+    getConnection().executeQueryInternal(this, getSignature(), null,
+        new QueryState(getSignature().sql), false);
+    // Result set is null for DML or DDL.
+    // Result set is closed if user cancelled the query.
+    return openResultSet != null && !openResultSet.isClosed();
+  }
+
+  public void addBatch() throws SQLException {
+    throw connection.helper.unsupported();
+  }
+
+  public void setCharacterStream(int parameterIndex, Reader reader, int length)
+      throws SQLException {
+    getSite(parameterIndex).setCharacterStream(reader, length);
+  }
+
+  public void setRef(int parameterIndex, Ref x) throws SQLException {
+    getSite(parameterIndex).setRef(x);
+  }
+
+  public void setBlob(int parameterIndex, Blob x) throws SQLException {
+    getSite(parameterIndex).setBlob(x);
+  }
+
+  public void setClob(int parameterIndex, Clob x) throws SQLException {
+    getSite(parameterIndex).setClob(x);
+  }
+
+  public void setArray(int parameterIndex, Array x) throws SQLException {
+    getSite(parameterIndex).setArray(x);
+  }
+
+  public ResultSetMetaData getMetaData() {
+    return resultSetMetaData;
+  }
+
+  public void setDate(int parameterIndex, Date x, Calendar calendar)
+      throws SQLException {
+    getSite(parameterIndex).setDate(x, calendar);
+  }
+
+  public void setDate(int parameterIndex, Date x) throws SQLException {
+    setDate(parameterIndex, x, getCalendar());
+  }
+
+  public void setTime(int parameterIndex, Time x, Calendar calendar)
+      throws SQLException {
+    getSite(parameterIndex).setTime(x, calendar);
+  }
+
+  public void setTime(int parameterIndex, Time x) throws SQLException {
+    setTime(parameterIndex, x, getCalendar());
+  }
+
+  public void setTimestamp(int parameterIndex, Timestamp x, Calendar calendar)
+      throws SQLException {
+    getSite(parameterIndex).setTimestamp(x, calendar);
+  }
+
+  public void setTimestamp(int parameterIndex, Timestamp x)
+      throws SQLException {
+    setTimestamp(parameterIndex, x, getCalendar());
+  }
+
+  public void setNull(int parameterIndex, int sqlType, String typeName)
+      throws SQLException {
+    getSite(parameterIndex).setNull(sqlType, typeName);
+  }
+
+  public void setURL(int parameterIndex, URL x) throws SQLException {
+    getSite(parameterIndex).setURL(x);
+  }
+
+  public void setObject(int parameterIndex, Object x, int targetSqlType,
+      int scaleOrLength) throws SQLException {
+    getSite(parameterIndex).setObject(x, targetSqlType, scaleOrLength);
+  }
+
+  // implement ParameterMetaData
+
+  protected AvaticaParameter getParameter(int param) throws SQLException {
+    try {
+      return getSignature().parameters.get(param - 1);
+    } catch (IndexOutOfBoundsException e) {
+      //noinspection ThrowableResultOfMethodCallIgnored
+      throw connection.helper.toSQLException(
+          connection.helper.createException(
+              "parameter ordinal " + param + " out of range"));
+    }
+  }
+
+  protected AvaticaSite getSite(int param) throws SQLException {
+    final AvaticaParameter parameter = getParameter(param);
+    return new AvaticaSite(parameter, getCalendar(), param - 1, slots);
+  }
+
+  public int getParameterCount() {
+    return getSignature().parameters.size();
+  }
+
+  public int isNullable(int param) throws SQLException {
+    return ParameterMetaData.parameterNullableUnknown;
+  }
+
+  public boolean isSigned(int index) throws SQLException {
+    return getParameter(index).signed;
+  }
+
+  public int getPrecision(int index) throws SQLException {
+    return getParameter(index).precision;
+  }
+
+  public int getScale(int index) throws SQLException {
+    return getParameter(index).scale;
+  }
+
+  public int getParameterType(int index) throws SQLException {
+    return getParameter(index).parameterType;
+  }
+
+  public String getParameterTypeName(int index) throws SQLException {
+    return getParameter(index).typeName;
+  }
+
+  public String getParameterClassName(int index) throws SQLException {
+    return getParameter(index).className;
+  }
+
+  public int getParameterMode(int param) throws SQLException {
+    //noinspection UnusedDeclaration
+    AvaticaParameter paramDef = getParameter(param); // forces param range check
+    return ParameterMetaData.parameterModeIn;
+  }
+}
+
+// End AvaticaPreparedStatement.java


[47/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/package-info.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/package-info.java
deleted file mode 100644
index f2b8728..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * Avatica server that listens for HTTP requests.
- */
-@PackageMarker
-package org.apache.calcite.avatica.server;
-
-import org.apache.calcite.avatica.util.PackageMarker;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java b/avatica-server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
deleted file mode 100644
index ba4c5b8..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/ConnectionSpec.java
+++ /dev/null
@@ -1,55 +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 net.hydromatic.scott.data.hsqldb.ScottHsqldb;
-
-import java.util.concurrent.locks.ReentrantLock;
-
-/** Information necessary to create a JDBC connection. Specify one to run
- * tests against a different database. (hsqldb is the default.) */
-public class ConnectionSpec {
-  public final String url;
-  public final String username;
-  public final String password;
-  public final String driver;
-
-  // CALCITE-687 HSQLDB seems to fail oddly when multiple tests are run concurrently
-  private static final ReentrantLock HSQLDB_LOCK = new ReentrantLock();
-
-  public ConnectionSpec(String url, String username, String password,
-      String driver) {
-    this.url = url;
-    this.username = username;
-    this.password = password;
-    this.driver = driver;
-  }
-
-  public static final ConnectionSpec HSQLDB =
-      new ConnectionSpec(ScottHsqldb.URI, ScottHsqldb.USER,
-          ScottHsqldb.PASSWORD, "org.hsqldb.jdbcDriver");
-
-  /**
-   * Return a lock used for controlling concurrent access to the database as it has been observed
-   * that concurrent access is causing problems with HSQLDB.
-   */
-  public static ReentrantLock getDatabaseLock() {
-    return HSQLDB_LOCK;
-  }
-}
-
-// End ConnectionSpec.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
deleted file mode 100644
index 9749ef6..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverMockTest.java
+++ /dev/null
@@ -1,219 +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.remote.MockJsonService;
-import org.apache.calcite.avatica.remote.MockProtobufService.MockProtobufServiceFactory;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * RemoteDriver tests that use a Mock implementation of a Connection.
- */
-@RunWith(Parameterized.class)
-public class RemoteDriverMockTest {
-  public static final String MJS = MockJsonService.Factory.class.getName();
-  public static final String MPBS = MockProtobufServiceFactory.class.getName();
-
-  private static Connection mjs() throws SQLException {
-    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + MJS);
-  }
-
-  private static Connection mpbs() throws SQLException {
-    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + MPBS);
-  }
-
-  @Parameters
-  public static List<Object[]> parameters() {
-    List<Object[]> parameters = new ArrayList<>();
-
-    parameters.add(new Object[] {new Callable<Connection>() {
-      public Connection call() throws SQLException {
-        return mjs();
-      }
-    } });
-
-    parameters.add(new Object[] {new Callable<Connection>() {
-      public Connection call() throws SQLException {
-        return mpbs();
-      }
-    } });
-
-    return parameters;
-  }
-
-  private final Callable<Connection> connectionFunctor;
-
-  public RemoteDriverMockTest(Callable<Connection> functor) {
-    this.connectionFunctor = functor;
-  }
-
-  private Connection getMockConnection() {
-    try {
-      return connectionFunctor.call();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  @Test public void testRegister() throws Exception {
-    final Connection connection = getMockConnection();
-    assertThat(connection.isClosed(), is(false));
-    connection.close();
-    assertThat(connection.isClosed(), is(true));
-  }
-
-  @Test public void testSchemas() throws Exception {
-    final Connection connection = getMockConnection();
-    final ResultSet resultSet =
-        connection.getMetaData().getSchemas(null, null);
-    assertFalse(resultSet.next());
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertTrue(metaData.getColumnCount() >= 2);
-    assertEquals("TABLE_CATALOG", metaData.getColumnName(1));
-    assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
-    resultSet.close();
-    connection.close();
-  }
-
-  @Test public void testTables() throws Exception {
-    final Connection connection = getMockConnection();
-    final ResultSet resultSet =
-        connection.getMetaData().getTables(null, null, null, new String[0]);
-    assertFalse(resultSet.next());
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertTrue(metaData.getColumnCount() >= 3);
-    assertEquals("TABLE_CAT", metaData.getColumnName(1));
-    assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
-    assertEquals("TABLE_NAME", metaData.getColumnName(3));
-    resultSet.close();
-    connection.close();
-  }
-
-  @Ignore
-  @Test public void testNoFactory() throws Exception {
-    final Connection connection =
-        DriverManager.getConnection("jdbc:avatica:remote:");
-    assertThat(connection.isClosed(), is(false));
-    final ResultSet resultSet = connection.getMetaData().getSchemas();
-    assertFalse(resultSet.next());
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
-    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
-    resultSet.close();
-    connection.close();
-    assertThat(connection.isClosed(), is(true));
-  }
-
-  @Ignore
-  @Test public void testCatalogsMock() throws Exception {
-    final Connection connection = getMockConnection();
-    assertThat(connection.isClosed(), is(false));
-    final ResultSet resultSet = connection.getMetaData().getSchemas();
-    assertFalse(resultSet.next());
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
-    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
-    resultSet.close();
-    connection.close();
-    assertThat(connection.isClosed(), is(true));
-  }
-
-  @Ignore
-  @Test public void testStatementExecuteQueryMock() throws Exception {
-    checkStatementExecuteQuery(getMockConnection(), false);
-  }
-
-  @Ignore
-  @Test public void testPrepareExecuteQueryMock() throws Exception {
-    checkStatementExecuteQuery(getMockConnection(), true);
-  }
-
-  private void checkStatementExecuteQuery(Connection connection,
-      boolean prepare) throws SQLException {
-    final String sql = "select * from (\n"
-        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
-    final Statement statement;
-    final ResultSet resultSet;
-    final ParameterMetaData parameterMetaData;
-    if (prepare) {
-      final PreparedStatement ps = connection.prepareStatement(sql);
-      statement = ps;
-      parameterMetaData = ps.getParameterMetaData();
-      resultSet = ps.executeQuery();
-    } else {
-      statement = connection.createStatement();
-      parameterMetaData = null;
-      resultSet = statement.executeQuery(sql);
-    }
-    if (parameterMetaData != null) {
-      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
-    }
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("C1", metaData.getColumnName(1));
-    assertEquals("C2", metaData.getColumnName(2));
-    assertTrue(resultSet.next());
-    assertTrue(resultSet.next());
-    assertTrue(resultSet.next());
-    assertFalse(resultSet.next());
-    resultSet.close();
-    statement.close();
-    connection.close();
-  }
-
-  @Test public void testResultSetsFinagled() throws Exception {
-    // These values specified in MockJsonService
-    final String table = "my_table";
-    final long value = 10;
-
-    final Connection connection = getMockConnection();
-    // Not an accurate ResultSet per JDBC, but close enough for testing.
-    ResultSet results = connection.getMetaData().getColumns(null, null, table, null);
-    assertTrue(results.next());
-    assertEquals(table, results.getString(1));
-    assertEquals(value, results.getLong(2));
-  }
-
-}
-
-// End RemoteDriverMockTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
deleted file mode 100644
index 228ba8d..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
+++ /dev/null
@@ -1,1320 +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.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.remote.JsonService;
-import org.apache.calcite.avatica.remote.LocalJsonService;
-import org.apache.calcite.avatica.remote.LocalProtobufService;
-import org.apache.calcite.avatica.remote.LocalService;
-import org.apache.calcite.avatica.remote.ProtobufTranslation;
-import org.apache.calcite.avatica.remote.ProtobufTranslationImpl;
-import org.apache.calcite.avatica.remote.Service;
-
-import com.google.common.cache.Cache;
-
-import net.jcip.annotations.NotThreadSafe;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.lang.reflect.Field;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.Date;
-import java.sql.DriverManager;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * Unit test for Avatica Remote JDBC driver.
- */
-@RunWith(Parameterized.class)
-@NotThreadSafe // for testConnectionIsolation
-public class RemoteDriverTest {
-  public static final String LJS =
-      LocalJdbcServiceFactory.class.getName();
-
-  public static final String QRJS =
-      QuasiRemoteJdbcServiceFactory.class.getName();
-
-  public static final String QRPBS =
-      QuasiRemotePBJdbcServiceFactory.class.getName();
-
-  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
-
-  private static Connection ljs() throws SQLException {
-    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + QRJS);
-  }
-
-  private static Connection lpbs() throws SQLException {
-    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + QRPBS);
-  }
-
-  private Connection canon() throws SQLException {
-    return DriverManager.getConnection(CONNECTION_SPEC.url,
-        CONNECTION_SPEC.username, CONNECTION_SPEC.password);
-  }
-
-  /**
-   * Interface that allows for alternate ways to access internals to the Connection for testing
-   * purposes.
-   */
-  interface ConnectionInternals {
-    /**
-     * Reaches into the guts of a quasi-remote connection and pull out the
-     * statement map from the other side.
-     *
-     * <p>TODO: refactor tests to replace reflection with package-local access
-     */
-    Cache<Integer, Object> getRemoteStatementMap(AvaticaConnection connection) throws Exception;
-
-    /**
-     * Reaches into the guts of a quasi-remote connection and pull out the
-     * connection map from the other side.
-     *
-     * <p>TODO: refactor tests to replace reflection with package-local access
-     */
-    Cache<String, Connection> getRemoteConnectionMap(AvaticaConnection connection) throws Exception;
-  }
-
-  // Run each test with the LocalJsonService and LocalProtobufService
-  @Parameters
-  public static List<Object[]> parameters() {
-    List<Object[]> connections = new ArrayList<>();
-
-    // Json and Protobuf operations should be equivalent -- tests against one work on the other
-    // Each test needs to get a fresh Connection and also access some internals on that Connection.
-
-    connections.add(
-      new Object[] {
-        new Callable<Connection>() {
-          public Connection call() {
-            try {
-              return ljs();
-            } catch (SQLException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        },
-        new QuasiRemoteJdbcServiceInternals(),
-        new Callable<RequestInspection>() {
-          public RequestInspection call() throws Exception {
-            assert null != QuasiRemoteJdbcServiceFactory.requestInspection;
-            return QuasiRemoteJdbcServiceFactory.requestInspection;
-          }
-        } });
-
-    // TODO write the ConnectionInternals implementation
-    connections.add(
-      new Object[] {
-        new Callable<Connection>() {
-          public Connection call() {
-            try {
-              return lpbs();
-            } catch (SQLException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        },
-        new QuasiRemoteProtobufJdbcServiceInternals(),
-        new Callable<RequestInspection>() {
-          public RequestInspection call() throws Exception {
-            assert null != QuasiRemotePBJdbcServiceFactory.requestInspection;
-            return QuasiRemotePBJdbcServiceFactory.requestInspection;
-          }
-        } });
-
-    return connections;
-  }
-
-  private final Callable<Connection> localConnectionCallable;
-  private final ConnectionInternals localConnectionInternals;
-  private final Callable<RequestInspection> requestInspectionCallable;
-
-  public RemoteDriverTest(Callable<Connection> localConnectionCallable,
-      ConnectionInternals internals, Callable<RequestInspection> requestInspectionCallable) {
-    this.localConnectionCallable = localConnectionCallable;
-    this.localConnectionInternals = internals;
-    this.requestInspectionCallable = requestInspectionCallable;
-  }
-
-  private Connection getLocalConnection() {
-    try {
-      return localConnectionCallable.call();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private ConnectionInternals getLocalConnectionInternals() {
-    return localConnectionInternals;
-  }
-
-  private RequestInspection getRequestInspection() {
-    try {
-      return requestInspectionCallable.call();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /** Executes a lambda for the canonical connection and the local
-   * connection. */
-  public void eachConnection(ConnectionFunction f, Connection localConn) throws Exception {
-    for (int i = 0; i < 2; i++) {
-      try (Connection connection = i == 0 ? canon() : localConn) {
-        f.apply(connection);
-      }
-    }
-  }
-
-  @Before
-  public void before() throws Exception {
-    QuasiRemoteJdbcServiceFactory.initService();
-    QuasiRemotePBJdbcServiceFactory.initService();
-  }
-
-  @Test public void testRegister() throws Exception {
-    final Connection connection = getLocalConnection();
-    assertThat(connection.isClosed(), is(false));
-    connection.close();
-    assertThat(connection.isClosed(), is(true));
-  }
-
-  @Test public void testDatabaseProperties() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      final Connection connection = getLocalConnection();
-      for (Meta.DatabaseProperty p : Meta.DatabaseProperty.values()) {
-        switch (p) {
-        case GET_NUMERIC_FUNCTIONS:
-          assertThat(connection.getMetaData().getNumericFunctions(),
-              equalTo("ABS,ACOS,ASIN,ATAN,ATAN2,BITAND,BITOR,BITXOR,"
-                  + "CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,"
-                  + "PI,POWER,RADIANS,RAND,ROUND,ROUNDMAGIC,SIGN,SIN,"
-                  + "SQRT,TAN,TRUNCATE"));
-          break;
-        case GET_SYSTEM_FUNCTIONS:
-          assertThat(connection.getMetaData().getSystemFunctions(),
-              equalTo("DATABASE,IFNULL,USER"));
-          break;
-        case GET_TIME_DATE_FUNCTIONS:
-          assertThat(connection.getMetaData().getTimeDateFunctions(),
-              equalTo("CURDATE,CURTIME,DATEDIFF,DAYNAME,DAYOFMONTH,DAYOFWEEK,"
-                  + "DAYOFYEAR,HOUR,MINUTE,MONTH,MONTHNAME,NOW,QUARTER,SECOND,"
-                  + "SECONDS_SINCE_MIDNIGHT,TIMESTAMPADD,TIMESTAMPDIFF,"
-                  + "TO_CHAR,WEEK,YEAR"));
-          break;
-        case GET_S_Q_L_KEYWORDS:
-          assertThat(connection.getMetaData().getSQLKeywords(),
-              equalTo("")); // No SQL keywords return for HSQLDB
-          break;
-        case GET_STRING_FUNCTIONS:
-          assertThat(connection.getMetaData().getStringFunctions(),
-              equalTo("ASCII,CHAR,CONCAT,DIFFERENCE,HEXTORAW,INSERT,LCASE,"
-                  + "LEFT,LENGTH,LOCATE,LTRIM,RAWTOHEX,REPEAT,REPLACE,"
-                  + "RIGHT,RTRIM,SOUNDEX,SPACE,SUBSTR,UCASE"));
-          break;
-        default:
-        }
-      }
-      connection.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testTypeInfo() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      final Connection connection = getLocalConnection();
-      final ResultSet resultSet =
-          connection.getMetaData().getTypeInfo();
-      assertTrue(resultSet.next());
-      final ResultSetMetaData metaData = resultSet.getMetaData();
-      assertTrue(metaData.getColumnCount() >= 18);
-      assertEquals("TYPE_NAME", metaData.getColumnName(1));
-      assertEquals("DATA_TYPE", metaData.getColumnName(2));
-      assertEquals("PRECISION", metaData.getColumnName(3));
-      assertEquals("SQL_DATA_TYPE", metaData.getColumnName(16));
-      assertEquals("SQL_DATETIME_SUB", metaData.getColumnName(17));
-      assertEquals("NUM_PREC_RADIX", metaData.getColumnName(18));
-      resultSet.close();
-      connection.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testGetTables() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      final Connection connection = getLocalConnection();
-      final ResultSet resultSet =
-              connection.getMetaData().getTables(null, "SCOTT", null, null);
-      assertEquals(13, resultSet.getMetaData().getColumnCount());
-      assertTrue(resultSet.next());
-      assertEquals("DEPT", resultSet.getString(3));
-      assertTrue(resultSet.next());
-      assertEquals("EMP", resultSet.getString(3));
-      assertTrue(resultSet.next());
-      assertEquals("BONUS", resultSet.getString(3));
-      assertTrue(resultSet.next());
-      assertEquals("SALGRADE", resultSet.getString(3));
-      resultSet.close();
-      connection.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Ignore
-  @Test public void testNoFactory() throws Exception {
-    final Connection connection =
-        DriverManager.getConnection("jdbc:avatica:remote:");
-    assertThat(connection.isClosed(), is(false));
-    final ResultSet resultSet = connection.getMetaData().getSchemas();
-    assertFalse(resultSet.next());
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
-    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
-    resultSet.close();
-    connection.close();
-    assertThat(connection.isClosed(), is(true));
-  }
-
-  @Test public void testStatementExecuteQueryLocal() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecuteQuery(getLocalConnection(), false);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testPrepareExecuteQueryLocal() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecuteQuery(getLocalConnection(), true);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testInsertDrop() throws Exception {
-    final String t = AvaticaUtils.unique("TEST_TABLE2");
-    final String create =
-        String.format("create table if not exists %s ("
-            + "id int not null, "
-            + "msg varchar(3) not null)", t);
-    final String insert = String.format("insert into %s values(1, 'foo')", t);
-    Connection connection = ljs();
-    Statement statement = connection.createStatement();
-    statement.execute(create);
-
-    Statement stmt = connection.createStatement();
-    int count = stmt.executeUpdate(insert);
-    assertThat(count, is(1));
-    ResultSet resultSet = stmt.getResultSet();
-    assertThat(resultSet, nullValue());
-
-    PreparedStatement pstmt = connection.prepareStatement(insert);
-    boolean status = pstmt.execute();
-    assertThat(status, is(false));
-    int updateCount = pstmt.getUpdateCount();
-    assertThat(updateCount, is(1));
-  }
-
-  private void checkStatementExecuteQuery(Connection connection,
-      boolean prepare) throws SQLException {
-    final String sql = "select * from (\n"
-        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
-    final Statement statement;
-    final ResultSet resultSet;
-    final ParameterMetaData parameterMetaData;
-    if (prepare) {
-      final PreparedStatement ps = connection.prepareStatement(sql);
-      statement = ps;
-      parameterMetaData = ps.getParameterMetaData();
-      resultSet = ps.executeQuery();
-    } else {
-      statement = connection.createStatement();
-      parameterMetaData = null;
-      resultSet = statement.executeQuery(sql);
-    }
-    if (parameterMetaData != null) {
-      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
-    }
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("C1", metaData.getColumnName(1));
-    assertEquals("C2", metaData.getColumnName(2));
-    assertTrue(resultSet.next());
-    assertTrue(resultSet.next());
-    assertTrue(resultSet.next());
-    assertFalse(resultSet.next());
-    resultSet.close();
-    statement.close();
-    connection.close();
-  }
-
-  @Test public void testStatementExecuteLocal() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecute(getLocalConnection(), false);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testStatementExecuteFetch() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      // Creating a > 100 rows queries to enable fetch request
-      String sql = "select * from emp cross join emp";
-      checkExecuteFetch(getLocalConnection(), sql, false, 1);
-      // PreparedStatement needed an extra fetch, as the execute will
-      // trigger the 1st fetch. Where statement execute will execute direct
-      // with results back.
-      // 1 fetch, because execute did the first fetch
-      checkExecuteFetch(getLocalConnection(), sql, true, 1);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkExecuteFetch(Connection conn, String sql, boolean isPrepare,
-    int fetchCountMatch) throws SQLException {
-    final Statement exeStatement;
-    final ResultSet results;
-    getRequestInspection().getRequestLogger().enableAndClear();
-    if (isPrepare) {
-      PreparedStatement statement = conn.prepareStatement(sql);
-      exeStatement = statement;
-      results = statement.executeQuery();
-    } else {
-      Statement statement = conn.createStatement();
-      exeStatement = statement;
-      results = statement.executeQuery(sql);
-    }
-    int count = 0;
-    int fetchCount = 0;
-    while (results.next()) {
-      count++;
-    }
-    results.close();
-    exeStatement.close();
-    List<String[]> x = getRequestInspection().getRequestLogger().getAndDisable();
-    for (String[] pair : x) {
-      if (pair[0].contains("\"request\":\"fetch")) {
-        fetchCount++;
-      }
-    }
-    assertEquals(count, 196);
-    assertEquals(fetchCountMatch, fetchCount);
-  }
-
-  @Test public void testStatementExecuteLocalMaxRow() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecute(getLocalConnection(), false, 2);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testFetchSize() throws Exception {
-    Connection connection = ljs();
-
-    Statement statement = connection.createStatement();
-    statement.setFetchSize(101);
-    assertEquals(statement.getFetchSize(), 101);
-
-    PreparedStatement preparedStatement =
-        connection.prepareStatement("select * from (values (1, 'a')) as tbl1 (c1, c2)");
-    preparedStatement.setFetchSize(1);
-    assertEquals(preparedStatement.getFetchSize(), 1);
-  }
-
-  @Ignore("CALCITE-719: Refactor PreparedStatement to support setMaxRows")
-  @Test public void testStatementPrepareExecuteLocalMaxRow() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecute(getLocalConnection(), true, 2);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testPrepareExecuteLocal() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkStatementExecute(getLocalConnection(), true);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkStatementExecute(Connection connection,
-      boolean prepare) throws SQLException {
-    checkStatementExecute(connection, prepare, 0);
-  }
-  private void checkStatementExecute(Connection connection,
-      boolean prepare, int maxRowCount) throws SQLException {
-    final String sql = "select * from (\n"
-        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
-    final Statement statement;
-    final ResultSet resultSet;
-    final ParameterMetaData parameterMetaData;
-    if (prepare) {
-      final PreparedStatement ps = connection.prepareStatement(sql);
-      statement = ps;
-      ps.setMaxRows(maxRowCount);
-      parameterMetaData = ps.getParameterMetaData();
-      assertTrue(ps.execute());
-      resultSet = ps.getResultSet();
-    } else {
-      statement = connection.createStatement();
-      statement.setMaxRows(maxRowCount);
-      parameterMetaData = null;
-      assertTrue(statement.execute(sql));
-      resultSet = statement.getResultSet();
-    }
-    if (parameterMetaData != null) {
-      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
-    }
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("C1", metaData.getColumnName(1));
-    assertEquals("C2", metaData.getColumnName(2));
-    for (int i = 0; i < maxRowCount || (maxRowCount == 0 && i < 3); i++) {
-      assertTrue(resultSet.next());
-    }
-    assertFalse(resultSet.next());
-    resultSet.close();
-    statement.close();
-    connection.close();
-  }
-
-  @Test public void testCreateInsertUpdateDrop() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    final String t = AvaticaUtils.unique("TEST_TABLE");
-    final String drop = String.format("drop table %s if exists", t);
-    final String create = String.format("create table %s("
-        + "id int not null, "
-        + "msg varchar(3) not null)",
-        t);
-    final String insert = String.format("insert into %s values(1, 'foo')", t);
-    final String update =
-        String.format("update %s set msg='bar' where id=1", t);
-    try (Connection connection = getLocalConnection();
-        Statement statement = connection.createStatement();
-        PreparedStatement pstmt = connection.prepareStatement("values 1")) {
-      // drop
-      assertFalse(statement.execute(drop));
-      assertEquals(0, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-      try {
-        final ResultSet rs = statement.executeQuery(drop);
-        fail("expected error, got " + rs);
-      } catch (SQLException e) {
-        assertThat(e.getMessage(),
-            equalTo("Statement did not return a result set"));
-      }
-      assertEquals(0, statement.executeUpdate(drop));
-      assertEquals(0, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-
-      // create
-      assertFalse(statement.execute(create));
-      assertEquals(0, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-      assertFalse(statement.execute(drop)); // tidy up
-      try {
-        final ResultSet rs = statement.executeQuery(create);
-        fail("expected error, got " + rs);
-      } catch (SQLException e) {
-        assertThat(e.getMessage(),
-            equalTo("Statement did not return a result set"));
-      }
-      assertFalse(statement.execute(drop)); // tidy up
-      assertEquals(0, statement.executeUpdate(create));
-      assertEquals(0, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-
-      // insert
-      assertFalse(statement.execute(insert));
-      assertEquals(1, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-      try {
-        final ResultSet rs = statement.executeQuery(insert);
-        fail("expected error, got " + rs);
-      } catch (SQLException e) {
-        assertThat(e.getMessage(),
-            equalTo("Statement did not return a result set"));
-      }
-      assertEquals(1, statement.executeUpdate(insert));
-      assertEquals(1, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-
-      // update
-      assertFalse(statement.execute(update));
-      assertEquals(3, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-      try {
-        final ResultSet rs = statement.executeQuery(update);
-        fail("expected error, got " + rs);
-      } catch (SQLException e) {
-        assertThat(e.getMessage(),
-            equalTo("Statement did not return a result set"));
-      }
-      assertEquals(3, statement.executeUpdate(update));
-      assertEquals(3, statement.getUpdateCount());
-      assertNull(statement.getResultSet());
-
-      final String[] messages = {
-        "Cannot call executeQuery(String) on prepared or callable statement",
-        "Cannot call execute(String) on prepared or callable statement",
-        "Cannot call executeUpdate(String) on prepared or callable statement",
-      };
-      for (String sql : new String[]{drop, create, insert, update}) {
-        for (int i = 0; i <= 2; i++) {
-          try {
-            Object o;
-            switch (i) {
-            case 0:
-              o = pstmt.executeQuery(sql);
-              break;
-            case 1:
-              o = pstmt.execute(sql);
-              break;
-            default:
-              o = pstmt.executeUpdate(sql);
-            }
-            fail("expected error, got " + o);
-          } catch (SQLException e) {
-            assertThat(e.getMessage(), equalTo(messages[i]));
-          }
-        }
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testTypeHandling() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      final String query = "select * from EMP";
-      try (Connection cannon = canon();
-          Connection underTest = getLocalConnection();
-          Statement s1 = cannon.createStatement();
-          Statement s2 = underTest.createStatement()) {
-        assertTrue(s1.execute(query));
-        assertTrue(s2.execute(query));
-        assertResultSetsEqual(s1, s2);
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void assertResultSetsEqual(Statement s1, Statement s2)
-      throws SQLException {
-    final TimeZone moscowTz = TimeZone.getTimeZone("Europe/Moscow");
-    final Calendar moscowCalendar = Calendar.getInstance(moscowTz);
-    final TimeZone alaskaTz = TimeZone.getTimeZone("America/Anchorage");
-    final Calendar alaskaCalendar = Calendar.getInstance(alaskaTz);
-    try (ResultSet rs1 = s1.getResultSet();
-        ResultSet rs2 = s2.getResultSet()) {
-      assertEquals(rs1.getMetaData().getColumnCount(),
-          rs2.getMetaData().getColumnCount());
-      int colCount = rs1.getMetaData().getColumnCount();
-      while (rs1.next() && rs2.next()) {
-        for (int i = 0; i < colCount; i++) {
-          Object o1 = rs1.getObject(i + 1);
-          Object o2 = rs2.getObject(i + 1);
-          if (o1 instanceof Integer && o2 instanceof Short) {
-            // Hsqldb returns Integer for short columns; we prefer Short
-            o1 = ((Number) o1).shortValue();
-          }
-          if (o1 instanceof Integer && o2 instanceof Byte) {
-            // Hsqldb returns Integer for tinyint columns; we prefer Byte
-            o1 = ((Number) o1).byteValue();
-          }
-          if (o1 instanceof Date) {
-            Date d1 = rs1.getDate(i + 1, moscowCalendar);
-            Date d2 = rs2.getDate(i + 1, moscowCalendar);
-            assertEquals(d1, d2);
-            d1 = rs1.getDate(i + 1, alaskaCalendar);
-            d2 = rs2.getDate(i + 1, alaskaCalendar);
-            assertEquals(d1, d2);
-            d1 = rs1.getDate(i + 1, null);
-            d2 = rs2.getDate(i + 1, null);
-            assertEquals(d1, d2);
-            d1 = rs1.getDate(i + 1);
-            d2 = rs2.getDate(i + 1);
-            assertEquals(d1, d2);
-          }
-          if (o1 instanceof Timestamp) {
-            Timestamp d1 = rs1.getTimestamp(i + 1, moscowCalendar);
-            Timestamp d2 = rs2.getTimestamp(i + 1, moscowCalendar);
-            assertEquals(d1, d2);
-            d1 = rs1.getTimestamp(i + 1, alaskaCalendar);
-            d2 = rs2.getTimestamp(i + 1, alaskaCalendar);
-            assertEquals(d1, d2);
-            d1 = rs1.getTimestamp(i + 1, null);
-            d2 = rs2.getTimestamp(i + 1, null);
-            assertEquals(d1, d2);
-            d1 = rs1.getTimestamp(i + 1);
-            d2 = rs2.getTimestamp(i + 1);
-            assertEquals(d1, d2);
-          }
-          assertEquals(o1, o2);
-        }
-      }
-      assertEquals(rs1.next(), rs2.next());
-    }
-  }
-
-  /** Callback to set parameters on each prepared statement before
-   * each is executed and the result sets compared. */
-  interface PreparedStatementFunction {
-    void apply(PreparedStatement s1, PreparedStatement s2)
-        throws SQLException;
-  }
-
-  /** Callback to execute some code against a connection. */
-  interface ConnectionFunction {
-    void apply(Connection c1) throws Exception;
-  }
-
-  @Test public void testSetParameter() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      checkSetParameter("select ? from (values 1)",
-          new PreparedStatementFunction() {
-            public void apply(PreparedStatement s1, PreparedStatement s2)
-                throws SQLException {
-              final Date d = new Date(1234567890);
-              s1.setDate(1, d);
-              s2.setDate(1, d);
-            }
-          });
-      checkSetParameter("select ? from (values 1)",
-          new PreparedStatementFunction() {
-            public void apply(PreparedStatement s1, PreparedStatement s2)
-                throws SQLException {
-              final Timestamp ts = new Timestamp(123456789012L);
-              s1.setTimestamp(1, ts);
-              s2.setTimestamp(1, ts);
-            }
-          });
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  void checkSetParameter(String query, PreparedStatementFunction fn)
-      throws SQLException {
-    try (Connection cannon = canon();
-         Connection underTest = ljs();
-         PreparedStatement s1 = cannon.prepareStatement(query);
-         PreparedStatement s2 = underTest.prepareStatement(query)) {
-      fn.apply(s1, s2);
-      assertTrue(s1.execute());
-      assertTrue(s2.execute());
-      assertResultSetsEqual(s1, s2);
-    }
-  }
-
-  @Test public void testStatementLifecycle() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection connection = (AvaticaConnection) getLocalConnection()) {
-      Map<Integer, AvaticaStatement> clientMap = connection.statementMap;
-      Cache<Integer, Object> serverMap = getLocalConnectionInternals()
-          .getRemoteStatementMap(connection);
-      // Other tests being run might leave statements in the cache.
-      // The lock guards against more statements being cached during the test.
-      serverMap.invalidateAll();
-      assertEquals(0, clientMap.size());
-      assertEquals(0, serverMap.size());
-      Statement stmt = connection.createStatement();
-      assertEquals(1, clientMap.size());
-      assertEquals(1, serverMap.size());
-      stmt.close();
-      assertEquals(0, clientMap.size());
-      assertEquals(0, serverMap.size());
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testConnectionIsolation() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      Cache<String, Connection> connectionMap = getLocalConnectionInternals()
-          .getRemoteConnectionMap((AvaticaConnection) getLocalConnection());
-      // Other tests being run might leave connections in the cache.
-      // The lock guards against more connections being cached during the test.
-      connectionMap.invalidateAll();
-
-      final String sql = "select * from (values (1, 'a'))";
-      assertEquals("connection cache should start empty",
-          0, connectionMap.size());
-      Connection conn1 = getLocalConnection();
-      Connection conn2 = getLocalConnection();
-      assertEquals("we now have two connections open",
-          2, connectionMap.size());
-      PreparedStatement conn1stmt1 = conn1.prepareStatement(sql);
-      assertEquals(
-          "creating a statement does not cause new connection",
-          2, connectionMap.size());
-      PreparedStatement conn2stmt1 = conn2.prepareStatement(sql);
-      assertEquals(
-          "creating a statement does not cause new connection",
-          2, connectionMap.size());
-      AvaticaPreparedStatement s1 = (AvaticaPreparedStatement) conn1stmt1;
-      AvaticaPreparedStatement s2 = (AvaticaPreparedStatement) conn2stmt1;
-      assertFalse("connection id's should be unique",
-          s1.handle.connectionId.equalsIgnoreCase(s2.handle.connectionId));
-      conn2.close();
-      assertEquals("closing a connection closes the server-side connection",
-          1, connectionMap.size());
-      conn1.close();
-      assertEquals("closing a connection closes the server-side connection",
-          0, connectionMap.size());
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testPrepareBindExecuteFetch() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      getRequestInspection().getRequestLogger().enableAndClear();
-      checkPrepareBindExecuteFetch(getLocalConnection());
-      List<String[]> x = getRequestInspection().getRequestLogger().getAndDisable();
-      for (String[] pair : x) {
-        System.out.println(pair[0] + "=" + pair[1]);
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkPrepareBindExecuteFetch(Connection connection)
-      throws SQLException {
-    final String sql = "select cast(? as integer) * 3 as c, 'x' as x\n"
-        + "from (values (1, 'a'))";
-    final PreparedStatement ps =
-        connection.prepareStatement(sql);
-    final ResultSetMetaData metaData = ps.getMetaData();
-    assertEquals(2, metaData.getColumnCount());
-    assertEquals("C", metaData.getColumnName(1));
-    assertEquals("X", metaData.getColumnName(2));
-    try {
-      final ResultSet resultSet = ps.executeQuery();
-      fail("expected error, got " + resultSet);
-    } catch (SQLException e) {
-      assertThat(e.getMessage(),
-          containsString("exception while executing query: unbound parameter"));
-    }
-
-    final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
-    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
-
-    ps.setInt(1, 10);
-    final ResultSet resultSet = ps.executeQuery();
-    assertTrue(resultSet.next());
-    assertThat(resultSet.getInt(1), equalTo(30));
-    assertFalse(resultSet.next());
-    resultSet.close();
-
-    ps.setInt(1, 20);
-    final ResultSet resultSet2 = ps.executeQuery();
-    assertFalse(resultSet2.isClosed());
-    assertTrue(resultSet2.next());
-    assertThat(resultSet2.getInt(1), equalTo(60));
-    assertThat(resultSet2.wasNull(), is(false));
-    assertFalse(resultSet2.next());
-    resultSet2.close();
-
-    ps.setObject(1, null);
-    final ResultSet resultSet3 = ps.executeQuery();
-    assertTrue(resultSet3.next());
-    assertThat(resultSet3.getInt(1), equalTo(0));
-    assertThat(resultSet3.wasNull(), is(true));
-    assertFalse(resultSet3.next());
-    resultSet3.close();
-
-    ps.close();
-    connection.close();
-  }
-
-  @Test public void testPrepareBindExecuteFetchVarbinary() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      final Connection connection = getLocalConnection();
-      final String sql = "select x'de' || ? as c from (values (1, 'a'))";
-      final PreparedStatement ps =
-          connection.prepareStatement(sql);
-      final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
-      assertThat(parameterMetaData.getParameterCount(), equalTo(1));
-
-      ps.setBytes(1, new byte[]{65, 0, 66});
-      final ResultSet resultSet = ps.executeQuery();
-      assertTrue(resultSet.next());
-      assertThat(resultSet.getBytes(1),
-          equalTo(new byte[]{(byte) 0xDE, 65, 0, 66}));
-      resultSet.close();
-      ps.close();
-      connection.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testPrepareBindExecuteFetchDate() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      eachConnection(
-          new ConnectionFunction() {
-            public void apply(Connection c1) throws Exception {
-              checkPrepareBindExecuteFetchDate(c1);
-            }
-          }, getLocalConnection());
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkPrepareBindExecuteFetchDate(Connection connection) throws Exception {
-    final String sql0 =
-        "select cast(? as varchar(20)) as c\n"
-            + "from (values (1, 'a'))";
-    final String sql1 = "select ? + interval '2' day as c from (values (1, 'a'))";
-
-    final Date date = Date.valueOf("2015-04-08");
-    final long time = date.getTime();
-
-    PreparedStatement ps;
-    ParameterMetaData parameterMetaData;
-    ResultSet resultSet;
-
-    ps = connection.prepareStatement(sql0);
-    parameterMetaData = ps.getParameterMetaData();
-    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
-    ps.setDate(1, date);
-    resultSet = ps.executeQuery();
-    assertThat(resultSet.next(), is(true));
-    assertThat(resultSet.getString(1), is("2015-04-08"));
-
-    ps.setTimestamp(1, new Timestamp(time));
-    resultSet = ps.executeQuery();
-    assertThat(resultSet.next(), is(true));
-    assertThat(resultSet.getString(1), is("2015-04-08 00:00:00.0"));
-
-    ps.setTime(1, new Time(time));
-    resultSet = ps.executeQuery();
-    assertThat(resultSet.next(), is(true));
-    assertThat(resultSet.getString(1), is("00:00:00"));
-    ps.close();
-
-    ps = connection.prepareStatement(sql1);
-    parameterMetaData = ps.getParameterMetaData();
-    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
-
-    ps.setDate(1, date);
-    resultSet = ps.executeQuery();
-    assertTrue(resultSet.next());
-    assertThat(resultSet.getDate(1),
-        equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
-    assertThat(resultSet.getTimestamp(1),
-        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
-
-    ps.setTimestamp(1, new Timestamp(time));
-    resultSet = ps.executeQuery();
-    assertTrue(resultSet.next());
-    assertThat(resultSet.getTimestamp(1),
-        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
-    assertThat(resultSet.getTimestamp(1),
-        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
-
-    ps.setObject(1, new java.util.Date(time));
-    resultSet = ps.executeQuery();
-    assertTrue(resultSet.next());
-    assertThat(resultSet.getDate(1),
-        equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
-    assertThat(resultSet.getTimestamp(1),
-        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
-
-    resultSet.close();
-    ps.close();
-    connection.close();
-  }
-
-  @Test public void testDatabaseProperty() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      eachConnection(
-          new ConnectionFunction() {
-            public void apply(Connection c1) throws Exception {
-              checkDatabaseProperty(c1);
-            }
-          }, getLocalConnection());
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkDatabaseProperty(Connection connection)
-      throws SQLException {
-    final DatabaseMetaData metaData = connection.getMetaData();
-    assertThat(metaData.getSQLKeywords(), equalTo(""));
-    assertThat(metaData.getStringFunctions(),
-        equalTo("ASCII,CHAR,CONCAT,DIFFERENCE,HEXTORAW,INSERT,LCASE,LEFT,"
-            + "LENGTH,LOCATE,LTRIM,RAWTOHEX,REPEAT,REPLACE,RIGHT,RTRIM,SOUNDEX,"
-            + "SPACE,SUBSTR,UCASE"));
-    assertThat(metaData.getDefaultTransactionIsolation(),
-        equalTo(Connection.TRANSACTION_READ_COMMITTED));
-  }
-
-  /**
-   * Factory that creates a service based on a local JDBC connection.
-   */
-  public static class LocalJdbcServiceFactory implements Service.Factory {
-    @Override public Service create(AvaticaConnection connection) {
-      try {
-        return new LocalService(
-            new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
-                CONNECTION_SPEC.password));
-      } catch (SQLException e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  /**
-   * Factory that creates a fully-local Protobuf service.
-   */
-  public static class QuasiRemotePBJdbcServiceFactory implements Service.Factory {
-    private static Service service;
-
-    private static RequestInspection requestInspection;
-
-    static void initService() {
-      try {
-        final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
-            CONNECTION_SPEC.username, CONNECTION_SPEC.password);
-        final LocalService localService = new LocalService(jdbcMeta);
-        service = new LoggingLocalProtobufService(localService, new ProtobufTranslationImpl());
-        requestInspection = (RequestInspection) service;
-      } catch (SQLException e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-    @Override public Service create(AvaticaConnection connection) {
-      assert null != service;
-      return service;
-    }
-  }
-
-  /**
-   * Proxy that logs all requests passed into the {@link LocalProtobufService}.
-   */
-  public static class LoggingLocalProtobufService extends LocalProtobufService
-      implements RequestInspection {
-    private static final ThreadLocal<RequestLogger> THREAD_LOG =
-        new ThreadLocal<RequestLogger>() {
-          @Override protected RequestLogger initialValue() {
-            return new RequestLogger();
-          }
-        };
-
-    public LoggingLocalProtobufService(Service service, ProtobufTranslation translation) {
-      super(service, translation);
-    }
-
-    @Override public RequestLogger getRequestLogger() {
-      return THREAD_LOG.get();
-    }
-
-    @Override public Response _apply(Request request) {
-      final RequestLogger logger = THREAD_LOG.get();
-      try {
-        String jsonRequest = JsonService.MAPPER.writeValueAsString(request);
-        logger.requestStart(jsonRequest);
-
-        Response response = super._apply(request);
-
-        String jsonResponse = JsonService.MAPPER.writeValueAsString(response);
-        logger.requestEnd(jsonRequest, jsonResponse);
-
-        return response;
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  /**
-   * Factory that creates a service based on a local JDBC connection.
-   */
-  public static class QuasiRemoteJdbcServiceFactory implements Service.Factory {
-
-    /** a singleton instance that is recreated for each test */
-    private static Service service;
-
-    private static RequestInspection requestInspection;
-
-    static void initService() {
-      try {
-        final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
-            CONNECTION_SPEC.username, CONNECTION_SPEC.password);
-        final LocalService localService = new LocalService(jdbcMeta);
-        service = new LoggingLocalJsonService(localService);
-        requestInspection = (RequestInspection) service;
-      } catch (SQLException e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-    @Override public Service create(AvaticaConnection connection) {
-      assert service != null;
-      return service;
-    }
-  }
-
-  /**
-   * Implementation that reaches into current connection state via reflection to extract certain
-   * internal information.
-   */
-  public static class QuasiRemoteJdbcServiceInternals implements ConnectionInternals {
-
-    @Override public Cache<Integer, Object>
-    getRemoteStatementMap(AvaticaConnection connection) throws Exception {
-      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
-      metaF.setAccessible(true);
-      Meta clientMeta = (Meta) metaF.get(connection);
-      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
-      remoteMetaServiceF.setAccessible(true);
-      LocalJsonService remoteMetaService = (LocalJsonService) remoteMetaServiceF.get(clientMeta);
-      // Use the explicitly class to avoid issues with LoggingLocalJsonService
-      Field remoteMetaServiceServiceF = LocalJsonService.class.getDeclaredField("service");
-      remoteMetaServiceServiceF.setAccessible(true);
-      LocalService remoteMetaServiceService =
-          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
-      Field remoteMetaServiceServiceMetaF =
-          remoteMetaServiceService.getClass().getDeclaredField("meta");
-      remoteMetaServiceServiceMetaF.setAccessible(true);
-      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
-      Field jdbcMetaStatementMapF = JdbcMeta.class.getDeclaredField("statementCache");
-      jdbcMetaStatementMapF.setAccessible(true);
-      //noinspection unchecked
-      @SuppressWarnings("unchecked")
-      Cache<Integer, Object> cache = (Cache<Integer, Object>) jdbcMetaStatementMapF.get(serverMeta);
-      return cache;
-    }
-
-    @Override public Cache<String, Connection>
-    getRemoteConnectionMap(AvaticaConnection connection) throws Exception {
-      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
-      metaF.setAccessible(true);
-      Meta clientMeta = (Meta) metaF.get(connection);
-      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
-      remoteMetaServiceF.setAccessible(true);
-      LocalJsonService remoteMetaService = (LocalJsonService) remoteMetaServiceF.get(clientMeta);
-      // Get the field explicitly off the correct class to avoid LocalLoggingJsonService.class
-      Field remoteMetaServiceServiceF = LocalJsonService.class.getDeclaredField("service");
-      remoteMetaServiceServiceF.setAccessible(true);
-      LocalService remoteMetaServiceService =
-          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
-      Field remoteMetaServiceServiceMetaF =
-          remoteMetaServiceService.getClass().getDeclaredField("meta");
-      remoteMetaServiceServiceMetaF.setAccessible(true);
-      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
-      Field jdbcMetaConnectionCacheF = JdbcMeta.class.getDeclaredField("connectionCache");
-      jdbcMetaConnectionCacheF.setAccessible(true);
-      //noinspection unchecked
-      @SuppressWarnings("unchecked")
-      Cache<String, Connection> cache =
-          (Cache<String, Connection>) jdbcMetaConnectionCacheF.get(serverMeta);
-      return cache;
-    }
-  }
-
-  /**
-   * Implementation that reaches into current connection state via reflection to extract certain
-   * internal information.
-   */
-  public static class QuasiRemoteProtobufJdbcServiceInternals implements ConnectionInternals {
-
-    @Override public Cache<Integer, Object>
-    getRemoteStatementMap(AvaticaConnection connection) throws Exception {
-      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
-      metaF.setAccessible(true);
-      Meta clientMeta = (Meta) metaF.get(connection);
-      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
-      remoteMetaServiceF.setAccessible(true);
-      LocalProtobufService remoteMetaService =
-          (LocalProtobufService) remoteMetaServiceF.get(clientMeta);
-      // Use the explicitly class to avoid issues with LoggingLocalJsonService
-      Field remoteMetaServiceServiceF = LocalProtobufService.class.getDeclaredField("service");
-      remoteMetaServiceServiceF.setAccessible(true);
-      LocalService remoteMetaServiceService =
-          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
-      Field remoteMetaServiceServiceMetaF =
-          remoteMetaServiceService.getClass().getDeclaredField("meta");
-      remoteMetaServiceServiceMetaF.setAccessible(true);
-      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
-      Field jdbcMetaStatementMapF = JdbcMeta.class.getDeclaredField("statementCache");
-      jdbcMetaStatementMapF.setAccessible(true);
-      //noinspection unchecked
-      @SuppressWarnings("unchecked")
-      Cache<Integer, Object> cache = (Cache<Integer, Object>) jdbcMetaStatementMapF.get(serverMeta);
-      return cache;
-    }
-
-    @Override public Cache<String, Connection>
-    getRemoteConnectionMap(AvaticaConnection connection) throws Exception {
-      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
-      metaF.setAccessible(true);
-      Meta clientMeta = (Meta) metaF.get(connection);
-      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
-      remoteMetaServiceF.setAccessible(true);
-      LocalProtobufService remoteMetaService =
-          (LocalProtobufService) remoteMetaServiceF.get(clientMeta);
-      // Get the field explicitly off the correct class to avoid LocalLoggingJsonService.class
-      Field remoteMetaServiceServiceF = LocalProtobufService.class.getDeclaredField("service");
-      remoteMetaServiceServiceF.setAccessible(true);
-      LocalService remoteMetaServiceService =
-          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
-      Field remoteMetaServiceServiceMetaF =
-          remoteMetaServiceService.getClass().getDeclaredField("meta");
-      remoteMetaServiceServiceMetaF.setAccessible(true);
-      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
-      Field jdbcMetaConnectionCacheF = JdbcMeta.class.getDeclaredField("connectionCache");
-      jdbcMetaConnectionCacheF.setAccessible(true);
-      //noinspection unchecked
-      @SuppressWarnings("unchecked")
-      Cache<String, Connection> cache =
-          (Cache<String, Connection>) jdbcMetaConnectionCacheF.get(serverMeta);
-      return cache;
-    }
-  }
-
-  /**
-   * Provides access to a log of requests.
-   */
-  interface RequestInspection {
-    RequestLogger getRequestLogger();
-  }
-
-  /** Extension to {@link LocalJsonService} that writes requests and responses
-   * into a thread-local. */
-  private static class LoggingLocalJsonService extends LocalJsonService
-      implements RequestInspection {
-    private static final ThreadLocal<RequestLogger> THREAD_LOG =
-        new ThreadLocal<RequestLogger>() {
-          @Override protected RequestLogger initialValue() {
-            return new RequestLogger();
-          }
-        };
-
-    public LoggingLocalJsonService(LocalService localService) {
-      super(localService);
-    }
-
-    @Override public String apply(String request) {
-      final RequestLogger logger = THREAD_LOG.get();
-      logger.requestStart(request);
-      final String response = super.apply(request);
-      logger.requestEnd(request, response);
-      return response;
-    }
-
-    @Override public RequestLogger getRequestLogger() {
-      return THREAD_LOG.get();
-    }
-  }
-
-  /** Logs request and response strings if enabled. */
-  private static class RequestLogger {
-    final List<String[]> requestResponses = new ArrayList<>();
-    boolean enabled;
-
-    void enableAndClear() {
-      enabled = true;
-      requestResponses.clear();
-    }
-
-    void requestStart(String request) {
-      if (enabled) {
-        requestResponses.add(new String[]{request, null});
-      }
-    }
-
-    void requestEnd(String request, String response) {
-      if (enabled) {
-        String[] last = requestResponses.get(requestResponses.size() - 1);
-        if (!request.equals(last[0])) {
-          throw new AssertionError();
-        }
-        last[1] = response;
-      }
-    }
-
-    List<String[]> getAndDisable() {
-      enabled = false;
-      return new ArrayList<>(requestResponses);
-    }
-  }
-}
-
-// End RemoteDriverTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
deleted file mode 100644
index 48887b4..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
+++ /dev/null
@@ -1,46 +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.jdbc;
-
-import org.junit.Test;
-
-import java.sql.SQLException;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-/**
- * Unit tests for {@link JdbcMeta}.
- */
-public class JdbcMetaTest {
-
-  @Test public void testExceptionPropagation() throws SQLException {
-    JdbcMeta meta = new JdbcMeta("url");
-    final Throwable e = new Exception();
-    final RuntimeException rte;
-    try {
-      meta.propagate(e);
-      fail("Expected an exception to be thrown");
-    } catch (RuntimeException caughtException) {
-      rte = caughtException;
-      assertThat(rte.getCause(), is(e));
-    }
-  }
-}
-
-// End JdbcMetaTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
deleted file mode 100644
index 2984692..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
+++ /dev/null
@@ -1,138 +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.jdbc;
-
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.sql.ResultSet;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests covering {@link StatementInfo}.
- */
-public class StatementInfoTest {
-
-  @Test
-  public void testLargeOffsets() throws Exception {
-    Statement stmt = Mockito.mock(Statement.class);
-    ResultSet results = Mockito.mock(ResultSet.class);
-
-    StatementInfo info = new StatementInfo(stmt);
-
-    Mockito.when(results.relative(Integer.MAX_VALUE)).thenReturn(true, true);
-    Mockito.when(results.relative(1)).thenReturn(true);
-
-    long offset = 1L + Integer.MAX_VALUE + Integer.MAX_VALUE;
-    assertTrue(info.advanceResultSetToOffset(results, offset));
-
-    InOrder inOrder = Mockito.inOrder(results);
-
-    inOrder.verify(results, Mockito.times(2)).relative(Integer.MAX_VALUE);
-    inOrder.verify(results).relative(1);
-
-    assertEquals(offset, info.getPosition());
-  }
-
-  @Test
-  public void testNextUpdatesPosition() throws Exception {
-    Statement stmt = Mockito.mock(Statement.class);
-    ResultSet results = Mockito.mock(ResultSet.class);
-
-    StatementInfo info = new StatementInfo(stmt);
-    info.setResultSet(results);
-
-    Mockito.when(results.next()).thenReturn(true, true, true, false);
-
-    for (int i = 0; i < 3; i++) {
-      assertTrue(i + "th call of next() should return true", info.next());
-      assertEquals(info.getPosition(), i + 1);
-    }
-
-    assertFalse("Expected last next() to return false", info.next());
-    assertEquals(info.getPosition(), 4L);
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testNoMovement() throws Exception {
-    Statement stmt = Mockito.mock(Statement.class);
-    ResultSet results = Mockito.mock(ResultSet.class);
-
-    StatementInfo info = new StatementInfo(stmt);
-    info.setPosition(500);
-
-    info.advanceResultSetToOffset(results, 400);
-  }
-
-  @Test public void testResultSetGetter() throws Exception {
-    Statement stmt = Mockito.mock(Statement.class);
-    ResultSet results = Mockito.mock(ResultSet.class);
-
-    StatementInfo info = new StatementInfo(stmt);
-
-    assertFalse("ResultSet should not be initialized", info.isResultSetInitialized());
-    assertNull("ResultSet should be null", info.getResultSet());
-
-    info.setResultSet(results);
-
-    assertTrue("ResultSet should be initialized", info.isResultSetInitialized());
-    assertEquals(results, info.getResultSet());
-  }
-
-  @Test public void testCheckPositionAfterFailedRelative() throws Exception {
-    Statement stmt = Mockito.mock(Statement.class);
-    ResultSet results = Mockito.mock(ResultSet.class);
-    final long offset = 500;
-
-    StatementInfo info = new StatementInfo(stmt);
-    info.setResultSet(results);
-
-    // relative() doesn't work
-    Mockito.when(results.relative((int) offset)).thenThrow(new SQLFeatureNotSupportedException());
-    // Should fall back to next(), 500 calls to next, 1 false
-    Mockito.when(results.next()).then(new Answer<Boolean>() {
-      private long invocations = 0;
-
-      // Return true until 500, false after.
-      @Override public Boolean answer(InvocationOnMock invocation) throws Throwable {
-        invocations++;
-        if (invocations >= offset) {
-          return false;
-        }
-        return true;
-      }
-    });
-
-    info.advanceResultSetToOffset(results, offset);
-
-    // Verify correct position
-    assertEquals(offset, info.getPosition());
-    // Make sure that we actually advanced the result set
-    Mockito.verify(results, Mockito.times(500)).next();
-  }
-}
-
-// End StatementInfoTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
deleted file mode 100644
index 6f4c51e..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
+++ /dev/null
@@ -1,396 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.ConnectionConfig;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.ConnectionSpec;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.server.AvaticaJsonHandler;
-import org.apache.calcite.avatica.server.HttpServer;
-import org.apache.calcite.avatica.server.Main;
-import org.apache.calcite.avatica.server.Main.HandlerFactory;
-
-import com.google.common.cache.Cache;
-
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests that verify that the Driver still functions when requests are randomly bounced between
- * more than one server.
- */
-public class AlternatingRemoteMetaTest {
-  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
-
-  private static String url;
-
-  static {
-    try {
-      // Force DriverManager initialization before we hit AlternatingDriver->Driver.<clinit>
-      // Otherwise Driver.<clinit> -> DriverManager.registerDriver -> scan service provider files
-      // causes a deadlock; see [CALCITE-1060]
-      DriverManager.getDrivers();
-      DriverManager.registerDriver(new AlternatingDriver());
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  // Keep a reference to the servers we start to clean them up after
-  private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
-
-  /** Factory that provides a {@link JdbcMeta}. */
-  public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
-
-    private static JdbcMeta instance = null;
-
-    private static JdbcMeta getInstance() {
-      if (instance == null) {
-        try {
-          instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
-              CONNECTION_SPEC.password);
-        } catch (SQLException e) {
-          throw new RuntimeException(e);
-        }
-      }
-      return instance;
-    }
-
-    @Override public Meta create(List<String> args) {
-      return getInstance();
-    }
-  }
-
-  /**
-   * AvaticaHttpClient implementation that randomly chooses among the provided URLs.
-   */
-  public static class AlternatingAvaticaHttpClient implements AvaticaHttpClient {
-    private final List<AvaticaHttpClientImpl> clients;
-    private final Random r = new Random();
-
-    public AlternatingAvaticaHttpClient(List<URL> urls) {
-      //System.out.println("Constructing clients for " + urls);
-      clients = new ArrayList<>(urls.size());
-      for (URL url : urls) {
-        clients.add(new AvaticaHttpClientImpl(url));
-      }
-    }
-
-    public byte[] send(byte[] request) {
-      AvaticaHttpClientImpl client = clients.get(r.nextInt(clients.size()));
-      //System.out.println("URL: " + client.url);
-      return client.send(request);
-    }
-
-  }
-
-  /**
-   * Driver implementation {@link AlternatingAvaticaHttpClient}.
-   */
-  public static class AlternatingDriver extends Driver {
-
-    public static final String PREFIX = "jdbc:avatica:remote-alternating:";
-
-    @Override protected String getConnectStringPrefix() {
-      return PREFIX;
-    }
-
-    @Override public Meta createMeta(AvaticaConnection connection) {
-      final ConnectionConfig config = connection.config();
-      return new RemoteMeta(connection, new RemoteService(getHttpClient(connection, config)));
-    }
-
-    @Override AvaticaHttpClient getHttpClient(AvaticaConnection connection,
-        ConnectionConfig config) {
-      return new AlternatingAvaticaHttpClient(parseUrls(config.url()));
-    }
-
-    List<URL> parseUrls(String urlStr) {
-      final List<URL> urls = new ArrayList<>();
-      final char comma = ',';
-
-      int prevIndex = 0;
-      int index = urlStr.indexOf(comma);
-      if (-1 == index) {
-        try {
-          return Collections.singletonList(new URL(urlStr));
-        } catch (MalformedURLException e) {
-          throw new RuntimeException(e);
-        }
-      }
-
-      // String split w/o regex
-      while (-1 != index) {
-        try {
-          urls.add(new URL(urlStr.substring(prevIndex, index)));
-        } catch (MalformedURLException e) {
-          throw new RuntimeException(e);
-        }
-        prevIndex = index + 1;
-        index = urlStr.indexOf(comma, prevIndex);
-      }
-
-      // Get the last one
-      try {
-        urls.add(new URL(urlStr.substring(prevIndex)));
-      } catch (MalformedURLException e) {
-        throw new RuntimeException(e);
-      }
-
-      return urls;
-    }
-
-  }
-
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    final String[] mainArgs = new String[] { FullyRemoteJdbcMetaFactory.class.getName() };
-
-    // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
-
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < 2; i++) {
-      if (sb.length() > 0) {
-        sb.append(",");
-      }
-      HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
-        @Override public AbstractHandler createHandler(Service service) {
-          return new AvaticaJsonHandler(service);
-        }
-      });
-      ACTIVE_SERVERS.add(jsonServer);
-      sb.append("http://localhost:").append(jsonServer.getPort());
-    }
-
-    url = AlternatingDriver.PREFIX + "url=" + sb.toString();
-  }
-
-  @AfterClass public static void afterClass() throws Exception {
-    for (HttpServer server : ACTIVE_SERVERS) {
-      if (server != null) {
-        server.stop();
-      }
-    }
-  }
-
-  private static Meta getMeta(AvaticaConnection conn) throws Exception {
-    Field f = AvaticaConnection.class.getDeclaredField("meta");
-    f.setAccessible(true);
-    return (Meta) f.get(conn);
-  }
-
-  private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
-    final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
-    Method m =
-        AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
-            AvaticaStatement.class, String.class, long.class);
-    m.setAccessible(true);
-    return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
-  }
-
-  private static Connection getConnection(JdbcMeta m, String id) throws Exception {
-    Field f = JdbcMeta.class.getDeclaredField("connectionCache");
-    f.setAccessible(true);
-    //noinspection unchecked
-    Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
-    return connectionCache.getIfPresent(id);
-  }
-
-  @Test public void testRemoteExecuteMaxRowCount() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      final AvaticaStatement statement = conn.createStatement();
-      prepareAndExecuteInternal(conn, statement,
-        "select * from (values ('a', 1), ('b', 2))", 0);
-      ResultSet rs = statement.getResultSet();
-      int count = 0;
-      while (rs.next()) {
-        count++;
-      }
-      assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
-      assertEquals("Check result set meta is still there",
-        rs.getMetaData().getColumnCount(), 2);
-      rs.close();
-      statement.close();
-      conn.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  /** Test case for
-   * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
-   * HTTP error 413 when sending a long string to the Avatica server</a>. */
-  @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      // Before the bug was fixed, a value over 7998 caused an HTTP 413.
-      // 16K bytes, I guess.
-      checkLargeQuery(8);
-      checkLargeQuery(240);
-      checkLargeQuery(8000);
-      checkLargeQuery(240000);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkLargeQuery(int n) throws Exception {
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      final AvaticaStatement statement = conn.createStatement();
-      final String frenchDisko = "It said human existence is pointless\n"
-          + "As acts of rebellious solidarity\n"
-          + "Can bring sense in this world\n"
-          + "La resistance!\n";
-      final String sql = "select '"
-          + longString(frenchDisko, n)
-          + "' as s from (values 'x')";
-      prepareAndExecuteInternal(conn, statement, sql, -1);
-      ResultSet rs = statement.getResultSet();
-      int count = 0;
-      while (rs.next()) {
-        count++;
-      }
-      assertThat(count, is(1));
-      rs.close();
-      statement.close();
-      conn.close();
-    }
-  }
-
-  /** Creates a string of exactly {@code length} characters by concatenating
-   * {@code fragment}. */
-  private static String longString(String fragment, int length) {
-    assert fragment.length() > 0;
-    final StringBuilder buf = new StringBuilder();
-    while (buf.length() < length) {
-      buf.append(fragment);
-    }
-    buf.setLength(length);
-    return buf.toString();
-  }
-
-  @Test public void testRemoteConnectionProperties() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      String id = conn.id;
-      final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
-      assertFalse("remote connection map should start ignorant", m.containsKey(id));
-      // force creating a connection object on the remote side.
-      try (final Statement stmt = conn.createStatement()) {
-        assertTrue("creating a statement starts a local object.", m.containsKey(id));
-        assertTrue(stmt.execute("select count(1) from EMP"));
-      }
-      Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
-      final boolean defaultRO = remoteConn.isReadOnly();
-      final boolean defaultAutoCommit = remoteConn.getAutoCommit();
-      final String defaultCatalog = remoteConn.getCatalog();
-      final String defaultSchema = remoteConn.getSchema();
-      conn.setReadOnly(!defaultRO);
-      assertTrue("local changes dirty local state", m.get(id).isDirty());
-      assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
-      conn.setAutoCommit(!defaultAutoCommit);
-      assertEquals("remote connection has not been touched",
-          defaultAutoCommit, remoteConn.getAutoCommit());
-
-      // further interaction with the connection will force a sync
-      try (final Statement stmt = conn.createStatement()) {
-        assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
-        assertFalse("local values should be clean", m.get(id).isDirty());
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testQuery() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
-        Statement statement = conn.createStatement()) {
-      assertFalse(statement.execute("SET SCHEMA \"SCOTT\""));
-      assertFalse(
-          statement.execute(
-              "CREATE TABLE \"FOO\"(\"KEY\" INTEGER NOT NULL, \"VALUE\" VARCHAR(10))"));
-      assertFalse(statement.execute("SET TABLE \"FOO\" READONLY FALSE"));
-
-      final int numRecords = 1000;
-      for (int i = 0; i < numRecords; i++) {
-        assertFalse(statement.execute("INSERT INTO \"FOO\" VALUES(" + i + ", '" + i + "')"));
-      }
-
-      // Make sure all the records are there that we expect
-      ResultSet results = statement.executeQuery("SELECT count(KEY) FROM FOO");
-      assertTrue(results.next());
-      assertEquals(1000, results.getInt(1));
-      assertFalse(results.next());
-
-      results = statement.executeQuery("SELECT KEY, VALUE FROM FOO ORDER BY KEY ASC");
-      for (int i = 0; i < numRecords; i++) {
-        assertTrue(results.next());
-        assertEquals(i, results.getInt(1));
-        assertEquals(Integer.toString(i), results.getString(2));
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testSingleUrlParsing() throws Exception {
-    AlternatingDriver d = new AlternatingDriver();
-    List<URL> urls = d.parseUrls("http://localhost:1234");
-    assertEquals(Arrays.asList(new URL("http://localhost:1234")), urls);
-  }
-
-  @Test public void testMultipleUrlParsing() throws Exception {
-    AlternatingDriver d = new AlternatingDriver();
-    List<URL> urls = d.parseUrls("http://localhost:1234,http://localhost:2345,"
-        + "http://localhost:3456");
-    List<URL> expectedUrls = Arrays.asList(new URL("http://localhost:1234"),
-        new URL("http://localhost:2345"), new URL("http://localhost:3456"));
-    assertEquals(expectedUrls, urls);
-  }
-}
-
-// End AlternatingRemoteMetaTest.java


[52/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md b/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
deleted file mode 100644
index 6a2bde4..0000000
--- a/avatica/site/_posts/2015-09-02-release-1.4.0-incubating.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-layout: news_item
-date: "2015-09-02 12:00:00 +0000"
-author: jhyde
-version: 1.4.0-incubating
-categories: [release]
-tag: v1-4-0
-sha: 0c0c203d
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-In addition to a large number of bug fixes and minor enhancements,
-this release includes improvements to
-<a href="https://issues.apache.org/jira/browse/CALCITE-758">lattices</a> and
-<a href="https://issues.apache.org/jira/browse/CALCITE-761">materialized views</a>,
-and adds a
-<a href="https://issues.apache.org/jira/browse/CALCITE-748">builder API</a>
-so that you can easily create relational algebra expressions.
-
-Read more about the [builder]({{ site.baseurl }}/news/2015/06/05/algebra-builder/),
-[relational algebra]({{ site.baseurl }}/docs/algebra.html), and
-[lattices]({{ site.baseurl }}/docs/lattice.html).

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-10-22-calcite-graduates.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-10-22-calcite-graduates.md b/avatica/site/_posts/2015-10-22-calcite-graduates.md
deleted file mode 100644
index fb954cb..0000000
--- a/avatica/site/_posts/2015-10-22-calcite-graduates.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-layout: news_item
-date: "2015-10-22 12:00:00 +0000"
-author: jhyde
-categories: [milestones]
-tag: v1-4-0
-sha: 0c0c203d
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-On October 21st, 2015 the board of the
-[Apache Software Foundation](http://www.apache.org)
-voted to establish Calcite as a top-level Apache project.
-
-![Calcite's graduation cake]({{ site.baseurl }}/img/cake.jpg)
-
-Describing itself as "the foundation for your next high-performance
-database", Calcite is a
-[framework for building data management systems]({{ site.baseurl }}/docs/).
-Calcite includes a comprehensive implementation of relational algebra
-and an extensible cost-based query optimizer. It also includes an
-optional SQL parser and JDBC driver.
-
-Calcite joined Apache as an incubator project in May, 2014. To
-graduate from the incubator, projects have to prove that they can
-create high quality releases, form a diverse community, and operate as
-a meritocracy.
-
-Calcite's committers have delivered eight releases during incubation
-(roughly one every two months) including the
-[milestone 1.0 release in January, 2015]({{ site.baseurl }}/news/2015/01/31/release-1.0.0-incubating/).
-
-The project has become a key component in many high-performance
-databases, including the
-[Apache Drill](http://drill.apache.org),
-[Apache Hive](http://hive.apache.org),
-[Apache Kylin](http://kylin.apache.org) and
-[Apache Phoenix](http://phoenix.apache.org) open source projects,
-and several commercial products.
-
-Also, in collaboration with [Apache Samza](http://samza.apache.org) and
-[Apache Storm](http://storm.apache.org), Calcite is developing
-[streaming extensions to standard SQL]({{ site.baseurl }}/docs/stream.html).
-
-The Calcite community met at a hangout on October 27th, 2015, and
-celebrated with a graduation cake.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-11-08-new-committers.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-11-08-new-committers.md b/avatica/site/_posts/2015-11-08-new-committers.md
deleted file mode 100644
index 8946fc5..0000000
--- a/avatica/site/_posts/2015-11-08-new-committers.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-layout: news_item
-title: "Calcite adds 2 committers"
-date: "2015-11-08 19:03:07 -0800"
-author: jhyde
-categories: [team]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-The Calcite project management committee today added two new
-committers for their work on Calcite. Welcome!
-
-* [Josh Elser](http://mail-archives.apache.org/mod_mbox/incubator-calcite-dev/201511.mbox/%3CCAPSgeEQ4%2Bj8MNjYFaa%3D15QjJV%2BiVDwG6bAhW1muk8Gdo0UAYWg%40mail.gmail.com%3E)
-* [Maryann Xue](http://mail-archives.apache.org/mod_mbox/incubator-calcite-dev/201511.mbox/%3CCAPSgeEQg7ACNWfPXiPY69PNPqA9ov%2BKGzzrNe7t7mMyOEV7hYQ%40mail.gmail.com%3E)

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2015-11-10-release-1.5.0.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2015-11-10-release-1.5.0.md b/avatica/site/_posts/2015-11-10-release-1.5.0.md
deleted file mode 100644
index e4bb8d1..0000000
--- a/avatica/site/_posts/2015-11-10-release-1.5.0.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-layout: news_item
-date: "2015-11-10 12:00:00 +0000"
-author: jcamacho
-version: 1.5.0
-categories: [release]
-tag: v1-5-0
-sha: ba6e43c
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-This is our first release as a top-level Apache project! Thanks to everyone who has contributed to it.
-
-In addition to a large number of bug fixes and minor enhancements, this release includes major improvements to Avatica, planner rules, and RelBuilder.
-
-Further, we built Piglet, a subset of the classic Hadoop language Pig. Pig is particularly interesting because it makes heavy use of nested multi-sets. You can follow this example to implement your own query language, and immediately taking advantage of Calcite's back-ends and optimizer rules.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2016-01-22-release-1.6.0.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-01-22-release-1.6.0.md b/avatica/site/_posts/2016-01-22-release-1.6.0.md
deleted file mode 100644
index beb5267..0000000
--- a/avatica/site/_posts/2016-01-22-release-1.6.0.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-layout: news_item
-date: "2016-01-22 12:00:00 +0000"
-author: jhyde
-version: 1.6.0
-categories: [release]
-tag: v1-6-0
-sha: c4d346b
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-As usual in this release, there are new SQL features, improvements to
-planning rules and Avatica, and lots of bug fixes. We'll spotlight a
-couple of features make it easier to handle complex queries.
-
-[<a href="https://issues.apache.org/jira/browse/CALCITE-816">CALCITE-816</a>]
-allows you to represent sub-queries (`EXISTS`, `IN` and scalar) as
-<a href="{{ site.apiRoot }}/org/apache/calcite/rex/RexSubQuery.html">RexSubQuery</a>,
-a kind of expression in the relational algebra. Until
-now, the sql-to-rel converter was burdened with expanding sub-queries,
-and people creating relational algebra directly (or via
-<a href="{{ site.apiRoot }}/org/apache/calcite/tools/RelBuilder.html">RelBuilder</a>)
-could only create 'flat' relational expressions. Now we have planner
-rules to expand and de-correlate sub-queries.
-
-Metadata is the fuel that powers query planning. It includes
-traditional query-planning statistics such as cost and row-count
-estimates, but also information such as which columns form unique
-keys, unique and what predicates are known to apply to a relational
-expression's output rows. From the predicates we can deduce which
-columns are constant, and following
-[<a href="https://issues.apache.org/jira/browse/CALCITE-1023">CALCITE-1023</a>]
-we can now remove constant columns from `GROUP BY` keys.
-
-Metadata is often computed recursively, and it is hard to safely and
-efficiently calculate metadata on a graph of `RelNode`s that is large,
-frequently cyclic, and constantly changing.
-[<a href="https://issues.apache.org/jira/browse/CALCITE-794">CALCITE-794</a>]
-introduces a context to each metadata call. That context can detect
-cyclic metadata calls and produce a safe answer to the metadata
-request. It will also allow us to add finer-grained caching and
-further tune the metadata layer.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2016-02-17-elser-pmc.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-02-17-elser-pmc.md b/avatica/site/_posts/2016-02-17-elser-pmc.md
deleted file mode 100644
index 960fe79..0000000
--- a/avatica/site/_posts/2016-02-17-elser-pmc.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-layout: news_item
-title: "Calcite appoints Josh Elser to PMC"
-date: "2016-02-17 10:30:00 -0800"
-author: jhyde
-categories: [team]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-The Apache Calcite project management committee (PMC) today announced the
-appointment of [Josh Elser](https://mail-archives.apache.org/mod_mbox/calcite-dev/201602.mbox/%3C12AA8D09-BBF8-470B-8933-5B672162546C%40apache.org%3E)
-to the committee.
-
-Josh has only been a committer for a few months, but has become a prominent
-member of the Calcite project, and has taken leadership in several areas,
-not least in discussing [the future of Avatica](https://mail-archives.apache.org/mod_mbox/calcite-dev/201601.mbox/%3C56ABCCFF.3010205%40gmail.com%3E).

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-02-17-streaming-sql-talk.md b/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
deleted file mode 100644
index 9c5d55a..0000000
--- a/avatica/site/_posts/2016-02-17-streaming-sql-talk.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-layout: news_item
-title: "Streaming SQL in Samza"
-date: "2016-02-17 11:53:00 -0800"
-author: jhyde
-categories: ["talks"]
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-Julian Hyde gave a talk at the [Apache Samza](http://samza.apache.org/)
-meetup in Mountain View, CA.
-
-His talk asked the questions:
-
-* What is [SamzaSQL](https://github.com/milinda/samza-sql),
-  and what might I use it for?
-* Does this mean that Samza is turning into a database?
-* What is a query optimizer, and what can it do for my streaming queries?
-
-The talk is available in
-[[slides](http://www.slideshare.net/julianhyde/streaming-sql)]
-and
-[[video](http://www.ustream.tv/recorded/83322450#to00:55:48)].

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2016-03-03-separate-project.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-03-03-separate-project.md b/avatica/site/_posts/2016-03-03-separate-project.md
new file mode 100644
index 0000000..6fee099
--- /dev/null
+++ b/avatica/site/_posts/2016-03-03-separate-project.md
@@ -0,0 +1,32 @@
+---
+layout: news_item
+title: "Splitting Avatica from Calcite"
+date: "2016-03-03 23:57:33 -0500"
+author: elserj
+categories: [milestones]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+This marks the separation of Avatica from it's previous location as a sub-module
+of Apache Calcite's Maven build. This separation is not to remove Avatica from
+the governance of the Apache Calcite project, but to allow for even more rapid
+releases from both the Avatica and Calcite projects. We can confidently make new
+releases of each without having to worry about the current state of development
+features in the other.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_posts/2016-03-03-tbd-release.md
----------------------------------------------------------------------
diff --git a/avatica/site/_posts/2016-03-03-tbd-release.md b/avatica/site/_posts/2016-03-03-tbd-release.md
new file mode 100644
index 0000000..f6ec926
--- /dev/null
+++ b/avatica/site/_posts/2016-03-03-tbd-release.md
@@ -0,0 +1,30 @@
+---
+layout: news_item
+title: "Avatica x.y.z"
+date: "2016-03-03 23:57:33 -0500"
+author: elserj
+version: 9.9.9
+tag: v9-9-9
+sha: abcdef
+categories: [release]
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Apache Calcite is happy to release Avatica x.y.z.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/community/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/community/index.md b/avatica/site/community/index.md
index b0c9fdb..14b81dc 100644
--- a/avatica/site/community/index.md
+++ b/avatica/site/community/index.md
@@ -67,50 +67,4 @@ Need help with Calcite? Try these resources:
   your question.
 * **Browse the code**.
   One of the advantages of open source software is that you can browse the code.
-  The code is available on [github](https://github.com/apache/calcite/tree/master).
-
-# Talks
-
-Want to learn more about Calcite?
-
-Watch some presentations and read through some slide decks about Calcite.
-
-## Apache Calcite: One planner fits all
-
-Voted [Best Lightning Talk at XLDB-2015](http://www.xldb.org/archives/2015/05/best-lightning-talks-selected/);
-[[video](https://www.youtube.com/watch?v=5_MyORYjq3w)],
-[[slides](http://www.slideshare.net/julianhyde/apache-calcite-one-planner-fits-all)].
-
-{% oembed https://www.youtube.com/watch?v=5_MyORYjq3w %}
-
-## Why you care about relational algebra (even though you didn't know it)
-
-Washington DC, April 2015;
-[[slides](http://www.slideshare.net/julianhyde/calcite-algebraedw2015)].
-
-<iframe src="//www.slideshare.net/slideshow/embed_code/key/vfVDu6y1mAM5Dl" width="629" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
-
-## Apache Calcite overview
-
-Apache Kylin meetup, 2014;
-[[slides](http://www.slideshare.net/julianhyde/apache-calcite-overview)].
-
-<iframe src="//www.slideshare.net/slideshow/embed_code/key/fCGsAedsQiq53V" width="629" height="354" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
-
-## Streaming SQL
-
-At Samza meetup, Mountain View, CA, 2016
-[[video](http://www.ustream.tv/recorded/83322450#to00:55:48)],
-[[slides](http://www.slideshare.net/julianhyde/streaming-sql)].
-
-<iframe src="//www.slideshare.net/slideshow/embed_code/key/rzaptOy3H8K6Gz" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
-
-## More talks
-
-* <a href="https://github.com/julianhyde/share/blob/master/slides/hive-cbo-seattle-2014.pdf?raw=true">Cost-based optimization in Hive 0.14</a> (Seattle, 2014)
-* <a href="https://github.com/julianhyde/share/blob/master/slides/dmmq-summit-2014.pdf?raw=true">Discardable, in-memory materialized query for Hadoop</a> (<a href="https://www.youtube.com/watch?v=CziGOa8GXqI">video</a>) (Hadoop Summit, 2014)
-* <a href="https://github.com/julianhyde/share/blob/master/slides/hive-cbo-summit-2014.pdf?raw=true">Cost-based optimization in Hive</a> (<a href="https://www.youtube.com/watch?v=vpG5noIbEFs">video</a>) (Hadoop Summit, 2014)
-* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-nosql-now-2013.pdf?raw=true">SQL Now!</a> (NoSQL Now! conference, 2013)
-* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-richrelevance-2013.pdf?raw=true">SQL on Big Data using Optiq</a> (2013)
-* <a href="https://github.com/julianhyde/share/blob/master/slides/optiq-drill-user-group-2013.pdf?raw=true">Drill / SQL / Optiq</a> (2013)
-* <a href="http://www.slideshare.net/julianhyde/how-to-integrate-splunk-with-any-data-solution">How to integrate Splunk with any data solution</a> (Splunk User Conference, 2012)
+  The code is available on [github](https://github.com/apache/calcite/tree/master/avatica).

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/develop/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/develop/index.md b/avatica/site/develop/index.md
index c2b11f3..f32836f 100644
--- a/avatica/site/develop/index.md
+++ b/avatica/site/develop/index.md
@@ -48,7 +48,7 @@ then build using maven:
 
 {% highlight bash %}
 $ git clone git://github.com/apache/calcite.git
-$ cd calcite
+$ cd calcite/avatica
 $ mvn install
 {% endhighlight %}
 
@@ -91,7 +91,7 @@ changes.
 
 Calcite has a collection of Jenkins jobs on ASF-hosted infrastructure.
 They are all organized in a single view and available at
-[https://builds.apache.org/view/A-D/view/Calcite/](https://builds.apache.org/view/A-D/view/Calcite/).
+[https://builds.apache.org/view/A-D/view/Calcite-Avatica/](https://builds.apache.org/view/A-D/view/Calcite-Avatica/).
 
 ## Getting started
 
@@ -114,4 +114,3 @@ We value all contributions that help to build a vibrant community, not just code
 You can contribute by testing the code, helping verify a release,
 writing documentation or the web site,
 or just by answering questions on the list.
-

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/doap_calcite.rdf
----------------------------------------------------------------------
diff --git a/avatica/site/doap_calcite.rdf b/avatica/site/doap_calcite.rdf
deleted file mode 100644
index 46204e9..0000000
--- a/avatica/site/doap_calcite.rdf
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl"?>
-<rdf:RDF xml:lang="en"
-         xmlns="http://usefulinc.com/ns/doap#"
-         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns:asfext="http://projects.apache.org/ns/asfext#"
-         xmlns:foaf="http://xmlns.com/foaf/0.1/">
-<!--
-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.
--->
-  <Project rdf:about="https://calcite.apache.org">
-    <created>2015-05-27</created>
-    <license rdf:resource="http://spdx.org/licenses/Apache-2.0" />
-    <name>Apache Calcite</name>
-    <homepage rdf:resource="https://calcite.apache.org" />
-    <asfext:pmc rdf:resource="https://calcite.apache.org" />
-    <shortdesc>A dynamic data management framework.</shortdesc>
-    <description>Calcite is a framework for writing data management
-      systems.  It converts queries, represented in relational algebra,
-      into an efficient executable form using pluggable query
-      transformation rules. There is an optional SQL parser and JDBC
-      driver. Calcite does not store data or have a preferred execution
-      engine. Data formats, execution algorithms, planning rules,
-      operator types, metadata, and cost model are added at runtime as
-      plugins.</description>
-    <bug-database rdf:resource="https://issues.apache.org/jira/browse/CALCITE" />
-    <mailing-list rdf:resource="https://calcite.apache.org/develop" />
-    <download-page rdf:resource="https://calcite.apache.org/downloads" />
-    <programming-language>Java</programming-language>
-    <category rdf:resource="http://projects.apache.org/category/big-data" />
-    <category rdf:resource="http://projects.apache.org/category/hadoop" />
-    <category rdf:resource="http://projects.apache.org/category/sql" />
-    <repository>
-      <GitRepository>
-        <location rdf:resource="https://git-wip-us.apache.org/repos/asf/calcite.git"/>
-        <browse rdf:resource="https://github.com/apache/calcite"/>
-      </GitRepository>
-    </repository>
-    <maintainer>
-      <foaf:Person>
-        <foaf:name>Julian Hyde</foaf:name>
-          <foaf:mbox rdf:resource="mailto:jhyde@apache.org"/>
-      </foaf:Person>
-    </maintainer>
-  </Project>
-</rdf:RDF>

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/downloads/index.md
----------------------------------------------------------------------
diff --git a/avatica/site/downloads/index.md b/avatica/site/downloads/index.md
index 7faead0..74e9225 100644
--- a/avatica/site/downloads/index.md
+++ b/avatica/site/downloads/index.md
@@ -88,13 +88,9 @@ Add the following to the dependencies section of your `pom.xml` file:
 {% highlight xml %}
 <dependencies>
   <dependency>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite-core</artifactId>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica</artifactId>
     <version>{{ current_release.version }}</version>
   </dependency>
 </dependencies>
 {% endhighlight %}
-
-Also include `<dependency>` elements for any extension modules you
-need: `calcite-mongodb`, `calcite-spark`, `calcite-splunk`, and so
-forth.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/index.html
----------------------------------------------------------------------
diff --git a/avatica/site/index.html b/avatica/site/index.html
index 8857d27..5bb3ff8 100644
--- a/avatica/site/index.html
+++ b/avatica/site/index.html
@@ -23,29 +23,18 @@ limitations under the License.
 <section class="intro">
   <div class="grid">
     <div class="unit whole center-on-mobiles">
-      <p class="first">The foundation for your next high-performance database.</p>
+      <p class="first">Avatica is a framework for building database drivers.</p>
     </div>
   </div>
 </section>
 <section class="features">
   <div class="grid">
-    <div class="unit one-third">
-      <h2>Standard SQL</h2>
-      <p>Industry-standard SQL parser, validator and JDBC driver.</p>
-      <a href="{{ site.baseurl }}/docs/reference.html">SQL &rarr;</a>
-    </div>
-    <div class="unit one-third">
-      <h2>Query optimization</h2>
-      <p>Represent your query in relational algebra, transform using
-        planning rules, and optimize according to a cost model.</p>
-      <a href="{{ site.baseurl }}/docs/algebra.html">Relational algebra &rarr;</a>
-    </div>
-    <div class="unit one-third">
-      <h2>Any data, anywhere</h2>
-      <p>Connect to third-party data sources, browse metadata, and optimize by pushing the computation to the data.</p>
-      <a href="{{ site.baseurl }}/docs/adapter.html">Adapters &rarr;</a>
+    <div class="unit whole center-on-mobiles">
+      <p>Avatica is defined by a wire API between a client and a server. The Avatica server is
+      an HTTP server, the Avatica client is a JDBC driver, and the wire API is defined by
+      JSON or Protobuf Buffers. The flexibility of the wire API and HTTP transport allows
+      other Avatica clients to be built in any language, implementing any client specification.</p>
     </div>
-    <div class="clear"></div>
   </div>
 </section>
 <section class="resources">

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/site/index.html
----------------------------------------------------------------------
diff --git a/site/index.html b/site/index.html
index 8857d27..33ed466 100644
--- a/site/index.html
+++ b/site/index.html
@@ -71,5 +71,13 @@ limitations under the License.
         </ul>
       </summary>
     </div>
+    <div class="unit one-third">
+      <summary>
+        <h3>Sub-Projects</h3>
+        <ul>
+          <li><a href="{{ site.baseurl }}/avatica">Avatica</a></li>
+        </ul>
+      </summary>
+    </div>
   </div>
 </section>


[37/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
new file mode 100644
index 0000000..1968fcd
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractHandler.java
@@ -0,0 +1,154 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.NoSuchConnectionException;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import java.io.IOException;
+
+/**
+ * Abstract base class for {@link Handler}s to extend to inherit functionality common across
+ * serialization strategies.
+ *
+ * @param <T> The format Requests/Responses are serialized as.
+ */
+public abstract class AbstractHandler<T> implements Handler<T> {
+  private static final String NULL_EXCEPTION_MESSAGE = "(null exception message)";
+  protected final Service service;
+  private RpcMetadataResponse metadata = null;
+
+  public AbstractHandler(Service service) {
+    this.service = service;
+  }
+
+  abstract Request decode(T serializedRequest) throws IOException;
+
+  /**
+   * Serialize the given {@link Response} per the concrete {@link Handler} implementation.
+   *
+   * @param response The {@link Response} to serialize.
+   * @return A serialized representation of the {@link Response}.
+   * @throws IOException
+   */
+  abstract T encode(Response response) throws IOException;
+
+  /**
+   * Unwrap Avatica-specific context about a given exception.
+   *
+   * @param e A caught exception throw by Avatica implementation.
+   * @return An {@link ErrorResponse}.
+   */
+  ErrorResponse unwrapException(Exception e) {
+    // By default, we know nothing extra.
+    int errorCode = ErrorResponse.UNKNOWN_ERROR_CODE;
+    String sqlState = ErrorResponse.UNKNOWN_SQL_STATE;
+    AvaticaSeverity severity = AvaticaSeverity.UNKNOWN;
+    String errorMsg = null;
+
+    // Extract the contextual information if we have it. We may not.
+    if (e instanceof AvaticaRuntimeException) {
+      AvaticaRuntimeException rte = (AvaticaRuntimeException) e;
+      errorCode = rte.getErrorCode();
+      sqlState = rte.getSqlState();
+      severity = rte.getSeverity();
+      errorMsg = rte.getErrorMessage();
+    } else if (e instanceof NoSuchConnectionException) {
+      errorCode = ErrorResponse.MISSING_CONNECTION_ERROR_CODE;
+      severity = AvaticaSeverity.ERROR;
+      errorMsg = e.getMessage();
+    } else {
+      // Try to construct a meaningful error message when the server impl doesn't provide one.
+      errorMsg = getCausalChain(e);
+    }
+
+    return new ErrorResponse(e, errorMsg, errorCode, sqlState, severity, metadata);
+  }
+
+  /**
+   * Compute a response for the given request, handling errors generated by that computation.
+   *
+   * @param serializedRequest The caller's request.
+   * @return A {@link Response} with additional context about that response.
+   */
+  public HandlerResponse<T> apply(T serializedRequest) {
+    final Service.Request request;
+    try {
+      request = decode(serializedRequest);
+    } catch (IOException e) {
+      // TODO provide a canned ErrorResponse.
+      throw new RuntimeException(e);
+    }
+
+    try {
+      final Service.Response response = request.accept(service);
+      return new HandlerResponse<>(encode(response), HTTP_OK);
+    } catch (Exception e) {
+      ErrorResponse errorResp = unwrapException(e);
+
+      try {
+        return new HandlerResponse<>(encode(errorResp), HTTP_INTERNAL_SERVER_ERROR);
+      } catch (IOException e1) {
+        // TODO provide a canned ErrorResponse
+
+        // If we can't serialize error message to JSON, can't give a meaningful error to caller.
+        // Just try to not unnecessarily create more exceptions.
+        if (e instanceof RuntimeException) {
+          throw (RuntimeException) e;
+        }
+
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /**
+   * Constructs a message for the summary of an Exception.
+   *
+   * @param e The Exception to summarize.
+   * @return A summary message for the Exception.
+   */
+  private String getCausalChain(Exception e) {
+    StringBuilder sb = new StringBuilder(16);
+    Throwable curr = e;
+    // Could use Guava, but that would increase dependency set unnecessarily.
+    while (null != curr) {
+      if (sb.length() > 0) {
+        sb.append(" -> ");
+      }
+      String message = curr.getMessage();
+      sb.append(curr.getClass().getSimpleName()).append(": ");
+      sb.append(null == message ? NULL_EXCEPTION_MESSAGE : message);
+      curr = curr.getCause();
+    }
+    if (sb.length() == 0) {
+      // Catch the case where we have no error message.
+      return "Unknown error message";
+    }
+    return sb.toString();
+  }
+
+  @Override public void setRpcMetadata(RpcMetadataResponse metadata) {
+    this.metadata = metadata;
+  }
+}
+
+// End AbstractHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
new file mode 100644
index 0000000..ffaa360
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AbstractService.java
@@ -0,0 +1,159 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.Meta;
+
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A common base class for {@link Service} implementations that implement
+ * modifications made to response objects.
+ */
+public abstract class AbstractService implements Service {
+
+  private RpcMetadataResponse rpcMetadata = null;
+
+  /**
+   * Represents the serialization of the data over a transport.
+   */
+  enum SerializationType {
+    JSON,
+    PROTOBUF
+  }
+
+  /**
+   * @return The manner in which the data is serialized.
+   */
+  abstract SerializationType getSerializationType();
+
+  /** Modifies a signature, changing the representation of numeric columns
+   * within it. This deals with the fact that JSON transmits a small long value,
+   * or a float which is a whole number, as an integer. Thus the accessors need
+   * be prepared to accept any numeric type. */
+  Meta.Signature finagle(Meta.Signature signature) {
+    final List<ColumnMetaData> columns = new ArrayList<>();
+    for (ColumnMetaData column : signature.columns) {
+      columns.add(finagle(column));
+    }
+    if (columns.equals(signature.columns)) {
+      return signature;
+    }
+    return new Meta.Signature(columns, signature.sql,
+        signature.parameters, signature.internalParameters,
+        signature.cursorFactory, signature.statementType);
+  }
+
+  ColumnMetaData finagle(ColumnMetaData column) {
+    switch (column.type.rep) {
+    case BYTE:
+    case PRIMITIVE_BYTE:
+    case DOUBLE:
+    case PRIMITIVE_DOUBLE:
+    case FLOAT:
+    case PRIMITIVE_FLOAT:
+    case INTEGER:
+    case PRIMITIVE_INT:
+    case SHORT:
+    case PRIMITIVE_SHORT:
+    case LONG:
+    case PRIMITIVE_LONG:
+      return column.setRep(ColumnMetaData.Rep.NUMBER);
+    default:
+      // continue
+      break;
+    }
+    switch (column.type.id) {
+    case Types.VARBINARY:
+    case Types.BINARY:
+      switch (getSerializationType()) {
+      case JSON:
+        return column.setRep(ColumnMetaData.Rep.STRING);
+      case PROTOBUF:
+        return column;
+      default:
+        throw new IllegalStateException("Unhadled case statement");
+      }
+    case Types.DECIMAL:
+    case Types.NUMERIC:
+      return column.setRep(ColumnMetaData.Rep.NUMBER);
+    default:
+      return column;
+    }
+  }
+
+  PrepareResponse finagle(PrepareResponse response) {
+    final Meta.StatementHandle statement = finagle(response.statement);
+    if (statement == response.statement) {
+      return response;
+    }
+    return new PrepareResponse(statement, rpcMetadata);
+  }
+
+  Meta.StatementHandle finagle(Meta.StatementHandle h) {
+    final Meta.Signature signature = finagle(h.signature);
+    if (signature == h.signature) {
+      return h;
+    }
+    return new Meta.StatementHandle(h.connectionId, h.id, signature);
+  }
+
+  ResultSetResponse finagle(ResultSetResponse r) {
+    if (r.updateCount != -1) {
+      assert r.signature == null;
+      return r;
+    }
+    if (r.signature == null) {
+      return r;
+    }
+    final Meta.Signature signature = finagle(r.signature);
+    if (signature == r.signature) {
+      return r;
+    }
+    return new ResultSetResponse(r.connectionId, r.statementId, r.ownStatement,
+        signature, r.firstFrame, r.updateCount, rpcMetadata);
+  }
+
+  ExecuteResponse finagle(ExecuteResponse r) {
+    if (r.missingStatement) {
+      return r;
+    }
+    final List<ResultSetResponse> results = new ArrayList<>();
+    int changeCount = 0;
+    for (ResultSetResponse result : r.results) {
+      ResultSetResponse result2 = finagle(result);
+      if (result2 != result) {
+        ++changeCount;
+      }
+      results.add(result2);
+    }
+    if (changeCount == 0) {
+      return r;
+    }
+    return new ExecuteResponse(results, r.missingStatement, rpcMetadata);
+  }
+
+  @Override public void setRpcMetadata(RpcMetadataResponse metadata) {
+    // OK if this is null
+    this.rpcMetadata = metadata;
+  }
+}
+
+// End AbstractService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
new file mode 100644
index 0000000..3bda248
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaCommonsHttpClientImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.remote;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.protocol.RequestExpectContinue;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.pool.BasicConnFactory;
+import org.apache.http.impl.pool.BasicConnPool;
+import org.apache.http.impl.pool.BasicPoolEntry;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.protocol.HttpCoreContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.protocol.RequestConnControl;
+import org.apache.http.protocol.RequestContent;
+import org.apache.http.protocol.RequestTargetHost;
+import org.apache.http.util.EntityUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.concurrent.Future;
+
+/**
+ * A common class to invoke HTTP requests against the Avatica server agnostic of the data being
+ * sent and received across the wire.
+ */
+public class AvaticaCommonsHttpClientImpl implements AvaticaHttpClient {
+  private static final Logger LOG = LoggerFactory.getLogger(AvaticaCommonsHttpClientImpl.class);
+  private static final ConnectionReuseStrategy REUSE = DefaultConnectionReuseStrategy.INSTANCE;
+
+  // Some basic exposed configurations
+  private static final String MAX_POOLED_CONNECTION_PER_ROUTE_KEY =
+      "avatica.pooled.connections.per.route";
+  private static final String MAX_POOLED_CONNECTION_PER_ROUTE_DEFAULT = "4";
+  private static final String MAX_POOLED_CONNECTIONS_KEY = "avatica.pooled.connections.max";
+  private static final String MAX_POOLED_CONNECTIONS_DEFAULT = "16";
+
+  protected final HttpHost host;
+  protected final HttpProcessor httpProcessor;
+  protected final HttpRequestExecutor httpExecutor;
+  protected final BasicConnPool httpPool;
+
+  public AvaticaCommonsHttpClientImpl(URL url) {
+    this.host = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
+
+    this.httpProcessor = HttpProcessorBuilder.create()
+        .add(new RequestContent())
+        .add(new RequestTargetHost())
+        .add(new RequestConnControl())
+        .add(new RequestExpectContinue()).build();
+
+    this.httpExecutor = new HttpRequestExecutor();
+
+    this.httpPool = new BasicConnPool(new BasicConnFactory());
+    int maxPerRoute = Integer.parseInt(
+        System.getProperty(MAX_POOLED_CONNECTION_PER_ROUTE_KEY,
+            MAX_POOLED_CONNECTION_PER_ROUTE_DEFAULT));
+    int maxTotal = Integer.parseInt(
+        System.getProperty(MAX_POOLED_CONNECTIONS_KEY,
+            MAX_POOLED_CONNECTIONS_DEFAULT));
+    httpPool.setDefaultMaxPerRoute(maxPerRoute);
+    httpPool.setMaxTotal(maxTotal);
+  }
+
+  public byte[] send(byte[] request) {
+    while (true) {
+      boolean reusable = false;
+      // Get a connection from the pool
+      Future<BasicPoolEntry> future = this.httpPool.lease(host, null);
+      BasicPoolEntry entry = null;
+      try {
+        entry = future.get();
+        HttpCoreContext coreContext = HttpCoreContext.create();
+        coreContext.setTargetHost(host);
+
+        HttpClientConnection conn = entry.getConnection();
+
+        ByteArrayEntity entity = new ByteArrayEntity(request, ContentType.APPLICATION_OCTET_STREAM);
+
+        BasicHttpEntityEnclosingRequest postRequest =
+            new BasicHttpEntityEnclosingRequest("POST", "/");
+        postRequest.setEntity(entity);
+
+        httpExecutor.preProcess(postRequest, httpProcessor, coreContext);
+        HttpResponse response = httpExecutor.execute(postRequest, conn, coreContext);
+        httpExecutor.postProcess(response, httpProcessor, coreContext);
+
+        // Should the connection be kept alive?
+        reusable = REUSE.keepAlive(response, coreContext);
+
+        final int statusCode = response.getStatusLine().getStatusCode();
+        if (HttpURLConnection.HTTP_UNAVAILABLE == statusCode) {
+          // Could be sitting behind a load-balancer, try again.
+          continue;
+        }
+
+        return EntityUtils.toByteArray(response.getEntity());
+      } catch (Exception e) {
+        LOG.debug("Failed to execute HTTP request", e);
+        throw new RuntimeException(e);
+      } finally {
+        // Release the connection back to the pool, marking if it's good to reuse or not.
+        httpPool.release(entry, reusable);
+      }
+    }
+  }
+}
+
+// End AvaticaCommonsHttpClientImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
new file mode 100644
index 0000000..eac1b74
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClient.java
@@ -0,0 +1,34 @@
+/*
+ * 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.remote;
+
+/**
+ * An interface which defines how requests are sent to the Avatica server.
+ */
+public interface AvaticaHttpClient {
+
+  /**
+   * Sends a serialized request to the Avatica server.
+   *
+   * @param request The serialized request.
+   * @return The serialized response.
+   */
+  byte[] send(byte[] request);
+
+}
+
+// End AvaticaHttpClient.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
new file mode 100644
index 0000000..b5d213a
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ConnectionConfig;
+
+import java.net.URL;
+
+/**
+ * A factory for constructing {@link AvaticaHttpClient}'s.
+ */
+public interface AvaticaHttpClientFactory {
+
+  /**
+   * Construct the appropriate implementation of {@link AvaticaHttpClient}.
+   *
+   * @param url URL that the client is for.
+   * @param config Configuration to use when constructing the implementation.
+   * @return An instance of {@link AvaticaHttpClient}.
+   */
+  AvaticaHttpClient getClient(URL url, ConnectionConfig config);
+
+}
+
+// End AvaticaHttpClientFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
new file mode 100644
index 0000000..cd6cbce
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientFactoryImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ConnectionConfig;
+
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Objects;
+
+/**
+ * Default implementation of {@link AvaticaHttpClientFactory} which chooses an implementation
+ * from a property.
+ */
+public class AvaticaHttpClientFactoryImpl implements AvaticaHttpClientFactory {
+  public static final String HTTP_CLIENT_IMPL_DEFAULT =
+      AvaticaCommonsHttpClientImpl.class.getName();
+
+  // Public for Type.PLUGIN
+  public static final AvaticaHttpClientFactoryImpl INSTANCE = new AvaticaHttpClientFactoryImpl();
+
+  // Public for Type.PLUGIN
+  public AvaticaHttpClientFactoryImpl() {}
+
+  /**
+   * Returns a singleton instance of {@link AvaticaHttpClientFactoryImpl}.
+   *
+   * @return A singleton instance.
+   */
+  public static AvaticaHttpClientFactoryImpl getInstance() {
+    return INSTANCE;
+  }
+
+  @Override public AvaticaHttpClient getClient(URL url, ConnectionConfig config) {
+    String className = config.httpClientClass();
+    if (null == className) {
+      className = HTTP_CLIENT_IMPL_DEFAULT;
+    }
+
+    try {
+      Class<?> clz = Class.forName(className);
+      Constructor<?> constructor = clz.getConstructor(URL.class);
+      Object instance = constructor.newInstance(Objects.requireNonNull(url));
+      return AvaticaHttpClient.class.cast(instance);
+    } catch (Exception e) {
+      throw new RuntimeException("Failed to construct AvaticaHttpClient implementation "
+          + className, e);
+    }
+  }
+}
+
+// End AvaticaHttpClientFactoryImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
new file mode 100644
index 0000000..c100eec
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaHttpClientImpl.java
@@ -0,0 +1,73 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * A common class to invoke HTTP requests against the Avatica server agnostic of the data being
+ * sent and received across the wire.
+ */
+public class AvaticaHttpClientImpl implements AvaticaHttpClient {
+  protected final URL url;
+
+  public AvaticaHttpClientImpl(URL url) {
+    this.url = url;
+  }
+
+  public byte[] send(byte[] request) {
+    // TODO back-off policy?
+    while (true) {
+      try {
+        final HttpURLConnection connection = openConnection();
+        connection.setRequestMethod("POST");
+        connection.setDoInput(true);
+        connection.setDoOutput(true);
+        try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
+          wr.write(request);
+          wr.flush();
+          wr.close();
+        }
+        final int responseCode = connection.getResponseCode();
+        final InputStream inputStream;
+        if (responseCode == HttpURLConnection.HTTP_UNAVAILABLE) {
+          // Could be sitting behind a load-balancer, try again.
+          continue;
+        } else if (responseCode != HttpURLConnection.HTTP_OK) {
+          inputStream = connection.getErrorStream();
+        } else {
+          inputStream = connection.getInputStream();
+        }
+        return AvaticaUtils.readFullyToBytes(inputStream);
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  HttpURLConnection openConnection() throws IOException {
+    return (HttpURLConnection) url.openConnection();
+  }
+}
+
+// End AvaticaHttpClientImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
new file mode 100644
index 0000000..d5ae9b1
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionConfigImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ConnectionConfigImpl;
+
+import java.util.Properties;
+
+/** Implementation of {@link org.apache.calcite.avatica.ConnectionConfig}
+ * with extra properties specific to Remote Driver. */
+public class AvaticaRemoteConnectionConfigImpl extends ConnectionConfigImpl {
+  public AvaticaRemoteConnectionConfigImpl(Properties properties) {
+    super(properties);
+  }
+
+  public Service.Factory factory() {
+    return AvaticaRemoteConnectionProperty.FACTORY.wrap(properties)
+        .getPlugin(Service.Factory.class, null);
+  }
+}
+
+// End AvaticaRemoteConnectionConfigImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
new file mode 100644
index 0000000..5e755f8
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRemoteConnectionProperty.java
@@ -0,0 +1,80 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ConnectionProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.apache.calcite.avatica.ConnectionConfigImpl.PropEnv;
+import static org.apache.calcite.avatica.ConnectionConfigImpl.parse;
+
+/**
+ * Enumeration of Avatica remote driver's built-in connection properties.
+ */
+public enum AvaticaRemoteConnectionProperty implements ConnectionProperty {
+  /** Factory. */
+  FACTORY("factory", Type.STRING, null);
+
+  private final String camelName;
+  private final Type type;
+  private final Object defaultValue;
+
+  private static final Map<String, AvaticaRemoteConnectionProperty> NAME_TO_PROPS;
+
+  static {
+    NAME_TO_PROPS = new HashMap<String, AvaticaRemoteConnectionProperty>();
+    for (AvaticaRemoteConnectionProperty p
+        : AvaticaRemoteConnectionProperty.values()) {
+      NAME_TO_PROPS.put(p.camelName.toUpperCase(), p);
+      NAME_TO_PROPS.put(p.name(), p);
+    }
+  }
+
+  AvaticaRemoteConnectionProperty(String camelName,
+      Type type,
+      Object defaultValue) {
+    this.camelName = camelName;
+    this.type = type;
+    this.defaultValue = defaultValue;
+    assert defaultValue == null || type.valid(defaultValue);
+  }
+
+  public String camelName() {
+    return camelName;
+  }
+
+  public Object defaultValue() {
+    return defaultValue;
+  }
+
+  public Type type() {
+    return type;
+  }
+
+  public PropEnv wrap(Properties properties) {
+    return new PropEnv(parse(properties, NAME_TO_PROPS), this);
+  }
+
+  public boolean required() {
+    return false;
+  }
+}
+
+// End AvaticaRemoteConnectionProperty.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
new file mode 100644
index 0000000..2f9a1cd
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/AvaticaRuntimeException.java
@@ -0,0 +1,102 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+
+import java.util.Objects;
+
+/**
+ * A {@link RuntimeException} thrown by Avatica with additional contextual information about
+ * what happened to cause the Exception.
+ */
+public class AvaticaRuntimeException extends RuntimeException {
+  private static final long serialVersionUID = 1L;
+  private final String errorMessage;
+  private final int errorCode;
+  private final String sqlState;
+  private final AvaticaSeverity severity;
+
+  /**
+   * Constructs an {@code AvaticaRuntimeException} with no additional information.
+   *
+   * <p>It is strongly preferred that the caller invoke
+   * {@link #AvaticaRuntimeException(String, int, String, AvaticaSeverity)}
+   * with proper contextual information.
+   */
+  public AvaticaRuntimeException() {
+    this("No additional context on exception", ErrorResponse.UNKNOWN_ERROR_CODE,
+        ErrorResponse.UNKNOWN_SQL_STATE, AvaticaSeverity.UNKNOWN);
+  }
+
+  /**
+   * Constructs an {@code AvaticaRuntimeException} with the given
+   * contextual information surrounding the error.
+   *
+   * @param errorMessage A human-readable explanation about what happened
+   * @param errorCode Numeric identifier for error
+   * @param sqlState 5-character identifier for error
+   * @param severity Severity
+   */
+  public AvaticaRuntimeException(String errorMessage, int errorCode, String sqlState,
+      AvaticaSeverity severity) {
+    this.errorMessage = Objects.requireNonNull(errorMessage);
+    this.errorCode = errorCode;
+    this.sqlState = Objects.requireNonNull(sqlState);
+    this.severity = Objects.requireNonNull(severity);
+  }
+
+  /**
+   * Returns a human-readable error message.
+   */
+  public String getErrorMessage() {
+    return errorMessage;
+  }
+
+  /**
+   * Returns a numeric code for this error.
+   */
+  public int getErrorCode() {
+    return errorCode;
+  }
+
+  /**
+   * Returns the five-character identifier for this error.
+   */
+  public String getSqlState() {
+    return sqlState;
+  }
+
+  /**
+   * Returns the severity at which this exception is thrown.
+   */
+  public AvaticaSeverity getSeverity() {
+    return severity;
+  }
+
+  @Override public String toString() {
+    StringBuilder sb = new StringBuilder(64);
+    return sb.append("AvaticaRuntimeException: [")
+        .append("Messsage: '").append(errorMessage).append("', ")
+        .append("Error code: '").append(errorCode).append("', ")
+        .append("SQL State: '").append(sqlState).append("', ")
+        .append("Severity: '").append(severity).append("']").toString();
+  }
+}
+
+// End AvaticaRuntimeException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Driver.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Driver.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Driver.java
new file mode 100644
index 0000000..e98c486
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Driver.java
@@ -0,0 +1,178 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.BuiltInConnectionProperty;
+import org.apache.calcite.avatica.ConnectionConfig;
+import org.apache.calcite.avatica.ConnectionProperty;
+import org.apache.calcite.avatica.DriverVersion;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.UnregisteredDriver;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Avatica Remote JDBC driver.
+ */
+public class Driver extends UnregisteredDriver {
+  private static final Logger LOG = LoggerFactory.getLogger(Driver.class);
+  public static final String CONNECT_STRING_PREFIX = "jdbc:avatica:remote:";
+
+  static {
+    new Driver().register();
+  }
+
+  public Driver() {
+    super();
+  }
+
+  /**
+   * Defines the method of message serialization used by the Driver
+   */
+  public static enum Serialization {
+    JSON,
+    PROTOBUF;
+  }
+
+  @Override protected String getConnectStringPrefix() {
+    return CONNECT_STRING_PREFIX;
+  }
+
+  protected DriverVersion createDriverVersion() {
+    return DriverVersion.load(
+        Driver.class,
+        "org-apache-calcite-jdbc.properties",
+        "Avatica Remote JDBC Driver",
+        "unknown version",
+        "Avatica",
+        "unknown version");
+  }
+
+  @Override protected Collection<ConnectionProperty> getConnectionProperties() {
+    final List<ConnectionProperty> list = new ArrayList<ConnectionProperty>();
+    Collections.addAll(list, BuiltInConnectionProperty.values());
+    Collections.addAll(list, AvaticaRemoteConnectionProperty.values());
+    return list;
+  }
+
+  @Override public Meta createMeta(AvaticaConnection connection) {
+    final ConnectionConfig config = connection.config();
+    final Service service = createService(connection, config);
+    return new RemoteMeta(connection, service);
+  }
+
+  /**
+   * Creates a {@link Service} with the given {@link AvaticaConnection} and configuration.
+   *
+   * @param connection The {@link AvaticaConnection} to use.
+   * @param config Configuration properties
+   * @return A Service implementation.
+   */
+  Service createService(AvaticaConnection connection, ConnectionConfig config) {
+    final Service.Factory metaFactory = config.factory();
+    final Service service;
+    if (metaFactory != null) {
+      service = metaFactory.create(connection);
+    } else if (config.url() != null) {
+      final AvaticaHttpClient httpClient = getHttpClient(connection, config);
+      final Serialization serializationType = getSerialization(config);
+
+      LOG.debug("Instantiating {} service", serializationType);
+      switch (serializationType) {
+      case JSON:
+        service = new RemoteService(httpClient);
+        break;
+      case PROTOBUF:
+        service = new RemoteProtobufService(httpClient, new ProtobufTranslationImpl());
+        break;
+      default:
+        throw new IllegalArgumentException("Unhandled serialization type: " + serializationType);
+      }
+    } else {
+      service = new MockJsonService(Collections.<String, String>emptyMap());
+    }
+    return service;
+  }
+
+  /**
+   * Creates the HTTP client that communicates with the Avatica server.
+   *
+   * @param connection The {@link AvaticaConnection}.
+   * @param config The configuration.
+   * @return An {@link AvaticaHttpClient} implementation.
+   */
+  AvaticaHttpClient getHttpClient(AvaticaConnection connection, ConnectionConfig config) {
+    URL url;
+    try {
+      url = new URL(config.url());
+    } catch (MalformedURLException e) {
+      throw new RuntimeException(e);
+    }
+
+    AvaticaHttpClientFactory httpClientFactory = config.httpClientFactory();
+
+    return httpClientFactory.getClient(url, config);
+  }
+
+  @Override public Connection connect(String url, Properties info)
+      throws SQLException {
+    AvaticaConnection conn = (AvaticaConnection) super.connect(url, info);
+    if (conn == null) {
+      // It's not an url for our driver
+      return null;
+    }
+
+    // Create the corresponding remote connection
+    ConnectionConfig config = conn.config();
+    Service service = createService(conn, config);
+
+    service.apply(
+        new Service.OpenConnectionRequest(conn.id,
+            Service.OpenConnectionRequest.serializeProperties(info)));
+
+    return conn;
+  }
+
+  Serialization getSerialization(ConnectionConfig config) {
+    final String serializationStr = config.serialization();
+    Serialization serializationType = Serialization.JSON;
+    if (null != serializationStr) {
+      try {
+        serializationType = Serialization.valueOf(serializationStr.toUpperCase());
+      } catch (Exception e) {
+        // Log a warning instead of failing harshly? Intentionally no loggers available?
+        throw new RuntimeException(e);
+      }
+    }
+
+    return serializationType;
+  }
+}
+
+// End Driver.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Handler.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Handler.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Handler.java
new file mode 100644
index 0000000..30d026c
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Handler.java
@@ -0,0 +1,68 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import java.util.Objects;
+
+/**
+ * API for text request-response calls to an Avatica server.
+ *
+ * @param <T> The type this handler accepts and returns
+ */
+public interface Handler<T> {
+  int HTTP_OK = 200;
+  int HTTP_INTERNAL_SERVER_ERROR = 500;
+  String HANDLER_SERIALIZATION_METRICS_NAME = "Handler.Serialization";
+
+  /**
+   * Struct that encapsulates the context of the result of a request to Avatica.
+   */
+  public class HandlerResponse<T> {
+    private final T response;
+    private final int statusCode;
+
+    public HandlerResponse(T response, int statusCode) {
+      this.response = Objects.requireNonNull(response);
+      this.statusCode = statusCode;
+    }
+
+    public T getResponse() {
+      return response;
+    }
+
+    public int getStatusCode() {
+      return statusCode;
+    }
+
+    @Override public String toString() {
+      return "Response: " + response + ", Status:" + statusCode;
+    }
+  }
+
+  HandlerResponse<T> apply(T request);
+
+  /**
+   * Sets some general server information to return to the client in all responses.
+   *
+   * @param metadata Server-wide information
+   */
+  void setRpcMetadata(RpcMetadataResponse metadata);
+}
+
+// End Handler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
new file mode 100644
index 0000000..fd57078
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
@@ -0,0 +1,76 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+import org.apache.calcite.avatica.remote.Service.Request;
+import org.apache.calcite.avatica.remote.Service.Response;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.remote.Handler}
+ * that decodes JSON requests, sends them to a {@link Service},
+ * and encodes the responses into JSON.
+ *
+ * @see org.apache.calcite.avatica.remote.JsonService
+ */
+public class JsonHandler extends AbstractHandler<String> {
+
+  protected static final ObjectMapper MAPPER = JsonService.MAPPER;
+
+  final MetricsSystem metrics;
+  final Timer serializationTimer;
+
+  public JsonHandler(Service service, MetricsSystem metrics) {
+    super(service);
+    this.metrics = metrics;
+    this.serializationTimer = this.metrics.getTimer(
+        MetricsHelper.concat(JsonHandler.class, HANDLER_SERIALIZATION_METRICS_NAME));
+  }
+
+  public HandlerResponse<String> apply(String jsonRequest) {
+    return super.apply(jsonRequest);
+  }
+
+  @Override Request decode(String request) throws IOException {
+    try (final Context ctx = serializationTimer.start()) {
+      return MAPPER.readValue(request, Service.Request.class);
+    }
+  }
+
+  /**
+   * Serializes the provided object as JSON.
+   *
+   * @param response The object to serialize.
+   * @return A JSON string.
+   */
+  @Override String encode(Response response) throws IOException {
+    try (final Context ctx = serializationTimer.start()) {
+      final StringWriter w = new StringWriter();
+      MAPPER.writeValue(w, response);
+      return w.toString();
+    }
+  }
+}
+
+// End JsonHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
new file mode 100644
index 0000000..668b3be
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
@@ -0,0 +1,227 @@
+/*
+ * 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.remote;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.remote.Service}
+ * that encodes requests and responses as JSON.
+ */
+public abstract class JsonService extends AbstractService {
+  public static final ObjectMapper MAPPER;
+  static {
+    MAPPER = new ObjectMapper();
+    MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+    MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+    MAPPER.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
+  }
+
+  public JsonService() {
+  }
+
+  /** Derived class should implement this method to transport requests and
+   * responses to and from the peer service. */
+  public abstract String apply(String request);
+
+  @Override SerializationType getSerializationType() {
+    return SerializationType.JSON;
+  }
+
+  //@VisibleForTesting
+  protected static <T> T decode(String response, Class<T> expectedType)
+      throws IOException {
+    Response resp = MAPPER.readValue(response, Response.class);
+    if (resp instanceof ErrorResponse) {
+      throw ((ErrorResponse) resp).toException();
+    } else if (!expectedType.isAssignableFrom(resp.getClass())) {
+      throw new ClassCastException("Cannot cast " + resp.getClass() + " into " + expectedType);
+    }
+
+    return expectedType.cast(resp);
+  }
+
+  //@VisibleForTesting
+  protected static <T> String encode(T request) throws IOException {
+    final StringWriter w = new StringWriter();
+    MAPPER.writeValue(w, request);
+    return w.toString();
+  }
+
+  protected RuntimeException handle(IOException e) {
+    return new RuntimeException(e);
+  }
+
+  public ResultSetResponse apply(CatalogsRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ResultSetResponse apply(SchemasRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ResultSetResponse apply(TablesRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ResultSetResponse apply(TableTypesRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ResultSetResponse apply(TypeInfoRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ResultSetResponse apply(ColumnsRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ResultSetResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public PrepareResponse apply(PrepareRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), PrepareResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ExecuteResponse apply(PrepareAndExecuteRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ExecuteResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public FetchResponse apply(FetchRequest request) {
+    try {
+      return decode(apply(encode(request)), FetchResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ExecuteResponse apply(ExecuteRequest request) {
+    try {
+      return finagle(decode(apply(encode(request)), ExecuteResponse.class));
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public CreateStatementResponse apply(CreateStatementRequest request) {
+    try {
+      return decode(apply(encode(request)), CreateStatementResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public CloseStatementResponse apply(CloseStatementRequest request) {
+    try {
+      return decode(apply(encode(request)), CloseStatementResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    try {
+      return decode(apply(encode(request)), OpenConnectionResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public CloseConnectionResponse apply(CloseConnectionRequest request) {
+    try {
+      return decode(apply(encode(request)), CloseConnectionResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
+    try {
+      return decode(apply(encode(request)), ConnectionSyncResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
+    try {
+      return decode(apply(encode(request)), DatabasePropertyResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public SyncResultsResponse apply(SyncResultsRequest request) {
+    try {
+      return decode(apply(encode(request)), SyncResultsResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public CommitResponse apply(CommitRequest request) {
+    try {
+      return decode(apply(encode(request)), CommitResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
+  public RollbackResponse apply(RollbackRequest request) {
+    try {
+      return decode(apply(encode(request)), RollbackResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+}
+
+// End JsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
new file mode 100644
index 0000000..0af6300
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalJsonService.java
@@ -0,0 +1,46 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ * Implementation of {@link org.apache.calcite.avatica.remote.Service}
+ * that goes to an in-process instance of {@code Service}.
+ */
+public class LocalJsonService extends JsonService {
+  private final Service service;
+
+  public LocalJsonService(Service service) {
+    this.service = service;
+  }
+
+  @Override public String apply(String request) {
+    try {
+      Request request2 = MAPPER.readValue(request, Request.class);
+      Response response2 = request2.accept(service);
+      final StringWriter w = new StringWriter();
+      MAPPER.writeValue(w, response2);
+      return w.toString();
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+}
+
+// End LocalJsonService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
new file mode 100644
index 0000000..76e2392
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalProtobufService.java
@@ -0,0 +1,58 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+
+/**
+ * A Service implementation that performs protocol buffer serialization on request and responses
+ * on either side of computing a response from a request to mimic some transport to a server which
+ * would normally perform such computation.
+ */
+public class LocalProtobufService extends ProtobufService {
+  private final Service service;
+  private final ProtobufTranslation translation;
+
+  public LocalProtobufService(Service service, ProtobufTranslation translation) {
+    this.service = service;
+    this.translation = translation;
+  }
+
+  @Override public Response _apply(Request request) {
+    try {
+      // Serialize the request to "send to the server"
+      byte[] serializedRequest = translation.serializeRequest(request);
+
+      // *some transport would normally happen here*
+
+      // Fake deserializing that request somewhere else
+      Request request2 = translation.parseRequest(serializedRequest);
+
+      // Serialize the response from the service to "send to the client"
+      byte[] serializedResponse = translation.serializeResponse(request2.accept(service));
+
+      // *some transport would normally happen here*
+
+      // Deserialize the response on "the client"
+      return translation.parseResponse(serializedResponse);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+}
+
+// End LocalProtobufService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
new file mode 100644
index 0000000..c070ec0
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
@@ -0,0 +1,358 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.Meta;
+
+import org.apache.calcite.avatica.MetaImpl;
+import org.apache.calcite.avatica.MissingResultsException;
+import org.apache.calcite.avatica.NoSuchStatementException;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
+
+/**
+ * Implementation of {@link Service} that talks to a local {@link Meta}.
+ */
+public class LocalService implements Service {
+  final Meta meta;
+  final MetricsSystem metrics;
+
+  private final Timer executeTimer;
+  private final Timer commitTimer;
+  private final Timer prepareTimer;
+  private final Timer prepareAndExecuteTimer;
+  private final Timer connectionSyncTimer;
+
+  private RpcMetadataResponse serverLevelRpcMetadata;
+
+  public LocalService(Meta meta) {
+    this(meta, NoopMetricsSystem.getInstance());
+  }
+
+  public LocalService(Meta meta, MetricsSystem metrics) {
+    this.meta = meta;
+    this.metrics = Objects.requireNonNull(metrics);
+
+    this.executeTimer = this.metrics.getTimer(name("Execute"));
+    this.commitTimer = this.metrics.getTimer(name("Commit"));
+    this.prepareTimer = this.metrics.getTimer(name("Prepare"));
+    this.prepareAndExecuteTimer = this.metrics.getTimer(name("PrepareAndExecute"));
+    this.connectionSyncTimer = this.metrics.getTimer(name("ConnectionSync"));
+  }
+
+  private static String name(String timer) {
+    return concat(LocalService.class, timer);
+  }
+
+  @Override public void setRpcMetadata(RpcMetadataResponse serverLevelRpcMetadata) {
+    this.serverLevelRpcMetadata = Objects.requireNonNull(serverLevelRpcMetadata);
+  }
+
+  private static <E> List<E> list(Iterable<E> iterable) {
+    if (iterable instanceof List) {
+      return (List<E>) iterable;
+    }
+    final List<E> rowList = new ArrayList<>();
+    for (E row : iterable) {
+      rowList.add(row);
+    }
+    return rowList;
+  }
+
+  /** Converts a result set (not serializable) into a serializable response. */
+  public ResultSetResponse toResponse(Meta.MetaResultSet resultSet) {
+    if (resultSet.updateCount != -1) {
+      return new ResultSetResponse(resultSet.connectionId,
+          resultSet.statementId, resultSet.ownStatement, null, null,
+          resultSet.updateCount, serverLevelRpcMetadata);
+    }
+
+    Meta.Signature signature = resultSet.signature;
+    Meta.CursorFactory cursorFactory = resultSet.signature.cursorFactory;
+    Meta.Frame frame = null;
+    int updateCount = -1;
+    final List<Object> list;
+
+    if (resultSet.firstFrame != null) {
+      list = list(resultSet.firstFrame.rows);
+      switch (cursorFactory.style) {
+      case ARRAY:
+        cursorFactory = Meta.CursorFactory.LIST;
+        break;
+      case MAP:
+      case LIST:
+        break;
+      case RECORD:
+        cursorFactory = Meta.CursorFactory.LIST;
+        break;
+      default:
+        cursorFactory = Meta.CursorFactory.map(cursorFactory.fieldNames);
+      }
+
+      final boolean done = resultSet.firstFrame.done;
+
+      frame = new Meta.Frame(0, done, list);
+      updateCount = -1;
+
+      if (signature.statementType != null) {
+        if (signature.statementType.canUpdate()) {
+          frame = null;
+          updateCount = ((Number) ((List) list.get(0)).get(0)).intValue();
+        }
+      }
+    } else {
+      //noinspection unchecked
+      list = (List<Object>) (List) list2(resultSet);
+      cursorFactory = Meta.CursorFactory.LIST;
+    }
+
+    if (cursorFactory != resultSet.signature.cursorFactory) {
+      signature = signature.setCursorFactory(cursorFactory);
+    }
+
+    return new ResultSetResponse(resultSet.connectionId, resultSet.statementId,
+        resultSet.ownStatement, signature, frame, updateCount, serverLevelRpcMetadata);
+  }
+
+  private List<List<Object>> list2(Meta.MetaResultSet resultSet) {
+    final Meta.StatementHandle h = new Meta.StatementHandle(
+        resultSet.connectionId, resultSet.statementId, null);
+    final List<TypedValue> parameterValues = Collections.emptyList();
+    final Iterable<Object> iterable = meta.createIterable(h, null,
+        resultSet.signature, parameterValues, resultSet.firstFrame);
+    final List<List<Object>> list = new ArrayList<>();
+    return MetaImpl.collect(resultSet.signature.cursorFactory, iterable, list);
+  }
+
+  public ResultSetResponse apply(CatalogsRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet = meta.getCatalogs(ch);
+    return toResponse(resultSet);
+  }
+
+  public ResultSetResponse apply(SchemasRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet =
+        meta.getSchemas(ch, request.catalog, Meta.Pat.of(request.schemaPattern));
+    return toResponse(resultSet);
+  }
+
+  public ResultSetResponse apply(TablesRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet =
+        meta.getTables(ch,
+            request.catalog,
+            Meta.Pat.of(request.schemaPattern),
+            Meta.Pat.of(request.tableNamePattern),
+            request.typeList);
+    return toResponse(resultSet);
+  }
+
+  public ResultSetResponse apply(TableTypesRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet = meta.getTableTypes(ch);
+    return toResponse(resultSet);
+  }
+
+  public ResultSetResponse apply(TypeInfoRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet = meta.getTypeInfo(ch);
+    return toResponse(resultSet);
+  }
+
+  public ResultSetResponse apply(ColumnsRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.MetaResultSet resultSet =
+        meta.getColumns(ch,
+            request.catalog,
+            Meta.Pat.of(request.schemaPattern),
+            Meta.Pat.of(request.tableNamePattern),
+            Meta.Pat.of(request.columnNamePattern));
+    return toResponse(resultSet);
+  }
+
+  public PrepareResponse apply(PrepareRequest request) {
+    try (final Context ctx = prepareTimer.start()) {
+      final Meta.ConnectionHandle ch =
+          new Meta.ConnectionHandle(request.connectionId);
+      final Meta.StatementHandle h =
+          meta.prepare(ch, request.sql, request.maxRowCount);
+      return new PrepareResponse(h, serverLevelRpcMetadata);
+    }
+  }
+
+  public ExecuteResponse apply(PrepareAndExecuteRequest request) {
+    try (final Context ctx = prepareAndExecuteTimer.start()) {
+      final Meta.StatementHandle sh =
+          new Meta.StatementHandle(request.connectionId, request.statementId, null);
+      try {
+        final Meta.ExecuteResult executeResult =
+            meta.prepareAndExecute(sh, request.sql, request.maxRowCount,
+                new Meta.PrepareCallback() {
+                  @Override public Object getMonitor() {
+                    return LocalService.class;
+                  }
+
+                  @Override public void clear() {
+                  }
+
+                  @Override public void assign(Meta.Signature signature,
+                      Meta.Frame firstFrame, long updateCount) {
+                  }
+
+                  @Override public void execute() {
+                  }
+                });
+        final List<ResultSetResponse> results = new ArrayList<>();
+        for (Meta.MetaResultSet metaResultSet : executeResult.resultSets) {
+          results.add(toResponse(metaResultSet));
+        }
+        return new ExecuteResponse(results, false, serverLevelRpcMetadata);
+      } catch (NoSuchStatementException e) {
+        // The Statement doesn't exist anymore, bubble up this information
+        return new ExecuteResponse(null, true, serverLevelRpcMetadata);
+      }
+    }
+  }
+
+  public FetchResponse apply(FetchRequest request) {
+    final Meta.StatementHandle h = new Meta.StatementHandle(
+        request.connectionId, request.statementId, null);
+    try {
+      final Meta.Frame frame =
+          meta.fetch(h,
+              request.offset,
+              request.fetchMaxRowCount);
+      return new FetchResponse(frame, false, false, serverLevelRpcMetadata);
+    } catch (NullPointerException | NoSuchStatementException e) {
+      // The Statement doesn't exist anymore, bubble up this information
+      return new FetchResponse(null, true, true, serverLevelRpcMetadata);
+    } catch (MissingResultsException e) {
+      return new FetchResponse(null, false, true, serverLevelRpcMetadata);
+    }
+  }
+
+  public ExecuteResponse apply(ExecuteRequest request) {
+    try (final Context ctx = executeTimer.start()) {
+      try {
+        final Meta.ExecuteResult executeResult = meta.execute(request.statementHandle,
+            request.parameterValues, request.maxRowCount);
+
+        final List<ResultSetResponse> results = new ArrayList<>(executeResult.resultSets.size());
+        for (Meta.MetaResultSet metaResultSet : executeResult.resultSets) {
+          results.add(toResponse(metaResultSet));
+        }
+        return new ExecuteResponse(results, false, serverLevelRpcMetadata);
+      } catch (NoSuchStatementException e) {
+        return new ExecuteResponse(null, true, serverLevelRpcMetadata);
+      }
+    }
+  }
+
+  public CreateStatementResponse apply(CreateStatementRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    final Meta.StatementHandle h = meta.createStatement(ch);
+    return new CreateStatementResponse(h.connectionId, h.id, serverLevelRpcMetadata);
+  }
+
+  public CloseStatementResponse apply(CloseStatementRequest request) {
+    final Meta.StatementHandle h = new Meta.StatementHandle(
+        request.connectionId, request.statementId, null);
+    meta.closeStatement(h);
+    return new CloseStatementResponse(serverLevelRpcMetadata);
+  }
+
+  public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    meta.openConnection(ch, request.info);
+    return new OpenConnectionResponse(serverLevelRpcMetadata);
+  }
+
+  public CloseConnectionResponse apply(CloseConnectionRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    meta.closeConnection(ch);
+    return new CloseConnectionResponse(serverLevelRpcMetadata);
+  }
+
+  public ConnectionSyncResponse apply(ConnectionSyncRequest request) {
+    try (final Context ctx = connectionSyncTimer.start()) {
+      final Meta.ConnectionHandle ch =
+          new Meta.ConnectionHandle(request.connectionId);
+      final Meta.ConnectionProperties connProps =
+          meta.connectionSync(ch, request.connProps);
+      return new ConnectionSyncResponse(connProps, serverLevelRpcMetadata);
+    }
+  }
+
+  public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
+    final Meta.ConnectionHandle ch =
+        new Meta.ConnectionHandle(request.connectionId);
+    return new DatabasePropertyResponse(meta.getDatabaseProperties(ch), serverLevelRpcMetadata);
+  }
+
+  public SyncResultsResponse apply(SyncResultsRequest request) {
+    final Meta.StatementHandle h = new Meta.StatementHandle(
+        request.connectionId, request.statementId, null);
+    SyncResultsResponse response;
+    try {
+      // Set success on the cached statement
+      response = new SyncResultsResponse(meta.syncResults(h, request.state, request.offset), false,
+          serverLevelRpcMetadata);
+    } catch (NoSuchStatementException e) {
+      // Tried to sync results on a statement which wasn't cached
+      response = new SyncResultsResponse(false, true, serverLevelRpcMetadata);
+    }
+
+    return response;
+  }
+
+  public CommitResponse apply(CommitRequest request) {
+    try (final Context ctx = commitTimer.start()) {
+      meta.commit(new Meta.ConnectionHandle(request.connectionId));
+
+      // If commit() errors, let the ErrorResponse be sent back via an uncaught Exception.
+      return new CommitResponse();
+    }
+  }
+
+  public RollbackResponse apply(RollbackRequest request) {
+    meta.rollback(new Meta.ConnectionHandle(request.connectionId));
+
+    // If rollback() errors, let the ErrorResponse be sent back via an uncaught Exception.
+    return new RollbackResponse();
+  }
+}
+
+// End LocalService.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
new file mode 100644
index 0000000..12a5b59
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetaDataOperation.java
@@ -0,0 +1,181 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.proto.Common;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+
+/**
+ * Identifies an operation from {@link DatabaseMetaData} which returns a {@link ResultSet}. This
+ * enum is used to allow clients to request the server to re-instantiate a {@link ResultSet} for
+ * these operations which do not have a SQL string associated with them as a normal query does.
+ */
+public enum MetaDataOperation {
+  GET_ATTRIBUTES,
+  GET_BEST_ROW_IDENTIFIER,
+  GET_CATALOGS,
+  GET_CLIENT_INFO_PROPERTIES,
+  GET_COLUMN_PRIVILEGES,
+  GET_COLUMNS,
+  GET_CROSS_REFERENCE,
+  GET_EXPORTED_KEYS,
+  GET_FUNCTION_COLUMNS,
+  GET_FUNCTIONS,
+  GET_IMPORTED_KEYS,
+  GET_INDEX_INFO,
+  GET_PRIMARY_KEYS,
+  GET_PROCEDURE_COLUMNS,
+  GET_PROCEDURES,
+  GET_PSEUDO_COLUMNS,
+  GET_SCHEMAS,
+  GET_SCHEMAS_WITH_ARGS,
+  GET_SUPER_TABLES,
+  GET_SUPER_TYPES,
+  GET_TABLE_PRIVILEGES,
+  GET_TABLES,
+  GET_TABLE_TYPES,
+  GET_TYPE_INFO,
+  GET_UDTS,
+  GET_VERSION_COLUMNS;
+
+  public Common.MetaDataOperation toProto() {
+    switch (this) {
+    case GET_ATTRIBUTES:
+      return Common.MetaDataOperation.GET_ATTRIBUTES;
+    case GET_BEST_ROW_IDENTIFIER:
+      return Common.MetaDataOperation.GET_BEST_ROW_IDENTIFIER;
+    case GET_CATALOGS:
+      return Common.MetaDataOperation.GET_CATALOGS;
+    case GET_CLIENT_INFO_PROPERTIES:
+      return Common.MetaDataOperation.GET_CLIENT_INFO_PROPERTIES;
+    case GET_COLUMNS:
+      return Common.MetaDataOperation.GET_COLUMNS;
+    case GET_COLUMN_PRIVILEGES:
+      return Common.MetaDataOperation.GET_COLUMN_PRIVILEGES;
+    case GET_CROSS_REFERENCE:
+      return Common.MetaDataOperation.GET_CROSS_REFERENCE;
+    case GET_EXPORTED_KEYS:
+      return Common.MetaDataOperation.GET_EXPORTED_KEYS;
+    case GET_FUNCTIONS:
+      return Common.MetaDataOperation.GET_FUNCTIONS;
+    case GET_FUNCTION_COLUMNS:
+      return Common.MetaDataOperation.GET_FUNCTION_COLUMNS;
+    case GET_IMPORTED_KEYS:
+      return Common.MetaDataOperation.GET_IMPORTED_KEYS;
+    case GET_INDEX_INFO:
+      return Common.MetaDataOperation.GET_INDEX_INFO;
+    case GET_PRIMARY_KEYS:
+      return Common.MetaDataOperation.GET_PRIMARY_KEYS;
+    case GET_PROCEDURES:
+      return Common.MetaDataOperation.GET_PROCEDURES;
+    case GET_PROCEDURE_COLUMNS:
+      return Common.MetaDataOperation.GET_PROCEDURE_COLUMNS;
+    case GET_PSEUDO_COLUMNS:
+      return Common.MetaDataOperation.GET_PSEUDO_COLUMNS;
+    case GET_SCHEMAS:
+      return Common.MetaDataOperation.GET_SCHEMAS;
+    case GET_SCHEMAS_WITH_ARGS:
+      return Common.MetaDataOperation.GET_SCHEMAS_WITH_ARGS;
+    case GET_SUPER_TABLES:
+      return Common.MetaDataOperation.GET_SUPER_TABLES;
+    case GET_SUPER_TYPES:
+      return Common.MetaDataOperation.GET_SUPER_TYPES;
+    case GET_TABLES:
+      return Common.MetaDataOperation.GET_TABLES;
+    case GET_TABLE_PRIVILEGES:
+      return Common.MetaDataOperation.GET_TABLE_PRIVILEGES;
+    case GET_TABLE_TYPES:
+      return Common.MetaDataOperation.GET_TABLE_TYPES;
+    case GET_TYPE_INFO:
+      return Common.MetaDataOperation.GET_TYPE_INFO;
+    case GET_UDTS:
+      return Common.MetaDataOperation.GET_UDTS;
+    case GET_VERSION_COLUMNS:
+      return Common.MetaDataOperation.GET_VERSION_COLUMNS;
+    default:
+      throw new RuntimeException("Unknown type: " + this);
+    }
+  }
+
+  public static MetaDataOperation fromProto(Common.MetaDataOperation protoOp) {
+    // Null is acceptable
+    if (null == protoOp) {
+      return null;
+    }
+
+    switch (protoOp) {
+    case GET_ATTRIBUTES:
+      return MetaDataOperation.GET_ATTRIBUTES;
+    case GET_BEST_ROW_IDENTIFIER:
+      return MetaDataOperation.GET_BEST_ROW_IDENTIFIER;
+    case GET_CATALOGS:
+      return MetaDataOperation.GET_CATALOGS;
+    case GET_CLIENT_INFO_PROPERTIES:
+      return MetaDataOperation.GET_CLIENT_INFO_PROPERTIES;
+    case GET_COLUMNS:
+      return MetaDataOperation.GET_COLUMNS;
+    case GET_COLUMN_PRIVILEGES:
+      return MetaDataOperation.GET_COLUMN_PRIVILEGES;
+    case GET_CROSS_REFERENCE:
+      return MetaDataOperation.GET_CROSS_REFERENCE;
+    case GET_EXPORTED_KEYS:
+      return MetaDataOperation.GET_EXPORTED_KEYS;
+    case GET_FUNCTIONS:
+      return MetaDataOperation.GET_FUNCTIONS;
+    case GET_FUNCTION_COLUMNS:
+      return MetaDataOperation.GET_FUNCTION_COLUMNS;
+    case GET_IMPORTED_KEYS:
+      return MetaDataOperation.GET_IMPORTED_KEYS;
+    case GET_INDEX_INFO:
+      return MetaDataOperation.GET_INDEX_INFO;
+    case GET_PRIMARY_KEYS:
+      return MetaDataOperation.GET_PRIMARY_KEYS;
+    case GET_PROCEDURES:
+      return MetaDataOperation.GET_PROCEDURES;
+    case GET_PROCEDURE_COLUMNS:
+      return MetaDataOperation.GET_PROCEDURE_COLUMNS;
+    case GET_PSEUDO_COLUMNS:
+      return MetaDataOperation.GET_PSEUDO_COLUMNS;
+    case GET_SCHEMAS:
+      return MetaDataOperation.GET_SCHEMAS;
+    case GET_SCHEMAS_WITH_ARGS:
+      return MetaDataOperation.GET_SCHEMAS_WITH_ARGS;
+    case GET_SUPER_TABLES:
+      return MetaDataOperation.GET_SUPER_TABLES;
+    case GET_SUPER_TYPES:
+      return MetaDataOperation.GET_SUPER_TYPES;
+    case GET_TABLES:
+      return MetaDataOperation.GET_TABLES;
+    case GET_TABLE_PRIVILEGES:
+      return MetaDataOperation.GET_TABLE_PRIVILEGES;
+    case GET_TABLE_TYPES:
+      return MetaDataOperation.GET_TABLE_TYPES;
+    case GET_TYPE_INFO:
+      return MetaDataOperation.GET_TYPE_INFO;
+    case GET_UDTS:
+      return MetaDataOperation.GET_UDTS;
+    case GET_VERSION_COLUMNS:
+      return MetaDataOperation.GET_VERSION_COLUMNS;
+    default:
+      throw new RuntimeException("Unknown type: " + protoOp);
+    }
+  }
+}
+
+// End MetaDataOperation.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
new file mode 100644
index 0000000..2561b29
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/MetricsHelper.java
@@ -0,0 +1,36 @@
+/*
+ * 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.remote;
+
+/**
+ * A utility class to encapsulate common logic in use of metrics implementation.
+ */
+public class MetricsHelper {
+
+  private static final String PERIOD = ".";
+
+  private MetricsHelper() {}
+
+  public static String concat(Class<?> clz, String name) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(clz.getName());
+    return sb.append(PERIOD).append(name).toString();
+  }
+
+}
+
+// End MetricsHelper.java


[08/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java b/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
deleted file mode 100644
index cd3d0cf..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
+++ /dev/null
@@ -1,11853 +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.
- */
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: responses.proto
-
-package org.apache.calcite.avatica.proto;
-
-@SuppressWarnings({"unused", "rawtypes"}) public final class Responses {
-  private Responses() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  public interface ResultSetResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:ResultSetResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-
-    /**
-     * <code>optional uint32 statement_id = 2;</code>
-     */
-    int getStatementId();
-
-    /**
-     * <code>optional bool own_statement = 3;</code>
-     */
-    boolean getOwnStatement();
-
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    boolean hasSignature();
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.Signature getSignature();
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder();
-
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    boolean hasFirstFrame();
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.Frame getFirstFrame();
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder();
-
-    /**
-     * <code>optional uint64 update_count = 6;</code>
-     *
-     * <pre>
-     * -1 for normal result sets, else this response contains a dummy result set
-     * </pre>
-     */
-    long getUpdateCount();
-
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    boolean hasMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
-  }
-  /**
-   * Protobuf type {@code ResultSetResponse}
-   *
-   * <pre>
-   * Response that contains a result set.
-   * </pre>
-   */
-  public  static final class ResultSetResponse extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:ResultSetResponse)
-      ResultSetResponseOrBuilder {
-    // Use ResultSetResponse.newBuilder() to construct.
-    private ResultSetResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private ResultSetResponse() {
-      connectionId_ = "";
-      statementId_ = 0;
-      ownStatement_ = false;
-      updateCount_ = 0L;
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private ResultSetResponse(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              break;
-            }
-            case 16: {
-
-              statementId_ = input.readUInt32();
-              break;
-            }
-            case 24: {
-
-              ownStatement_ = input.readBool();
-              break;
-            }
-            case 34: {
-              org.apache.calcite.avatica.proto.Common.Signature.Builder subBuilder = null;
-              if (signature_ != null) {
-                subBuilder = signature_.toBuilder();
-              }
-              signature_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Signature.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(signature_);
-                signature_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 42: {
-              org.apache.calcite.avatica.proto.Common.Frame.Builder subBuilder = null;
-              if (firstFrame_ != null) {
-                subBuilder = firstFrame_.toBuilder();
-              }
-              firstFrame_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Frame.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(firstFrame_);
-                firstFrame_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 48: {
-
-              updateCount_ = input.readUInt64();
-              break;
-            }
-            case 58: {
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
-              if (metadata_ != null) {
-                subBuilder = metadata_.toBuilder();
-              }
-              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(metadata_);
-                metadata_ = subBuilder.buildPartial();
-              }
-
-              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.Responses.internal_static_ResultSetResponse_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Responses.ResultSetResponse.class, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder.class);
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int STATEMENT_ID_FIELD_NUMBER = 2;
-    private int statementId_;
-    /**
-     * <code>optional uint32 statement_id = 2;</code>
-     */
-    public int getStatementId() {
-      return statementId_;
-    }
-
-    public static final int OWN_STATEMENT_FIELD_NUMBER = 3;
-    private boolean ownStatement_;
-    /**
-     * <code>optional bool own_statement = 3;</code>
-     */
-    public boolean getOwnStatement() {
-      return ownStatement_;
-    }
-
-    public static final int SIGNATURE_FIELD_NUMBER = 4;
-    private org.apache.calcite.avatica.proto.Common.Signature signature_;
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    public boolean hasSignature() {
-      return signature_ != null;
-    }
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
-      return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-    }
-    /**
-     * <code>optional .Signature signature = 4;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
-      return getSignature();
-    }
-
-    public static final int FIRST_FRAME_FIELD_NUMBER = 5;
-    private org.apache.calcite.avatica.proto.Common.Frame firstFrame_;
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    public boolean hasFirstFrame() {
-      return firstFrame_ != null;
-    }
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.Frame getFirstFrame() {
-      return firstFrame_ == null ? org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
-    }
-    /**
-     * <code>optional .Frame first_frame = 5;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder() {
-      return getFirstFrame();
-    }
-
-    public static final int UPDATE_COUNT_FIELD_NUMBER = 6;
-    private long updateCount_;
-    /**
-     * <code>optional uint64 update_count = 6;</code>
-     *
-     * <pre>
-     * -1 for normal result sets, else this response contains a dummy result set
-     * </pre>
-     */
-    public long getUpdateCount() {
-      return updateCount_;
-    }
-
-    public static final int METADATA_FIELD_NUMBER = 7;
-    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    public boolean hasMetadata() {
-      return metadata_ != null;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
-      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 7;</code>
-     *
-     * <pre>
-     * with no signature nor other data.
-     * </pre>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
-      return getMetadata();
-    }
-
-    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 {
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
-      }
-      if (statementId_ != 0) {
-        output.writeUInt32(2, statementId_);
-      }
-      if (ownStatement_ != false) {
-        output.writeBool(3, ownStatement_);
-      }
-      if (signature_ != null) {
-        output.writeMessage(4, getSignature());
-      }
-      if (firstFrame_ != null) {
-        output.writeMessage(5, getFirstFrame());
-      }
-      if (updateCount_ != 0L) {
-        output.writeUInt64(6, updateCount_);
-      }
-      if (metadata_ != null) {
-        output.writeMessage(7, getMetadata());
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
-      }
-      if (statementId_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(2, statementId_);
-      }
-      if (ownStatement_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(3, ownStatement_);
-      }
-      if (signature_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getSignature());
-      }
-      if (firstFrame_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getFirstFrame());
-      }
-      if (updateCount_ != 0L) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt64Size(6, updateCount_);
-      }
-      if (metadata_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, getMetadata());
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse 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.Responses.ResultSetResponse 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 ResultSetResponse}
-     *
-     * <pre>
-     * Response that contains a result set.
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:ResultSetResponse)
-        org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Responses.ResultSetResponse.class, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Responses.ResultSetResponse.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        connectionId_ = "";
-
-        statementId_ = 0;
-
-        ownStatement_ = false;
-
-        if (signatureBuilder_ == null) {
-          signature_ = null;
-        } else {
-          signature_ = null;
-          signatureBuilder_ = null;
-        }
-        if (firstFrameBuilder_ == null) {
-          firstFrame_ = null;
-        } else {
-          firstFrame_ = null;
-          firstFrameBuilder_ = null;
-        }
-        updateCount_ = 0L;
-
-        if (metadataBuilder_ == null) {
-          metadata_ = null;
-        } else {
-          metadata_ = null;
-          metadataBuilder_ = null;
-        }
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ResultSetResponse_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse build() {
-        org.apache.calcite.avatica.proto.Responses.ResultSetResponse result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse buildPartial() {
-        org.apache.calcite.avatica.proto.Responses.ResultSetResponse result = new org.apache.calcite.avatica.proto.Responses.ResultSetResponse(this);
-        result.connectionId_ = connectionId_;
-        result.statementId_ = statementId_;
-        result.ownStatement_ = ownStatement_;
-        if (signatureBuilder_ == null) {
-          result.signature_ = signature_;
-        } else {
-          result.signature_ = signatureBuilder_.build();
-        }
-        if (firstFrameBuilder_ == null) {
-          result.firstFrame_ = firstFrame_;
-        } else {
-          result.firstFrame_ = firstFrameBuilder_.build();
-        }
-        result.updateCount_ = updateCount_;
-        if (metadataBuilder_ == null) {
-          result.metadata_ = metadata_;
-        } else {
-          result.metadata_ = metadataBuilder_.build();
-        }
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Responses.ResultSetResponse) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Responses.ResultSetResponse)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Responses.ResultSetResponse other) {
-        if (other == org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance()) return this;
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        if (other.getStatementId() != 0) {
-          setStatementId(other.getStatementId());
-        }
-        if (other.getOwnStatement() != false) {
-          setOwnStatement(other.getOwnStatement());
-        }
-        if (other.hasSignature()) {
-          mergeSignature(other.getSignature());
-        }
-        if (other.hasFirstFrame()) {
-          mergeFirstFrame(other.getFirstFrame());
-        }
-        if (other.getUpdateCount() != 0L) {
-          setUpdateCount(other.getUpdateCount());
-        }
-        if (other.hasMetadata()) {
-          mergeMetadata(other.getMetadata());
-        }
-        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.Responses.ResultSetResponse parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Responses.ResultSetResponse) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object connectionId_ = "";
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public java.lang.String getConnectionId() {
-        java.lang.Object ref = connectionId_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          connectionId_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getConnectionIdBytes() {
-        java.lang.Object ref = connectionId_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          connectionId_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionId(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder clearConnectionId() {
-        
-        connectionId_ = getDefaultInstance().getConnectionId();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionIdBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-
-      private int statementId_ ;
-      /**
-       * <code>optional uint32 statement_id = 2;</code>
-       */
-      public int getStatementId() {
-        return statementId_;
-      }
-      /**
-       * <code>optional uint32 statement_id = 2;</code>
-       */
-      public Builder setStatementId(int value) {
-        
-        statementId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional uint32 statement_id = 2;</code>
-       */
-      public Builder clearStatementId() {
-        
-        statementId_ = 0;
-        onChanged();
-        return this;
-      }
-
-      private boolean ownStatement_ ;
-      /**
-       * <code>optional bool own_statement = 3;</code>
-       */
-      public boolean getOwnStatement() {
-        return ownStatement_;
-      }
-      /**
-       * <code>optional bool own_statement = 3;</code>
-       */
-      public Builder setOwnStatement(boolean value) {
-        
-        ownStatement_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool own_statement = 3;</code>
-       */
-      public Builder clearOwnStatement() {
-        
-        ownStatement_ = false;
-        onChanged();
-        return this;
-      }
-
-      private org.apache.calcite.avatica.proto.Common.Signature signature_ = null;
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> signatureBuilder_;
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public boolean hasSignature() {
-        return signatureBuilder_ != null || signature_ != null;
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
-        if (signatureBuilder_ == null) {
-          return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-        } else {
-          return signatureBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public Builder setSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
-        if (signatureBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          signature_ = value;
-          onChanged();
-        } else {
-          signatureBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public Builder setSignature(
-          org.apache.calcite.avatica.proto.Common.Signature.Builder builderForValue) {
-        if (signatureBuilder_ == null) {
-          signature_ = builderForValue.build();
-          onChanged();
-        } else {
-          signatureBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public Builder mergeSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
-        if (signatureBuilder_ == null) {
-          if (signature_ != null) {
-            signature_ =
-              org.apache.calcite.avatica.proto.Common.Signature.newBuilder(signature_).mergeFrom(value).buildPartial();
-          } else {
-            signature_ = value;
-          }
-          onChanged();
-        } else {
-          signatureBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public Builder clearSignature() {
-        if (signatureBuilder_ == null) {
-          signature_ = null;
-          onChanged();
-        } else {
-          signature_ = null;
-          signatureBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Signature.Builder getSignatureBuilder() {
-        
-        onChanged();
-        return getSignatureFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
-        if (signatureBuilder_ != null) {
-          return signatureBuilder_.getMessageOrBuilder();
-        } else {
-          return signature_ == null ?
-              org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-        }
-      }
-      /**
-       * <code>optional .Signature signature = 4;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> 
-          getSignatureFieldBuilder() {
-        if (signatureBuilder_ == null) {
-          signatureBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-              org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder>(
-                  getSignature(),
-                  getParentForChildren(),
-                  isClean());
-          signature_ = null;
-        }
-        return signatureBuilder_;
-      }
-
-      private org.apache.calcite.avatica.proto.Common.Frame firstFrame_ = null;
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder> firstFrameBuilder_;
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public boolean hasFirstFrame() {
-        return firstFrameBuilder_ != null || firstFrame_ != null;
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Frame getFirstFrame() {
-        if (firstFrameBuilder_ == null) {
-          return firstFrame_ == null ? org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
-        } else {
-          return firstFrameBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public Builder setFirstFrame(org.apache.calcite.avatica.proto.Common.Frame value) {
-        if (firstFrameBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          firstFrame_ = value;
-          onChanged();
-        } else {
-          firstFrameBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public Builder setFirstFrame(
-          org.apache.calcite.avatica.proto.Common.Frame.Builder builderForValue) {
-        if (firstFrameBuilder_ == null) {
-          firstFrame_ = builderForValue.build();
-          onChanged();
-        } else {
-          firstFrameBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public Builder mergeFirstFrame(org.apache.calcite.avatica.proto.Common.Frame value) {
-        if (firstFrameBuilder_ == null) {
-          if (firstFrame_ != null) {
-            firstFrame_ =
-              org.apache.calcite.avatica.proto.Common.Frame.newBuilder(firstFrame_).mergeFrom(value).buildPartial();
-          } else {
-            firstFrame_ = value;
-          }
-          onChanged();
-        } else {
-          firstFrameBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public Builder clearFirstFrame() {
-        if (firstFrameBuilder_ == null) {
-          firstFrame_ = null;
-          onChanged();
-        } else {
-          firstFrame_ = null;
-          firstFrameBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Frame.Builder getFirstFrameBuilder() {
-        
-        onChanged();
-        return getFirstFrameFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.FrameOrBuilder getFirstFrameOrBuilder() {
-        if (firstFrameBuilder_ != null) {
-          return firstFrameBuilder_.getMessageOrBuilder();
-        } else {
-          return firstFrame_ == null ?
-              org.apache.calcite.avatica.proto.Common.Frame.getDefaultInstance() : firstFrame_;
-        }
-      }
-      /**
-       * <code>optional .Frame first_frame = 5;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder> 
-          getFirstFrameFieldBuilder() {
-        if (firstFrameBuilder_ == null) {
-          firstFrameBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-              org.apache.calcite.avatica.proto.Common.Frame, org.apache.calcite.avatica.proto.Common.Frame.Builder, org.apache.calcite.avatica.proto.Common.FrameOrBuilder>(
-                  getFirstFrame(),
-                  getParentForChildren(),
-                  isClean());
-          firstFrame_ = null;
-        }
-        return firstFrameBuilder_;
-      }
-
-      private long updateCount_ ;
-      /**
-       * <code>optional uint64 update_count = 6;</code>
-       *
-       * <pre>
-       * -1 for normal result sets, else this response contains a dummy result set
-       * </pre>
-       */
-      public long getUpdateCount() {
-        return updateCount_;
-      }
-      /**
-       * <code>optional uint64 update_count = 6;</code>
-       *
-       * <pre>
-       * -1 for normal result sets, else this response contains a dummy result set
-       * </pre>
-       */
-      public Builder setUpdateCount(long value) {
-        
-        updateCount_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional uint64 update_count = 6;</code>
-       *
-       * <pre>
-       * -1 for normal result sets, else this response contains a dummy result set
-       * </pre>
-       */
-      public Builder clearUpdateCount() {
-        
-        updateCount_ = 0L;
-        onChanged();
-        return this;
-      }
-
-      private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_ = null;
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> metadataBuilder_;
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public boolean hasMetadata() {
-        return metadataBuilder_ != null || metadata_ != null;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
-        if (metadataBuilder_ == null) {
-          return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-        } else {
-          return metadataBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public Builder setMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
-        if (metadataBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          metadata_ = value;
-          onChanged();
-        } else {
-          metadataBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public Builder setMetadata(
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder builderForValue) {
-        if (metadataBuilder_ == null) {
-          metadata_ = builderForValue.build();
-          onChanged();
-        } else {
-          metadataBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public Builder mergeMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
-        if (metadataBuilder_ == null) {
-          if (metadata_ != null) {
-            metadata_ =
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.newBuilder(metadata_).mergeFrom(value).buildPartial();
-          } else {
-            metadata_ = value;
-          }
-          onChanged();
-        } else {
-          metadataBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public Builder clearMetadata() {
-        if (metadataBuilder_ == null) {
-          metadata_ = null;
-          onChanged();
-        } else {
-          metadata_ = null;
-          metadataBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder getMetadataBuilder() {
-        
-        onChanged();
-        return getMetadataFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
-        if (metadataBuilder_ != null) {
-          return metadataBuilder_.getMessageOrBuilder();
-        } else {
-          return metadata_ == null ?
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-        }
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 7;</code>
-       *
-       * <pre>
-       * with no signature nor other data.
-       * </pre>
-       */
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> 
-          getMetadataFieldBuilder() {
-        if (metadataBuilder_ == null) {
-          metadataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>(
-                  getMetadata(),
-                  getParentForChildren(),
-                  isClean());
-          metadata_ = null;
-        }
-        return metadataBuilder_;
-      }
-      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:ResultSetResponse)
-    }
-
-    // @@protoc_insertion_point(class_scope:ResultSetResponse)
-    private static final org.apache.calcite.avatica.proto.Responses.ResultSetResponse DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Responses.ResultSetResponse();
-    }
-
-    public static org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<ResultSetResponse>
-        PARSER = new com.google.protobuf.AbstractParser<ResultSetResponse>() {
-      public ResultSetResponse parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new ResultSetResponse(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<ResultSetResponse> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ResultSetResponse> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface ExecuteResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:ExecuteResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> 
-        getResultsList();
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index);
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    int getResultsCount();
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
-        getResultsOrBuilderList();
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
-        int index);
-
-    /**
-     * <code>optional bool missing_statement = 2;</code>
-     *
-     * <pre>
-     * Did the request fail because of no-cached statement
-     * </pre>
-     */
-    boolean getMissingStatement();
-
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    boolean hasMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
-  }
-  /**
-   * Protobuf type {@code ExecuteResponse}
-   *
-   * <pre>
-   * Response to PrepareAndExecuteRequest
-   * </pre>
-   */
-  public  static final class ExecuteResponse extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:ExecuteResponse)
-      ExecuteResponseOrBuilder {
-    // Use ExecuteResponse.newBuilder() to construct.
-    private ExecuteResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private ExecuteResponse() {
-      results_ = java.util.Collections.emptyList();
-      missingStatement_ = false;
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private ExecuteResponse(
-        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 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                results_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Responses.ResultSetResponse>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              results_.add(input.readMessage(org.apache.calcite.avatica.proto.Responses.ResultSetResponse.parser(), extensionRegistry));
-              break;
-            }
-            case 16: {
-
-              missingStatement_ = input.readBool();
-              break;
-            }
-            case 26: {
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
-              if (metadata_ != null) {
-                subBuilder = metadata_.toBuilder();
-              }
-              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(metadata_);
-                metadata_ = subBuilder.buildPartial();
-              }
-
-              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 {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          results_ = java.util.Collections.unmodifiableList(results_);
-        }
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Responses.ExecuteResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteResponse.Builder.class);
-    }
-
-    private int bitField0_;
-    public static final int RESULTS_FIELD_NUMBER = 1;
-    private java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> results_;
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> getResultsList() {
-      return results_;
-    }
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    public java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
-        getResultsOrBuilderList() {
-      return results_;
-    }
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    public int getResultsCount() {
-      return results_.size();
-    }
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index) {
-      return results_.get(index);
-    }
-    /**
-     * <code>repeated .ResultSetResponse results = 1;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
-        int index) {
-      return results_.get(index);
-    }
-
-    public static final int MISSING_STATEMENT_FIELD_NUMBER = 2;
-    private boolean missingStatement_;
-    /**
-     * <code>optional bool missing_statement = 2;</code>
-     *
-     * <pre>
-     * Did the request fail because of no-cached statement
-     * </pre>
-     */
-    public boolean getMissingStatement() {
-      return missingStatement_;
-    }
-
-    public static final int METADATA_FIELD_NUMBER = 3;
-    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    public boolean hasMetadata() {
-      return metadata_ != null;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
-      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 3;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
-      return getMetadata();
-    }
-
-    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 < results_.size(); i++) {
-        output.writeMessage(1, results_.get(i));
-      }
-      if (missingStatement_ != false) {
-        output.writeBool(2, missingStatement_);
-      }
-      if (metadata_ != null) {
-        output.writeMessage(3, getMetadata());
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      for (int i = 0; i < results_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, results_.get(i));
-      }
-      if (missingStatement_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(2, missingStatement_);
-      }
-      if (metadata_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getMetadata());
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse 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.Responses.ExecuteResponse 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 ExecuteResponse}
-     *
-     * <pre>
-     * Response to PrepareAndExecuteRequest
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:ExecuteResponse)
-        org.apache.calcite.avatica.proto.Responses.ExecuteResponseOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Responses.ExecuteResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteResponse.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Responses.ExecuteResponse.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-          getResultsFieldBuilder();
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        if (resultsBuilder_ == null) {
-          results_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          resultsBuilder_.clear();
-        }
-        missingStatement_ = false;
-
-        if (metadataBuilder_ == null) {
-          metadata_ = null;
-        } else {
-          metadata_ = null;
-          metadataBuilder_ = null;
-        }
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteResponse_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Responses.ExecuteResponse.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse build() {
-        org.apache.calcite.avatica.proto.Responses.ExecuteResponse result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Responses.ExecuteResponse buildPartial() {
-        org.apache.calcite.avatica.proto.Responses.ExecuteResponse result = new org.apache.calcite.avatica.proto.Responses.ExecuteResponse(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (resultsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            results_ = java.util.Collections.unmodifiableList(results_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.results_ = results_;
-        } else {
-          result.results_ = resultsBuilder_.build();
-        }
-        result.missingStatement_ = missingStatement_;
-        if (metadataBuilder_ == null) {
-          result.metadata_ = metadata_;
-        } else {
-          result.metadata_ = metadataBuilder_.build();
-        }
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Responses.ExecuteResponse) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Responses.ExecuteResponse)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Responses.ExecuteResponse other) {
-        if (other == org.apache.calcite.avatica.proto.Responses.ExecuteResponse.getDefaultInstance()) return this;
-        if (resultsBuilder_ == null) {
-          if (!other.results_.isEmpty()) {
-            if (results_.isEmpty()) {
-              results_ = other.results_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureResultsIsMutable();
-              results_.addAll(other.results_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.results_.isEmpty()) {
-            if (resultsBuilder_.isEmpty()) {
-              resultsBuilder_.dispose();
-              resultsBuilder_ = null;
-              results_ = other.results_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              resultsBuilder_ = 
-                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
-                   getResultsFieldBuilder() : null;
-            } else {
-              resultsBuilder_.addAllMessages(other.results_);
-            }
-          }
-        }
-        if (other.getMissingStatement() != false) {
-          setMissingStatement(other.getMissingStatement());
-        }
-        if (other.hasMetadata()) {
-          mergeMetadata(other.getMetadata());
-        }
-        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.Responses.ExecuteResponse parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Responses.ExecuteResponse) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      private java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> results_ =
-        java.util.Collections.emptyList();
-      private void ensureResultsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
-          results_ = new java.util.ArrayList<org.apache.calcite.avatica.proto.Responses.ResultSetResponse>(results_);
-          bitField0_ |= 0x00000001;
-         }
-      }
-
-      private com.google.protobuf.RepeatedFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> resultsBuilder_;
-
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse> getResultsList() {
-        if (resultsBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(results_);
-        } else {
-          return resultsBuilder_.getMessageList();
-        }
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public int getResultsCount() {
-        if (resultsBuilder_ == null) {
-          return results_.size();
-        } else {
-          return resultsBuilder_.getCount();
-        }
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse getResults(int index) {
-        if (resultsBuilder_ == null) {
-          return results_.get(index);
-        } else {
-          return resultsBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder setResults(
-          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
-        if (resultsBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureResultsIsMutable();
-          results_.set(index, value);
-          onChanged();
-        } else {
-          resultsBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder setResults(
-          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
-        if (resultsBuilder_ == null) {
-          ensureResultsIsMutable();
-          results_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          resultsBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder addResults(org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
-        if (resultsBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureResultsIsMutable();
-          results_.add(value);
-          onChanged();
-        } else {
-          resultsBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder addResults(
-          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse value) {
-        if (resultsBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureResultsIsMutable();
-          results_.add(index, value);
-          onChanged();
-        } else {
-          resultsBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder addResults(
-          org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
-        if (resultsBuilder_ == null) {
-          ensureResultsIsMutable();
-          results_.add(builderForValue.build());
-          onChanged();
-        } else {
-          resultsBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder addResults(
-          int index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder builderForValue) {
-        if (resultsBuilder_ == null) {
-          ensureResultsIsMutable();
-          results_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          resultsBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder addAllResults(
-          java.lang.Iterable<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponse> values) {
-        if (resultsBuilder_ == null) {
-          ensureResultsIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, results_);
-          onChanged();
-        } else {
-          resultsBuilder_.addAllMessages(values);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder clearResults() {
-        if (resultsBuilder_ == null) {
-          results_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          resultsBuilder_.clear();
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public Builder removeResults(int index) {
-        if (resultsBuilder_ == null) {
-          ensureResultsIsMutable();
-          results_.remove(index);
-          onChanged();
-        } else {
-          resultsBuilder_.remove(index);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder getResultsBuilder(
-          int index) {
-        return getResultsFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder getResultsOrBuilder(
-          int index) {
-        if (resultsBuilder_ == null) {
-          return results_.get(index);  } else {
-          return resultsBuilder_.getMessageOrBuilder(index);
-        }
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public java.util.List<? extends org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
-           getResultsOrBuilderList() {
-        if (resultsBuilder_ != null) {
-          return resultsBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(results_);
-        }
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder addResultsBuilder() {
-        return getResultsFieldBuilder().addBuilder(
-            org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder addResultsBuilder(
-          int index) {
-        return getResultsFieldBuilder().addBuilder(
-            index, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .ResultSetResponse results = 1;</code>
-       */
-      public java.util.List<org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder> 
-           getResultsBuilderList() {
-        return getResultsFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder> 
-          getResultsFieldBuilder() {
-        if (resultsBuilder_ == null) {
-          resultsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
-              org.apache.calcite.avatica.proto.Responses.ResultSetResponse, org.apache.calcite.avatica.proto.Responses.ResultSetResponse.Builder, org.apache.calcite.avatica.proto.Responses.ResultSetResponseOrBuilder>(
-                  results_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
-                  getParentForChildren(),
-                  isClean());
-          results_ = null;
-        }
-        return resultsBuilder_;
-      }
-
-      private boolean missingStatement_ ;
-      /**
-       * <code>optional bool missing_statement = 2;</code>
-       *
-       * <pre>
-       * Did the request fail because of no-cached statement
-       * </pre>
-       */
-      public boolean getMissingStatement() {
-        return missingStatement_;
-      }
-      /**
-       * <code>optional bool missing_statement = 2;</code>
-       *
-       * <pre>
-       * Did the request fail because of no-cached statement
-       * </pre>
-       */
-      public Builder setMissingStatement(boolean value) {
-        
-        missingStatement_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool missing_statement = 2;</code>
-       *
-       * <pre>
-       * Did the request fail because of no-cached statement
-       * </pre>
-       */
-      public Builder clearMissingStatement() {
-        
-        missingStatement_ = false;
-        onChanged();
-        return this;
-      }
-
-      private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_ = null;
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> metadataBuilder_;
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public boolean hasMetadata() {
-        return metadataBuilder_ != null || metadata_ != null;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
-        if (metadataBuilder_ == null) {
-          return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-        } else {
-          return metadataBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public Builder setMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
-        if (metadataBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          metadata_ = value;
-          onChanged();
-        } else {
-          metadataBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public Builder setMetadata(
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder builderForValue) {
-        if (metadataBuilder_ == null) {
-          metadata_ = builderForValue.build();
-          onChanged();
-        } else {
-          metadataBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public Builder mergeMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
-        if (metadataBuilder_ == null) {
-          if (metadata_ != null) {
-            metadata_ =
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.newBuilder(metadata_).mergeFrom(value).buildPartial();
-          } else {
-            metadata_ = value;
-          }
-          onChanged();
-        } else {
-          metadataBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public Builder clearMetadata() {
-        if (metadataBuilder_ == null) {
-          metadata_ = null;
-          onChanged();
-        } else {
-          metadata_ = null;
-          metadataBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder getMetadataBuilder() {
-        
-        onChanged();
-        return getMetadataFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
-        if (metadataBuilder_ != null) {
-          return metadataBuilder_.getMessageOrBuilder();
-        } else {
-          return metadata_ == null ?
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-        }
-      }
-      /**
-       * <code>optional .RpcMetadata metadata = 3;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> 
-          getMetadataFieldBuilder() {
-        if (metadataBuilder_ == null) {
-          metadataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>(
-                  getMetadata(),
-                  getParentForChildren(),
-                  isClean());
-          metadata_ = null;
-        }
-        return metadataBuilder_;
-      }
-      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:ExecuteResponse)
-    }
-
-    // @@protoc_insertion_point(class_scope:ExecuteResponse)
-    private static final org.apache.calcite.avatica.proto.Responses.ExecuteResponse DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Responses.ExecuteResponse();
-    }
-
-    public static org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<ExecuteResponse>
-        PARSER = new com.google.protobuf.AbstractParser<ExecuteResponse>() {
-      public ExecuteResponse parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new ExecuteResponse(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<ExecuteResponse> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ExecuteResponse> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Responses.ExecuteResponse getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface PrepareResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:PrepareResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    boolean hasStatement();
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.StatementHandle getStatement();
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder getStatementOrBuilder();
-
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    boolean hasMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
-  }
-  /**
-   * Protobuf type {@code PrepareResponse}
-   *
-   * <pre>
-   * Response to PrepareRequest
-   * </pre>
-   */
-  public  static final class PrepareResponse extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:PrepareResponse)
-      PrepareResponseOrBuilder {
-    // Use PrepareResponse.newBuilder() to construct.
-    private PrepareResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private PrepareResponse() {
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private PrepareResponse(
-        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 10: {
-              org.apache.calcite.avatica.proto.Common.StatementHandle.Builder subBuilder = null;
-              if (statement_ != null) {
-                subBuilder = statement_.toBuilder();
-              }
-              statement_ = input.readMessage(org.apache.calcite.avatica.proto.Common.StatementHandle.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(statement_);
-                statement_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 18: {
-              org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
-              if (metadata_ != null) {
-                subBuilder = metadata_.toBuilder();
-              }
-              metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(metadata_);
-                metadata_ = subBuilder.buildPartial();
-              }
-
-              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.Responses.internal_static_PrepareResponse_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Responses.internal_static_PrepareResponse_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Responses.PrepareResponse.class, org.apache.calcite.avatica.proto.Responses.PrepareResponse.Builder.class);
-    }
-
-    public static final int STATEMENT_FIELD_NUMBER = 1;
-    private org.apache.calcite.avatica.proto.Common.StatementHandle statement_;
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    public boolean hasStatement() {
-      return statement_ != null;
-    }
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.StatementHandle getStatement() {
-      return statement_ == null ? org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance() : statement_;
-    }
-    /**
-     * <code>optional .StatementHandle statement = 1;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder getStatementOrBuilder() {
-      return getStatement();
-    }
-
-    public static final int METADATA_FIELD_NUMBER = 2;
-    private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    public boolean hasMetadata() {
-      return metadata_ != null;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
-      return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
-    }
-    /**
-     * <code>optional .RpcMetadata metadata = 2;</code>
-     */
-    public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
-      return getMetadata();
-    }
-
-    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 {
-      if (statement_ != null) {
-        output.writeMessage(1, getStatement());
-      }
-      if (metadata_ != null) {
-        output.writeMessage(2, getMetadata());
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (statement_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getStatement());
-      }
-      if (metadata_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getMetadata());
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Responses.PrepareResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Responses.PrepareResponse 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.Responses.PrepareResponse 

<TRUNCATED>

[11/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/QueryState.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/QueryState.java b/avatica/src/main/java/org/apache/calcite/avatica/QueryState.java
deleted file mode 100644
index 4ca9ce1..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/QueryState.java
+++ /dev/null
@@ -1,466 +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.proto.Common.MetaDataOperationArgument;
-import org.apache.calcite.avatica.proto.Common.MetaDataOperationArgument.ArgumentType;
-import org.apache.calcite.avatica.remote.MetaDataOperation;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * A struct used to encapsulate the necessary information to reconstitute a ResultSet in the
- * Avatica server.
- */
-public class QueryState {
-
-  /**
-   * An enumeration that represents how a ResultSet was created.
-   */
-  public enum StateType {
-    SQL,
-    METADATA;
-
-    public Common.StateType toProto() {
-      switch (this) {
-      case SQL:
-        return Common.StateType.SQL;
-      case METADATA:
-        return Common.StateType.METADATA;
-      default:
-        return Common.StateType.UNRECOGNIZED;
-      }
-    }
-
-    public static StateType fromProto(Common.StateType protoType) {
-      switch (protoType) {
-      case SQL:
-        return StateType.SQL;
-      case METADATA:
-        return StateType.METADATA;
-      default:
-        throw new IllegalArgumentException("Unhandled StateType " + protoType);
-      }
-    }
-  }
-
-  @JsonProperty("type")
-  public final StateType type;
-
-  @JsonProperty("sql")
-  public final String sql;
-
-  @JsonProperty("metaDataOperation")
-  public final MetaDataOperation metaDataOperation;
-  @JsonProperty("operationArgs")
-  public final Object[] operationArgs;
-
-  /**
-   * Constructor encapsulating a SQL query used to create a result set.
-   *
-   * @param sql The SQL query.
-   */
-  public QueryState(String sql) {
-    // This doesn't to be non-null
-    this.sql = sql;
-    this.type = StateType.SQL;
-
-    // Null out the members we don't use.
-    this.metaDataOperation = null;
-    this.operationArgs = null;
-  }
-
-  /**
-   * Constructor encapsulating a metadata operation's result set.
-   *
-   * @param op A pointer to the {@link DatabaseMetaData} operation being invoked.
-   * @param args The arguments to the method being invoked.
-   */
-  public QueryState(MetaDataOperation op, Object... args) {
-    this.metaDataOperation = Objects.requireNonNull(op);
-    this.operationArgs = Arrays.copyOf(Objects.requireNonNull(args), args.length);
-    this.type = StateType.METADATA;
-
-    // Null out the members we won't use
-    this.sql = null;
-  }
-
-  /**
-   * Not intended for external use. For Jackson-databind only.
-   */
-  public QueryState(StateType type, String sql, MetaDataOperation op, Object... args) {
-    this.type = Objects.requireNonNull(type);
-    switch (type) {
-    case SQL:
-      this.sql = Objects.requireNonNull(sql);
-      if (null != op) {
-        throw new IllegalArgumentException("Expected null MetaDataOperation, but got " + op);
-      }
-      this.metaDataOperation = null;
-      if (null != args) {
-        throw new IllegalArgumentException("Expected null arguments, but got "
-            + Arrays.toString(args));
-      }
-      this.operationArgs = null;
-      break;
-    case METADATA:
-      this.metaDataOperation = Objects.requireNonNull(op);
-      this.operationArgs = Objects.requireNonNull(args);
-      if (null != sql) {
-        throw new IllegalArgumentException("Expected null SQl but got " + sql);
-      }
-      this.sql = null;
-      break;
-    default:
-      throw new IllegalArgumentException("Unable to handle StateType " + type);
-    }
-  }
-
-  /**
-   * Not intended for external use. For Jackson-databind only.
-   */
-  public QueryState() {
-    this.sql = null;
-    this.metaDataOperation = null;
-    this.type = null;
-    this.operationArgs = null;
-  }
-
-  /**
-   * @return The {@link StateType} for this encapsulated state.
-   */
-  public StateType getType() {
-    return type;
-  }
-
-  /**
-   * @return The SQL expression to invoke.
-   */
-  public String getSql() {
-    assert type == StateType.SQL;
-    return sql;
-  }
-
-  /**
-   * @return The metadata operation to invoke.
-   */
-  public MetaDataOperation getMetaDataOperation() {
-    assert type == StateType.METADATA;
-    return metaDataOperation;
-  }
-
-  /**
-   * @return The Arguments for the given metadata operation.
-   */
-  public Object[] getOperationArgs() {
-    assert type == StateType.METADATA;
-    return operationArgs;
-  }
-
-  public ResultSet invoke(Connection conn, Statement statement) throws SQLException {
-    switch (type) {
-    case SQL:
-      boolean ret = Objects.requireNonNull(statement).execute(sql);
-      ResultSet results = statement.getResultSet();
-
-      // Either execute(sql) returned true or the resultSet was null
-      assert ret || null == results;
-
-      return results;
-    case METADATA:
-      DatabaseMetaData metadata = Objects.requireNonNull(conn).getMetaData();
-      switch (metaDataOperation) {
-      case GET_ATTRIBUTES:
-        verifyOpArgs(4);
-        return metadata.getAttributes((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_BEST_ROW_IDENTIFIER:
-        verifyOpArgs(5);
-        return metadata.getBestRowIdentifier((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (int) operationArgs[3],
-            (boolean) operationArgs[4]);
-      case GET_CATALOGS:
-        verifyOpArgs(0);
-        return metadata.getCatalogs();
-      case GET_COLUMNS:
-        verifyOpArgs(4);
-        return metadata.getColumns((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_COLUMN_PRIVILEGES:
-        verifyOpArgs(4);
-        return metadata.getColumnPrivileges((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_CROSS_REFERENCE:
-        verifyOpArgs(6);
-        return metadata.getCrossReference((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3],
-            (String) operationArgs[4],
-            (String) operationArgs[5]);
-      case GET_EXPORTED_KEYS:
-        verifyOpArgs(3);
-        return metadata.getExportedKeys((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_FUNCTIONS:
-        verifyOpArgs(3);
-        return metadata.getFunctions((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_FUNCTION_COLUMNS:
-        verifyOpArgs(4);
-        return metadata.getFunctionColumns((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_IMPORTED_KEYS:
-        verifyOpArgs(3);
-        return metadata.getImportedKeys((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_INDEX_INFO:
-        verifyOpArgs(5);
-        return metadata.getIndexInfo((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (boolean) operationArgs[3],
-            (boolean) operationArgs[4]);
-      case GET_PRIMARY_KEYS:
-        verifyOpArgs(3);
-        return metadata.getPrimaryKeys((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_PROCEDURES:
-        verifyOpArgs(3);
-        return metadata.getProcedures((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_PROCEDURE_COLUMNS:
-        verifyOpArgs(4);
-        return metadata.getProcedureColumns((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_PSEUDO_COLUMNS:
-        verifyOpArgs(4);
-        return metadata.getPseudoColumns((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String) operationArgs[3]);
-      case GET_SCHEMAS:
-        verifyOpArgs(0);
-        return metadata.getSchemas();
-      case GET_SCHEMAS_WITH_ARGS:
-        verifyOpArgs(2);
-        return metadata.getSchemas((String) operationArgs[0],
-            (String) operationArgs[1]);
-      case GET_SUPER_TABLES:
-        verifyOpArgs(3);
-        return metadata.getSuperTables((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_SUPER_TYPES:
-        verifyOpArgs(3);
-        return metadata.getSuperTypes((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_TABLES:
-        verifyOpArgs(4);
-        return metadata.getTables((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (String[]) operationArgs[3]);
-      case GET_TABLE_PRIVILEGES:
-        verifyOpArgs(3);
-        return metadata.getTablePrivileges((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      case GET_TABLE_TYPES:
-        verifyOpArgs(0);
-        return metadata.getTableTypes();
-      case GET_TYPE_INFO:
-        verifyOpArgs(0);
-        return metadata.getTypeInfo();
-      case GET_UDTS:
-        verifyOpArgs(4);
-        return metadata.getUDTs((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2],
-            (int[]) operationArgs[3]);
-      case GET_VERSION_COLUMNS:
-        verifyOpArgs(3);
-        return metadata.getVersionColumns((String) operationArgs[0],
-            (String) operationArgs[1],
-            (String) operationArgs[2]);
-      default:
-        throw new IllegalArgumentException("Unhandled Metadata operation: " + metaDataOperation);
-      }
-    default:
-      throw new IllegalArgumentException("Unable to process QueryState of type " + type);
-    }
-  }
-
-  private void verifyOpArgs(int expectedArgs) {
-    if (expectedArgs != operationArgs.length) {
-      throw new RuntimeException("Expected " + expectedArgs + " arguments, but got "
-          + Arrays.toString(operationArgs));
-    }
-  }
-
-  public Common.QueryState toProto() {
-    Common.QueryState.Builder builder = Common.QueryState.newBuilder();
-
-    // Required
-    switch (type) {
-    case SQL:
-      builder.setType(Common.StateType.SQL);
-      break;
-    case METADATA:
-      builder.setType(Common.StateType.METADATA);
-      break;
-    default:
-      throw new IllegalStateException("Unhandled type: " + type);
-    }
-
-    // Optional SQL
-    if (null != sql) {
-      builder.setSql(sql).setHasSql(true);
-    }
-
-    // Optional metaDataOperation
-    if (null != metaDataOperation) {
-      builder.setOp(metaDataOperation.toProto()).setHasOp(true);
-    }
-
-    // Optional operationArgs
-    if (null != operationArgs) {
-      builder.setHasArgs(true);
-      for (Object arg : operationArgs) {
-        MetaDataOperationArgument.Builder argBuilder = MetaDataOperationArgument.newBuilder();
-
-        if (null == arg) {
-          builder.addArgs(argBuilder.setType(ArgumentType.NULL).build());
-        } else if (arg instanceof String) {
-          builder.addArgs(argBuilder.setType(ArgumentType.STRING)
-              .setStringValue((String) arg).build());
-        } else if (arg instanceof Integer) {
-          builder.addArgs(argBuilder.setType(ArgumentType.INT).setIntValue((int) arg).build());
-        } else if (arg instanceof Boolean) {
-          builder.addArgs(
-              argBuilder.setType(ArgumentType.BOOL).setBoolValue((boolean) arg).build());
-        } else if (arg instanceof String[]) {
-          argBuilder.setType(ArgumentType.REPEATED_STRING);
-          for (String strArg : (String[]) arg) {
-            argBuilder.addStringArrayValues(strArg);
-          }
-          builder.addArgs(argBuilder.build());
-        } else if (arg instanceof int[]) {
-          argBuilder.setType(ArgumentType.REPEATED_INT);
-          for (int intArg : (int[]) arg) {
-            argBuilder.addIntArrayValues(intArg);
-          }
-          builder.addArgs(argBuilder.build());
-        } else {
-          throw new RuntimeException("Unexpected operation argument: " + arg.getClass());
-        }
-      }
-    } else {
-      builder.setHasArgs(false);
-    }
-
-    return builder.build();
-  }
-
-  public static QueryState fromProto(Common.QueryState protoState) {
-    StateType type = StateType.fromProto(protoState.getType());
-    String sql = protoState.getHasSql() ? protoState.getSql() : null;
-    MetaDataOperation op = protoState.getHasOp()
-        ? MetaDataOperation.fromProto(protoState.getOp()) : null;
-    Object[] opArgs = null;
-    if (protoState.getHasArgs()) {
-      opArgs = new Object[protoState.getArgsCount()];
-      int i = 0;
-      for (Common.MetaDataOperationArgument arg : protoState.getArgsList()) {
-        switch (arg.getType()) {
-        case STRING:
-          opArgs[i] = arg.getStringValue();
-          break;
-        case BOOL:
-          opArgs[i] = arg.getBoolValue();
-          break;
-        case INT:
-          opArgs[i] = arg.getIntValue();
-          break;
-        case REPEATED_STRING:
-          opArgs[i] = arg.getStringArrayValuesList().toArray(
-              new String[arg.getStringArrayValuesCount()]);
-          break;
-        case REPEATED_INT:
-          int[] arr = new int[arg.getIntArrayValuesCount()];
-          int offset = 0;
-          for (Integer val : arg.getIntArrayValuesList()) {
-            arr[offset] = val;
-            offset++;
-          }
-          opArgs[i] = arr;
-          break;
-        case NULL:
-          opArgs[i] = null;
-          break;
-        default:
-          throw new RuntimeException("Could not interpret " + arg.getType());
-        }
-
-        i++;
-      }
-    }
-
-    return new QueryState(type, sql, op, opArgs);
-  }
-
-  @Override public int hashCode() {
-    return Objects.hash(metaDataOperation, Arrays.hashCode(operationArgs), sql);
-  }
-
-  @Override public boolean equals(Object o) {
-    return o == this
-        || o instanceof QueryState
-        && metaDataOperation == ((QueryState) o).metaDataOperation
-        && Arrays.deepEquals(operationArgs, ((QueryState) o).operationArgs)
-        && Objects.equals(sql, ((QueryState) o).sql);
-  }
-}
-
-// End QueryState.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java b/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
deleted file mode 100644
index e34bee6..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
+++ /dev/null
@@ -1,559 +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.util.ByteString;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.Ref;
-import java.sql.RowId;
-import java.sql.Struct;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Extends the information in {@link java.sql.Types}.
- *
- * <p>The information in the following conversions tables
- * (from the JDBC 4.1 specification) is held in members of this class.
- *
- * <p>Table B-1: JDBC Types Mapped to Java Types
- *
- * <pre>
- * JDBC Type     Java Type
- * ============= =========================
- * CHAR          String
- * VARCHAR       String
- * LONGVARCHAR   String
- * NUMERIC       java.math.BigDecimal
- * DECIMAL       java.math.BigDecimal
- * BIT           boolean
- * BOOLEAN       boolean
- * TINYINT       byte
- * SMALLINT      short
- * INTEGER       int
- * BIGINT        long
- * REAL          float
- * FLOAT         double
- * DOUBLE        double
- * BINARY        byte[]
- * VARBINARY     byte[]
- * LONGVARBINARY byte[]
- * DATE          java.sql.Date
- * TIME          java.sql.Time
- * TIMESTAMP     java.sql.Timestamp
- * CLOB          java.sql.Clob
- * BLOB          java.sql.Blob
- * ARRAY         java.sql.Array
- * DISTINCT      mapping of underlying type
- * STRUCT        java.sql.Struct
- * REF           java.sql.Ref
- * DATALINK      java.net.URL
- * JAVA_OBJECT   underlying Java class
- * ROWID         java.sql.RowId
- * NCHAR         String
- * NVARCHAR      String
- * LONGNVARCHAR  String
- * NCLOB         java.sql.NClob
- * SQLXML        java.sql.SQLXML
- * </pre>
- *
- * <p>Table B-2: Standard Mapping from Java Types to JDBC Types
- *
- * <pre>
- * Java Type            JDBC Type
- * ==================== ==============================================
- * String               CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR or
- *                      LONGNVARCHAR
- * java.math.BigDecimal NUMERIC
- * boolean              BIT or BOOLEAN
- * byte                 TINYINT
- * short                SMALLINT
- * int                  INTEGER
- * long                 BIGINT
- * float                REAL
- * double               DOUBLE
- * byte[]               BINARY, VARBINARY, or LONGVARBINARY
- * java.sql.Date        DATE
- * java.sql.Time        TIME
- * java.sql.Timestamp   TIMESTAMP
- * java.sql.Clob        CLOB
- * java.sql.Blob        BLOB
- * java.sql.Array       ARRAY
- * java.sql.Struct      STRUCT
- * java.sql.Ref         REF
- * java.net.URL         DATALINK
- * Java class           JAVA_OBJECT
- * java.sql.RowId       ROWID
- * java.sql.NClob       NCLOB
- * java.sql.SQLXML      SQLXML
- * </pre>
- *
- * <p>TABLE B-3: Mapping from JDBC Types to Java Object Types
- *
- * <pre>
- * JDBC Type     Java Object Type
- * ============= ======================
- * CHAR          String
- * VARCHAR       String
- * LONGVARCHAR   String
- * NUMERIC       java.math.BigDecimal
- * DECIMAL       java.math.BigDecimal
- * BIT           Boolean
- * BOOLEAN       Boolean
- * TINYINT       Integer
- * SMALLINT      Integer
- * INTEGER       Integer
- * BIGINT        Long
- * REAL          Float
- * FLOAT         Double
- * DOUBLE        Double
- * BINARY        byte[]
- * VARBINARY     byte[]
- * LONGVARBINARY byte[]
- * DATE          java.sql.Date
- * TIME          java.sql.Time
- * TIMESTAMP     java.sql.Timestamp
- * DISTINCT      Object type of underlying type
- * CLOB          java.sql.Clob
- * BLOB          java.sql.Blob
- * ARRAY         java.sql.Array
- * STRUCT        java.sql.Struct or java.sql.SQLData
- * REF           java.sql.Ref
- * DATALINK      java.net.URL
- * JAVA_OBJECT   underlying Java class
- * ROWID         java.sql.RowId
- * NCHAR         String
- * NVARCHAR      String
- * LONGNVARCHAR  String
- * NCLOB         java.sql.NClob
- * SQLXML        java.sql.SQLXML
- * </pre>
- *
- * <p>TABLE B-4: Mapping from Java Object Types to JDBC Types
- *
- * <pre>
- * Java Object Type     JDBC Type
- * ==================== ===========================================
- * String               CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR
- *                      or LONGNVARCHAR
- * java.math.BigDecimal NUMERIC
- * Boolean              BIT or BOOLEAN
- * Byte                 TINYINT
- * Short                SMALLINT
- * Integer              INTEGER
- * Long                 BIGINT
- * Float                REAL
- * Double               DOUBLE
- * byte[]               BINARY, VARBINARY, or LONGVARBINARY
- * java.math.BigInteger BIGINT
- * java.sql.Date        DATE
- * java.sql.Time        TIME
- * java.sql.Timestamp   TIMESTAMP
- * java.sql.Clob        CLOB
- * java.sql.Blob        BLOB
- * java.sql.Array       ARRAY
- * java.sql.Struct      STRUCT
- * java.sql.Ref         REF
- * java.net.URL         DATALINK
- * Java class           JAVA_OBJECT
- * java.sql.RowId       ROWID
- * java.sql.NClob       NCLOB
- * java.sql.SQLXML      SQLXML
- * java.util.Calendar   TIMESTAMP
- * java.util.Date       TIMESTAMP
- * </pre>
- *
- * <p><a name="B5">TABLE B-5</a>: Conversions performed by {@code setObject} and
- * {@code setNull} between Java object types and target JDBC types
- *
- * <!--
- * CHECKSTYLE: OFF
- * -->
- * <pre>
- *                      T S I B R F D D N B B C V L B V L D T T A B C S R D J R N N L N S
- *                      I M N I E L O E U I O H A O I A O A I I R L L T E A A O C V O C Q
- *                      N A T G A O U C M T O A R N N R N T M M R O O R F T V W H A N L L
- *                      Y L E I L A B I E   L R C G A B G E E E A B B U   A A I A R G O X
- *                      I L G N   T L M R   E   H V R I V E   S Y     C   L _ D R C N B M
- *                      N I E T     E A I   A   A A Y N A     T       T   I O     H V   L
- *                      T N R         L C   N   R R   A R     A           N B     A A
- *                        T                       C   R B     M           K J     R R
- *                                                H   Y I     P                     C
- * Java type                                  
- * ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- * String               x x x x x x x x x x x x x x x x x x x x . . . . . . . . x x x . .
- * java.math.BigDecimal x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Boolean              x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Byte                 x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Short                x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Integer              x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Long                 x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Float                x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * Double               x x x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * byte[]               . . . . . . . . . . . . . . x x x . . . . . . . . . . . . . . . .
- * java.math.BigInteger . . . x . . . . . . . x x x . . . . . . . . . . . . . . . . . . .
- * java.sql.Date        . . . . . . . . . . . x x x . . . x . x . . . . . . . . . . . . .
- * java.sql.Time        . . . . . . . . . . . x x x . . . . x x . . . . . . . . . . . . .
- * java.sql.Timestamp   . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
- * java.sql.Array       . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . . .
- * java.sql.Blob        . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . .
- * java.sql.Clob        . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . .
- * java.sql.Struct      . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . .
- * java.sql.Ref         . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . .
- * java.net.URL         . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . .
- * Java class           . . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . .
- * java.sql.Rowid       . . . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . .
- * java.sql.NClob       . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x .
- * java.sql.SQLXML      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x
- * java.util.Calendar   . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
- * java.util.Date       . . . . . . . . . . . x x x . . . x x x . . . . . . . . . . . . .
- * </pre>
- * <!--
- * CHECKSTYLE: ON
- * -->
- *
- * <p><a name="B6">TABLE B-6</a>: Use of {@code ResultSet} getter methods to
- * retrieve JDBC data types
- *
- * <!--
- * CHECKSTYLE: OFF
- * -->
- * <pre>
- *                      T S I B R F D D N B B C V L B V L D T T C B A R D S J R N N L N S
- *                      I M N I E L O E U I O H A O I A O A I I L L R E A T A O C V O C Q
- *                      N A T G A O U C M T O A R N N R N T M M O O R F T R V W H A N L L
- *                      Y L E I L A B I E   L R C G A B G E E E B B A   A U A I A R G O X
- *                      I L G N   T L M R   E   H V R I V E   S     Y   L C _ D R C N B M
- *                      N I E T     E A I   A   A A Y N A     T         I T O     H V   L
- *                      T N R         L C   N   R R   A R     A         N   B     A A
- *                        T                       C   R B     M         K   J     R R
- *                                                H   Y I     P                     C
- * Java type                                                                
- * ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- * getByte              X x x x x x x x x x x x x . . . . . . . . . . . . . . x . . . . .
- * getShort             x X x x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * getInt               x x X x x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * getLong              x x x X x x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * getFloat             x x x x X x x x x x x x x . . . . . . . . . . . . . . . . . . . .
- * getDouble            x x x x x X X x x x x x x . . . . . . . . . . . . . . . . . . . .
- * getBigDecimal        x x x x x x x X X x x x x . . . . . . . . . . . . . . . . . . . .
- * getBoolean           x x x x x x x x x X x x x . . . . . . . . . . . . . . . . . . . .
- * getString            x x x x x x x x x x x X X x x x x x x x . . . . x . . . x x x . .
- * getNString           x x x x x x x x x x x x x x x x x x x x . . . . x . . . X X x . .
- * getBytes             . . . . . . . . . . . . . . X X x . . . . . . . . . . . . . . . .
- * getDate              . . . . . . . . . . . x x x . . . X . x . . . . . . . . . . . . .
- * getTime              . . . . . . . . . . . x x x . . . . X x . . . . . . . . . . . . .
- * getTimestamp         . . . . . . . . . . . x x x . . . x x X . . . . . . . . . . . x .
- * getAsciiStream       . . . . . . . . . . . x x X x x x . . . x . . . . . . . . . . . x
- * getBinaryStream      . . . . . . . . . . . . . . x x X . . . . x . . . . . . . . . x x
- * getCharacterStream   . . . . . . . . . . . x x X x x x . . . x . . . . . . . x x x x x
- * getNCharacterStream  . . . . . . . . . . . x x x x x x . . . x . . . . . . . x x X x x
- * getClob              . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . x .
- * getNClob             . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . X .
- * getBlob              . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . .
- * getArray             . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . .
- * getRef               . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . .
- * getURL               . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . .
- * getObject            x x x x x x x x x x x x x x x x x x x x x x x x x X X x x x x x x
- * getRowId             . . . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . .
- * getSQLXML            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X
- * </pre>
- * <!--
- * CHECKSTYLE: ON
- * -->
- */
-public enum SqlType {
-  BIT(Types.BIT, boolean.class),
-  BOOLEAN(Types.BOOLEAN, boolean.class),
-  TINYINT(Types.TINYINT, byte.class),
-  SMALLINT(Types.SMALLINT, short.class),
-  INTEGER(Types.INTEGER, int.class),
-  BIGINT(Types.BIGINT, long.class),
-  NUMERIC(Types.NUMERIC, BigDecimal.class),
-  DECIMAL(Types.DECIMAL, BigDecimal.class),
-  FLOAT(Types.FLOAT, double.class),
-  REAL(Types.REAL, float.class),
-  DOUBLE(Types.DOUBLE, double.class),
-  DATE(Types.DATE, java.sql.Date.class, int.class),
-  TIME(Types.TIME, Time.class, int.class),
-  TIMESTAMP(Types.TIMESTAMP, Timestamp.class, long.class),
-  INTERVAL_YEAR_MONTH(Types.OTHER, Boolean.class),
-  INTERVAL_DAY_TIME(Types.OTHER, Boolean.class),
-  CHAR(Types.CHAR, String.class),
-  VARCHAR(Types.VARCHAR, String.class),
-  LONGVARCHAR(Types.LONGVARCHAR, String.class),
-  BINARY(Types.BINARY, byte[].class, ByteString.class, String.class),
-  VARBINARY(Types.VARBINARY, byte[].class, ByteString.class, String.class),
-  LONGVARBINARY(Types.LONGVARBINARY, byte[].class, ByteString.class,
-      String.class),
-  NULL(Types.NULL, Void.class),
-  ANY(Types.JAVA_OBJECT, Object.class),
-  SYMBOL(Types.OTHER, Object.class),
-  MULTISET(Types.ARRAY, List.class),
-  ARRAY(Types.ARRAY, Array.class),
-  BLOB(Types.BLOB, Blob.class),
-  CLOB(Types.CLOB, Clob.class),
-  SQLXML(Types.SQLXML, java.sql.SQLXML.class),
-  MAP(Types.OTHER, Map.class),
-  DISTINCT(Types.DISTINCT, Object.class),
-  STRUCT(Types.STRUCT, Struct.class),
-  REF(Types.REF, Ref.class),
-  DATALINK(Types.DATALINK, URL.class),
-  JAVA_OBJECT(Types.JAVA_OBJECT, Object.class),
-  ROWID(Types.ROWID, RowId.class),
-  NCHAR(Types.NCHAR, String.class),
-  NVARCHAR(Types.NVARCHAR, String.class),
-  LONGNVARCHAR(Types.LONGNVARCHAR, String.class),
-  NCLOB(Types.NCLOB, NClob.class),
-  ROW(Types.STRUCT, Object.class),
-  OTHER(Types.OTHER, Object.class),
-  CURSOR(2012, Object.class),
-  COLUMN_LIST(Types.OTHER + 2, Object.class);
-
-  /** Type id as appears in {@link java.sql.Types},
-   * e.g. {@link java.sql.Types#INTEGER}. */
-  public final int id;
-
-  /** Default Java type for this SQL type, as described in table B-1. */
-  public final Class clazz;
-
-  /** Class used internally in Calcite to represent instances of this type. */
-  public final Class internal;
-
-  /** Class used to serialize values of this type as JSON. */
-  public final Class serial;
-
-  private static final Map<Integer, SqlType> BY_ID = new HashMap<>();
-  static {
-    for (SqlType sqlType : values()) {
-      BY_ID.put(sqlType.id, sqlType);
-    }
-  }
-
-  SqlType(int id, Class clazz, Class internal, Class serial) {
-    this.id = id;
-    this.clazz = clazz;
-    this.internal = internal;
-    this.serial = serial;
-  }
-
-  SqlType(int id, Class clazz, Class internal) {
-    this(id, clazz, internal, internal);
-  }
-
-  SqlType(int id, Class clazz) {
-    this(id, clazz, clazz, clazz);
-  }
-
-  public static SqlType valueOf(int type) {
-    final SqlType sqlType = BY_ID.get(type);
-    if (sqlType == null) {
-      throw new IllegalArgumentException("Unknown SQL type " + type);
-    }
-    return sqlType;
-  }
-
-  /** Returns the boxed type. */
-  public Class boxedClass() {
-    return AvaticaUtils.box(clazz);
-  }
-
-  /** Returns the entries in JDBC table B-5. */
-  public static Iterable<Map.Entry<Class, SqlType>> getSetConversions() {
-    final ArrayList<Map.Entry<Class, SqlType>> list = new ArrayList<>();
-    for (Map.Entry<Class, EnumSet<SqlType>> entry : SET_LIST.entrySet()) {
-      for (SqlType sqlType : entry.getValue()) {
-        list.add(new AbstractMap.SimpleEntry<>(entry.getKey(), sqlType));
-      }
-    }
-    return list;
-  }
-
-  public static final Map<Class, EnumSet<SqlType>> SET_LIST;
-  public static final Map<Method, EnumSet<SqlType>> GET_LIST;
-
-  static {
-    SET_LIST = new HashMap<>();
-    GET_LIST = new HashMap<>();
-
-    EnumSet<SqlType> numericTypes = EnumSet.of(TINYINT, SMALLINT, INTEGER,
-        BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, BOOLEAN);
-    Class[] numericClasses = {
-      BigDecimal.class, Boolean.class, Byte.class, Short.class, Integer.class,
-      Long.class, Float.class, Double.class
-    };
-    EnumSet<SqlType> charTypes = EnumSet.of(CHAR, VARCHAR, LONGVARCHAR);
-    EnumSet<SqlType> ncharTypes = EnumSet.of(NCHAR, NVARCHAR, LONGNVARCHAR);
-    EnumSet<SqlType> binaryTypes = EnumSet.of(BINARY, VARBINARY, LONGVARBINARY);
-    EnumSet<SqlType> dateTimeTypes = EnumSet.of(DATE, TIME, TIMESTAMP);
-    final EnumSet<SqlType> numericCharTypes = concat(numericTypes, charTypes);
-    SET_LIST.put(String.class,
-        concat(numericCharTypes, binaryTypes, dateTimeTypes, ncharTypes));
-    for (Class clazz : numericClasses) {
-      SET_LIST.put(clazz, numericCharTypes);
-    }
-    SET_LIST.put(byte[].class, binaryTypes);
-    SET_LIST.put(BigInteger.class,
-        EnumSet.of(BIGINT, CHAR, VARCHAR, LONGVARCHAR));
-    SET_LIST.put(java.sql.Date.class,
-        concat(charTypes, EnumSet.of(DATE, TIMESTAMP)));
-    SET_LIST.put(Time.class,
-        concat(charTypes, EnumSet.of(TIME, TIMESTAMP)));
-    SET_LIST.put(Timestamp.class,
-        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
-    SET_LIST.put(Array.class, EnumSet.of(ARRAY));
-    SET_LIST.put(Blob.class, EnumSet.of(BLOB));
-    SET_LIST.put(Clob.class, EnumSet.of(CLOB));
-    SET_LIST.put(Struct.class, EnumSet.of(STRUCT));
-    SET_LIST.put(Ref.class, EnumSet.of(REF));
-    SET_LIST.put(URL.class, EnumSet.of(DATALINK));
-    SET_LIST.put(Class.class, EnumSet.of(JAVA_OBJECT));
-    SET_LIST.put(RowId.class, EnumSet.of(ROWID));
-    SET_LIST.put(NClob.class, EnumSet.of(NCLOB));
-    SET_LIST.put(java.sql.SQLXML.class, EnumSet.of(SQLXML));
-    SET_LIST.put(Calendar.class,
-        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
-    SET_LIST.put(java.util.Date.class,
-        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
-
-    EnumSet<Method> numericMethods =
-        EnumSet.of(Method.GET_BYTE, Method.GET_SHORT, Method.GET_INT,
-            Method.GET_LONG, Method.GET_FLOAT, Method.GET_DOUBLE,
-            Method.GET_BIG_DECIMAL, Method.GET_BOOLEAN);
-    for (Method method : numericMethods) {
-      GET_LIST.put(method, numericCharTypes);
-    }
-    GET_LIST.put(Method.GET_BYTE, EnumSet.of(ROWID));
-    for (Method method : EnumSet.of(Method.GET_STRING, Method.GET_N_STRING)) {
-      GET_LIST.put(method,
-          concat(numericCharTypes, binaryTypes, dateTimeTypes,
-              EnumSet.of(DATALINK), ncharTypes));
-    }
-    GET_LIST.put(Method.GET_BYTES, binaryTypes);
-    GET_LIST.put(Method.GET_DATE,
-        concat(charTypes, EnumSet.of(DATE, TIMESTAMP)));
-    GET_LIST.put(Method.GET_TIME,
-        concat(charTypes, EnumSet.of(TIME, TIMESTAMP)));
-    GET_LIST.put(Method.GET_TIMESTAMP,
-        concat(charTypes, EnumSet.of(DATE, TIME, TIMESTAMP)));
-    GET_LIST.put(Method.GET_ASCII_STREAM,
-        concat(charTypes, binaryTypes, EnumSet.of(CLOB, NCLOB)));
-    GET_LIST.put(Method.GET_BINARY_STREAM,
-        concat(binaryTypes, EnumSet.of(BLOB, SQLXML)));
-    GET_LIST.put(Method.GET_CHARACTER_STREAM,
-        concat(charTypes, binaryTypes, ncharTypes,
-            EnumSet.of(CLOB, NCLOB, SQLXML)));
-    GET_LIST.put(Method.GET_N_CHARACTER_STREAM,
-        concat(
-            charTypes, binaryTypes, ncharTypes, EnumSet.of(CLOB, NCLOB, SQLXML)));
-    GET_LIST.put(Method.GET_CLOB, EnumSet.of(CLOB, NCLOB));
-    GET_LIST.put(Method.GET_N_CLOB, EnumSet.of(CLOB, NCLOB));
-    GET_LIST.put(Method.GET_BLOB, EnumSet.of(BLOB));
-    GET_LIST.put(Method.GET_ARRAY, EnumSet.of(ARRAY));
-    GET_LIST.put(Method.GET_REF, EnumSet.of(REF));
-    GET_LIST.put(Method.GET_BLOB, EnumSet.of(BLOB));
-    GET_LIST.put(Method.GET_URL, EnumSet.of(DATALINK));
-    GET_LIST.put(Method.GET_OBJECT, EnumSet.allOf(SqlType.class));
-    GET_LIST.put(Method.GET_ROW_ID, EnumSet.of(ROWID));
-    GET_LIST.put(Method.GET_SQLXML, EnumSet.of(SQLXML));
-  }
-
-  @SafeVarargs
-  private static <E extends Enum<E>> EnumSet<E> concat(Collection<E>... ess) {
-    final List<E> list = new ArrayList<>();
-    for (Collection<E> es : ess) {
-      list.addAll(es);
-    }
-    return EnumSet.copyOf(list);
-  }
-
-  /** Returns whether {@link java.sql.PreparedStatement#setObject} and
-   * {@link PreparedStatement#setNull} can assign a value of a particular class
-   * to a column of a particular SQL type.
-   *
-   * <p>The JDBC standard describes the mapping in table <a href="#B5">B-5</a>.
-   */
-  public static boolean canSet(Class aClass, SqlType sqlType) {
-    final EnumSet<SqlType> sqlTypes = SET_LIST.get(aClass);
-    return sqlTypes != null && sqlTypes.contains(sqlType);
-  }
-
-  /** Returns whether {@link java.sql.ResultSet#getInt(int)} and similar methods
-   * can convert a value to a particular SQL type.
-   *
-   * <p>The JDBC standard describes the mapping in table <a href="#B6">B-6</a>.
-   */
-  public static boolean canGet(Method method, SqlType sqlType) {
-    final EnumSet<SqlType> sqlTypes = GET_LIST.get(method);
-    return sqlTypes != null && sqlTypes.contains(sqlType);
-  }
-
-  /** Getter methods in {@link java.sql.ResultSet}. */
-  public enum Method {
-    GET_BYTE("getByte"),
-    GET_SHORT("getShort"),
-    GET_INT("getInt"),
-    GET_LONG("getLong"),
-    GET_FLOAT("getFloat"),
-    GET_DOUBLE("getDouble"),
-    GET_BIG_DECIMAL("getBigDecimal"),
-    GET_BOOLEAN("getBoolean"),
-    GET_STRING("getString"),
-    GET_N_STRING("getNString"),
-    GET_BYTES("getBytes"),
-    GET_DATE("getDate"),
-    GET_TIME("getTime"),
-    GET_TIMESTAMP("getTimestamp"),
-    GET_ASCII_STREAM("getAsciiStream"),
-    GET_BINARY_STREAM("getBinaryStream"),
-    GET_CHARACTER_STREAM("getCharacterStream"),
-    GET_N_CHARACTER_STREAM("getNCharacterStream"),
-    GET_CLOB("getClob"),
-    GET_N_CLOB("getNClob"),
-    GET_BLOB("getBlob"),
-    GET_ARRAY("getArray"),
-    GET_REF("getRef"),
-    GET_URL("getURL"),
-    GET_OBJECT("getObject"),
-    GET_ROW_ID("getRowId"),
-    GET_SQLXML("getSQLXML");
-
-    public final String methodName;
-
-    Method(String methodName) {
-      this.methodName = methodName;
-    }
-  }
-}
-
-// End SqlType.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java b/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
deleted file mode 100644
index b1fe787..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
+++ /dev/null
@@ -1,255 +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.Connection;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Implementation of JDBC driver that does not register itself.
- *
- * <p>You can easily create a "vanity driver" that recognizes its own
- * URL prefix as a sub-class of this class. Per the JDBC specification it
- * must register itself when the class is loaded.</p>
- *
- * <p>Derived classes must implement {@link #createDriverVersion()} and
- * {@link #getConnectStringPrefix()}, and may override
- * {@link #createFactory()}.</p>
- *
- * <p>The provider must implement:</p>
- * <ul>
- *   <li>{@link Meta#prepare(Meta.ConnectionHandle, String, long)}
- *   <li>{@link Meta#createIterable(org.apache.calcite.avatica.Meta.StatementHandle, org.apache.calcite.avatica.QueryState, org.apache.calcite.avatica.Meta.Signature, java.util.List, Meta.Frame)}
- * </ul>
- */
-public abstract class UnregisteredDriver implements java.sql.Driver {
-  final DriverVersion version;
-  protected final AvaticaFactory factory;
-  public final Handler handler;
-
-  protected UnregisteredDriver() {
-    this.factory = createFactory();
-    this.version = createDriverVersion();
-    this.handler = createHandler();
-  }
-
-  /**
-   * Creates a factory for JDBC objects (connection, statement).
-   * Called from the driver constructor.
-   *
-   * <p>The default implementation calls {@link JdbcVersion#current},
-   * then {@link #getFactoryClassName} with that version,
-   * then passes that class name to {@link #instantiateFactory(String)}.
-   * This approach is recommended it does not include in the code references
-   * to classes that may not be instantiable in all JDK versions.
-   * But drivers are free to do it their own way.</p>
-   *
-   * @return JDBC object factory
-   */
-  protected AvaticaFactory createFactory() {
-    return instantiateFactory(getFactoryClassName(JdbcVersion.current()));
-  }
-
-  /** Creates a Handler. */
-  protected Handler createHandler() {
-    return new HandlerImpl();
-  }
-
-  /**
-   * Returns the name of a class to be factory for JDBC objects
-   * (connection, statement) appropriate for the current JDBC version.
-   */
-  protected String getFactoryClassName(JdbcVersion jdbcVersion) {
-    switch (jdbcVersion) {
-    case JDBC_30:
-    case JDBC_40:
-      throw new IllegalArgumentException("JDBC version not supported: "
-          + jdbcVersion);
-    case JDBC_41:
-    default:
-      return "org.apache.calcite.avatica.AvaticaJdbc41Factory";
-    }
-  }
-
-  /**
-   * Creates an object describing the name and version of this driver.
-   * Called from the driver constructor.
-   */
-  protected abstract DriverVersion createDriverVersion();
-
-  /**
-   * Returns the connection properties supported by this driver.
-   */
-  protected Collection<ConnectionProperty> getConnectionProperties() {
-    return Arrays.<ConnectionProperty>asList(
-        BuiltInConnectionProperty.values());
-  }
-
-  /** Helper method for creating factories. */
-  protected static AvaticaFactory instantiateFactory(String factoryClassName) {
-    try {
-      final Class<?> clazz = Class.forName(factoryClassName);
-      return (AvaticaFactory) clazz.newInstance();
-    } catch (ClassNotFoundException e) {
-      throw handle("Error loading factory " + factoryClassName, e);
-    } catch (IllegalAccessException e) {
-      throw handle("Error loading factory " + factoryClassName, e);
-    } catch (InstantiationException e) {
-      throw handle("Error loading factory " + factoryClassName, e);
-    } catch (Throwable e) {
-      // It is not usually good to catch Throwable. But class loading can fail
-      // with serious errors such as java.lang.NoClassDefFoundError
-      throw handle("Error loading factory " + factoryClassName, e);
-    }
-  }
-
-  private static RuntimeException handle(String msg, Throwable e) {
-    Logger.getLogger("").log(Level.SEVERE, msg, e);
-    throw new RuntimeException(msg, e);
-  }
-
-  public Connection connect(String url, Properties info) throws SQLException {
-    if (!acceptsURL(url)) {
-      return null;
-    }
-    final String prefix = getConnectStringPrefix();
-    assert url.startsWith(prefix);
-    final String urlSuffix = url.substring(prefix.length());
-    final Properties info2 = ConnectStringParser.parse(urlSuffix, info);
-    final AvaticaConnection connection =
-        factory.newConnection(this, factory, url, info2);
-    handler.onConnectionInit(connection);
-    return connection;
-  }
-
-  public boolean acceptsURL(String url) throws SQLException {
-    return url.startsWith(getConnectStringPrefix());
-  }
-
-  /** Returns the prefix of the connect string that this driver will recognize
-   * as its own. For example, "jdbc:calcite:". */
-  protected abstract String getConnectStringPrefix();
-
-  public DriverPropertyInfo[] getPropertyInfo(
-      String url, Properties info) throws SQLException {
-    List<DriverPropertyInfo> list = new ArrayList<DriverPropertyInfo>();
-
-    // First, add the contents of info
-    for (Map.Entry<Object, Object> entry : info.entrySet()) {
-      list.add(
-          new DriverPropertyInfo(
-              (String) entry.getKey(),
-              (String) entry.getValue()));
-    }
-    // Next, add property definitions not mentioned in info
-    for (ConnectionProperty p : getConnectionProperties()) {
-      if (info.containsKey(p.name())) {
-        continue;
-      }
-      list.add(new DriverPropertyInfo(p.name(), null));
-    }
-    return list.toArray(new DriverPropertyInfo[list.size()]);
-  }
-
-  // JDBC 4.1 support (JDK 1.7 and higher)
-  public Logger getParentLogger() {
-    return Logger.getLogger("");
-  }
-
-  /**
-   * Returns the driver version object. Not in the JDBC API.
-   *
-   * @return Driver version
-   */
-  public DriverVersion getDriverVersion() {
-    return version;
-  }
-
-  public final int getMajorVersion() {
-    return version.majorVersion;
-  }
-
-  public final int getMinorVersion() {
-    return version.minorVersion;
-  }
-
-  public boolean jdbcCompliant() {
-    return version.jdbcCompliant;
-  }
-
-  /**
-   * Registers this driver with the driver manager.
-   */
-  protected void register() {
-    try {
-      DriverManager.registerDriver(this);
-    } catch (SQLException e) {
-      System.out.println(
-          "Error occurred while registering JDBC driver "
-          + this + ": " + e.toString());
-    }
-  }
-
-  /** Creates a service handler that will give connections from this Driver
-   * their behavior. */
-  public abstract Meta createMeta(AvaticaConnection connection);
-
-  /** JDBC version. */
-  protected enum JdbcVersion {
-    /** Unknown JDBC version. */
-    JDBC_UNKNOWN,
-    /** JDBC version 3.0. Generally associated with JDK 1.5. */
-    JDBC_30,
-    /** JDBC version 4.0. Generally associated with JDK 1.6. */
-    JDBC_40,
-    /** JDBC version 4.1. Generally associated with JDK 1.7. */
-    JDBC_41;
-
-    /** Deduces the current JDBC version. */
-    public static JdbcVersion current() {
-      try {
-        // If java.sql.PseudoColumnUsage is present, we are running JDBC
-        // 4.1 or later.
-        Class.forName("java.sql.PseudoColumnUsage");
-        return JDBC_41;
-      } catch (ClassNotFoundException e) {
-        // java.sql.PseudoColumnUsage is not present. This means we are
-        // running JDBC 4.0 or earlier.
-        try {
-          Class.forName("java.sql.Wrapper");
-          return JDBC_40;
-        } catch (ClassNotFoundException e2) {
-          // java.sql.Wrapper is not present. This means we are
-          // running JDBC 3.0 or earlier (probably JDK 1.5).
-          return JDBC_30;
-        }
-      }
-    }
-  }
-}
-
-// End UnregisteredDriver.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/package-info.java b/avatica/src/main/java/org/apache/calcite/avatica/package-info.java
deleted file mode 100644
index 89a9fbb..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * Avatica JDBC framework.
- */
-@PackageMarker
-package org.apache.calcite.avatica;
-
-import org.apache.calcite.avatica.util.PackageMarker;
-
-// End package-info.java


[17/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/fonts/fontawesome-webfont.svg
----------------------------------------------------------------------
diff --git a/avatica/site/fonts/fontawesome-webfont.svg b/avatica/site/fonts/fontawesome-webfont.svg
new file mode 100755
index 0000000..b612969
--- /dev/null
+++ b/avatica/site/fonts/fontawesome-webfont.svg
@@ -0,0 +1,520 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="fontawesomeregular" horiz-adv-x="1536" >
+<font-face units-per-em="1792" ascent="1536" descent="-256" />
+<missing-glyph horiz-adv-x="448" />
+<glyph unicode=" "  horiz-adv-x="448" />
+<glyph unicode="&#x09;" horiz-adv-x="448" />
+<glyph unicode="&#xa0;" horiz-adv-x="448" />
+<glyph unicode="&#xa8;" horiz-adv-x="1792" />
+<glyph unicode="&#xa9;" horiz-adv-x="1792" />
+<glyph unicode="&#xae;" horiz-adv-x="1792" />
+<glyph unicode="&#xb4;" horiz-adv-x="1792" />
+<glyph unicode="&#xc6;" horiz-adv-x="1792" />
+<glyph unicode="&#xd8;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" horiz-adv-x="1537" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" horiz-adv-x="1537" />
+<glyph unicode="&#x2004;" horiz-adv-x="512" />
+<glyph unicode="&#x2005;" horiz-adv-x="384" />
+<glyph unicode="&#x2006;" horiz-adv-x="256" />
+<glyph unicode="&#x2007;" horiz-adv-x="256" />
+<glyph unicode="&#x2008;" horiz-adv-x="192" />
+<glyph unicode="&#x2009;" horiz-adv-x="307" />
+<glyph unicode="&#x200a;" horiz-adv-x="85" />
+<glyph unicode="&#x202f;" horiz-adv-x="307" />
+<glyph unicode="&#x205f;" horiz-adv-x="384" />
+<glyph unicode="&#x2122;" horiz-adv-x="1792" />
+<glyph unicode="&#x221e;" horiz-adv-x="1792" />
+<glyph unicode="&#x2260;" horiz-adv-x="1792" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
+<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
+<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
+<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t1
 9 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28
 t28 -68z" />
+<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
+<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
+<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
+<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
+<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
+<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
+<glyph unicode="&#xf016;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " />
+<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
+<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
+<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
+<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
+<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -1
 13 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
+<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
+<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
+<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
+<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
+<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
+<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
+<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
+<glyph unicode="&#xf035;" d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41
 .5t-59.5 49t-36 30q-26 21 -26 49 t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
+<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t
 -22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
+<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
+<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
+<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
+<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
+<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
+<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
+<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
+<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
+<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
+<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
+<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
+<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
+<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
+<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
+<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
+<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
+<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
+<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
+<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
+<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
+<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
+<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
+<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
+<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
+<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
+<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
+<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
+<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
+<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
+<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
+<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
+<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
+<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf082;" d="M1536 160q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5v-960z" />
+<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
+<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 
 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
+<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
+<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
+<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
+<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
+<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
+<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
+<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 
 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
+<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
+<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
+<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
+<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
+<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
+<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
+<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
+<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
+<glyph unicode="&#xf0a2;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
+<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
+<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
+<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
+<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17
 t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-1
 5 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q
 -15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/avatica/site/fonts/fontawesome-webfont.ttf b/avatica/site/fonts/fontawesome-webfont.ttf
new file mode 100755
index 0000000..96a3639
Binary files /dev/null and b/avatica/site/fonts/fontawesome-webfont.ttf differ


[48/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index dfe7f99..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ /dev/null
@@ -1,976 +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.jdbc;
-
-import org.apache.calcite.avatica.AvaticaParameter;
-import org.apache.calcite.avatica.AvaticaPreparedStatement;
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.MetaImpl;
-import org.apache.calcite.avatica.MissingResultsException;
-import org.apache.calcite.avatica.NoSuchConnectionException;
-import org.apache.calcite.avatica.NoSuchStatementException;
-import org.apache.calcite.avatica.QueryState;
-import org.apache.calcite.avatica.SqlType;
-import org.apache.calcite.avatica.metrics.Gauge;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.remote.TypedValue;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
-
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.DriverManager;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-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;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/** Implementation of {@link Meta} upon an existing JDBC data source. */
-public class JdbcMeta implements Meta {
-  private static final Logger LOG = LoggerFactory.getLogger(JdbcMeta.class);
-
-  private static final String CONN_CACHE_KEY_BASE = "avatica.connectioncache";
-
-  private static final String STMT_CACHE_KEY_BASE = "avatica.statementcache";
-
-  /** Special value for {@code Statement#getLargeMaxRows()} that means fetch
-   * an unlimited number of rows in a single batch.
-   *
-   * <p>Any other negative value will return an unlimited number of rows but
-   * will do it in the default batch size, namely 100. */
-  public static final long UNLIMITED_COUNT = -2L;
-
-  // End of constants, start of member variables
-
-  final Calendar calendar = Calendar.getInstance();
-
-  /** Generates ids for statements. The ids are unique across all connections
-   * created by this JdbcMeta. */
-  private final AtomicInteger statementIdGenerator = new AtomicInteger();
-
-  private final String url;
-  private final Properties info;
-  private final Cache<String, Connection> connectionCache;
-  private final Cache<Integer, StatementInfo> statementCache;
-  private final MetricsSystem metrics;
-
-  /**
-   * Creates a JdbcMeta.
-   *
-   * @param url a database url of the form
-   *  <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
-   */
-  public JdbcMeta(String url) throws SQLException {
-    this(url, new Properties());
-  }
-
-  /**
-   * Creates a JdbcMeta.
-   *
-   * @param url a database url of the form
-   * <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
-   * @param user the database user on whose behalf the connection is being
-   *   made
-   * @param password the user's password
-   */
-  public JdbcMeta(final String url, final String user, final String password)
-      throws SQLException {
-    this(url, new Properties() {
-      {
-        put("user", user);
-        put("password", password);
-      }
-    });
-  }
-
-  public JdbcMeta(String url, Properties info) throws SQLException {
-    this(url, info, NoopMetricsSystem.getInstance());
-  }
-
-  /**
-   * Creates a JdbcMeta.
-   *
-   * @param url a database url of the form
-   * <code> jdbc:<em>subprotocol</em>:<em>subname</em></code>
-   * @param info a list of arbitrary string tag/value pairs as
-   * connection arguments; normally at least a "user" and
-   * "password" property should be included
-   */
-  public JdbcMeta(String url, Properties info, MetricsSystem metrics)
-      throws SQLException {
-    this.url = url;
-    this.info = info;
-    this.metrics = Objects.requireNonNull(metrics);
-
-    int concurrencyLevel = Integer.parseInt(
-        info.getProperty(ConnectionCacheSettings.CONCURRENCY_LEVEL.key(),
-            ConnectionCacheSettings.CONCURRENCY_LEVEL.defaultValue()));
-    int initialCapacity = Integer.parseInt(
-        info.getProperty(ConnectionCacheSettings.INITIAL_CAPACITY.key(),
-            ConnectionCacheSettings.INITIAL_CAPACITY.defaultValue()));
-    long maxCapacity = Long.parseLong(
-        info.getProperty(ConnectionCacheSettings.MAX_CAPACITY.key(),
-            ConnectionCacheSettings.MAX_CAPACITY.defaultValue()));
-    long connectionExpiryDuration = Long.parseLong(
-        info.getProperty(ConnectionCacheSettings.EXPIRY_DURATION.key(),
-            ConnectionCacheSettings.EXPIRY_DURATION.defaultValue()));
-    TimeUnit connectionExpiryUnit = TimeUnit.valueOf(
-        info.getProperty(ConnectionCacheSettings.EXPIRY_UNIT.key(),
-            ConnectionCacheSettings.EXPIRY_UNIT.defaultValue()));
-    this.connectionCache = CacheBuilder.newBuilder()
-        .concurrencyLevel(concurrencyLevel)
-        .initialCapacity(initialCapacity)
-        .maximumSize(maxCapacity)
-        .expireAfterAccess(connectionExpiryDuration, connectionExpiryUnit)
-        .removalListener(new ConnectionExpiryHandler())
-        .build();
-    LOG.debug("instantiated connection cache: {}", connectionCache.stats());
-
-    concurrencyLevel = Integer.parseInt(
-        info.getProperty(StatementCacheSettings.CONCURRENCY_LEVEL.key(),
-            StatementCacheSettings.CONCURRENCY_LEVEL.defaultValue()));
-    initialCapacity = Integer.parseInt(
-        info.getProperty(StatementCacheSettings.INITIAL_CAPACITY.key(),
-            StatementCacheSettings.INITIAL_CAPACITY.defaultValue()));
-    maxCapacity = Long.parseLong(
-        info.getProperty(StatementCacheSettings.MAX_CAPACITY.key(),
-            StatementCacheSettings.MAX_CAPACITY.defaultValue()));
-    connectionExpiryDuration = Long.parseLong(
-        info.getProperty(StatementCacheSettings.EXPIRY_DURATION.key(),
-            StatementCacheSettings.EXPIRY_DURATION.defaultValue()));
-    connectionExpiryUnit = TimeUnit.valueOf(
-        info.getProperty(StatementCacheSettings.EXPIRY_UNIT.key(),
-            StatementCacheSettings.EXPIRY_UNIT.defaultValue()));
-    this.statementCache = CacheBuilder.newBuilder()
-        .concurrencyLevel(concurrencyLevel)
-        .initialCapacity(initialCapacity)
-        .maximumSize(maxCapacity)
-        .expireAfterAccess(connectionExpiryDuration, connectionExpiryUnit)
-        .removalListener(new StatementExpiryHandler())
-        .build();
-
-    LOG.debug("instantiated statement cache: {}", statementCache.stats());
-
-    // Register some metrics
-    this.metrics.register(concat(JdbcMeta.class, "ConnectionCacheSize"), new Gauge<Long>() {
-      @Override public Long getValue() {
-        return connectionCache.size();
-      }
-    });
-
-    this.metrics.register(concat(JdbcMeta.class, "StatementCacheSize"), new Gauge<Long>() {
-      @Override public Long getValue() {
-        return statementCache.size();
-      }
-    });
-  }
-
-  /**
-   * Converts from JDBC metadata to Avatica columns.
-   */
-  protected static List<ColumnMetaData>
-  columns(ResultSetMetaData metaData) throws SQLException {
-    if (metaData == null) {
-      return Collections.emptyList();
-    }
-    final List<ColumnMetaData> columns = new ArrayList<>();
-    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);
-      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),
-              metaData.isCurrency(i), metaData.isNullable(i),
-              metaData.isSigned(i), metaData.getColumnDisplaySize(i),
-              metaData.getColumnLabel(i), metaData.getColumnName(i),
-              metaData.getSchemaName(i), metaData.getPrecision(i),
-              metaData.getScale(i), metaData.getTableName(i),
-              metaData.getCatalogName(i), t, metaData.isReadOnly(i),
-              metaData.isWritable(i), metaData.isDefinitelyWritable(i),
-              metaData.getColumnClassName(i));
-      columns.add(md);
-    }
-    return columns;
-  }
-
-  /**
-   * Converts from JDBC metadata to Avatica parameters
-   */
-  protected static List<AvaticaParameter> parameters(ParameterMetaData metaData)
-      throws SQLException {
-    if (metaData == null) {
-      return Collections.emptyList();
-    }
-    final List<AvaticaParameter> params = new ArrayList<>();
-    for (int i = 1; i <= metaData.getParameterCount(); i++) {
-      params.add(
-          new AvaticaParameter(metaData.isSigned(i), metaData.getPrecision(i),
-              metaData.getScale(i), metaData.getParameterType(i),
-              metaData.getParameterTypeName(i),
-              metaData.getParameterClassName(i), "?" + i));
-    }
-    return params;
-  }
-
-  protected static Signature signature(ResultSetMetaData metaData,
-      ParameterMetaData parameterMetaData, String sql,
-      Meta.StatementType statementType) throws  SQLException {
-    final CursorFactory cf = CursorFactory.LIST;  // because JdbcResultSet#frame
-    return new Signature(columns(metaData), sql, parameters(parameterMetaData),
-        null, cf, statementType);
-  }
-
-  protected static Signature signature(ResultSetMetaData metaData)
-      throws SQLException {
-    return signature(metaData, null, null, null);
-  }
-
-  public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
-    try {
-      final Map<DatabaseProperty, Object> map = new HashMap<>();
-      final DatabaseMetaData metaData = getConnection(ch.id).getMetaData();
-      for (DatabaseProperty p : DatabaseProperty.values()) {
-        addProperty(map, metaData, p);
-      }
-      return map;
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private static Object addProperty(Map<DatabaseProperty, Object> map,
-      DatabaseMetaData metaData, DatabaseProperty p) throws SQLException {
-    try {
-      return map.put(p, p.method.invoke(metaData));
-    } catch (IllegalAccessException | InvocationTargetException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getTables(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat tableNamePattern, List<String> typeList) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getTables(catalog, schemaPattern.s,
-              tableNamePattern.s, toArray(typeList));
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /**
-    * Registers a StatementInfo for the given ResultSet, returning the id under
-    * which it is registered. This should be used for metadata ResultSets, which
-    * have an implicit statement created.
-    */
-  private int registerMetaStatement(ResultSet rs) throws SQLException {
-    final int id = statementIdGenerator.getAndIncrement();
-    StatementInfo statementInfo = new StatementInfo(rs.getStatement());
-    statementInfo.setResultSet(rs);
-    statementCache.put(id, statementInfo);
-    return id;
-  }
-
-  public MetaResultSet getColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat tableNamePattern, Pat columnNamePattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getColumns(catalog, schemaPattern.s,
-              tableNamePattern.s, columnNamePattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat schemaPattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getSchemas(catalog, schemaPattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getCatalogs(ConnectionHandle ch) {
-    try {
-      final ResultSet rs = getConnection(ch.id).getMetaData().getCatalogs();
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getTableTypes(ConnectionHandle ch) {
-    try {
-      final ResultSet rs = getConnection(ch.id).getMetaData().getTableTypes();
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getProcedures(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat procedureNamePattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getProcedures(catalog, schemaPattern.s,
-              procedureNamePattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getProcedureColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat procedureNamePattern, Pat columnNamePattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getProcedureColumns(catalog,
-              schemaPattern.s, procedureNamePattern.s, columnNamePattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getColumnPrivileges(ConnectionHandle ch, String catalog, String schema,
-      String table, Pat columnNamePattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getColumnPrivileges(catalog, schema,
-              table, columnNamePattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getTablePrivileges(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat tableNamePattern) {
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getTablePrivileges(catalog,
-              schemaPattern.s, tableNamePattern.s);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getBestRowIdentifier(ConnectionHandle ch, String catalog, String schema,
-      String table, int scope, boolean nullable) {
-    LOG.trace("getBestRowIdentifier catalog:{} schema:{} table:{} scope:{} nullable:{}", catalog,
-        schema, table, scope, nullable);
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getBestRowIdentifier(catalog, schema,
-              table, scope, nullable);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getVersionColumns(ConnectionHandle ch, String catalog, String schema,
-      String table) {
-    LOG.trace("getVersionColumns catalog:{} schema:{} table:{}", catalog, schema, table);
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getVersionColumns(catalog, schema, table);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getPrimaryKeys(ConnectionHandle ch, String catalog, String schema,
-      String table) {
-    LOG.trace("getPrimaryKeys catalog:{} schema:{} table:{}", catalog, schema, table);
-    try {
-      final ResultSet rs =
-          getConnection(ch.id).getMetaData().getPrimaryKeys(catalog, schema, table);
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getImportedKeys(ConnectionHandle ch, String catalog, String schema,
-      String table) {
-    return null;
-  }
-
-  public MetaResultSet getExportedKeys(ConnectionHandle ch, String catalog, String schema,
-      String table) {
-    return null;
-  }
-
-  public MetaResultSet getCrossReference(ConnectionHandle ch, String parentCatalog,
-      String parentSchema, String parentTable, String foreignCatalog,
-      String foreignSchema, String foreignTable) {
-    return null;
-  }
-
-  public MetaResultSet getTypeInfo(ConnectionHandle ch) {
-    try {
-      final ResultSet rs = getConnection(ch.id).getMetaData().getTypeInfo();
-      int stmtId = registerMetaStatement(rs);
-      return JdbcResultSet.create(ch.id, stmtId, rs);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public MetaResultSet getIndexInfo(ConnectionHandle ch, String catalog, String schema,
-      String table, boolean unique, boolean approximate) {
-    return null;
-  }
-
-  public MetaResultSet getUDTs(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat typeNamePattern, int[] types) {
-    return null;
-  }
-
-  public MetaResultSet getSuperTypes(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat typeNamePattern) {
-    return null;
-  }
-
-  public MetaResultSet getSuperTables(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat tableNamePattern) {
-    return null;
-  }
-
-  public MetaResultSet getAttributes(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat typeNamePattern, Pat attributeNamePattern) {
-    return null;
-  }
-
-  public MetaResultSet getClientInfoProperties(ConnectionHandle ch) {
-    return null;
-  }
-
-  public MetaResultSet getFunctions(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat functionNamePattern) {
-    return null;
-  }
-
-  public MetaResultSet getFunctionColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat functionNamePattern, Pat columnNamePattern) {
-    return null;
-  }
-
-  public MetaResultSet getPseudoColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
-      Pat tableNamePattern, Pat columnNamePattern) {
-    return null;
-  }
-
-  public Iterable<Object> createIterable(StatementHandle handle, QueryState state,
-      Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
-    return null;
-  }
-
-  protected Connection getConnection(String id) throws SQLException {
-    if (id == null) {
-      throw new NullPointerException("Connection id is null.");
-    }
-    Connection conn = connectionCache.getIfPresent(id);
-    if (conn == null) {
-      throw new NoSuchConnectionException("Connection not found: invalid id, closed, or expired: "
-          + id);
-    }
-    return conn;
-  }
-
-  public StatementHandle createStatement(ConnectionHandle ch) {
-    try {
-      final Connection conn = getConnection(ch.id);
-      final Statement statement = conn.createStatement();
-      final int id = statementIdGenerator.getAndIncrement();
-      statementCache.put(id, new StatementInfo(statement));
-      StatementHandle h = new StatementHandle(ch.id, id, null);
-      LOG.trace("created statement {}", h);
-      return h;
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  @Override public void closeStatement(StatementHandle h) {
-    StatementInfo info = statementCache.getIfPresent(h.id);
-    if (info == null || info.statement == null) {
-      LOG.debug("client requested close unknown statement {}", h);
-      return;
-    }
-    LOG.trace("closing statement {}", h);
-    try {
-      ResultSet results = info.getResultSet();
-      if (info.isResultSetInitialized() && null != results) {
-        results.close();
-      }
-      info.statement.close();
-    } catch (SQLException e) {
-      throw propagate(e);
-    } finally {
-      statementCache.invalidate(h.id);
-    }
-  }
-
-  @Override public void openConnection(ConnectionHandle ch,
-      Map<String, String> info) {
-    Properties fullInfo = new Properties();
-    fullInfo.putAll(this.info);
-    if (info != null) {
-      fullInfo.putAll(info);
-    }
-
-    synchronized (this) {
-      try {
-        if (connectionCache.asMap().containsKey(ch.id)) {
-          throw new RuntimeException("Connection already exists: " + ch.id);
-        }
-        Connection conn = DriverManager.getConnection(url, fullInfo);
-        connectionCache.put(ch.id, conn);
-      } catch (SQLException e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  @Override public void closeConnection(ConnectionHandle ch) {
-    Connection conn = connectionCache.getIfPresent(ch.id);
-    if (conn == null) {
-      LOG.debug("client requested close unknown connection {}", ch);
-      return;
-    }
-    LOG.trace("closing connection {}", ch);
-    try {
-      conn.close();
-    } catch (SQLException e) {
-      throw propagate(e);
-    } finally {
-      connectionCache.invalidate(ch.id);
-    }
-  }
-
-  protected void apply(Connection conn, ConnectionProperties connProps)
-      throws SQLException {
-    if (connProps.isAutoCommit() != null) {
-      conn.setAutoCommit(connProps.isAutoCommit());
-    }
-    if (connProps.isReadOnly() != null) {
-      conn.setReadOnly(connProps.isReadOnly());
-    }
-    if (connProps.getTransactionIsolation() != null) {
-      conn.setTransactionIsolation(connProps.getTransactionIsolation());
-    }
-    if (connProps.getCatalog() != null) {
-      conn.setCatalog(connProps.getCatalog());
-    }
-    if (connProps.getSchema() != null) {
-      conn.setSchema(connProps.getSchema());
-    }
-  }
-
-  @Override public ConnectionProperties connectionSync(ConnectionHandle ch,
-      ConnectionProperties connProps) {
-    LOG.trace("syncing properties for connection {}", ch);
-    try {
-      Connection conn = getConnection(ch.id);
-      ConnectionPropertiesImpl props = new ConnectionPropertiesImpl(conn).merge(connProps);
-      if (props.isDirty()) {
-        apply(conn, props);
-        props.setDirty(false);
-      }
-      return props;
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  RuntimeException propagate(Throwable e) {
-    if (e instanceof RuntimeException) {
-      throw (RuntimeException) e;
-    } else if (e instanceof Error) {
-      throw (Error) e;
-    } else {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public StatementHandle prepare(ConnectionHandle ch, String sql,
-      long maxRowCount) {
-    try {
-      final Connection conn = getConnection(ch.id);
-      final PreparedStatement statement = conn.prepareStatement(sql);
-      final int id = statementIdGenerator.getAndIncrement();
-      Meta.StatementType statementType = null;
-      if (statement.isWrapperFor(AvaticaPreparedStatement.class)) {
-        final AvaticaPreparedStatement avaticaPreparedStatement;
-        avaticaPreparedStatement =
-            statement.unwrap(AvaticaPreparedStatement.class);
-        statementType = avaticaPreparedStatement.getStatementType();
-      }
-      statementCache.put(id, new StatementInfo(statement));
-      StatementHandle h = new StatementHandle(ch.id, id,
-          signature(statement.getMetaData(), statement.getParameterMetaData(),
-              sql, statementType));
-      LOG.trace("prepared statement {}", h);
-      return h;
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
-    try {
-      final StatementInfo info = statementCache.getIfPresent(h.id);
-      if (info == null) {
-        throw new NoSuchStatementException(h);
-      }
-      final Statement statement = info.statement;
-      // Special handling of maxRowCount as JDBC 0 is unlimited, our meta 0 row
-      if (maxRowCount > 0) {
-        AvaticaUtils.setLargeMaxRows(statement, maxRowCount);
-      } else if (maxRowCount < 0) {
-        statement.setMaxRows(0);
-      }
-      boolean ret = statement.execute(sql);
-      info.setResultSet(statement.getResultSet());
-      // Either execute(sql) returned true or the resultSet was null
-      assert ret || null == info.getResultSet();
-      final List<MetaResultSet> resultSets = new ArrayList<>();
-      if (null == info.getResultSet()) {
-        // Create a special result set that just carries update count
-        resultSets.add(
-            JdbcResultSet.count(h.connectionId, h.id,
-                AvaticaUtils.getLargeUpdateCount(statement)));
-      } else {
-        resultSets.add(
-            JdbcResultSet.create(h.connectionId, h.id, info.getResultSet(), maxRowCount));
-      }
-      LOG.trace("prepAndExec statement {}", h);
-      // TODO: review client to ensure statementId is updated when appropriate
-      return new ExecuteResult(resultSets);
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  public boolean syncResults(StatementHandle sh, QueryState state, long offset)
-      throws NoSuchStatementException {
-    try {
-      final Connection conn = getConnection(sh.connectionId);
-      final StatementInfo info = statementCache.getIfPresent(sh.id);
-      if (null == info) {
-        throw new NoSuchStatementException(sh);
-      }
-      final Statement statement = info.statement;
-      // Let the state recreate the necessary ResultSet on the Statement
-      info.setResultSet(state.invoke(conn, statement));
-
-      if (null != info.getResultSet()) {
-        // If it is non-null, try to advance to the requested offset.
-        return info.advanceResultSetToOffset(info.getResultSet(), offset);
-      }
-
-      // No results, nothing to do. Client can move on.
-      return false;
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  public Frame fetch(StatementHandle h, long offset, int fetchMaxRowCount) throws
-      NoSuchStatementException, MissingResultsException {
-    LOG.trace("fetching {} offset:{} fetchMaxRowCount:{}", h, offset, fetchMaxRowCount);
-    try {
-      final StatementInfo statementInfo = statementCache.getIfPresent(h.id);
-      if (null == statementInfo) {
-        // Statement might have expired, or never existed on this server.
-        throw new NoSuchStatementException(h);
-      }
-
-      if (!statementInfo.isResultSetInitialized()) {
-        // The Statement exists, but the results are missing. Need to call syncResults(...)
-        throw new MissingResultsException(h);
-      }
-      if (statementInfo.getResultSet() == null) {
-        return Frame.EMPTY;
-      } else {
-        return JdbcResultSet.frame(statementInfo, statementInfo.getResultSet(), offset,
-            fetchMaxRowCount, calendar);
-      }
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  private static String[] toArray(List<String> typeList) {
-    if (typeList == null) {
-      return null;
-    }
-    return typeList.toArray(new String[typeList.size()]);
-  }
-
-  @Override public ExecuteResult execute(StatementHandle h,
-      List<TypedValue> parameterValues, long maxRowCount) throws NoSuchStatementException {
-    try {
-      if (MetaImpl.checkParameterValueHasNull(parameterValues)) {
-        throw new SQLException("exception while executing query: unbound parameter");
-      }
-
-      final StatementInfo statementInfo = statementCache.getIfPresent(h.id);
-      if (null == statementInfo) {
-        throw new NoSuchStatementException(h);
-      }
-      final List<MetaResultSet> resultSets;
-      final PreparedStatement preparedStatement =
-          (PreparedStatement) statementInfo.statement;
-
-      if (parameterValues != null) {
-        for (int i = 0; i < parameterValues.size(); i++) {
-          TypedValue o = parameterValues.get(i);
-          preparedStatement.setObject(i + 1, o.toJdbc(calendar));
-        }
-      }
-
-      if (preparedStatement.execute()) {
-        final Meta.Frame frame;
-        final Signature signature2;
-        if (preparedStatement.isWrapperFor(AvaticaPreparedStatement.class)) {
-          signature2 = h.signature;
-        } else {
-          h.signature = signature(preparedStatement.getMetaData(),
-              preparedStatement.getParameterMetaData(), h.signature.sql,
-              Meta.StatementType.SELECT);
-          signature2 = h.signature;
-        }
-
-        // Make sure we set this for subsequent fetch()'s to find the result set.
-        statementInfo.setResultSet(preparedStatement.getResultSet());
-
-        if (statementInfo.getResultSet() == null) {
-          frame = Frame.EMPTY;
-          resultSets = Collections.<MetaResultSet>singletonList(
-              JdbcResultSet.empty(h.connectionId, h.id, signature2));
-        } else {
-          resultSets = Collections.<MetaResultSet>singletonList(
-              JdbcResultSet.create(h.connectionId, h.id, statementInfo.getResultSet(),
-                  maxRowCount, signature2));
-        }
-      } else {
-        resultSets = Collections.<MetaResultSet>singletonList(
-            JdbcResultSet.count(h.connectionId, h.id, preparedStatement.getUpdateCount()));
-      }
-
-      return new ExecuteResult(resultSets);
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  @Override public void commit(ConnectionHandle ch) {
-    try {
-      final Connection conn = getConnection(ch.id);
-      conn.commit();
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  @Override public void rollback(ConnectionHandle ch) {
-    try {
-      final Connection conn = getConnection(ch.id);
-      conn.rollback();
-    } catch (SQLException e) {
-      throw propagate(e);
-    }
-  }
-
-  /** Configurable statement cache settings. */
-  public enum StatementCacheSettings {
-    /** JDBC connection property for setting connection cache concurrency level. */
-    CONCURRENCY_LEVEL(STMT_CACHE_KEY_BASE + ".concurrency", "100"),
-
-    /** JDBC connection property for setting connection cache initial capacity. */
-    INITIAL_CAPACITY(STMT_CACHE_KEY_BASE + ".initialcapacity", "1000"),
-
-    /** JDBC connection property for setting connection cache maximum capacity. */
-    MAX_CAPACITY(STMT_CACHE_KEY_BASE + ".maxcapacity", "10000"),
-
-    /** JDBC connection property for setting connection cache expiration duration.
-     *
-     * <p>Used in conjunction with {@link #EXPIRY_UNIT}.</p>
-     */
-    EXPIRY_DURATION(STMT_CACHE_KEY_BASE + ".expirydiration", "5"),
-
-    /** JDBC connection property for setting connection cache expiration unit.
-     *
-     * <p>Used in conjunction with {@link #EXPIRY_DURATION}.</p>
-     */
-    EXPIRY_UNIT(STMT_CACHE_KEY_BASE + ".expiryunit", TimeUnit.MINUTES.name());
-
-    private final String key;
-    private final String defaultValue;
-
-    StatementCacheSettings(String key, String defaultValue) {
-      this.key = key;
-      this.defaultValue = defaultValue;
-    }
-
-    /** The configuration key for specifying this setting. */
-    public String key() {
-      return key;
-    }
-
-    /** The default value for this setting. */
-    public String defaultValue() {
-      return defaultValue;
-    }
-  }
-
-  /** Configurable connection cache settings. */
-  public enum ConnectionCacheSettings {
-    /** JDBC connection property for setting connection cache concurrency level. */
-    CONCURRENCY_LEVEL(CONN_CACHE_KEY_BASE + ".concurrency", "10"),
-
-    /** JDBC connection property for setting connection cache initial capacity. */
-    INITIAL_CAPACITY(CONN_CACHE_KEY_BASE + ".initialcapacity", "100"),
-
-    /** JDBC connection property for setting connection cache maximum capacity. */
-    MAX_CAPACITY(CONN_CACHE_KEY_BASE + ".maxcapacity", "1000"),
-
-    /** JDBC connection property for setting connection cache expiration duration. */
-    EXPIRY_DURATION(CONN_CACHE_KEY_BASE + ".expiryduration", "10"),
-
-    /** JDBC connection property for setting connection cache expiration unit. */
-    EXPIRY_UNIT(CONN_CACHE_KEY_BASE + ".expiryunit", TimeUnit.MINUTES.name());
-
-    private final String key;
-    private final String defaultValue;
-
-    ConnectionCacheSettings(String key, String defaultValue) {
-      this.key = key;
-      this.defaultValue = defaultValue;
-    }
-
-    /** The configuration key for specifying this setting. */
-    public String key() {
-      return key;
-    }
-
-    /** The default value for this setting. */
-    public String defaultValue() {
-      return defaultValue;
-    }
-  }
-
-  /** Callback for {@link #connectionCache} member expiration. */
-  private class ConnectionExpiryHandler
-      implements RemovalListener<String, Connection> {
-
-    public void onRemoval(RemovalNotification<String, Connection> notification) {
-      String connectionId = notification.getKey();
-      Connection doomed = notification.getValue();
-      LOG.debug("Expiring connection {} because {}", connectionId, notification.getCause());
-      try {
-        if (doomed != null) {
-          doomed.close();
-        }
-      } catch (Throwable t) {
-        LOG.info("Exception thrown while expiring connection {}", connectionId, t);
-      }
-    }
-  }
-
-  /** Callback for {@link #statementCache} member expiration. */
-  private class StatementExpiryHandler
-      implements RemovalListener<Integer, StatementInfo> {
-    public void onRemoval(RemovalNotification<Integer, StatementInfo> notification) {
-      Integer stmtId = notification.getKey();
-      StatementInfo doomed = notification.getValue();
-      if (doomed == null) {
-        // log/throw?
-        return;
-      }
-      LOG.debug("Expiring statement {} because {}", stmtId, notification.getCause());
-      try {
-        if (doomed.getResultSet() != null) {
-          doomed.getResultSet().close();
-        }
-        if (doomed.statement != null) {
-          doomed.statement.close();
-        }
-      } catch (Throwable t) {
-        LOG.info("Exception thrown while expiring statement {}", stmtId, t);
-      }
-    }
-  }
-}
-
-// End JdbcMeta.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index 6630124..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
+++ /dev/null
@@ -1,215 +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.jdbc;
-
-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}.
- *
- *  @see org.apache.calcite.avatica.jdbc.JdbcMeta */
-class JdbcResultSet extends Meta.MetaResultSet {
-  protected JdbcResultSet(String connectionId, int statementId,
-      boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame) {
-    this(connectionId, statementId, ownStatement, signature, firstFrame, -1L);
-  }
-
-  protected JdbcResultSet(String connectionId, int statementId,
-      boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame,
-      long updateCount) {
-    super(connectionId, statementId, ownStatement, signature, firstFrame, updateCount);
-  }
-
-  /** Creates a result set. */
-  public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet) {
-    // -1 still limits to 100 but -2 does not limit to any number
-    return create(connectionId, statementId, resultSet,
-        JdbcMeta.UNLIMITED_COUNT);
-  }
-
-  /** Creates a result set with maxRowCount.
-   *
-   * <p>If {@code maxRowCount} is -2 ({@link JdbcMeta#UNLIMITED_COUNT}),
-   * returns an unlimited number of rows in a single frame; any other
-   * negative value (typically -1) returns an unlimited number of rows
-   * in frames of the default frame size. */
-  public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet, long maxRowCount) {
-    try {
-      Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
-      return create(connectionId, statementId, resultSet, maxRowCount, sig);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet, long maxRowCount, Meta.Signature signature) {
-    try {
-      final Calendar calendar = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
-      final int fetchRowCount;
-      if (maxRowCount == JdbcMeta.UNLIMITED_COUNT) {
-        fetchRowCount = -1;
-      } else if (maxRowCount < 0L) {
-        fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
-      } else if (maxRowCount > AvaticaStatement.DEFAULT_FETCH_SIZE) {
-        fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
-      } else {
-        fetchRowCount = (int) maxRowCount;
-      }
-      final Meta.Frame firstFrame = frame(null, resultSet, 0, fetchRowCount, calendar);
-      if (firstFrame.done) {
-        resultSet.close();
-      }
-      return new JdbcResultSet(connectionId, statementId, true, signature,
-          firstFrame);
-    } catch (SQLException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /** Creates a empty result set with empty frame */
-  public static JdbcResultSet empty(String connectionId, int statementId,
-      Meta.Signature signature) {
-    return new JdbcResultSet(connectionId, statementId, true, signature,
-        Meta.Frame.EMPTY);
-  }
-
-  /** Creates a result set that only has an update count. */
-  public static JdbcResultSet count(String connectionId, int statementId,
-      int updateCount) {
-    return new JdbcResultSet(connectionId, statementId, true, null, null, updateCount);
-  }
-
-  /** Creates a frame containing a given number or unlimited number of rows
-   * from a result set. */
-  static Meta.Frame frame(StatementInfo info, ResultSet resultSet, long offset,
-      int fetchMaxRowCount, Calendar calendar) throws SQLException {
-    final ResultSetMetaData metaData = resultSet.getMetaData();
-    final int columnCount = metaData.getColumnCount();
-    final int[] types = new int[columnCount];
-    for (int i = 0; i < types.length; i++) {
-      types[i] = metaData.getColumnType(i + 1);
-    }
-    final List<Object> rows = new ArrayList<>();
-    // Meta prepare/prepareAndExecute 0 return 0 row and done
-    boolean done = fetchMaxRowCount == 0;
-    for (int i = 0; fetchMaxRowCount < 0 || i < fetchMaxRowCount; i++) {
-      final boolean hasRow;
-      if (null != info) {
-        hasRow = info.next();
-      } else {
-        hasRow = resultSet.next();
-      }
-      if (!hasRow) {
-        done = true;
-        resultSet.close();
-        break;
-      }
-      Object[] columns = new Object[columnCount];
-      for (int j = 0; j < columnCount; j++) {
-        columns[j] = getValue(resultSet, types[j], j, calendar);
-      }
-      rows.add(columns);
-    }
-    return new Meta.Frame(offset, done, rows);
-  }
-
-  private static Object getValue(ResultSet resultSet, int type, int j,
-      Calendar calendar) throws SQLException {
-    switch (type) {
-    case Types.BIGINT:
-      final long aLong = resultSet.getLong(j + 1);
-      return aLong == 0 && resultSet.wasNull() ? null : aLong;
-    case Types.INTEGER:
-      final int anInt = resultSet.getInt(j + 1);
-      return anInt == 0 && resultSet.wasNull() ? null : anInt;
-    case Types.SMALLINT:
-      final short aShort = resultSet.getShort(j + 1);
-      return aShort == 0 && resultSet.wasNull() ? null : aShort;
-    case Types.TINYINT:
-      final byte aByte = resultSet.getByte(j + 1);
-      return aByte == 0 && resultSet.wasNull() ? null : aByte;
-    case Types.DOUBLE:
-    case Types.FLOAT:
-      final double aDouble = resultSet.getDouble(j + 1);
-      return aDouble == 0D && resultSet.wasNull() ? null : aDouble;
-    case Types.REAL:
-      final float aFloat = resultSet.getFloat(j + 1);
-      return aFloat == 0D && resultSet.wasNull() ? null : aFloat;
-    case Types.DATE:
-      final Date aDate = resultSet.getDate(j + 1, calendar);
-      return aDate == null
-          ? null
-          : (int) (aDate.getTime() / DateTimeUtils.MILLIS_PER_DAY);
-    case Types.TIME:
-      final Time aTime = resultSet.getTime(j + 1, calendar);
-      return aTime == null
-          ? null
-          : (int) (aTime.getTime() % DateTimeUtils.MILLIS_PER_DAY);
-    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);
-    }
-  }
-}
-
-// End JdbcResultSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
deleted file mode 100644
index ff27d05..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
+++ /dev/null
@@ -1,170 +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.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-import java.util.Objects;
-
-/**
- * All we know about a statement. Encapsulates a {@link ResultSet}.
- */
-public class StatementInfo {
-  private volatile Boolean relativeSupported = null;
-
-  final Statement statement; // sometimes a PreparedStatement
-  private ResultSet resultSet;
-  private long position = 0;
-
-  // True when setResultSet(ResultSet) is called to let us determine the difference between
-  // a null ResultSet (from an update) from the lack of a ResultSet.
-  private boolean resultsInitialized = false;
-
-  public StatementInfo(Statement statement) {
-    this.statement = Objects.requireNonNull(statement);
-  }
-
-  // Visible for testing
-  void setPosition(long position) {
-    this.position = position;
-  }
-
-  // Visible for testing
-  long getPosition() {
-    return this.position;
-  }
-
-  /**
-   * Set a ResultSet on this object.
-   *
-   * @param resultSet The current ResultSet
-   */
-  public void setResultSet(ResultSet resultSet) {
-    resultsInitialized = true;
-    this.resultSet = resultSet;
-  }
-
-  /**
-   * @return The {@link ResultSet} for this Statement, may be null.
-   */
-  public ResultSet getResultSet() {
-    return this.resultSet;
-  }
-
-  /**
-   * @return True if {@link #setResultSet(ResultSet)} was ever invoked.
-   */
-  public boolean isResultSetInitialized() {
-    return resultsInitialized;
-  }
-
-  /**
-   * @see ResultSet#next()
-   */
-  public boolean next() throws SQLException {
-    return _next(resultSet);
-  }
-
-  boolean _next(ResultSet results) throws SQLException {
-    boolean ret = results.next();
-    position++;
-    return ret;
-  }
-
-  /**
-   * Consumes <code>offset - position</code> elements from the {@link ResultSet}.
-   *
-   * @param offset The offset to advance to
-   * @return True if the resultSet was advanced to the current point, false if insufficient rows
-   *      were present to advance to the requested offset.
-   */
-  public boolean advanceResultSetToOffset(ResultSet results, long offset) throws SQLException {
-    if (offset < 0 || offset < position) {
-      throw new IllegalArgumentException("Offset should be "
-        + " non-negative and not less than the current position. " + offset + ", " + position);
-    }
-    if (position >= offset) {
-      return true;
-    }
-
-    if (null == relativeSupported) {
-      Boolean moreResults = null;
-      synchronized (this) {
-        if (null == relativeSupported) {
-          try {
-            moreResults = advanceByRelative(results, offset);
-            relativeSupported = true;
-          } catch (SQLFeatureNotSupportedException e) {
-            relativeSupported = false;
-          }
-        }
-      }
-
-      if (null != moreResults) {
-        // We figured out whether or not relative is supported.
-        // Make sure we actually do the necessary work.
-        if (!relativeSupported) {
-          // We avoided calling advanceByNext in the synchronized block earlier.
-          moreResults = advanceByNext(results, offset);
-        }
-
-        return moreResults;
-      }
-
-      // Another thread updated the RELATIVE_SUPPORTED before we did, fall through.
-    }
-
-    if (relativeSupported) {
-      return advanceByRelative(results, offset);
-    } else {
-      return advanceByNext(results, offset);
-    }
-  }
-
-  private boolean advanceByRelative(ResultSet results, long offset) throws SQLException {
-    long diff = offset - position;
-    while (diff > Integer.MAX_VALUE) {
-      if (!results.relative(Integer.MAX_VALUE)) {
-        // Avoid updating position until relative succeeds.
-        position += Integer.MAX_VALUE;
-        return false;
-      }
-      // Avoid updating position until relative succeeds.
-      position += Integer.MAX_VALUE;
-      diff -= Integer.MAX_VALUE;
-    }
-    boolean ret = results.relative((int) diff);
-    // Make sure we only update the position after successfully calling relative(int).
-    position += diff;
-    return ret;
-  }
-
-  private boolean advanceByNext(ResultSet results, long offset) throws SQLException {
-    while (position < offset) {
-      // Advance while maintaining `position`
-      if (!_next(results)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-}
-
-// End StatementInfo.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
deleted file mode 100644
index 8b8fb76..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-
-/** Implements an Avatica provider on top of an existing JDBC data source. */
-package org.apache.calcite.avatica.jdbc;
-
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
deleted file mode 100644
index 42b13c9..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
+++ /dev/null
@@ -1,32 +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.server;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.server.Handler;
-
-/**
- * A custom interface that extends the Jetty interface to enable extra control within Avatica.
- */
-public interface AvaticaHandler extends Handler {
-
-  void setServerRpcMetadata(RpcMetadataResponse metadata);
-
-}
-
-// End AvaticaHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
deleted file mode 100644
index 34a9333..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
+++ /dev/null
@@ -1,127 +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.server;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
-import org.apache.calcite.avatica.remote.JsonHandler;
-import org.apache.calcite.avatica.remote.Service;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class AvaticaJsonHandler extends AbstractHandler implements MetricsAwareAvaticaHandler {
-  private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
-
-  final Service service;
-  final JsonHandler jsonHandler;
-
-  final MetricsSystem metrics;
-  final Timer requestTimer;
-
-  final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
-
-  public AvaticaJsonHandler(Service service) {
-    this(service, NoopMetricsSystem.getInstance());
-  }
-
-  public AvaticaJsonHandler(Service service, MetricsSystem metrics) {
-    this.service = Objects.requireNonNull(service);
-    this.metrics = Objects.requireNonNull(metrics);
-    // Avatica doesn't have a Guava dependency
-    this.jsonHandler = new JsonHandler(service, this.metrics);
-
-    // Metrics
-    this.requestTimer = this.metrics.getTimer(
-        concat(AvaticaJsonHandler.class, MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
-
-    this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
-      @Override public UnsynchronizedBuffer initialValue() {
-        return new UnsynchronizedBuffer();
-      }
-    };
-  }
-
-  public void handle(String target, Request baseRequest,
-      HttpServletRequest request, HttpServletResponse response)
-      throws IOException, ServletException {
-    try (final Context ctx = requestTimer.start()) {
-      response.setContentType("application/json;charset=utf-8");
-      response.setStatus(HttpServletResponse.SC_OK);
-      if (request.getMethod().equals("POST")) {
-        // First look for a request in the header, then look in the body.
-        // The latter allows very large requests without hitting HTTP 413.
-        String rawRequest = request.getHeader("request");
-        if (rawRequest == null) {
-          // Avoid a new buffer creation for every HTTP request
-          final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
-          try (ServletInputStream inputStream = request.getInputStream()) {
-            rawRequest = AvaticaUtils.readFully(inputStream, buffer);
-          } finally {
-            // Reset the offset into the buffer after we're done
-            buffer.reset();
-          }
-        }
-        final String jsonRequest =
-            new String(rawRequest.getBytes("ISO-8859-1"), "UTF-8");
-        LOG.trace("request: {}", jsonRequest);
-
-        final HandlerResponse<String> jsonResponse = jsonHandler.apply(jsonRequest);
-        LOG.trace("response: {}", jsonResponse);
-        baseRequest.setHandled(true);
-        // Set the status code and write out the response.
-        response.setStatus(jsonResponse.getStatusCode());
-        response.getWriter().println(jsonResponse.getResponse());
-      }
-    }
-  }
-
-  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
-    // Set the metadata for the normal service calls
-    service.setRpcMetadata(metadata);
-    // Also add it to the handler to include with exceptions
-    jsonHandler.setRpcMetadata(metadata);
-  }
-
-  @Override public MetricsSystem getMetrics() {
-    return metrics;
-  }
-}
-
-// End AvaticaJsonHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
deleted file mode 100644
index 27e73de..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
+++ /dev/null
@@ -1,121 +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.server;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
-import org.apache.calcite.avatica.remote.MetricsHelper;
-import org.apache.calcite.avatica.remote.ProtobufHandler;
-import org.apache.calcite.avatica.remote.ProtobufTranslation;
-import org.apache.calcite.avatica.remote.ProtobufTranslationImpl;
-import org.apache.calcite.avatica.remote.Service;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class AvaticaProtobufHandler extends AbstractHandler implements MetricsAwareAvaticaHandler {
-  private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
-
-  private final Service service;
-  private final ProtobufHandler pbHandler;
-  private final ProtobufTranslation protobufTranslation;
-  private final MetricsSystem metrics;
-  private final Timer requestTimer;
-
-  final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
-
-  public AvaticaProtobufHandler(Service service) {
-    this(service, NoopMetricsSystem.getInstance());
-  }
-
-  public AvaticaProtobufHandler(Service service, MetricsSystem metrics) {
-    this.service = Objects.requireNonNull(service);
-    this.metrics = Objects.requireNonNull(metrics);
-
-    this.requestTimer = this.metrics.getTimer(
-        MetricsHelper.concat(AvaticaProtobufHandler.class,
-            MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
-
-    this.protobufTranslation = new ProtobufTranslationImpl();
-    this.pbHandler = new ProtobufHandler(service, protobufTranslation, metrics);
-
-    this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
-      @Override public UnsynchronizedBuffer initialValue() {
-        return new UnsynchronizedBuffer();
-      }
-    };
-  }
-
-  public void handle(String target, Request baseRequest,
-      HttpServletRequest request, HttpServletResponse response)
-      throws IOException, ServletException {
-    try (final Context ctx = this.requestTimer.start()) {
-      response.setContentType("application/octet-stream;charset=utf-8");
-      response.setStatus(HttpServletResponse.SC_OK);
-      if (request.getMethod().equals("POST")) {
-        byte[] requestBytes;
-        // Avoid a new buffer creation for every HTTP request
-        final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
-        try (ServletInputStream inputStream = request.getInputStream()) {
-          requestBytes = AvaticaUtils.readFullyToBytes(inputStream, buffer);
-        } finally {
-          buffer.reset();
-        }
-
-        HandlerResponse<byte[]> handlerResponse = pbHandler.apply(requestBytes);
-
-        baseRequest.setHandled(true);
-        response.setStatus(handlerResponse.getStatusCode());
-        response.getOutputStream().write(handlerResponse.getResponse());
-      }
-    }
-  }
-
-  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
-    // Set the metadata for the normal service calls
-    service.setRpcMetadata(metadata);
-    // Also add it to the handler to include with exceptions
-    pbHandler.setRpcMetadata(metadata);
-  }
-
-  @Override public MetricsSystem getMetrics() {
-    return this.metrics;
-  }
-
-}
-
-// End AvaticaProtobufHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
deleted file mode 100644
index a574985..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
+++ /dev/null
@@ -1,116 +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.server;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * An AvaticaHandler implementation that delegates to a provided Jetty Handler instance.
- *
- * <p>This implementation provides a no-op implementation for
- * {@link #setServerRpcMetadata(org.apache.calcite.avatica.remote.Service.RpcMetadataResponse)}.
- *
- * Does not implement {@link MetricsAwareAvaticaHandler} as this implementation is only presented
- * for backwards compatibility.
- */
-public class DelegatingAvaticaHandler implements AvaticaHandler {
-  private static final Logger LOG = LoggerFactory.getLogger(DelegatingAvaticaHandler.class);
-
-  private final Handler handler;
-
-  public DelegatingAvaticaHandler(Handler handler) {
-    this.handler = Objects.requireNonNull(handler);
-  }
-
-  @Override public void handle(String target, Request baseRequest, HttpServletRequest request,
-      HttpServletResponse response) throws IOException, ServletException {
-    handler.handle(target, baseRequest, request, response);
-  }
-
-  @Override public void setServer(Server server) {
-    handler.setServer(server);
-  }
-
-  @Override public Server getServer() {
-    return handler.getServer();
-  }
-
-  @Override public void destroy() {
-    handler.destroy();
-  }
-
-  @Override public void start() throws Exception {
-    handler.start();
-  }
-
-  @Override public void stop() throws Exception {
-    handler.stop();
-  }
-
-  @Override public boolean isRunning() {
-    return handler.isRunning();
-  }
-
-  @Override public boolean isStarted() {
-    return handler.isStarted();
-  }
-
-  @Override public boolean isStarting() {
-    return handler.isStarting();
-  }
-
-  @Override public boolean isStopping() {
-    return handler.isStopping();
-  }
-
-  @Override public boolean isStopped() {
-    return handler.isStopped();
-  }
-
-  @Override public boolean isFailed() {
-    return handler.isFailed();
-  }
-
-  @Override public void addLifeCycleListener(Listener listener) {
-    handler.addLifeCycleListener(listener);
-  }
-
-  @Override public void removeLifeCycleListener(Listener listener) {
-    handler.removeLifeCycleListener(listener);
-  }
-
-  @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
-    LOG.warn("Setting RpcMetadata is not implemented for DelegatingAvaticaHandler");
-  }
-
-}
-
-// End DelegatingAvaticaHandler.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
deleted file mode 100644
index b1fcb40..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
+++ /dev/null
@@ -1,115 +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.server;
-
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
-import org.apache.calcite.avatica.metrics.MetricsSystemLoader;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
-import org.apache.calcite.avatica.remote.Driver;
-import org.apache.calcite.avatica.remote.Service;
-
-import org.eclipse.jetty.server.Handler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.ServiceLoader;
-
-/**
- * Factory that instantiates the desired implementation, typically differing on the method
- * used to serialize messages, for use in the Avatica server.
- */
-public class HandlerFactory {
-  private static final Logger LOG = LoggerFactory.getLogger(HandlerFactory.class);
-
-  /**
-   * Constructs the desired implementation for the given serialization method with metrics.
-   *
-   * @param service The underlying {@link Service}.
-   * @param serialization The desired message serialization.
-   * @return The {@link Handler}.
-   */
-  public Handler getHandler(Service service, Driver.Serialization serialization) {
-    return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance());
-  }
-
-  /**
-   * Constructs the desired implementation for the given serialization method with metrics.
-   *
-   * @param service The underlying {@link Service}.
-   * @param serialization The desired message serialization.
-   * @param metricsConfig Configuration for the {@link MetricsSystem}.
-   * @return The {@link Handler}.
-   */
-  public Handler getHandler(Service service, Driver.Serialization serialization,
-      MetricsSystemConfiguration<?> metricsConfig) {
-    MetricsSystem metrics = MetricsSystemLoader.load(Objects.requireNonNull(metricsConfig));
-
-    switch (serialization) {
-    case JSON:
-      return new AvaticaJsonHandler(service, metrics);
-    case PROTOBUF:
-      return new AvaticaProtobufHandler(service, metrics);
-    default:
-      throw new IllegalArgumentException("Unknown Avatica handler for " + serialization.name());
-    }
-  }
-
-  /**
-   * Load a {@link MetricsSystem} using ServiceLoader to create a {@link MetricsSystemFactory}.
-   *
-   * @param config State to pass to the factory for initialization.
-   * @return A {@link MetricsSystem} instance.
-   */
-  MetricsSystem loadMetricsSystem(MetricsSystemConfiguration<?> config) {
-    ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class);
-    List<MetricsSystemFactory> availableFactories = new ArrayList<>();
-    for (MetricsSystemFactory factory : loader) {
-      availableFactories.add(factory);
-    }
-
-    if (1 == availableFactories.size()) {
-      // One and only one instance -- what we want
-      MetricsSystemFactory factory = availableFactories.get(0);
-      LOG.info("Loaded MetricsSystem {}", factory.getClass());
-      return factory.create(config);
-    } else if (availableFactories.isEmpty()) {
-      // None-provided default to no metrics
-      LOG.info("No metrics implementation available on classpath. Using No-op implementation");
-      return NoopMetricsSystem.getInstance();
-    } else {
-      // Tell the user they're doing something wrong, and choose the first impl.
-      StringBuilder sb = new StringBuilder();
-      for (MetricsSystemFactory factory : availableFactories) {
-        if (sb.length() > 0) {
-          sb.append(", ");
-        }
-        sb.append(factory.getClass());
-      }
-      LOG.warn("Found multiple MetricsSystemFactory implementations: {}."
-          + " Using No-op implementation", sb);
-      return NoopMetricsSystem.getInstance();
-    }
-  }
-}
-
-// End HandlerFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
deleted file mode 100644
index c81e899..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
+++ /dev/null
@@ -1,168 +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.server;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.server.handler.HandlerList;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Avatica HTTP server.
- *
- * <p>If you need to change the server's configuration, override the
- * {@link #configureConnector(ServerConnector, int)} method in a derived class.
- */
-public class HttpServer {
-  private static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);
-
-  private Server server;
-  private int port = -1;
-  private final AvaticaHandler handler;
-
-  @Deprecated
-  public HttpServer(Handler handler) {
-    this(wrapJettyHandler(handler));
-  }
-
-  public HttpServer(AvaticaHandler handler) {
-    this(0, handler);
-  }
-
-  @Deprecated
-  public HttpServer(int port, Handler handler) {
-    this(port, wrapJettyHandler(handler));
-  }
-
-  public HttpServer(int port, AvaticaHandler handler) {
-    this.port = port;
-    this.handler = handler;
-  }
-
-  private static AvaticaHandler wrapJettyHandler(Handler handler) {
-    if (handler instanceof AvaticaHandler) {
-      return (AvaticaHandler) handler;
-    }
-    // Backwards compatibility, noop's the AvaticaHandler interface
-    return new DelegatingAvaticaHandler(handler);
-  }
-
-  public void start() {
-    if (server != null) {
-      throw new RuntimeException("Server is already started");
-    }
-
-    final QueuedThreadPool threadPool = new QueuedThreadPool();
-    threadPool.setDaemon(true);
-    server = new Server(threadPool);
-    server.manage(threadPool);
-
-    final ServerConnector connector = configureConnector(new ServerConnector(server), port);
-
-    server.setConnectors(new Connector[] { connector });
-
-    final HandlerList handlerList = new HandlerList();
-    handlerList.setHandlers(new Handler[] { handler, new DefaultHandler() });
-    server.setHandler(handlerList);
-    try {
-      server.start();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-    port = connector.getLocalPort();
-
-    LOG.info("Service listening on port {}.", getPort());
-
-    // Set the information about the address for this server
-    try {
-      this.handler.setServerRpcMetadata(createRpcServerMetadata(connector));
-    } catch (UnknownHostException e) {
-      // Failed to do the DNS lookup, bail out.
-      throw new RuntimeException(e);
-    }
-  }
-
-  private RpcMetadataResponse createRpcServerMetadata(ServerConnector connector) throws
-      UnknownHostException {
-    String host = connector.getHost();
-    if (null == host) {
-      // "null" means binding to all interfaces, we need to pick one so the client gets a real
-      // address and not "0.0.0.0" or similar.
-      host = InetAddress.getLocalHost().getHostName();
-    }
-
-    final int port = connector.getLocalPort();
-
-    return new RpcMetadataResponse(String.format("%s:%d", host, port));
-  }
-
-  /**
-   * Configures the server connector.
-   *
-   * <p>The default configuration sets a timeout of 1 minute and disables
-   * TCP linger time.
-   *
-   * <p>To change the configuration, override this method in a derived class.
-   * The overriding method must call its super method.
-   *
-   * @param connector connector to be configured
-   * @param port port number handed over in constructor
-   */
-  protected ServerConnector configureConnector(ServerConnector connector, int port) {
-    connector.setIdleTimeout(60 * 1000);
-    connector.setSoLingerTime(-1);
-    connector.setPort(port);
-    return connector;
-  }
-
-  public void stop() {
-    if (server == null) {
-      throw new RuntimeException("Server is already stopped");
-    }
-
-    LOG.info("Service terminating.");
-    try {
-      final Server server1 = server;
-      port = -1;
-      server = null;
-      server1.stop();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public void join() throws InterruptedException {
-    server.join();
-  }
-
-  public int getPort() {
-    return port;
-  }
-}
-
-// End HttpServer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/Main.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/Main.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/Main.java
deleted file mode 100644
index 8b05931..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/Main.java
+++ /dev/null
@@ -1,100 +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.server;
-
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.remote.LocalService;
-import org.apache.calcite.avatica.remote.Service;
-
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import java.util.Arrays;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class Main {
-  private Main() {}
-
-  public static void main(String[] args)
-      throws InterruptedException, ClassNotFoundException,
-      IllegalAccessException, InstantiationException {
-    HttpServer server = start(args);
-    server.join();
-  }
-
-  /**
-   * Factory that instantiates Jetty Handlers
-   */
-  public interface HandlerFactory {
-    AbstractHandler createHandler(Service service);
-  }
-
-  private static final HandlerFactory JSON_HANDLER_FACTORY = new HandlerFactory() {
-    public AbstractHandler createHandler(Service service) {
-      return new AvaticaJsonHandler(service);
-    }
-  };
-
-  /**
-   * Creates and starts an {@link HttpServer} using JSON POJO serialization of requests/responses.
-   *
-   * <p>Arguments are as follows:
-   * <ul>
-   *   <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
-   *       name
-   *   <li>args[1+]: arguments passed along to
-   *   {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
-   * </ul>
-   *
-   * @param args Command-line arguments
-   */
-  public static HttpServer start(String[] args) throws ClassNotFoundException,
-         InstantiationException, IllegalAccessException {
-    return start(args, 8765, JSON_HANDLER_FACTORY);
-  }
-
-  /**
-   * Creates and starts an {@link HttpServer} using the given factory to create the Handler.
-   *
-   * <p>Arguments are as follows:
-   * <ul>
-   *   <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
-   *       name
-   *   <li>args[1+]: arguments passed along to
-   *   {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
-   * </ul>
-   *
-   * @param args Command-line arguments
-   * @param port Server port to bind
-   * @param handlerFactory Factory to create the handler used by the server
-   */
-  public static HttpServer start(String[] args, int port, HandlerFactory handlerFactory)
-      throws ClassNotFoundException, InstantiationException,
-      IllegalAccessException {
-    String factoryClassName = args[0];
-    Class<?> factoryClass = Class.forName(factoryClassName);
-    Meta.Factory factory = (Meta.Factory) factoryClass.newInstance();
-    Meta meta = factory.create(Arrays.asList(args).subList(1, args.length));
-    Service service = new LocalService(meta);
-    HttpServer server = new HttpServer(port, handlerFactory.createHandler(service));
-    server.start();
-    return server;
-  }
-}
-
-// End Main.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java b/avatica-server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
deleted file mode 100644
index 0914dbd..0000000
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/server/MetricsAwareAvaticaHandler.java
+++ /dev/null
@@ -1,43 +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.server;
-
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-
-/**
- * An {@link AvaticaHandler} that is capable of collecting metrics.
- */
-public interface MetricsAwareAvaticaHandler extends AvaticaHandler {
-
-  /**
-   * General prefix for all metrics in a handler.
-   */
-  String HANDLER_PREFIX = "Handler.";
-
-  /**
-   * Name for timing requests from users
-   */
-  String REQUEST_TIMER_NAME = HANDLER_PREFIX + "RequestTimings";
-
-  /**
-   * @return An instance of the {@link MetricsSystem} for this AvaticaHandler.
-   */
-  MetricsSystem getMetrics();
-
-}
-
-// End MetricsAwareAvaticaHandler.java


[16/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/avatica/site/fonts/fontawesome-webfont.woff b/avatica/site/fonts/fontawesome-webfont.woff
new file mode 100755
index 0000000..628b6a5
Binary files /dev/null and b/avatica/site/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/img/cake.jpg
----------------------------------------------------------------------
diff --git a/avatica/site/img/cake.jpg b/avatica/site/img/cake.jpg
new file mode 100644
index 0000000..af370c6
Binary files /dev/null and b/avatica/site/img/cake.jpg differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/img/feather.png
----------------------------------------------------------------------
diff --git a/avatica/site/img/feather.png b/avatica/site/img/feather.png
new file mode 100644
index 0000000..a2da98a
Binary files /dev/null and b/avatica/site/img/feather.png differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/img/logo.png
----------------------------------------------------------------------
diff --git a/avatica/site/img/logo.png b/avatica/site/img/logo.png
new file mode 100644
index 0000000..b883465
Binary files /dev/null and b/avatica/site/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/img/pie-chart.png
----------------------------------------------------------------------
diff --git a/avatica/site/img/pie-chart.png b/avatica/site/img/pie-chart.png
new file mode 100644
index 0000000..59e2ddb
Binary files /dev/null and b/avatica/site/img/pie-chart.png differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/img/window-types.png
----------------------------------------------------------------------
diff --git a/avatica/site/img/window-types.png b/avatica/site/img/window-types.png
new file mode 100644
index 0000000..366c00a
Binary files /dev/null and b/avatica/site/img/window-types.png differ

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/index.html
----------------------------------------------------------------------
diff --git a/avatica/site/index.html b/avatica/site/index.html
new file mode 100644
index 0000000..8857d27
--- /dev/null
+++ b/avatica/site/index.html
@@ -0,0 +1,75 @@
+---
+layout: default
+title: Apache Calcite &bull; Dynamic data management framework
+overview: true
+---
+{% comment %}
+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.
+{% endcomment %}
+
+<section class="intro">
+  <div class="grid">
+    <div class="unit whole center-on-mobiles">
+      <p class="first">The foundation for your next high-performance database.</p>
+    </div>
+  </div>
+</section>
+<section class="features">
+  <div class="grid">
+    <div class="unit one-third">
+      <h2>Standard SQL</h2>
+      <p>Industry-standard SQL parser, validator and JDBC driver.</p>
+      <a href="{{ site.baseurl }}/docs/reference.html">SQL &rarr;</a>
+    </div>
+    <div class="unit one-third">
+      <h2>Query optimization</h2>
+      <p>Represent your query in relational algebra, transform using
+        planning rules, and optimize according to a cost model.</p>
+      <a href="{{ site.baseurl }}/docs/algebra.html">Relational algebra &rarr;</a>
+    </div>
+    <div class="unit one-third">
+      <h2>Any data, anywhere</h2>
+      <p>Connect to third-party data sources, browse metadata, and optimize by pushing the computation to the data.</p>
+      <a href="{{ site.baseurl }}/docs/adapter.html">Adapters &rarr;</a>
+    </div>
+    <div class="clear"></div>
+  </div>
+</section>
+<section class="resources">
+  <div class="grid">
+    <div class="unit one-third">
+      <summary>
+        <h3>Resources</h3>
+        <ul>
+          <li><a href="{{ site.baseurl }}/downloads">Downloads</a></li>
+          <li><a href="{{ site.baseurl }}/docs/history.html">History</a></li>
+          <li><a href="http://www.apache.org/security">Security</a></li>
+        </ul>
+      </summary>
+    </div>
+    <div class="unit one-third">
+      <summary>
+        <h3>Apache</h3>
+        <ul>
+          <li><a href="http://www.apache.org/licenses">License</a></li>
+          <li><a href="http://www.apache.org/foundation/sponsorship.html">Donate</a></li>
+          <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+          <li><a href="http://www.apache.org">Website</a></li>
+        </ul>
+      </summary>
+    </div>
+  </div>
+</section>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/js/html5shiv.min.js
----------------------------------------------------------------------
diff --git a/avatica/site/js/html5shiv.min.js b/avatica/site/js/html5shiv.min.js
new file mode 100644
index 0000000..d4c731a
--- /dev/null
+++ b/avatica/site/js/html5shiv.min.js
@@ -0,0 +1,4 @@
+/**
+* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag
 ()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"
 ==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/js/respond.min.js
----------------------------------------------------------------------
diff --git a/avatica/site/js/respond.min.js b/avatica/site/js/respond.min.js
new file mode 100644
index 0000000..80a7b69
--- /dev/null
+++ b/avatica/site/js/respond.min.js
@@ -0,0 +1,5 @@
+/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
+ * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
+ *  */
+
+!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:
 o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeC
 hild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substr
 ing(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("
 //"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/news/index.html
----------------------------------------------------------------------
diff --git a/avatica/site/news/index.html b/avatica/site/news/index.html
new file mode 100644
index 0000000..66d4dcd
--- /dev/null
+++ b/avatica/site/news/index.html
@@ -0,0 +1,35 @@
+---
+layout: news
+title: News
+permalink: /news/
+author: all
+---
+{% comment %}
+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.
+{% endcomment %}
+
+{% for post in site.posts %}
+  {% include news_item.html %}
+{% endfor %}
+
+<p></p>
+
+<h2>Calcite Twitter</h2>
+
+<p>The official <a href="https://twitter.com/ApacheCalcite">@ApacheCalcite</a>
+Twitter account pushes announcements about Calcite. If you give a talk about
+Calcite, let us know and we'll tweet it out and add it to the news section
+of the website.</p>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/news/releases/index.html
----------------------------------------------------------------------
diff --git a/avatica/site/news/releases/index.html b/avatica/site/news/releases/index.html
new file mode 100644
index 0000000..c6c9fa6
--- /dev/null
+++ b/avatica/site/news/releases/index.html
@@ -0,0 +1,26 @@
+---
+layout: news
+title: Releases
+permalink: /news/releases/
+author: all
+---
+{% comment %}
+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.
+{% endcomment %}
+
+{% for post in site.categories.release %}
+  {% include news_item.html %}
+{% endfor %}

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/config/assemblies/source-assembly.xml
----------------------------------------------------------------------
diff --git a/avatica/src/main/config/assemblies/source-assembly.xml b/avatica/src/main/config/assemblies/source-assembly.xml
new file mode 100644
index 0000000..2b1f930
--- /dev/null
+++ b/avatica/src/main/config/assemblies/source-assembly.xml
@@ -0,0 +1,103 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+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.
+-->
+<assembly>
+  <id>source-release</id>
+  <formats>
+    <format>zip</format>
+    <format>tar.gz</format>
+  </formats>
+  <fileSets>
+    <!-- main project directory structure -->
+    <fileSet>
+      <directory>.</directory>
+      <outputDirectory>/</outputDirectory>
+      <useDefaultExcludes>true</useDefaultExcludes>
+      <excludes>
+        <!-- build output -->
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*]
+        </exclude>
+
+        <!-- NOTE: Most of the following excludes should not be required
+          if the standard release process is followed. This is because the release
+          plugin checks out project sources into a location like target/checkout, then
+          runs the build from there. The result is a source-release archive that comes
+          from a pretty clean directory structure. HOWEVER, if the release plugin is
+          configured to run extra goals or generate a project website, it's definitely
+          possible that some of these files will be present. So, it's safer to exclude
+          them. -->
+
+        <!-- IDEs -->
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?maven-eclipse\.xml]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.project]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.classpath]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iws]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.idea(/.*)?]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?out(/.*)?]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.ipr]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.settings(/.*)?]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.externalToolBuilders(/.*)?]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.deployables(/.*)?]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.wtpmodules(/.*)?]
+        </exclude>
+
+
+        <!-- scm -->
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.gitignore(/.*)?]
+        </exclude>
+
+        <exclude>**/.buildpath</exclude>
+        <exclude>**/sandbox/**</exclude>
+
+        <!-- misc -->
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?cobertura\.ser]
+        </exclude>
+
+        <!-- release-plugin temp files -->
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup]
+        </exclude>
+        <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties]
+        </exclude>
+      </excludes>
+    </fileSet>
+    <!-- LICENSE, NOTICE, DEPENDENCIES, git.properties, etc. calculated at build time -->
+    <fileSet>
+      <directory>${project.build.directory}/maven-shared-archive-resources/META-INF
+      </directory>
+      <outputDirectory>/</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>${project.build.directory}</directory>
+      <includes>
+        <include>git.properties</include>
+      </includes>
+      <outputDirectory>/</outputDirectory>
+    </fileSet>
+  </fileSets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/config/checkstyle/checker.xml
----------------------------------------------------------------------
diff --git a/avatica/src/main/config/checkstyle/checker.xml b/avatica/src/main/config/checkstyle/checker.xml
new file mode 100644
index 0000000..167511b
--- /dev/null
+++ b/avatica/src/main/config/checkstyle/checker.xml
@@ -0,0 +1,279 @@
+<?xml version="1.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.
+-->
+
+<!--
+  This version of checkstyle is based on the Apache Giraph checkstyle
+  configuration, which in turn is based on Hadoop and common-math
+  configurations.
+
+  The documentation for checkstyle is available at
+
+  http://checkstyle.sourceforge.net
+-->
+
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+
+<!-- Calcite customization of default Checkstyle behavior -->
+<module name="Checker">
+  <property name="localeLanguage" value="en"/>
+
+  <!-- Checks for headers -->
+  <!-- See http://checkstyle.sf.net/config_header.html -->
+    <!-- Verify that EVERY source file has the appropriate license -->
+  <module name="Header">
+    <property name="headerFile" value="${checkstyle.header.file}"/>
+  </module>
+
+  <!-- Checks for Javadoc comments (checker).           -->
+  <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+    <!-- Require package javadoc -->
+  <module name="JavadocPackage"/>
+
+  <!-- Miscellaneous other checks (checker).         -->
+  <!-- See http://checkstyle.sf.net/config_misc.html -->
+    <!-- Require files to end with newline characters -->
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+
+  <!-- Checks for whitespace (tree walker)                 -->
+  <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <!-- No tabs allowed! -->
+  <module name="FileTabCharacter"/>
+
+  <module name="TreeWalker">
+    <property name="cacheFile" value="target/checkstyle-cachefile"/>
+
+    <!-- Checks for blocks. You know, those {}'s         -->
+    <!-- See http://checkstyle.sf.net/config_blocks.html -->
+      <!-- No empty blocks (i.e. catch); must contain at least a comment -->
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+    </module>
+    <module name="AvoidNestedBlocks">
+        <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="LeftCurly"/>
+      <!-- No if/else/do/for/while without braces -->
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+
+    <!-- Checks for class design                         -->
+    <!-- See http://checkstyle.sf.net/config_design.html -->
+      <!-- Utility class should not be instantiated, they must have a
+           private constructor -->
+    <module name="HideUtilityClassConstructor"/>
+
+    <!-- Checks for common coding problems               -->
+    <!-- See http://checkstyle.sf.net/config_coding.html -->
+    <module name="EmptyStatement"/>
+      <!-- Require hash code override when equals is -->
+    <module name="EqualsHashCode"/>
+      <!-- Disallow unnecessary instantiation of Boolean, String -->
+    <module name="IllegalInstantiation">
+      <property name="classes" value="java.lang.Boolean, java.lang.String"/>
+    </module>
+      <!-- Switch statements should be complete and with independent cases -->
+    <module name="FallThrough"/>
+    <module name="SimplifyBooleanExpression"/>
+    <module name="SimplifyBooleanReturn"/>
+      <!-- Only one statement per line allowed -->
+    <module name="OneStatementPerLine"/>
+      <!-- Don't add up parentheses when they are not required -->
+    <module name="UnnecessaryParentheses" />
+      <!-- Don't use = or != for string comparisons -->
+    <module name="StringLiteralEquality" />
+      <!-- Don't declare multiple variables in the same statement -->
+    <module name="MultipleVariableDeclarations" />
+      <!-- String literals more than one character long should not be
+           repeated several times -->
+      <!-- the "unchecked" string is also accepted to allow
+           @SuppressWarnings("unchecked") -->
+      <!-- Disabling for now until we have a better ignoreStringsRegexp -->
+      <!--
+    <module name="MultipleStringLiterals" >
+      <property name="ignoreStringsRegexp" value='^(("")|(".")|("unchecked"))$'/>
+    </module>
+      -->
+
+    <!-- Checks for imports                              -->
+    <!-- See http://checkstyle.sf.net/config_import.html -->
+    <module name="RedundantImport"/>
+      <!-- Import should be explicit, and only from pure java packages.
+           But we allow imports that are only used in javadoc. -->
+    <module name="UnusedImports">
+      <property name="processJavadoc" value="true"/>
+    </module>
+    <module name="IllegalImport" />
+    <module name="AvoidStarImport" />
+    <module name="ImportOrder">
+      <property name="groups" value="org.apache.calcite,org.apache,au.com.,com.,io.,mondrian.,net.,org.,scala.,/^javax?\./"/>
+      <property name="ordered" value="true"/>
+      <property name="separated" value="true"/>
+      <property name="option" value="bottom"/>
+    </module>
+
+    <!-- Checks for Javadoc comments (tree walker).       -->
+    <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+      <!-- Javadoc must be formatted correctly -->
+    <module name="JavadocStyle">
+      <property name="checkFirstSentence" value="false"/>
+    </module>
+      <!-- Must have class / interface header comments -->
+    <module name="JavadocType"/>
+
+    <!-- Miscellaneous other checks (tree walker).     -->
+    <!-- See http://checkstyle.sf.net/config_misc.html -->
+      <!-- Java style arrays -->
+    <module name="ArrayTypeStyle"/>
+      <!-- Indentation -->
+    <module name="Indentation">
+      <property name="caseIndent" value="0"/>
+      <property name="basicOffset" value="2"/>
+      <property name="braceAdjustment" value="0"/>
+    </module>
+      <!-- Turn this on to see what needs to be done
+    <module name="TodoComment"/>
+       -->
+    <module name="UpperEll"/>
+
+    <module name="OperatorWrap"/>
+
+    <!-- Modifier Checks                                    -->
+    <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+      <!-- Use a consistent way to put modifiers -->
+    <module name="ModifierOrder"/>
+    <module name="RedundantModifier"/>
+
+    <!-- Checks for Naming Conventions.                  -->
+    <!-- See http://checkstyle.sf.net/config_naming.html -->
+      <!-- Constant names should obey the traditional all uppercase
+           naming convention -->
+    <module name="ConstantName"/>
+    <module name="LocalFinalVariableName">
+      <!-- Allow '_' except first. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+    </module>
+    <module name="LocalVariableName">
+      <!-- Allow '_' except first. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+    </module>
+    <module name="MemberName"/>
+    <module name="MethodName">
+      <!-- Allow trailing '_', signifying private methods.
+           Also allow '_' prefix, indicating disabled method or junit test. -->
+      <property name="format" value="^_?[a-z][a-zA-Z0-9]*_?$"/>
+    </module>
+    <module name="PackageName"/>
+    <module name="ParameterName">
+      <!-- Allow trailing '_'. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
+    </module>
+    <module name="StaticVariableName"/>
+    <module name="TypeName"/>
+
+    <!-- Checks for regexp expressions.                  -->
+    <!-- See http://checkstyle.sf.net/config_regexp.html -->
+
+    <!-- No trailing whitespace -->
+    <module name="Regexp">
+      <property name="format" value="[ \t]+$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="Trailing whitespace"/>
+    </module>
+
+    <!-- Authors should be in pom.xml file -->
+    <module name="Regexp">
+      <property name="format" value="@author"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="developers names should be in pom file"/>
+    </module>
+
+    <!-- No multi-line C-style comments except at start of line. -->
+    <module name="Regexp">
+      <property name="format" value="^ +/\*[^*][^/]$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="C-style comment"/>
+    </module>
+
+    <module name="Regexp">
+      <property name="format" value="^ +/\*$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="C-style comment"/>
+    </module>
+
+    <!-- Checks for Size Violations.                    -->
+    <!-- See http://checkstyle.sf.net/config_sizes.html -->
+    <!-- Lines cannot exceed 80 chars, except if they are hyperlinks
+         or strings (possibly preceded by '+' and followed by say '),'. -->
+    <module name="LineLength">
+      <property name="max" value="100"/>
+      <property name="ignorePattern" value="^import|@see|@link|@BaseMessage|href|^[ +]*&quot;.*&quot;[);,]*$"/>
+    </module>
+      <!-- Over time, we will revise this down -->
+    <module name="MethodLength">
+      <property name="max" value="390"/>
+    </module>
+
+    <!-- Checks for whitespace (tree walker)                 -->
+    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <module name="EmptyForIteratorPad"/>
+      <!-- Spacing around methods -->
+    <module name="MethodParamPad">
+      <property name="option" value="nospace"/>
+      <property name="allowLineBreaks" value="true"/>
+     </module>
+      <!-- No whitespace before a token -->
+    <module name="NoWhitespaceBefore"/>
+      <!-- Whitespace after tokens is required -->
+    <module name="WhitespaceAfter"/>
+      <!-- Whitespace around tokens is required -->
+    <module name="WhitespaceAround">
+        <property name="allowEmptyConstructors" value="true"/>
+        <property name="allowEmptyMethods" value="true"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad"/>
+      <!-- No extra whitespace around types -->
+    <module name="GenericWhitespace"/>
+
+    <!-- Required for SuppressionCommentFilter below -->
+    <module name="FileContentsHolder"/>
+  </module>
+
+  <!-- Setup special comments to suppress specific checks from source files -->
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CHECKSTYLE\: stop ([\w\|]+)"/>
+    <property name="onCommentFormat"  value="CHECKSTYLE\: resume ([\w\|]+)"/>
+    <property name="checkFormat"      value="$1"/>
+  </module>
+
+  <!-- Turn off all checks between OFF and ON -->
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CHECKSTYLE\: OFF"/>
+    <property name="onCommentFormat"  value="CHECKSTYLE\: ON"/>
+  </module>
+
+  <!-- Turn off checks for the next N lines. -->
+  <module name="SuppressWithNearbyCommentFilter">
+    <property name="commentFormat" value="CHECKSTYLE: +IGNORE (\d+)"/>
+    <property name="influenceFormat" value="$1"/>
+  </module>
+
+  <module name="net.hydromatic.toolbox.checkstyle.HydromaticFileSetCheck"/>
+</module>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/config/checkstyle/header.txt
----------------------------------------------------------------------
diff --git a/avatica/src/main/config/checkstyle/header.txt b/avatica/src/main/config/checkstyle/header.txt
new file mode 100644
index 0000000..2a42971
--- /dev/null
+++ b/avatica/src/main/config/checkstyle/header.txt
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/config/checkstyle/suppressions.xml
----------------------------------------------------------------------
diff --git a/avatica/src/main/config/checkstyle/suppressions.xml b/avatica/src/main/config/checkstyle/suppressions.xml
new file mode 100644
index 0000000..d9ae88a
--- /dev/null
+++ b/avatica/src/main/config/checkstyle/suppressions.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!DOCTYPE suppressions PUBLIC
+        "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+        "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+<!--
+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.
+-->
+<suppressions>
+  <!-- Suppress checks on generated files. -->
+  <suppress checks="Header" files="CalciteResource.properties"/>
+  <suppress checks=".*" files="org-apache-calcite-jdbc.properties"/>
+  <suppress checks=".*" files="Foo.java"/>
+  <suppress checks=".*" files=".*[/\\]target[/\\]maven-archiver[/\\]pom.properties"/>
+  <suppress checks=".*" files="git.properties"/>
+  <suppress checks=".*" files="trace.properties"/>
+  <suppress checks=".*" files="release.properties"/>
+  <suppress checks=".*" files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]apache[/\\]calcite[/\\]avatica[/\\]proto"/>
+  <suppress checks=".*" files="log4j.properties"/>
+
+  <!-- This file triggers https://github.com/checkstyle/checkstyle/issues/92,
+       through no fault of its own. -->
+  <suppress checks=".*" files="SqlSimpleParser.java"/>
+
+  <!-- Don't complain about field names such as cust_id -->
+  <suppress checks=".*Name" files="JdbcExample.java"/>
+
+  <!-- Suppress JavadocPackage in the test packages -->
+  <suppress checks="JavadocPackage" files="src[/\\]test[/\\]java[/\\]"/>
+
+  <!-- And likewise in ubenchmark -->
+  <suppress checks="JavadocPackage" files="StatementTest.java"/>
+
+  <!-- Method names in Resource can have underscores -->
+  <suppress checks="MethodName" files="CalciteResource.java"/>
+</suppressions>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java b/avatica/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
deleted file mode 100644
index 62c4dd2..0000000
--- a/avatica/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
+++ /dev/null
@@ -1,77 +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 com.google.protobuf;
-
-/**
- * Helper class to extract byte arrays from {@link ByteString} without copy.
- *
- * Without this protobufs would force us to copy every single byte array out
- * of the objects de-serialized from the wire (which already do one copy, on
- * top of the copies the JVM does to go from kernel buffer to C buffer and
- * from C buffer to JVM buffer).
- *
- * Graciously copied from Apache HBase.
- */
-public final class HBaseZeroCopyByteString extends LiteralByteString {
-  // Gotten from AsyncHBase code base with permission.
-  /** Private constructor so this class cannot be instantiated. */
-  private HBaseZeroCopyByteString() {
-    super(null);
-    throw new UnsupportedOperationException("Should never be here.");
-  }
-
-  /**
-   * Wraps a byte array in a {@link ByteString} without copying it.
-   *
-   * @param array The byte array to wrap
-   * @return a ByteString wrapping the <code>array</code>
-   */
-  public static ByteString wrap(final byte[] array) {
-    return new LiteralByteString(array);
-  }
-
-  /**
-   * Wraps a subset of a byte array in a {@link ByteString} without copying it.
-   *
-   * @param array The byte array to wrap
-   * @param offset the start of data in the array
-   * @param length The number of bytes of data at <code>offset</code>
-   * @return a ByteString wrapping the <code>array</code>
-   */
-  public static ByteString wrap(final byte[] array, int offset, int length) {
-    return new BoundedByteString(array, offset, length);
-  }
-
-
-  /**
-   * Extracts the byte array from the given {@link ByteString} without copy.
-   * @param buf A buffer from which to extract the array.  This buffer must be
-   * actually an instance of a {@code LiteralByteString}.
-   *
-   * @param buf <code>ByteString</code> to access
-   * @return The underlying byte array of the ByteString
-   */
-  public static byte[] zeroCopyGetBytes(final ByteString buf) {
-    if (buf instanceof LiteralByteString) {
-      return ((LiteralByteString) buf).bytes;
-    }
-    throw new UnsupportedOperationException("Need a LiteralByteString, got a "
-                                            + buf.getClass().getName());
-  }
-}
-
-// End HBaseZeroCopyByteString.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/com/google/protobuf/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/com/google/protobuf/package-info.java b/avatica/src/main/java/com/google/protobuf/package-info.java
deleted file mode 100644
index 92f110e..0000000
--- a/avatica/src/main/java/com/google/protobuf/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * Avatica-custom classes to access protected classes in Google Protobuf.
- */
-@PackageMarker
-package com.google.protobuf;
-
-import org.apache.calcite.avatica.util.PackageMarker;
-
-// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
deleted file mode 100644
index df03b03..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
+++ /dev/null
@@ -1,94 +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.remote.AvaticaRuntimeException;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * The client-side representation of {@link AvaticaRuntimeException}. This exception is not intended
- * for consumption by clients, {@link AvaticaSqlException} serves that purpose. This exception only
- * exists to pass the original error attributes to a higher level of execution without modifying
- * existing exception-handling logic.
- */
-public class AvaticaClientRuntimeException extends RuntimeException {
-
-  private static final long serialVersionUID = 1L;
-
-  private final int errorCode;
-  private final String sqlState;
-  private final AvaticaSeverity severity;
-  private final List<String> serverExceptions;
-  private final RpcMetadataResponse metadata;
-
-  public AvaticaClientRuntimeException(String errorMessage, int errorCode, String sqlState,
-      AvaticaSeverity severity, List<String> serverExceptions, RpcMetadataResponse metadata) {
-    super(errorMessage);
-    this.errorCode = errorCode;
-    this.sqlState = sqlState;
-    this.severity = severity;
-    this.serverExceptions = serverExceptions;
-    this.metadata = metadata;
-  }
-
-  public AvaticaClientRuntimeException(String message, Throwable cause) {
-    super(message, cause);
-    errorCode = ErrorResponse.UNKNOWN_ERROR_CODE;
-    sqlState = ErrorResponse.UNKNOWN_SQL_STATE;
-    severity = AvaticaSeverity.UNKNOWN;
-    serverExceptions = Collections.singletonList("");
-    metadata = null;
-  }
-
-  public int getErrorCode() {
-    return errorCode;
-  }
-
-  public String getSqlState() {
-    return sqlState;
-  }
-
-  public AvaticaSeverity getSeverity() {
-    return severity;
-  }
-
-  public List<String> getServerExceptions() {
-    return serverExceptions;
-  }
-
-  public RpcMetadataResponse getRpcMetadata() {
-    return metadata;
-  }
-
-  @Override public String toString() {
-    StringBuilder sb = new StringBuilder(64);
-    sb.append(getClass().getSimpleName()).append(": ")
-    .append(getMessage()).append(". Error ").append(getErrorCode())
-    .append(" (").append(sqlState).append(") ").append(getSeverity()).append("\n\n");
-    for (String serverException : getServerExceptions()) {
-      sb.append(serverException).append("\n");
-    }
-    return sb.toString();
-  }
-
-}
-
-// End AvaticaClientRuntimeException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
deleted file mode 100644
index 2d89f45..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
+++ /dev/null
@@ -1,696 +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.Meta.MetaResultSet;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-import org.apache.calcite.avatica.remote.Service.OpenConnectionRequest;
-import org.apache.calcite.avatica.remote.TypedValue;
-
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Struct;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-
-/**
- * Implementation of JDBC connection
- * for the Avatica framework.
- *
- * <p>Abstract to allow newer versions of JDBC to add methods.
- */
-public abstract class AvaticaConnection implements Connection {
-
-  /** The name of the sole column returned by DML statements, containing
-   * the number of rows modified. */
-  public static final String ROWCOUNT_COLUMN_NAME = "ROWCOUNT";
-
-  public static final String NUM_EXECUTE_RETRIES_KEY = "avatica.statement.retries";
-  public static final String NUM_EXECUTE_RETRIES_DEFAULT = "5";
-
-  /** The name of the sole column returned by an EXPLAIN statement.
-   *
-   * <p>Actually Avatica does not care what this column is called, but here is
-   * a useful place to define a suggested value. */
-  public static final String PLAN_COLUMN_NAME = "PLAN";
-
-  protected int statementCount;
-  private boolean closed;
-  private int holdability;
-  private int networkTimeout;
-
-  public final String id;
-  public final Meta.ConnectionHandle handle;
-  protected final UnregisteredDriver driver;
-  protected final AvaticaFactory factory;
-  final String url;
-  protected final Properties info;
-  protected final Meta meta;
-  protected final AvaticaDatabaseMetaData metaData;
-  public final Helper helper = Helper.INSTANCE;
-  public final Map<InternalProperty, Object> properties = new HashMap<>();
-  public final Map<Integer, AvaticaStatement> statementMap =
-      new ConcurrentHashMap<>();
-  protected final long maxRetriesPerExecute;
-
-  /**
-   * Creates an AvaticaConnection.
-   *
-   * <p>Not public; method is called only from the driver or a derived
-   * class.</p>
-   *
-   * @param driver Driver
-   * @param factory Factory for JDBC objects
-   * @param url Server URL
-   * @param info Other connection properties
-   */
-  protected AvaticaConnection(UnregisteredDriver driver,
-      AvaticaFactory factory,
-      String url,
-      Properties info) {
-    this.id = UUID.randomUUID().toString();
-    this.handle = new Meta.ConnectionHandle(this.id);
-    this.driver = driver;
-    this.factory = factory;
-    this.url = url;
-    this.info = info;
-    this.meta = driver.createMeta(this);
-    this.metaData = factory.newDatabaseMetaData(this);
-    this.holdability = metaData.getResultSetHoldability();
-    this.maxRetriesPerExecute = getNumStatementRetries(info);
-  }
-
-  /** Computes the number of retries
-   * {@link AvaticaStatement#executeInternal(Meta.Signature, boolean)}
-   * should retry before failing. */
-  long getNumStatementRetries(Properties props) {
-    return Long.valueOf(Objects.requireNonNull(props)
-        .getProperty(NUM_EXECUTE_RETRIES_KEY, NUM_EXECUTE_RETRIES_DEFAULT));
-  }
-
-  /** Returns a view onto this connection's configuration properties. Code
-   * in Avatica and derived projects should use this view rather than calling
-   * {@link java.util.Properties#getProperty(String)}. Derived projects will
-   * almost certainly subclass {@link ConnectionConfig} with their own
-   * properties. */
-  public ConnectionConfig config() {
-    return new ConnectionConfigImpl(info);
-  }
-
-  /**
-   * Opens the connection on the server.
-   */
-  public void openConnection() {
-    // Open the connection on the server
-    this.meta.openConnection(handle, OpenConnectionRequest.serializeProperties(info));
-  }
-
-  // Connection methods
-
-  public AvaticaStatement createStatement() throws SQLException {
-    //noinspection MagicConstant
-    return createStatement(ResultSet.TYPE_FORWARD_ONLY,
-        ResultSet.CONCUR_READ_ONLY,
-        holdability);
-  }
-
-  public PreparedStatement prepareStatement(String sql) throws SQLException {
-    //noinspection MagicConstant
-    return prepareStatement(
-        sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
-        holdability);
-  }
-
-  public CallableStatement prepareCall(String sql) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public String nativeSQL(String sql) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setAutoCommit(boolean autoCommit) throws SQLException {
-    meta.connectionSync(handle, new ConnectionPropertiesImpl().setAutoCommit(autoCommit));
-  }
-
-  public boolean getAutoCommit() throws SQLException {
-    return unbox(sync().isAutoCommit(), true);
-  }
-
-  public void commit() throws SQLException {
-    meta.commit(handle);
-  }
-
-  public void rollback() throws SQLException {
-    meta.rollback(handle);
-  }
-
-  public void close() throws SQLException {
-    if (!closed) {
-      closed = true;
-
-      // Per specification, if onConnectionClose throws, this method will throw
-      // a SQLException, but statement will still be closed.
-      try {
-        meta.closeConnection(handle);
-        driver.handler.onConnectionClose(this);
-      } catch (RuntimeException e) {
-        throw helper.createException("While closing connection", e);
-      }
-    }
-  }
-
-  public boolean isClosed() throws SQLException {
-    return closed;
-  }
-
-  public DatabaseMetaData getMetaData() throws SQLException {
-    return metaData;
-  }
-
-  public void setReadOnly(boolean readOnly) throws SQLException {
-    meta.connectionSync(handle, new ConnectionPropertiesImpl().setReadOnly(readOnly));
-  }
-
-  public boolean isReadOnly() throws SQLException {
-    return unbox(sync().isReadOnly(), true);
-  }
-
-  public void setCatalog(String catalog) throws SQLException {
-    meta.connectionSync(handle, new ConnectionPropertiesImpl().setCatalog(catalog));
-  }
-
-  public String getCatalog() {
-    return sync().getCatalog();
-  }
-
-  public void setTransactionIsolation(int level) throws SQLException {
-    meta.connectionSync(handle, new ConnectionPropertiesImpl().setTransactionIsolation(level));
-  }
-
-  public int getTransactionIsolation() throws SQLException {
-    //noinspection MagicConstant
-    return unbox(sync().getTransactionIsolation(), TRANSACTION_NONE);
-  }
-
-  public SQLWarning getWarnings() throws SQLException {
-    return null;
-  }
-
-  public void clearWarnings() throws SQLException {
-    // no-op since connection pooling often calls this.
-  }
-
-  public Statement createStatement(
-      int resultSetType, int resultSetConcurrency) throws SQLException {
-    //noinspection MagicConstant
-    return createStatement(resultSetType, resultSetConcurrency, holdability);
-  }
-
-  public PreparedStatement prepareStatement(
-      String sql,
-      int resultSetType,
-      int resultSetConcurrency) throws SQLException {
-    //noinspection MagicConstant
-    return prepareStatement(
-        sql, resultSetType, resultSetConcurrency, holdability);
-  }
-
-  public CallableStatement prepareCall(
-      String sql,
-      int resultSetType,
-      int resultSetConcurrency) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Map<String, Class<?>> getTypeMap() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setHoldability(int holdability) throws SQLException {
-    if (!(holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT
-        || holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
-      throw new SQLException("invalid value");
-    }
-    this.holdability = holdability;
-  }
-
-  public int getHoldability() throws SQLException {
-    return holdability;
-  }
-
-  public Savepoint setSavepoint() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Savepoint setSavepoint(String name) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void rollback(Savepoint savepoint) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public AvaticaStatement createStatement(
-      int resultSetType,
-      int resultSetConcurrency,
-      int resultSetHoldability) throws SQLException {
-    return factory.newStatement(this, null, resultSetType, resultSetConcurrency,
-        resultSetHoldability);
-  }
-
-  public PreparedStatement prepareStatement(
-      String sql,
-      int resultSetType,
-      int resultSetConcurrency,
-      int resultSetHoldability) throws SQLException {
-    try {
-      final Meta.StatementHandle h = meta.prepare(handle, sql, -1);
-      return factory.newPreparedStatement(this, h, h.signature, resultSetType,
-          resultSetConcurrency, resultSetHoldability);
-    } catch (RuntimeException e) {
-      throw helper.createException("while preparing SQL: " + sql, e);
-    }
-  }
-
-  public CallableStatement prepareCall(
-      String sql,
-      int resultSetType,
-      int resultSetConcurrency,
-      int resultSetHoldability) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public PreparedStatement prepareStatement(
-      String sql, int autoGeneratedKeys) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public PreparedStatement prepareStatement(
-      String sql, int[] columnIndexes) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public PreparedStatement prepareStatement(
-      String sql, String[] columnNames) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Clob createClob() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Blob createBlob() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public NClob createNClob() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public SQLXML createSQLXML() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public boolean isValid(int timeout) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setClientInfo(String name, String value)
-      throws SQLClientInfoException {
-    throw helper.clientInfo();
-  }
-
-  public void setClientInfo(Properties properties)
-      throws SQLClientInfoException {
-    throw helper.clientInfo();
-  }
-
-  public String getClientInfo(String name) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Properties getClientInfo() throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Array createArrayOf(String typeName, Object[] elements)
-      throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public Struct createStruct(String typeName, Object[] attributes)
-      throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setSchema(String schema) throws SQLException {
-    meta.connectionSync(handle, new ConnectionPropertiesImpl().setSchema(schema));
-  }
-
-  public String getSchema() {
-    return sync().getSchema();
-  }
-
-  public void abort(Executor executor) throws SQLException {
-    throw helper.unsupported();
-  }
-
-  public void setNetworkTimeout(
-      Executor executor, int milliseconds) throws SQLException {
-    this.networkTimeout = milliseconds;
-  }
-
-  public int getNetworkTimeout() throws SQLException {
-    return networkTimeout;
-  }
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    if (iface.isInstance(this)) {
-      return iface.cast(this);
-    }
-    throw helper.createException(
-        "does not implement '" + iface + "'");
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return iface.isInstance(this);
-  }
-
-  /** Returns the time zone of this connection. Determines the offset applied
-   * when converting datetime values from the database into
-   * {@link java.sql.Timestamp} values. */
-  public TimeZone getTimeZone() {
-    final String timeZoneName = config().timeZone();
-    return timeZoneName == null
-        ? TimeZone.getDefault()
-        : TimeZone.getTimeZone(timeZoneName);
-  }
-
-  /**
-   * Executes a prepared query, closing any previously open result set.
-   *
-   * @param statement     Statement
-   * @param signature     Prepared query
-   * @param firstFrame    First frame of rows, or null if we need to execute
-   * @param state         The state used to create the given result
-   * @param isUpdate      Was the caller context via {@link PreparedStatement#executeUpdate()}.
-   * @return Result set
-   * @throws java.sql.SQLException if a database error occurs
-   */
-  protected ResultSet executeQueryInternal(AvaticaStatement statement,
-      Meta.Signature signature, Meta.Frame firstFrame, QueryState state, boolean isUpdate)
-      throws SQLException {
-    // Close the previous open result set, if there is one.
-    Meta.Frame frame = firstFrame;
-    Meta.Signature signature2 = signature;
-
-    synchronized (statement) {
-      if (statement.openResultSet != null) {
-        final AvaticaResultSet rs = statement.openResultSet;
-        statement.openResultSet = null;
-        try {
-          rs.close();
-        } catch (Exception e) {
-          throw helper.createException(
-              "Error while closing previous result set", e);
-        }
-      }
-
-      try {
-        if (statement.isWrapperFor(AvaticaPreparedStatement.class)) {
-          final AvaticaPreparedStatement pstmt = (AvaticaPreparedStatement) statement;
-          Meta.StatementHandle handle = pstmt.handle;
-          if (isUpdate) {
-            // Make a copy of the StatementHandle, nulling out the Signature.
-            // CALCITE-1086 we don't need to send the Signature to the server
-            // when we're only performing an update. Saves on serialization.
-            handle = new Meta.StatementHandle(handle.connectionId, handle.id, null);
-          }
-          final Meta.ExecuteResult executeResult =
-              meta.execute(handle, pstmt.getParameterValues(),
-                  statement.getFetchSize());
-          final MetaResultSet metaResultSet = executeResult.resultSets.get(0);
-          frame = metaResultSet.firstFrame;
-          statement.updateCount = metaResultSet.updateCount;
-          signature2 = executeResult.resultSets.get(0).signature;
-        }
-      } catch (Exception e) {
-        e.printStackTrace();
-        throw helper.createException(e.getMessage(), e);
-      }
-
-      final TimeZone timeZone = getTimeZone();
-      if (frame == null && signature2 == null && statement.updateCount != -1) {
-        statement.openResultSet = null;
-      } else {
-        // Duplicative SQL, for support non-prepared statements
-        statement.openResultSet =
-            factory.newResultSet(statement, state, signature2, timeZone, frame);
-      }
-    }
-    // Release the monitor before executing, to give another thread the
-    // opportunity to call cancel.
-    try {
-      if (statement.openResultSet != null) {
-        statement.openResultSet.execute();
-        isUpdateCapable(statement);
-      }
-    } catch (Exception e) {
-      throw helper.createException(
-          "exception while executing query: " + e.getMessage(), e);
-    }
-    return statement.openResultSet;
-  }
-
-  /** Returns whether a a statement is capable of updates and if so,
-   * and the statement's {@code updateCount} is still -1, proceeds to
-   * get updateCount value from statement's resultSet.
-   *
-   * <p>Handles "ROWCOUNT" object as Number or List
-   *
-   * @param statement Statement
-   * @throws SQLException on error
-   */
-  private void isUpdateCapable(final AvaticaStatement statement)
-      throws SQLException {
-    Meta.Signature signature = statement.getSignature();
-    if (signature == null || signature.statementType == null) {
-      return;
-    }
-    if (signature.statementType.canUpdate() && statement.updateCount == -1) {
-      statement.openResultSet.next();
-      Object obj = statement.openResultSet.getObject(ROWCOUNT_COLUMN_NAME);
-      if (obj instanceof Number) {
-        statement.updateCount = ((Number) obj).intValue();
-      } else if (obj instanceof List) {
-        @SuppressWarnings("unchecked")
-        final List<Number> numbers = (List<Number>) obj;
-        statement.updateCount = numbers.get(0).intValue();
-      } else {
-        throw helper.createException("Not a valid return result.");
-      }
-      statement.openResultSet = null;
-    }
-  }
-
-  protected Meta.ExecuteResult prepareAndExecuteInternal(
-      final AvaticaStatement statement, final String sql, long maxRowCount)
-      throws SQLException, NoSuchStatementException {
-    final Meta.PrepareCallback callback =
-        new Meta.PrepareCallback() {
-          public Object getMonitor() {
-            return statement;
-          }
-
-          public void clear() throws SQLException {
-            if (statement.openResultSet != null) {
-              final AvaticaResultSet rs = statement.openResultSet;
-              statement.openResultSet = null;
-              try {
-                rs.close();
-              } catch (Exception e) {
-                throw helper.createException(
-                    "Error while closing previous result set", e);
-              }
-            }
-          }
-
-          public void assign(Meta.Signature signature, Meta.Frame firstFrame,
-              long updateCount) throws SQLException {
-            statement.setSignature(signature);
-
-            if (updateCount != -1) {
-              statement.updateCount = updateCount;
-            } else {
-              final TimeZone timeZone = getTimeZone();
-              statement.openResultSet = factory.newResultSet(statement, new QueryState(sql),
-                  signature, timeZone, firstFrame);
-            }
-          }
-
-          public void execute() throws SQLException {
-            if (statement.openResultSet != null) {
-              statement.openResultSet.execute();
-              isUpdateCapable(statement);
-            }
-          }
-        };
-    return meta.prepareAndExecute(statement.handle, sql, maxRowCount, callback);
-  }
-
-  protected ResultSet createResultSet(Meta.MetaResultSet metaResultSet, QueryState state)
-      throws SQLException {
-    final Meta.StatementHandle h = new Meta.StatementHandle(
-        metaResultSet.connectionId, metaResultSet.statementId, null);
-    final AvaticaStatement statement = lookupStatement(h);
-    // These are all the metadata operations, no updates
-    ResultSet resultSet = executeQueryInternal(statement, metaResultSet.signature.sanitize(),
-        metaResultSet.firstFrame, state, false);
-    if (metaResultSet.ownStatement) {
-      resultSet.getStatement().closeOnCompletion();
-    }
-    return resultSet;
-  }
-
-  /** Creates a statement wrapper around an existing handle. */
-  protected AvaticaStatement lookupStatement(Meta.StatementHandle h)
-      throws SQLException {
-    final AvaticaStatement statement = statementMap.get(h.id);
-    if (statement != null) {
-      return statement;
-    }
-    //noinspection MagicConstant
-    return factory.newStatement(this, Objects.requireNonNull(h),
-        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, holdability);
-  }
-
-  // do not make public
-  protected static Trojan createTrojan() {
-    return new Trojan();
-  }
-
-  /** Converts a {@link Boolean} to a {@code boolean}, with a default value. */
-  private boolean unbox(Boolean b, boolean defaultValue) {
-    return b == null ? defaultValue : b;
-  }
-
-  /** Converts an {@link Integer} to an {@code int}, with a default value. */
-  private int unbox(Integer i, int defaultValue) {
-    return i == null ? defaultValue : i;
-  }
-
-  private Meta.ConnectionProperties sync() {
-    return meta.connectionSync(handle, new ConnectionPropertiesImpl());
-  }
-
-  /** A way to call package-protected methods. But only a sub-class of
-   * connection can create one. */
-  public static class Trojan {
-    // must be private
-    private Trojan() {
-    }
-
-    /** A means for anyone who has a trojan to call the protected method
-     * {@link org.apache.calcite.avatica.AvaticaResultSet#execute()}.
-     * @throws SQLException if execute fails for some reason. */
-    public ResultSet execute(AvaticaResultSet resultSet) throws SQLException {
-      return resultSet.execute();
-    }
-
-    /** A means for anyone who has a trojan to call the protected method
-     * {@link org.apache.calcite.avatica.AvaticaStatement#getParameterValues()}.
-     */
-    public List<TypedValue> getParameterValues(AvaticaStatement statement) {
-      return statement.getParameterValues();
-    }
-
-    /** A means for anyone who has a trojan to get the protected field
-     * {@link org.apache.calcite.avatica.AvaticaConnection#meta}. */
-    public Meta getMeta(AvaticaConnection connection) {
-      return connection.meta;
-    }
-  }
-
-  /**
-   * A Callable-like interface but without a "throws Exception".
-   *
-   * @param <T> The return type from {@code call}.
-   */
-  public interface CallableWithoutException<T> {
-    T call();
-  }
-
-  /**
-   * Invokes the given "callable", retrying the call when the server responds with an error
-   * denoting that the connection is missing on the server.
-   *
-   * @param callable The function to invoke.
-   * @return The value from the result of the callable.
-   */
-  public <T> T invokeWithRetries(CallableWithoutException<T> callable) {
-    RuntimeException lastException = null;
-    for (int i = 0; i < maxRetriesPerExecute; i++) {
-      try {
-        return callable.call();
-      } catch (AvaticaClientRuntimeException e) {
-        lastException = e;
-        if (ErrorResponse.MISSING_CONNECTION_ERROR_CODE == e.getErrorCode()) {
-          this.openConnection();
-          continue;
-        }
-        throw e;
-      }
-    }
-    if (null != lastException) {
-      throw lastException;
-    } else {
-      // Shouldn't ever happen.
-      throw new IllegalStateException();
-    }
-  }
-}
-
-// End AvaticaConnection.java


[54/59] calcite git commit: [CALCITE-1079] Split out an Avatica website, made to slot into the Calcite site at /avatica

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/protobuf_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/protobuf_reference.md b/avatica/site/_docs/protobuf_reference.md
new file mode 100644
index 0000000..4840ceb
--- /dev/null
+++ b/avatica/site/_docs/protobuf_reference.md
@@ -0,0 +1,1181 @@
+---
+layout: docs
+title: Protocol Buffers Reference
+sidebar_title: Protobuf Reference
+permalink: /docs/protobuf_reference.html
+requests:
+  - { name: "CatalogsRequest" }
+  - { name: "CloseConnectionRequest" }
+  - { name: "CloseStatementRequest" }
+  - { name: "ColumnsRequest" }
+  - { name: "CommitRequest" }
+  - { name: "ConnectionSyncRequest" }
+  - { name: "CreateStatementRequest" }
+  - { name: "DatabasePropertyRequest" }
+  - { name: "ExecuteRequest" }
+  - { name: "FetchRequest" }
+  - { name: "OpenConnectionRequest" }
+  - { name: "PrepareAndExecuteRequest" }
+  - { name: "PrepareRequest" }
+  - { name: "RollbackRequest" }
+  - { name: "SchemasRequest" }
+  - { name: "SyncResultsRequest" }
+  - { name: "TableTypesRequest" }
+  - { name: "TablesRequest" }
+  - { name: "TypeInfoRequest" }
+miscellaneous:
+  - { name: "AvaticaParameter" }
+  - { name: "AvaticaSeverity" }
+  - { name: "AvaticaType" }
+  - { name: "ColumnMetaData" }
+  - { name: "ColumnValue" }
+  - { name: "ConnectionProperties" }
+  - { name: "CursorFactory" }
+  - { name: "DatabaseProperty" }
+  - { name: "Frame" }
+  - { name: "QueryState" }
+  - { name: "Rep" }
+  - { name: "Row" }
+  - { name: "RpcMetadata" }
+  - { name: "Signature" }
+  - { name: "StateType" }
+  - { name: "StatementHandle" }
+  - { name: "StatementType" }
+  - { name: "Style" }
+  - { name: "TypedValue" }
+  - { name: "WireMessage" }
+responses:
+  - { name: "CloseConnectionResponse" }
+  - { name: "CloseStatementResponse" }
+  - { name: "CommitResponse" }
+  - { name: "ConnectionSyncResponse" }
+  - { name: "CreateStatementResponse" }
+  - { name: "DatabasePropertyResponse" }
+  - { name: "ErrorResponse" }
+  - { name: "ExecuteResponse" }
+  - { name: "FetchResponse" }
+  - { name: "OpenConnectionResponse" }
+  - { name: "PrepareResponse" }
+  - { name: "ResultSetResponse" }
+  - { name: "RollbackResponse" }
+  - { name: "SyncResultsResponse" }
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Avatica also supports [Protocol Buffers](https://developers.google.com/protocol-buffers/)
+as a message format since version 1.5.0. The Protocol Buffer, or protobuf for
+short, implementation is extremely similar to the JSON implementation. Some
+differences include protobuf's expanded type support (such as native byte arrays)
+and inability to differentiate between the default value for a field and the
+absence of a value for a field.
+
+Other notable structural differences to JSON include the addition of a
+`WireMessage` message which is used to identify the type of the wrapped message
+returned by the server (synonymous with `request` or `response` attribute on the
+JSON messages) and a change to `TypedValue` containing an `Object` value to
+a collection of optional strongly-typed values (as protobuf does not natively
+support an `Object` type that is unwrapped at runtime).
+
+Unless otherwise specified with use of the `required` modifier, all fields in
+all protocol buffer messages are `optional` by default.
+
+## Index
+
+### Requests
+<ul>
+  {% for item in page.requests %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Responses
+<ul>
+  {% for item in page.responses %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+### Miscellaneous
+<ul>
+  {% for item in page.miscellaneous %}<li><a href="#{{ item.name | downcase }}">{{ item.name }}</a></li>{% endfor %}
+</ul>
+
+
+## Requests
+
+The collection of all protobuf objects accepted as requests to Avatica. All request
+objects should be wrapped in a `WireMessage` before being sent to Avatica.
+
+### CatalogsRequest
+
+This request is used to fetch the available catalog names in the database.
+
+{% highlight protobuf %}
+message CatalogsRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+### CloseConnectionRequest
+
+This request is used to close the Connection object in the Avatica server identified by the given IDs.
+
+{% highlight protobuf %}
+message CloseConnectionRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to close.
+
+### CloseStatementRequest
+
+This request is used to close the Statement object in the Avatica server identified by the given IDs.
+
+{% highlight protobuf %}
+message CloseStatementRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to which the statement belongs.
+
+`statement_id` The identifier of the statement to close.
+
+### ColumnsRequest
+
+This request is used to fetch columns in the database given some optional filtering criteria.
+
+{% highlight protobuf %}
+message ColumnsRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  string column_name_pattern = 4;
+  string connection_id = 5;
+}
+{% endhighlight %}
+
+`catalog` The name of a catalog to limit returned columns.
+
+`schema_pattern` A Java Pattern against schemas to limit returned columns.
+
+`table_name_pattern` A Java Pattern against table names to limit returned columns.
+
+`column_name_pattern` A Java Pattern against column names to limit returned columns.
+
+`connection_id` The identifier of the connection which to use to fetch the columns.
+
+### CommitRequest
+
+This request is used to issue a `commit` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight protobuf %}
+message CommitRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection on which to invoke commit.
+
+### ConnectionSyncRequest
+
+This request is used to ensure that the client and server have a consistent view of the database properties.
+
+{% highlight protobuf %}
+message ConnectionSyncRequest {
+  string connection_id = 1;
+  ConnectionProperties conn_props = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to synchronize.
+
+`conn_props` A <a href="#connectionproperties">ConnectionProperties</a> object to synchronize between the client and server.
+
+### CreateStatementRequest
+
+This request is used to create a new Statement in the Avatica server.
+
+{% highlight protobuf %}
+message CreateStatementRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use in creating a statement.
+
+### DatabasePropertyRequest
+
+This request is used to fetch all <a href="#databaseproperty">database properties</a>.
+
+{% highlight protobuf %}
+message DatabasePropertyRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use when fetching the database properties.
+
+### ExecuteRequest
+
+This request is used to execute a PreparedStatement, optionally with values to bind to the parameters in the Statement.
+
+{% highlight protobuf %}
+message ExecuteRequest {
+  StatementHandle statementHandle = 1;
+  repeated TypedValue parameter_values = 2;
+  uint64 max_row_count = 3;
+  bool has_parameter_values = 4;
+}
+{% endhighlight %}
+
+`statementHandle` A <a href="#statementhandle">StatementHandle</a> object.
+
+`parameter_values` The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
+
+`max_row_count` The maximum number of rows returned in the response.
+
+`has_parameter_values` A boolean which denotes if the user set a value for the `parameter_values` field.
+
+### FetchRequest
+
+This request is used to fetch a batch of rows from a Statement previously created.
+
+{% highlight protobuf %}
+message FetchRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  uint64 offset = 3;
+  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to use.
+
+`statement_id` The identifier of the statement created using the above connection.
+
+`offset` The positional offset into a result set to fetch.
+
+`fetch_match_row_count` The maximum number of rows to return in the response to this request.
+
+### OpenConnectionRequest
+
+This request is used to open a new Connection in the Avatica server.
+
+{% highlight protobuf %}
+message OpenConnectionRequest {
+  string connection_id = 1;
+  map<string, string> info = 2;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to open in the server.
+
+`info` A Map containing properties to include when creating the Connection.
+
+### PrepareAndExecuteRequest
+
+This request is used as a short-hand for create a Statement and fetching the first batch of results in a single call without any parameter substitution.
+
+{% highlight protobuf %}
+message PrepareAndExecuteRequest {
+  string connection_id = 1;
+  uint32 statement_id = 4;
+  string sql = 2;
+  uint64 max_row_count = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`statement_id` The identifier for the statement created by the above connection to use.
+
+`sql` A SQL statement
+
+`max_row_count` The maximum number of rows returned in the response.
+
+### PrepareRequest
+
+This request is used to create create a new Statement with the given query in the Avatica server.
+
+{% highlight protobuf %}
+message PrepareRequest {
+  string connection_id = 1;
+  string sql = 2;
+  uint64 max_row_count = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`sql` A SQL statement
+
+`max_row_count` The maximum number of rows returned in the response.
+
+### SyncResultsRequest
+
+This request is used to reset a ResultSet's iterator to a specific offset in the Avatica server.
+
+{% highlight protobuf %}
+message SyncResultsRequest {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  QueryState state = 3;
+  uint64 offset = 4;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection to use.
+
+`statement_id` The identifier for the statement to use.
+
+`state` The <a href="#querystate">QueryState</a> object.
+
+`offset` The offset into the ResultSet to seek to.
+
+### RollbackRequest
+
+This request is used to issue a `rollback` on the Connection in the Avatica server identified by the given ID.
+
+{% highlight protobuf %}
+message RollbackRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection on which to invoke rollback.
+
+### SchemasRequest
+
+This request is used to fetch the schemas matching the provided criteria in the database.
+
+{% highlight protobuf %}
+message SchemasRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string connection_id = 3;
+}
+{% endhighlight %}
+
+`catalog` The name of the catalog to fetch the schema from.
+
+`schema_pattern` A Java pattern of schemas to fetch.
+
+`connection_id` The identifier for the connection to fetch schemas from.
+
+### TableTypesRequest
+
+This request is used to fetch the table types available in this database.
+
+{% highlight protobuf %}
+message TableTypesRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to fetch the table types from.
+
+### TablesRequest
+
+This request is used to fetch the tables available in this database filtered by the provided criteria.
+
+{% highlight protobuf %}
+message TablesRequest {
+  string catalog = 1;
+  string schema_pattern = 2;
+  string table_name_pattern = 3;
+  repeated string type_list = 4;
+  bool has_type_list = 6;
+  string connection_id = 7;
+}
+{% endhighlight %}
+
+`catalog` The name of a catalog to restrict fetched tables.
+
+`schema_pattern` A Java Pattern representing schemas to include in fetched tables.
+
+`table_name_pattern` A Java Pattern representing table names to include in fetched tables.
+
+`type_list` A list of table types used to restrict fetched tables.
+
+`has_type_list` A boolean which denotes if the field `type_list` was provided.
+
+`connection_id` The identifier of the connection to fetch the tables from.
+
+### TypeInfoRequest
+
+This request is used to fetch the types available in this database.
+
+{% highlight protobuf %}
+message TypeInfoRequest {
+  string connection_id = 1;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to fetch the types from.
+
+## Responses
+
+The collection of all protobuf objects accepted as requests to Avatica. All response
+objects will be wrapped in a `WireMessage` before being returned from Avatica.
+
+### CloseConnectionResponse
+
+A response to the <a href="#closeconnectionrequest">CloseConnectionRequest</a>.
+
+{% highlight protobuf %}
+message CloseConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CloseStatementResponse
+
+A response to the <a href="#closestatementrequest">CloseStatementRequest</a>.
+
+{% highlight protobuf %}
+message CloseStatementResponse {
+  RpcMetadata metadata = 1;
+}
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CommitResponse
+
+A response to the <a href="#commitrequest">CommitRequest</a>.
+
+{% highlight protobuf %}
+message CommitResponse {
+
+}
+{% endhighlight %}
+
+There are no attributes on this Response.
+
+### ConnectionSyncResponse
+
+A response to the <a href="#connectionsyncrequest">ConnectionSyncRequest</a>. Properties included in the
+response are those of the Connection in the Avatica server.
+
+{% highlight protobuf %}
+message ConnectionSyncResponse {
+  ConnectionProperties conn_props = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`conn_props` The <a href="#connectionproperties">ConnectionProperties</a> that were synchronized.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### CreateStatementResponse
+
+A response to the <a href="#createstatementrequest">CreateStatementRequest</a>. The ID of the statement
+that was created is included in the response. Clients will use this `statement_id` in subsequent calls.
+
+{% highlight protobuf %}
+message CreateStatementResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection used to create the statement.
+
+`statement_id` The identifier for the created statement.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### DatabasePropertyResponse
+
+A response to the <a href="#databasepropertyrequest">DatabasePropertyRequest</a>. See <a hred="#databaseproperty">DatabaseProperty</a>
+for information on the available property keys.
+
+{% highlight protobuf %}
+message DatabasePropertyResponse {
+  repeated DatabasePropertyElement props = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`props` A collection of <a href="#databaseproperty">DatabaseProperty</a>'s.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ErrorResponse
+
+A response when an error was caught executing a request. Any request may return this response.
+
+{% highlight protobuf %}
+message ErrorResponse {
+  repeated string exceptions = 1;
+  bool has_exceptions = 7;
+  string error_message = 2;
+  Severity severity = 3;
+  uint32 error_code = 4;
+  string sql_state = 5;
+  RpcMetadata metadata = 6;
+}
+{% endhighlight %}
+
+`exceptions` A list of stringified Java StackTraces.
+
+`has_exceptions` A boolean which denotes the presence of `exceptions`.
+
+`error_message` A human-readable error message.
+
+`error_code` A numeric code for this error.
+
+`sql_state` A five character alphanumeric code for this error.
+
+`severity` An <a href="#avaticaseverity">AvaticaSeverity</a> object which denotes how critical the error is.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ExecuteResponse
+
+A response to the <a href="#executerequest">ExecuteRequest</a> which contains the results for a metadata query.
+
+{% highlight protobuf %}
+message ExecuteResponse {
+  repeated ResultSetResponse results = 1;
+  bool missing_statement = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`results` An array of <a href="#resultsetresponse">ResultSetResponse</a>s.
+
+`missing_statement` A boolean which denotes if the request failed due to a missing statement.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### FetchResponse
+
+A response to the <a href="#fetchrequest">FetchRequest</a> which contains the request for the query.
+
+{% highlight protobuf %}
+message FetchResponse {
+  Frame frame = 1;
+  bool missing_statement = 2;
+  bool missing_results = 3;
+  RpcMetadata metadata = 4;
+}
+{% endhighlight %}
+
+`frame` A <a href="#frame">Frame</a> containing the results of the fetch.
+
+`missing_statement` A boolean which denotes if the request failed due to a missing Statement.
+
+`missing_results` A boolean which denotes if the request failed due to a missing ResultSet.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### OpenConnectionResponse
+
+A response to the <a href="#openconnectionrequest">OpenConnectionRequest</a>. The ID for the connection that
+the client should use in subsequent calls was provided by the client in the request.
+
+{% highlight protobuf %}
+message OpenConnectionResponse {
+  RpcMetadata metadata = 1;
+}
+
+{% endhighlight %}
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### PrepareResponse
+
+A response to the <a href="#preparerequest">PrepareRequest</a>. This response includes a <a href="#statementhandle">StatementHandle</a>
+which clients must use to fetch the results from the Statement.
+
+{% highlight protobuf %}
+message PrepareResponse {
+  StatementHandle statement = 1;
+  RpcMetadata metadata = 2;
+}
+{% endhighlight %}
+
+`statement` A <a href="#statementhandle">StatementHandle</a> object.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### ResultSetResponse
+
+A response which contains the results and type details from a query.
+
+{% highlight protobuf %}
+message ResultSetResponse {
+  string connection_id = 1;
+  uint32 statement_id = 2;
+  bool own_statement = 3;
+  Signature signature = 4;
+  Frame first_frame = 5;
+  uint64 update_count = 6;
+  RpcMetadata metadata = 7;
+}
+{% endhighlight %}
+
+`connection_id` The identifier for the connection used to generate this response.
+
+`statement_id` The identifier for the statement used to generate this response.
+
+`own_statement` Whether the result set has its own dedicated statement. If true, the server must automatically close the
+statement when the result set is closed. This is used for JDBC metadata result sets, for instance.
+
+`signature` A non-optional nested object <a href="#signature">Signature</a>
+
+`first_frame` A optional nested object <a href="#frame">Frame</a>
+
+`update_count` A number which is always `-1` for normal result sets. Any other value denotes a "dummy" result set
+that only contains this count and no additional data.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+### RollbackResponse
+
+A response to the <a href="#rollbackrequest">RollBackRequest</a>.
+
+{% highlight protobuf %}
+message RollbackResponse {
+
+}
+{% endhighlight %}
+
+There are no attributes on this Response.
+
+### SyncResultsResponse
+
+A response to the <a href="#syncresultsrequest">SyncResultsRequest</a>. When `moreResults` is true, a <a href="#fetchrequest">FetchRequest</a>
+should be issued to get the next batch of records. When `missingStatement` is true, the statement must be re-created using <a href="#preparerequest">PrepareRequest</a>
+or the appropriate Request for a DDL request (e.g. <a href="#catalogsrequest">CatalogsRequest</a> or <a href="#schemasrequest">SchemasRequest</a>).
+
+{% highlight protobuf %}
+message SyncResultsResponse {
+  bool missing_statement = 1;
+  bool more_results = 2;
+  RpcMetadata metadata = 3;
+}
+{% endhighlight %}
+
+`more_results` A boolean which denotes if results exist for the ResultSet being "synced" per the request.
+
+`missing_statement` A boolean which denotes if the statement for the ResultSet still exists.
+
+`metadata` <a href="#rpcmetadata">Server metadata</a> about this call.
+
+## Miscellaneous
+
+### AvaticaParameter
+
+This object describes the "simple", or scalar, JDBC type representation of a column in a result. This does not include
+complex types such as arrays.
+
+{% highlight protobuf %}
+message AvaticaParameter {
+  bool signed = 1;
+  uint32 precision = 2;
+  uint32 scale = 3;
+  uint32 parameter_type = 4;
+  string class_name = 5;
+  string class_name = 6;
+  string name = 7;
+}
+{% endhighlight %}
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`parameter_type` An integer corresponding to the JDBC Types class denoting the column's type.
+
+`type_name` The JDBC type name for this column.
+
+`class_name` The Java class backing the JDBC type for this column.
+
+`name` The name of the column.
+
+### AvaticaSeverity
+
+This enumeration describes the various levels of concern for an error in the Avatica server.
+
+{% highlight protobuf %}
+enum Severity {
+  UNKNOWN_SEVERITY = 0;
+  FATAL_SEVERITY = 1;
+  ERROR_SEVERITY = 2;
+  WARNING_SEVERITY = 3;
+}
+{% endhighlight %}
+
+### AvaticaType
+
+This object describes a simple or complex type for a column. Complex types will contain
+additional information in the `component` or `columns` attribute which describe the nested
+types of the complex parent type.
+
+{% highlight protobuf %}
+message AvaticaType {
+  uint32 id = 1;
+  string name = 2;
+  Rep rep = 3;
+  repeated ColumnMetaData columns = 4;
+  AvaticaType component = 5;
+}
+{% endhighlight %}
+
+`type` One of: `scalar`, `array`, `struct`.
+
+`id` A numeric value corresponding to the type of the object per the JDBC Types class.
+
+`name` The readable name of the JDBC type.
+
+`rep` A nested <a href="#rep">Rep</a> object used by Avatica to hold additional type information.
+
+`columns` For `STRUCT` types, a list of the columns contained in that `STRUCT`.
+
+`component` For `ARRAY` types, the type of the elements contained in that `ARRAY`.
+
+### ColumnMetaData
+
+This object represents the JDBC ResultSetMetaData for a column.
+
+{% highlight protobuf %}
+message ColumnMetaData {
+  uint32 ordinal = 1;
+  bool auto_increment = 2;
+  bool case_sensitive = 3;
+  bool searchable = 4;
+  bool currency = 5;
+  uint32 nullable = 6;
+  bool signed = 7;
+  uint32 display_size = 8;
+  string label = 9;
+  string column_name = 10;
+  string schema_name = 11;
+  uint32 precision = 12;
+  uint32 scale = 13;
+  string table_name = 14;
+  string catalog_name = 15;
+  bool read_only = 16;
+  bool writable = 17;
+  bool definitely_writable = 18;
+  string column_class_name = 19;
+  AvaticaType type = 20;
+}
+{% endhighlight %}
+
+`ordinal` A positional offset number.
+
+`auto_increment` A boolean denoting whether the column is automatically incremented.
+
+`case_sensitive` A boolean denoting whether the column is case sensitive.
+
+`searchable` A boolean denoting whether this column supports all WHERE search clauses.
+
+`currency` A boolean denoting whether this column represents currency.
+
+`nullable` A number denoting whether this column supports null values.
+
+* 0 = No null values are allowed
+* 1 = Null values are allowed
+* 2 = It is unknown if null values are allowed
+
+`signed` A boolean denoting whether the column is a signed numeric.
+
+`display_size` The character width of the column.
+
+`label` A description for this column.
+
+`column_name` The name of the column.
+
+`schema_name` The schema to which this column belongs.
+
+`precision` The maximum numeric precision supported by this column.
+
+`scale` The maximum numeric scale supported by this column.
+
+`table_name` The name of the table to which this column belongs.
+
+`catalog_name` The name of the catalog to which this column belongs.
+
+`type` A nested <a href="#avaticatype">AvaticaType</a> representing the type of the column.
+
+`read_only` A boolean denoting whether the column is read-only.
+
+`writable` A boolean denoting whether the column is possible to be updated.
+
+`definitely_writable` A boolean denoting whether the column definitely can be updated.
+
+`column_class_name` The name of the Java class backing the column's type.
+
+### ConnectionProperties
+
+This object represents the properties for a given JDBC Connection.
+
+{% highlight protobuf %}
+message ConnectionProperties {
+  bool is_dirty = 1;
+  bool auto_commit = 2;
+  bool has_auto_commit = 7;
+  bool read_only = 3;
+  bool has_read_only = 8;
+  uint32 transaction_isolation = 4;
+  string catalog = 5;
+  string schema = 6;
+}
+{% endhighlight %}
+
+`is_dirty` A boolean denoting if the properties have been altered.
+
+`auto_commit` A boolean denoting if autoCommit is enabled for transactions.
+
+`has_auto_commit` A boolean denoting if `auto_commit` was set.
+
+`read_only` A boolean denoting if a JDBC connection is read-only.
+
+`has_read_only` A boolean denoting if `read_only` was set.
+
+`transaction_isolation` An integer which denotes the level of transactions isolation per the JDBC
+specification. This value is analogous to the values defined in `java.sql.Connection`.
+
+* 0 = Transactions are not supported
+* 1 = Dirty reads, non-repeatable reads and phantom reads may occur.
+* 2 = Dirty reads are prevented, but non-repeatable reads and phantom reads may occur.
+* 4 = Dirty reads and non-repeatable reads are prevented, but phantom reads may occur.
+* 8 = Dirty reads, non-repeatable reads, and phantom reads are all prevented.
+
+`catalog` The name of a catalog to use when fetching connection properties.
+
+`schema` The name of the schema to use when fetching connection properties.
+
+### CursorFactory
+
+This object represents the information required to cast untyped objects into the necessary type for some results.
+
+{% highlight protobuf %}
+message CursorFactory {
+  enum Style {
+    OBJECT = 0;
+    RECORD = 1;
+    RECORD_PROJECTION = 2;
+    ARRAY = 3;
+    LIST = 4;
+    MAP = 5;
+  }
+
+  Style style = 1;
+  string class_name = 2;
+  repeated string field_names = 3;
+}
+{% endhighlight %}
+
+`style` A string denoting the <a href="#style">Style</a> of the contained objects.
+
+`class_name` The name of the for `RECORD` or `RECORD_PROJECTION`.
+
+### DatabaseProperty
+
+This object represents the exposed database properties for a Connection through the Avatica server.
+
+{% highlight protobuf %}
+message DatabaseProperty {
+  string name = 1;
+  repeated string functions = 2;
+}
+{% endhighlight %}
+
+`name` The name of the database property.
+
+`functions` A collection of values for the property.
+
+### Frame
+
+This object represents a batch of results, tracking the offset into the results and whether more results still exist
+to be fetched in the Avatica server.
+
+{% highlight protobuf %}
+message Frame {
+  uint64 offset = 1;
+  bool done = 2;
+  repeated Row rows = 3;
+}
+{% endhighlight %}
+
+`offset` The starting position of these `rows` in the encompassing result set.
+
+`done` A boolean denoting whether more results exist for this result set.
+
+`rows` A collection of <a href="#row">Row</a>s.
+
+### Row
+
+This object represents a row in a relational database table.
+
+{% highlight protobuf %}
+message Row {
+  repeated ColumnValue value = 1;
+}
+{% endhighlight %}
+
+`value` A collection of <a href="#columnvalue">ColumnValue</a>s, the columns in the row.
+
+### ColumnValue
+
+{% highlight protobuf %}
+message ColumnValue {
+  repeated TypedValue value = 1; // Deprecated!
+  repeated ColumnValue array_value = 2;
+  boolean has_array_value = 3;
+  TypedValue scalar_value = 4;
+}
+{% endhighlight %}
+
+`value` The pre Calcite-1.6 means of serializing <a href="#typedvalue">TypedValue</a>s. Not used anymore.
+
+`array_value` The value of this column if it is an array (not a scalar).
+
+`has_array_value` Should be set to true if `array_value` is set.
+
+`scalar_value` The value of this column if it is a scalar (not an array).
+
+### QueryState
+
+This object represents the way a ResultSet was created in the Avatica server. A ResultSet could be created by a user-provided
+SQL or by a DatabaseMetaData operation with arguments on that operation.
+
+{% highlight protobuf %}
+message QueryState {
+  StateType type = 1;
+  string sql = 2;
+  MetaDataOperation op = 3;
+  repeated MetaDataOperationArgument args = 4;
+  bool has_args = 5;
+  bool has_sql = 6;
+  bool has_op = 7;
+}
+{% endhighlight %}
+
+`type` A <a href="#statetype">StateType</a> object denoting what type of operation backs the ResultSet for this query.
+
+`sql` The SQL statement which created the ResultSet for this query. Required if the `type` is `SQL`.
+
+`op` The DML operation which created the ResultSet for this query. Required if the `type` is `METADATA`.
+
+`args` The arguments to the invoked DML operation. Required if the `type` is `METADATA`.
+
+`has_args` A boolean which denotes if the field `args` is provided.
+
+`has_sql` A boolean which denotes if the field `sql` is provided.
+
+`has_op` A boolean which denotes if the field `op` is provided.
+
+### Rep
+
+This enumeration represents the concrete Java type for some value.
+
+{% highlight protobuf %}
+enum Rep {
+  PRIMITIVE_BOOLEAN = 0;
+  PRIMITIVE_BYTE = 1;
+  PRIMITIVE_CHAR = 2;
+  PRIMITIVE_SHORT = 3;
+  PRIMITIVE_INT = 4;
+  PRIMITIVE_LONG = 5;
+  PRIMITIVE_FLOAT = 6;
+  PRIMITIVE_DOUBLE = 7;
+  BOOLEAN = 8;
+  BYTE = 9;
+  CHARACTER = 10;
+  SHORT = 11;
+  INTEGER = 12;
+  LONG = 13;
+  FLOAT = 14;
+  DOUBLE = 15;
+  BIG_INTEGER = 25;
+  BIG_DECIMAL = 26;
+  JAVA_SQL_TIME = 16;
+  JAVA_SQL_TIMESTAMP = 17;
+  JAVA_SQL_DATE = 18;
+  JAVA_UTIL_DATE = 19;
+  BYTE_STRING = 20;
+  STRING = 21;
+  NUMBER = 22;
+  OBJECT = 23;
+  NULL = 24;
+  ARRAY = 27;
+  STRUCT = 28;
+  MULTISET = 29;
+}
+{% endhighlight %}
+
+### RpcMetadata
+
+This object contains assorted per-call/contextual metadata returned by the Avatica server.
+
+{% highlight protobuf %}
+message RpcMetadata {
+  string server_address = 1;
+}
+{% endhighlight %}
+
+`serverAddress` The `host:port` of the server which created this object.
+
+### Signature
+
+This object represents the result of preparing a Statement in the Avatica server.
+
+{% highlight protobuf %}
+message Signature {
+  repeated ColumnMetaData columns = 1;
+  string sql = 2;
+  repeated AvaticaParameter parameters = 3;
+  CursorFactory cursor_factory = 4;
+  StatementType statementType = 5;
+}
+{% endhighlight %}
+
+`columns` An array of <a href="#columnmetadata">ColumnMetaData</a> objects denoting the schema of the result set.
+
+`sql` The SQL executed.
+
+`parameters` An array of <a href="#avaticaparameter">AvaticaParameter</a> objects denoting type-specific details.
+
+`cursor_factory` An <a href="#cursorfactory">CursorFactory</a> object representing the Java representation of the frame.
+
+`statementType` The type of the statement.
+
+### StateType
+
+This enumeration denotes whether user-provided SQL or a DatabaseMetaData operation was used to create some ResultSet.
+
+{% highlight protobuf %}
+enum StateType {
+  SQL = 0;
+  METADATA = 1;
+}
+{% endhighlight %}
+
+### StatementHandle
+
+This object encapsulates all of the information of a Statement created in the Avatica server.
+
+{% highlight protobuf %}
+message StatementHandle {
+  string connection_id = 1;
+  uint32 id = 2;
+  Signature signature = 3;
+}
+{% endhighlight %}
+
+`connection_id` The identifier of the connection to which this statement belongs.
+
+`id` The identifier of the statement.
+
+`signature` A <a href="#signature">Signature</a> object for the statement.
+
+### StatementType
+
+This message represents what kind the Statement is.
+
+{% highlight protobuf %}
+enum StatementType {
+  SELECT = 0;
+  INSERT = 1;
+  UPDATE = 2;
+  DELETE = 3;
+  UPSERT = 4;
+  MERGE = 5;
+  OTHER_DML = 6;
+  CREATE = 7;
+  DROP = 8;
+  ALTER = 9;
+  OTHER_DDL = 10;
+  CALL = 11;
+}
+{% endhighlight %}
+
+### Style
+
+This enumeration represents the generic "class" of type for a value. Defined within <a href="#cursorfactory">CursorFactory</a>.
+
+{% highlight protobuf %}
+enum Style {
+  OBJECT = 0;
+  RECORD = 1;
+  RECORD_PROJECTION = 2;
+  ARRAY = 3;
+  LIST = 4;
+  MAP = 5;
+}
+{% endhighlight %}
+
+### TypedValue
+
+This object encapsulates the type and value for a column in a row.
+
+{% highlight protobuf %}
+message TypedValue {
+  Rep type = 1;
+  bool bool_value = 2;
+  string string_value = 3;
+  sint64 number_value = 4;
+  bytes bytes_values = 5;
+  double double_value = 6;
+  bool null = 7;
+}
+{% endhighlight %}
+
+`type` A name referring to which attribute is populated with the column's value.
+
+`bool_value` A boolean value.
+
+`string_value` A character/string value.
+
+`number_value` A numeric value (non-`double`).
+
+`bytes_value` A byte-array value.
+
+`double_value` A `double` value.
+
+`null` A boolean which denotes if the value was null.
+
+### WireMessage
+
+This message wraps all `Request`s and `Response`s.
+
+{% highlight protobuf %}
+message WireMessage {
+  string name = 1;
+  bytes wrapped_message = 2;
+}
+{% endhighlight %}
+
+`name` The Java class name of the wrapped message.
+
+`wrapped_message` A serialized representation of the wrapped message of the same type specified by `name`.

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/reference.md b/avatica/site/_docs/reference.md
deleted file mode 100644
index 7bc9bc3..0000000
--- a/avatica/site/_docs/reference.md
+++ /dev/null
@@ -1,1248 +0,0 @@
----
-layout: docs
-title: SQL language
-permalink: /docs/reference.html
----
-<!--
-{% comment %}
-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.
-{% endcomment %}
--->
-
-The page describes the SQL dialect recognized by Calcite's default SQL parser.
-
-## Grammar
-
-SQL grammar in [BNF](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)-like
-form.
-
-{% highlight sql %}
-statement:
-      setStatement
-  |   resetStatement
-  |   explain
-  |   insert
-  |   update
-  |   merge
-  |   delete
-  |   query
-
-setStatement:
-      [ ALTER ( SYSTEM | SESSION ) ] SET identifier '=' expression
-
-resetStatement:
-      [ ALTER ( SYSTEM | SESSION ) ] RESET identifier
-  |   [ ALTER ( SYSTEM | SESSION ) ] RESET ALL
-
-explain:
-      EXPLAIN PLAN
-      [ WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION ]
-      [ EXCLUDING ATTRIBUTES | INCLUDING [ ALL ] ATTRIBUTES ]
-      FOR ( insert | update | merge | delete | query )
-
-insert:
-      ( INSERT | UPSERT ) INTO tablePrimary
-      [ '(' column [, column ]* ')' ]
-      query
-
-update:
-      UPDATE tablePrimary
-      SET assign [, assign ]*
-      [ WHERE booleanExpression ]
-
-assign:
-      identifier '=' expression
-
-merge:
-      MERGE INTO tablePrimary [ [ AS ] alias ]
-      USING tablePrimary
-      ON booleanExpression
-      [ WHEN MATCHED THEN UPDATE SET assign [, assign ]* ]
-      [ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
-
-delete:
-      DELETE FROM tablePrimary [ [ AS ] alias ]
-      [ WHERE booleanExpression ]
-
-query:
-      [ WITH withItem [ , withItem ]* query ]
-  |   {
-          select
-      |   query UNION [ ALL ] query
-      |   query EXCEPT query
-      |   query INTERSECT query
-      }
-      [ ORDER BY orderItem [, orderItem ]* ]
-      [ LIMIT { count | ALL } ]
-      [ OFFSET start { ROW | ROWS } ]
-      [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ]
-
-withItem:
-      name
-      [ '(' column [, column ]* ')' ]
-      AS '(' query ')'
-
-orderItem:
-      expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
-
-select:
-      SELECT [ STREAM ] [ ALL | DISTINCT ]
-          { * | projectItem [, projectItem ]* }
-      FROM tableExpression
-      [ WHERE booleanExpression ]
-      [ GROUP BY { groupItem [, groupItem ]* } ]
-      [ HAVING booleanExpression ]
-      [ WINDOW windowName AS windowSpec [, windowName AS windowSpec ]* ]
-
-projectItem:
-      expression [ [ AS ] columnAlias ]
-  |   tableAlias . *
-
-tableExpression:
-      tableReference [, tableReference ]*
-  |   tableExpression [ NATURAL ] [ LEFT | RIGHT | FULL ] JOIN tableExpression [ joinCondition ]
-
-joinCondition:
-      ON booleanExpression
-  |   USING '(' column [, column ]* ')'
-
-tableReference:
-      [ LATERAL ]
-      tablePrimary
-      [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
-
-tablePrimary:
-      [ TABLE ] [ [ catalogName . ] schemaName . ] tableName
-  |   '(' query ')'
-  |   values
-  |   UNNEST '(' expression ')' [ WITH ORDINALITY ]
-  |   TABLE '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
-
-values:
-      VALUES expression [, expression ]*
-
-groupItem:
-      expression
-  |   '(' ')'
-  |   '(' expression [, expression ]* ')'
-  |   CUBE '(' expression [, expression ]* ')'
-  |   ROLLUP '(' expression [, expression ]* ')'
-  |   GROUPING SETS '(' groupItem [, groupItem ]* ')'
-
-windowRef:
-      windowName
-  |   windowSpec
-
-windowSpec:
-      [ windowName ]
-      '('
-      [ ORDER BY orderItem [, orderItem ]* ]
-      [ PARTITION BY expression [, expression ]* ]
-      [
-          RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
-      |   ROWS numericExpression { PRECEDING | FOLLOWING }
-      ]
-      ')'
-{% endhighlight %}
-
-In *merge*, at least one of the WHEN MATCHED and WHEN NOT MATCHED clauses must
-be present.
-
-In *orderItem*, if *expression* is a positive integer *n*, it denotes
-the <em>n</em>th item in the SELECT clause.
-
-An aggregate query is a query that contains a GROUP BY or a HAVING
-clause, or aggregate functions in the SELECT clause. In the SELECT,
-HAVING and ORDER BY clauses of an aggregate query, all expressions
-must be constant within the current group (that is, grouping constants
-as defined by the GROUP BY clause, or constants), or aggregate
-functions, or a combination of constants and aggregate
-functions. Aggregate and grouping functions may only appear in an
-aggregate query, and only in a SELECT, HAVING or ORDER BY clause.
-
-A scalar sub-query is a sub-query used as an expression.
-If the sub-query returns no rows, the value is NULL; if it
-returns more than one row, it is an error.
-
-IN, EXISTS and scalar sub-queries can occur
-in any place where an expression can occur (such as the SELECT clause,
-WHERE clause, ON clause of a JOIN, or as an argument to an aggregate
-function).
-
-An IN, EXISTS or scalar sub-query may be correlated; that is, it
-may refer to tables in the FROM clause of an enclosing query.
-
-## Keywords
-
-The following is a list of SQL keywords.
-Reserved keywords are **bold**.
-
-{% comment %} start {% endcomment %}
-A,
-**ABS**,
-ABSOLUTE,
-ACTION,
-ADA,
-ADD,
-ADMIN,
-AFTER,
-**ALL**,
-**ALLOCATE**,
-**ALLOW**,
-**ALTER**,
-ALWAYS,
-**AND**,
-**ANY**,
-**ARE**,
-**ARRAY**,
-**AS**,
-ASC,
-**ASENSITIVE**,
-ASSERTION,
-ASSIGNMENT,
-**ASYMMETRIC**,
-**AT**,
-**ATOMIC**,
-ATTRIBUTE,
-ATTRIBUTES,
-**AUTHORIZATION**,
-**AVG**,
-BEFORE,
-**BEGIN**,
-BERNOULLI,
-**BETWEEN**,
-**BIGINT**,
-**BINARY**,
-**BIT**,
-**BLOB**,
-**BOOLEAN**,
-**BOTH**,
-BREADTH,
-**BY**,
-C,
-**CALL**,
-**CALLED**,
-**CARDINALITY**,
-CASCADE,
-**CASCADED**,
-**CASE**,
-**CAST**,
-CATALOG,
-CATALOG_NAME,
-**CEIL**,
-**CEILING**,
-CHAIN,
-**CHAR**,
-**CHARACTER**,
-CHARACTERISTICTS,
-CHARACTERS,
-**CHARACTER_LENGTH**,
-CHARACTER_SET_CATALOG,
-CHARACTER_SET_NAME,
-CHARACTER_SET_SCHEMA,
-**CHAR_LENGTH**,
-**CHECK**,
-CLASS_ORIGIN,
-**CLOB**,
-**CLOSE**,
-**COALESCE**,
-COBOL,
-**COLLATE**,
-COLLATION,
-COLLATION_CATALOG,
-COLLATION_NAME,
-COLLATION_SCHEMA,
-**COLLECT**,
-**COLUMN**,
-COLUMN_NAME,
-COMMAND_FUNCTION,
-COMMAND_FUNCTION_CODE,
-**COMMIT**,
-COMMITTED,
-**CONDITION**,
-CONDITION_NUMBER,
-**CONNECT**,
-CONNECTION,
-CONNECTION_NAME,
-**CONSTRAINT**,
-CONSTRAINTS,
-CONSTRAINT_CATALOG,
-CONSTRAINT_NAME,
-CONSTRAINT_SCHEMA,
-CONSTRUCTOR,
-CONTAINS,
-CONTINUE,
-**CONVERT**,
-**CORR**,
-**CORRESPONDING**,
-**COUNT**,
-**COVAR_POP**,
-**COVAR_SAMP**,
-**CREATE**,
-**CROSS**,
-**CUBE**,
-**CUME_DIST**,
-**CURRENT**,
-**CURRENT_CATALOG**,
-**CURRENT_DATE**,
-**CURRENT_DEFAULT_TRANSFORM_GROUP**,
-**CURRENT_PATH**,
-**CURRENT_ROLE**,
-**CURRENT_SCHEMA**,
-**CURRENT_TIME**,
-**CURRENT_TIMESTAMP**,
-**CURRENT_TRANSFORM_GROUP_FOR_TYPE**,
-**CURRENT_USER**,
-**CURSOR**,
-CURSOR_NAME,
-**CYCLE**,
-DATA,
-**DATE**,
-DATETIME_INTERVAL_CODE,
-DATETIME_INTERVAL_PRECISION,
-**DAY**,
-**DEALLOCATE**,
-**DEC**,
-**DECIMAL**,
-**DECLARE**,
-**DEFAULT**,
-DEFAULTS,
-DEFERRABLE,
-DEFERRED,
-DEFINED,
-DEFINER,
-DEGREE,
-**DELETE**,
-**DENSE_RANK**,
-DEPTH,
-**DEREF**,
-DERIVED,
-DESC,
-**DESCRIBE**,
-DESCRIPTION,
-DESCRIPTOR,
-**DETERMINISTIC**,
-DIAGNOSTICS,
-**DISALLOW**,
-**DISCONNECT**,
-DISPATCH,
-**DISTINCT**,
-DOMAIN,
-**DOUBLE**,
-**DROP**,
-**DYNAMIC**,
-DYNAMIC_FUNCTION,
-DYNAMIC_FUNCTION_CODE,
-**EACH**,
-**ELEMENT**,
-**ELSE**,
-**END**,
-**END-EXEC**,
-EQUALS,
-**ESCAPE**,
-**EVERY**,
-**EXCEPT**,
-EXCEPTION,
-EXCLUDE,
-EXCLUDING,
-**EXEC**,
-**EXECUTE**,
-**EXISTS**,
-**EXP**,
-**EXPLAIN**,
-**EXTEND**,
-**EXTERNAL**,
-**EXTRACT**,
-**FALSE**,
-**FETCH**,
-**FILTER**,
-FINAL,
-FIRST,
-**FIRST_VALUE**,
-**FLOAT**,
-**FLOOR**,
-FOLLOWING,
-**FOR**,
-**FOREIGN**,
-FORTRAN,
-FOUND,
-**FREE**,
-**FROM**,
-**FULL**,
-**FUNCTION**,
-**FUSION**,
-G,
-GENERAL,
-GENERATED,
-**GET**,
-**GLOBAL**,
-GO,
-GOTO,
-**GRANT**,
-GRANTED,
-**GROUP**,
-**GROUPING**,
-**HAVING**,
-HIERARCHY,
-**HOLD**,
-**HOUR**,
-**IDENTITY**,
-IMMEDIATE,
-IMPLEMENTATION,
-**IMPORT**,
-**IN**,
-INCLUDING,
-INCREMENT,
-**INDICATOR**,
-INITIALLY,
-**INNER**,
-**INOUT**,
-INPUT,
-**INSENSITIVE**,
-**INSERT**,
-INSTANCE,
-INSTANTIABLE,
-**INT**,
-**INTEGER**,
-**INTERSECT**,
-**INTERSECTION**,
-**INTERVAL**,
-**INTO**,
-INVOKER,
-**IS**,
-ISOLATION,
-JAVA,
-**JOIN**,
-K,
-KEY,
-KEY_MEMBER,
-KEY_TYPE,
-LABEL,
-**LANGUAGE**,
-**LARGE**,
-LAST,
-**LAST_VALUE**,
-**LATERAL**,
-**LEADING**,
-**LEFT**,
-LENGTH,
-LEVEL,
-LIBRARY,
-**LIKE**,
-**LIMIT**,
-**LN**,
-**LOCAL**,
-**LOCALTIME**,
-**LOCALTIMESTAMP**,
-LOCATOR,
-**LOWER**,
-M,
-MAP,
-**MATCH**,
-MATCHED,
-**MAX**,
-MAXVALUE,
-**MEMBER**,
-**MERGE**,
-MESSAGE_LENGTH,
-MESSAGE_OCTET_LENGTH,
-MESSAGE_TEXT,
-**METHOD**,
-**MIN**,
-**MINUTE**,
-MINVALUE,
-**MOD**,
-**MODIFIES**,
-**MODULE**,
-**MONTH**,
-MORE,
-**MULTISET**,
-MUMPS,
-NAME,
-NAMES,
-**NATIONAL**,
-**NATURAL**,
-**NCHAR**,
-**NCLOB**,
-NESTING,
-**NEW**,
-**NEXT**,
-**NO**,
-**NONE**,
-**NORMALIZE**,
-NORMALIZED,
-**NOT**,
-**NULL**,
-NULLABLE,
-**NULLIF**,
-NULLS,
-NUMBER,
-**NUMERIC**,
-OBJECT,
-OCTETS,
-**OCTET_LENGTH**,
-**OF**,
-**OFFSET**,
-**OLD**,
-**ON**,
-**ONLY**,
-**OPEN**,
-OPTION,
-OPTIONS,
-**OR**,
-**ORDER**,
-ORDERING,
-ORDINALITY,
-OTHERS,
-**OUT**,
-**OUTER**,
-OUTPUT,
-**OVER**,
-**OVERLAPS**,
-**OVERLAY**,
-OVERRIDING,
-PAD,
-**PARAMETER**,
-PARAMETER_MODE,
-PARAMETER_NAME,
-PARAMETER_ORDINAL_POSITION,
-PARAMETER_SPECIFIC_CATALOG,
-PARAMETER_SPECIFIC_NAME,
-PARAMETER_SPECIFIC_SCHEMA,
-PARTIAL,
-**PARTITION**,
-PASCAL,
-PASSTHROUGH,
-PATH,
-**PERCENTILE_CONT**,
-**PERCENTILE_DISC**,
-**PERCENT_RANK**,
-PLACING,
-PLAN,
-PLI,
-**POSITION**,
-**POWER**,
-PRECEDING,
-**PRECISION**,
-**PREPARE**,
-PRESERVE,
-**PRIMARY**,
-PRIOR,
-PRIVILEGES,
-**PROCEDURE**,
-PUBLIC,
-**RANGE**,
-**RANK**,
-READ,
-**READS**,
-**REAL**,
-**RECURSIVE**,
-**REF**,
-**REFERENCES**,
-**REFERENCING**,
-**REGR_AVGX**,
-**REGR_AVGY**,
-**REGR_COUNT**,
-**REGR_INTERCEPT**,
-**REGR_R2**,
-**REGR_SLOPE**,
-**REGR_SXX**,
-**REGR_SXY**,
-**REGR_SYY**,
-RELATIVE,
-**RELEASE**,
-REPEATABLE,
-**RESET**,
-RESTART,
-RESTRICT,
-**RESULT**,
-**RETURN**,
-RETURNED_CARDINALITY,
-RETURNED_LENGTH,
-RETURNED_OCTET_LENGTH,
-RETURNED_SQLSTATE,
-**RETURNS**,
-**REVOKE**,
-**RIGHT**,
-ROLE,
-**ROLLBACK**,
-**ROLLUP**,
-ROUTINE,
-ROUTINE_CATALOG,
-ROUTINE_NAME,
-ROUTINE_SCHEMA,
-**ROW**,
-**ROWS**,
-ROW_COUNT,
-**ROW_NUMBER**,
-**SAVEPOINT**,
-SCALE,
-SCHEMA,
-SCHEMA_NAME,
-**SCOPE**,
-SCOPE_CATALOGS,
-SCOPE_NAME,
-SCOPE_SCHEMA,
-**SCROLL**,
-**SEARCH**,
-**SECOND**,
-SECTION,
-SECURITY,
-**SELECT**,
-SELF,
-**SENSITIVE**,
-SEQUENCE,
-SERIALIZABLE,
-SERVER,
-SERVER_NAME,
-SESSION,
-**SESSION_USER**,
-**SET**,
-SETS,
-**SIMILAR**,
-SIMPLE,
-SIZE,
-**SMALLINT**,
-**SOME**,
-SOURCE,
-SPACE,
-**SPECIFIC**,
-**SPECIFICTYPE**,
-SPECIFIC_NAME,
-**SQL**,
-**SQLEXCEPTION**,
-**SQLSTATE**,
-**SQLWARNING**,
-**SQRT**,
-**START**,
-STATE,
-STATEMENT,
-**STATIC**,
-**STDDEV_POP**,
-**STDDEV_SAMP**,
-**STREAM**,
-STRUCTURE,
-STYLE,
-SUBCLASS_ORIGIN,
-**SUBMULTISET**,
-SUBSTITUTE,
-**SUBSTRING**,
-**SUM**,
-**SYMMETRIC**,
-**SYSTEM**,
-**SYSTEM_USER**,
-**TABLE**,
-**TABLESAMPLE**,
-TABLE_NAME,
-TEMPORARY,
-**THEN**,
-TIES,
-**TIME**,
-**TIMESTAMP**,
-**TIMEZONE_HOUR**,
-**TIMEZONE_MINUTE**,
-**TINYINT**,
-**TO**,
-TOP_LEVEL_COUNT,
-**TRAILING**,
-TRANSACTION,
-TRANSACTIONS_ACTIVE,
-TRANSACTIONS_COMMITTED,
-TRANSACTIONS_ROLLED_BACK,
-TRANSFORM,
-TRANSFORMS,
-**TRANSLATE**,
-**TRANSLATION**,
-**TREAT**,
-**TRIGGER**,
-TRIGGER_CATALOG,
-TRIGGER_NAME,
-TRIGGER_SCHEMA,
-**TRIM**,
-**TRUE**,
-TYPE,
-**UESCAPE**,
-UNBOUNDED,
-UNCOMMITTED,
-UNDER,
-**UNION**,
-**UNIQUE**,
-**UNKNOWN**,
-UNNAMED,
-**UNNEST**,
-**UPDATE**,
-**UPPER**,
-**UPSERT**,
-USAGE,
-**USER**,
-USER_DEFINED_TYPE_CATALOG,
-USER_DEFINED_TYPE_CODE,
-USER_DEFINED_TYPE_NAME,
-USER_DEFINED_TYPE_SCHEMA,
-**USING**,
-**VALUE**,
-**VALUES**,
-**VARBINARY**,
-**VARCHAR**,
-**VARYING**,
-**VAR_POP**,
-**VAR_SAMP**,
-VERSION,
-VIEW,
-**WHEN**,
-**WHENEVER**,
-**WHERE**,
-**WIDTH_BUCKET**,
-**WINDOW**,
-**WITH**,
-**WITHIN**,
-**WITHOUT**,
-WORK,
-WRAPPER,
-WRITE,
-XML,
-**YEAR**,
-ZONE.
-{% comment %} end {% endcomment %}
-
-## Identifiers
-
-Identifiers are the names of tables, columns and other metadata
-elements used in a SQL query.
-
-Unquoted identifiers, such as emp, must start with a letter and can
-only contain letters, digits, and underscores. They are implicitly
-converted to upper case.
-
-Quoted identifiers, such as `"Employee Name"`, start and end with
-double quotes.  They may contain virtually any character, including
-spaces and other punctuation.  If you wish to include a double quote
-in an identifier, use another double quote to escape it, like this:
-`"An employee called ""Fred""."`.
-
-In Calcite, matching identifiers to the name of the referenced object is
-case-sensitive.  But remember that unquoted identifiers are implicitly
-converted to upper case before matching, and if the object it refers
-to was created using an unquoted identifier for its name, then its
-name will have been converted to upper case also.
-
-## Data types
-
-### Scalar types
-
-| Data type   | Description               | Range and examples   |
-|:----------- |:------------------------- |:---------------------|
-| BOOLEAN     | Logical values            | Values: TRUE, FALSE, UNKNOWN
-| TINYINT     | 1 byte signed integer     | Range is -255 to 256
-| SMALLINT    | 2 byte signed integer     | Range is -32768 to 32767
-| INTEGER, INT | 4 byte signed integer    | Range is -2147483648 to 2147483647
-| BIGINT      | 8 byte signed integer     | Range is -9223372036854775808 to 9223372036854775807
-| DECIMAL(p, s) | Fixed point             | Example: 123.45 is a DECIMAL(5, 2) value.
-| NUMERIC     | Fixed point               |
-| REAL, FLOAT | 4 byte floating point     | 6 decimal digits precision
-| DOUBLE      | 8 byte floating point     | 15 decimal digits precision
-| CHAR(n), CHARACTER(n) | Fixed-width character string | 'Hello', '' (empty string), _latin1'Hello', n'Hello', _UTF16'Hello', 'Hello' 'there' (literal split into multiple parts)
-| VARCHAR(n), CHARACTER VARYING(n) | Variable-length character string | As CHAR(n)
-| BINARY(n)   | Fixed-width binary string | x'45F0AB', x'' (empty binary string), x'AB' 'CD' (multi-part binary string literal)
-| VARBINARY(n), BINARY VARYING(n) | Variable-length binary string | As BINARY(n)
-| DATE        | Date                      | Example: DATE '1969-07-20'
-| TIME        | Time of day               | Example: TIME '20:17:40'
-| TIMESTAMP [ WITHOUT TIME ZONE ] | Date and time | Example: TIMESTAMP '1969-07-20 20:17:40'
-| TIMESTAMP WITH TIME ZONE | Date and time with time zone | Example: TIMESTAMP '1969-07-20 20:17:40 America/Los Angeles'
-| INTERVAL timeUnit [ TO timeUnit ] | Date time interval | Examples: INTERVAL '1:5' YEAR TO MONTH, INTERVAL '45' DAY
-| Anchored interval | Date time interval  | Example: (DATE '1969-07-20', DATE '1972-08-29')
-
-Where:
-
-{% highlight sql %}
-timeUnit:
-  YEAR | MONTH | DAY | HOUR | MINUTE | SECOND
-{% endhighlight %}
-
-Note:
-
-* DATE, TIME and TIMESTAMP have no time zone. There is not even an implicit
-  time zone, such as UTC (as in Java) or the local time zone. It is left to
-  the user or application to supply a time zone.
-
-### Non-scalar types
-
-| Type     | Description
-|:-------- |:-----------------------------------------------------------
-| ANY      | A value of an unknown type
-| ROW      | Row with 1 or more columns
-| MAP      | Collection of keys mapped to values
-| MULTISET | Unordered collection that may contain duplicates
-| ARRAY    | Ordered, contiguous collection that may contain duplicates
-| CURSOR   | Cursor over the result of executing a query
-
-## Operators and functions
-
-### Comparison operators
-
-| Operator syntax                                   | Description
-|:------------------------------------------------- |:-----------
-| value1 = value2                                   | Equals
-| value1 <> value2                                  | Not equal
-| value1 > value2                                   | Greater than
-| value1 >= value2                                  | Greater than or equal
-| value1 < value2                                   | Less than
-| value1 <= value2                                  | Less than or equal
-| value IS NULL                                     | Whether *value* is null
-| value IS NOT NULL                                 | Whether *value* is not null
-| value1 IS DISTINCT FROM value2                    | Whether two values are not equal, treating null values as the same
-| value1 IS NOT DISTINCT FROM value2                | Whether two values are equal, treating null values as the same
-| value1 BETWEEN value2 AND value3                  | Whether *value1* is greater than or equal to *value2* and less than or equal to *value3*
-| value1 NOT BETWEEN value2 AND value3              | Whether *value1* is less than *value2* or greater than *value3*
-| string1 LIKE string2 [ ESCAPE string3 ]           | Whether *string1* matches pattern *string2*
-| string1 NOT LIKE string2 [ ESCAPE string3 ]       | Whether *string1* does not match pattern *string2*
-| string1 SIMILAR TO string2 [ ESCAPE string3 ]     | Whether *string1* matches regular expression *string2*
-| string1 NOT SIMILAR TO string2 [ ESCAPE string3 ] | Whether *string1* does not match regular expression *string2*
-| value IN (value [, value]* )                      | Whether *value* is equal to a value in a list
-| value NOT IN (value [, value]* )                  | Whether *value* is not equal to every value in a list
-| value IN (sub-query)                              | Whether *value* is equal to a row returned by *sub-query*
-| value NOT IN (sub-query)                          | Whether *value* is not equal to every row returned by *sub-query*
-| EXISTS (sub-query)                                | Whether *sub-query* returns at least one row
-
-### Logical operators
-
-| Operator syntax        | Description
-|:---------------------- |:-----------
-| boolean1 OR boolean2   | Whether *boolean1* is TRUE or *boolean2* is TRUE
-| boolean1 AND boolean2  | Whether *boolean1* and *boolean2* are both TRUE
-| NOT boolean            | Whether *boolean* is not TRUE; returns UNKNOWN if *boolean* is UNKNOWN
-| boolean IS FALSE       | Whether *boolean* is FALSE; returns FALSE if *boolean* is UNKNOWN
-| boolean IS NOT FALSE   | Whether *boolean* is not FALSE; returns TRUE if *boolean* is UNKNOWN
-| boolean IS TRUE        | Whether *boolean* is TRUE; returns FALSE if *boolean* is UNKNOWN
-| boolean IS NOT TRUE    | Whether *boolean* is not TRUE; returns TRUE if *boolean* is UNKNOWN
-| boolean IS UNKNOWN     | Whether *boolean* is UNKNOWN
-| boolean IS NOT UNKNOWN | Whether *boolean* is not UNKNOWN
-
-### Arithmetic operators and functions
-
-| Operator syntax           | Description
-|:------------------------- |:-----------
-| + numeric                 | Returns *numeric*
-|:- numeric                 | Returns negative *numeric*
-| numeric1 + numeric2       | Returns *numeric1* plus *numeric2*
-| numeric1 - numeric2       | Returns *numeric1* minus *numeric2*
-| numeric1 * numeric2       | Returns *numeric1* multiplied by *numeric2*
-| numeric1 / numeric2       | Returns *numeric1* divided by *numeric2*
-| POWER(numeric1, numeric2) | Returns *numeric1* raised to the power of *numeric2*
-| ABS(numeric)              | Returns the absolute value of *numeric*
-| MOD(numeric, numeric)     | Returns the remainder (modulus) of *numeric1* divided by *numeric2*. The result is negative only if *numeric1* is negative
-| SQRT(numeric)             | Returns the square root of *numeric*
-| LN(numeric)               | Returns the natural logarithm (base *e*) of *numeric*
-| LOG10(numeric)            | Returns the base 10 logarithm of *numeric*
-| EXP(numeric)              | Returns *e* raised to the power of *numeric*
-| CEIL(numeric)             | Rounds *numeric* up, and returns the smallest number that is greater than or equal to *numeric*
-| FLOOR(numeric)            | Rounds *numeric* down, and returns the largest number that is less than or equal to *numeric*
-
-### Character string operators and functions
-
-| Operator syntax            | Description
-|:-------------------------- |:-----------
-| string &#124;&#124; string | Concatenates two character strings.
-| CHAR_LENGTH(string)        | Returns the number of characters in a character string
-| CHARACTER_LENGTH(string)   | As CHAR_LENGTH(*string*)
-| UPPER(string)              | Returns a character string converted to upper case
-| LOWER(string)              | Returns a character string converted to lower case
-| POSITION(string1 IN string2) | Returns the position of the first occurrence of *string1* in *string2*
-| TRIM( { BOTH &#124; LEADING &#124; TRAILING } string1 FROM string2) | Removes the longest string containing only the characters in *string1* from the start/end/both ends of *string1*
-| OVERLAY(string1 PLACING string2 FROM integer [ FOR integer2 ]) | Replaces a substring of *string1* with *string2*
-| SUBSTRING(string FROM integer)  | Returns a substring of a character string starting at a given point.
-| SUBSTRING(string FROM integer FOR integer) | Returns a substring of a character string starting at a given point with a given length.
-| INITCAP(string)            | Returns *string* with the first letter of each word converter to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters.
-
-Not implemented:
-
-* SUBSTRING(string FROM regexp FOR regexp)
-
-### Binary string operators and functions
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| binary &#124;&#124; binary | Concatenates two binary strings.
-| POSITION(binary1 IN binary2) | Returns the position of the first occurrence of *binary1* in *binary2*
-| OVERLAY(binary1 PLACING binary2 FROM integer [ FOR integer2 ]) | Replaces a substring of *binary1* with *binary2*
-| SUBSTRING(binary FROM integer) | Returns a substring of *binary* starting at a given point
-| SUBSTRING(binary FROM integer FOR integer) | Returns a substring of *binary* starting at a given point with a given length
-
-### Date/time functions
-
-| Operator syntax           | Description
-|:------------------------- |:-----------
-| LOCALTIME                 | Returns the current date and time in the session time zone in a value of datatype TIME
-| LOCALTIME(precision)      | Returns the current date and time in the session time zone in a value of datatype TIME, with *precision* digits of precision
-| LOCALTIMESTAMP            | Returns the current date and time in the session time zone in a value of datatype TIMESTAMP
-| LOCALTIMESTAMP(precision) | Returns the current date and time in the session time zone in a value of datatype TIMESTAMP, with *precision* digits of precision
-| CURRENT_TIME              | Returns the current time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE
-| CURRENT_DATE              | Returns the current date in the session time zone, in a value of datatype DATE
-| CURRENT_TIMESTAMP         | Returns the current date and time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE
-| EXTRACT(timeUnit FROM datetime) | Extracts and returns the value of a specified datetime field from a datetime value expression
-| FLOOR(datetime TO timeUnit) | Rounds *datetime* down to *timeUnit*
-| CEIL(datetime TO timeUnit) | Rounds *datetime* up to *timeUnit*
-
-Not implemented:
-
-* EXTRACT(timeUnit FROM interval)
-* CEIL(interval)
-* FLOOR(interval)
-* datetime - datetime timeUnit [ TO timeUnit ]
-* interval OVERLAPS interval
-* \+ interval
-* \- interval
-* interval + interval
-* interval - interval
-* interval / interval
-* datetime + interval
-* datetime - interval
-
-### System functions
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| USER            | Equivalent to CURRENT_USER
-| CURRENT_USER    | User name of current execution context
-| SESSION_USER    | Session user name
-| SYSTEM_USER     | Returns the name of the current data store user as identified by the operating system
-| CURRENT_PATH    | Returns a character string representing the current lookup scope for references to user-defined routines and types
-| CURRENT_ROLE    | Returns the current active role
-
-### Conditional functions and operators
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| CASE value<br/>WHEN value1 [, value11 ]* THEN result1<br/>[ WHEN valueN [, valueN1 ]* THEN resultN ]*<br/>[ ELSE resultZ ]<br/> END | Simple case
-| CASE<br/>WHEN condition1 THEN result1<br/>[ WHEN conditionN THEN resultN ]*<br/>[ ELSE resultZ ]<br/>END | Searched case
-| NULLIF(value, value) | Returns NULL if the values are the same.<br/><br/>For example, <code>NULLIF(5, 5)</code> returns NULL; <code>NULLIF(5, 0)</code> returns 5.
-| COALESCE(value, value [, value ]* ) | Provides a value if the first value is null.<br/><br/>For example, <code>COALESCE(NULL, 5)</code> returns 5.
-
-### Type conversion
-
-| Operator syntax | Description
-|:--------------- | :----------
-| CAST(value AS type) | Converts a value to a given type.
-
-### Value constructors
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| ROW (value [, value]* ) | Creates a row from a list of values.
-| (value [, value]* )     | Creates a row from a list of values.
-| map '[' key ']'     | Returns the element of a map with a particular key.
-| array '[' index ']' | Returns the element at a particular location in an array.
-| ARRAY '[' value [, value ]* ']' | Creates an array from a list of values.
-| MAP '[' key, value [, key, value ]* ']' | Creates a map from a list of key-value pairs.
-
-### Collection functions
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| ELEMENT(value)  | Returns the sole element of a array or multiset; null if the collection is empty; throws if it has more than one element.
-| CARDINALITY(value) | Returns the number of elements in an array or multiset.
-
-See also: UNNEST relational operator converts a collection to a relation.
-
-### JDBC function escape
-
-#### Numeric
-
-| Operator syntax                | Description
-|:------------------------------ |:-----------
-| {fn LOG10(numeric)}            | Returns the base-10 logarithm of *numeric*
-| {fn POWER(numeric1, numeric2)} | Returns *numeric1* raised to the power of *numeric2*
-
-Not implemented:
-
-* {fn ABS(numeric)} - Returns the absolute value of *numeric*
-* {fn ACOS(numeric)} - Returns the arc cosine of *numeric*
-* {fn ASIN(numeric)} - Returns the arc sine of *numeric*
-* {fn ATAN(numeric)} - Returns the arc tangent of *numeric*
-* {fn ATAN2(numeric, numeric)}
-* {fn CEILING(numeric)} - Rounds *numeric* up, and returns the smallest number that is greater than or equal to *numeric*
-* {fn COS(numeric)} - Returns the cosine of *numeric*
-* {fn COT(numeric)}
-* {fn DEGREES(numeric)} - Converts *numeric* from radians to degrees
-* {fn EXP(numeric)} - Returns *e* raised to the power of *numeric*
-* {fn FLOOR(numeric)} - Rounds *numeric* down, and returns the largest number that is less than or equal to *numeric*
-* {fn LOG(numeric)} - Returns the natural logarithm (base *e*) of *numeric*
-* {fn MOD(numeric1, numeric2)} - Returns the remainder (modulus) of *numeric1* divided by *numeric2*. The result is negative only if *numeric1* is negative
-* {fn PI()} - Returns a value that is closer than any other value to *pi*
-* {fn RADIANS(numeric)} - Converts *numeric* from degrees to radians
-* {fn RAND(numeric)}
-* {fn ROUND(numeric, numeric)}
-* {fn SIGN(numeric)}
-* {fn SIN(numeric)} - Returns the sine of *numeric*
-* {fn SQRT(numeric)} - Returns the square root of *numeric*
-* {fn TAN(numeric)} - Returns the tangent of *numeric*
-* {fn TRUNCATE(numeric, numeric)}
-
-#### String
-
-| Operator syntax | Description
-|:--------------- |:-----------
-| {fn LOCATE(string1, string2)} | Returns the position in *string2* of the first occurrence of *string1*. Searches from the beginning of the second CharacterExpression, unless the startIndex parameter is specified.
-| {fn INSERT(string1, start, length, string2)} | Inserts *string2* into a slot in *string1*
-| {fn LCASE(string)}            | Returns a string in which all alphabetic characters in *string* have been converted to lower case
-
-Not implemented:
-
-* {fn ASCII(string)} - Convert a single-character string to the corresponding ASCII code, an integer between 0 and 255
-* {fn CHAR(string)}
-* {fn CONCAT(character, character)} - Returns the concatenation of character strings
-* {fn DIFFERENCE(string, string)}
-* {fn LEFT(string, integer)}
-* {fn LENGTH(string)}
-* {fn LOCATE(string1, string2 [, integer])} - Returns the position in *string2* of the first occurrence of *string1*. Searches from the beginning of *string2*, unless *integer* is specified.
-* {fn LTRIM(string)}
-* {fn REPEAT(string, integer)}
-* {fn REPLACE(string, string, string)}
-* {fn RIGHT(string, integer)}
-* {fn RTRIM(string)}
-* {fn SOUNDEX(string)}
-* {fn SPACE(integer)}
-* {fn SUBSTRING(string, integer, integer)}
-* {fn UCASE(string)} - Returns a string in which all alphabetic characters in *string* have been converted to upper case
-
-#### Date/time
-
-Not implemented:
-
-* {fn CURDATE()}
-* {fn CURTIME()}
-* {fn DAYNAME(date)}
-* {fn DAYOFMONTH(date)}
-* {fn DAYOFWEEK(date)}
-* {fn DAYOFYEAR(date)}
-* {fn HOUR(time)}
-* {fn MINUTE(time)}
-* {fn MONTH(date)}
-* {fn MONTHNAME(date)}
-* {fn NOW()}
-* {fn QUARTER(date)}
-* {fn SECOND(time)}
-* {fn TIMESTAMPADD(interval, count, timestamp)}
-* {fn TIMESTAMPDIFF(interval, timestamp, timestamp)}
-* {fn WEEK(date)}
-* {fn YEAR(date)}
-
-#### System
-
-Not implemented:
-
-* {fn DATABASE()}
-* {fn IFNULL(value, value)}
-* {fn USER(value, value)}
-* {fn CONVERT(value, type)}
-
-### Aggregate functions
-
-Syntax:
-
-{% highlight sql %}
-aggregateCall:
-        agg( [ DISTINCT ] value [, value]* ) [ FILTER ( WHERE condition ) ]
-    |   agg(*) [ FILTER ( WHERE condition ) ]
-{% endhighlight %}
-
-If `FILTER` is present, the aggregate function only considers rows for which
-*condition* evaluates to TRUE.
-
-If `DISTINCT` is present, duplicate argument values are eliminated before being
-passed to the aggregate function.
-
-| Operator syntax                    | Description
-|:---------------------------------- |:-----------
-| COLLECT( [ DISTINCT ] value)       | Returns a multiset of the values
-| COUNT( [ DISTINCT ] value [, value]* ) | Returns the number of input rows for which *value* is not null (wholly not null if *value* is composite)
-| COUNT(*)                           | Returns the number of input rows
-| AVG( [ DISTINCT ] numeric)         | Returns the average (arithmetic mean) of *numeric* across all input values
-| SUM( [ DISTINCT ] numeric)         | Returns the sum of *numeric* across all input values
-| MAX( [ DISTINCT ] value)           | Returns the maximum value of *value* across all input values
-| MIN( [ DISTINCT ] value)           | Returns the minimum value of *value* across all input values
-| STDDEV_POP( [ DISTINCT ] numeric)  | Returns the population standard deviation of *numeric* across all input values
-| STDDEV_SAMP( [ DISTINCT ] numeric) | Returns the sample standard deviation of *numeric* across all input values
-| VAR_POP( [ DISTINCT ] value)       | Returns the population variance (square of the population standard deviation) of *numeric* across all input values
-| VAR_SAMP( [ DISTINCT ] numeric)    | Returns the sample variance (square of the sample standard deviation) of *numeric* across all input values
-| COVAR_POP(numeric1, numeric2)      | Returns the population covariance of the pair (*numeric1*, *numeric2*) across all input values
-| COVAR_SAMP(numeric1, numeric2)     | Returns the sample covariance of the pair (*numeric1*, *numeric2*) across all input values
-| REGR_SXX(numeric1, numeric2)       | Returns the sum of squares of the dependent expression in a linear regression model
-| REGR_SYY(numeric1, numeric2)       | Returns the sum of squares of the independent expression in a linear regression model
-
-Not implemented:
-
-* REGR_AVGX(numeric1, numeric2)
-* REGR_AVGY(numeric1, numeric2)
-* REGR_COUNT(numeric1, numeric2)
-* REGR_INTERCEPT(numeric1, numeric2)
-* REGR_R2(numeric1, numeric2)
-* REGR_SLOPE(numeric1, numeric2)
-* REGR_SXY(numeric1, numeric2)
-
-### Window functions
-
-| Operator syntax                           | Description
-|:----------------------------------------- |:-----------
-| COUNT(value [, value ]* ) OVER window     | Returns the number of rows in *window* for which *value* is not null (wholly not null if *value* is composite)
-| COUNT(*) OVER window                      | Returns the number of rows in *window*
-| AVG(numeric) OVER window                  | Returns the average (arithmetic mean) of *numeric* across all values in *window*
-| SUM(numeric) OVER window                  | Returns the sum of *numeric* across all values in *window*
-| MAX(value) OVER window                    | Returns the maximum value of *value* across all values in *window*
-| MIN(value) OVER window                    | Returns the minimum value of *value* across all values in *window*
-| RANK() OVER window                        | Returns the rank of the current row with gaps; same as ROW_NUMBER of its first peer
-| DENSE_RANK() OVER window                  | Returns the rank of the current row without gaps; this function counts peer groups
-| ROW_NUMBER() OVER window                  | Returns the number of the current row within its partition, counting from 1
-| FIRST_VALUE(value) OVER window            | Returns *value* evaluated at the row that is the first row of the window frame
-| LAST_VALUE(value) OVER window             | Returns *value* evaluated at the row that is the last row of the window frame
-| LEAD(value, offset, default) OVER window  | Returns *value* evaluated at the row that is *offset* rows after the current row within the partition; if there is no such row, instead returns *default*. Both *offset* and *default* are evaluated with respect to the current row. If omitted, *offset* defaults to 1 and *default* to NULL
-| LAG(value, offset, default) OVER window   | Returns *value* evaluated at the row that is *offset* rows before the current row within the partition; if there is no such row, instead returns *default*. Both *offset* and *default* are evaluated with respect to the current row. If omitted, *offset* defaults to 1 and *default* to NULL
-| NTILE(value) OVER window                  | Returns an integer ranging from 1 to *value*, dividing the partition as equally as possible
-
-Not implemented:
-
-* COUNT(DISTINCT value) OVER window
-* FIRST_VALUE(value) IGNORE NULLS OVER window
-* LAST_VALUE(value) IGNORE NULLS OVER window
-* PERCENT_RANK(value) OVER window
-* CUME_DIST(value) OVER window
-* NTH_VALUE(value, nth) OVER window
-
-### Grouping functions
-
-| Operator syntax      | Description
-|:-------------------- |:-----------
-| GROUPING(expression) | Returns 1 if expression is rolled up in the current row's grouping set, 0 otherwise
-| GROUP_ID()           | Returns an integer that uniquely identifies the combination of grouping keys
-| GROUPING_ID(expression [, expression ] * ) | Returns a bit vector of the given grouping expressions
-
-### User-defined functions
-
-Calcite is extensible. You can define each kind of function using user code.
-For each kind of function there are often several ways to define a function,
-varying from convenient to efficient.
-
-To implement a *scalar function*, there are 3 options:
-
-* Create a class with a public static `eval` method,
-  and register the class;
-* Create a class with a public non-static `eval` method,
-  and a public constructor with no arguments,
-  and register the class;
-* Create a class with one or more public static methods,
-  and register each class/method combination.
-
-To implement an *aggregate function*, there are 2 options:
-
-* Create a class with public static `init`, `add` and `result` methods,
-  and register the class;
-* Create a class with public non-static `init`, `add` and `result` methods,
-  and a  public constructor with no arguments,
-  and register the class.
-
-Optionally, add a public `merge` method to the class; this allows Calcite to
-generate code that merges sub-totals.
-
-Optionally, make your class implement the
-[SqlSplittableAggFunction]({{ site.apiRoot }}/org/apache/calcite/sql/SqlSplittableAggFunction.html)
-interface; this allows Calcite to decompose the function across several stages
-of aggregation, roll up from summary tables, and push it through joins.
-
-To implement a *table function*, there are 3 options:
-
-* Create a class with a static `eval` method that returns
-  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
-  or
-  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
-  and register the class;
-* Create a class with a non-static `eval` method that returns
-  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
-  or
-  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
-  and register the class;
-* Create a class with one or more public static methods that return
-  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
-  or
-  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
-  and register each class/method combination.
-
-To implement a *table macro*, there are 3 options:
-
-* Create a class with a static `eval` method that returns
-  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
-  and register the class;
-* Create a class with a non-static `eval` method that returns
-  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
-  and register the class;
-* Create a class with one or more public static methods that return
-  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
-  and register each class/method combination.
-
-Calcite deduces the parameter types and result type of a function from the
-parameter and return types of the Java method that implements it. Further, you
-can specify the name and optionality of each parameter using the
-[Parameter]({{ site.apiRoot }}/org/apache/calcite/linq4j/function/Parameter.html)
-annotation.
-
-### Calling functions with named and optional parameters
-
-Usually when you call a function, you need to specify all of its parameters,
-in order. But that can be a problem if a function has a lot of parameters,
-and especially if you want to add more parameters over time.
-
-To solve this problem, the SQL standard allows you to pass parameters by name,
-and to define parameters which are optional (that is, have a default value
-that is used if they are not specified).
-
-Suppose you have a function `f`, declared as in the following pseudo syntax:
-
-```FUNCTION f(
-  INTEGER a,
-  INTEGER b DEFAULT NULL,
-  INTEGER c,
-  INTEGER d DEFAULT NULL,
-  INTEGER e DEFAULT NULL) RETURNS INTEGER```
-
-All of the function's parameters have names, and parameters `b`, `d` and `e`
-have a default value of `NULL` and are therefore optional.
-(In Calcite, `NULL` is the only allowable default value for optional parameters;
-this may change
-[in future](https://issues.apache.org/jira/browse/CALCITE-947).)
-
-When calling a function with optional parameters,
-you can omit optional arguments at the end of the list, or use the `DEFAULT`
-keyword for any optional arguments.
-Here are some examples:
-
-* `f(1, 2, 3, 4, 5)` provides a value to each parameter, in order;
-* `f(1, 2, 3, 4)` omits `e`, which gets its default value, `NULL`;
-* `f(1, DEFAULT, 3)` omits `d` and `e`,
-  and specifies to use the default value of `b`;
-* `f(1, DEFAULT, 3, DEFAULT, DEFAULT)` has the same effect as the previous
-  example;
-* `f(1, 2)` is not legal, because `c` is not optional;
-* `f(1, 2, DEFAULT, 4)` is not legal, because `c` is not optional.
-
-You can specify arguments by name using the `=>` syntax.
-If one argument is named, they all must be.
-Arguments may be in any other, but must not specify any argument more than once,
-and you need to provide a value for every parameter which is not optional.
-Here are some examples:
-
-* `f(c => 3, d => 1, a => 0)` is equivalent to `f(0, NULL, 3, 1, NULL)`;
-* `f(c => 3, d => 1)` is not legal, because you have not specified a value for
-  `a` and `a` is not optional.
-

http://git-wip-us.apache.org/repos/asf/calcite/blob/65f2afa7/avatica/site/_docs/roadmap.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/roadmap.md b/avatica/site/_docs/roadmap.md
new file mode 100644
index 0000000..30618ee
--- /dev/null
+++ b/avatica/site/_docs/roadmap.md
@@ -0,0 +1,51 @@
+---
+layout: docs
+title: Roadmap
+sidebar_title: Roadmap
+permalink: /docs/roadmap.html
+---
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+## Status
+
+### Implemented
+
+* Create connection, create statement, metadata, prepare, bind, execute, fetch
+* RPC using JSON over HTTP
+* Local implementation
+* Implementation over an existing JDBC driver
+* Composite RPCs (combining several requests into one round trip)
+  * Execute-Fetch
+  * Metadata-Fetch (metadata calls such as getTables return all rows)
+
+### Not implemented
+
+* ODBC
+* RPCs
+  * CloseStatement
+  * CloseConnection
+* Composite RPCs
+  * CreateStatement-Prepare
+  * CloseStatement-CloseConnection
+  * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
+* Remove statements from statement table
+* DML (INSERT, UPDATE, DELETE)
+* Statement.execute applied to SELECT statement


[05/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
deleted file mode 100644
index 5790848..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ /dev/null
@@ -1,2771 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaClientRuntimeException;
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaSeverity;
-import org.apache.calcite.avatica.BuiltInConnectionProperty;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.QueryState;
-import org.apache.calcite.avatica.proto.Common;
-import org.apache.calcite.avatica.proto.Requests;
-import org.apache.calcite.avatica.proto.Responses;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-import com.google.protobuf.HBaseZeroCopyByteString;
-import com.google.protobuf.Message;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Properties;
-
-/**
- * API for request-response calls to an Avatica server.
- */
-public interface Service {
-  ResultSetResponse apply(CatalogsRequest request);
-  ResultSetResponse apply(SchemasRequest request);
-  ResultSetResponse apply(TablesRequest request);
-  ResultSetResponse apply(TableTypesRequest request);
-  ResultSetResponse apply(TypeInfoRequest request);
-  ResultSetResponse apply(ColumnsRequest request);
-  PrepareResponse apply(PrepareRequest request);
-  ExecuteResponse apply(ExecuteRequest request);
-  ExecuteResponse apply(PrepareAndExecuteRequest request);
-  SyncResultsResponse apply(SyncResultsRequest request);
-  FetchResponse apply(FetchRequest request);
-  CreateStatementResponse apply(CreateStatementRequest request);
-  CloseStatementResponse apply(CloseStatementRequest request);
-  OpenConnectionResponse apply(OpenConnectionRequest request);
-  CloseConnectionResponse apply(CloseConnectionRequest request);
-  ConnectionSyncResponse apply(ConnectionSyncRequest request);
-  DatabasePropertyResponse apply(DatabasePropertyRequest request);
-  CommitResponse apply(CommitRequest request);
-  RollbackResponse apply(RollbackRequest request);
-
-  /**
-   * Sets server-level metadata for RPCs. This includes information that is static across all RPCs.
-   *
-   * @param metadata The server-level metadata.
-   */
-  void setRpcMetadata(RpcMetadataResponse metadata);
-
-  /** Factory that creates a {@code Service}. */
-  interface Factory {
-    Service create(AvaticaConnection connection);
-  }
-
-  /** Base class for request and response. */
-  abstract class Base {
-    static final int PRIME = 31;
-
-    protected static int p(int result, Object o) {
-      return PRIME * result + ((o == null) ? 0 : o.hashCode());
-    }
-
-    protected static int p(int result, boolean v) {
-      return PRIME * result + (v ? 1231 : 1237);
-    }
-
-    protected static int p(int result, int v) {
-      return PRIME * result + v;
-    }
-
-    protected static int p(int result, long v) {
-      return PRIME * result + (int) (v ^ (v >>> 32));
-    }
-  }
-
-  /** Base class for all service request messages. */
-  @JsonTypeInfo(
-      use = JsonTypeInfo.Id.NAME,
-      property = "request",
-      defaultImpl = SchemasRequest.class)
-  @JsonSubTypes({
-      @JsonSubTypes.Type(value = CatalogsRequest.class, name = "getCatalogs"),
-      @JsonSubTypes.Type(value = SchemasRequest.class, name = "getSchemas"),
-      @JsonSubTypes.Type(value = TablesRequest.class, name = "getTables"),
-      @JsonSubTypes.Type(value = TableTypesRequest.class, name = "getTableTypes"),
-      @JsonSubTypes.Type(value = TypeInfoRequest.class, name = "getTypeInfo"),
-      @JsonSubTypes.Type(value = ColumnsRequest.class, name = "getColumns"),
-      @JsonSubTypes.Type(value = ExecuteRequest.class, name = "execute"),
-      @JsonSubTypes.Type(value = PrepareRequest.class, name = "prepare"),
-      @JsonSubTypes.Type(value = PrepareAndExecuteRequest.class,
-          name = "prepareAndExecute"),
-      @JsonSubTypes.Type(value = FetchRequest.class, name = "fetch"),
-      @JsonSubTypes.Type(value = CreateStatementRequest.class,
-          name = "createStatement"),
-      @JsonSubTypes.Type(value = CloseStatementRequest.class,
-          name = "closeStatement"),
-      @JsonSubTypes.Type(value = OpenConnectionRequest.class,
-          name = "openConnection"),
-      @JsonSubTypes.Type(value = CloseConnectionRequest.class,
-          name = "closeConnection"),
-      @JsonSubTypes.Type(value = ConnectionSyncRequest.class, name = "connectionSync"),
-      @JsonSubTypes.Type(value = DatabasePropertyRequest.class, name = "databaseProperties"),
-      @JsonSubTypes.Type(value = SyncResultsRequest.class, name = "syncResults"),
-      @JsonSubTypes.Type(value = CommitRequest.class, name = "commit"),
-      @JsonSubTypes.Type(value = RollbackRequest.class, name = "rollback") })
-  abstract class Request extends Base {
-    abstract Response accept(Service service);
-    abstract Request deserialize(Message genericMsg);
-    abstract Message serialize();
-  }
-
-  /** Base class for all service response messages. */
-  @JsonTypeInfo(
-      use = JsonTypeInfo.Id.NAME,
-      property = "response",
-      defaultImpl = ResultSetResponse.class)
-  @JsonSubTypes({
-      @JsonSubTypes.Type(value = OpenConnectionResponse.class, name = "openConnection"),
-      @JsonSubTypes.Type(value = ResultSetResponse.class, name = "resultSet"),
-      @JsonSubTypes.Type(value = PrepareResponse.class, name = "prepare"),
-      @JsonSubTypes.Type(value = FetchResponse.class, name = "fetch"),
-      @JsonSubTypes.Type(value = CreateStatementResponse.class,
-          name = "createStatement"),
-      @JsonSubTypes.Type(value = CloseStatementResponse.class,
-          name = "closeStatement"),
-      @JsonSubTypes.Type(value = CloseConnectionResponse.class,
-          name = "closeConnection"),
-      @JsonSubTypes.Type(value = ConnectionSyncResponse.class, name = "connectionSync"),
-      @JsonSubTypes.Type(value = DatabasePropertyResponse.class, name = "databaseProperties"),
-      @JsonSubTypes.Type(value = ExecuteResponse.class, name = "executeResults"),
-      @JsonSubTypes.Type(value = ErrorResponse.class, name = "error"),
-      @JsonSubTypes.Type(value = SyncResultsResponse.class, name = "syncResults"),
-      @JsonSubTypes.Type(value = RpcMetadataResponse.class, name = "rpcMetadata"),
-      @JsonSubTypes.Type(value = CommitResponse.class, name = "commit"),
-      @JsonSubTypes.Type(value = RollbackResponse.class, name = "rollback") })
-  abstract class Response extends Base {
-    abstract Response deserialize(Message genericMsg);
-    abstract Message serialize();
-  }
-
-  /** Request for
-   * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)}. */
-  class CatalogsRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CatalogsRequest.
-        getDescriptor().findFieldByNumber(Requests.CatalogsRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-
-    public CatalogsRequest() {
-      connectionId = null;
-    }
-
-    @JsonCreator
-    public CatalogsRequest(@JsonProperty("connectionId") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    ResultSetResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override CatalogsRequest deserialize(Message genericMsg) {
-      final Requests.CatalogsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.CatalogsRequest.class);
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new CatalogsRequest(connectionId);
-    }
-
-    @Override Requests.CatalogsRequest serialize() {
-      Requests.CatalogsRequest.Builder builder = Requests.CatalogsRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CatalogsRequest
-          && Objects.equals(connectionId, ((CatalogsRequest) o).connectionId);
-    }
-  }
-
-  /** Request for
-   * {@link org.apache.calcite.avatica.Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */
-  class DatabasePropertyRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR =
-        Requests.DatabasePropertyRequest.getDescriptor().
-        findFieldByNumber(Requests.DatabasePropertyRequest.CONNECTION_ID_FIELD_NUMBER);
-
-    public final String connectionId;
-
-    public DatabasePropertyRequest() {
-      connectionId = null;
-    }
-
-    @JsonCreator
-    public DatabasePropertyRequest(@JsonProperty("connectionId") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    DatabasePropertyResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override DatabasePropertyRequest deserialize(Message genericMsg) {
-      final Requests.DatabasePropertyRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.DatabasePropertyRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new DatabasePropertyRequest(connectionId);
-    }
-
-    @Override Requests.DatabasePropertyRequest serialize() {
-      Requests.DatabasePropertyRequest.Builder builder =
-          Requests.DatabasePropertyRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof DatabasePropertyRequest
-          && Objects.equals(connectionId, ((DatabasePropertyRequest) o).connectionId);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#getSchemas(Meta.ConnectionHandle, String, Meta.Pat)}. */
-  class SchemasRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SchemasRequest.
-        getDescriptor().findFieldByNumber(Requests.SchemasRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.SchemasRequest.
-        getDescriptor().findFieldByNumber(Requests.SchemasRequest.CATALOG_FIELD_NUMBER);
-    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.SchemasRequest.
-        getDescriptor().findFieldByNumber(Requests.SchemasRequest.SCHEMA_PATTERN_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final String catalog;
-    public final String schemaPattern;
-
-    SchemasRequest() {
-      connectionId = null;
-      catalog = null;
-      schemaPattern = null;
-    }
-
-    @JsonCreator
-    public SchemasRequest(@JsonProperty("connectionId") String connectionId,
-        @JsonProperty("catalog") String catalog,
-        @JsonProperty("schemaPattern") String schemaPattern) {
-      this.connectionId = connectionId;
-      this.catalog = catalog;
-      this.schemaPattern = schemaPattern;
-    }
-
-    ResultSetResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override SchemasRequest deserialize(Message genericMsg) {
-      final Requests.SchemasRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.SchemasRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      String catalog = null;
-      if (msg.hasField(CATALOG_DESCRIPTOR)) {
-        catalog = msg.getCatalog();
-      }
-
-      String schemaPattern = null;
-      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
-        schemaPattern = msg.getSchemaPattern();
-      }
-
-      return new SchemasRequest(connectionId, catalog, schemaPattern);
-    }
-
-    @Override Requests.SchemasRequest serialize() {
-      Requests.SchemasRequest.Builder builder = Requests.SchemasRequest.newBuilder();
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-      if (null != catalog) {
-        builder.setCatalog(catalog);
-      }
-      if (null != schemaPattern) {
-        builder.setSchemaPattern(schemaPattern);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, catalog);
-      result = p(result, schemaPattern);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof SchemasRequest
-          && Objects.equals(connectionId, ((SchemasRequest) o).connectionId)
-          && Objects.equals(catalog, ((SchemasRequest) o).catalog)
-          && Objects.equals(schemaPattern, ((SchemasRequest) o).schemaPattern);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#getTables(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, java.util.List)}
-   */
-  class TablesRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TablesRequest.
-        getDescriptor().findFieldByNumber(Requests.TablesRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.TablesRequest.
-        getDescriptor().findFieldByNumber(Requests.TablesRequest.CATALOG_FIELD_NUMBER);
-    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.TablesRequest.
-        getDescriptor().findFieldByNumber(Requests.TablesRequest.SCHEMA_PATTERN_FIELD_NUMBER);
-    private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.TablesRequest.
-        getDescriptor().findFieldByNumber(Requests.TablesRequest.TABLE_NAME_PATTERN_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final String catalog;
-    public final String schemaPattern;
-    public final String tableNamePattern;
-    public final List<String> typeList;
-
-    TablesRequest() {
-      connectionId = null;
-      catalog = null;
-      schemaPattern = null;
-      tableNamePattern = null;
-      typeList = null;
-    }
-
-    @JsonCreator
-    public TablesRequest(@JsonProperty("connectionId") String connectionId,
-        @JsonProperty("catalog") String catalog,
-        @JsonProperty("schemaPattern") String schemaPattern,
-        @JsonProperty("tableNamePattern") String tableNamePattern,
-        @JsonProperty("typeList") List<String> typeList) {
-      this.connectionId = connectionId;
-      this.catalog = catalog;
-      this.schemaPattern = schemaPattern;
-      this.tableNamePattern = tableNamePattern;
-      this.typeList = typeList;
-    }
-
-    @Override Response accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override Request deserialize(Message genericMsg) {
-      final Requests.TablesRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.TablesRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      String catalog = null;
-      if (msg.hasField(CATALOG_DESCRIPTOR)) {
-        catalog = msg.getCatalog();
-      }
-
-      String schemaPattern = null;
-      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
-        schemaPattern = msg.getSchemaPattern();
-      }
-
-      String tableNamePattern = null;
-      if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) {
-        tableNamePattern = msg.getTableNamePattern();
-      }
-
-      // Cannot determine if a value was set for a repeated field. Must use an extra boolean
-      // parameter to distinguish an empty and null typeList.
-      List<String> typeList = null;
-      if (msg.getHasTypeList()) {
-        typeList = msg.getTypeListList();
-      }
-
-      return new TablesRequest(connectionId, catalog, schemaPattern, tableNamePattern, typeList);
-    }
-
-    @Override Requests.TablesRequest serialize() {
-      Requests.TablesRequest.Builder builder = Requests.TablesRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-      if (null != catalog) {
-        builder.setCatalog(catalog);
-      }
-      if (null != schemaPattern) {
-        builder.setSchemaPattern(schemaPattern);
-      }
-      if (null != tableNamePattern) {
-        builder.setTableNamePattern(tableNamePattern);
-      }
-      if (null != typeList) {
-        builder.setHasTypeList(true);
-        builder.addAllTypeList(typeList);
-      } else {
-        builder.setHasTypeList(false);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, catalog);
-      result = p(result, schemaPattern);
-      result = p(result, tableNamePattern);
-      result = p(result, typeList);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof TablesRequest
-          && Objects.equals(connectionId, ((TablesRequest) o).connectionId)
-          && Objects.equals(catalog, ((TablesRequest) o).catalog)
-          && Objects.equals(schemaPattern, ((TablesRequest) o).schemaPattern)
-          && Objects.equals(tableNamePattern, ((TablesRequest) o).tableNamePattern)
-          && Objects.equals(typeList, ((TablesRequest) o).typeList);
-    }
-  }
-
-  /**
-   * Request for {@link Meta#getTableTypes(Meta.ConnectionHandle)}.
-   */
-  class TableTypesRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TableTypesRequest.
-        getDescriptor().findFieldByNumber(Requests.TableTypesRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-
-    public TableTypesRequest() {
-      this.connectionId = null;
-    }
-
-    @JsonCreator
-    public TableTypesRequest(@JsonProperty("connectionId") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    @Override ResultSetResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override TableTypesRequest deserialize(Message genericMsg) {
-      final Requests.TableTypesRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.TableTypesRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new TableTypesRequest(connectionId);
-    }
-
-    @Override Requests.TableTypesRequest serialize() {
-      Requests.TableTypesRequest.Builder builder = Requests.TableTypesRequest.newBuilder();
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof TableTypesRequest
-          && Objects.equals(connectionId, ((TableTypesRequest) o).connectionId);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#getColumns(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat)}.
-   */
-  class ColumnsRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ColumnsRequest.
-        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.ColumnsRequest.
-        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CATALOG_FIELD_NUMBER);
-    private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
-        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.SCHEMA_PATTERN_FIELD_NUMBER);
-    private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
-        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.TABLE_NAME_PATTERN_FIELD_NUMBER);
-    private static final FieldDescriptor COLUMN_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest.
-        getDescriptor().findFieldByNumber(Requests.ColumnsRequest.COLUMN_NAME_PATTERN_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final String catalog;
-    public final String schemaPattern;
-    public final String tableNamePattern;
-    public final String columnNamePattern;
-
-    ColumnsRequest() {
-      connectionId = null;
-      catalog = null;
-      schemaPattern = null;
-      tableNamePattern = null;
-      columnNamePattern = null;
-    }
-
-    @JsonCreator
-    public ColumnsRequest(@JsonProperty("connectionId") String connectionId,
-        @JsonProperty("catalog") String catalog,
-        @JsonProperty("schemaPattern") String schemaPattern,
-        @JsonProperty("tableNamePattern") String tableNamePattern,
-        @JsonProperty("columnNamePattern") String columnNamePattern) {
-      this.connectionId = connectionId;
-      this.catalog = catalog;
-      this.schemaPattern = schemaPattern;
-      this.tableNamePattern = tableNamePattern;
-      this.columnNamePattern = columnNamePattern;
-    }
-
-    ResultSetResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override ColumnsRequest deserialize(Message genericMsg) {
-      final Requests.ColumnsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.ColumnsRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      String catalog = null;
-      if (msg.hasField(CATALOG_DESCRIPTOR)) {
-        catalog = msg.getCatalog();
-      }
-
-      String schemaPattern = null;
-      if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) {
-        schemaPattern = msg.getSchemaPattern();
-      }
-
-      String tableNamePattern = null;
-      if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) {
-        tableNamePattern = msg.getTableNamePattern();
-      }
-
-      String columnNamePattern = null;
-      if (msg.hasField(COLUMN_NAME_PATTERN_DESCRIPTOR)) {
-        columnNamePattern = msg.getColumnNamePattern();
-      }
-
-      return new ColumnsRequest(connectionId, catalog, schemaPattern, tableNamePattern,
-          columnNamePattern);
-    }
-
-    @Override Requests.ColumnsRequest serialize() {
-      Requests.ColumnsRequest.Builder builder = Requests.ColumnsRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-      if (null != catalog) {
-        builder.setCatalog(catalog);
-      }
-      if (null != schemaPattern) {
-        builder.setSchemaPattern(schemaPattern);
-      }
-      if (null != tableNamePattern) {
-        builder.setTableNamePattern(tableNamePattern);
-      }
-      if (null != columnNamePattern) {
-        builder.setColumnNamePattern(columnNamePattern);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, catalog);
-      result = p(result, columnNamePattern);
-      result = p(result, schemaPattern);
-      result = p(result, tableNamePattern);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ColumnsRequest
-          && Objects.equals(connectionId, ((ColumnsRequest) o).connectionId)
-          && Objects.equals(catalog, ((ColumnsRequest) o).catalog)
-          && Objects.equals(schemaPattern, ((ColumnsRequest) o).schemaPattern)
-          && Objects.equals(tableNamePattern, ((ColumnsRequest) o).tableNamePattern)
-          && Objects.equals(columnNamePattern, ((ColumnsRequest) o).columnNamePattern);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#getTypeInfo(Meta.ConnectionHandle)}. */
-  class TypeInfoRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TypeInfoRequest.
-        getDescriptor().findFieldByNumber(Requests.TypeInfoRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-
-    public TypeInfoRequest() {
-      connectionId = null;
-    }
-
-    @JsonCreator
-    public TypeInfoRequest(@JsonProperty("connectionId") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    @Override ResultSetResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override TypeInfoRequest deserialize(Message genericMsg) {
-      final Requests.TypeInfoRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.TypeInfoRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new TypeInfoRequest(connectionId);
-    }
-
-    @Override Requests.TypeInfoRequest serialize() {
-      Requests.TypeInfoRequest.Builder builder = Requests.TypeInfoRequest.newBuilder();
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof TypeInfoRequest
-          && Objects.equals(connectionId, ((TypeInfoRequest) o).connectionId);
-    }
-  }
-
-  /** Response that contains a result set.
-   *
-   * <p>Regular result sets have {@code updateCount} -1;
-   * any other value means a dummy result set that is just a count, and has
-   * no signature and no other data.
-   *
-   * <p>Several types of request, including
-   * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)} and
-   * {@link org.apache.calcite.avatica.Meta#getSchemas(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat)}
-   * {@link Meta#getTables(Meta.ConnectionHandle, String, Meta.Pat, Meta.Pat, List)}
-   * {@link Meta#getTableTypes(Meta.ConnectionHandle)}
-   * return this response. */
-  class ResultSetResponse extends Response {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.ResultSetResponse.
-        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor SIGNATURE_DESCRIPTOR = Responses.ResultSetResponse.
-        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.SIGNATURE_FIELD_NUMBER);
-    private static final FieldDescriptor FIRST_FRAME_DESCRIPTOR = Responses.ResultSetResponse.
-        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.FIRST_FRAME_FIELD_NUMBER);
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ResultSetResponse.
-        getDescriptor().findFieldByNumber(Responses.ResultSetResponse.METADATA_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final int statementId;
-    public final boolean ownStatement;
-    public final Meta.Signature signature;
-    public final Meta.Frame firstFrame;
-    public final long updateCount;
-    public final RpcMetadataResponse rpcMetadata;
-
-    ResultSetResponse() {
-      connectionId = null;
-      statementId = 0;
-      ownStatement = false;
-      signature = null;
-      firstFrame = null;
-      updateCount = 0;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public ResultSetResponse(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId,
-        @JsonProperty("ownStatement") boolean ownStatement,
-        @JsonProperty("signature") Meta.Signature signature,
-        @JsonProperty("firstFrame") Meta.Frame firstFrame,
-        @JsonProperty("updateCount") long updateCount,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.ownStatement = ownStatement;
-      this.signature = signature;
-      this.firstFrame = firstFrame;
-      this.updateCount = updateCount;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override ResultSetResponse deserialize(Message genericMsg) {
-      final Responses.ResultSetResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.ResultSetResponse.class);
-
-      return fromProto(msg);
-    }
-
-    static ResultSetResponse fromProto(Responses.ResultSetResponse msg) {
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      Meta.Signature signature = null;
-      if (msg.hasField(SIGNATURE_DESCRIPTOR)) {
-        signature = Meta.Signature.fromProto(msg.getSignature());
-      }
-
-      Meta.Frame frame = null;
-      if (msg.hasField(FIRST_FRAME_DESCRIPTOR)) {
-        frame = Meta.Frame.fromProto(msg.getFirstFrame());
-      }
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new ResultSetResponse(connectionId, msg.getStatementId(), msg.getOwnStatement(),
-          signature, frame, msg.getUpdateCount(), metadata);
-    }
-
-    @Override Responses.ResultSetResponse serialize() {
-      Responses.ResultSetResponse.Builder builder = Responses.ResultSetResponse.newBuilder();
-
-      builder.setStatementId(statementId).setOwnStatement(ownStatement).setUpdateCount(updateCount);
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      if (null != signature) {
-        builder.setSignature(signature.toProto());
-      }
-
-      if (null != firstFrame) {
-        builder.setFirstFrame(firstFrame.toProto());
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, firstFrame);
-      result = p(result, ownStatement);
-      result = p(result, signature);
-      result = p(result, statementId);
-      result = p(result, updateCount);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ResultSetResponse
-          && statementId == ((ResultSetResponse) o).statementId
-          && ownStatement == ((ResultSetResponse) o).ownStatement
-          && updateCount == ((ResultSetResponse) o).updateCount
-          && Objects.equals(connectionId, ((ResultSetResponse) o).connectionId)
-          && Objects.equals(firstFrame, ((ResultSetResponse) o).firstFrame)
-          && Objects.equals(signature, ((ResultSetResponse) o).signature)
-          && Objects.equals(rpcMetadata, ((ResultSetResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)}. */
-  class PrepareAndExecuteRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.
-        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
-            Requests.PrepareAndExecuteRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor SQL_DESCRIPTOR = Requests.
-        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
-            Requests.PrepareAndExecuteRequest.SQL_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final String sql;
-    public final long maxRowCount;
-    public final int statementId;
-
-    PrepareAndExecuteRequest() {
-      connectionId = null;
-      sql = null;
-      maxRowCount = 0;
-      statementId = 0;
-    }
-
-    @JsonCreator
-    public PrepareAndExecuteRequest(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId,
-        @JsonProperty("sql") String sql,
-        @JsonProperty("maxRowCount") long maxRowCount) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.sql = sql;
-      this.maxRowCount = maxRowCount;
-    }
-
-    @Override ExecuteResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override PrepareAndExecuteRequest deserialize(Message genericMsg) {
-      final Requests.PrepareAndExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.PrepareAndExecuteRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      String sql = null;
-      if (msg.hasField(SQL_DESCRIPTOR)) {
-        sql = msg.getSql();
-      }
-
-      return new PrepareAndExecuteRequest(connectionId, msg.getStatementId(), sql,
-          msg.getMaxRowCount());
-    }
-
-    @Override Requests.PrepareAndExecuteRequest serialize() {
-      Requests.PrepareAndExecuteRequest.Builder builder = Requests.PrepareAndExecuteRequest
-          .newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-      if (null != sql) {
-        builder.setSql(sql);
-      }
-      builder.setStatementId(statementId);
-      builder.setMaxRowCount(maxRowCount);
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, maxRowCount);
-      result = p(result, sql);
-      result = p(result, statementId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof PrepareAndExecuteRequest
-          && statementId == ((PrepareAndExecuteRequest) o).statementId
-          && maxRowCount == ((PrepareAndExecuteRequest) o).maxRowCount
-          && Objects.equals(connectionId, ((PrepareAndExecuteRequest) o).connectionId)
-          && Objects.equals(sql, ((PrepareAndExecuteRequest) o).sql);
-    }
-  }
-
-  /** Request for
-   * {@link org.apache.calcite.avatica.Meta#execute}. */
-  class ExecuteRequest extends Request {
-    private static final FieldDescriptor STATEMENT_HANDLE_DESCRIPTOR = Requests.ExecuteRequest.
-        getDescriptor().findFieldByNumber(Requests.ExecuteRequest.STATEMENTHANDLE_FIELD_NUMBER);
-    public final Meta.StatementHandle statementHandle;
-    public final List<TypedValue> parameterValues;
-    public final long maxRowCount;
-
-    ExecuteRequest() {
-      statementHandle = null;
-      parameterValues = null;
-      maxRowCount = 0;
-    }
-
-    @JsonCreator
-    public ExecuteRequest(
-        @JsonProperty("statementHandle") Meta.StatementHandle statementHandle,
-        @JsonProperty("parameterValues") List<TypedValue> parameterValues,
-        @JsonProperty("maxRowCount") long maxRowCount) {
-      this.statementHandle = statementHandle;
-      this.parameterValues = parameterValues;
-      this.maxRowCount = maxRowCount;
-    }
-
-    @Override ExecuteResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override ExecuteRequest deserialize(Message genericMsg) {
-      final Requests.ExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.ExecuteRequest.class);
-
-      Meta.StatementHandle statemetnHandle = null;
-      if (msg.hasField(STATEMENT_HANDLE_DESCRIPTOR)) {
-        statemetnHandle = Meta.StatementHandle.fromProto(msg.getStatementHandle());
-      }
-
-      List<TypedValue> values = null;
-      if (msg.getHasParameterValues()) {
-        values = new ArrayList<>(msg.getParameterValuesCount());
-        for (Common.TypedValue valueProto : msg.getParameterValuesList()) {
-          values.add(TypedValue.fromProto(valueProto));
-        }
-      }
-
-      return new ExecuteRequest(statemetnHandle, values, msg.getMaxRowCount());
-    }
-
-    @Override Requests.ExecuteRequest serialize() {
-      Requests.ExecuteRequest.Builder builder = Requests.ExecuteRequest.newBuilder();
-
-      if (null != statementHandle) {
-        builder.setStatementHandle(statementHandle.toProto());
-      }
-
-      if (null != parameterValues) {
-        builder.setHasParameterValues(true);
-        for (TypedValue paramValue : parameterValues) {
-          if (paramValue == null) {
-            builder.addParameterValues(TypedValue.NULL.toProto());
-          } else {
-            builder.addParameterValues(paramValue.toProto());
-          }
-        }
-      } else {
-        builder.setHasParameterValues(false);
-      }
-
-      builder.setMaxRowCount(maxRowCount);
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, statementHandle);
-      result = p(result, parameterValues);
-      result = p(result, maxRowCount);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ExecuteRequest
-          && maxRowCount == ((ExecuteRequest) o).maxRowCount
-          && Objects.equals(statementHandle, ((ExecuteRequest) o).statementHandle)
-          && Objects.equals(parameterValues, ((ExecuteRequest) o).parameterValues);
-    }
-  }
-
-  /** Response to a
-   * {@link org.apache.calcite.avatica.remote.Service.PrepareAndExecuteRequest}. */
-  class ExecuteResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ExecuteResponse.
-        getDescriptor().findFieldByNumber(Responses.ExecuteResponse.METADATA_FIELD_NUMBER);
-    public final List<ResultSetResponse> results;
-    public boolean missingStatement = false;
-    public final RpcMetadataResponse rpcMetadata;
-
-    ExecuteResponse() {
-      results = null;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public ExecuteResponse(@JsonProperty("resultSets") List<ResultSetResponse> results,
-        @JsonProperty("missingStatement") boolean missingStatement,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.results = results;
-      this.missingStatement = missingStatement;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override ExecuteResponse deserialize(Message genericMsg) {
-      final Responses.ExecuteResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.ExecuteResponse.class);
-
-      List<Responses.ResultSetResponse> msgResults = msg.getResultsList();
-      List<ResultSetResponse> copiedResults = new ArrayList<>(msgResults.size());
-
-      for (Responses.ResultSetResponse msgResult : msgResults) {
-        copiedResults.add(ResultSetResponse.fromProto(msgResult));
-      }
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new ExecuteResponse(copiedResults, msg.getMissingStatement(), metadata);
-    }
-
-    @Override Responses.ExecuteResponse serialize() {
-      Responses.ExecuteResponse.Builder builder = Responses.ExecuteResponse.newBuilder();
-
-      if (null != results) {
-        for (ResultSetResponse result : results) {
-          builder.addResults(result.serialize());
-        }
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.setMissingStatement(missingStatement).build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, results);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ExecuteResponse
-          && Objects.equals(results, ((ExecuteResponse) o).results)
-          && Objects.equals(rpcMetadata, ((ExecuteResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#prepare(Meta.ConnectionHandle, String, long)}. */
-  class PrepareRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.PrepareRequest.
-        getDescriptor().findFieldByNumber(Requests.PrepareRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor SQL_DESCRIPTOR = Requests.PrepareRequest.
-        getDescriptor().findFieldByNumber(Requests.PrepareRequest.SQL_FIELD_NUMBER);
-    public final String connectionId;
-    public final String sql;
-    public final long maxRowCount;
-
-    PrepareRequest() {
-      connectionId = null;
-      sql = null;
-      maxRowCount = 0;
-    }
-
-    @JsonCreator
-    public PrepareRequest(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("sql") String sql,
-        @JsonProperty("maxRowCount") long maxRowCount) {
-      this.connectionId = connectionId;
-      this.sql = sql;
-      this.maxRowCount = maxRowCount;
-    }
-
-    @Override PrepareResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override PrepareRequest deserialize(Message genericMsg) {
-      final Requests.PrepareRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.PrepareRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      String sql = null;
-      if (msg.hasField(SQL_DESCRIPTOR)) {
-        sql = msg.getSql();
-      }
-
-      return new PrepareRequest(connectionId, sql, msg.getMaxRowCount());
-    }
-
-    @Override Requests.PrepareRequest serialize() {
-      Requests.PrepareRequest.Builder builder = Requests.PrepareRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      if (null != sql) {
-        builder.setSql(sql);
-      }
-
-      return builder.setMaxRowCount(maxRowCount).build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, maxRowCount);
-      result = p(result, sql);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof PrepareRequest
-          && maxRowCount == ((PrepareRequest) o).maxRowCount
-          && Objects.equals(connectionId, ((PrepareRequest) o).connectionId)
-          && Objects.equals(sql, ((PrepareRequest) o).sql);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.PrepareRequest}. */
-  class PrepareResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.PrepareResponse.
-        getDescriptor().findFieldByNumber(Responses.PrepareResponse.METADATA_FIELD_NUMBER);
-    public final Meta.StatementHandle statement;
-    public final RpcMetadataResponse rpcMetadata;
-
-    PrepareResponse() {
-      statement = null;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public PrepareResponse(
-        @JsonProperty("statement") Meta.StatementHandle statement,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.statement = statement;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override PrepareResponse deserialize(Message genericMsg) {
-      final Responses.PrepareResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.PrepareResponse.class);
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new PrepareResponse(Meta.StatementHandle.fromProto(msg.getStatement()), metadata);
-    }
-
-    @Override Responses.PrepareResponse serialize() {
-      Responses.PrepareResponse.Builder builder = Responses.PrepareResponse.newBuilder();
-
-      if (null != statement) {
-        builder.setStatement(statement.toProto());
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, statement);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof PrepareResponse
-          && Objects.equals(statement, ((PrepareResponse) o).statement)
-          && Objects.equals(rpcMetadata, ((PrepareResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#fetch}. */
-  class FetchRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.FetchRequest.
-        getDescriptor().findFieldByNumber(Requests.FetchRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-    public final int statementId;
-    public final long offset;
-    /** Maximum number of rows to be returned in the frame. Negative means no
-     * limit. */
-    public final int fetchMaxRowCount;
-
-    FetchRequest() {
-      connectionId = null;
-      statementId = 0;
-      offset = 0;
-      fetchMaxRowCount = 0;
-    }
-
-    @JsonCreator
-    public FetchRequest(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId,
-        @JsonProperty("offset") long offset,
-        @JsonProperty("fetchMaxRowCount") int fetchMaxRowCount) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.offset = offset;
-      this.fetchMaxRowCount = fetchMaxRowCount;
-    }
-
-    @Override FetchResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override FetchRequest deserialize(Message genericMsg) {
-      final Requests.FetchRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.FetchRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new FetchRequest(connectionId, msg.getStatementId(), msg.getOffset(),
-          msg.getFetchMaxRowCount());
-    }
-
-    @Override Requests.FetchRequest serialize() {
-      Requests.FetchRequest.Builder builder = Requests.FetchRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      builder.setStatementId(statementId);
-      builder.setOffset(offset);
-      builder.setFetchMaxRowCount(fetchMaxRowCount);
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, fetchMaxRowCount);
-      result = p(result, offset);
-      result = p(result, statementId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof FetchRequest
-          && statementId == ((FetchRequest) o).statementId
-          && offset == ((FetchRequest) o).offset
-          && fetchMaxRowCount == ((FetchRequest) o).fetchMaxRowCount
-          && Objects.equals(connectionId, ((FetchRequest) o).connectionId);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.FetchRequest}. */
-  class FetchResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.FetchResponse.
-        getDescriptor().findFieldByNumber(Responses.FetchResponse.METADATA_FIELD_NUMBER);
-    public final Meta.Frame frame;
-    public boolean missingStatement = false;
-    public boolean missingResults = false;
-    public final RpcMetadataResponse rpcMetadata;
-
-    FetchResponse() {
-      frame = null;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public FetchResponse(@JsonProperty("frame") Meta.Frame frame,
-        @JsonProperty("missingStatement") boolean missingStatement,
-        @JsonProperty("missingResults") boolean missingResults,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.frame = frame;
-      this.missingStatement = missingStatement;
-      this.missingResults = missingResults;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override FetchResponse deserialize(Message genericMsg) {
-      final Responses.FetchResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.FetchResponse.class);
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new FetchResponse(Meta.Frame.fromProto(msg.getFrame()), msg.getMissingStatement(),
-          msg.getMissingResults(), metadata);
-    }
-
-    @Override Responses.FetchResponse serialize() {
-      Responses.FetchResponse.Builder builder = Responses.FetchResponse.newBuilder();
-
-      if (null != frame) {
-        builder.setFrame(frame.toProto());
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.setMissingStatement(missingStatement)
-          .setMissingResults(missingResults).build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, frame);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof FetchResponse
-          && Objects.equals(frame, ((FetchResponse) o).frame)
-          && Objects.equals(rpcMetadata, ((FetchResponse) o).rpcMetadata)
-          && missingStatement == ((FetchResponse) o).missingStatement;
-    }
-  }
-
-  /** Request for
-   * {@link org.apache.calcite.avatica.Meta#createStatement(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */
-  class CreateStatementRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CreateStatementRequest.
-        getDescriptor().findFieldByNumber(
-            Requests.CreateStatementRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-
-    CreateStatementRequest() {
-      connectionId = null;
-    }
-
-    @JsonCreator
-    public CreateStatementRequest(
-        @JsonProperty("signature") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    @Override CreateStatementResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override CreateStatementRequest deserialize(Message genericMsg) {
-      final Requests.CreateStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.CreateStatementRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new CreateStatementRequest(connectionId);
-    }
-
-    @Override Requests.CreateStatementRequest serialize() {
-      Requests.CreateStatementRequest.Builder builder = Requests.CreateStatementRequest
-          .newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CreateStatementRequest
-          && Objects.equals(connectionId, ((CreateStatementRequest) o).connectionId);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.CreateStatementRequest}. */
-  class CreateStatementResponse extends Response {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.
-        CreateStatementResponse.getDescriptor().findFieldByNumber(
-            Responses.CreateStatementResponse.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.
-        CreateStatementResponse.getDescriptor().findFieldByNumber(
-            Responses.CreateStatementResponse.METADATA_FIELD_NUMBER);
-    public final String connectionId;
-    public final int statementId;
-    public final RpcMetadataResponse rpcMetadata;
-
-    CreateStatementResponse() {
-      connectionId = null;
-      statementId = 0;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public CreateStatementResponse(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override CreateStatementResponse deserialize(Message genericMsg) {
-      final Responses.CreateStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.CreateStatementResponse.class);
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new CreateStatementResponse(connectionId, msg.getStatementId(), metadata);
-    }
-
-    @Override Responses.CreateStatementResponse serialize() {
-      Responses.CreateStatementResponse.Builder builder = Responses.CreateStatementResponse
-          .newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      builder.setStatementId(statementId);
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, statementId);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CreateStatementResponse
-          && statementId == ((CreateStatementResponse) o).statementId
-          && Objects.equals(connectionId, ((CreateStatementResponse) o).connectionId)
-          && Objects.equals(rpcMetadata, ((CreateStatementResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link org.apache.calcite.avatica.Meta#closeStatement(org.apache.calcite.avatica.Meta.StatementHandle)}. */
-  class CloseStatementRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseStatementRequest.
-        getDescriptor().findFieldByNumber(
-            Requests.CloseStatementRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-    public final int statementId;
-
-    CloseStatementRequest() {
-      connectionId = null;
-      statementId = 0;
-    }
-
-    @JsonCreator
-    public CloseStatementRequest(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-    }
-
-    @Override CloseStatementResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override CloseStatementRequest deserialize(Message genericMsg) {
-      final Requests.CloseStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.CloseStatementRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new CloseStatementRequest(connectionId, msg.getStatementId());
-    }
-
-    @Override Requests.CloseStatementRequest serialize() {
-      Requests.CloseStatementRequest.Builder builder = Requests.CloseStatementRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.setStatementId(statementId).build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, statementId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CloseStatementRequest
-          && statementId == ((CloseStatementRequest) o).statementId
-          && Objects.equals(connectionId, ((CloseStatementRequest) o).connectionId);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.CloseStatementRequest}. */
-  class CloseStatementResponse extends Response {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.
-        CloseStatementResponse.getDescriptor().findFieldByNumber(
-            Responses.CloseStatementResponse.METADATA_FIELD_NUMBER);
-
-    public final RpcMetadataResponse rpcMetadata;
-
-    public CloseStatementResponse() {
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public CloseStatementResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override CloseStatementResponse deserialize(Message genericMsg) {
-      final Responses.CloseStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.CloseStatementResponse.class);
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new CloseStatementResponse(metadata);
-    }
-
-    @Override Responses.CloseStatementResponse serialize() {
-      Responses.CloseStatementResponse.Builder builder =
-          Responses.CloseStatementResponse.newBuilder();
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CloseStatementResponse
-          && Objects.equals(rpcMetadata, ((CloseStatementResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#openConnection}. */
-  class OpenConnectionRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.OpenConnectionRequest
-        .getDescriptor().findFieldByNumber(
-            Requests.OpenConnectionRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-    public final Map<String, String> info;
-
-    public OpenConnectionRequest() {
-      connectionId = null;
-      info = null;
-    }
-
-    @JsonCreator
-    public OpenConnectionRequest(@JsonProperty("connectionId") String connectionId,
-        @JsonProperty("info") Map<String, String> info) {
-      this.connectionId = connectionId;
-      this.info = info;
-    }
-
-    @Override OpenConnectionResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    /**
-     * Serializes the necessary properties into a Map.
-     *
-     * @param props The properties to serialize.
-     * @return A representation of the Properties as a Map.
-     */
-    public static Map<String, String> serializeProperties(Properties props) {
-      Map<String, String> infoAsString = new HashMap<>();
-      for (Map.Entry<Object, Object> entry : props.entrySet()) {
-        // Determine if this is a property we want to forward to the server
-        boolean localProperty = false;
-        for (BuiltInConnectionProperty prop : BuiltInConnectionProperty.values()) {
-          if (prop.camelName().equals(entry.getKey())) {
-            localProperty = true;
-            break;
-          }
-        }
-
-        if (!localProperty) {
-          infoAsString.put(entry.getKey().toString(), entry.getValue().toString());
-        }
-      }
-      return infoAsString;
-    }
-
-    @Override Request deserialize(Message genericMsg) {
-      final Requests.OpenConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.OpenConnectionRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      Map<String, String> info = msg.getInfo();
-      if (info.isEmpty()) {
-        info = null;
-      }
-
-      return new OpenConnectionRequest(connectionId, info);
-    }
-
-    @Override Message serialize() {
-      Requests.OpenConnectionRequest.Builder builder = Requests.OpenConnectionRequest.newBuilder();
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-      if (null != info) {
-        builder.getMutableInfo().putAll(info);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      result = p(result, info);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof OpenConnectionRequest
-          && Objects.equals(connectionId, ((OpenConnectionRequest) o).connectionId)
-          && Objects.equals(info, ((OpenConnectionRequest) o).info);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.OpenConnectionRequest}. */
-  class OpenConnectionResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.OpenConnectionResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.OpenConnectionResponse.METADATA_FIELD_NUMBER);
-    public final RpcMetadataResponse rpcMetadata;
-
-    public OpenConnectionResponse() {
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public OpenConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override OpenConnectionResponse deserialize(Message genericMsg) {
-      final Responses.OpenConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.OpenConnectionResponse.class);
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new OpenConnectionResponse(metadata);
-    }
-
-    @Override Responses.OpenConnectionResponse serialize() {
-      Responses.OpenConnectionResponse.Builder builder =
-          Responses.OpenConnectionResponse.newBuilder();
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof OpenConnectionResponse
-          && Objects.equals(rpcMetadata, ((OpenConnectionResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for
-   * {@link Meta#closeConnection(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */
-  class CloseConnectionRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseConnectionRequest
-        .getDescriptor().findFieldByNumber(
-            Requests.CloseConnectionRequest.CONNECTION_ID_FIELD_NUMBER);
-    public final String connectionId;
-
-    CloseConnectionRequest() {
-      connectionId = null;
-    }
-
-    @JsonCreator
-    public CloseConnectionRequest(
-        @JsonProperty("connectionId") String connectionId) {
-      this.connectionId = connectionId;
-    }
-
-    @Override CloseConnectionResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override CloseConnectionRequest deserialize(Message genericMsg) {
-      final Requests.CloseConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.CloseConnectionRequest.class);
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      return new CloseConnectionRequest(connectionId);
-    }
-
-    @Override Requests.CloseConnectionRequest serialize() {
-      Requests.CloseConnectionRequest.Builder builder = Requests.CloseConnectionRequest
-          .newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CloseConnectionRequest
-          && Objects.equals(connectionId, ((CloseConnectionRequest) o).connectionId);
-    }
-  }
-
-  /** Response from
-   * {@link org.apache.calcite.avatica.remote.Service.CloseConnectionRequest}. */
-  class CloseConnectionResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.CloseConnectionResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.CloseConnectionResponse.METADATA_FIELD_NUMBER);
-
-    public final RpcMetadataResponse rpcMetadata;
-
-    public CloseConnectionResponse() {
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public CloseConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override CloseConnectionResponse deserialize(Message genericMsg) {
-      final Responses.CloseConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.CloseConnectionResponse.class);
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new CloseConnectionResponse(metadata);
-    }
-
-    @Override Responses.CloseConnectionResponse serialize() {
-      Responses.CloseConnectionResponse.Builder builder =
-          Responses.CloseConnectionResponse.newBuilder();
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof CloseConnectionResponse
-          && Objects.equals(rpcMetadata, ((CloseConnectionResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Request for {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */
-  class ConnectionSyncRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ConnectionSyncRequest
-        .getDescriptor().findFieldByNumber(
-            Requests.ConnectionSyncRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor CONN_PROPS_DESCRIPTOR = Requests.ConnectionSyncRequest
-        .getDescriptor().findFieldByNumber(Requests.ConnectionSyncRequest.CONN_PROPS_FIELD_NUMBER);
-
-    public final String connectionId;
-    public final Meta.ConnectionProperties connProps;
-
-    ConnectionSyncRequest() {
-      connectionId = null;
-      connProps = null;
-    }
-
-    @JsonCreator
-    public ConnectionSyncRequest(
-        @JsonProperty("connectionId") String connectionId,
-        @JsonProperty("connProps") Meta.ConnectionProperties connProps) {
-      this.connectionId = connectionId;
-      this.connProps = connProps;
-    }
-
-    @Override ConnectionSyncResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    @Override ConnectionSyncRequest deserialize(Message genericMsg) {
-      final Requests.ConnectionSyncRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.ConnectionSyncRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      Meta.ConnectionProperties connProps = null;
-      if (msg.hasField(CONN_PROPS_DESCRIPTOR)) {
-        connProps = ConnectionPropertiesImpl.fromProto(msg.getConnProps());
-      }
-
-      return new ConnectionSyncRequest(connectionId, connProps);
-    }
-
-    @Override Requests.ConnectionSyncRequest serialize() {
-      Requests.ConnectionSyncRequest.Builder builder = Requests.ConnectionSyncRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      if (null != connProps) {
-        builder.setConnProps(connProps.toProto());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connProps);
-      result = p(result, connectionId);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ConnectionSyncRequest
-          && Objects.equals(connectionId, ((ConnectionSyncRequest) o).connectionId)
-          && Objects.equals(connProps, ((ConnectionSyncRequest) o).connProps);
-    }
-  }
-
-  /** Response for
-   * {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */
-  class ConnectionSyncResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ConnectionSyncResponse
-        .getDescriptor().findFieldByNumber(Responses.ConnectionSyncResponse.METADATA_FIELD_NUMBER);
-    public final Meta.ConnectionProperties connProps;
-    public final RpcMetadataResponse rpcMetadata;
-
-    ConnectionSyncResponse() {
-      connProps = null;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public ConnectionSyncResponse(@JsonProperty("connProps") Meta.ConnectionProperties connProps,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.connProps = connProps;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override ConnectionSyncResponse deserialize(Message genericMsg) {
-      final Responses.ConnectionSyncResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.ConnectionSyncResponse.class);
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new ConnectionSyncResponse(ConnectionPropertiesImpl.fromProto(msg.getConnProps()),
-          metadata);
-    }
-
-    @Override Responses.ConnectionSyncResponse serialize() {
-      Responses.ConnectionSyncResponse.Builder builder = Responses.ConnectionSyncResponse
-          .newBuilder();
-
-      if (null != connProps) {
-        builder.setConnProps(connProps.toProto());
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, connProps);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof ConnectionSyncResponse
-          && Objects.equals(connProps, ((ConnectionSyncResponse) o).connProps)
-          && Objects.equals(rpcMetadata, ((ConnectionSyncResponse) o).rpcMetadata);
-    }
-  }
-
-  /** Response for
-   * {@link Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */
-  class DatabasePropertyResponse extends Response {
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.DatabasePropertyResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.DatabasePropertyResponse.METADATA_FIELD_NUMBER);
-    public final Map<Meta.DatabaseProperty, Object> map;
-    public final RpcMetadataResponse rpcMetadata;
-
-    DatabasePropertyResponse() {
-      map = null;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public DatabasePropertyResponse(@JsonProperty("map") Map<Meta.DatabaseProperty, Object> map,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.map = map;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    @Override DatabasePropertyResponse deserialize(Message genericMsg) {
-      final Responses.DatabasePropertyResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.DatabasePropertyResponse.class);
-      HashMap<Meta.DatabaseProperty, Object> properties = new HashMap<>();
-      for (Responses.DatabasePropertyElement property : msg.getPropsList()) {
-        final Meta.DatabaseProperty dbProp = Meta.DatabaseProperty.fromProto(property.getKey());
-        final Common.TypedValue value = property.getValue();
-
-        Object obj;
-        switch (dbProp) {
-        // Just need to keep parity with the exposed values on DatabaseProperty
-        case GET_NUMERIC_FUNCTIONS:
-        case GET_STRING_FUNCTIONS:
-        case GET_SYSTEM_FUNCTIONS:
-        case GET_TIME_DATE_FUNCTIONS:
-        case GET_S_Q_L_KEYWORDS:
-          // String
-          if (Common.Rep.STRING != value.getType()) {
-            throw new IllegalArgumentException("Expected STRING, but got " + value.getType());
-          }
-
-          obj = value.getStringValue();
-          break;
-        case GET_DEFAULT_TRANSACTION_ISOLATION:
-          // int
-          if (Common.Rep.INTEGER != value.getType()) {
-            throw new IllegalArgumentException("Expected INTEGER, but got " + value.getType());
-          }
-
-          obj = (int) value.getNumberValue();
-          break;
-        default:
-          throw new RuntimeException("Unhandled DatabaseProperty");
-        }
-
-        properties.put(dbProp, obj);
-      }
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new DatabasePropertyResponse(properties, metadata);
-    }
-
-    @Override Responses.DatabasePropertyResponse serialize() {
-      Responses.DatabasePropertyResponse.Builder builder = Responses.DatabasePropertyResponse
-          .newBuilder();
-
-      if (null != map) {
-        for (Entry<Meta.DatabaseProperty, Object> entry : map.entrySet()) {
-          Object obj = entry.getValue();
-
-          Common.TypedValue.Builder valueBuilder = Common.TypedValue.newBuilder();
-          switch (entry.getKey()) {
-          // Just need to keep parity with the exposed values on DatabaseProperty
-          case GET_NUMERIC_FUNCTIONS:
-          case GET_STRING_FUNCTIONS:
-          case GET_SYSTEM_FUNCTIONS:
-          case GET_TIME_DATE_FUNCTIONS:
-          case GET_S_Q_L_KEYWORDS:
-            // String
-            if (!(obj instanceof String)) {
-              throw new RuntimeException("Expected a String, but got " + obj.getClass());
-            }
-
-            valueBuilder.setType(Common.Rep.STRING).setStringValue((String) obj);
-            break;
-          case GET_DEFAULT_TRANSACTION_ISOLATION:
-            // int
-            if (!(obj instanceof Integer)) {
-              throw new RuntimeException("Expected an Integer, but got " + obj.getClass());
-            }
-
-            valueBuilder.setType(Common.Rep.INTEGER).setNumberValue(((Integer) obj).longValue());
-            break;
-          default:
-            throw new RuntimeException("Unhandled DatabaseProperty");
-          }
-
-          builder.addProps(Responses.DatabasePropertyElement.newBuilder()
-              .setKey(entry.getKey().toProto()).setValue(valueBuilder.build()));
-        }
-      }
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      return builder.build();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, map);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o == this
-          || o instanceof DatabasePropertyResponse
-          && Objects.equals(map, ((DatabasePropertyResponse) o).map)
-          && Objects.equals(rpcMetadata, ((DatabasePropertyResponse) o).rpcMetadata);
-    }
-  }
-
-  /**
-   * Response for any request that the server failed to successfully perform.
-   * It is used internally by the transport layers to format errors for
-   * transport over the wire. Thus, {@link Service#apply} will never return
-   * an ErrorResponse.
-   */
-  public class ErrorResponse extends Response {
-    private static final FieldDescriptor ERROR_MESSAGE_DESCRIPTOR = Responses.ErrorResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.ErrorResponse.ERROR_MESSAGE_FIELD_NUMBER);
-    private static final FieldDescriptor SQL_DESCRIPTOR = Responses.ErrorResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.ErrorResponse.SQL_STATE_FIELD_NUMBER);
-    private static final FieldDescriptor SEVERITY_DESCRIPTOR = Responses.ErrorResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.ErrorResponse.SEVERITY_FIELD_NUMBER);
-    private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ErrorResponse
-        .getDescriptor().findFieldByNumber(
-            Responses.ErrorResponse.METADATA_FIELD_NUMBER);
-
-    public static final int UNKNOWN_ERROR_CODE = -1;
-    public static final int MISSING_CONNECTION_ERROR_CODE = 1;
-
-    public static final String UNKNOWN_SQL_STATE = "00000";
-
-    public final List<String> exceptions;
-    public final String errorMessage;
-    public final int errorCode;
-    public final String sqlState;
-    public final AvaticaSeverity severity;
-    public final RpcMetadataResponse rpcMetadata;
-
-    ErrorResponse() {
-      exceptions = Collections.singletonList("Unhandled exception");
-      errorMessage = "Unknown message";
-      errorCode = -1;
-      sqlState = UNKNOWN_SQL_STATE;
-      severity = AvaticaSeverity.UNKNOWN;
-      rpcMetadata = null;
-    }
-
-    @JsonCreator
-    public ErrorResponse(@JsonProperty("exceptions") List<String> exceptions,
-        @JsonProperty("errorMessage") String errorMessage,
-        @JsonProperty("errorCode") int errorCode,
-        @JsonProperty("sqlState") String sqlState,
-        @JsonProperty("severity") AvaticaSeverity severity,
-        @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
-      this.exceptions = exceptions;
-      this.errorMessage = errorMessage;
-      this.errorCode = errorCode;
-      this.sqlState = sqlState;
-      this.severity = severity;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    protected ErrorResponse(Exception e, String errorMessage, int code, String sqlState,
-        AvaticaSeverity severity, RpcMetadataResponse rpcMetadata) {
-      this(errorMessage, code, sqlState, severity, toStackTraces(e), rpcMetadata);
-    }
-
-    protected ErrorResponse(String errorMessage, int code, String sqlState,
-        AvaticaSeverity severity, List<String> exceptions, RpcMetadataResponse rpcMetadata) {
-      this.exceptions = exceptions;
-      this.errorMessage = errorMessage;
-      this.errorCode = code;
-      this.sqlState = sqlState;
-      this.severity = severity;
-      this.rpcMetadata = rpcMetadata;
-    }
-
-    static List<String> toStackTraces(Exception e) {
-      List<String> stackTraces = new ArrayList<>();
-      stackTraces.add(toString(e));
-      if (e instanceof SQLException) {
-        SQLException next = ((SQLException) e).getNextException();
-        while (null != next) {
-          stackTraces.add(toString(next));
-          next = next.getNextException();
-        }
-      }
-      return stackTraces;
-    }
-
-    static String toString(Exception e) {
-      //noinspection ThrowableResultOfMethodCallIgnored
-      Objects.requireNonNull(e);
-      StringWriter sw = new StringWriter();
-      e.printStackTrace(new PrintWriter(sw));
-      return sw.toString();
-    }
-
-    @Override ErrorResponse deserialize(Message genericMsg) {
-      final Responses.ErrorResponse msg = ProtobufService.castProtobufMessage(genericMsg,
-          Responses.ErrorResponse.class);
-      List<String> exceptions = null;
-      if (msg.getHasExceptions()) {
-        exceptions = msg.getExceptionsList();
-      }
-
-      String errorMessage = null;
-      if (msg.hasField(ERROR_MESSAGE_DESCRIPTOR)) {
-        errorMessage = msg.getErrorMessage();
-      }
-
-      String sqlState = null;
-      if (msg.hasField(SQL_DESCRIPTOR)) {
-        sqlState = msg.getSqlState();
-      }
-
-      AvaticaSeverity severity = null;
-      if (msg.hasField(SEVERITY_DESCRIPTOR)) {
-        severity = AvaticaSeverity.fromProto(msg.getSeverity());
-      }
-
-      RpcMetadataResponse metadata = null;
-      if (msg.hasField(METADATA_DESCRIPTOR)) {
-        metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
-      }
-
-      return new ErrorResponse(exceptions, errorMessage, msg.getErrorCode(), sqlState, severity,
-          metadata);
-    }
-
-    @Override Responses.ErrorResponse serialize() {
-      Responses.ErrorResponse.Builder builder = Responses.ErrorResponse.newBuilder();
-
-      if (null != rpcMetadata) {
-        builder.setMetadata(rpcMetadata.serialize());
-      }
-
-      if (null != exceptions) {
-        builder.setHasExceptions(true);
-        builder.addAllExceptions(exceptions);
-      } else {
-        builder.setHasExceptions(false);
-      }
-
-      if (null != errorMessage) {
-        builder.setErrorMessage(errorMessage);
-      }
-
-      if (null != sqlState) {
-        builder.setSqlState(sqlState);
-      }
-
-      if (null != severity) {
-        builder.setSeverity(severity.toProto());
-      }
-
-      return builder.setErrorCode(errorCode).build();
-    }
-
-    @Override public String toString() {
-      StringBuilder sb = new StringBuilder(32);
-      sb.append("ErrorResponse[errorCode=").append(errorCode)
-          .append(", sqlState=").append(sqlState)
-          .append(", severity=").append(severity)
-          .append(", errorMessage=").append(errorMessage)
-          .append(", exceptions=").append(exceptions);
-      return sb.toString();
-    }
-
-    @Override public int hashCode() {
-      int result = 1;
-      result = p(result, exceptions);
-      result = p(result, errorMessage);
-      result = p(result, errorCode);
-      result = p(result, sqlState);
-      result = p(result, severity);
-      result = p(result, rpcMetadata);
-      return result;
-    }
-
-    @Override public boolean equals(Object o) {
-      return this == o
-          || o instanceof ErrorResponse
-          && errorCode == ((ErrorResponse) o).errorCode
-          && severity == ((ErrorResponse) o).severity
-          && Objects.equals(exceptions, ((ErrorResponse) o).exceptions)
-          && Objects.equals(errorMessage, ((ErrorResponse) o).errorMessage)
-          && Objects.equals(sqlState, ((ErrorResponse) o).sqlState)
-          && Objects.equals(rpcMetadata, ((ErrorResponse) o).rpcMetadata);
-    }
-
-    public AvaticaClientRuntimeException toException() {
-      return new AvaticaClientRuntimeException("Remote driver error: " + errorMessage, errorCode,
-          sqlState, severity, exceptions, rpcMetadata);
-    }
-  }
-
-  /**
-   * Request for {@link Service#apply(SyncResultsRequest)}
-   */
-  class SyncResultsRequest extends Request {
-    private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SyncResultsRequest
-        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.CONNECTION_ID_FIELD_NUMBER);
-    private static final FieldDescriptor STATEMENT_ID_DESCRIPTOR = Requests.SyncResultsRequest
-        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATEMENT_ID_FIELD_NUMBER);
-    private static final FieldDescriptor STATE_DESCRIPTOR = Requests.SyncResultsRequest
-        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATE_FIELD_NUMBER);
-    private static final FieldDescriptor OFFSET_DESCRIPTOR = Requests.SyncResultsRequest
-        .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.OFFSET_FIELD_NUMBER);
-    public final String connectionId;
-    public final int statementId;
-    public final QueryState state;
-    public final long offset;
-
-    SyncResultsRequest() {
-      this.connectionId = null;
-      this.statementId = 0;
-      this.state = null;
-      this.offset = 0L;
-    }
-
-    public SyncResultsRequest(@JsonProperty("connectionId") String connectionId,
-        @JsonProperty("statementId") int statementId, @JsonProperty("state") QueryState state,
-        @JsonProperty("offset") long offset) {
-      this.connectionId = connectionId;
-      this.statementId = statementId;
-      this.state = state;
-      this.offset = offset;
-    }
-
-    SyncResultsResponse accept(Service service) {
-      return service.apply(this);
-    }
-
-    Request deserialize(Message genericMsg) {
-      final Requests.SyncResultsRequest msg = ProtobufService.castProtobufMessage(genericMsg,
-          Requests.SyncResultsRequest.class);
-
-      String connectionId = null;
-      if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) {
-        connectionId = msg.getConnectionId();
-      }
-
-      int statementId = 0;
-      if (msg.hasField(STATEMENT_ID_DESCRIPTOR)) {
-        statementId = msg.getStatementId();
-      }
-
-      Common.QueryState state = null;
-      if (msg.hasField(STATE_DESCRIPTOR)) {
-        state = msg.getState();
-      }
-
-      long offset = 0;
-      if (msg.hasField(OFFSET_DESCRIPTOR)) {
-        offset = msg.getOffset();
-      }
-
-      return new SyncResultsRequest(connectionId, statementId,
-          null == state ? null : QueryState.fromProto(msg.getState()), offset);
-    }
-
-    Requests.SyncResultsRequest serialize() {
-      Requests.SyncResultsRequest.Builder builder = Requests.SyncResultsRequest.newBuilder();
-
-      if (null != connectionId) {
-        builder.setConnectionId(connectionId);
-      }
-
-      if (null != state) {
-        builder.setState(state.toProto());
-      }
-
-      builde

<TRUNCATED>

[25/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
new file mode 100644
index 0000000..228ba8d
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
@@ -0,0 +1,1320 @@
+/*
+ * 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.jdbc.JdbcMeta;
+import org.apache.calcite.avatica.remote.JsonService;
+import org.apache.calcite.avatica.remote.LocalJsonService;
+import org.apache.calcite.avatica.remote.LocalProtobufService;
+import org.apache.calcite.avatica.remote.LocalService;
+import org.apache.calcite.avatica.remote.ProtobufTranslation;
+import org.apache.calcite.avatica.remote.ProtobufTranslationImpl;
+import org.apache.calcite.avatica.remote.Service;
+
+import com.google.common.cache.Cache;
+
+import net.jcip.annotations.NotThreadSafe;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit test for Avatica Remote JDBC driver.
+ */
+@RunWith(Parameterized.class)
+@NotThreadSafe // for testConnectionIsolation
+public class RemoteDriverTest {
+  public static final String LJS =
+      LocalJdbcServiceFactory.class.getName();
+
+  public static final String QRJS =
+      QuasiRemoteJdbcServiceFactory.class.getName();
+
+  public static final String QRPBS =
+      QuasiRemotePBJdbcServiceFactory.class.getName();
+
+  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
+
+  private static Connection ljs() throws SQLException {
+    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + QRJS);
+  }
+
+  private static Connection lpbs() throws SQLException {
+    return DriverManager.getConnection("jdbc:avatica:remote:factory=" + QRPBS);
+  }
+
+  private Connection canon() throws SQLException {
+    return DriverManager.getConnection(CONNECTION_SPEC.url,
+        CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+  }
+
+  /**
+   * Interface that allows for alternate ways to access internals to the Connection for testing
+   * purposes.
+   */
+  interface ConnectionInternals {
+    /**
+     * Reaches into the guts of a quasi-remote connection and pull out the
+     * statement map from the other side.
+     *
+     * <p>TODO: refactor tests to replace reflection with package-local access
+     */
+    Cache<Integer, Object> getRemoteStatementMap(AvaticaConnection connection) throws Exception;
+
+    /**
+     * Reaches into the guts of a quasi-remote connection and pull out the
+     * connection map from the other side.
+     *
+     * <p>TODO: refactor tests to replace reflection with package-local access
+     */
+    Cache<String, Connection> getRemoteConnectionMap(AvaticaConnection connection) throws Exception;
+  }
+
+  // Run each test with the LocalJsonService and LocalProtobufService
+  @Parameters
+  public static List<Object[]> parameters() {
+    List<Object[]> connections = new ArrayList<>();
+
+    // Json and Protobuf operations should be equivalent -- tests against one work on the other
+    // Each test needs to get a fresh Connection and also access some internals on that Connection.
+
+    connections.add(
+      new Object[] {
+        new Callable<Connection>() {
+          public Connection call() {
+            try {
+              return ljs();
+            } catch (SQLException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        },
+        new QuasiRemoteJdbcServiceInternals(),
+        new Callable<RequestInspection>() {
+          public RequestInspection call() throws Exception {
+            assert null != QuasiRemoteJdbcServiceFactory.requestInspection;
+            return QuasiRemoteJdbcServiceFactory.requestInspection;
+          }
+        } });
+
+    // TODO write the ConnectionInternals implementation
+    connections.add(
+      new Object[] {
+        new Callable<Connection>() {
+          public Connection call() {
+            try {
+              return lpbs();
+            } catch (SQLException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        },
+        new QuasiRemoteProtobufJdbcServiceInternals(),
+        new Callable<RequestInspection>() {
+          public RequestInspection call() throws Exception {
+            assert null != QuasiRemotePBJdbcServiceFactory.requestInspection;
+            return QuasiRemotePBJdbcServiceFactory.requestInspection;
+          }
+        } });
+
+    return connections;
+  }
+
+  private final Callable<Connection> localConnectionCallable;
+  private final ConnectionInternals localConnectionInternals;
+  private final Callable<RequestInspection> requestInspectionCallable;
+
+  public RemoteDriverTest(Callable<Connection> localConnectionCallable,
+      ConnectionInternals internals, Callable<RequestInspection> requestInspectionCallable) {
+    this.localConnectionCallable = localConnectionCallable;
+    this.localConnectionInternals = internals;
+    this.requestInspectionCallable = requestInspectionCallable;
+  }
+
+  private Connection getLocalConnection() {
+    try {
+      return localConnectionCallable.call();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private ConnectionInternals getLocalConnectionInternals() {
+    return localConnectionInternals;
+  }
+
+  private RequestInspection getRequestInspection() {
+    try {
+      return requestInspectionCallable.call();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /** Executes a lambda for the canonical connection and the local
+   * connection. */
+  public void eachConnection(ConnectionFunction f, Connection localConn) throws Exception {
+    for (int i = 0; i < 2; i++) {
+      try (Connection connection = i == 0 ? canon() : localConn) {
+        f.apply(connection);
+      }
+    }
+  }
+
+  @Before
+  public void before() throws Exception {
+    QuasiRemoteJdbcServiceFactory.initService();
+    QuasiRemotePBJdbcServiceFactory.initService();
+  }
+
+  @Test public void testRegister() throws Exception {
+    final Connection connection = getLocalConnection();
+    assertThat(connection.isClosed(), is(false));
+    connection.close();
+    assertThat(connection.isClosed(), is(true));
+  }
+
+  @Test public void testDatabaseProperties() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      final Connection connection = getLocalConnection();
+      for (Meta.DatabaseProperty p : Meta.DatabaseProperty.values()) {
+        switch (p) {
+        case GET_NUMERIC_FUNCTIONS:
+          assertThat(connection.getMetaData().getNumericFunctions(),
+              equalTo("ABS,ACOS,ASIN,ATAN,ATAN2,BITAND,BITOR,BITXOR,"
+                  + "CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,"
+                  + "PI,POWER,RADIANS,RAND,ROUND,ROUNDMAGIC,SIGN,SIN,"
+                  + "SQRT,TAN,TRUNCATE"));
+          break;
+        case GET_SYSTEM_FUNCTIONS:
+          assertThat(connection.getMetaData().getSystemFunctions(),
+              equalTo("DATABASE,IFNULL,USER"));
+          break;
+        case GET_TIME_DATE_FUNCTIONS:
+          assertThat(connection.getMetaData().getTimeDateFunctions(),
+              equalTo("CURDATE,CURTIME,DATEDIFF,DAYNAME,DAYOFMONTH,DAYOFWEEK,"
+                  + "DAYOFYEAR,HOUR,MINUTE,MONTH,MONTHNAME,NOW,QUARTER,SECOND,"
+                  + "SECONDS_SINCE_MIDNIGHT,TIMESTAMPADD,TIMESTAMPDIFF,"
+                  + "TO_CHAR,WEEK,YEAR"));
+          break;
+        case GET_S_Q_L_KEYWORDS:
+          assertThat(connection.getMetaData().getSQLKeywords(),
+              equalTo("")); // No SQL keywords return for HSQLDB
+          break;
+        case GET_STRING_FUNCTIONS:
+          assertThat(connection.getMetaData().getStringFunctions(),
+              equalTo("ASCII,CHAR,CONCAT,DIFFERENCE,HEXTORAW,INSERT,LCASE,"
+                  + "LEFT,LENGTH,LOCATE,LTRIM,RAWTOHEX,REPEAT,REPLACE,"
+                  + "RIGHT,RTRIM,SOUNDEX,SPACE,SUBSTR,UCASE"));
+          break;
+        default:
+        }
+      }
+      connection.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testTypeInfo() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      final Connection connection = getLocalConnection();
+      final ResultSet resultSet =
+          connection.getMetaData().getTypeInfo();
+      assertTrue(resultSet.next());
+      final ResultSetMetaData metaData = resultSet.getMetaData();
+      assertTrue(metaData.getColumnCount() >= 18);
+      assertEquals("TYPE_NAME", metaData.getColumnName(1));
+      assertEquals("DATA_TYPE", metaData.getColumnName(2));
+      assertEquals("PRECISION", metaData.getColumnName(3));
+      assertEquals("SQL_DATA_TYPE", metaData.getColumnName(16));
+      assertEquals("SQL_DATETIME_SUB", metaData.getColumnName(17));
+      assertEquals("NUM_PREC_RADIX", metaData.getColumnName(18));
+      resultSet.close();
+      connection.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testGetTables() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      final Connection connection = getLocalConnection();
+      final ResultSet resultSet =
+              connection.getMetaData().getTables(null, "SCOTT", null, null);
+      assertEquals(13, resultSet.getMetaData().getColumnCount());
+      assertTrue(resultSet.next());
+      assertEquals("DEPT", resultSet.getString(3));
+      assertTrue(resultSet.next());
+      assertEquals("EMP", resultSet.getString(3));
+      assertTrue(resultSet.next());
+      assertEquals("BONUS", resultSet.getString(3));
+      assertTrue(resultSet.next());
+      assertEquals("SALGRADE", resultSet.getString(3));
+      resultSet.close();
+      connection.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Ignore
+  @Test public void testNoFactory() throws Exception {
+    final Connection connection =
+        DriverManager.getConnection("jdbc:avatica:remote:");
+    assertThat(connection.isClosed(), is(false));
+    final ResultSet resultSet = connection.getMetaData().getSchemas();
+    assertFalse(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("TABLE_SCHEM", metaData.getColumnName(1));
+    assertEquals("TABLE_CATALOG", metaData.getColumnName(2));
+    resultSet.close();
+    connection.close();
+    assertThat(connection.isClosed(), is(true));
+  }
+
+  @Test public void testStatementExecuteQueryLocal() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecuteQuery(getLocalConnection(), false);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testPrepareExecuteQueryLocal() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecuteQuery(getLocalConnection(), true);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testInsertDrop() throws Exception {
+    final String t = AvaticaUtils.unique("TEST_TABLE2");
+    final String create =
+        String.format("create table if not exists %s ("
+            + "id int not null, "
+            + "msg varchar(3) not null)", t);
+    final String insert = String.format("insert into %s values(1, 'foo')", t);
+    Connection connection = ljs();
+    Statement statement = connection.createStatement();
+    statement.execute(create);
+
+    Statement stmt = connection.createStatement();
+    int count = stmt.executeUpdate(insert);
+    assertThat(count, is(1));
+    ResultSet resultSet = stmt.getResultSet();
+    assertThat(resultSet, nullValue());
+
+    PreparedStatement pstmt = connection.prepareStatement(insert);
+    boolean status = pstmt.execute();
+    assertThat(status, is(false));
+    int updateCount = pstmt.getUpdateCount();
+    assertThat(updateCount, is(1));
+  }
+
+  private void checkStatementExecuteQuery(Connection connection,
+      boolean prepare) throws SQLException {
+    final String sql = "select * from (\n"
+        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
+    final Statement statement;
+    final ResultSet resultSet;
+    final ParameterMetaData parameterMetaData;
+    if (prepare) {
+      final PreparedStatement ps = connection.prepareStatement(sql);
+      statement = ps;
+      parameterMetaData = ps.getParameterMetaData();
+      resultSet = ps.executeQuery();
+    } else {
+      statement = connection.createStatement();
+      parameterMetaData = null;
+      resultSet = statement.executeQuery(sql);
+    }
+    if (parameterMetaData != null) {
+      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
+    }
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("C1", metaData.getColumnName(1));
+    assertEquals("C2", metaData.getColumnName(2));
+    assertTrue(resultSet.next());
+    assertTrue(resultSet.next());
+    assertTrue(resultSet.next());
+    assertFalse(resultSet.next());
+    resultSet.close();
+    statement.close();
+    connection.close();
+  }
+
+  @Test public void testStatementExecuteLocal() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecute(getLocalConnection(), false);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testStatementExecuteFetch() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      // Creating a > 100 rows queries to enable fetch request
+      String sql = "select * from emp cross join emp";
+      checkExecuteFetch(getLocalConnection(), sql, false, 1);
+      // PreparedStatement needed an extra fetch, as the execute will
+      // trigger the 1st fetch. Where statement execute will execute direct
+      // with results back.
+      // 1 fetch, because execute did the first fetch
+      checkExecuteFetch(getLocalConnection(), sql, true, 1);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkExecuteFetch(Connection conn, String sql, boolean isPrepare,
+    int fetchCountMatch) throws SQLException {
+    final Statement exeStatement;
+    final ResultSet results;
+    getRequestInspection().getRequestLogger().enableAndClear();
+    if (isPrepare) {
+      PreparedStatement statement = conn.prepareStatement(sql);
+      exeStatement = statement;
+      results = statement.executeQuery();
+    } else {
+      Statement statement = conn.createStatement();
+      exeStatement = statement;
+      results = statement.executeQuery(sql);
+    }
+    int count = 0;
+    int fetchCount = 0;
+    while (results.next()) {
+      count++;
+    }
+    results.close();
+    exeStatement.close();
+    List<String[]> x = getRequestInspection().getRequestLogger().getAndDisable();
+    for (String[] pair : x) {
+      if (pair[0].contains("\"request\":\"fetch")) {
+        fetchCount++;
+      }
+    }
+    assertEquals(count, 196);
+    assertEquals(fetchCountMatch, fetchCount);
+  }
+
+  @Test public void testStatementExecuteLocalMaxRow() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecute(getLocalConnection(), false, 2);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testFetchSize() throws Exception {
+    Connection connection = ljs();
+
+    Statement statement = connection.createStatement();
+    statement.setFetchSize(101);
+    assertEquals(statement.getFetchSize(), 101);
+
+    PreparedStatement preparedStatement =
+        connection.prepareStatement("select * from (values (1, 'a')) as tbl1 (c1, c2)");
+    preparedStatement.setFetchSize(1);
+    assertEquals(preparedStatement.getFetchSize(), 1);
+  }
+
+  @Ignore("CALCITE-719: Refactor PreparedStatement to support setMaxRows")
+  @Test public void testStatementPrepareExecuteLocalMaxRow() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecute(getLocalConnection(), true, 2);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testPrepareExecuteLocal() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkStatementExecute(getLocalConnection(), true);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkStatementExecute(Connection connection,
+      boolean prepare) throws SQLException {
+    checkStatementExecute(connection, prepare, 0);
+  }
+  private void checkStatementExecute(Connection connection,
+      boolean prepare, int maxRowCount) throws SQLException {
+    final String sql = "select * from (\n"
+        + "  values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
+    final Statement statement;
+    final ResultSet resultSet;
+    final ParameterMetaData parameterMetaData;
+    if (prepare) {
+      final PreparedStatement ps = connection.prepareStatement(sql);
+      statement = ps;
+      ps.setMaxRows(maxRowCount);
+      parameterMetaData = ps.getParameterMetaData();
+      assertTrue(ps.execute());
+      resultSet = ps.getResultSet();
+    } else {
+      statement = connection.createStatement();
+      statement.setMaxRows(maxRowCount);
+      parameterMetaData = null;
+      assertTrue(statement.execute(sql));
+      resultSet = statement.getResultSet();
+    }
+    if (parameterMetaData != null) {
+      assertThat(parameterMetaData.getParameterCount(), equalTo(0));
+    }
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("C1", metaData.getColumnName(1));
+    assertEquals("C2", metaData.getColumnName(2));
+    for (int i = 0; i < maxRowCount || (maxRowCount == 0 && i < 3); i++) {
+      assertTrue(resultSet.next());
+    }
+    assertFalse(resultSet.next());
+    resultSet.close();
+    statement.close();
+    connection.close();
+  }
+
+  @Test public void testCreateInsertUpdateDrop() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    final String t = AvaticaUtils.unique("TEST_TABLE");
+    final String drop = String.format("drop table %s if exists", t);
+    final String create = String.format("create table %s("
+        + "id int not null, "
+        + "msg varchar(3) not null)",
+        t);
+    final String insert = String.format("insert into %s values(1, 'foo')", t);
+    final String update =
+        String.format("update %s set msg='bar' where id=1", t);
+    try (Connection connection = getLocalConnection();
+        Statement statement = connection.createStatement();
+        PreparedStatement pstmt = connection.prepareStatement("values 1")) {
+      // drop
+      assertFalse(statement.execute(drop));
+      assertEquals(0, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+      try {
+        final ResultSet rs = statement.executeQuery(drop);
+        fail("expected error, got " + rs);
+      } catch (SQLException e) {
+        assertThat(e.getMessage(),
+            equalTo("Statement did not return a result set"));
+      }
+      assertEquals(0, statement.executeUpdate(drop));
+      assertEquals(0, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+
+      // create
+      assertFalse(statement.execute(create));
+      assertEquals(0, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+      assertFalse(statement.execute(drop)); // tidy up
+      try {
+        final ResultSet rs = statement.executeQuery(create);
+        fail("expected error, got " + rs);
+      } catch (SQLException e) {
+        assertThat(e.getMessage(),
+            equalTo("Statement did not return a result set"));
+      }
+      assertFalse(statement.execute(drop)); // tidy up
+      assertEquals(0, statement.executeUpdate(create));
+      assertEquals(0, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+
+      // insert
+      assertFalse(statement.execute(insert));
+      assertEquals(1, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+      try {
+        final ResultSet rs = statement.executeQuery(insert);
+        fail("expected error, got " + rs);
+      } catch (SQLException e) {
+        assertThat(e.getMessage(),
+            equalTo("Statement did not return a result set"));
+      }
+      assertEquals(1, statement.executeUpdate(insert));
+      assertEquals(1, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+
+      // update
+      assertFalse(statement.execute(update));
+      assertEquals(3, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+      try {
+        final ResultSet rs = statement.executeQuery(update);
+        fail("expected error, got " + rs);
+      } catch (SQLException e) {
+        assertThat(e.getMessage(),
+            equalTo("Statement did not return a result set"));
+      }
+      assertEquals(3, statement.executeUpdate(update));
+      assertEquals(3, statement.getUpdateCount());
+      assertNull(statement.getResultSet());
+
+      final String[] messages = {
+        "Cannot call executeQuery(String) on prepared or callable statement",
+        "Cannot call execute(String) on prepared or callable statement",
+        "Cannot call executeUpdate(String) on prepared or callable statement",
+      };
+      for (String sql : new String[]{drop, create, insert, update}) {
+        for (int i = 0; i <= 2; i++) {
+          try {
+            Object o;
+            switch (i) {
+            case 0:
+              o = pstmt.executeQuery(sql);
+              break;
+            case 1:
+              o = pstmt.execute(sql);
+              break;
+            default:
+              o = pstmt.executeUpdate(sql);
+            }
+            fail("expected error, got " + o);
+          } catch (SQLException e) {
+            assertThat(e.getMessage(), equalTo(messages[i]));
+          }
+        }
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testTypeHandling() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      final String query = "select * from EMP";
+      try (Connection cannon = canon();
+          Connection underTest = getLocalConnection();
+          Statement s1 = cannon.createStatement();
+          Statement s2 = underTest.createStatement()) {
+        assertTrue(s1.execute(query));
+        assertTrue(s2.execute(query));
+        assertResultSetsEqual(s1, s2);
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void assertResultSetsEqual(Statement s1, Statement s2)
+      throws SQLException {
+    final TimeZone moscowTz = TimeZone.getTimeZone("Europe/Moscow");
+    final Calendar moscowCalendar = Calendar.getInstance(moscowTz);
+    final TimeZone alaskaTz = TimeZone.getTimeZone("America/Anchorage");
+    final Calendar alaskaCalendar = Calendar.getInstance(alaskaTz);
+    try (ResultSet rs1 = s1.getResultSet();
+        ResultSet rs2 = s2.getResultSet()) {
+      assertEquals(rs1.getMetaData().getColumnCount(),
+          rs2.getMetaData().getColumnCount());
+      int colCount = rs1.getMetaData().getColumnCount();
+      while (rs1.next() && rs2.next()) {
+        for (int i = 0; i < colCount; i++) {
+          Object o1 = rs1.getObject(i + 1);
+          Object o2 = rs2.getObject(i + 1);
+          if (o1 instanceof Integer && o2 instanceof Short) {
+            // Hsqldb returns Integer for short columns; we prefer Short
+            o1 = ((Number) o1).shortValue();
+          }
+          if (o1 instanceof Integer && o2 instanceof Byte) {
+            // Hsqldb returns Integer for tinyint columns; we prefer Byte
+            o1 = ((Number) o1).byteValue();
+          }
+          if (o1 instanceof Date) {
+            Date d1 = rs1.getDate(i + 1, moscowCalendar);
+            Date d2 = rs2.getDate(i + 1, moscowCalendar);
+            assertEquals(d1, d2);
+            d1 = rs1.getDate(i + 1, alaskaCalendar);
+            d2 = rs2.getDate(i + 1, alaskaCalendar);
+            assertEquals(d1, d2);
+            d1 = rs1.getDate(i + 1, null);
+            d2 = rs2.getDate(i + 1, null);
+            assertEquals(d1, d2);
+            d1 = rs1.getDate(i + 1);
+            d2 = rs2.getDate(i + 1);
+            assertEquals(d1, d2);
+          }
+          if (o1 instanceof Timestamp) {
+            Timestamp d1 = rs1.getTimestamp(i + 1, moscowCalendar);
+            Timestamp d2 = rs2.getTimestamp(i + 1, moscowCalendar);
+            assertEquals(d1, d2);
+            d1 = rs1.getTimestamp(i + 1, alaskaCalendar);
+            d2 = rs2.getTimestamp(i + 1, alaskaCalendar);
+            assertEquals(d1, d2);
+            d1 = rs1.getTimestamp(i + 1, null);
+            d2 = rs2.getTimestamp(i + 1, null);
+            assertEquals(d1, d2);
+            d1 = rs1.getTimestamp(i + 1);
+            d2 = rs2.getTimestamp(i + 1);
+            assertEquals(d1, d2);
+          }
+          assertEquals(o1, o2);
+        }
+      }
+      assertEquals(rs1.next(), rs2.next());
+    }
+  }
+
+  /** Callback to set parameters on each prepared statement before
+   * each is executed and the result sets compared. */
+  interface PreparedStatementFunction {
+    void apply(PreparedStatement s1, PreparedStatement s2)
+        throws SQLException;
+  }
+
+  /** Callback to execute some code against a connection. */
+  interface ConnectionFunction {
+    void apply(Connection c1) throws Exception;
+  }
+
+  @Test public void testSetParameter() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      checkSetParameter("select ? from (values 1)",
+          new PreparedStatementFunction() {
+            public void apply(PreparedStatement s1, PreparedStatement s2)
+                throws SQLException {
+              final Date d = new Date(1234567890);
+              s1.setDate(1, d);
+              s2.setDate(1, d);
+            }
+          });
+      checkSetParameter("select ? from (values 1)",
+          new PreparedStatementFunction() {
+            public void apply(PreparedStatement s1, PreparedStatement s2)
+                throws SQLException {
+              final Timestamp ts = new Timestamp(123456789012L);
+              s1.setTimestamp(1, ts);
+              s2.setTimestamp(1, ts);
+            }
+          });
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  void checkSetParameter(String query, PreparedStatementFunction fn)
+      throws SQLException {
+    try (Connection cannon = canon();
+         Connection underTest = ljs();
+         PreparedStatement s1 = cannon.prepareStatement(query);
+         PreparedStatement s2 = underTest.prepareStatement(query)) {
+      fn.apply(s1, s2);
+      assertTrue(s1.execute());
+      assertTrue(s2.execute());
+      assertResultSetsEqual(s1, s2);
+    }
+  }
+
+  @Test public void testStatementLifecycle() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection connection = (AvaticaConnection) getLocalConnection()) {
+      Map<Integer, AvaticaStatement> clientMap = connection.statementMap;
+      Cache<Integer, Object> serverMap = getLocalConnectionInternals()
+          .getRemoteStatementMap(connection);
+      // Other tests being run might leave statements in the cache.
+      // The lock guards against more statements being cached during the test.
+      serverMap.invalidateAll();
+      assertEquals(0, clientMap.size());
+      assertEquals(0, serverMap.size());
+      Statement stmt = connection.createStatement();
+      assertEquals(1, clientMap.size());
+      assertEquals(1, serverMap.size());
+      stmt.close();
+      assertEquals(0, clientMap.size());
+      assertEquals(0, serverMap.size());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testConnectionIsolation() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      Cache<String, Connection> connectionMap = getLocalConnectionInternals()
+          .getRemoteConnectionMap((AvaticaConnection) getLocalConnection());
+      // Other tests being run might leave connections in the cache.
+      // The lock guards against more connections being cached during the test.
+      connectionMap.invalidateAll();
+
+      final String sql = "select * from (values (1, 'a'))";
+      assertEquals("connection cache should start empty",
+          0, connectionMap.size());
+      Connection conn1 = getLocalConnection();
+      Connection conn2 = getLocalConnection();
+      assertEquals("we now have two connections open",
+          2, connectionMap.size());
+      PreparedStatement conn1stmt1 = conn1.prepareStatement(sql);
+      assertEquals(
+          "creating a statement does not cause new connection",
+          2, connectionMap.size());
+      PreparedStatement conn2stmt1 = conn2.prepareStatement(sql);
+      assertEquals(
+          "creating a statement does not cause new connection",
+          2, connectionMap.size());
+      AvaticaPreparedStatement s1 = (AvaticaPreparedStatement) conn1stmt1;
+      AvaticaPreparedStatement s2 = (AvaticaPreparedStatement) conn2stmt1;
+      assertFalse("connection id's should be unique",
+          s1.handle.connectionId.equalsIgnoreCase(s2.handle.connectionId));
+      conn2.close();
+      assertEquals("closing a connection closes the server-side connection",
+          1, connectionMap.size());
+      conn1.close();
+      assertEquals("closing a connection closes the server-side connection",
+          0, connectionMap.size());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testPrepareBindExecuteFetch() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      getRequestInspection().getRequestLogger().enableAndClear();
+      checkPrepareBindExecuteFetch(getLocalConnection());
+      List<String[]> x = getRequestInspection().getRequestLogger().getAndDisable();
+      for (String[] pair : x) {
+        System.out.println(pair[0] + "=" + pair[1]);
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkPrepareBindExecuteFetch(Connection connection)
+      throws SQLException {
+    final String sql = "select cast(? as integer) * 3 as c, 'x' as x\n"
+        + "from (values (1, 'a'))";
+    final PreparedStatement ps =
+        connection.prepareStatement(sql);
+    final ResultSetMetaData metaData = ps.getMetaData();
+    assertEquals(2, metaData.getColumnCount());
+    assertEquals("C", metaData.getColumnName(1));
+    assertEquals("X", metaData.getColumnName(2));
+    try {
+      final ResultSet resultSet = ps.executeQuery();
+      fail("expected error, got " + resultSet);
+    } catch (SQLException e) {
+      assertThat(e.getMessage(),
+          containsString("exception while executing query: unbound parameter"));
+    }
+
+    final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
+    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+
+    ps.setInt(1, 10);
+    final ResultSet resultSet = ps.executeQuery();
+    assertTrue(resultSet.next());
+    assertThat(resultSet.getInt(1), equalTo(30));
+    assertFalse(resultSet.next());
+    resultSet.close();
+
+    ps.setInt(1, 20);
+    final ResultSet resultSet2 = ps.executeQuery();
+    assertFalse(resultSet2.isClosed());
+    assertTrue(resultSet2.next());
+    assertThat(resultSet2.getInt(1), equalTo(60));
+    assertThat(resultSet2.wasNull(), is(false));
+    assertFalse(resultSet2.next());
+    resultSet2.close();
+
+    ps.setObject(1, null);
+    final ResultSet resultSet3 = ps.executeQuery();
+    assertTrue(resultSet3.next());
+    assertThat(resultSet3.getInt(1), equalTo(0));
+    assertThat(resultSet3.wasNull(), is(true));
+    assertFalse(resultSet3.next());
+    resultSet3.close();
+
+    ps.close();
+    connection.close();
+  }
+
+  @Test public void testPrepareBindExecuteFetchVarbinary() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      final Connection connection = getLocalConnection();
+      final String sql = "select x'de' || ? as c from (values (1, 'a'))";
+      final PreparedStatement ps =
+          connection.prepareStatement(sql);
+      final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
+      assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+
+      ps.setBytes(1, new byte[]{65, 0, 66});
+      final ResultSet resultSet = ps.executeQuery();
+      assertTrue(resultSet.next());
+      assertThat(resultSet.getBytes(1),
+          equalTo(new byte[]{(byte) 0xDE, 65, 0, 66}));
+      resultSet.close();
+      ps.close();
+      connection.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testPrepareBindExecuteFetchDate() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      eachConnection(
+          new ConnectionFunction() {
+            public void apply(Connection c1) throws Exception {
+              checkPrepareBindExecuteFetchDate(c1);
+            }
+          }, getLocalConnection());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkPrepareBindExecuteFetchDate(Connection connection) throws Exception {
+    final String sql0 =
+        "select cast(? as varchar(20)) as c\n"
+            + "from (values (1, 'a'))";
+    final String sql1 = "select ? + interval '2' day as c from (values (1, 'a'))";
+
+    final Date date = Date.valueOf("2015-04-08");
+    final long time = date.getTime();
+
+    PreparedStatement ps;
+    ParameterMetaData parameterMetaData;
+    ResultSet resultSet;
+
+    ps = connection.prepareStatement(sql0);
+    parameterMetaData = ps.getParameterMetaData();
+    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+    ps.setDate(1, date);
+    resultSet = ps.executeQuery();
+    assertThat(resultSet.next(), is(true));
+    assertThat(resultSet.getString(1), is("2015-04-08"));
+
+    ps.setTimestamp(1, new Timestamp(time));
+    resultSet = ps.executeQuery();
+    assertThat(resultSet.next(), is(true));
+    assertThat(resultSet.getString(1), is("2015-04-08 00:00:00.0"));
+
+    ps.setTime(1, new Time(time));
+    resultSet = ps.executeQuery();
+    assertThat(resultSet.next(), is(true));
+    assertThat(resultSet.getString(1), is("00:00:00"));
+    ps.close();
+
+    ps = connection.prepareStatement(sql1);
+    parameterMetaData = ps.getParameterMetaData();
+    assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+
+    ps.setDate(1, date);
+    resultSet = ps.executeQuery();
+    assertTrue(resultSet.next());
+    assertThat(resultSet.getDate(1),
+        equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
+    assertThat(resultSet.getTimestamp(1),
+        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
+
+    ps.setTimestamp(1, new Timestamp(time));
+    resultSet = ps.executeQuery();
+    assertTrue(resultSet.next());
+    assertThat(resultSet.getTimestamp(1),
+        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
+    assertThat(resultSet.getTimestamp(1),
+        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
+
+    ps.setObject(1, new java.util.Date(time));
+    resultSet = ps.executeQuery();
+    assertTrue(resultSet.next());
+    assertThat(resultSet.getDate(1),
+        equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
+    assertThat(resultSet.getTimestamp(1),
+        equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
+
+    resultSet.close();
+    ps.close();
+    connection.close();
+  }
+
+  @Test public void testDatabaseProperty() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      eachConnection(
+          new ConnectionFunction() {
+            public void apply(Connection c1) throws Exception {
+              checkDatabaseProperty(c1);
+            }
+          }, getLocalConnection());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkDatabaseProperty(Connection connection)
+      throws SQLException {
+    final DatabaseMetaData metaData = connection.getMetaData();
+    assertThat(metaData.getSQLKeywords(), equalTo(""));
+    assertThat(metaData.getStringFunctions(),
+        equalTo("ASCII,CHAR,CONCAT,DIFFERENCE,HEXTORAW,INSERT,LCASE,LEFT,"
+            + "LENGTH,LOCATE,LTRIM,RAWTOHEX,REPEAT,REPLACE,RIGHT,RTRIM,SOUNDEX,"
+            + "SPACE,SUBSTR,UCASE"));
+    assertThat(metaData.getDefaultTransactionIsolation(),
+        equalTo(Connection.TRANSACTION_READ_COMMITTED));
+  }
+
+  /**
+   * Factory that creates a service based on a local JDBC connection.
+   */
+  public static class LocalJdbcServiceFactory implements Service.Factory {
+    @Override public Service create(AvaticaConnection connection) {
+      try {
+        return new LocalService(
+            new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
+                CONNECTION_SPEC.password));
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /**
+   * Factory that creates a fully-local Protobuf service.
+   */
+  public static class QuasiRemotePBJdbcServiceFactory implements Service.Factory {
+    private static Service service;
+
+    private static RequestInspection requestInspection;
+
+    static void initService() {
+      try {
+        final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
+            CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+        final LocalService localService = new LocalService(jdbcMeta);
+        service = new LoggingLocalProtobufService(localService, new ProtobufTranslationImpl());
+        requestInspection = (RequestInspection) service;
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    @Override public Service create(AvaticaConnection connection) {
+      assert null != service;
+      return service;
+    }
+  }
+
+  /**
+   * Proxy that logs all requests passed into the {@link LocalProtobufService}.
+   */
+  public static class LoggingLocalProtobufService extends LocalProtobufService
+      implements RequestInspection {
+    private static final ThreadLocal<RequestLogger> THREAD_LOG =
+        new ThreadLocal<RequestLogger>() {
+          @Override protected RequestLogger initialValue() {
+            return new RequestLogger();
+          }
+        };
+
+    public LoggingLocalProtobufService(Service service, ProtobufTranslation translation) {
+      super(service, translation);
+    }
+
+    @Override public RequestLogger getRequestLogger() {
+      return THREAD_LOG.get();
+    }
+
+    @Override public Response _apply(Request request) {
+      final RequestLogger logger = THREAD_LOG.get();
+      try {
+        String jsonRequest = JsonService.MAPPER.writeValueAsString(request);
+        logger.requestStart(jsonRequest);
+
+        Response response = super._apply(request);
+
+        String jsonResponse = JsonService.MAPPER.writeValueAsString(response);
+        logger.requestEnd(jsonRequest, jsonResponse);
+
+        return response;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /**
+   * Factory that creates a service based on a local JDBC connection.
+   */
+  public static class QuasiRemoteJdbcServiceFactory implements Service.Factory {
+
+    /** a singleton instance that is recreated for each test */
+    private static Service service;
+
+    private static RequestInspection requestInspection;
+
+    static void initService() {
+      try {
+        final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
+            CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+        final LocalService localService = new LocalService(jdbcMeta);
+        service = new LoggingLocalJsonService(localService);
+        requestInspection = (RequestInspection) service;
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    @Override public Service create(AvaticaConnection connection) {
+      assert service != null;
+      return service;
+    }
+  }
+
+  /**
+   * Implementation that reaches into current connection state via reflection to extract certain
+   * internal information.
+   */
+  public static class QuasiRemoteJdbcServiceInternals implements ConnectionInternals {
+
+    @Override public Cache<Integer, Object>
+    getRemoteStatementMap(AvaticaConnection connection) throws Exception {
+      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
+      metaF.setAccessible(true);
+      Meta clientMeta = (Meta) metaF.get(connection);
+      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
+      remoteMetaServiceF.setAccessible(true);
+      LocalJsonService remoteMetaService = (LocalJsonService) remoteMetaServiceF.get(clientMeta);
+      // Use the explicitly class to avoid issues with LoggingLocalJsonService
+      Field remoteMetaServiceServiceF = LocalJsonService.class.getDeclaredField("service");
+      remoteMetaServiceServiceF.setAccessible(true);
+      LocalService remoteMetaServiceService =
+          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
+      Field remoteMetaServiceServiceMetaF =
+          remoteMetaServiceService.getClass().getDeclaredField("meta");
+      remoteMetaServiceServiceMetaF.setAccessible(true);
+      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
+      Field jdbcMetaStatementMapF = JdbcMeta.class.getDeclaredField("statementCache");
+      jdbcMetaStatementMapF.setAccessible(true);
+      //noinspection unchecked
+      @SuppressWarnings("unchecked")
+      Cache<Integer, Object> cache = (Cache<Integer, Object>) jdbcMetaStatementMapF.get(serverMeta);
+      return cache;
+    }
+
+    @Override public Cache<String, Connection>
+    getRemoteConnectionMap(AvaticaConnection connection) throws Exception {
+      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
+      metaF.setAccessible(true);
+      Meta clientMeta = (Meta) metaF.get(connection);
+      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
+      remoteMetaServiceF.setAccessible(true);
+      LocalJsonService remoteMetaService = (LocalJsonService) remoteMetaServiceF.get(clientMeta);
+      // Get the field explicitly off the correct class to avoid LocalLoggingJsonService.class
+      Field remoteMetaServiceServiceF = LocalJsonService.class.getDeclaredField("service");
+      remoteMetaServiceServiceF.setAccessible(true);
+      LocalService remoteMetaServiceService =
+          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
+      Field remoteMetaServiceServiceMetaF =
+          remoteMetaServiceService.getClass().getDeclaredField("meta");
+      remoteMetaServiceServiceMetaF.setAccessible(true);
+      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
+      Field jdbcMetaConnectionCacheF = JdbcMeta.class.getDeclaredField("connectionCache");
+      jdbcMetaConnectionCacheF.setAccessible(true);
+      //noinspection unchecked
+      @SuppressWarnings("unchecked")
+      Cache<String, Connection> cache =
+          (Cache<String, Connection>) jdbcMetaConnectionCacheF.get(serverMeta);
+      return cache;
+    }
+  }
+
+  /**
+   * Implementation that reaches into current connection state via reflection to extract certain
+   * internal information.
+   */
+  public static class QuasiRemoteProtobufJdbcServiceInternals implements ConnectionInternals {
+
+    @Override public Cache<Integer, Object>
+    getRemoteStatementMap(AvaticaConnection connection) throws Exception {
+      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
+      metaF.setAccessible(true);
+      Meta clientMeta = (Meta) metaF.get(connection);
+      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
+      remoteMetaServiceF.setAccessible(true);
+      LocalProtobufService remoteMetaService =
+          (LocalProtobufService) remoteMetaServiceF.get(clientMeta);
+      // Use the explicitly class to avoid issues with LoggingLocalJsonService
+      Field remoteMetaServiceServiceF = LocalProtobufService.class.getDeclaredField("service");
+      remoteMetaServiceServiceF.setAccessible(true);
+      LocalService remoteMetaServiceService =
+          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
+      Field remoteMetaServiceServiceMetaF =
+          remoteMetaServiceService.getClass().getDeclaredField("meta");
+      remoteMetaServiceServiceMetaF.setAccessible(true);
+      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
+      Field jdbcMetaStatementMapF = JdbcMeta.class.getDeclaredField("statementCache");
+      jdbcMetaStatementMapF.setAccessible(true);
+      //noinspection unchecked
+      @SuppressWarnings("unchecked")
+      Cache<Integer, Object> cache = (Cache<Integer, Object>) jdbcMetaStatementMapF.get(serverMeta);
+      return cache;
+    }
+
+    @Override public Cache<String, Connection>
+    getRemoteConnectionMap(AvaticaConnection connection) throws Exception {
+      Field metaF = AvaticaConnection.class.getDeclaredField("meta");
+      metaF.setAccessible(true);
+      Meta clientMeta = (Meta) metaF.get(connection);
+      Field remoteMetaServiceF = clientMeta.getClass().getDeclaredField("service");
+      remoteMetaServiceF.setAccessible(true);
+      LocalProtobufService remoteMetaService =
+          (LocalProtobufService) remoteMetaServiceF.get(clientMeta);
+      // Get the field explicitly off the correct class to avoid LocalLoggingJsonService.class
+      Field remoteMetaServiceServiceF = LocalProtobufService.class.getDeclaredField("service");
+      remoteMetaServiceServiceF.setAccessible(true);
+      LocalService remoteMetaServiceService =
+          (LocalService) remoteMetaServiceServiceF.get(remoteMetaService);
+      Field remoteMetaServiceServiceMetaF =
+          remoteMetaServiceService.getClass().getDeclaredField("meta");
+      remoteMetaServiceServiceMetaF.setAccessible(true);
+      JdbcMeta serverMeta = (JdbcMeta) remoteMetaServiceServiceMetaF.get(remoteMetaServiceService);
+      Field jdbcMetaConnectionCacheF = JdbcMeta.class.getDeclaredField("connectionCache");
+      jdbcMetaConnectionCacheF.setAccessible(true);
+      //noinspection unchecked
+      @SuppressWarnings("unchecked")
+      Cache<String, Connection> cache =
+          (Cache<String, Connection>) jdbcMetaConnectionCacheF.get(serverMeta);
+      return cache;
+    }
+  }
+
+  /**
+   * Provides access to a log of requests.
+   */
+  interface RequestInspection {
+    RequestLogger getRequestLogger();
+  }
+
+  /** Extension to {@link LocalJsonService} that writes requests and responses
+   * into a thread-local. */
+  private static class LoggingLocalJsonService extends LocalJsonService
+      implements RequestInspection {
+    private static final ThreadLocal<RequestLogger> THREAD_LOG =
+        new ThreadLocal<RequestLogger>() {
+          @Override protected RequestLogger initialValue() {
+            return new RequestLogger();
+          }
+        };
+
+    public LoggingLocalJsonService(LocalService localService) {
+      super(localService);
+    }
+
+    @Override public String apply(String request) {
+      final RequestLogger logger = THREAD_LOG.get();
+      logger.requestStart(request);
+      final String response = super.apply(request);
+      logger.requestEnd(request, response);
+      return response;
+    }
+
+    @Override public RequestLogger getRequestLogger() {
+      return THREAD_LOG.get();
+    }
+  }
+
+  /** Logs request and response strings if enabled. */
+  private static class RequestLogger {
+    final List<String[]> requestResponses = new ArrayList<>();
+    boolean enabled;
+
+    void enableAndClear() {
+      enabled = true;
+      requestResponses.clear();
+    }
+
+    void requestStart(String request) {
+      if (enabled) {
+        requestResponses.add(new String[]{request, null});
+      }
+    }
+
+    void requestEnd(String request, String response) {
+      if (enabled) {
+        String[] last = requestResponses.get(requestResponses.size() - 1);
+        if (!request.equals(last[0])) {
+          throw new AssertionError();
+        }
+        last[1] = response;
+      }
+    }
+
+    List<String[]> getAndDisable() {
+      enabled = false;
+      return new ArrayList<>(requestResponses);
+    }
+  }
+}
+
+// End RemoteDriverTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
new file mode 100644
index 0000000..48887b4
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.jdbc;
+
+import org.junit.Test;
+
+import java.sql.SQLException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit tests for {@link JdbcMeta}.
+ */
+public class JdbcMetaTest {
+
+  @Test public void testExceptionPropagation() throws SQLException {
+    JdbcMeta meta = new JdbcMeta("url");
+    final Throwable e = new Exception();
+    final RuntimeException rte;
+    try {
+      meta.propagate(e);
+      fail("Expected an exception to be thrown");
+    } catch (RuntimeException caughtException) {
+      rte = caughtException;
+      assertThat(rte.getCause(), is(e));
+    }
+  }
+}
+
+// End JdbcMetaTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
new file mode 100644
index 0000000..2984692
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.jdbc;
+
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.sql.ResultSet;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Statement;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests covering {@link StatementInfo}.
+ */
+public class StatementInfoTest {
+
+  @Test
+  public void testLargeOffsets() throws Exception {
+    Statement stmt = Mockito.mock(Statement.class);
+    ResultSet results = Mockito.mock(ResultSet.class);
+
+    StatementInfo info = new StatementInfo(stmt);
+
+    Mockito.when(results.relative(Integer.MAX_VALUE)).thenReturn(true, true);
+    Mockito.when(results.relative(1)).thenReturn(true);
+
+    long offset = 1L + Integer.MAX_VALUE + Integer.MAX_VALUE;
+    assertTrue(info.advanceResultSetToOffset(results, offset));
+
+    InOrder inOrder = Mockito.inOrder(results);
+
+    inOrder.verify(results, Mockito.times(2)).relative(Integer.MAX_VALUE);
+    inOrder.verify(results).relative(1);
+
+    assertEquals(offset, info.getPosition());
+  }
+
+  @Test
+  public void testNextUpdatesPosition() throws Exception {
+    Statement stmt = Mockito.mock(Statement.class);
+    ResultSet results = Mockito.mock(ResultSet.class);
+
+    StatementInfo info = new StatementInfo(stmt);
+    info.setResultSet(results);
+
+    Mockito.when(results.next()).thenReturn(true, true, true, false);
+
+    for (int i = 0; i < 3; i++) {
+      assertTrue(i + "th call of next() should return true", info.next());
+      assertEquals(info.getPosition(), i + 1);
+    }
+
+    assertFalse("Expected last next() to return false", info.next());
+    assertEquals(info.getPosition(), 4L);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testNoMovement() throws Exception {
+    Statement stmt = Mockito.mock(Statement.class);
+    ResultSet results = Mockito.mock(ResultSet.class);
+
+    StatementInfo info = new StatementInfo(stmt);
+    info.setPosition(500);
+
+    info.advanceResultSetToOffset(results, 400);
+  }
+
+  @Test public void testResultSetGetter() throws Exception {
+    Statement stmt = Mockito.mock(Statement.class);
+    ResultSet results = Mockito.mock(ResultSet.class);
+
+    StatementInfo info = new StatementInfo(stmt);
+
+    assertFalse("ResultSet should not be initialized", info.isResultSetInitialized());
+    assertNull("ResultSet should be null", info.getResultSet());
+
+    info.setResultSet(results);
+
+    assertTrue("ResultSet should be initialized", info.isResultSetInitialized());
+    assertEquals(results, info.getResultSet());
+  }
+
+  @Test public void testCheckPositionAfterFailedRelative() throws Exception {
+    Statement stmt = Mockito.mock(Statement.class);
+    ResultSet results = Mockito.mock(ResultSet.class);
+    final long offset = 500;
+
+    StatementInfo info = new StatementInfo(stmt);
+    info.setResultSet(results);
+
+    // relative() doesn't work
+    Mockito.when(results.relative((int) offset)).thenThrow(new SQLFeatureNotSupportedException());
+    // Should fall back to next(), 500 calls to next, 1 false
+    Mockito.when(results.next()).then(new Answer<Boolean>() {
+      private long invocations = 0;
+
+      // Return true until 500, false after.
+      @Override public Boolean answer(InvocationOnMock invocation) throws Throwable {
+        invocations++;
+        if (invocations >= offset) {
+          return false;
+        }
+        return true;
+      }
+    });
+
+    info.advanceResultSetToOffset(results, offset);
+
+    // Verify correct position
+    assertEquals(offset, info.getPosition());
+    // Make sure that we actually advanced the result set
+    Mockito.verify(results, Mockito.times(500)).next();
+  }
+}
+
+// End StatementInfoTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
new file mode 100644
index 0000000..6f4c51e
--- /dev/null
+++ b/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
@@ -0,0 +1,396 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.ConnectionConfig;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.ConnectionSpec;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.jdbc.JdbcMeta;
+import org.apache.calcite.avatica.server.AvaticaJsonHandler;
+import org.apache.calcite.avatica.server.HttpServer;
+import org.apache.calcite.avatica.server.Main;
+import org.apache.calcite.avatica.server.Main.HandlerFactory;
+
+import com.google.common.cache.Cache;
+
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests that verify that the Driver still functions when requests are randomly bounced between
+ * more than one server.
+ */
+public class AlternatingRemoteMetaTest {
+  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
+
+  private static String url;
+
+  static {
+    try {
+      // Force DriverManager initialization before we hit AlternatingDriver->Driver.<clinit>
+      // Otherwise Driver.<clinit> -> DriverManager.registerDriver -> scan service provider files
+      // causes a deadlock; see [CALCITE-1060]
+      DriverManager.getDrivers();
+      DriverManager.registerDriver(new AlternatingDriver());
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  // Keep a reference to the servers we start to clean them up after
+  private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
+
+  /** Factory that provides a {@link JdbcMeta}. */
+  public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
+
+    private static JdbcMeta instance = null;
+
+    private static JdbcMeta getInstance() {
+      if (instance == null) {
+        try {
+          instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
+              CONNECTION_SPEC.password);
+        } catch (SQLException e) {
+          throw new RuntimeException(e);
+        }
+      }
+      return instance;
+    }
+
+    @Override public Meta create(List<String> args) {
+      return getInstance();
+    }
+  }
+
+  /**
+   * AvaticaHttpClient implementation that randomly chooses among the provided URLs.
+   */
+  public static class AlternatingAvaticaHttpClient implements AvaticaHttpClient {
+    private final List<AvaticaHttpClientImpl> clients;
+    private final Random r = new Random();
+
+    public AlternatingAvaticaHttpClient(List<URL> urls) {
+      //System.out.println("Constructing clients for " + urls);
+      clients = new ArrayList<>(urls.size());
+      for (URL url : urls) {
+        clients.add(new AvaticaHttpClientImpl(url));
+      }
+    }
+
+    public byte[] send(byte[] request) {
+      AvaticaHttpClientImpl client = clients.get(r.nextInt(clients.size()));
+      //System.out.println("URL: " + client.url);
+      return client.send(request);
+    }
+
+  }
+
+  /**
+   * Driver implementation {@link AlternatingAvaticaHttpClient}.
+   */
+  public static class AlternatingDriver extends Driver {
+
+    public static final String PREFIX = "jdbc:avatica:remote-alternating:";
+
+    @Override protected String getConnectStringPrefix() {
+      return PREFIX;
+    }
+
+    @Override public Meta createMeta(AvaticaConnection connection) {
+      final ConnectionConfig config = connection.config();
+      return new RemoteMeta(connection, new RemoteService(getHttpClient(connection, config)));
+    }
+
+    @Override AvaticaHttpClient getHttpClient(AvaticaConnection connection,
+        ConnectionConfig config) {
+      return new AlternatingAvaticaHttpClient(parseUrls(config.url()));
+    }
+
+    List<URL> parseUrls(String urlStr) {
+      final List<URL> urls = new ArrayList<>();
+      final char comma = ',';
+
+      int prevIndex = 0;
+      int index = urlStr.indexOf(comma);
+      if (-1 == index) {
+        try {
+          return Collections.singletonList(new URL(urlStr));
+        } catch (MalformedURLException e) {
+          throw new RuntimeException(e);
+        }
+      }
+
+      // String split w/o regex
+      while (-1 != index) {
+        try {
+          urls.add(new URL(urlStr.substring(prevIndex, index)));
+        } catch (MalformedURLException e) {
+          throw new RuntimeException(e);
+        }
+        prevIndex = index + 1;
+        index = urlStr.indexOf(comma, prevIndex);
+      }
+
+      // Get the last one
+      try {
+        urls.add(new URL(urlStr.substring(prevIndex)));
+      } catch (MalformedURLException e) {
+        throw new RuntimeException(e);
+      }
+
+      return urls;
+    }
+
+  }
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    final String[] mainArgs = new String[] { FullyRemoteJdbcMetaFactory.class.getName() };
+
+    // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
+
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < 2; i++) {
+      if (sb.length() > 0) {
+        sb.append(",");
+      }
+      HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
+        @Override public AbstractHandler createHandler(Service service) {
+          return new AvaticaJsonHandler(service);
+        }
+      });
+      ACTIVE_SERVERS.add(jsonServer);
+      sb.append("http://localhost:").append(jsonServer.getPort());
+    }
+
+    url = AlternatingDriver.PREFIX + "url=" + sb.toString();
+  }
+
+  @AfterClass public static void afterClass() throws Exception {
+    for (HttpServer server : ACTIVE_SERVERS) {
+      if (server != null) {
+        server.stop();
+      }
+    }
+  }
+
+  private static Meta getMeta(AvaticaConnection conn) throws Exception {
+    Field f = AvaticaConnection.class.getDeclaredField("meta");
+    f.setAccessible(true);
+    return (Meta) f.get(conn);
+  }
+
+  private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
+    final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
+    Method m =
+        AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
+            AvaticaStatement.class, String.class, long.class);
+    m.setAccessible(true);
+    return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
+  }
+
+  private static Connection getConnection(JdbcMeta m, String id) throws Exception {
+    Field f = JdbcMeta.class.getDeclaredField("connectionCache");
+    f.setAccessible(true);
+    //noinspection unchecked
+    Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
+    return connectionCache.getIfPresent(id);
+  }
+
+  @Test public void testRemoteExecuteMaxRowCount() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      final AvaticaStatement statement = conn.createStatement();
+      prepareAndExecuteInternal(conn, statement,
+        "select * from (values ('a', 1), ('b', 2))", 0);
+      ResultSet rs = statement.getResultSet();
+      int count = 0;
+      while (rs.next()) {
+        count++;
+      }
+      assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
+      assertEquals("Check result set meta is still there",
+        rs.getMetaData().getColumnCount(), 2);
+      rs.close();
+      statement.close();
+      conn.close();
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
+   * HTTP error 413 when sending a long string to the Avatica server</a>. */
+  @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      // Before the bug was fixed, a value over 7998 caused an HTTP 413.
+      // 16K bytes, I guess.
+      checkLargeQuery(8);
+      checkLargeQuery(240);
+      checkLargeQuery(8000);
+      checkLargeQuery(240000);
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void checkLargeQuery(int n) throws Exception {
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      final AvaticaStatement statement = conn.createStatement();
+      final String frenchDisko = "It said human existence is pointless\n"
+          + "As acts of rebellious solidarity\n"
+          + "Can bring sense in this world\n"
+          + "La resistance!\n";
+      final String sql = "select '"
+          + longString(frenchDisko, n)
+          + "' as s from (values 'x')";
+      prepareAndExecuteInternal(conn, statement, sql, -1);
+      ResultSet rs = statement.getResultSet();
+      int count = 0;
+      while (rs.next()) {
+        count++;
+      }
+      assertThat(count, is(1));
+      rs.close();
+      statement.close();
+      conn.close();
+    }
+  }
+
+  /** Creates a string of exactly {@code length} characters by concatenating
+   * {@code fragment}. */
+  private static String longString(String fragment, int length) {
+    assert fragment.length() > 0;
+    final StringBuilder buf = new StringBuilder();
+    while (buf.length() < length) {
+      buf.append(fragment);
+    }
+    buf.setLength(length);
+    return buf.toString();
+  }
+
+  @Test public void testRemoteConnectionProperties() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
+      String id = conn.id;
+      final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
+      assertFalse("remote connection map should start ignorant", m.containsKey(id));
+      // force creating a connection object on the remote side.
+      try (final Statement stmt = conn.createStatement()) {
+        assertTrue("creating a statement starts a local object.", m.containsKey(id));
+        assertTrue(stmt.execute("select count(1) from EMP"));
+      }
+      Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
+      final boolean defaultRO = remoteConn.isReadOnly();
+      final boolean defaultAutoCommit = remoteConn.getAutoCommit();
+      final String defaultCatalog = remoteConn.getCatalog();
+      final String defaultSchema = remoteConn.getSchema();
+      conn.setReadOnly(!defaultRO);
+      assertTrue("local changes dirty local state", m.get(id).isDirty());
+      assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
+      conn.setAutoCommit(!defaultAutoCommit);
+      assertEquals("remote connection has not been touched",
+          defaultAutoCommit, remoteConn.getAutoCommit());
+
+      // further interaction with the connection will force a sync
+      try (final Statement stmt = conn.createStatement()) {
+        assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
+        assertFalse("local values should be clean", m.get(id).isDirty());
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testQuery() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
+        Statement statement = conn.createStatement()) {
+      assertFalse(statement.execute("SET SCHEMA \"SCOTT\""));
+      assertFalse(
+          statement.execute(
+              "CREATE TABLE \"FOO\"(\"KEY\" INTEGER NOT NULL, \"VALUE\" VARCHAR(10))"));
+      assertFalse(statement.execute("SET TABLE \"FOO\" READONLY FALSE"));
+
+      final int numRecords = 1000;
+      for (int i = 0; i < numRecords; i++) {
+        assertFalse(statement.execute("INSERT INTO \"FOO\" VALUES(" + i + ", '" + i + "')"));
+      }
+
+      // Make sure all the records are there that we expect
+      ResultSet results = statement.executeQuery("SELECT count(KEY) FROM FOO");
+      assertTrue(results.next());
+      assertEquals(1000, results.getInt(1));
+      assertFalse(results.next());
+
+      results = statement.executeQuery("SELECT KEY, VALUE FROM FOO ORDER BY KEY ASC");
+      for (int i = 0; i < numRecords; i++) {
+        assertTrue(results.next());
+        assertEquals(i, results.getInt(1));
+        assertEquals(Integer.toString(i), results.getString(2));
+      }
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  @Test public void testSingleUrlParsing() throws Exception {
+    AlternatingDriver d = new AlternatingDriver();
+    List<URL> urls = d.parseUrls("http://localhost:1234");
+    assertEquals(Arrays.asList(new URL("http://localhost:1234")), urls);
+  }
+
+  @Test public void testMultipleUrlParsing() throws Exception {
+    AlternatingDriver d = new AlternatingDriver();
+    List<URL> urls = d.parseUrls("http://localhost:1234,http://localhost:2345,"
+        + "http://localhost:3456");
+    List<URL> expectedUrls = Arrays.asList(new URL("http://localhost:1234"),
+        new URL("http://localhost:2345"), new URL("http://localhost:3456"));
+    assertEquals(expectedUrls, urls);
+  }
+}
+
+// End AlternatingRemoteMetaTest.java


[29/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
new file mode 100644
index 0000000..b037196
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardCounterTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Counter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link DropwizardCounter}.
+ */
+public class DropwizardCounterTest {
+
+  private Counter counter;
+
+  @Before public void setup() {
+    this.counter = new Counter();
+  }
+
+  @Test public void testCounting() {
+    DropwizardCounter dwCounter = new DropwizardCounter(counter);
+
+    dwCounter.increment();
+    assertEquals(1L, counter.getCount());
+    dwCounter.increment();
+    assertEquals(2L, counter.getCount());
+    dwCounter.increment(2L);
+    assertEquals(4L, counter.getCount());
+    dwCounter.increment(-1L);
+    assertEquals(3L, counter.getCount());
+
+    dwCounter.decrement();
+    assertEquals(2L, counter.getCount());
+    dwCounter.decrement();
+    assertEquals(1L, counter.getCount());
+    dwCounter.decrement(4L);
+    assertEquals(-3L, counter.getCount());
+    dwCounter.decrement(-3L);
+    assertEquals(0L, counter.getCount());
+  }
+
+}
+
+// End DropwizardCounterTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
new file mode 100644
index 0000000..ed78a58
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardGaugeTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.Gauge;
+
+import org.junit.Test;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link DropwizardGauge}.
+ */
+public class DropwizardGaugeTest {
+
+  @Test public void test() {
+    SimpleGauge gauge = new SimpleGauge();
+    DropwizardGauge<Long> dwGauge = new DropwizardGauge<>(gauge);
+
+    assertEquals(gauge.getValue(), dwGauge.getValue());
+
+    gauge.setValue(1000L);
+
+    assertEquals(gauge.getValue(), dwGauge.getValue());
+  }
+
+  /**
+   * Gauge implementation with a setter.
+   */
+  private static class SimpleGauge implements Gauge<Long> {
+
+    private final AtomicLong value = new AtomicLong(0L);
+
+    @Override public Long getValue() {
+      return this.value.get();
+    }
+
+    public void setValue(long value) {
+      this.value.set(value);
+    }
+  }
+}
+
+// End DropwizardGaugeTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
new file mode 100644
index 0000000..25ec5c0
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardHistogramTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Histogram;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Test class for {@link DropwizardHistogram}.
+ */
+public class DropwizardHistogramTest {
+
+  private Histogram histogram;
+
+  @Before public void setup() {
+    this.histogram = Mockito.mock(Histogram.class);
+  }
+
+  @Test public void test() {
+    DropwizardHistogram dwHistogram = new DropwizardHistogram(histogram);
+
+    dwHistogram.update(10);
+
+    dwHistogram.update(100L);
+
+    Mockito.verify(histogram).update(10);
+    Mockito.verify(histogram).update(100L);
+  }
+
+}
+
+// End DropwizardHistogramTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
new file mode 100644
index 0000000..c76c7e0
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMeterTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import com.codahale.metrics.Meter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Test class for {@link DropwizardMeter}.
+ */
+public class DropwizardMeterTest {
+
+  private Meter meter;
+
+  @Before public void setup() {
+    this.meter = Mockito.mock(Meter.class);
+  }
+
+  @Test public void test() {
+    DropwizardMeter dwMeter = new DropwizardMeter(this.meter);
+
+    dwMeter.mark();
+    dwMeter.mark(10L);
+    dwMeter.mark();
+    dwMeter.mark();
+
+    Mockito.verify(meter, Mockito.times(3)).mark();
+    Mockito.verify(meter).mark(10L);
+  }
+
+}
+
+// End DropwizardMeterTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
new file mode 100644
index 0000000..332c6e0
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemFactoryTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Test class for {@link DropwizardMetricsSystemFactory}.
+ */
+public class DropwizardMetricsSystemFactoryTest {
+
+  private DropwizardMetricsSystemFactory factory;
+
+  @Before public void setup() {
+    factory = new DropwizardMetricsSystemFactory();
+  }
+
+  @Test(expected = IllegalStateException.class) public void testNullConfigurationFails() {
+    factory.create(null);
+  }
+
+  @Test(expected = IllegalStateException.class) public void testUnhandledConfigurationType() {
+    factory.create(NoopMetricsSystemConfiguration.getInstance());
+  }
+
+  @Test public void testHandledConfigurationType() {
+    DropwizardMetricsSystem metrics =
+        factory.create(new DropwizardMetricsSystemConfiguration(new MetricRegistry()));
+    assertNotNull("Expected DropwizardMetricsSystem to be non-null", metrics);
+  }
+}
+
+// End DropwizardMetricsSystemFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
new file mode 100644
index 0000000..7eeec3b
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardMetricsSystemTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.Counter;
+import org.apache.calcite.avatica.metrics.Gauge;
+import org.apache.calcite.avatica.metrics.Histogram;
+import org.apache.calcite.avatica.metrics.Meter;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link DropwizardMetricsSystem}.
+ */
+public class DropwizardMetricsSystemTest {
+
+  private MetricRegistry mockRegistry;
+  private DropwizardMetricsSystem metrics;
+
+  @Before public void setup() {
+    mockRegistry = mock(MetricRegistry.class);
+    metrics = new DropwizardMetricsSystem(mockRegistry);
+  }
+
+  @Test public void testGauge() {
+    final long gaugeValue = 42L;
+    final String name = "gauge";
+    metrics.register(name, new Gauge<Long>() {
+      @Override public Long getValue() {
+        return gaugeValue;
+      }
+    });
+
+    verify(mockRegistry, times(1)).register(eq(name), any(com.codahale.metrics.Gauge.class));
+  }
+
+  @Test public void testMeter() {
+    final String name = "meter";
+    final com.codahale.metrics.Meter mockMeter = mock(com.codahale.metrics.Meter.class);
+
+    when(mockRegistry.meter(name)).thenReturn(mockMeter);
+
+    Meter meter = metrics.getMeter(name);
+
+    final long count = 5;
+    meter.mark(count);
+
+    verify(mockMeter, times(1)).mark(count);
+
+    meter.mark();
+
+    verify(mockMeter, times(1)).mark();
+  }
+
+  @Test public void testHistogram() {
+    final String name = "histogram";
+    final com.codahale.metrics.Histogram mockHistogram = mock(com.codahale.metrics.Histogram.class);
+
+    when(mockRegistry.histogram(name)).thenReturn(mockHistogram);
+
+    Histogram histogram = metrics.getHistogram(name);
+
+    long[] long_values = new long[] {1L, 5L, 15L, 30L, 60L};
+    for (long value : long_values) {
+      histogram.update(value);
+    }
+
+    for (long value : long_values) {
+      verify(mockHistogram).update(value);
+    }
+
+    int[] int_values = new int[] {2, 6, 16, 31, 61};
+    for (int value : int_values) {
+      histogram.update(value);
+    }
+
+    for (int value : int_values) {
+      verify(mockHistogram).update(value);
+    }
+  }
+
+  @Test public void testCounter() {
+    final String name = "counter";
+    final com.codahale.metrics.Counter mockCounter = mock(com.codahale.metrics.Counter.class);
+
+    when(mockRegistry.counter(name)).thenReturn(mockCounter);
+
+    Counter counter = metrics.getCounter(name);
+
+    long[] updates = new long[] {1L, 5L, -2L, 4L, -8L, 0};
+    for (long update : updates) {
+      if (update < 0) {
+        counter.decrement(Math.abs(update));
+      } else {
+        counter.increment(update);
+      }
+    }
+
+    for (long update : updates) {
+      if (update < 0) {
+        verify(mockCounter).dec(Math.abs(update));
+      } else {
+        verify(mockCounter).inc(update);
+      }
+    }
+
+    int numSingleUpdates = 3;
+    for (int i = 0; i < numSingleUpdates; i++) {
+      counter.increment();
+      counter.decrement();
+    }
+
+    verify(mockCounter, times(numSingleUpdates)).inc();
+    verify(mockCounter, times(numSingleUpdates)).dec();
+  }
+
+  @Test public void testTimer() {
+    final String name = "timer";
+    final com.codahale.metrics.Timer mockTimer = mock(com.codahale.metrics.Timer.class);
+    final com.codahale.metrics.Timer.Context mockContext =
+        mock(com.codahale.metrics.Timer.Context.class);
+
+    when(mockRegistry.timer(name)).thenReturn(mockTimer);
+    when(mockTimer.time()).thenReturn(mockContext);
+
+    Timer timer = metrics.getTimer(name);
+    Context context = timer.start();
+    context.close();
+
+    verify(mockTimer).time();
+    verify(mockContext).stop();
+  }
+}
+
+// End DropwizardMetricsSystemTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
new file mode 100644
index 0000000..536d935
--- /dev/null
+++ b/avatica/metrics-dropwizardmetrics3/src/test/java/org/apache/calcite/avatica/metrics/dropwizard3/DropwizardTimerTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.metrics.dropwizard3;
+
+import org.apache.calcite.avatica.metrics.dropwizard3.DropwizardTimer.DropwizardContext;
+
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.Timer.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Test class for {@link DropwizardTimer}
+ */
+public class DropwizardTimerTest {
+
+  private Timer timer;
+  private Context context;
+
+  @Before public void setup() {
+    this.timer = Mockito.mock(Timer.class);
+    this.context = Mockito.mock(Context.class);
+  }
+
+  @Test public void test() {
+    DropwizardTimer dwTimer = new DropwizardTimer(timer);
+
+    Mockito.when(timer.time()).thenReturn(context);
+
+    DropwizardContext dwContext = dwTimer.start();
+
+    dwContext.close();
+
+    Mockito.verify(timer).time();
+    Mockito.verify(context).stop();
+  }
+
+}
+
+// End DropwizardTimerTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/metrics/pom.xml b/avatica/metrics/pom.xml
new file mode 100644
index 0000000..1b8ad66
--- /dev/null
+++ b/avatica/metrics/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica-parent</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>calcite-avatica-metrics</artifactId>
+  <packaging>jar</packaging>
+  <name>Calcite Avatica Metrics</name>
+  <description>A library designed to abstract away any required dependency on a metrics library</description>
+
+  <properties>
+    <top.dir>${project.basedir}/..</top.dir>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <versionRange>[2.12.1,)</versionRange>
+                    <goals>
+                      <goal>check</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <!-- configurations do not cascade, so all of the definition from
+             ../pom.xml:build:plugin-management:plugins:plugin must be repeated in child poms -->
+        <executions>
+          <execution>
+            <id>analyze</id>
+            <goals>
+              <goal>analyze-only</goal>
+            </goals>
+            <configuration>
+              <failOnWarning>true</failOnWarning>
+              <!-- ignore "unused but declared" warnings -->
+              <ignoredUnusedDeclaredDependencies>
+                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+              </ignoredUnusedDeclaredDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Parent module has the same plugin and does the work of
+           generating -sources.jar for each project. But without the
+           plugin declared here, IDEs don't know the sources are
+           available. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>non-root-resources</id>
+            <goals>
+              <goal>process</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
new file mode 100644
index 0000000..87aec1b
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Counter.java
@@ -0,0 +1,49 @@
+/*
+ * 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.metrics;
+
+/**
+ * A mutable number.
+ */
+public interface Counter {
+
+  /**
+   * Increment {@code this} by 1.
+   */
+  void increment();
+
+  /**
+   * Increment {@code this} by {@code n}.
+   *
+   * @param n The amount to increment.
+   */
+  void increment(long n);
+
+  /**
+   * Decrement {@code this} by 1.
+   */
+  void decrement();
+
+  /**
+   * Decrement {@code this} by {@code n}.
+   *
+   * @param n The amount to decrement.
+   */
+  void decrement(long n);
+}
+
+// End Counter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
new file mode 100644
index 0000000..6313a9a
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Gauge.java
@@ -0,0 +1,30 @@
+/*
+ * 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.metrics;
+
+/**
+ * A metrics which measures a discrete value.
+ *
+ * @param <T> The value of the Gauge.
+ */
+public interface Gauge<T> extends Metric {
+
+  T getValue();
+
+}
+
+// End Gauge.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
new file mode 100644
index 0000000..633af78
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Histogram.java
@@ -0,0 +1,40 @@
+/*
+ * 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.metrics;
+
+/**
+ * A metric which measures the distribution of values.
+ */
+public interface Histogram extends Metric {
+
+  /**
+   * Adds a new value to the distribution.
+   *
+   * @param value The value to add
+   */
+  void update(int value);
+
+  /**
+   * Adds a new value to the distribution.
+   *
+   * @param value The value to add
+   */
+  void update(long value);
+
+}
+
+// End Histogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
new file mode 100644
index 0000000..b27f023
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Meter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.metrics;
+
+/**
+ * A metric which measure the rate at which some operation is invoked.
+ */
+public interface Meter extends Metric {
+
+  /**
+   * Records one occurrence.
+   */
+  void mark();
+
+  /**
+   * Records {@code events} occurrences.
+   *
+   * @param events Number of occurrences to record.
+   */
+  void mark(long events);
+
+}
+
+// End Meter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
new file mode 100644
index 0000000..fe133da
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Metric.java
@@ -0,0 +1,26 @@
+/*
+ * 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.metrics;
+
+/**
+ * Parent interface for all metrics.
+ */
+public interface Metric {
+
+}
+
+// End Metric.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
new file mode 100644
index 0000000..0d1cb4b
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystem.java
@@ -0,0 +1,68 @@
+/*
+ * 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.metrics;
+
+/**
+ * General purpose factory for creating various metrics. Modeled off of the Dropwizard Metrics API.
+ */
+public interface MetricsSystem {
+
+  /**
+   * Get or construct a {@link Timer} used to measure durations and report rates.
+   *
+   * @param name The name of the Timer.
+   * @return An instance of {@link Timer}.
+   */
+  Timer getTimer(String name);
+
+  /**
+   * Get or construct a {@link Histogram} used to measure a distribution of values.
+   *
+   * @param name The name of the Histogram.
+   * @return An instance of {@link Histogram}.
+   */
+  Histogram getHistogram(String name);
+
+  /**
+   * Get or construct a {@link Meter} used to measure durations and report distributions (a
+   * combination of a {@link Timer} and a {@link Histogram}.
+   *
+   * @param name The name of the Meter.
+   * @return An instance of {@link Meter}.
+   */
+  Meter getMeter(String name);
+
+  /**
+   * Get or construct a {@link Counter} used to track a mutable number.
+   *
+   * @param name The name of the Counter
+   * @return An instance of {@link Counter}.
+   */
+  Counter getCounter(String name);
+
+  /**
+   * Register a {@link Gauge}. The Gauge will be invoked at a period defined by the implementation
+   * of {@link MetricsSystem}.
+   *
+   * @param name The name of the Gauge.
+   * @param gauge A callback to compute the current value.
+   */
+  <T> void register(String name, Gauge<T> gauge);
+
+}
+
+// End MetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
new file mode 100644
index 0000000..99b6e8c
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * 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.metrics;
+
+/**
+ * A container used by a {@link MetricsSystemFactory} to create a {@link MetricsSystem}.
+ *
+ * @param <T> Configuration/State for the {@link MetricsSystem}.
+ */
+public interface MetricsSystemConfiguration<T> {
+
+  /**
+   * @return Some state or configuration to create a {@link MetricsSystem}.
+   */
+  T get();
+
+}
+
+// End MetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
new file mode 100644
index 0000000..484b230
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+/**
+ * A factory class for creating instances of {@link MetricsSystem}.
+ */
+public interface MetricsSystemFactory {
+
+  /**
+   * Creates an instance of a {@link MetricsSystem}.
+   *
+   * @return A new {@link MetricsSystem}.
+   */
+  MetricsSystem create(MetricsSystemConfiguration<?> config);
+}
+
+// End MetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java
new file mode 100644
index 0000000..3a15c5b
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/MetricsSystemLoader.java
@@ -0,0 +1,87 @@
+/*
+ * 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.metrics;
+
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.ServiceLoader;
+
+/**
+ * A utility encapsulating use of {@link ServiceLoader} to instantiate a {@link MetricsSystem}.
+ */
+public class MetricsSystemLoader {
+  private static final Logger LOG = LoggerFactory.getLogger(MetricsSystemLoader.class);
+  private static final MetricsSystemLoader INSTANCE = new MetricsSystemLoader();
+
+  private MetricsSystemLoader() {}
+
+  /**
+   * Creates a {@link MetricsSystem} instance using the corresponding {@link MetricsSystemFactory}
+   * available to {@link ServiceLoader} on the classpath. If there is not exactly one instance of
+   * a {@link MetricsSystemFactory}, an instance of {@link NoopMetricsSystem} will be returned.
+   *
+   * @param config State to pass to the {@link MetricsSystemFactory}.
+   * @return A {@link MetricsSystem} implementation.
+   */
+  public static MetricsSystem load(MetricsSystemConfiguration<?> config) {
+    return INSTANCE._load(Objects.requireNonNull(config));
+  }
+
+  MetricsSystem _load(MetricsSystemConfiguration<?> config) {
+    List<MetricsSystemFactory> availableFactories = getFactories();
+
+    if (1 == availableFactories.size()) {
+      // One and only one instance -- what we want/expect
+      MetricsSystemFactory factory = availableFactories.get(0);
+      LOG.info("Loaded MetricsSystem {}", factory.getClass());
+      return factory.create(config);
+    } else if (availableFactories.isEmpty()) {
+      // None-provided default to no metrics
+      LOG.info("No metrics implementation available on classpath. Using No-op implementation");
+      return NoopMetricsSystem.getInstance();
+    } else {
+      // Tell the user they're doing something wrong, and choose the first impl.
+      StringBuilder sb = new StringBuilder();
+      for (MetricsSystemFactory factory : availableFactories) {
+        if (sb.length() > 0) {
+          sb.append(", ");
+        }
+        sb.append(factory.getClass());
+      }
+      LOG.warn("Found multiple MetricsSystemFactory implementations: {}."
+          + " Using No-op implementation", sb);
+      return NoopMetricsSystem.getInstance();
+    }
+  }
+
+  List<MetricsSystemFactory> getFactories() {
+    ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class);
+    List<MetricsSystemFactory> availableFactories = new ArrayList<>();
+    for (MetricsSystemFactory factory : loader) {
+      availableFactories.add(factory);
+    }
+    return availableFactories;
+  }
+}
+
+// End MetricsSystemLoader.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
new file mode 100644
index 0000000..e627d31
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/PackageMarker.java
@@ -0,0 +1,37 @@
+/*
+ * 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.metrics;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is a dummy annotation that forces javac to produce output for
+ * otherwise empty package-info.java.
+ *
+ * <p>The result is maven-compiler-plugin can properly identify the scope of
+ * changed files
+ *
+ * <p>See more details in
+ * <a href="https://jira.codehaus.org/browse/MCOMPILER-205">
+ *   maven-compiler-plugin: incremental compilation broken</a>
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface PackageMarker {
+}
+
+// End PackageMarker.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
new file mode 100644
index 0000000..be792cc
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/Timer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.metrics;
+
+/**
+ * A metric which encompasses a {@link Histogram} and {@link Meter}.
+ */
+public interface Timer extends Metric {
+
+  Context start();
+
+  /**
+   * A object that tracks an active timing state.
+   */
+  public interface Context extends AutoCloseable {
+    /**
+     * Stops the timer.
+     */
+    void close();
+  }
+}
+
+// End Timer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
new file mode 100644
index 0000000..9ce8476
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopCounter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Counter;
+
+/**
+ * {@link Counter} implementation which does nothing.
+ */
+public class NoopCounter implements Counter {
+
+  @Override public void increment() {}
+
+  @Override public void increment(long n) {}
+
+  @Override public void decrement() {}
+
+  @Override public void decrement(long n) {}
+
+}
+
+// End NoopCounter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
new file mode 100644
index 0000000..ee056e9
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopHistogram.java
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Histogram;
+
+/**
+ * {@link Histogram} which does nothing.
+ */
+public class NoopHistogram implements Histogram {
+
+  @Override public void update(int value) {}
+
+  @Override public void update(long value) {}
+
+}
+
+// End NoopHistogram.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
new file mode 100644
index 0000000..4ad68c9
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMeter.java
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Meter;
+
+/**
+ * {@link Meter} which does nothing.
+ */
+public class NoopMeter implements Meter {
+
+  @Override public void mark() {}
+
+  @Override public void mark(long events) {}
+
+}
+
+// End NoopMeter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
new file mode 100644
index 0000000..12b5af1
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystem.java
@@ -0,0 +1,69 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Counter;
+import org.apache.calcite.avatica.metrics.Gauge;
+import org.apache.calcite.avatica.metrics.Histogram;
+import org.apache.calcite.avatica.metrics.Meter;
+import org.apache.calcite.avatica.metrics.Metric;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+
+/**
+ * {@link MetricsSystem} implementation which does nothing. Returns {@link Metric} implementations
+ * which also does nothing (avoiding null instances).
+ */
+public class NoopMetricsSystem implements MetricsSystem {
+
+  private static final NoopMetricsSystem NOOP_METRICS = new NoopMetricsSystem();
+
+  private static final Timer TIMER = new NoopTimer();
+  private static final Histogram HISTOGRAM = new NoopHistogram();
+  private static final Meter METER = new NoopMeter();
+  private static final Counter COUNTER = new NoopCounter();
+
+  /**
+   * @return A {@link NoopMetricsSystem} instance.
+   */
+  public static NoopMetricsSystem getInstance() {
+    return NOOP_METRICS;
+  }
+
+  private NoopMetricsSystem() {}
+
+  @Override public Timer getTimer(String name) {
+    return TIMER;
+  }
+
+  @Override public Histogram getHistogram(String name) {
+    return HISTOGRAM;
+  }
+
+  @Override public Meter getMeter(String name) {
+    return METER;
+  }
+
+  @Override public Counter getCounter(String name) {
+    return COUNTER;
+  }
+
+  @Override public <T> void register(String name, Gauge<T> gauge) {}
+
+}
+
+// End NoopMetricsSystem.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
new file mode 100644
index 0000000..42b3f24
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemConfiguration.java
@@ -0,0 +1,40 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
+
+/**
+ * An empty configuration for the {@link NoopMetricsSystem}.
+ */
+public class NoopMetricsSystemConfiguration implements MetricsSystemConfiguration<Void> {
+
+  private static final NoopMetricsSystemConfiguration INSTANCE =
+      new NoopMetricsSystemConfiguration();
+
+  public static NoopMetricsSystemConfiguration getInstance() {
+    return INSTANCE;
+  }
+
+  private NoopMetricsSystemConfiguration() {}
+
+  @Override public Void get() {
+    return null;
+  }
+}
+
+// End NoopMetricsSystemConfiguration.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
new file mode 100644
index 0000000..c15f978
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactory.java
@@ -0,0 +1,35 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
+import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
+
+/**
+ * A {@link MetricsSystemFactory} for the {@link NoopMetricsSystem}.
+ *
+ * No service file is provided for this implementation. It is the fallback implementation if
+ * no implementation or more than one implementation is found on the classpath.
+ */
+public class NoopMetricsSystemFactory implements MetricsSystemFactory {
+
+  @Override public NoopMetricsSystem create(MetricsSystemConfiguration<?> config) {
+    return NoopMetricsSystem.getInstance();
+  }
+}
+
+// End NoopMetricsSystemFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
new file mode 100644
index 0000000..a45cd63
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/NoopTimer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+
+/**
+ * {@link Timer} which does nothing.
+ */
+public class NoopTimer implements Timer {
+
+  private static final NoopContext CONTEXT = new NoopContext();
+
+  @Override public NoopContext start() {
+    return CONTEXT;
+  }
+
+  /**
+   * {@link Context} which does nothing.
+   */
+  public static class NoopContext implements Context {
+
+    @Override public void close() {}
+
+  }
+}
+
+// End NoopTimer.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
new file mode 100644
index 0000000..826a655
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/noop/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * No-operation implementation for the Avatica Metrics framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
new file mode 100644
index 0000000..efed28c
--- /dev/null
+++ b/avatica/metrics/src/main/java/org/apache/calcite/avatica/metrics/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * Metrics for the Avatica framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.metrics;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
new file mode 100644
index 0000000..1c405ee
--- /dev/null
+++ b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/MetricsSystemLoaderTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.metrics;
+
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test class for {@link MetricsSystemLoader}.
+ */
+public class MetricsSystemLoaderTest {
+
+  @Test public void testSingleInstance() {
+    final List<MetricsSystemFactory> factories =
+        Collections.<MetricsSystemFactory>singletonList(new MarkedNoopMetricsSystemFactory());
+    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
+
+    Mockito.when(loader.getFactories()).thenReturn(factories);
+    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
+
+    // One MetricsSystemFactory should return the MetricsSystem it creates
+    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
+    assertEquals(MarkedMetricsSystem.INSTANCE, system);
+  }
+
+  @Test public void testMultipleInstances() {
+    // The type of the factories doesn't matter (we can send duplicates for testing purposes)
+    final List<MetricsSystemFactory> factories =
+        Arrays.<MetricsSystemFactory>asList(new MarkedNoopMetricsSystemFactory(),
+            new MarkedNoopMetricsSystemFactory());
+    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
+
+    Mockito.when(loader.getFactories()).thenReturn(factories);
+    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
+
+    // We had two factories loaded, therefore we'll fall back to the NoopMetricsSystem
+    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
+    assertEquals(NoopMetricsSystem.getInstance(), system);
+  }
+
+  @Test public void testNoInstances() {
+    // The type of the factories doesn't matter (we can send duplicates for testing purposes)
+    final List<MetricsSystemFactory> factories = Collections.emptyList();
+    MetricsSystemLoader loader = Mockito.mock(MetricsSystemLoader.class);
+
+    Mockito.when(loader.getFactories()).thenReturn(factories);
+    Mockito.when(loader._load(Mockito.any(MetricsSystemConfiguration.class))).thenCallRealMethod();
+
+    // We had no factories loaded, therefore we'll fall back to the NoopMetricsSystem
+    MetricsSystem system = loader._load(NoopMetricsSystemConfiguration.getInstance());
+    assertEquals(NoopMetricsSystem.getInstance(), system);
+  }
+
+  /**
+   * A test factory implementation which can return a recognized MetricsSystem implementation.
+   */
+  private static class MarkedNoopMetricsSystemFactory implements MetricsSystemFactory {
+    public MarkedMetricsSystem create(MetricsSystemConfiguration<?> config) {
+      return MarkedMetricsSystem.INSTANCE;
+    }
+  }
+
+  /**
+   * A metrics system implementation that is identifiable for testing.
+   */
+  private static class MarkedMetricsSystem implements MetricsSystem {
+    private static final MarkedMetricsSystem INSTANCE = new MarkedMetricsSystem();
+
+    private MarkedMetricsSystem() {}
+
+    @Override public Timer getTimer(String name) {
+      return null;
+    }
+
+    @Override public Histogram getHistogram(String name) {
+      return null;
+    }
+
+    @Override public Meter getMeter(String name) {
+      return null;
+    }
+
+    @Override public Counter getCounter(String name) {
+      return null;
+    }
+
+    @Override public <T> void register(String name, Gauge<T> gauge) {}
+  }
+}
+
+// End MetricsSystemLoaderTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
new file mode 100644
index 0000000..3060b2f
--- /dev/null
+++ b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemFactoryTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.metrics.noop;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link NoopMetricsSystemFactory}.
+ */
+public class NoopMetricsSystemFactoryTest {
+
+  @Test public void testSingleton() {
+    NoopMetricsSystemFactory factory = new NoopMetricsSystemFactory();
+    NoopMetricsSystemConfiguration config = NoopMetricsSystemConfiguration.getInstance();
+    assertTrue("The factory should only return one NoopMetricsSystem instance",
+        factory.create(config) == factory.create(config));
+  }
+
+}
+
+// End NoopMetricsSystemFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
new file mode 100644
index 0000000..f28d123
--- /dev/null
+++ b/avatica/metrics/src/test/java/org/apache/calcite/avatica/metrics/noop/NoopMetricsSystemTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.metrics.noop;
+
+import org.apache.calcite.avatica.metrics.Counter;
+import org.apache.calcite.avatica.metrics.Gauge;
+import org.apache.calcite.avatica.metrics.Histogram;
+import org.apache.calcite.avatica.metrics.Meter;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.Timer;
+import org.apache.calcite.avatica.metrics.Timer.Context;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link NoopMetricsSystem}.
+ */
+public class NoopMetricsSystemTest {
+
+  @Test public void testNoNulls() {
+    // The NOOP implementation should act as a real implementation, no "nulls" allowed.
+    MetricsSystem metrics = NoopMetricsSystem.getInstance();
+
+    Counter counter = metrics.getCounter("counter");
+    counter.decrement();
+    counter.increment();
+    counter.decrement(1L);
+    counter.increment(1L);
+
+    Histogram histogram = metrics.getHistogram("histogram");
+    histogram.update(1);
+    histogram.update(1L);
+
+    Timer timer = metrics.getTimer("timer");
+    Context context = timer.start();
+    context.close();
+    Context contextTwo = timer.start();
+    assertTrue("Timer's context should be a singleton", context == contextTwo);
+
+    Meter meter = metrics.getMeter("meter");
+    meter.mark();
+    meter.mark(5L);
+
+    metrics.register("gauge", new Gauge<Long>() {
+      @Override public Long getValue() {
+        return 42L;
+      }
+    });
+  }
+
+  @Test public void testSingleton() {
+    assertTrue("Should be a singleton",
+        NoopMetricsSystem.getInstance() == NoopMetricsSystem.getInstance());
+  }
+}
+
+// End NoopMetricsSystemTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/metrics/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica/metrics/src/test/resources/log4j.properties b/avatica/metrics/src/test/resources/log4j.properties
new file mode 100644
index 0000000..834e2db
--- /dev/null
+++ b/avatica/metrics/src/test/resources/log4j.properties
@@ -0,0 +1,24 @@
+# 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.
+
+# Root logger is configured at INFO and is sent to A1
+log4j.rootLogger=INFO, A1
+
+# A1 goes to the console
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# Set the pattern for each log message
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p - %m%n

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/noop-driver/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/noop-driver/pom.xml b/avatica/noop-driver/pom.xml
new file mode 100644
index 0000000..5c2326c
--- /dev/null
+++ b/avatica/noop-driver/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica-parent</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>calcite-avatica-noop</artifactId>
+  <packaging>jar</packaging>
+  <name>Calcite Avatica Noop</name>
+  <description>A Noop JDBC driver.</description>
+
+  <properties>
+    <top.dir>${project.basedir}/..</top.dir>
+  </properties>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <versionRange>[2.12.1,)</versionRange>
+                    <goals>
+                      <goal>check</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <!-- Parent module has the same plugin and does the work of
+           generating -sources.jar for each project. But without the
+           plugin declared here, IDEs don't know the sources are
+           available. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Produce a tests jar so that avatica-server/pom.xml can reference for suite.
+           TODO: remove after moving over to annotation-based TestSuite definitions. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>non-root-resources</id>
+            <goals>
+              <goal>process</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>


[14/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
deleted file mode 100644
index 478723f..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
+++ /dev/null
@@ -1,1046 +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.remote.TypedValue;
-import org.apache.calcite.avatica.util.ArrayImpl;
-import org.apache.calcite.avatica.util.Cursor;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-
-/**
- * Implementation of {@link java.sql.ResultSet}
- * for the Avatica engine.
- */
-public class AvaticaResultSet implements ResultSet, ArrayImpl.Factory {
-  protected final AvaticaStatement statement;
-  protected final QueryState state;
-  protected final Meta.Signature signature;
-  protected final Meta.Frame firstFrame;
-  protected final List<ColumnMetaData> columnMetaDataList;
-  protected final ResultSetMetaData resultSetMetaData;
-  protected final Calendar localCalendar;
-
-  protected Cursor cursor;
-  protected List<Cursor.Accessor> accessorList;
-  private int row;
-  private boolean afterLast;
-  private int fetchDirection;
-  private int fetchSize;
-  private int type;
-  private int concurrency;
-  private int holdability;
-  private boolean closed;
-  private long timeoutMillis;
-  private Cursor timeoutCursor;
-
-  public AvaticaResultSet(AvaticaStatement statement,
-      QueryState state,
-      Meta.Signature signature,
-      ResultSetMetaData resultSetMetaData,
-      TimeZone timeZone,
-      Meta.Frame firstFrame) {
-    this.statement = statement;
-    this.state = state;
-    this.signature = signature;
-    this.firstFrame = firstFrame;
-    this.columnMetaDataList = signature.columns;
-    this.type = statement.resultSetType;
-    this.concurrency = statement.resultSetConcurrency;
-    this.holdability = statement.resultSetHoldability;
-    this.fetchSize = statement.getFetchSize();
-    this.fetchDirection = statement.getFetchDirection();
-    this.resultSetMetaData = resultSetMetaData;
-    this.localCalendar = Calendar.getInstance(timeZone);
-  }
-
-  private int findColumn0(String columnLabel) throws SQLException {
-    for (ColumnMetaData columnMetaData : columnMetaDataList) {
-      // Per JDBC 3.0 specification, match is case-insensitive and if there is
-      // more than one column with a particular name, take the first.
-      if (columnMetaData.label.equalsIgnoreCase(columnLabel)) {
-        return columnMetaData.ordinal; // 0-based
-      }
-    }
-    throw new SQLException("column '" + columnLabel + "' not found");
-  }
-
-  /**
-   * Returns the accessor for column with a given index.
-   *
-   * @param columnIndex 1-based column index
-   * @return Accessor
-   * @throws SQLException if index is not valid
-   */
-  private Cursor.Accessor getAccessor(int columnIndex) throws SQLException {
-    try {
-      return accessorList.get(columnIndex - 1);
-    } catch (IndexOutOfBoundsException e) {
-      throw new SQLException("invalid column ordinal: " + columnIndex);
-    }
-  }
-
-  /**
-   * Returns the accessor for column with a given label.
-   *
-   * @param columnLabel Column label
-   * @return Accessor
-   * @throws SQLException if there is no column with that label
-   */
-  private Cursor.Accessor getAccessor(String columnLabel) throws SQLException {
-    return accessorList.get(findColumn0(columnLabel));
-  }
-
-  public void close() {
-    closed = true;
-    final Cursor cursor = this.cursor;
-    if (cursor != null) {
-      this.cursor = null;
-      cursor.close();
-    }
-    statement.onResultSetClose(this);
-    // TODO: for timeout, see IteratorResultSet.close
-/*
-        if (timeoutCursor != null) {
-            final long noTimeout = 0;
-            timeoutCursor.close(noTimeout);
-            timeoutCursor = null;
-        }
-*/
-  }
-
-  /**
-   * Sets the timeout that this result set will wait for a row from the
-   * underlying iterator.
-   *
-   * <p>Not a JDBC method.</p>
-   *
-   * @param timeoutMillis Timeout in milliseconds. Must be greater than zero.
-   */
-  void setTimeout(long timeoutMillis) {
-    assert timeoutMillis > 0;
-    assert this.timeoutMillis == 0;
-    this.timeoutMillis = timeoutMillis;
-    assert timeoutCursor == null;
-    timeoutCursor = cursor;
-
-    // TODO: for timeout, see IteratorResultSet.setTimeout
-/*
-        timeoutCursor = new TimeoutCursor(timeoutMillis);
-        timeoutCursor.start();
-*/
-  }
-
-  // not JDBC
-  protected void cancel() {
-    throw new UnsupportedOperationException(); // TODO:
-  }
-
-  /**
-   * Executes this result set. (Not a JDBC method.)
-   *
-   * <p>Note that execute cannot occur in the constructor, because the
-   * constructor occurs while the statement is locked, to make sure that
-   * execute/cancel don't happen at the same time.</p>
-   *
-   * @see org.apache.calcite.avatica.AvaticaConnection.Trojan#execute(AvaticaResultSet)
-   *
-   * @throws SQLException if execute fails for some reason.
-   */
-  protected AvaticaResultSet execute() throws SQLException {
-    final List<TypedValue> parameterValues = statement.getBoundParameterValues();
-    final Iterable<Object> iterable1 =
-        statement.connection.meta.createIterable(statement.handle, state, signature,
-            parameterValues, firstFrame);
-    this.cursor = MetaImpl.createCursor(signature.cursorFactory, iterable1);
-    this.accessorList =
-        cursor.createAccessors(columnMetaDataList, localCalendar, this);
-    this.row = -1;
-    this.afterLast = false;
-    return this;
-  }
-
-  protected AvaticaResultSet execute2(Cursor cursor,
-      List<ColumnMetaData> columnMetaDataList) {
-    this.cursor = cursor;
-    this.accessorList =
-        cursor.createAccessors(columnMetaDataList, localCalendar, this);
-    this.row = -1;
-    this.afterLast = false;
-    return this;
-  }
-
-  public ResultSet create(ColumnMetaData.AvaticaType elementType,
-      Iterable<Object> iterable) {
-    throw new UnsupportedOperationException();
-  }
-
-  public boolean next() throws SQLException {
-    // TODO: for timeout, see IteratorResultSet.next
-    if (isClosed()) {
-      throw new SQLException("next() called on closed cursor");
-    }
-    if (cursor.next()) {
-      ++row;
-      return true;
-    } else {
-      afterLast = true;
-      return false;
-    }
-  }
-
-  public int findColumn(String columnLabel) throws SQLException {
-    return findColumn0(columnLabel) + 1;
-  }
-
-  public boolean wasNull() throws SQLException {
-    return cursor.wasNull();
-  }
-
-  public String getString(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getString();
-  }
-
-  public boolean getBoolean(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getBoolean();
-  }
-
-  public byte getByte(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getByte();
-  }
-
-  public short getShort(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getShort();
-  }
-
-  public int getInt(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getInt();
-  }
-
-  public long getLong(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getLong();
-  }
-
-  public float getFloat(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getFloat();
-  }
-
-  public double getDouble(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getDouble();
-  }
-
-  public BigDecimal getBigDecimal(
-      int columnIndex, int scale) throws SQLException {
-    return getAccessor(columnIndex).getBigDecimal(scale);
-  }
-
-  public byte[] getBytes(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getBytes();
-  }
-
-  public Date getDate(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getDate(localCalendar);
-  }
-
-  public Time getTime(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getTime(localCalendar);
-  }
-
-  public Timestamp getTimestamp(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getTimestamp(localCalendar);
-  }
-
-  public InputStream getAsciiStream(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getAsciiStream();
-  }
-
-  public InputStream getUnicodeStream(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getUnicodeStream();
-  }
-
-  public InputStream getBinaryStream(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getBinaryStream();
-  }
-
-  public String getString(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getString();
-  }
-
-  public boolean getBoolean(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getBoolean();
-  }
-
-  public byte getByte(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getByte();
-  }
-
-  public short getShort(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getShort();
-  }
-
-  public int getInt(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getInt();
-  }
-
-  public long getLong(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getLong();
-  }
-
-  public float getFloat(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getFloat();
-  }
-
-  public double getDouble(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getDouble();
-  }
-
-  public BigDecimal getBigDecimal(
-      String columnLabel, int scale) throws SQLException {
-    return getAccessor(columnLabel).getBigDecimal(scale);
-  }
-
-  public byte[] getBytes(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getBytes();
-  }
-
-  public Date getDate(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getDate(localCalendar);
-  }
-
-  public Time getTime(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getTime(localCalendar);
-  }
-
-  public Timestamp getTimestamp(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getTimestamp(localCalendar);
-  }
-
-  public InputStream getAsciiStream(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getAsciiStream();
-  }
-
-  public InputStream getUnicodeStream(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getUnicodeStream();
-  }
-
-  public InputStream getBinaryStream(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getBinaryStream();
-  }
-
-  public SQLWarning getWarnings() throws SQLException {
-    return null; // no warnings, since warnings are not supported
-  }
-
-  public void clearWarnings() throws SQLException {
-    // no-op since warnings are not supported
-  }
-
-  public String getCursorName() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public ResultSetMetaData getMetaData() throws SQLException {
-    return resultSetMetaData;
-  }
-
-  public Object getObject(int columnIndex) throws SQLException {
-    final Cursor.Accessor accessor = getAccessor(columnIndex);
-    final ColumnMetaData metaData = columnMetaDataList.get(columnIndex - 1);
-    return AvaticaSite.get(accessor, metaData.type.id, localCalendar);
-  }
-
-  public Object getObject(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getObject();
-  }
-
-  public Reader getCharacterStream(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getCharacterStream();
-  }
-
-  public Reader getCharacterStream(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getCharacterStream();
-  }
-
-  public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getBigDecimal();
-  }
-
-  public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getBigDecimal();
-  }
-
-  public boolean isBeforeFirst() throws SQLException {
-    return row < 0;
-  }
-
-  public boolean isAfterLast() throws SQLException {
-    return afterLast;
-  }
-
-  public boolean isFirst() throws SQLException {
-    return row == 0;
-  }
-
-  public boolean isLast() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void beforeFirst() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void afterLast() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public boolean first() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public boolean last() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public int getRow() throws SQLException {
-    return row;
-  }
-
-  public boolean absolute(int row) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public boolean relative(int rows) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public boolean previous() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void setFetchDirection(int direction) throws SQLException {
-    this.fetchDirection = direction;
-  }
-
-  public int getFetchDirection() throws SQLException {
-    return fetchDirection;
-  }
-
-  public void setFetchSize(int fetchSize) throws SQLException {
-    this.fetchSize = fetchSize;
-  }
-
-  public int getFetchSize() throws SQLException {
-    return fetchSize;
-  }
-
-  public int getType() throws SQLException {
-    return type;
-  }
-
-  public int getConcurrency() throws SQLException {
-    return concurrency;
-  }
-
-  public boolean rowUpdated() throws SQLException {
-    return false;
-  }
-
-  public boolean rowInserted() throws SQLException {
-    return false;
-  }
-
-  public boolean rowDeleted() throws SQLException {
-    return false;
-  }
-
-  public void updateNull(int columnIndex) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateByte(int columnIndex, byte x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateShort(int columnIndex, short x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateInt(int columnIndex, int x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateLong(int columnIndex, long x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateFloat(int columnIndex, float x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateDouble(int columnIndex, double x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBigDecimal(
-      int columnIndex, BigDecimal x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateString(int columnIndex, String x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBytes(int columnIndex, byte[] x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateDate(int columnIndex, Date x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateTime(int columnIndex, Time x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateTimestamp(
-      int columnIndex, Timestamp x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      int columnIndex, InputStream x, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      int columnIndex, InputStream x, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      int columnIndex, Reader x, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateObject(
-      int columnIndex, Object x, int scaleOrLength) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateObject(int columnIndex, Object x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNull(String columnLabel) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBoolean(
-      String columnLabel, boolean x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateByte(String columnLabel, byte x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateShort(String columnLabel, short x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateInt(String columnLabel, int x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateLong(String columnLabel, long x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateFloat(String columnLabel, float x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateDouble(String columnLabel, double x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBigDecimal(
-      String columnLabel, BigDecimal x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateString(String columnLabel, String x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBytes(String columnLabel, byte[] x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateDate(String columnLabel, Date x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateTime(String columnLabel, Time x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateTimestamp(
-      String columnLabel, Timestamp x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      String columnLabel, InputStream x, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      String columnLabel, InputStream x, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      String columnLabel, Reader reader, int length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateObject(
-      String columnLabel, Object x, int scaleOrLength) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateObject(String columnLabel, Object x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void insertRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void deleteRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void refreshRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void cancelRowUpdates() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void moveToInsertRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void moveToCurrentRow() throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public AvaticaStatement getStatement() {
-    return statement;
-  }
-
-  public Object getObject(
-      int columnIndex, Map<String, Class<?>> map) throws SQLException {
-    return getAccessor(columnIndex).getObject(map);
-  }
-
-  public Ref getRef(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getRef();
-  }
-
-  public Blob getBlob(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getBlob();
-  }
-
-  public Clob getClob(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getClob();
-  }
-
-  public Array getArray(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getArray();
-  }
-
-  public Object getObject(
-      String columnLabel, Map<String, Class<?>> map) throws SQLException {
-    return getAccessor(columnLabel).getObject(map);
-  }
-
-  public Ref getRef(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getRef();
-  }
-
-  public Blob getBlob(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getBlob();
-  }
-
-  public Clob getClob(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getClob();
-  }
-
-  public Array getArray(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getArray();
-  }
-
-  public Date getDate(int columnIndex, Calendar cal) throws SQLException {
-    return getAccessor(columnIndex).getDate(cal);
-  }
-
-  public Date getDate(String columnLabel, Calendar cal) throws SQLException {
-    return getAccessor(columnLabel).getDate(cal);
-  }
-
-  public Time getTime(int columnIndex, Calendar cal) throws SQLException {
-    return getAccessor(columnIndex).getTime(cal);
-  }
-
-  public Time getTime(String columnLabel, Calendar cal) throws SQLException {
-    return getAccessor(columnLabel).getTime(cal);
-  }
-
-  public Timestamp getTimestamp(
-      int columnIndex, Calendar cal) throws SQLException {
-    return getAccessor(columnIndex).getTimestamp(cal);
-  }
-
-  public Timestamp getTimestamp(
-      String columnLabel, Calendar cal) throws SQLException {
-    return getAccessor(columnLabel).getTimestamp(cal);
-  }
-
-  public URL getURL(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getURL();
-  }
-
-  public URL getURL(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getURL();
-  }
-
-  public void updateRef(int columnIndex, Ref x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateRef(String columnLabel, Ref x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(int columnIndex, Blob x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(String columnLabel, Blob x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(int columnIndex, Clob x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(String columnLabel, Clob x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateArray(int columnIndex, Array x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateArray(String columnLabel, Array x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public RowId getRowId(int columnIndex) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public RowId getRowId(String columnLabel) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateRowId(int columnIndex, RowId x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateRowId(String columnLabel, RowId x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public int getHoldability() throws SQLException {
-    return holdability;
-  }
-
-  public boolean isClosed() throws SQLException {
-    return closed;
-  }
-
-  public void updateNString(
-      int columnIndex, String nString) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNString(
-      String columnLabel, String nString) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(
-      String columnLabel, NClob nClob) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public NClob getNClob(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getNClob();
-  }
-
-  public NClob getNClob(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getNClob();
-  }
-
-  public SQLXML getSQLXML(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getSQLXML();
-  }
-
-  public SQLXML getSQLXML(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getSQLXML();
-  }
-
-  public void updateSQLXML(
-      int columnIndex, SQLXML xmlObject) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateSQLXML(
-      String columnLabel, SQLXML xmlObject) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public String getNString(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getNString();
-  }
-
-  public String getNString(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getNString();
-  }
-
-  public Reader getNCharacterStream(int columnIndex) throws SQLException {
-    return getAccessor(columnIndex).getNCharacterStream();
-  }
-
-  public Reader getNCharacterStream(String columnLabel) throws SQLException {
-    return getAccessor(columnLabel).getNCharacterStream();
-  }
-
-  public void updateNCharacterStream(
-      int columnIndex, Reader x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNCharacterStream(
-      String columnLabel, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      int columnIndex, InputStream x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      int columnIndex, InputStream x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      int columnIndex, Reader x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      String columnLabel, InputStream x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      String columnLabel, InputStream x, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      String columnLabel, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(
-      int columnIndex,
-      InputStream inputStream,
-      long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(
-      String columnLabel,
-      InputStream inputStream,
-      long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(
-      int columnIndex, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(
-      String columnLabel, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(
-      int columnIndex, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(
-      String columnLabel, Reader reader, long length) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNCharacterStream(
-      int columnIndex, Reader x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNCharacterStream(
-      String columnLabel, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      int columnIndex, InputStream x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      int columnIndex, InputStream x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      int columnIndex, Reader x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateAsciiStream(
-      String columnLabel, InputStream x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBinaryStream(
-      String columnLabel, InputStream x) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateCharacterStream(
-      String columnLabel, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(
-      int columnIndex, InputStream inputStream) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateBlob(
-      String columnLabel, InputStream inputStream) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(int columnIndex, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateClob(
-      String columnLabel, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(
-      int columnIndex, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public void updateNClob(
-      String columnLabel, Reader reader) throws SQLException {
-    throw new UnsupportedOperationException();
-  }
-
-  public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
-    return getAccessor(columnIndex).getObject(type);
-  }
-
-  public <T> T getObject(
-      String columnLabel, Class<T> type) throws SQLException {
-    return getAccessor(columnLabel).getObject(type);
-  }
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    if (iface.isInstance(this)) {
-      return iface.cast(this);
-    }
-    throw statement.connection.helper.createException(
-        "does not implement '" + iface + "'");
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return iface.isInstance(this);
-  }
-}
-
-// End AvaticaResultSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
deleted file mode 100644
index b4e8892..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSetMetaData.java
+++ /dev/null
@@ -1,145 +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.ResultSetMetaData;
-import java.sql.SQLException;
-
-/**
- * Implementation of {@link ResultSetMetaData}
- * for the Avatica framework.
- */
-public class AvaticaResultSetMetaData implements ResultSetMetaData {
-  final AvaticaStatement statement;
-  final Object query; // reserved for future use
-  final Meta.Signature signature;
-
-  public AvaticaResultSetMetaData(
-      AvaticaStatement statement,
-      Object query,
-      Meta.Signature signature) {
-    this.statement = statement;
-    this.query = query;
-    this.signature = signature;
-  }
-
-  private ColumnMetaData getColumnMetaData(int column) {
-    return signature.columns.get(column - 1);
-  }
-
-  // implement ResultSetMetaData
-
-  public int getColumnCount() throws SQLException {
-    return signature.columns.size();
-  }
-
-  public boolean isAutoIncrement(int column) throws SQLException {
-    return getColumnMetaData(column).autoIncrement;
-  }
-
-  public boolean isCaseSensitive(int column) throws SQLException {
-    return getColumnMetaData(column).caseSensitive;
-  }
-
-  public boolean isSearchable(int column) throws SQLException {
-    return getColumnMetaData(column).searchable;
-  }
-
-  public boolean isCurrency(int column) throws SQLException {
-    return getColumnMetaData(column).currency;
-  }
-
-  public int isNullable(int column) throws SQLException {
-    return getColumnMetaData(column).nullable;
-  }
-
-  public boolean isSigned(int column) throws SQLException {
-    return getColumnMetaData(column).signed;
-  }
-
-  public int getColumnDisplaySize(int column) throws SQLException {
-    return getColumnMetaData(column).displaySize;
-  }
-
-  public String getColumnLabel(int column) throws SQLException {
-    return getColumnMetaData(column).label;
-  }
-
-  public String getColumnName(int column) throws SQLException {
-    return getColumnMetaData(column).columnName;
-  }
-
-  public String getSchemaName(int column) throws SQLException {
-    return getColumnMetaData(column).schemaName;
-  }
-
-  public int getPrecision(int column) throws SQLException {
-    return getColumnMetaData(column).precision;
-  }
-
-  public int getScale(int column) throws SQLException {
-    return getColumnMetaData(column).scale;
-  }
-
-  public String getTableName(int column) throws SQLException {
-    return getColumnMetaData(column).tableName;
-  }
-
-  public String getCatalogName(int column) throws SQLException {
-    return getColumnMetaData(column).catalogName;
-  }
-
-  public int getColumnType(int column) throws SQLException {
-    return getColumnMetaData(column).type.id;
-  }
-
-  public String getColumnTypeName(int column) throws SQLException {
-    return getColumnMetaData(column).type.name;
-  }
-
-  public boolean isReadOnly(int column) throws SQLException {
-    return getColumnMetaData(column).readOnly;
-  }
-
-  public boolean isWritable(int column) throws SQLException {
-    return getColumnMetaData(column).writable;
-  }
-
-  public boolean isDefinitelyWritable(int column) throws SQLException {
-    return getColumnMetaData(column).definitelyWritable;
-  }
-
-  public String getColumnClassName(int column) throws SQLException {
-    return getColumnMetaData(column).columnClassName;
-  }
-
-  // implement Wrapper
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    if (iface.isInstance(this)) {
-      return iface.cast(this);
-    }
-    throw statement.connection.helper.createException(
-        "does not implement '" + iface + "'");
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return iface.isInstance(this);
-  }
-}
-
-// End AvaticaResultSetMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
deleted file mode 100644
index 675c8af..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSeverity.java
+++ /dev/null
@@ -1,90 +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 java.util.Objects;
-
-/**
- * An enumeration that denotes the severity of a given unexpected state.
- */
-public enum AvaticaSeverity {
-  /**
-   * The severity of the outcome of some unexpected state is unknown.
-   */
-  UNKNOWN(0),
-
-  /**
-   * The system has been left in an unrecoverable state as a result of an operation.
-   */
-  FATAL(1),
-
-  /**
-   * The result of an action resulted in an error which the current operation cannot recover
-   * from. Clients can attempt to execute the operation again.
-   */
-  ERROR(2),
-
-  /**
-   * The operation completed successfully but a message was generated to warn the client about
-   * some unexpected state or action.
-   */
-  WARNING(3);
-
-  private final int value;
-
-  AvaticaSeverity(int value) {
-    this.value = value;
-  }
-
-  public int getValue() {
-    return value;
-  }
-
-  public Common.Severity toProto() {
-    switch (this) {
-    case UNKNOWN:
-      return Common.Severity.UNKNOWN_SEVERITY;
-    case FATAL:
-      return Common.Severity.FATAL_SEVERITY;
-    case ERROR:
-      return Common.Severity.ERROR_SEVERITY;
-    case WARNING:
-      return Common.Severity.WARNING_SEVERITY;
-    default:
-      throw new RuntimeException("Unhandled Severity level: " + this);
-    }
-  }
-
-  public static AvaticaSeverity fromProto(Common.Severity proto) {
-    switch (Objects.requireNonNull(proto)) {
-    case UNKNOWN_SEVERITY:
-      return AvaticaSeverity.UNKNOWN;
-    case FATAL_SEVERITY:
-      return AvaticaSeverity.FATAL;
-    case ERROR_SEVERITY:
-      return AvaticaSeverity.ERROR;
-    case WARNING_SEVERITY:
-      return AvaticaSeverity.WARNING;
-    default:
-      throw new RuntimeException("Unhandled protobuf Severity level: " + proto);
-    }
-  }
-}
-
-// End AvaticaSeverity.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
deleted file mode 100644
index 7fd6947..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
+++ /dev/null
@@ -1,587 +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.remote.TypedValue;
-import org.apache.calcite.avatica.util.Cursor;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-
-/**
- * A location that a value can be written to or read from.
- */
-public class AvaticaSite {
-  final AvaticaParameter parameter;
-
-  /** Calendar is not thread-safe. But calendar is only used from within one
-   * thread, and we have to trust that clients are not modifying calendars
-   * that they pass to us in a method such as
-   * {@link java.sql.PreparedStatement#setTime(int, Time, Calendar)}, so we do
-   * not need to synchronize access. */
-  final Calendar calendar;
-  private final int index;
-  final TypedValue[] slots;
-
-  /** Value that means the parameter has been set to null.
-   * If value is null, parameter has not been set. */
-  public static final Object DUMMY_VALUE = Dummy.INSTANCE;
-
-  public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,
-      TypedValue[] slots) {
-    assert calendar != null;
-    assert parameter != null;
-    assert slots != null;
-    this.parameter = parameter;
-    this.calendar = calendar;
-    this.index = index;
-    this.slots = slots;
-  }
-
-  private TypedValue wrap(ColumnMetaData.Rep rep, Object o,
-      Calendar calendar) {
-    return TypedValue.ofJdbc(rep, o, calendar);
-  }
-
-  private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {
-    return TypedValue.ofJdbc(rep, o, calendar);
-  }
-
-  public boolean isSet(int index) {
-    return slots[index] != null;
-  }
-
-  public void setByte(byte o) {
-    slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);
-  }
-
-  public void setChar(char o) {
-    slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);
-  }
-
-  public void setShort(short o) {
-    slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);
-  }
-
-  public void setInt(int o) {
-    slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);
-  }
-
-  public void setLong(long o) {
-    slots[index] = wrap(ColumnMetaData.Rep.LONG, o);
-  }
-
-  public void setBoolean(boolean o) {
-    slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);
-  }
-
-  public void setRowId(RowId x) {
-    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);
-  }
-
-  public void setNString(String o) {
-    slots[index] = wrap(ColumnMetaData.Rep.STRING, o);
-  }
-
-  public void setNCharacterStream(Reader value, long length) {
-  }
-
-  public void setNClob(NClob value) {
-    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);
-  }
-
-  public void setClob(Reader reader, long length) {
-  }
-
-  public void setBlob(InputStream inputStream, long length) {
-  }
-
-  public void setNClob(Reader reader, long length) {
-  }
-
-  public void setSQLXML(SQLXML xmlObject) {
-    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);
-  }
-
-  public void setAsciiStream(InputStream x, long length) {
-  }
-
-  public void setBinaryStream(InputStream x, long length) {
-  }
-
-  public void setCharacterStream(Reader reader, long length) {
-  }
-
-  public void setAsciiStream(InputStream x) {
-  }
-
-  public void setBinaryStream(InputStream x) {
-  }
-
-  public void setCharacterStream(Reader reader) {
-  }
-
-  public void setNCharacterStream(Reader value) {
-  }
-
-  public void setClob(Reader reader) {
-  }
-
-  public void setBlob(InputStream inputStream) {
-  }
-
-  public void setNClob(Reader reader) {
-  }
-
-  public void setUnicodeStream(InputStream x, int length) {
-  }
-
-  public void setFloat(float x) {
-    slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);
-  }
-
-  public void setDouble(double x) {
-    slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);
-  }
-
-  public void setBigDecimal(BigDecimal x) {
-    slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);
-  }
-
-  public void setString(String x) {
-    slots[index] = wrap(ColumnMetaData.Rep.STRING, x);
-  }
-
-  public void setBytes(byte[] x) {
-    slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);
-  }
-
-  public void setTimestamp(Timestamp x, Calendar calendar) {
-    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);
-  }
-
-  public void setTime(Time x, Calendar calendar) {
-    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);
-  }
-
-  public void setDate(Date x, Calendar cal) {
-    slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);
-  }
-
-  public void setObject(Object x, int targetSqlType) {
-    if (x == null || Types.NULL == targetSqlType) {
-      setNull(targetSqlType);
-      return;
-    }
-    switch (targetSqlType) {
-    case Types.CLOB:
-    case Types.DATALINK:
-    case Types.NCLOB:
-    case Types.OTHER:
-    case Types.REF:
-    case Types.SQLXML:
-    case Types.STRUCT:
-      throw notImplemented();
-    case Types.ARRAY:
-      setArray(toArray(x));
-      break;
-    case Types.BIGINT:
-      setLong(toLong(x));
-      break;
-    case Types.BINARY:
-    case Types.LONGVARBINARY:
-    case Types.VARBINARY:
-      setBytes(toBytes(x));
-      break;
-    case Types.BIT:
-    case Types.BOOLEAN:
-      setBoolean(toBoolean(x));
-      break;
-    case Types.BLOB:
-      if (x instanceof Blob) {
-        setBlob((Blob) x);
-        break;
-      } else if (x instanceof InputStream) {
-        setBlob((InputStream) x);
-      }
-      throw unsupportedCast(x.getClass(), Blob.class);
-    case Types.DATE:
-      setDate(toDate(x), calendar);
-      break;
-    case Types.DECIMAL:
-    case Types.NUMERIC:
-      setBigDecimal(toBigDecimal(x));
-      break;
-    case Types.DISTINCT:
-      throw notImplemented();
-    case Types.DOUBLE:
-    case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
-      setDouble(toDouble(x));
-      break;
-    case Types.INTEGER:
-      setInt(toInt(x));
-      break;
-    case Types.JAVA_OBJECT:
-      setObject(x);
-      break;
-    case Types.LONGNVARCHAR:
-    case Types.LONGVARCHAR:
-    case Types.NVARCHAR:
-    case Types.VARCHAR:
-    case Types.CHAR:
-    case Types.NCHAR:
-      setString(toString(x));
-      break;
-    case Types.REAL:
-      setFloat(toFloat(x));
-      break;
-    case Types.ROWID:
-      if (x instanceof RowId) {
-        setRowId((RowId) x);
-        break;
-      }
-      throw unsupportedCast(x.getClass(), RowId.class);
-    case Types.SMALLINT:
-      setShort(toShort(x));
-      break;
-    case Types.TIME:
-      setTime(toTime(x), calendar);
-      break;
-    case Types.TIMESTAMP:
-      setTimestamp(toTimestamp(x), calendar);
-      break;
-    case Types.TINYINT:
-      setByte(toByte(x));
-      break;
-    default:
-      throw notImplemented();
-    }
-  }
-
-  /** Similar logic to {@link #setObject}. */
-  public static Object get(Cursor.Accessor accessor, int targetSqlType,
-      Calendar localCalendar) throws SQLException {
-    switch (targetSqlType) {
-    case Types.CLOB:
-    case Types.DATALINK:
-    case Types.NCLOB:
-    case Types.REF:
-    case Types.SQLXML:
-    case Types.STRUCT:
-      throw notImplemented();
-    case Types.ARRAY:
-      return accessor.getArray();
-    case Types.BIGINT:
-      final long aLong = accessor.getLong();
-      if (aLong == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return aLong;
-    case Types.BINARY:
-    case Types.LONGVARBINARY:
-    case Types.VARBINARY:
-      return accessor.getBytes();
-    case Types.BIT:
-    case Types.BOOLEAN:
-      final boolean aBoolean = accessor.getBoolean();
-      if (!aBoolean && accessor.wasNull()) {
-        return null;
-      }
-      return aBoolean;
-    case Types.BLOB:
-      return accessor.getBlob();
-    case Types.DATE:
-      return accessor.getDate(localCalendar);
-    case Types.DECIMAL:
-    case Types.NUMERIC:
-      return accessor.getBigDecimal();
-    case Types.DISTINCT:
-      throw notImplemented();
-    case Types.DOUBLE:
-    case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
-      final double aDouble = accessor.getDouble();
-      if (aDouble == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return aDouble;
-    case Types.INTEGER:
-      final int anInt = accessor.getInt();
-      if (anInt == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return anInt;
-    case Types.JAVA_OBJECT:
-    case Types.OTHER:
-      return accessor.getObject();
-    case Types.LONGNVARCHAR:
-    case Types.LONGVARCHAR:
-    case Types.NVARCHAR:
-    case Types.VARCHAR:
-    case Types.CHAR:
-    case Types.NCHAR:
-      return accessor.getString();
-    case Types.REAL:
-      final float aFloat = accessor.getFloat();
-      if (aFloat == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return aFloat;
-    case Types.ROWID:
-      throw notImplemented();
-    case Types.SMALLINT:
-      final short aShort = accessor.getShort();
-      if (aShort == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return aShort;
-    case Types.TIME:
-      return accessor.getTime(localCalendar);
-    case Types.TIMESTAMP:
-      return accessor.getTimestamp(localCalendar);
-    case Types.TINYINT:
-      final byte aByte = accessor.getByte();
-      if (aByte == 0 && accessor.wasNull()) {
-        return null;
-      }
-      return aByte;
-    default:
-      throw notImplemented();
-    }
-  }
-
-  public void setObject(Object x) {
-    slots[index] = TypedValue.ofJdbc(x, calendar);
-  }
-
-  public void setNull(int sqlType) {
-    slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);
-  }
-
-  public void setRef(Ref x) {
-  }
-
-  public void setBlob(Blob x) {
-  }
-
-  public void setClob(Clob x) {
-  }
-
-  public void setArray(Array x) {
-  }
-
-  public void setNull(int sqlType, String typeName) {
-  }
-
-  public void setURL(URL x) {
-  }
-
-  public void setObject(Object x, int targetSqlType,
-      int scaleOrLength) {
-  }
-
-  private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
-    return new UnsupportedOperationException("Cannot convert from "
-        + from.getCanonicalName() + " to " + to.getCanonicalName());
-  }
-
-  private static RuntimeException notImplemented() {
-    return new RuntimeException("not implemented");
-  }
-
-  private static Array toArray(Object x) {
-    if (x instanceof Array) {
-      return (Array) x;
-    }
-    throw unsupportedCast(x.getClass(), Array.class);
-  }
-
-  public static BigDecimal toBigDecimal(Object x) {
-    if (x instanceof BigDecimal) {
-      return (BigDecimal) x;
-    } else if (x instanceof BigInteger) {
-      return new BigDecimal((BigInteger) x);
-    } else if (x instanceof Number) {
-      if (x instanceof Double || x instanceof Float) {
-        return new BigDecimal(((Number) x).doubleValue());
-      } else {
-        return new BigDecimal(((Number) x).longValue());
-      }
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
-    } else if (x instanceof String) {
-      return new BigDecimal((String) x);
-    }
-    throw unsupportedCast(x.getClass(), BigDecimal.class);
-  }
-
-  private static boolean toBoolean(Object x) {
-    if (x instanceof Boolean) {
-      return (Boolean) x;
-    } else if (x instanceof Number) {
-      return ((Number) x).intValue() != 0;
-    } else if (x instanceof String) {
-      String s = (String) x;
-      if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
-        return true;
-      } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
-        return false;
-      }
-    }
-    throw unsupportedCast(x.getClass(), Boolean.TYPE);
-  }
-
-  private static byte toByte(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).byteValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? (byte) 1 : (byte) 0;
-    } else if (x instanceof String) {
-      return Byte.parseByte((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Byte.TYPE);
-    }
-  }
-
-  private static byte[] toBytes(Object x) {
-    if (x instanceof byte[]) {
-      return (byte[]) x;
-    }
-    if (x instanceof String) {
-      return ((String) x).getBytes();
-    }
-    throw unsupportedCast(x.getClass(), byte[].class);
-  }
-
-  private static Date toDate(Object x) {
-    if (x instanceof String) {
-      return Date.valueOf((String) x);
-    }
-    return new Date(toLong(x));
-  }
-
-  private static Time toTime(Object x) {
-    if (x instanceof String) {
-      return Time.valueOf((String) x);
-    }
-    return new Time(toLong(x));
-  }
-
-  private static Timestamp toTimestamp(Object x) {
-    if (x instanceof String) {
-      return Timestamp.valueOf((String) x);
-    }
-    return new Timestamp(toLong(x));
-  }
-
-  private static double toDouble(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).doubleValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? 1D : 0D;
-    } else if (x instanceof String) {
-      return Double.parseDouble((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Double.TYPE);
-    }
-  }
-
-  private static float toFloat(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).floatValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? 1F : 0F;
-    } else if (x instanceof String) {
-      return Float.parseFloat((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Float.TYPE);
-    }
-  }
-
-  private static int toInt(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).intValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? 1 : 0;
-    } else if (x instanceof String) {
-      return Integer.parseInt((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Integer.TYPE);
-    }
-  }
-
-  private static long toLong(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).longValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? 1L : 0L;
-    } else if (x instanceof String) {
-      return Long.parseLong((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Long.TYPE);
-    }
-  }
-
-  private static short toShort(Object x) {
-    if (x instanceof Number) {
-      return ((Number) x).shortValue();
-    } else if (x instanceof Boolean) {
-      return (Boolean) x ? (short) 1 : (short) 0;
-    } else if (x instanceof String) {
-      return Short.parseShort((String) x);
-    } else {
-      throw unsupportedCast(x.getClass(), Short.TYPE);
-    }
-  }
-
-  private static String toString(Object x) {
-    if (x instanceof String) {
-      return (String) x;
-    } else if (x instanceof Character
-        || x instanceof Boolean) {
-      return x.toString();
-    }
-    throw unsupportedCast(x.getClass(), String.class);
-  }
-
-  /** Singleton value to denote parameters that have been set to null (as
-   * opposed to not set).
-   *
-   * <p>Not a valid value for a parameter.
-   *
-   * <p>As an enum, it is serializable by Jackson. */
-  private enum Dummy {
-    INSTANCE
-  }
-}
-
-// End AvaticaSite.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
deleted file mode 100644
index 9408a7b..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSqlException.java
+++ /dev/null
@@ -1,138 +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.PrintStream;
-import java.io.PrintWriter;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A client-facing {@link SQLException} which encapsulates errors from the remote Avatica server.
- */
-public class AvaticaSqlException extends SQLException {
-
-  private static final long serialVersionUID = 1L;
-
-  private final String errorMessage;
-  private final List<String> stackTraces;
-  private final String remoteServer;
-
-  /**
-   * Construct the Exception with information from the server.
-   *
-   * @param errorMessage A human-readable error message.
-   * @param errorCode An integer corresponding to a known error.
-   * @param stackTraces Server-side stacktrace.
-   * @param remoteServer The host:port where the Avatica server is located
-   */
-  public AvaticaSqlException(String errorMessage, String sqlState, int errorCode,
-      List<String> stackTraces, String remoteServer) {
-    super("Error " + errorCode + " (" + sqlState + ") : " + errorMessage, sqlState, errorCode);
-    this.errorMessage = errorMessage;
-    this.stackTraces = Objects.requireNonNull(stackTraces);
-    this.remoteServer = remoteServer;
-  }
-
-  public String getErrorMessage() {
-    return errorMessage;
-  }
-
-  /**
-   * @return The stacktraces for exceptions thrown on the Avatica server.
-   */
-  public List<String> getStackTraces() {
-    return stackTraces;
-  }
-
-  /**
-   * @return The host:port for the remote Avatica server. May be null.
-   */
-  public String getRemoteServer() {
-    return remoteServer;
-  }
-
-  // printStackTrace() will get redirected to printStackTrace(PrintStream), don't need to override.
-
-  @Override public void printStackTrace(PrintStream stream) {
-    super.printStackTrace(stream);
-    stream.flush();
-    printServerStackTrace(new PrintStreamOrWriter(stream));
-  }
-
-  @Override public void printStackTrace(PrintWriter writer) {
-    super.printStackTrace(writer);
-    writer.flush();
-    printServerStackTrace(new PrintStreamOrWriter(writer));
-  }
-
-  void printServerStackTrace(PrintStreamOrWriter streamOrWriter) {
-    for (String serverStackTrace : this.stackTraces) {
-      streamOrWriter.println(serverStackTrace);
-    }
-  }
-
-  /**
-   * A class that encapsulates either a PrintStream or a PrintWriter.
-   */
-  private static class PrintStreamOrWriter {
-    /**
-     * Enumeration to differentiate between a PrintStream and a PrintWriter.
-     */
-    private enum Type {
-      STREAM,
-      WRITER
-    }
-
-    private PrintStream stream;
-    private PrintWriter writer;
-    private final Type type;
-
-    public PrintStreamOrWriter(PrintStream stream) {
-      this.stream = stream;
-      type = Type.STREAM;
-    }
-
-    public PrintStreamOrWriter(PrintWriter writer) {
-      this.writer = writer;
-      type = Type.WRITER;
-    }
-
-    /**
-     * Prints the given string to the the provided stream or writer.
-     *
-     * @param string The string to print
-     */
-    public void println(String string) {
-      switch (type) {
-      case STREAM:
-        stream.println(string);
-        stream.flush();
-        return;
-      case WRITER:
-        writer.println(string);
-        writer.flush();
-        return;
-      default:
-        throw new IllegalStateException();
-      }
-    }
-  }
-}
-
-// End AvaticaSqlException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
deleted file mode 100644
index cfd1d45..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
+++ /dev/null
@@ -1,527 +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.remote.TypedValue;
-
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Implementation of {@link java.sql.Statement}
- * for the Avatica engine.
- */
-public abstract class AvaticaStatement
-    implements Statement {
-  /** The default value for {@link Statement#getFetchSize()}. */
-  public static final int DEFAULT_FETCH_SIZE = 100;
-
-  public final AvaticaConnection connection;
-  /** Statement id; unique within connection. */
-  public Meta.StatementHandle handle;
-  protected boolean closed;
-
-  /**
-   * Support for {@link #closeOnCompletion()} method.
-   */
-  protected boolean closeOnCompletion;
-
-  /**
-   * Current result set, or null if the statement is not executing anything.
-   * Any method which modifies this member must synchronize
-   * on the AvaticaStatement.
-   */
-  protected AvaticaResultSet openResultSet;
-
-  /** Current update count. Same lifecycle as {@link #openResultSet}. */
-  protected long updateCount;
-
-  private int queryTimeoutMillis;
-  final int resultSetType;
-  final int resultSetConcurrency;
-  final int resultSetHoldability;
-  private int fetchSize = DEFAULT_FETCH_SIZE;
-  private int fetchDirection;
-  protected long maxRowCount = 0;
-
-  private Meta.Signature signature;
-
-  protected void setSignature(Meta.Signature signature) {
-    this.signature = signature;
-  }
-
-  protected Meta.Signature getSignature() {
-    return signature;
-  }
-
-  public Meta.StatementType getStatementType() {
-    return signature.statementType;
-  }
-
-  /**
-   * Creates an AvaticaStatement.
-   *
-   * @param connection Connection
-   * @param h Statement handle
-   * @param resultSetType Result set type
-   * @param resultSetConcurrency Result set concurrency
-   * @param resultSetHoldability Result set holdability
-   */
-  protected AvaticaStatement(AvaticaConnection connection,
-      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
-      int resultSetHoldability) {
-    this(connection, h, resultSetType, resultSetConcurrency, resultSetHoldability, null);
-  }
-
-  protected AvaticaStatement(AvaticaConnection connection,
-      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
-      int resultSetHoldability, Meta.Signature signature) {
-    this.connection = Objects.requireNonNull(connection);
-    this.resultSetType = resultSetType;
-    this.resultSetConcurrency = resultSetConcurrency;
-    this.resultSetHoldability = resultSetHoldability;
-    this.signature = signature;
-    this.closed = false;
-    if (h == null) {
-      final Meta.ConnectionHandle ch = connection.handle;
-      h = connection.meta.createStatement(ch);
-    }
-    connection.statementMap.put(h.id, this);
-    this.handle = h;
-  }
-
-  /** Returns the identifier of the statement, unique within its connection. */
-  public int getId() {
-    return handle.id;
-  }
-
-  private void checkNotPreparedOrCallable(String s) throws SQLException {
-    if (this instanceof PreparedStatement
-        || this instanceof CallableStatement) {
-      throw connection.helper.createException("Cannot call " + s
-          + " on prepared or callable statement");
-    }
-  }
-
-  protected void executeInternal(String sql) throws SQLException {
-    // reset previous state before moving forward.
-    this.updateCount = -1;
-    try {
-      // In JDBC, maxRowCount = 0 means no limit; in prepare it means LIMIT 0
-      final long maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
-      for (int i = 0; i < connection.maxRetriesPerExecute; i++) {
-        try {
-          Meta.ExecuteResult x =
-              connection.prepareAndExecuteInternal(this, sql, maxRowCount1);
-          return;
-        } catch (NoSuchStatementException e) {
-          resetStatement();
-        }
-      }
-    } catch (RuntimeException e) {
-      throw connection.helper.createException("Error while executing SQL \"" + sql + "\": "
-          + e.getMessage(), e);
-    }
-
-    throw new RuntimeException("Failed to successfully execute query after "
-        + connection.maxRetriesPerExecute + " attempts.");
-  }
-
-  protected void resetStatement() {
-    // Invalidate the old statement
-    connection.statementMap.remove(handle.id);
-    // Get a new one
-    final Meta.ConnectionHandle ch = new Meta.ConnectionHandle(connection.id);
-    Meta.StatementHandle h = connection.meta.createStatement(ch);
-    // Cache it in the connection
-    connection.statementMap.put(h.id, this);
-    // Update the local state and try again
-    this.handle = h;
-  }
-
-  /**
-   * Re-initialize the ResultSet on the server with the given state.
-   * @param state The ResultSet's state.
-   * @param offset Offset into the desired ResultSet
-   * @return True if the ResultSet has more results, false if there are no more results.
-   */
-  protected boolean syncResults(QueryState state, long offset) throws NoSuchStatementException {
-    return connection.meta.syncResults(handle, state, offset);
-  }
-
-  // implement Statement
-
-  public boolean execute(String sql) throws SQLException {
-    checkNotPreparedOrCallable("execute(String)");
-    executeInternal(sql);
-    // Result set is null for DML or DDL.
-    // Result set is closed if user cancelled the query.
-    return openResultSet != null && !openResultSet.isClosed();
-  }
-
-  public ResultSet executeQuery(String sql) throws SQLException {
-    checkNotPreparedOrCallable("executeQuery(String)");
-    try {
-      executeInternal(sql);
-      if (openResultSet == null) {
-        throw connection.helper.createException(
-            "Statement did not return a result set");
-      }
-      return openResultSet;
-    } catch (RuntimeException e) {
-      throw connection.helper.createException("Error while executing SQL \"" + sql + "\": "
-          + e.getMessage(), e);
-    }
-  }
-
-  public final int executeUpdate(String sql) throws SQLException {
-    return (int) executeLargeUpdate(sql);
-  }
-
-  public long executeLargeUpdate(String sql) throws SQLException {
-    checkNotPreparedOrCallable("executeUpdate(String)");
-    executeInternal(sql);
-    return updateCount;
-  }
-
-  public synchronized void close() throws SQLException {
-    try {
-      close_();
-    } catch (RuntimeException e) {
-      throw connection.helper.createException("While closing statement", e);
-    }
-  }
-
-  protected void close_() {
-    if (!closed) {
-      closed = true;
-      if (openResultSet != null) {
-        AvaticaResultSet c = openResultSet;
-        openResultSet = null;
-        c.close();
-      }
-      try {
-        // inform the server to close the resource
-        connection.meta.closeStatement(handle);
-      } finally {
-        // make sure we don't leak on our side
-        connection.statementMap.remove(handle.id);
-      }
-      // If onStatementClose throws, this method will throw an exception (later
-      // converted to SQLException), but this statement still gets closed.
-      connection.driver.handler.onStatementClose(this);
-    }
-  }
-
-  public int getMaxFieldSize() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public void setMaxFieldSize(int max) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public final int getMaxRows() {
-    return (int) getLargeMaxRows();
-  }
-
-  public long getLargeMaxRows() {
-    return maxRowCount;
-  }
-
-  public final void setMaxRows(int maxRowCount) throws SQLException {
-    setLargeMaxRows(maxRowCount);
-  }
-
-  public void setLargeMaxRows(long maxRowCount) throws SQLException {
-    if (maxRowCount < 0) {
-      throw connection.helper.createException(
-          "illegal maxRows value: " + maxRowCount);
-    }
-    this.maxRowCount = maxRowCount;
-  }
-
-  public void setEscapeProcessing(boolean enable) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int getQueryTimeout() throws SQLException {
-    long timeoutSeconds = getQueryTimeoutMillis() / 1000;
-    if (timeoutSeconds > Integer.MAX_VALUE) {
-      return Integer.MAX_VALUE;
-    }
-    if (timeoutSeconds == 0 && getQueryTimeoutMillis() > 0) {
-      // Don't return timeout=0 if e.g. timeoutMillis=500. 0 is special.
-      return 1;
-    }
-    return (int) timeoutSeconds;
-  }
-
-  int getQueryTimeoutMillis() {
-    return queryTimeoutMillis;
-  }
-
-  public void setQueryTimeout(int seconds) throws SQLException {
-    if (seconds < 0) {
-      throw connection.helper.createException(
-          "illegal timeout value " + seconds);
-    }
-    setQueryTimeoutMillis(seconds * 1000);
-  }
-
-  void setQueryTimeoutMillis(int millis) {
-    this.queryTimeoutMillis = millis;
-  }
-
-  public synchronized void cancel() throws SQLException {
-    if (openResultSet != null) {
-      openResultSet.cancel();
-    }
-  }
-
-  public SQLWarning getWarnings() throws SQLException {
-    return null; // no warnings, since warnings are not supported
-  }
-
-  public void clearWarnings() throws SQLException {
-    // no-op since warnings are not supported
-  }
-
-  public void setCursorName(String name) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public ResultSet getResultSet() throws SQLException {
-    // NOTE: result set becomes visible in this member while
-    // executeQueryInternal is still in progress, and before it has
-    // finished executing. Its internal state may not be ready for API
-    // calls. JDBC never claims to be thread-safe! (Except for calls to the
-    // cancel method.) It is not possible to synchronize, because it would
-    // block 'cancel'.
-    return openResultSet;
-  }
-
-  public int getUpdateCount() throws SQLException {
-    return (int) updateCount;
-  }
-
-  public long getLargeUpdateCount() throws SQLException {
-    return updateCount;
-  }
-
-  public boolean getMoreResults() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public void setFetchDirection(int direction) throws SQLException {
-    this.fetchDirection = direction;
-  }
-
-  public int getFetchDirection() {
-    return fetchDirection;
-  }
-
-  public void setFetchSize(int rows) throws SQLException {
-    this.fetchSize = rows;
-  }
-
-  public int getFetchSize() {
-    return fetchSize;
-  }
-
-  public int getResultSetConcurrency() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int getResultSetType() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public void addBatch(String sql) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public void clearBatch() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int[] executeBatch() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public AvaticaConnection getConnection() {
-    return connection;
-  }
-
-  public boolean getMoreResults(int current) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public ResultSet getGeneratedKeys() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int executeUpdate(
-      String sql, int autoGeneratedKeys) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int executeUpdate(
-      String sql, int[] columnIndexes) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int executeUpdate(
-      String sql, String[] columnNames) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public boolean execute(
-      String sql, int autoGeneratedKeys) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public boolean execute(
-      String sql, int[] columnIndexes) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public boolean execute(
-      String sql, String[] columnNames) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public int getResultSetHoldability() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public boolean isClosed() throws SQLException {
-    return closed;
-  }
-
-  public void setPoolable(boolean poolable) throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public boolean isPoolable() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  // implements java.sql.Statement.closeOnCompletion (added in JDK 1.7)
-  public void closeOnCompletion() throws SQLException {
-    closeOnCompletion = true;
-  }
-
-  // implements java.sql.Statement.isCloseOnCompletion (added in JDK 1.7)
-  public boolean isCloseOnCompletion() throws SQLException {
-    return closeOnCompletion;
-  }
-
-  // implement Wrapper
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    if (iface.isInstance(this)) {
-      return iface.cast(this);
-    }
-    throw connection.helper.createException(
-        "does not implement '" + iface + "'");
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return iface.isInstance(this);
-  }
-
-  /**
-   * Executes a prepared statement.
-   *
-   * @param signature Parsed statement
-   * @param isUpdate if the execute is for an update
-   *
-   * @return as specified by {@link java.sql.Statement#execute(String)}
-   * @throws java.sql.SQLException if a database error occurs
-   */
-  protected boolean executeInternal(Meta.Signature signature, boolean isUpdate)
-      throws SQLException {
-    ResultSet resultSet = executeQueryInternal(signature, isUpdate);
-    // user may have cancelled the query
-    if (resultSet.isClosed()) {
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Executes a prepared query, closing any previously open result set.
-   *
-   * @param signature Parsed query
-   * @param isUpdate If the execute is for an update
-   * @return Result set
-   * @throws java.sql.SQLException if a database error occurs
-   */
-  protected ResultSet executeQueryInternal(Meta.Signature signature, boolean isUpdate)
-      throws SQLException {
-    return connection.executeQueryInternal(this, signature, null, null, isUpdate);
-  }
-
-  /**
-   * Called by each child result set when it is closed.
-   *
-   * @param resultSet Result set or cell set
-   */
-  void onResultSetClose(ResultSet resultSet) {
-    if (closeOnCompletion) {
-      close_();
-    }
-  }
-
-  /** Returns the list of values of this statement's parameters.
-   *
-   * <p>Called at execute time. Not a public API.</p>
-   *
-   * <p>The default implementation returns the empty list, because non-prepared
-   * statements have no parameters.</p>
-   *
-   * @see org.apache.calcite.avatica.AvaticaConnection.Trojan#getParameterValues(AvaticaStatement)
-   */
-  protected List<TypedValue> getParameterValues() {
-    return Collections.emptyList();
-  }
-
-  /** Returns a list of bound parameter values.
-   *
-   * <p>If any of the parameters have not been bound, throws.
-   * If parameters have been bound to null, the value in the list is null.
-   */
-  protected List<TypedValue> getBoundParameterValues() throws SQLException {
-    final List<TypedValue> parameterValues = getParameterValues();
-    for (Object parameterValue : parameterValues) {
-      if (parameterValue == null) {
-        throw new SQLException("unbound parameter");
-      }
-    }
-    return parameterValues;
-  }
-}
-
-// End AvaticaStatement.java


[10/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index 7d5cef9..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/proto/Common.java
+++ /dev/null
@@ -1,17128 +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.
- */
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: common.proto
-
-package org.apache.calcite.avatica.proto;
-
-@SuppressWarnings({"unused", "rawtypes"}) public final class Common {
-  private Common() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  /**
-   * Protobuf enum {@code StatementType}
-   *
-   * <pre>
-   * Has to be consistent with Meta.StatementType
-   * </pre>
-   */
-  public enum StatementType
-      implements com.google.protobuf.ProtocolMessageEnum {
-    /**
-     * <code>SELECT = 0;</code>
-     */
-    SELECT(0, 0),
-    /**
-     * <code>INSERT = 1;</code>
-     */
-    INSERT(1, 1),
-    /**
-     * <code>UPDATE = 2;</code>
-     */
-    UPDATE(2, 2),
-    /**
-     * <code>DELETE = 3;</code>
-     */
-    DELETE(3, 3),
-    /**
-     * <code>UPSERT = 4;</code>
-     */
-    UPSERT(4, 4),
-    /**
-     * <code>MERGE = 5;</code>
-     */
-    MERGE(5, 5),
-    /**
-     * <code>OTHER_DML = 6;</code>
-     */
-    OTHER_DML(6, 6),
-    /**
-     * <code>CREATE = 7;</code>
-     */
-    CREATE(7, 7),
-    /**
-     * <code>DROP = 8;</code>
-     */
-    DROP(8, 8),
-    /**
-     * <code>ALTER = 9;</code>
-     */
-    ALTER(9, 9),
-    /**
-     * <code>OTHER_DDL = 10;</code>
-     */
-    OTHER_DDL(10, 10),
-    /**
-     * <code>CALL = 11;</code>
-     */
-    CALL(11, 11),
-    UNRECOGNIZED(-1, -1),
-    ;
-
-    /**
-     * <code>SELECT = 0;</code>
-     */
-    public static final int SELECT_VALUE = 0;
-    /**
-     * <code>INSERT = 1;</code>
-     */
-    public static final int INSERT_VALUE = 1;
-    /**
-     * <code>UPDATE = 2;</code>
-     */
-    public static final int UPDATE_VALUE = 2;
-    /**
-     * <code>DELETE = 3;</code>
-     */
-    public static final int DELETE_VALUE = 3;
-    /**
-     * <code>UPSERT = 4;</code>
-     */
-    public static final int UPSERT_VALUE = 4;
-    /**
-     * <code>MERGE = 5;</code>
-     */
-    public static final int MERGE_VALUE = 5;
-    /**
-     * <code>OTHER_DML = 6;</code>
-     */
-    public static final int OTHER_DML_VALUE = 6;
-    /**
-     * <code>CREATE = 7;</code>
-     */
-    public static final int CREATE_VALUE = 7;
-    /**
-     * <code>DROP = 8;</code>
-     */
-    public static final int DROP_VALUE = 8;
-    /**
-     * <code>ALTER = 9;</code>
-     */
-    public static final int ALTER_VALUE = 9;
-    /**
-     * <code>OTHER_DDL = 10;</code>
-     */
-    public static final int OTHER_DDL_VALUE = 10;
-    /**
-     * <code>CALL = 11;</code>
-     */
-    public static final int CALL_VALUE = 11;
-
-
-    public final int getNumber() {
-      if (index == -1) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    public static StatementType valueOf(int value) {
-      switch (value) {
-        case 0: return SELECT;
-        case 1: return INSERT;
-        case 2: return UPDATE;
-        case 3: return DELETE;
-        case 4: return UPSERT;
-        case 5: return MERGE;
-        case 6: return OTHER_DML;
-        case 7: return CREATE;
-        case 8: return DROP;
-        case 9: return ALTER;
-        case 10: return OTHER_DDL;
-        case 11: return CALL;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<StatementType>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        StatementType> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<StatementType>() {
-            public StatementType findValueByNumber(int number) {
-              return StatementType.valueOf(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(0);
-    }
-
-    private static final StatementType[] VALUES = values();
-
-    public static StatementType valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int index;
-    private final int value;
-
-    private StatementType(int index, int value) {
-      this.index = index;
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:StatementType)
-  }
-
-  /**
-   * Protobuf enum {@code Rep}
-   */
-  public enum Rep
-      implements com.google.protobuf.ProtocolMessageEnum {
-    /**
-     * <code>PRIMITIVE_BOOLEAN = 0;</code>
-     */
-    PRIMITIVE_BOOLEAN(0, 0),
-    /**
-     * <code>PRIMITIVE_BYTE = 1;</code>
-     */
-    PRIMITIVE_BYTE(1, 1),
-    /**
-     * <code>PRIMITIVE_CHAR = 2;</code>
-     */
-    PRIMITIVE_CHAR(2, 2),
-    /**
-     * <code>PRIMITIVE_SHORT = 3;</code>
-     */
-    PRIMITIVE_SHORT(3, 3),
-    /**
-     * <code>PRIMITIVE_INT = 4;</code>
-     */
-    PRIMITIVE_INT(4, 4),
-    /**
-     * <code>PRIMITIVE_LONG = 5;</code>
-     */
-    PRIMITIVE_LONG(5, 5),
-    /**
-     * <code>PRIMITIVE_FLOAT = 6;</code>
-     */
-    PRIMITIVE_FLOAT(6, 6),
-    /**
-     * <code>PRIMITIVE_DOUBLE = 7;</code>
-     */
-    PRIMITIVE_DOUBLE(7, 7),
-    /**
-     * <code>BOOLEAN = 8;</code>
-     */
-    BOOLEAN(8, 8),
-    /**
-     * <code>BYTE = 9;</code>
-     */
-    BYTE(9, 9),
-    /**
-     * <code>CHARACTER = 10;</code>
-     */
-    CHARACTER(10, 10),
-    /**
-     * <code>SHORT = 11;</code>
-     */
-    SHORT(11, 11),
-    /**
-     * <code>INTEGER = 12;</code>
-     */
-    INTEGER(12, 12),
-    /**
-     * <code>LONG = 13;</code>
-     */
-    LONG(13, 13),
-    /**
-     * <code>FLOAT = 14;</code>
-     */
-    FLOAT(14, 14),
-    /**
-     * <code>DOUBLE = 15;</code>
-     */
-    DOUBLE(15, 15),
-    /**
-     * <code>BIG_INTEGER = 25;</code>
-     */
-    BIG_INTEGER(16, 25),
-    /**
-     * <code>BIG_DECIMAL = 26;</code>
-     */
-    BIG_DECIMAL(17, 26),
-    /**
-     * <code>JAVA_SQL_TIME = 16;</code>
-     */
-    JAVA_SQL_TIME(18, 16),
-    /**
-     * <code>JAVA_SQL_TIMESTAMP = 17;</code>
-     */
-    JAVA_SQL_TIMESTAMP(19, 17),
-    /**
-     * <code>JAVA_SQL_DATE = 18;</code>
-     */
-    JAVA_SQL_DATE(20, 18),
-    /**
-     * <code>JAVA_UTIL_DATE = 19;</code>
-     */
-    JAVA_UTIL_DATE(21, 19),
-    /**
-     * <code>BYTE_STRING = 20;</code>
-     */
-    BYTE_STRING(22, 20),
-    /**
-     * <code>STRING = 21;</code>
-     */
-    STRING(23, 21),
-    /**
-     * <code>NUMBER = 22;</code>
-     */
-    NUMBER(24, 22),
-    /**
-     * <code>OBJECT = 23;</code>
-     */
-    OBJECT(25, 23),
-    /**
-     * <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),
-    ;
-
-    /**
-     * <code>PRIMITIVE_BOOLEAN = 0;</code>
-     */
-    public static final int PRIMITIVE_BOOLEAN_VALUE = 0;
-    /**
-     * <code>PRIMITIVE_BYTE = 1;</code>
-     */
-    public static final int PRIMITIVE_BYTE_VALUE = 1;
-    /**
-     * <code>PRIMITIVE_CHAR = 2;</code>
-     */
-    public static final int PRIMITIVE_CHAR_VALUE = 2;
-    /**
-     * <code>PRIMITIVE_SHORT = 3;</code>
-     */
-    public static final int PRIMITIVE_SHORT_VALUE = 3;
-    /**
-     * <code>PRIMITIVE_INT = 4;</code>
-     */
-    public static final int PRIMITIVE_INT_VALUE = 4;
-    /**
-     * <code>PRIMITIVE_LONG = 5;</code>
-     */
-    public static final int PRIMITIVE_LONG_VALUE = 5;
-    /**
-     * <code>PRIMITIVE_FLOAT = 6;</code>
-     */
-    public static final int PRIMITIVE_FLOAT_VALUE = 6;
-    /**
-     * <code>PRIMITIVE_DOUBLE = 7;</code>
-     */
-    public static final int PRIMITIVE_DOUBLE_VALUE = 7;
-    /**
-     * <code>BOOLEAN = 8;</code>
-     */
-    public static final int BOOLEAN_VALUE = 8;
-    /**
-     * <code>BYTE = 9;</code>
-     */
-    public static final int BYTE_VALUE = 9;
-    /**
-     * <code>CHARACTER = 10;</code>
-     */
-    public static final int CHARACTER_VALUE = 10;
-    /**
-     * <code>SHORT = 11;</code>
-     */
-    public static final int SHORT_VALUE = 11;
-    /**
-     * <code>INTEGER = 12;</code>
-     */
-    public static final int INTEGER_VALUE = 12;
-    /**
-     * <code>LONG = 13;</code>
-     */
-    public static final int LONG_VALUE = 13;
-    /**
-     * <code>FLOAT = 14;</code>
-     */
-    public static final int FLOAT_VALUE = 14;
-    /**
-     * <code>DOUBLE = 15;</code>
-     */
-    public static final int DOUBLE_VALUE = 15;
-    /**
-     * <code>BIG_INTEGER = 25;</code>
-     */
-    public static final int BIG_INTEGER_VALUE = 25;
-    /**
-     * <code>BIG_DECIMAL = 26;</code>
-     */
-    public static final int BIG_DECIMAL_VALUE = 26;
-    /**
-     * <code>JAVA_SQL_TIME = 16;</code>
-     */
-    public static final int JAVA_SQL_TIME_VALUE = 16;
-    /**
-     * <code>JAVA_SQL_TIMESTAMP = 17;</code>
-     */
-    public static final int JAVA_SQL_TIMESTAMP_VALUE = 17;
-    /**
-     * <code>JAVA_SQL_DATE = 18;</code>
-     */
-    public static final int JAVA_SQL_DATE_VALUE = 18;
-    /**
-     * <code>JAVA_UTIL_DATE = 19;</code>
-     */
-    public static final int JAVA_UTIL_DATE_VALUE = 19;
-    /**
-     * <code>BYTE_STRING = 20;</code>
-     */
-    public static final int BYTE_STRING_VALUE = 20;
-    /**
-     * <code>STRING = 21;</code>
-     */
-    public static final int STRING_VALUE = 21;
-    /**
-     * <code>NUMBER = 22;</code>
-     */
-    public static final int NUMBER_VALUE = 22;
-    /**
-     * <code>OBJECT = 23;</code>
-     */
-    public static final int OBJECT_VALUE = 23;
-    /**
-     * <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() {
-      if (index == -1) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    public static Rep valueOf(int value) {
-      switch (value) {
-        case 0: return PRIMITIVE_BOOLEAN;
-        case 1: return PRIMITIVE_BYTE;
-        case 2: return PRIMITIVE_CHAR;
-        case 3: return PRIMITIVE_SHORT;
-        case 4: return PRIMITIVE_INT;
-        case 5: return PRIMITIVE_LONG;
-        case 6: return PRIMITIVE_FLOAT;
-        case 7: return PRIMITIVE_DOUBLE;
-        case 8: return BOOLEAN;
-        case 9: return BYTE;
-        case 10: return CHARACTER;
-        case 11: return SHORT;
-        case 12: return INTEGER;
-        case 13: return LONG;
-        case 14: return FLOAT;
-        case 15: return DOUBLE;
-        case 25: return BIG_INTEGER;
-        case 26: return BIG_DECIMAL;
-        case 16: return JAVA_SQL_TIME;
-        case 17: return JAVA_SQL_TIMESTAMP;
-        case 18: return JAVA_SQL_DATE;
-        case 19: return JAVA_UTIL_DATE;
-        case 20: return BYTE_STRING;
-        case 21: return STRING;
-        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;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Rep>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Rep> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Rep>() {
-            public Rep findValueByNumber(int number) {
-              return Rep.valueOf(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(1);
-    }
-
-    private static final Rep[] VALUES = values();
-
-    public static Rep valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int index;
-    private final int value;
-
-    private Rep(int index, int value) {
-      this.index = index;
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:Rep)
-  }
-
-  /**
-   * Protobuf enum {@code Severity}
-   *
-   * <pre>
-   * The severity of some unexpected outcome to an operation.
-   * Protobuf enum values must be unique across all other enums
-   * </pre>
-   */
-  public enum Severity
-      implements com.google.protobuf.ProtocolMessageEnum {
-    /**
-     * <code>UNKNOWN_SEVERITY = 0;</code>
-     */
-    UNKNOWN_SEVERITY(0, 0),
-    /**
-     * <code>FATAL_SEVERITY = 1;</code>
-     */
-    FATAL_SEVERITY(1, 1),
-    /**
-     * <code>ERROR_SEVERITY = 2;</code>
-     */
-    ERROR_SEVERITY(2, 2),
-    /**
-     * <code>WARNING_SEVERITY = 3;</code>
-     */
-    WARNING_SEVERITY(3, 3),
-    UNRECOGNIZED(-1, -1),
-    ;
-
-    /**
-     * <code>UNKNOWN_SEVERITY = 0;</code>
-     */
-    public static final int UNKNOWN_SEVERITY_VALUE = 0;
-    /**
-     * <code>FATAL_SEVERITY = 1;</code>
-     */
-    public static final int FATAL_SEVERITY_VALUE = 1;
-    /**
-     * <code>ERROR_SEVERITY = 2;</code>
-     */
-    public static final int ERROR_SEVERITY_VALUE = 2;
-    /**
-     * <code>WARNING_SEVERITY = 3;</code>
-     */
-    public static final int WARNING_SEVERITY_VALUE = 3;
-
-
-    public final int getNumber() {
-      if (index == -1) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    public static Severity valueOf(int value) {
-      switch (value) {
-        case 0: return UNKNOWN_SEVERITY;
-        case 1: return FATAL_SEVERITY;
-        case 2: return ERROR_SEVERITY;
-        case 3: return WARNING_SEVERITY;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Severity>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Severity> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Severity>() {
-            public Severity findValueByNumber(int number) {
-              return Severity.valueOf(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(2);
-    }
-
-    private static final Severity[] VALUES = values();
-
-    public static Severity valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int index;
-    private final int value;
-
-    private Severity(int index, int value) {
-      this.index = index;
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:Severity)
-  }
-
-  /**
-   * Protobuf enum {@code MetaDataOperation}
-   *
-   * <pre>
-   * Enumeration corresponding to DatabaseMetaData operations
-   * </pre>
-   */
-  public enum MetaDataOperation
-      implements com.google.protobuf.ProtocolMessageEnum {
-    /**
-     * <code>GET_ATTRIBUTES = 0;</code>
-     */
-    GET_ATTRIBUTES(0, 0),
-    /**
-     * <code>GET_BEST_ROW_IDENTIFIER = 1;</code>
-     */
-    GET_BEST_ROW_IDENTIFIER(1, 1),
-    /**
-     * <code>GET_CATALOGS = 2;</code>
-     */
-    GET_CATALOGS(2, 2),
-    /**
-     * <code>GET_CLIENT_INFO_PROPERTIES = 3;</code>
-     */
-    GET_CLIENT_INFO_PROPERTIES(3, 3),
-    /**
-     * <code>GET_COLUMN_PRIVILEGES = 4;</code>
-     */
-    GET_COLUMN_PRIVILEGES(4, 4),
-    /**
-     * <code>GET_COLUMNS = 5;</code>
-     */
-    GET_COLUMNS(5, 5),
-    /**
-     * <code>GET_CROSS_REFERENCE = 6;</code>
-     */
-    GET_CROSS_REFERENCE(6, 6),
-    /**
-     * <code>GET_EXPORTED_KEYS = 7;</code>
-     */
-    GET_EXPORTED_KEYS(7, 7),
-    /**
-     * <code>GET_FUNCTION_COLUMNS = 8;</code>
-     */
-    GET_FUNCTION_COLUMNS(8, 8),
-    /**
-     * <code>GET_FUNCTIONS = 9;</code>
-     */
-    GET_FUNCTIONS(9, 9),
-    /**
-     * <code>GET_IMPORTED_KEYS = 10;</code>
-     */
-    GET_IMPORTED_KEYS(10, 10),
-    /**
-     * <code>GET_INDEX_INFO = 11;</code>
-     */
-    GET_INDEX_INFO(11, 11),
-    /**
-     * <code>GET_PRIMARY_KEYS = 12;</code>
-     */
-    GET_PRIMARY_KEYS(12, 12),
-    /**
-     * <code>GET_PROCEDURE_COLUMNS = 13;</code>
-     */
-    GET_PROCEDURE_COLUMNS(13, 13),
-    /**
-     * <code>GET_PROCEDURES = 14;</code>
-     */
-    GET_PROCEDURES(14, 14),
-    /**
-     * <code>GET_PSEUDO_COLUMNS = 15;</code>
-     */
-    GET_PSEUDO_COLUMNS(15, 15),
-    /**
-     * <code>GET_SCHEMAS = 16;</code>
-     */
-    GET_SCHEMAS(16, 16),
-    /**
-     * <code>GET_SCHEMAS_WITH_ARGS = 17;</code>
-     */
-    GET_SCHEMAS_WITH_ARGS(17, 17),
-    /**
-     * <code>GET_SUPER_TABLES = 18;</code>
-     */
-    GET_SUPER_TABLES(18, 18),
-    /**
-     * <code>GET_SUPER_TYPES = 19;</code>
-     */
-    GET_SUPER_TYPES(19, 19),
-    /**
-     * <code>GET_TABLE_PRIVILEGES = 20;</code>
-     */
-    GET_TABLE_PRIVILEGES(20, 20),
-    /**
-     * <code>GET_TABLES = 21;</code>
-     */
-    GET_TABLES(21, 21),
-    /**
-     * <code>GET_TABLE_TYPES = 22;</code>
-     */
-    GET_TABLE_TYPES(22, 22),
-    /**
-     * <code>GET_TYPE_INFO = 23;</code>
-     */
-    GET_TYPE_INFO(23, 23),
-    /**
-     * <code>GET_UDTS = 24;</code>
-     */
-    GET_UDTS(24, 24),
-    /**
-     * <code>GET_VERSION_COLUMNS = 25;</code>
-     */
-    GET_VERSION_COLUMNS(25, 25),
-    UNRECOGNIZED(-1, -1),
-    ;
-
-    /**
-     * <code>GET_ATTRIBUTES = 0;</code>
-     */
-    public static final int GET_ATTRIBUTES_VALUE = 0;
-    /**
-     * <code>GET_BEST_ROW_IDENTIFIER = 1;</code>
-     */
-    public static final int GET_BEST_ROW_IDENTIFIER_VALUE = 1;
-    /**
-     * <code>GET_CATALOGS = 2;</code>
-     */
-    public static final int GET_CATALOGS_VALUE = 2;
-    /**
-     * <code>GET_CLIENT_INFO_PROPERTIES = 3;</code>
-     */
-    public static final int GET_CLIENT_INFO_PROPERTIES_VALUE = 3;
-    /**
-     * <code>GET_COLUMN_PRIVILEGES = 4;</code>
-     */
-    public static final int GET_COLUMN_PRIVILEGES_VALUE = 4;
-    /**
-     * <code>GET_COLUMNS = 5;</code>
-     */
-    public static final int GET_COLUMNS_VALUE = 5;
-    /**
-     * <code>GET_CROSS_REFERENCE = 6;</code>
-     */
-    public static final int GET_CROSS_REFERENCE_VALUE = 6;
-    /**
-     * <code>GET_EXPORTED_KEYS = 7;</code>
-     */
-    public static final int GET_EXPORTED_KEYS_VALUE = 7;
-    /**
-     * <code>GET_FUNCTION_COLUMNS = 8;</code>
-     */
-    public static final int GET_FUNCTION_COLUMNS_VALUE = 8;
-    /**
-     * <code>GET_FUNCTIONS = 9;</code>
-     */
-    public static final int GET_FUNCTIONS_VALUE = 9;
-    /**
-     * <code>GET_IMPORTED_KEYS = 10;</code>
-     */
-    public static final int GET_IMPORTED_KEYS_VALUE = 10;
-    /**
-     * <code>GET_INDEX_INFO = 11;</code>
-     */
-    public static final int GET_INDEX_INFO_VALUE = 11;
-    /**
-     * <code>GET_PRIMARY_KEYS = 12;</code>
-     */
-    public static final int GET_PRIMARY_KEYS_VALUE = 12;
-    /**
-     * <code>GET_PROCEDURE_COLUMNS = 13;</code>
-     */
-    public static final int GET_PROCEDURE_COLUMNS_VALUE = 13;
-    /**
-     * <code>GET_PROCEDURES = 14;</code>
-     */
-    public static final int GET_PROCEDURES_VALUE = 14;
-    /**
-     * <code>GET_PSEUDO_COLUMNS = 15;</code>
-     */
-    public static final int GET_PSEUDO_COLUMNS_VALUE = 15;
-    /**
-     * <code>GET_SCHEMAS = 16;</code>
-     */
-    public static final int GET_SCHEMAS_VALUE = 16;
-    /**
-     * <code>GET_SCHEMAS_WITH_ARGS = 17;</code>
-     */
-    public static final int GET_SCHEMAS_WITH_ARGS_VALUE = 17;
-    /**
-     * <code>GET_SUPER_TABLES = 18;</code>
-     */
-    public static final int GET_SUPER_TABLES_VALUE = 18;
-    /**
-     * <code>GET_SUPER_TYPES = 19;</code>
-     */
-    public static final int GET_SUPER_TYPES_VALUE = 19;
-    /**
-     * <code>GET_TABLE_PRIVILEGES = 20;</code>
-     */
-    public static final int GET_TABLE_PRIVILEGES_VALUE = 20;
-    /**
-     * <code>GET_TABLES = 21;</code>
-     */
-    public static final int GET_TABLES_VALUE = 21;
-    /**
-     * <code>GET_TABLE_TYPES = 22;</code>
-     */
-    public static final int GET_TABLE_TYPES_VALUE = 22;
-    /**
-     * <code>GET_TYPE_INFO = 23;</code>
-     */
-    public static final int GET_TYPE_INFO_VALUE = 23;
-    /**
-     * <code>GET_UDTS = 24;</code>
-     */
-    public static final int GET_UDTS_VALUE = 24;
-    /**
-     * <code>GET_VERSION_COLUMNS = 25;</code>
-     */
-    public static final int GET_VERSION_COLUMNS_VALUE = 25;
-
-
-    public final int getNumber() {
-      if (index == -1) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    public static MetaDataOperation valueOf(int value) {
-      switch (value) {
-        case 0: return GET_ATTRIBUTES;
-        case 1: return GET_BEST_ROW_IDENTIFIER;
-        case 2: return GET_CATALOGS;
-        case 3: return GET_CLIENT_INFO_PROPERTIES;
-        case 4: return GET_COLUMN_PRIVILEGES;
-        case 5: return GET_COLUMNS;
-        case 6: return GET_CROSS_REFERENCE;
-        case 7: return GET_EXPORTED_KEYS;
-        case 8: return GET_FUNCTION_COLUMNS;
-        case 9: return GET_FUNCTIONS;
-        case 10: return GET_IMPORTED_KEYS;
-        case 11: return GET_INDEX_INFO;
-        case 12: return GET_PRIMARY_KEYS;
-        case 13: return GET_PROCEDURE_COLUMNS;
-        case 14: return GET_PROCEDURES;
-        case 15: return GET_PSEUDO_COLUMNS;
-        case 16: return GET_SCHEMAS;
-        case 17: return GET_SCHEMAS_WITH_ARGS;
-        case 18: return GET_SUPER_TABLES;
-        case 19: return GET_SUPER_TYPES;
-        case 20: return GET_TABLE_PRIVILEGES;
-        case 21: return GET_TABLES;
-        case 22: return GET_TABLE_TYPES;
-        case 23: return GET_TYPE_INFO;
-        case 24: return GET_UDTS;
-        case 25: return GET_VERSION_COLUMNS;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<MetaDataOperation>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        MetaDataOperation> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<MetaDataOperation>() {
-            public MetaDataOperation findValueByNumber(int number) {
-              return MetaDataOperation.valueOf(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(3);
-    }
-
-    private static final MetaDataOperation[] VALUES = values();
-
-    public static MetaDataOperation valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int index;
-    private final int value;
-
-    private MetaDataOperation(int index, int value) {
-      this.index = index;
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:MetaDataOperation)
-  }
-
-  /**
-   * Protobuf enum {@code StateType}
-   */
-  public enum StateType
-      implements com.google.protobuf.ProtocolMessageEnum {
-    /**
-     * <code>SQL = 0;</code>
-     */
-    SQL(0, 0),
-    /**
-     * <code>METADATA = 1;</code>
-     */
-    METADATA(1, 1),
-    UNRECOGNIZED(-1, -1),
-    ;
-
-    /**
-     * <code>SQL = 0;</code>
-     */
-    public static final int SQL_VALUE = 0;
-    /**
-     * <code>METADATA = 1;</code>
-     */
-    public static final int METADATA_VALUE = 1;
-
-
-    public final int getNumber() {
-      if (index == -1) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    public static StateType valueOf(int value) {
-      switch (value) {
-        case 0: return SQL;
-        case 1: return METADATA;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<StateType>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        StateType> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<StateType>() {
-            public StateType findValueByNumber(int number) {
-              return StateType.valueOf(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return org.apache.calcite.avatica.proto.Common.getDescriptor().getEnumTypes().get(4);
-    }
-
-    private static final StateType[] VALUES = values();
-
-    public static StateType valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int index;
-    private final int value;
-
-    private StateType(int index, int value) {
-      this.index = index;
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:StateType)
-  }
-
-  public interface ConnectionPropertiesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:ConnectionProperties)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional bool is_dirty = 1;</code>
-     */
-    boolean getIsDirty();
-
-    /**
-     * <code>optional bool auto_commit = 2;</code>
-     */
-    boolean getAutoCommit();
-
-    /**
-     * <code>optional bool has_auto_commit = 7;</code>
-     *
-     * <pre>
-     * field is a Boolean, need to discern null and default value
-     * </pre>
-     */
-    boolean getHasAutoCommit();
-
-    /**
-     * <code>optional bool read_only = 3;</code>
-     */
-    boolean getReadOnly();
-
-    /**
-     * <code>optional bool has_read_only = 8;</code>
-     *
-     * <pre>
-     * field is a Boolean, need to discern null and default value
-     * </pre>
-     */
-    boolean getHasReadOnly();
-
-    /**
-     * <code>optional uint32 transaction_isolation = 4;</code>
-     */
-    int getTransactionIsolation();
-
-    /**
-     * <code>optional string catalog = 5;</code>
-     */
-    java.lang.String getCatalog();
-    /**
-     * <code>optional string catalog = 5;</code>
-     */
-    com.google.protobuf.ByteString
-        getCatalogBytes();
-
-    /**
-     * <code>optional string schema = 6;</code>
-     */
-    java.lang.String getSchema();
-    /**
-     * <code>optional string schema = 6;</code>
-     */
-    com.google.protobuf.ByteString
-        getSchemaBytes();
-  }
-  /**
-   * Protobuf type {@code ConnectionProperties}
-   *
-   * <pre>
-   * Details about a connection
-   * </pre>
-   */
-  public  static final class ConnectionProperties extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:ConnectionProperties)
-      ConnectionPropertiesOrBuilder {
-    // Use ConnectionProperties.newBuilder() to construct.
-    private ConnectionProperties(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private ConnectionProperties() {
-      isDirty_ = false;
-      autoCommit_ = false;
-      hasAutoCommit_ = false;
-      readOnly_ = false;
-      hasReadOnly_ = false;
-      transactionIsolation_ = 0;
-      catalog_ = "";
-      schema_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private ConnectionProperties(
-        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: {
-
-              isDirty_ = input.readBool();
-              break;
-            }
-            case 16: {
-
-              autoCommit_ = input.readBool();
-              break;
-            }
-            case 24: {
-
-              readOnly_ = input.readBool();
-              break;
-            }
-            case 32: {
-
-              transactionIsolation_ = input.readUInt32();
-              break;
-            }
-            case 42: {
-              String s = input.readStringRequireUtf8();
-
-              catalog_ = s;
-              break;
-            }
-            case 50: {
-              String s = input.readStringRequireUtf8();
-
-              schema_ = s;
-              break;
-            }
-            case 56: {
-
-              hasAutoCommit_ = input.readBool();
-              break;
-            }
-            case 64: {
-
-              hasReadOnly_ = 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_ConnectionProperties_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Common.ConnectionProperties.class, org.apache.calcite.avatica.proto.Common.ConnectionProperties.Builder.class);
-    }
-
-    public static final int IS_DIRTY_FIELD_NUMBER = 1;
-    private boolean isDirty_;
-    /**
-     * <code>optional bool is_dirty = 1;</code>
-     */
-    public boolean getIsDirty() {
-      return isDirty_;
-    }
-
-    public static final int AUTO_COMMIT_FIELD_NUMBER = 2;
-    private boolean autoCommit_;
-    /**
-     * <code>optional bool auto_commit = 2;</code>
-     */
-    public boolean getAutoCommit() {
-      return autoCommit_;
-    }
-
-    public static final int HAS_AUTO_COMMIT_FIELD_NUMBER = 7;
-    private boolean hasAutoCommit_;
-    /**
-     * <code>optional bool has_auto_commit = 7;</code>
-     *
-     * <pre>
-     * field is a Boolean, need to discern null and default value
-     * </pre>
-     */
-    public boolean getHasAutoCommit() {
-      return hasAutoCommit_;
-    }
-
-    public static final int READ_ONLY_FIELD_NUMBER = 3;
-    private boolean readOnly_;
-    /**
-     * <code>optional bool read_only = 3;</code>
-     */
-    public boolean getReadOnly() {
-      return readOnly_;
-    }
-
-    public static final int HAS_READ_ONLY_FIELD_NUMBER = 8;
-    private boolean hasReadOnly_;
-    /**
-     * <code>optional bool has_read_only = 8;</code>
-     *
-     * <pre>
-     * field is a Boolean, need to discern null and default value
-     * </pre>
-     */
-    public boolean getHasReadOnly() {
-      return hasReadOnly_;
-    }
-
-    public static final int TRANSACTION_ISOLATION_FIELD_NUMBER = 4;
-    private int transactionIsolation_;
-    /**
-     * <code>optional uint32 transaction_isolation = 4;</code>
-     */
-    public int getTransactionIsolation() {
-      return transactionIsolation_;
-    }
-
-    public static final int CATALOG_FIELD_NUMBER = 5;
-    private volatile java.lang.Object catalog_;
-    /**
-     * <code>optional string catalog = 5;</code>
-     */
-    public java.lang.String getCatalog() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        catalog_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string catalog = 5;</code>
-     */
-    public com.google.protobuf.ByteString
-        getCatalogBytes() {
-      java.lang.Object ref = catalog_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        catalog_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int SCHEMA_FIELD_NUMBER = 6;
-    private volatile java.lang.Object schema_;
-    /**
-     * <code>optional string schema = 6;</code>
-     */
-    public java.lang.String getSchema() {
-      java.lang.Object ref = schema_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        schema_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string schema = 6;</code>
-     */
-    public com.google.protobuf.ByteString
-        getSchemaBytes() {
-      java.lang.Object ref = schema_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        schema_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    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 {
-      if (isDirty_ != false) {
-        output.writeBool(1, isDirty_);
-      }
-      if (autoCommit_ != false) {
-        output.writeBool(2, autoCommit_);
-      }
-      if (readOnly_ != false) {
-        output.writeBool(3, readOnly_);
-      }
-      if (transactionIsolation_ != 0) {
-        output.writeUInt32(4, transactionIsolation_);
-      }
-      if (!getCatalogBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 5, catalog_);
-      }
-      if (!getSchemaBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 6, schema_);
-      }
-      if (hasAutoCommit_ != false) {
-        output.writeBool(7, hasAutoCommit_);
-      }
-      if (hasReadOnly_ != false) {
-        output.writeBool(8, hasReadOnly_);
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (isDirty_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(1, isDirty_);
-      }
-      if (autoCommit_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(2, autoCommit_);
-      }
-      if (readOnly_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(3, readOnly_);
-      }
-      if (transactionIsolation_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(4, transactionIsolation_);
-      }
-      if (!getCatalogBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(5, catalog_);
-      }
-      if (!getSchemaBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(6, schema_);
-      }
-      if (hasAutoCommit_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(7, hasAutoCommit_);
-      }
-      if (hasReadOnly_ != false) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(8, hasReadOnly_);
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties 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.ConnectionProperties 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 ConnectionProperties}
-     *
-     * <pre>
-     * Details about a connection
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:ConnectionProperties)
-        org.apache.calcite.avatica.proto.Common.ConnectionPropertiesOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Common.ConnectionProperties.class, org.apache.calcite.avatica.proto.Common.ConnectionProperties.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Common.ConnectionProperties.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        isDirty_ = false;
-
-        autoCommit_ = false;
-
-        hasAutoCommit_ = false;
-
-        readOnly_ = false;
-
-        hasReadOnly_ = false;
-
-        transactionIsolation_ = 0;
-
-        catalog_ = "";
-
-        schema_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_ConnectionProperties_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Common.ConnectionProperties.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Common.ConnectionProperties build() {
-        org.apache.calcite.avatica.proto.Common.ConnectionProperties result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Common.ConnectionProperties buildPartial() {
-        org.apache.calcite.avatica.proto.Common.ConnectionProperties result = new org.apache.calcite.avatica.proto.Common.ConnectionProperties(this);
-        result.isDirty_ = isDirty_;
-        result.autoCommit_ = autoCommit_;
-        result.hasAutoCommit_ = hasAutoCommit_;
-        result.readOnly_ = readOnly_;
-        result.hasReadOnly_ = hasReadOnly_;
-        result.transactionIsolation_ = transactionIsolation_;
-        result.catalog_ = catalog_;
-        result.schema_ = schema_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Common.ConnectionProperties) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Common.ConnectionProperties)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Common.ConnectionProperties other) {
-        if (other == org.apache.calcite.avatica.proto.Common.ConnectionProperties.getDefaultInstance()) return this;
-        if (other.getIsDirty() != false) {
-          setIsDirty(other.getIsDirty());
-        }
-        if (other.getAutoCommit() != false) {
-          setAutoCommit(other.getAutoCommit());
-        }
-        if (other.getHasAutoCommit() != false) {
-          setHasAutoCommit(other.getHasAutoCommit());
-        }
-        if (other.getReadOnly() != false) {
-          setReadOnly(other.getReadOnly());
-        }
-        if (other.getHasReadOnly() != false) {
-          setHasReadOnly(other.getHasReadOnly());
-        }
-        if (other.getTransactionIsolation() != 0) {
-          setTransactionIsolation(other.getTransactionIsolation());
-        }
-        if (!other.getCatalog().isEmpty()) {
-          catalog_ = other.catalog_;
-          onChanged();
-        }
-        if (!other.getSchema().isEmpty()) {
-          schema_ = other.schema_;
-          onChanged();
-        }
-        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.ConnectionProperties parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Common.ConnectionProperties) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private boolean isDirty_ ;
-      /**
-       * <code>optional bool is_dirty = 1;</code>
-       */
-      public boolean getIsDirty() {
-        return isDirty_;
-      }
-      /**
-       * <code>optional bool is_dirty = 1;</code>
-       */
-      public Builder setIsDirty(boolean value) {
-        
-        isDirty_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool is_dirty = 1;</code>
-       */
-      public Builder clearIsDirty() {
-        
-        isDirty_ = false;
-        onChanged();
-        return this;
-      }
-
-      private boolean autoCommit_ ;
-      /**
-       * <code>optional bool auto_commit = 2;</code>
-       */
-      public boolean getAutoCommit() {
-        return autoCommit_;
-      }
-      /**
-       * <code>optional bool auto_commit = 2;</code>
-       */
-      public Builder setAutoCommit(boolean value) {
-        
-        autoCommit_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool auto_commit = 2;</code>
-       */
-      public Builder clearAutoCommit() {
-        
-        autoCommit_ = false;
-        onChanged();
-        return this;
-      }
-
-      private boolean hasAutoCommit_ ;
-      /**
-       * <code>optional bool has_auto_commit = 7;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public boolean getHasAutoCommit() {
-        return hasAutoCommit_;
-      }
-      /**
-       * <code>optional bool has_auto_commit = 7;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public Builder setHasAutoCommit(boolean value) {
-        
-        hasAutoCommit_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool has_auto_commit = 7;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public Builder clearHasAutoCommit() {
-        
-        hasAutoCommit_ = false;
-        onChanged();
-        return this;
-      }
-
-      private boolean readOnly_ ;
-      /**
-       * <code>optional bool read_only = 3;</code>
-       */
-      public boolean getReadOnly() {
-        return readOnly_;
-      }
-      /**
-       * <code>optional bool read_only = 3;</code>
-       */
-      public Builder setReadOnly(boolean value) {
-        
-        readOnly_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool read_only = 3;</code>
-       */
-      public Builder clearReadOnly() {
-        
-        readOnly_ = false;
-        onChanged();
-        return this;
-      }
-
-      private boolean hasReadOnly_ ;
-      /**
-       * <code>optional bool has_read_only = 8;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public boolean getHasReadOnly() {
-        return hasReadOnly_;
-      }
-      /**
-       * <code>optional bool has_read_only = 8;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public Builder setHasReadOnly(boolean value) {
-        
-        hasReadOnly_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional bool has_read_only = 8;</code>
-       *
-       * <pre>
-       * field is a Boolean, need to discern null and default value
-       * </pre>
-       */
-      public Builder clearHasReadOnly() {
-        
-        hasReadOnly_ = false;
-        onChanged();
-        return this;
-      }
-
-      private int transactionIsolation_ ;
-      /**
-       * <code>optional uint32 transaction_isolation = 4;</code>
-       */
-      public int getTransactionIsolation() {
-        return transactionIsolation_;
-      }
-      /**
-       * <code>optional uint32 transaction_isolation = 4;</code>
-       */
-      public Builder setTransactionIsolation(int value) {
-        
-        transactionIsolation_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional uint32 transaction_isolation = 4;</code>
-       */
-      public Builder clearTransactionIsolation() {
-        
-        transactionIsolation_ = 0;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object catalog_ = "";
-      /**
-       * <code>optional string catalog = 5;</code>
-       */
-      public java.lang.String getCatalog() {
-        java.lang.Object ref = catalog_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          catalog_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 5;</code>
-       */
-      public com.google.protobuf.ByteString
-          getCatalogBytes() {
-        java.lang.Object ref = catalog_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          catalog_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string catalog = 5;</code>
-       */
-      public Builder setCatalog(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 5;</code>
-       */
-      public Builder clearCatalog() {
-        
-        catalog_ = getDefaultInstance().getCatalog();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string catalog = 5;</code>
-       */
-      public Builder setCatalogBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        catalog_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object schema_ = "";
-      /**
-       * <code>optional string schema = 6;</code>
-       */
-      public java.lang.String getSchema() {
-        java.lang.Object ref = schema_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          schema_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string schema = 6;</code>
-       */
-      public com.google.protobuf.ByteString
-          getSchemaBytes() {
-        java.lang.Object ref = schema_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          schema_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string schema = 6;</code>
-       */
-      public Builder setSchema(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        schema_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema = 6;</code>
-       */
-      public Builder clearSchema() {
-        
-        schema_ = getDefaultInstance().getSchema();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string schema = 6;</code>
-       */
-      public Builder setSchemaBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        schema_ = value;
-        onChanged();
-        return this;
-      }
-      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:ConnectionProperties)
-    }
-
-    // @@protoc_insertion_point(class_scope:ConnectionProperties)
-    private static final org.apache.calcite.avatica.proto.Common.ConnectionProperties DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Common.ConnectionProperties();
-    }
-
-    public static org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<ConnectionProperties>
-        PARSER = new com.google.protobuf.AbstractParser<ConnectionProperties>() {
-      public ConnectionProperties parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new ConnectionProperties(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<ConnectionProperties> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ConnectionProperties> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Common.ConnectionProperties getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface StatementHandleOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:StatementHandle)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    java.lang.String getConnectionId();
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getConnectionIdBytes();
-
-    /**
-     * <code>optional uint32 id = 2;</code>
-     */
-    int getId();
-
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    boolean hasSignature();
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.Signature getSignature();
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder();
-  }
-  /**
-   * Protobuf type {@code StatementHandle}
-   *
-   * <pre>
-   * Statement handle
-   * </pre>
-   */
-  public  static final class StatementHandle extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:StatementHandle)
-      StatementHandleOrBuilder {
-    // Use StatementHandle.newBuilder() to construct.
-    private StatementHandle(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private StatementHandle() {
-      connectionId_ = "";
-      id_ = 0;
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
-    }
-    private StatementHandle(
-        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 10: {
-              String s = input.readStringRequireUtf8();
-
-              connectionId_ = s;
-              break;
-            }
-            case 16: {
-
-              id_ = input.readUInt32();
-              break;
-            }
-            case 26: {
-              org.apache.calcite.avatica.proto.Common.Signature.Builder subBuilder = null;
-              if (signature_ != null) {
-                subBuilder = signature_.toBuilder();
-              }
-              signature_ = input.readMessage(org.apache.calcite.avatica.proto.Common.Signature.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(signature_);
-                signature_ = subBuilder.buildPartial();
-              }
-
-              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_StatementHandle_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.apache.calcite.avatica.proto.Common.StatementHandle.class, org.apache.calcite.avatica.proto.Common.StatementHandle.Builder.class);
-    }
-
-    public static final int CONNECTION_ID_FIELD_NUMBER = 1;
-    private volatile java.lang.Object connectionId_;
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public java.lang.String getConnectionId() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        connectionId_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>optional string connection_id = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getConnectionIdBytes() {
-      java.lang.Object ref = connectionId_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        connectionId_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int ID_FIELD_NUMBER = 2;
-    private int id_;
-    /**
-     * <code>optional uint32 id = 2;</code>
-     */
-    public int getId() {
-      return id_;
-    }
-
-    public static final int SIGNATURE_FIELD_NUMBER = 3;
-    private org.apache.calcite.avatica.proto.Common.Signature signature_;
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    public boolean hasSignature() {
-      return signature_ != null;
-    }
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
-      return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-    }
-    /**
-     * <code>optional .Signature signature = 3;</code>
-     */
-    public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
-      return getSignature();
-    }
-
-    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 {
-      if (!getConnectionIdBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
-      }
-      if (id_ != 0) {
-        output.writeUInt32(2, id_);
-      }
-      if (signature_ != null) {
-        output.writeMessage(3, getSignature());
-      }
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getConnectionIdBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
-      }
-      if (id_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(2, id_);
-      }
-      if (signature_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getSignature());
-      }
-      memoizedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle 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.StatementHandle 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 StatementHandle}
-     *
-     * <pre>
-     * Statement handle
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:StatementHandle)
-        org.apache.calcite.avatica.proto.Common.StatementHandleOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.apache.calcite.avatica.proto.Common.StatementHandle.class, org.apache.calcite.avatica.proto.Common.StatementHandle.Builder.class);
-      }
-
-      // Construct using org.apache.calcite.avatica.proto.Common.StatementHandle.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        connectionId_ = "";
-
-        id_ = 0;
-
-        if (signatureBuilder_ == null) {
-          signature_ = null;
-        } else {
-          signature_ = null;
-          signatureBuilder_ = null;
-        }
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.apache.calcite.avatica.proto.Common.internal_static_StatementHandle_descriptor;
-      }
-
-      public org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstanceForType() {
-        return org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance();
-      }
-
-      public org.apache.calcite.avatica.proto.Common.StatementHandle build() {
-        org.apache.calcite.avatica.proto.Common.StatementHandle result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.apache.calcite.avatica.proto.Common.StatementHandle buildPartial() {
-        org.apache.calcite.avatica.proto.Common.StatementHandle result = new org.apache.calcite.avatica.proto.Common.StatementHandle(this);
-        result.connectionId_ = connectionId_;
-        result.id_ = id_;
-        if (signatureBuilder_ == null) {
-          result.signature_ = signature_;
-        } else {
-          result.signature_ = signatureBuilder_.build();
-        }
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.apache.calcite.avatica.proto.Common.StatementHandle) {
-          return mergeFrom((org.apache.calcite.avatica.proto.Common.StatementHandle)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.apache.calcite.avatica.proto.Common.StatementHandle other) {
-        if (other == org.apache.calcite.avatica.proto.Common.StatementHandle.getDefaultInstance()) return this;
-        if (!other.getConnectionId().isEmpty()) {
-          connectionId_ = other.connectionId_;
-          onChanged();
-        }
-        if (other.getId() != 0) {
-          setId(other.getId());
-        }
-        if (other.hasSignature()) {
-          mergeSignature(other.getSignature());
-        }
-        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.StatementHandle parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.apache.calcite.avatica.proto.Common.StatementHandle) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object connectionId_ = "";
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public java.lang.String getConnectionId() {
-        java.lang.Object ref = connectionId_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          connectionId_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getConnectionIdBytes() {
-        java.lang.Object ref = connectionId_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          connectionId_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionId(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder clearConnectionId() {
-        
-        connectionId_ = getDefaultInstance().getConnectionId();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional string connection_id = 1;</code>
-       */
-      public Builder setConnectionIdBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        connectionId_ = value;
-        onChanged();
-        return this;
-      }
-
-      private int id_ ;
-      /**
-       * <code>optional uint32 id = 2;</code>
-       */
-      public int getId() {
-        return id_;
-      }
-      /**
-       * <code>optional uint32 id = 2;</code>
-       */
-      public Builder setId(int value) {
-        
-        id_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional uint32 id = 2;</code>
-       */
-      public Builder clearId() {
-        
-        id_ = 0;
-        onChanged();
-        return this;
-      }
-
-      private org.apache.calcite.avatica.proto.Common.Signature signature_ = null;
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> signatureBuilder_;
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public boolean hasSignature() {
-        return signatureBuilder_ != null || signature_ != null;
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Signature getSignature() {
-        if (signatureBuilder_ == null) {
-          return signature_ == null ? org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-        } else {
-          return signatureBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public Builder setSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
-        if (signatureBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          signature_ = value;
-          onChanged();
-        } else {
-          signatureBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public Builder setSignature(
-          org.apache.calcite.avatica.proto.Common.Signature.Builder builderForValue) {
-        if (signatureBuilder_ == null) {
-          signature_ = builderForValue.build();
-          onChanged();
-        } else {
-          signatureBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public Builder mergeSignature(org.apache.calcite.avatica.proto.Common.Signature value) {
-        if (signatureBuilder_ == null) {
-          if (signature_ != null) {
-            signature_ =
-              org.apache.calcite.avatica.proto.Common.Signature.newBuilder(signature_).mergeFrom(value).buildPartial();
-          } else {
-            signature_ = value;
-          }
-          onChanged();
-        } else {
-          signatureBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public Builder clearSignature() {
-        if (signatureBuilder_ == null) {
-          signature_ = null;
-          onChanged();
-        } else {
-          signature_ = null;
-          signatureBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.Signature.Builder getSignatureBuilder() {
-        
-        onChanged();
-        return getSignatureFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      public org.apache.calcite.avatica.proto.Common.SignatureOrBuilder getSignatureOrBuilder() {
-        if (signatureBuilder_ != null) {
-          return signatureBuilder_.getMessageOrBuilder();
-        } else {
-          return signature_ == null ?
-              org.apache.calcite.avatica.proto.Common.Signature.getDefaultInstance() : signature_;
-        }
-      }
-      /**
-       * <code>optional .Signature signature = 3;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilder<
-          org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder> 
-          getSignatureFieldBuilder() {
-        if (signatureBuilder_ == null) {
-          signatureBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-              org.apache.calcite.avatica.proto.Common.Signature, org.apache.calcite.avatica.proto.Common.Signature.Builder, org.apache.calcite.avatica.proto.Common.SignatureOrBuilder>(
-                  getSignature(),
-                  getParentForChildren(),
-                  isClean());
-          signature_ = null;
-        }
-        return signatureBuilder_;
-      }
-      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:StatementHandle)
-    }
-
-    // @@protoc_insertion_point(class_scope:StatementHandle)
-    private static final org.apache.calcite.avatica.proto.Common.StatementHandle DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Common.StatementHandle();
-    }
-
-    public static org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<StatementHandle>
-        PARSER = new com.google.protobuf.AbstractParser<StatementHandle>() {
-      public StatementHandle parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new StatementHandle(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<StatementHandle> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<StatementHandle> getParserForType() {
-      return PARSER;
-    }
-
-    public org.apache.calcite.avatica.proto.Common.StatementHandle getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SignatureOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:Signature)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>repeated .ColumnMetaData columns = 1;</code>
-     */
-    java.util.List<org.apache.calcite.avatica.proto.Common.ColumnMetaData> 
-        getColumnsList();
-    /**
-     * <code>repeated .ColumnMetaData columns = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.ColumnMetaData getColumns(int index);
-    /**
-     * <code>repeated .ColumnMetaData columns = 1;</code>
-     */
-    int getColumnsCount();
-    /**
-     * <code>repeated .ColumnMetaData columns = 1;</code>
-     */
-    java.util.List<? extends org.apache.calcite.avatica.proto.Common.ColumnMetaDataOrBuilder> 
-        getColumnsOrBuilderList();
-    /**
-     * <code>repeated .ColumnMetaData columns = 1;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.ColumnMetaDataOrBuilder getColumnsOrBuilder(
-        int index);
-
-    /**
-     * <code>optional string sql = 2;</code>
-     */
-    java.lang.String getSql();
-    /**
-     * <code>optional string sql = 2;</code>
-     */
-    com.google.protobuf.ByteString
-        getSqlBytes();
-
-    /**
-     * <code>repeated .AvaticaParameter parameters = 3;</code>
-     */
-    java.util.List<org.apache.calcite.avatica.proto.Common.AvaticaParameter> 
-        getParametersList();
-    /**
-     * <code>repeated .AvaticaParameter parameters = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.AvaticaParameter getParameters(int index);
-    /**
-     * <code>repeated .AvaticaParameter parameters = 3;</code>
-     */
-    int getParametersCount();
-    /**
-     * <code>repeated .AvaticaParameter parameters = 3;</code>
-     */
-    java.util.List<? extends org.apache.calcite.avatica.proto.Common.AvaticaParameterOrBuilder> 
-        getParametersOrBuilderList();
-    /**
-     * <code>repeated .AvaticaParameter parameters = 3;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.AvaticaParameterOrBuilder getParametersOrBuilder(
-        int index);
-
-    /**
-     * <code>optional .CursorFactory cursor_factory = 4;</code>
-     */
-    boolean hasCursorFactory();
-    /**
-     * <code>optional .CursorFactory cursor_factory = 4;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.CursorFactory getCursorFactory();
-    /**
-     * <code>optional .CursorFactory cursor_factory = 4;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.CursorFactoryOrBuilder getCursorFactoryOrBuilder();
-
-    /**
-     * <code>optional .StatementType statementType = 5;</code>
-     */
-    int getStatementTypeValue();
-    /**
-     * <code>optional .StatementType statementType = 5;</code>
-     */
-    org.apache.calcite.avatica.proto.Common.StatementType getStatementType();
-  }
-  /**
-   * Protobuf type {@code Signature}
-   *
-   * <pre>
-   * Results of preparing a statement
-   * </pre>
-   */
-  public  static final class Signature extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:Signature)
-      SignatureOrBuilder {
-    // Use Signature.newBuilder() to construct.
-    private Signature(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-    }
-    private Signature() {
-      columns_ = java.util.Collections.emptyList();
-      sql_ = "";
-      parameters_ = java.util.Collections.emptyList();
-      statementType_ = 0;
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-     

<TRUNCATED>

[20/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/reference.md b/avatica/site/_docs/reference.md
new file mode 100644
index 0000000..7bc9bc3
--- /dev/null
+++ b/avatica/site/_docs/reference.md
@@ -0,0 +1,1248 @@
+---
+layout: docs
+title: SQL language
+permalink: /docs/reference.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+The page describes the SQL dialect recognized by Calcite's default SQL parser.
+
+## Grammar
+
+SQL grammar in [BNF](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)-like
+form.
+
+{% highlight sql %}
+statement:
+      setStatement
+  |   resetStatement
+  |   explain
+  |   insert
+  |   update
+  |   merge
+  |   delete
+  |   query
+
+setStatement:
+      [ ALTER ( SYSTEM | SESSION ) ] SET identifier '=' expression
+
+resetStatement:
+      [ ALTER ( SYSTEM | SESSION ) ] RESET identifier
+  |   [ ALTER ( SYSTEM | SESSION ) ] RESET ALL
+
+explain:
+      EXPLAIN PLAN
+      [ WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION ]
+      [ EXCLUDING ATTRIBUTES | INCLUDING [ ALL ] ATTRIBUTES ]
+      FOR ( insert | update | merge | delete | query )
+
+insert:
+      ( INSERT | UPSERT ) INTO tablePrimary
+      [ '(' column [, column ]* ')' ]
+      query
+
+update:
+      UPDATE tablePrimary
+      SET assign [, assign ]*
+      [ WHERE booleanExpression ]
+
+assign:
+      identifier '=' expression
+
+merge:
+      MERGE INTO tablePrimary [ [ AS ] alias ]
+      USING tablePrimary
+      ON booleanExpression
+      [ WHEN MATCHED THEN UPDATE SET assign [, assign ]* ]
+      [ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
+
+delete:
+      DELETE FROM tablePrimary [ [ AS ] alias ]
+      [ WHERE booleanExpression ]
+
+query:
+      [ WITH withItem [ , withItem ]* query ]
+  |   {
+          select
+      |   query UNION [ ALL ] query
+      |   query EXCEPT query
+      |   query INTERSECT query
+      }
+      [ ORDER BY orderItem [, orderItem ]* ]
+      [ LIMIT { count | ALL } ]
+      [ OFFSET start { ROW | ROWS } ]
+      [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ]
+
+withItem:
+      name
+      [ '(' column [, column ]* ')' ]
+      AS '(' query ')'
+
+orderItem:
+      expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
+
+select:
+      SELECT [ STREAM ] [ ALL | DISTINCT ]
+          { * | projectItem [, projectItem ]* }
+      FROM tableExpression
+      [ WHERE booleanExpression ]
+      [ GROUP BY { groupItem [, groupItem ]* } ]
+      [ HAVING booleanExpression ]
+      [ WINDOW windowName AS windowSpec [, windowName AS windowSpec ]* ]
+
+projectItem:
+      expression [ [ AS ] columnAlias ]
+  |   tableAlias . *
+
+tableExpression:
+      tableReference [, tableReference ]*
+  |   tableExpression [ NATURAL ] [ LEFT | RIGHT | FULL ] JOIN tableExpression [ joinCondition ]
+
+joinCondition:
+      ON booleanExpression
+  |   USING '(' column [, column ]* ')'
+
+tableReference:
+      [ LATERAL ]
+      tablePrimary
+      [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
+
+tablePrimary:
+      [ TABLE ] [ [ catalogName . ] schemaName . ] tableName
+  |   '(' query ')'
+  |   values
+  |   UNNEST '(' expression ')' [ WITH ORDINALITY ]
+  |   TABLE '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
+
+values:
+      VALUES expression [, expression ]*
+
+groupItem:
+      expression
+  |   '(' ')'
+  |   '(' expression [, expression ]* ')'
+  |   CUBE '(' expression [, expression ]* ')'
+  |   ROLLUP '(' expression [, expression ]* ')'
+  |   GROUPING SETS '(' groupItem [, groupItem ]* ')'
+
+windowRef:
+      windowName
+  |   windowSpec
+
+windowSpec:
+      [ windowName ]
+      '('
+      [ ORDER BY orderItem [, orderItem ]* ]
+      [ PARTITION BY expression [, expression ]* ]
+      [
+          RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
+      |   ROWS numericExpression { PRECEDING | FOLLOWING }
+      ]
+      ')'
+{% endhighlight %}
+
+In *merge*, at least one of the WHEN MATCHED and WHEN NOT MATCHED clauses must
+be present.
+
+In *orderItem*, if *expression* is a positive integer *n*, it denotes
+the <em>n</em>th item in the SELECT clause.
+
+An aggregate query is a query that contains a GROUP BY or a HAVING
+clause, or aggregate functions in the SELECT clause. In the SELECT,
+HAVING and ORDER BY clauses of an aggregate query, all expressions
+must be constant within the current group (that is, grouping constants
+as defined by the GROUP BY clause, or constants), or aggregate
+functions, or a combination of constants and aggregate
+functions. Aggregate and grouping functions may only appear in an
+aggregate query, and only in a SELECT, HAVING or ORDER BY clause.
+
+A scalar sub-query is a sub-query used as an expression.
+If the sub-query returns no rows, the value is NULL; if it
+returns more than one row, it is an error.
+
+IN, EXISTS and scalar sub-queries can occur
+in any place where an expression can occur (such as the SELECT clause,
+WHERE clause, ON clause of a JOIN, or as an argument to an aggregate
+function).
+
+An IN, EXISTS or scalar sub-query may be correlated; that is, it
+may refer to tables in the FROM clause of an enclosing query.
+
+## Keywords
+
+The following is a list of SQL keywords.
+Reserved keywords are **bold**.
+
+{% comment %} start {% endcomment %}
+A,
+**ABS**,
+ABSOLUTE,
+ACTION,
+ADA,
+ADD,
+ADMIN,
+AFTER,
+**ALL**,
+**ALLOCATE**,
+**ALLOW**,
+**ALTER**,
+ALWAYS,
+**AND**,
+**ANY**,
+**ARE**,
+**ARRAY**,
+**AS**,
+ASC,
+**ASENSITIVE**,
+ASSERTION,
+ASSIGNMENT,
+**ASYMMETRIC**,
+**AT**,
+**ATOMIC**,
+ATTRIBUTE,
+ATTRIBUTES,
+**AUTHORIZATION**,
+**AVG**,
+BEFORE,
+**BEGIN**,
+BERNOULLI,
+**BETWEEN**,
+**BIGINT**,
+**BINARY**,
+**BIT**,
+**BLOB**,
+**BOOLEAN**,
+**BOTH**,
+BREADTH,
+**BY**,
+C,
+**CALL**,
+**CALLED**,
+**CARDINALITY**,
+CASCADE,
+**CASCADED**,
+**CASE**,
+**CAST**,
+CATALOG,
+CATALOG_NAME,
+**CEIL**,
+**CEILING**,
+CHAIN,
+**CHAR**,
+**CHARACTER**,
+CHARACTERISTICTS,
+CHARACTERS,
+**CHARACTER_LENGTH**,
+CHARACTER_SET_CATALOG,
+CHARACTER_SET_NAME,
+CHARACTER_SET_SCHEMA,
+**CHAR_LENGTH**,
+**CHECK**,
+CLASS_ORIGIN,
+**CLOB**,
+**CLOSE**,
+**COALESCE**,
+COBOL,
+**COLLATE**,
+COLLATION,
+COLLATION_CATALOG,
+COLLATION_NAME,
+COLLATION_SCHEMA,
+**COLLECT**,
+**COLUMN**,
+COLUMN_NAME,
+COMMAND_FUNCTION,
+COMMAND_FUNCTION_CODE,
+**COMMIT**,
+COMMITTED,
+**CONDITION**,
+CONDITION_NUMBER,
+**CONNECT**,
+CONNECTION,
+CONNECTION_NAME,
+**CONSTRAINT**,
+CONSTRAINTS,
+CONSTRAINT_CATALOG,
+CONSTRAINT_NAME,
+CONSTRAINT_SCHEMA,
+CONSTRUCTOR,
+CONTAINS,
+CONTINUE,
+**CONVERT**,
+**CORR**,
+**CORRESPONDING**,
+**COUNT**,
+**COVAR_POP**,
+**COVAR_SAMP**,
+**CREATE**,
+**CROSS**,
+**CUBE**,
+**CUME_DIST**,
+**CURRENT**,
+**CURRENT_CATALOG**,
+**CURRENT_DATE**,
+**CURRENT_DEFAULT_TRANSFORM_GROUP**,
+**CURRENT_PATH**,
+**CURRENT_ROLE**,
+**CURRENT_SCHEMA**,
+**CURRENT_TIME**,
+**CURRENT_TIMESTAMP**,
+**CURRENT_TRANSFORM_GROUP_FOR_TYPE**,
+**CURRENT_USER**,
+**CURSOR**,
+CURSOR_NAME,
+**CYCLE**,
+DATA,
+**DATE**,
+DATETIME_INTERVAL_CODE,
+DATETIME_INTERVAL_PRECISION,
+**DAY**,
+**DEALLOCATE**,
+**DEC**,
+**DECIMAL**,
+**DECLARE**,
+**DEFAULT**,
+DEFAULTS,
+DEFERRABLE,
+DEFERRED,
+DEFINED,
+DEFINER,
+DEGREE,
+**DELETE**,
+**DENSE_RANK**,
+DEPTH,
+**DEREF**,
+DERIVED,
+DESC,
+**DESCRIBE**,
+DESCRIPTION,
+DESCRIPTOR,
+**DETERMINISTIC**,
+DIAGNOSTICS,
+**DISALLOW**,
+**DISCONNECT**,
+DISPATCH,
+**DISTINCT**,
+DOMAIN,
+**DOUBLE**,
+**DROP**,
+**DYNAMIC**,
+DYNAMIC_FUNCTION,
+DYNAMIC_FUNCTION_CODE,
+**EACH**,
+**ELEMENT**,
+**ELSE**,
+**END**,
+**END-EXEC**,
+EQUALS,
+**ESCAPE**,
+**EVERY**,
+**EXCEPT**,
+EXCEPTION,
+EXCLUDE,
+EXCLUDING,
+**EXEC**,
+**EXECUTE**,
+**EXISTS**,
+**EXP**,
+**EXPLAIN**,
+**EXTEND**,
+**EXTERNAL**,
+**EXTRACT**,
+**FALSE**,
+**FETCH**,
+**FILTER**,
+FINAL,
+FIRST,
+**FIRST_VALUE**,
+**FLOAT**,
+**FLOOR**,
+FOLLOWING,
+**FOR**,
+**FOREIGN**,
+FORTRAN,
+FOUND,
+**FREE**,
+**FROM**,
+**FULL**,
+**FUNCTION**,
+**FUSION**,
+G,
+GENERAL,
+GENERATED,
+**GET**,
+**GLOBAL**,
+GO,
+GOTO,
+**GRANT**,
+GRANTED,
+**GROUP**,
+**GROUPING**,
+**HAVING**,
+HIERARCHY,
+**HOLD**,
+**HOUR**,
+**IDENTITY**,
+IMMEDIATE,
+IMPLEMENTATION,
+**IMPORT**,
+**IN**,
+INCLUDING,
+INCREMENT,
+**INDICATOR**,
+INITIALLY,
+**INNER**,
+**INOUT**,
+INPUT,
+**INSENSITIVE**,
+**INSERT**,
+INSTANCE,
+INSTANTIABLE,
+**INT**,
+**INTEGER**,
+**INTERSECT**,
+**INTERSECTION**,
+**INTERVAL**,
+**INTO**,
+INVOKER,
+**IS**,
+ISOLATION,
+JAVA,
+**JOIN**,
+K,
+KEY,
+KEY_MEMBER,
+KEY_TYPE,
+LABEL,
+**LANGUAGE**,
+**LARGE**,
+LAST,
+**LAST_VALUE**,
+**LATERAL**,
+**LEADING**,
+**LEFT**,
+LENGTH,
+LEVEL,
+LIBRARY,
+**LIKE**,
+**LIMIT**,
+**LN**,
+**LOCAL**,
+**LOCALTIME**,
+**LOCALTIMESTAMP**,
+LOCATOR,
+**LOWER**,
+M,
+MAP,
+**MATCH**,
+MATCHED,
+**MAX**,
+MAXVALUE,
+**MEMBER**,
+**MERGE**,
+MESSAGE_LENGTH,
+MESSAGE_OCTET_LENGTH,
+MESSAGE_TEXT,
+**METHOD**,
+**MIN**,
+**MINUTE**,
+MINVALUE,
+**MOD**,
+**MODIFIES**,
+**MODULE**,
+**MONTH**,
+MORE,
+**MULTISET**,
+MUMPS,
+NAME,
+NAMES,
+**NATIONAL**,
+**NATURAL**,
+**NCHAR**,
+**NCLOB**,
+NESTING,
+**NEW**,
+**NEXT**,
+**NO**,
+**NONE**,
+**NORMALIZE**,
+NORMALIZED,
+**NOT**,
+**NULL**,
+NULLABLE,
+**NULLIF**,
+NULLS,
+NUMBER,
+**NUMERIC**,
+OBJECT,
+OCTETS,
+**OCTET_LENGTH**,
+**OF**,
+**OFFSET**,
+**OLD**,
+**ON**,
+**ONLY**,
+**OPEN**,
+OPTION,
+OPTIONS,
+**OR**,
+**ORDER**,
+ORDERING,
+ORDINALITY,
+OTHERS,
+**OUT**,
+**OUTER**,
+OUTPUT,
+**OVER**,
+**OVERLAPS**,
+**OVERLAY**,
+OVERRIDING,
+PAD,
+**PARAMETER**,
+PARAMETER_MODE,
+PARAMETER_NAME,
+PARAMETER_ORDINAL_POSITION,
+PARAMETER_SPECIFIC_CATALOG,
+PARAMETER_SPECIFIC_NAME,
+PARAMETER_SPECIFIC_SCHEMA,
+PARTIAL,
+**PARTITION**,
+PASCAL,
+PASSTHROUGH,
+PATH,
+**PERCENTILE_CONT**,
+**PERCENTILE_DISC**,
+**PERCENT_RANK**,
+PLACING,
+PLAN,
+PLI,
+**POSITION**,
+**POWER**,
+PRECEDING,
+**PRECISION**,
+**PREPARE**,
+PRESERVE,
+**PRIMARY**,
+PRIOR,
+PRIVILEGES,
+**PROCEDURE**,
+PUBLIC,
+**RANGE**,
+**RANK**,
+READ,
+**READS**,
+**REAL**,
+**RECURSIVE**,
+**REF**,
+**REFERENCES**,
+**REFERENCING**,
+**REGR_AVGX**,
+**REGR_AVGY**,
+**REGR_COUNT**,
+**REGR_INTERCEPT**,
+**REGR_R2**,
+**REGR_SLOPE**,
+**REGR_SXX**,
+**REGR_SXY**,
+**REGR_SYY**,
+RELATIVE,
+**RELEASE**,
+REPEATABLE,
+**RESET**,
+RESTART,
+RESTRICT,
+**RESULT**,
+**RETURN**,
+RETURNED_CARDINALITY,
+RETURNED_LENGTH,
+RETURNED_OCTET_LENGTH,
+RETURNED_SQLSTATE,
+**RETURNS**,
+**REVOKE**,
+**RIGHT**,
+ROLE,
+**ROLLBACK**,
+**ROLLUP**,
+ROUTINE,
+ROUTINE_CATALOG,
+ROUTINE_NAME,
+ROUTINE_SCHEMA,
+**ROW**,
+**ROWS**,
+ROW_COUNT,
+**ROW_NUMBER**,
+**SAVEPOINT**,
+SCALE,
+SCHEMA,
+SCHEMA_NAME,
+**SCOPE**,
+SCOPE_CATALOGS,
+SCOPE_NAME,
+SCOPE_SCHEMA,
+**SCROLL**,
+**SEARCH**,
+**SECOND**,
+SECTION,
+SECURITY,
+**SELECT**,
+SELF,
+**SENSITIVE**,
+SEQUENCE,
+SERIALIZABLE,
+SERVER,
+SERVER_NAME,
+SESSION,
+**SESSION_USER**,
+**SET**,
+SETS,
+**SIMILAR**,
+SIMPLE,
+SIZE,
+**SMALLINT**,
+**SOME**,
+SOURCE,
+SPACE,
+**SPECIFIC**,
+**SPECIFICTYPE**,
+SPECIFIC_NAME,
+**SQL**,
+**SQLEXCEPTION**,
+**SQLSTATE**,
+**SQLWARNING**,
+**SQRT**,
+**START**,
+STATE,
+STATEMENT,
+**STATIC**,
+**STDDEV_POP**,
+**STDDEV_SAMP**,
+**STREAM**,
+STRUCTURE,
+STYLE,
+SUBCLASS_ORIGIN,
+**SUBMULTISET**,
+SUBSTITUTE,
+**SUBSTRING**,
+**SUM**,
+**SYMMETRIC**,
+**SYSTEM**,
+**SYSTEM_USER**,
+**TABLE**,
+**TABLESAMPLE**,
+TABLE_NAME,
+TEMPORARY,
+**THEN**,
+TIES,
+**TIME**,
+**TIMESTAMP**,
+**TIMEZONE_HOUR**,
+**TIMEZONE_MINUTE**,
+**TINYINT**,
+**TO**,
+TOP_LEVEL_COUNT,
+**TRAILING**,
+TRANSACTION,
+TRANSACTIONS_ACTIVE,
+TRANSACTIONS_COMMITTED,
+TRANSACTIONS_ROLLED_BACK,
+TRANSFORM,
+TRANSFORMS,
+**TRANSLATE**,
+**TRANSLATION**,
+**TREAT**,
+**TRIGGER**,
+TRIGGER_CATALOG,
+TRIGGER_NAME,
+TRIGGER_SCHEMA,
+**TRIM**,
+**TRUE**,
+TYPE,
+**UESCAPE**,
+UNBOUNDED,
+UNCOMMITTED,
+UNDER,
+**UNION**,
+**UNIQUE**,
+**UNKNOWN**,
+UNNAMED,
+**UNNEST**,
+**UPDATE**,
+**UPPER**,
+**UPSERT**,
+USAGE,
+**USER**,
+USER_DEFINED_TYPE_CATALOG,
+USER_DEFINED_TYPE_CODE,
+USER_DEFINED_TYPE_NAME,
+USER_DEFINED_TYPE_SCHEMA,
+**USING**,
+**VALUE**,
+**VALUES**,
+**VARBINARY**,
+**VARCHAR**,
+**VARYING**,
+**VAR_POP**,
+**VAR_SAMP**,
+VERSION,
+VIEW,
+**WHEN**,
+**WHENEVER**,
+**WHERE**,
+**WIDTH_BUCKET**,
+**WINDOW**,
+**WITH**,
+**WITHIN**,
+**WITHOUT**,
+WORK,
+WRAPPER,
+WRITE,
+XML,
+**YEAR**,
+ZONE.
+{% comment %} end {% endcomment %}
+
+## Identifiers
+
+Identifiers are the names of tables, columns and other metadata
+elements used in a SQL query.
+
+Unquoted identifiers, such as emp, must start with a letter and can
+only contain letters, digits, and underscores. They are implicitly
+converted to upper case.
+
+Quoted identifiers, such as `"Employee Name"`, start and end with
+double quotes.  They may contain virtually any character, including
+spaces and other punctuation.  If you wish to include a double quote
+in an identifier, use another double quote to escape it, like this:
+`"An employee called ""Fred""."`.
+
+In Calcite, matching identifiers to the name of the referenced object is
+case-sensitive.  But remember that unquoted identifiers are implicitly
+converted to upper case before matching, and if the object it refers
+to was created using an unquoted identifier for its name, then its
+name will have been converted to upper case also.
+
+## Data types
+
+### Scalar types
+
+| Data type   | Description               | Range and examples   |
+|:----------- |:------------------------- |:---------------------|
+| BOOLEAN     | Logical values            | Values: TRUE, FALSE, UNKNOWN
+| TINYINT     | 1 byte signed integer     | Range is -255 to 256
+| SMALLINT    | 2 byte signed integer     | Range is -32768 to 32767
+| INTEGER, INT | 4 byte signed integer    | Range is -2147483648 to 2147483647
+| BIGINT      | 8 byte signed integer     | Range is -9223372036854775808 to 9223372036854775807
+| DECIMAL(p, s) | Fixed point             | Example: 123.45 is a DECIMAL(5, 2) value.
+| NUMERIC     | Fixed point               |
+| REAL, FLOAT | 4 byte floating point     | 6 decimal digits precision
+| DOUBLE      | 8 byte floating point     | 15 decimal digits precision
+| CHAR(n), CHARACTER(n) | Fixed-width character string | 'Hello', '' (empty string), _latin1'Hello', n'Hello', _UTF16'Hello', 'Hello' 'there' (literal split into multiple parts)
+| VARCHAR(n), CHARACTER VARYING(n) | Variable-length character string | As CHAR(n)
+| BINARY(n)   | Fixed-width binary string | x'45F0AB', x'' (empty binary string), x'AB' 'CD' (multi-part binary string literal)
+| VARBINARY(n), BINARY VARYING(n) | Variable-length binary string | As BINARY(n)
+| DATE        | Date                      | Example: DATE '1969-07-20'
+| TIME        | Time of day               | Example: TIME '20:17:40'
+| TIMESTAMP [ WITHOUT TIME ZONE ] | Date and time | Example: TIMESTAMP '1969-07-20 20:17:40'
+| TIMESTAMP WITH TIME ZONE | Date and time with time zone | Example: TIMESTAMP '1969-07-20 20:17:40 America/Los Angeles'
+| INTERVAL timeUnit [ TO timeUnit ] | Date time interval | Examples: INTERVAL '1:5' YEAR TO MONTH, INTERVAL '45' DAY
+| Anchored interval | Date time interval  | Example: (DATE '1969-07-20', DATE '1972-08-29')
+
+Where:
+
+{% highlight sql %}
+timeUnit:
+  YEAR | MONTH | DAY | HOUR | MINUTE | SECOND
+{% endhighlight %}
+
+Note:
+
+* DATE, TIME and TIMESTAMP have no time zone. There is not even an implicit
+  time zone, such as UTC (as in Java) or the local time zone. It is left to
+  the user or application to supply a time zone.
+
+### Non-scalar types
+
+| Type     | Description
+|:-------- |:-----------------------------------------------------------
+| ANY      | A value of an unknown type
+| ROW      | Row with 1 or more columns
+| MAP      | Collection of keys mapped to values
+| MULTISET | Unordered collection that may contain duplicates
+| ARRAY    | Ordered, contiguous collection that may contain duplicates
+| CURSOR   | Cursor over the result of executing a query
+
+## Operators and functions
+
+### Comparison operators
+
+| Operator syntax                                   | Description
+|:------------------------------------------------- |:-----------
+| value1 = value2                                   | Equals
+| value1 <> value2                                  | Not equal
+| value1 > value2                                   | Greater than
+| value1 >= value2                                  | Greater than or equal
+| value1 < value2                                   | Less than
+| value1 <= value2                                  | Less than or equal
+| value IS NULL                                     | Whether *value* is null
+| value IS NOT NULL                                 | Whether *value* is not null
+| value1 IS DISTINCT FROM value2                    | Whether two values are not equal, treating null values as the same
+| value1 IS NOT DISTINCT FROM value2                | Whether two values are equal, treating null values as the same
+| value1 BETWEEN value2 AND value3                  | Whether *value1* is greater than or equal to *value2* and less than or equal to *value3*
+| value1 NOT BETWEEN value2 AND value3              | Whether *value1* is less than *value2* or greater than *value3*
+| string1 LIKE string2 [ ESCAPE string3 ]           | Whether *string1* matches pattern *string2*
+| string1 NOT LIKE string2 [ ESCAPE string3 ]       | Whether *string1* does not match pattern *string2*
+| string1 SIMILAR TO string2 [ ESCAPE string3 ]     | Whether *string1* matches regular expression *string2*
+| string1 NOT SIMILAR TO string2 [ ESCAPE string3 ] | Whether *string1* does not match regular expression *string2*
+| value IN (value [, value]* )                      | Whether *value* is equal to a value in a list
+| value NOT IN (value [, value]* )                  | Whether *value* is not equal to every value in a list
+| value IN (sub-query)                              | Whether *value* is equal to a row returned by *sub-query*
+| value NOT IN (sub-query)                          | Whether *value* is not equal to every row returned by *sub-query*
+| EXISTS (sub-query)                                | Whether *sub-query* returns at least one row
+
+### Logical operators
+
+| Operator syntax        | Description
+|:---------------------- |:-----------
+| boolean1 OR boolean2   | Whether *boolean1* is TRUE or *boolean2* is TRUE
+| boolean1 AND boolean2  | Whether *boolean1* and *boolean2* are both TRUE
+| NOT boolean            | Whether *boolean* is not TRUE; returns UNKNOWN if *boolean* is UNKNOWN
+| boolean IS FALSE       | Whether *boolean* is FALSE; returns FALSE if *boolean* is UNKNOWN
+| boolean IS NOT FALSE   | Whether *boolean* is not FALSE; returns TRUE if *boolean* is UNKNOWN
+| boolean IS TRUE        | Whether *boolean* is TRUE; returns FALSE if *boolean* is UNKNOWN
+| boolean IS NOT TRUE    | Whether *boolean* is not TRUE; returns TRUE if *boolean* is UNKNOWN
+| boolean IS UNKNOWN     | Whether *boolean* is UNKNOWN
+| boolean IS NOT UNKNOWN | Whether *boolean* is not UNKNOWN
+
+### Arithmetic operators and functions
+
+| Operator syntax           | Description
+|:------------------------- |:-----------
+| + numeric                 | Returns *numeric*
+|:- numeric                 | Returns negative *numeric*
+| numeric1 + numeric2       | Returns *numeric1* plus *numeric2*
+| numeric1 - numeric2       | Returns *numeric1* minus *numeric2*
+| numeric1 * numeric2       | Returns *numeric1* multiplied by *numeric2*
+| numeric1 / numeric2       | Returns *numeric1* divided by *numeric2*
+| POWER(numeric1, numeric2) | Returns *numeric1* raised to the power of *numeric2*
+| ABS(numeric)              | Returns the absolute value of *numeric*
+| MOD(numeric, numeric)     | Returns the remainder (modulus) of *numeric1* divided by *numeric2*. The result is negative only if *numeric1* is negative
+| SQRT(numeric)             | Returns the square root of *numeric*
+| LN(numeric)               | Returns the natural logarithm (base *e*) of *numeric*
+| LOG10(numeric)            | Returns the base 10 logarithm of *numeric*
+| EXP(numeric)              | Returns *e* raised to the power of *numeric*
+| CEIL(numeric)             | Rounds *numeric* up, and returns the smallest number that is greater than or equal to *numeric*
+| FLOOR(numeric)            | Rounds *numeric* down, and returns the largest number that is less than or equal to *numeric*
+
+### Character string operators and functions
+
+| Operator syntax            | Description
+|:-------------------------- |:-----------
+| string &#124;&#124; string | Concatenates two character strings.
+| CHAR_LENGTH(string)        | Returns the number of characters in a character string
+| CHARACTER_LENGTH(string)   | As CHAR_LENGTH(*string*)
+| UPPER(string)              | Returns a character string converted to upper case
+| LOWER(string)              | Returns a character string converted to lower case
+| POSITION(string1 IN string2) | Returns the position of the first occurrence of *string1* in *string2*
+| TRIM( { BOTH &#124; LEADING &#124; TRAILING } string1 FROM string2) | Removes the longest string containing only the characters in *string1* from the start/end/both ends of *string1*
+| OVERLAY(string1 PLACING string2 FROM integer [ FOR integer2 ]) | Replaces a substring of *string1* with *string2*
+| SUBSTRING(string FROM integer)  | Returns a substring of a character string starting at a given point.
+| SUBSTRING(string FROM integer FOR integer) | Returns a substring of a character string starting at a given point with a given length.
+| INITCAP(string)            | Returns *string* with the first letter of each word converter to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters.
+
+Not implemented:
+
+* SUBSTRING(string FROM regexp FOR regexp)
+
+### Binary string operators and functions
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| binary &#124;&#124; binary | Concatenates two binary strings.
+| POSITION(binary1 IN binary2) | Returns the position of the first occurrence of *binary1* in *binary2*
+| OVERLAY(binary1 PLACING binary2 FROM integer [ FOR integer2 ]) | Replaces a substring of *binary1* with *binary2*
+| SUBSTRING(binary FROM integer) | Returns a substring of *binary* starting at a given point
+| SUBSTRING(binary FROM integer FOR integer) | Returns a substring of *binary* starting at a given point with a given length
+
+### Date/time functions
+
+| Operator syntax           | Description
+|:------------------------- |:-----------
+| LOCALTIME                 | Returns the current date and time in the session time zone in a value of datatype TIME
+| LOCALTIME(precision)      | Returns the current date and time in the session time zone in a value of datatype TIME, with *precision* digits of precision
+| LOCALTIMESTAMP            | Returns the current date and time in the session time zone in a value of datatype TIMESTAMP
+| LOCALTIMESTAMP(precision) | Returns the current date and time in the session time zone in a value of datatype TIMESTAMP, with *precision* digits of precision
+| CURRENT_TIME              | Returns the current time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE
+| CURRENT_DATE              | Returns the current date in the session time zone, in a value of datatype DATE
+| CURRENT_TIMESTAMP         | Returns the current date and time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE
+| EXTRACT(timeUnit FROM datetime) | Extracts and returns the value of a specified datetime field from a datetime value expression
+| FLOOR(datetime TO timeUnit) | Rounds *datetime* down to *timeUnit*
+| CEIL(datetime TO timeUnit) | Rounds *datetime* up to *timeUnit*
+
+Not implemented:
+
+* EXTRACT(timeUnit FROM interval)
+* CEIL(interval)
+* FLOOR(interval)
+* datetime - datetime timeUnit [ TO timeUnit ]
+* interval OVERLAPS interval
+* \+ interval
+* \- interval
+* interval + interval
+* interval - interval
+* interval / interval
+* datetime + interval
+* datetime - interval
+
+### System functions
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| USER            | Equivalent to CURRENT_USER
+| CURRENT_USER    | User name of current execution context
+| SESSION_USER    | Session user name
+| SYSTEM_USER     | Returns the name of the current data store user as identified by the operating system
+| CURRENT_PATH    | Returns a character string representing the current lookup scope for references to user-defined routines and types
+| CURRENT_ROLE    | Returns the current active role
+
+### Conditional functions and operators
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| CASE value<br/>WHEN value1 [, value11 ]* THEN result1<br/>[ WHEN valueN [, valueN1 ]* THEN resultN ]*<br/>[ ELSE resultZ ]<br/> END | Simple case
+| CASE<br/>WHEN condition1 THEN result1<br/>[ WHEN conditionN THEN resultN ]*<br/>[ ELSE resultZ ]<br/>END | Searched case
+| NULLIF(value, value) | Returns NULL if the values are the same.<br/><br/>For example, <code>NULLIF(5, 5)</code> returns NULL; <code>NULLIF(5, 0)</code> returns 5.
+| COALESCE(value, value [, value ]* ) | Provides a value if the first value is null.<br/><br/>For example, <code>COALESCE(NULL, 5)</code> returns 5.
+
+### Type conversion
+
+| Operator syntax | Description
+|:--------------- | :----------
+| CAST(value AS type) | Converts a value to a given type.
+
+### Value constructors
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| ROW (value [, value]* ) | Creates a row from a list of values.
+| (value [, value]* )     | Creates a row from a list of values.
+| map '[' key ']'     | Returns the element of a map with a particular key.
+| array '[' index ']' | Returns the element at a particular location in an array.
+| ARRAY '[' value [, value ]* ']' | Creates an array from a list of values.
+| MAP '[' key, value [, key, value ]* ']' | Creates a map from a list of key-value pairs.
+
+### Collection functions
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| ELEMENT(value)  | Returns the sole element of a array or multiset; null if the collection is empty; throws if it has more than one element.
+| CARDINALITY(value) | Returns the number of elements in an array or multiset.
+
+See also: UNNEST relational operator converts a collection to a relation.
+
+### JDBC function escape
+
+#### Numeric
+
+| Operator syntax                | Description
+|:------------------------------ |:-----------
+| {fn LOG10(numeric)}            | Returns the base-10 logarithm of *numeric*
+| {fn POWER(numeric1, numeric2)} | Returns *numeric1* raised to the power of *numeric2*
+
+Not implemented:
+
+* {fn ABS(numeric)} - Returns the absolute value of *numeric*
+* {fn ACOS(numeric)} - Returns the arc cosine of *numeric*
+* {fn ASIN(numeric)} - Returns the arc sine of *numeric*
+* {fn ATAN(numeric)} - Returns the arc tangent of *numeric*
+* {fn ATAN2(numeric, numeric)}
+* {fn CEILING(numeric)} - Rounds *numeric* up, and returns the smallest number that is greater than or equal to *numeric*
+* {fn COS(numeric)} - Returns the cosine of *numeric*
+* {fn COT(numeric)}
+* {fn DEGREES(numeric)} - Converts *numeric* from radians to degrees
+* {fn EXP(numeric)} - Returns *e* raised to the power of *numeric*
+* {fn FLOOR(numeric)} - Rounds *numeric* down, and returns the largest number that is less than or equal to *numeric*
+* {fn LOG(numeric)} - Returns the natural logarithm (base *e*) of *numeric*
+* {fn MOD(numeric1, numeric2)} - Returns the remainder (modulus) of *numeric1* divided by *numeric2*. The result is negative only if *numeric1* is negative
+* {fn PI()} - Returns a value that is closer than any other value to *pi*
+* {fn RADIANS(numeric)} - Converts *numeric* from degrees to radians
+* {fn RAND(numeric)}
+* {fn ROUND(numeric, numeric)}
+* {fn SIGN(numeric)}
+* {fn SIN(numeric)} - Returns the sine of *numeric*
+* {fn SQRT(numeric)} - Returns the square root of *numeric*
+* {fn TAN(numeric)} - Returns the tangent of *numeric*
+* {fn TRUNCATE(numeric, numeric)}
+
+#### String
+
+| Operator syntax | Description
+|:--------------- |:-----------
+| {fn LOCATE(string1, string2)} | Returns the position in *string2* of the first occurrence of *string1*. Searches from the beginning of the second CharacterExpression, unless the startIndex parameter is specified.
+| {fn INSERT(string1, start, length, string2)} | Inserts *string2* into a slot in *string1*
+| {fn LCASE(string)}            | Returns a string in which all alphabetic characters in *string* have been converted to lower case
+
+Not implemented:
+
+* {fn ASCII(string)} - Convert a single-character string to the corresponding ASCII code, an integer between 0 and 255
+* {fn CHAR(string)}
+* {fn CONCAT(character, character)} - Returns the concatenation of character strings
+* {fn DIFFERENCE(string, string)}
+* {fn LEFT(string, integer)}
+* {fn LENGTH(string)}
+* {fn LOCATE(string1, string2 [, integer])} - Returns the position in *string2* of the first occurrence of *string1*. Searches from the beginning of *string2*, unless *integer* is specified.
+* {fn LTRIM(string)}
+* {fn REPEAT(string, integer)}
+* {fn REPLACE(string, string, string)}
+* {fn RIGHT(string, integer)}
+* {fn RTRIM(string)}
+* {fn SOUNDEX(string)}
+* {fn SPACE(integer)}
+* {fn SUBSTRING(string, integer, integer)}
+* {fn UCASE(string)} - Returns a string in which all alphabetic characters in *string* have been converted to upper case
+
+#### Date/time
+
+Not implemented:
+
+* {fn CURDATE()}
+* {fn CURTIME()}
+* {fn DAYNAME(date)}
+* {fn DAYOFMONTH(date)}
+* {fn DAYOFWEEK(date)}
+* {fn DAYOFYEAR(date)}
+* {fn HOUR(time)}
+* {fn MINUTE(time)}
+* {fn MONTH(date)}
+* {fn MONTHNAME(date)}
+* {fn NOW()}
+* {fn QUARTER(date)}
+* {fn SECOND(time)}
+* {fn TIMESTAMPADD(interval, count, timestamp)}
+* {fn TIMESTAMPDIFF(interval, timestamp, timestamp)}
+* {fn WEEK(date)}
+* {fn YEAR(date)}
+
+#### System
+
+Not implemented:
+
+* {fn DATABASE()}
+* {fn IFNULL(value, value)}
+* {fn USER(value, value)}
+* {fn CONVERT(value, type)}
+
+### Aggregate functions
+
+Syntax:
+
+{% highlight sql %}
+aggregateCall:
+        agg( [ DISTINCT ] value [, value]* ) [ FILTER ( WHERE condition ) ]
+    |   agg(*) [ FILTER ( WHERE condition ) ]
+{% endhighlight %}
+
+If `FILTER` is present, the aggregate function only considers rows for which
+*condition* evaluates to TRUE.
+
+If `DISTINCT` is present, duplicate argument values are eliminated before being
+passed to the aggregate function.
+
+| Operator syntax                    | Description
+|:---------------------------------- |:-----------
+| COLLECT( [ DISTINCT ] value)       | Returns a multiset of the values
+| COUNT( [ DISTINCT ] value [, value]* ) | Returns the number of input rows for which *value* is not null (wholly not null if *value* is composite)
+| COUNT(*)                           | Returns the number of input rows
+| AVG( [ DISTINCT ] numeric)         | Returns the average (arithmetic mean) of *numeric* across all input values
+| SUM( [ DISTINCT ] numeric)         | Returns the sum of *numeric* across all input values
+| MAX( [ DISTINCT ] value)           | Returns the maximum value of *value* across all input values
+| MIN( [ DISTINCT ] value)           | Returns the minimum value of *value* across all input values
+| STDDEV_POP( [ DISTINCT ] numeric)  | Returns the population standard deviation of *numeric* across all input values
+| STDDEV_SAMP( [ DISTINCT ] numeric) | Returns the sample standard deviation of *numeric* across all input values
+| VAR_POP( [ DISTINCT ] value)       | Returns the population variance (square of the population standard deviation) of *numeric* across all input values
+| VAR_SAMP( [ DISTINCT ] numeric)    | Returns the sample variance (square of the sample standard deviation) of *numeric* across all input values
+| COVAR_POP(numeric1, numeric2)      | Returns the population covariance of the pair (*numeric1*, *numeric2*) across all input values
+| COVAR_SAMP(numeric1, numeric2)     | Returns the sample covariance of the pair (*numeric1*, *numeric2*) across all input values
+| REGR_SXX(numeric1, numeric2)       | Returns the sum of squares of the dependent expression in a linear regression model
+| REGR_SYY(numeric1, numeric2)       | Returns the sum of squares of the independent expression in a linear regression model
+
+Not implemented:
+
+* REGR_AVGX(numeric1, numeric2)
+* REGR_AVGY(numeric1, numeric2)
+* REGR_COUNT(numeric1, numeric2)
+* REGR_INTERCEPT(numeric1, numeric2)
+* REGR_R2(numeric1, numeric2)
+* REGR_SLOPE(numeric1, numeric2)
+* REGR_SXY(numeric1, numeric2)
+
+### Window functions
+
+| Operator syntax                           | Description
+|:----------------------------------------- |:-----------
+| COUNT(value [, value ]* ) OVER window     | Returns the number of rows in *window* for which *value* is not null (wholly not null if *value* is composite)
+| COUNT(*) OVER window                      | Returns the number of rows in *window*
+| AVG(numeric) OVER window                  | Returns the average (arithmetic mean) of *numeric* across all values in *window*
+| SUM(numeric) OVER window                  | Returns the sum of *numeric* across all values in *window*
+| MAX(value) OVER window                    | Returns the maximum value of *value* across all values in *window*
+| MIN(value) OVER window                    | Returns the minimum value of *value* across all values in *window*
+| RANK() OVER window                        | Returns the rank of the current row with gaps; same as ROW_NUMBER of its first peer
+| DENSE_RANK() OVER window                  | Returns the rank of the current row without gaps; this function counts peer groups
+| ROW_NUMBER() OVER window                  | Returns the number of the current row within its partition, counting from 1
+| FIRST_VALUE(value) OVER window            | Returns *value* evaluated at the row that is the first row of the window frame
+| LAST_VALUE(value) OVER window             | Returns *value* evaluated at the row that is the last row of the window frame
+| LEAD(value, offset, default) OVER window  | Returns *value* evaluated at the row that is *offset* rows after the current row within the partition; if there is no such row, instead returns *default*. Both *offset* and *default* are evaluated with respect to the current row. If omitted, *offset* defaults to 1 and *default* to NULL
+| LAG(value, offset, default) OVER window   | Returns *value* evaluated at the row that is *offset* rows before the current row within the partition; if there is no such row, instead returns *default*. Both *offset* and *default* are evaluated with respect to the current row. If omitted, *offset* defaults to 1 and *default* to NULL
+| NTILE(value) OVER window                  | Returns an integer ranging from 1 to *value*, dividing the partition as equally as possible
+
+Not implemented:
+
+* COUNT(DISTINCT value) OVER window
+* FIRST_VALUE(value) IGNORE NULLS OVER window
+* LAST_VALUE(value) IGNORE NULLS OVER window
+* PERCENT_RANK(value) OVER window
+* CUME_DIST(value) OVER window
+* NTH_VALUE(value, nth) OVER window
+
+### Grouping functions
+
+| Operator syntax      | Description
+|:-------------------- |:-----------
+| GROUPING(expression) | Returns 1 if expression is rolled up in the current row's grouping set, 0 otherwise
+| GROUP_ID()           | Returns an integer that uniquely identifies the combination of grouping keys
+| GROUPING_ID(expression [, expression ] * ) | Returns a bit vector of the given grouping expressions
+
+### User-defined functions
+
+Calcite is extensible. You can define each kind of function using user code.
+For each kind of function there are often several ways to define a function,
+varying from convenient to efficient.
+
+To implement a *scalar function*, there are 3 options:
+
+* Create a class with a public static `eval` method,
+  and register the class;
+* Create a class with a public non-static `eval` method,
+  and a public constructor with no arguments,
+  and register the class;
+* Create a class with one or more public static methods,
+  and register each class/method combination.
+
+To implement an *aggregate function*, there are 2 options:
+
+* Create a class with public static `init`, `add` and `result` methods,
+  and register the class;
+* Create a class with public non-static `init`, `add` and `result` methods,
+  and a  public constructor with no arguments,
+  and register the class.
+
+Optionally, add a public `merge` method to the class; this allows Calcite to
+generate code that merges sub-totals.
+
+Optionally, make your class implement the
+[SqlSplittableAggFunction]({{ site.apiRoot }}/org/apache/calcite/sql/SqlSplittableAggFunction.html)
+interface; this allows Calcite to decompose the function across several stages
+of aggregation, roll up from summary tables, and push it through joins.
+
+To implement a *table function*, there are 3 options:
+
+* Create a class with a static `eval` method that returns
+  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
+  or
+  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
+  and register the class;
+* Create a class with a non-static `eval` method that returns
+  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
+  or
+  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
+  and register the class;
+* Create a class with one or more public static methods that return
+  [ScannableTable]({{ site.apiRoot }}/org/apache/calcite/schema/ScannableTable.html)
+  or
+  [QueryableTable]({{ site.apiRoot }}/org/apache/calcite/schema/QueryableTable.html),
+  and register each class/method combination.
+
+To implement a *table macro*, there are 3 options:
+
+* Create a class with a static `eval` method that returns
+  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
+  and register the class;
+* Create a class with a non-static `eval` method that returns
+  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
+  and register the class;
+* Create a class with one or more public static methods that return
+  [TranslatableTable]({{ site.apiRoot }}/org/apache/calcite/schema/TranslatableTable.html),
+  and register each class/method combination.
+
+Calcite deduces the parameter types and result type of a function from the
+parameter and return types of the Java method that implements it. Further, you
+can specify the name and optionality of each parameter using the
+[Parameter]({{ site.apiRoot }}/org/apache/calcite/linq4j/function/Parameter.html)
+annotation.
+
+### Calling functions with named and optional parameters
+
+Usually when you call a function, you need to specify all of its parameters,
+in order. But that can be a problem if a function has a lot of parameters,
+and especially if you want to add more parameters over time.
+
+To solve this problem, the SQL standard allows you to pass parameters by name,
+and to define parameters which are optional (that is, have a default value
+that is used if they are not specified).
+
+Suppose you have a function `f`, declared as in the following pseudo syntax:
+
+```FUNCTION f(
+  INTEGER a,
+  INTEGER b DEFAULT NULL,
+  INTEGER c,
+  INTEGER d DEFAULT NULL,
+  INTEGER e DEFAULT NULL) RETURNS INTEGER```
+
+All of the function's parameters have names, and parameters `b`, `d` and `e`
+have a default value of `NULL` and are therefore optional.
+(In Calcite, `NULL` is the only allowable default value for optional parameters;
+this may change
+[in future](https://issues.apache.org/jira/browse/CALCITE-947).)
+
+When calling a function with optional parameters,
+you can omit optional arguments at the end of the list, or use the `DEFAULT`
+keyword for any optional arguments.
+Here are some examples:
+
+* `f(1, 2, 3, 4, 5)` provides a value to each parameter, in order;
+* `f(1, 2, 3, 4)` omits `e`, which gets its default value, `NULL`;
+* `f(1, DEFAULT, 3)` omits `d` and `e`,
+  and specifies to use the default value of `b`;
+* `f(1, DEFAULT, 3, DEFAULT, DEFAULT)` has the same effect as the previous
+  example;
+* `f(1, 2)` is not legal, because `c` is not optional;
+* `f(1, 2, DEFAULT, 4)` is not legal, because `c` is not optional.
+
+You can specify arguments by name using the `=>` syntax.
+If one argument is named, they all must be.
+Arguments may be in any other, but must not specify any argument more than once,
+and you need to provide a value for every parameter which is not optional.
+Here are some examples:
+
+* `f(c => 3, d => 1, a => 0)` is equivalent to `f(0, NULL, 3, 1, NULL)`;
+* `f(c => 3, d => 1)` is not legal, because you have not specified a value for
+  `a` and `a` is not optional.
+

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/stream.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/stream.md b/avatica/site/_docs/stream.md
new file mode 100644
index 0000000..f66fbce
--- /dev/null
+++ b/avatica/site/_docs/stream.md
@@ -0,0 +1,1023 @@
+---
+layout: docs
+title: Streaming
+permalink: /docs/stream.html
+---
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->
+
+Calcite has extended SQL and relational algebra in order to support
+streaming queries.
+
+* TOC
+{:toc}
+
+## Introduction
+
+Streams are collections to records that flow continuously, and forever.
+Unlike tables, they are not typically stored on disk, but flow over the
+network and are held for short periods of time in memory.
+
+Streams complement tables because they represent what is happening in the
+present and future of the enterprise whereas tables represent the past.
+It is very common for a stream to be archived into a table.
+
+Like tables, you often want to query streams in a high-level language
+based on relational algebra, validated according to a schema, and optimized
+to take advantage of available resources and algorithms.
+
+Calcite's SQL is an extension to standard SQL, not another 'SQL-like' language.
+The distinction is important, for several reasons:
+
+* Streaming SQL is easy to learn for anyone who knows regular SQL.
+* The semantics are clear, because we aim to produce the same results on a
+  stream as if the same data were in a table.
+* You can write queries that combine streams and tables (or the history of
+  a stream, which is basically an in-memory table).
+* Lots of existing tools can generate standard SQL.
+
+If you don't use the `STREAM` keyword, you are back in regular
+standard SQL.
+
+## An example schema
+
+Our streaming SQL examples use the following schema:
+
+* `Orders (rowtime, productId, orderId, units)` - a stream and a table
+* `Products (rowtime, productId, name)` - a table
+* `Shipments (rowtime, orderId)` - a stream
+
+## A simple query
+
+Let's start with the simplest streaming query:
+
+{% highlight sql %}
+SELECT STREAM *
+FROM Orders;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 10:17:00 |        30 |       5 |     4
+ 10:17:05 |        10 |       6 |     1
+ 10:18:05 |        20 |       7 |     2
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:09:30 |        40 |      11 |    12
+ 11:24:11 |        10 |      12 |     4
+{% endhighlight %}
+
+This query reads all columns and rows from the `Orders` stream.
+Like any streaming query, it never terminates. It outputs a record whenever
+a record arrives in `Orders`.
+
+Type `Control-C` to terminate the query.
+
+The `STREAM` keyword is the main extension in streaming SQL. It tells the
+system that you are interested in incoming orders, not existing ones. The query
+
+{% highlight sql %}
+SELECT *
+FROM Orders;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 08:30:00 |        10 |       1 |     3
+ 08:45:10 |        20 |       2 |     1
+ 09:12:21 |        10 |       3 |    10
+ 09:27:44 |        30 |       4 |     2
+
+4 records returned.
+{% endhighlight %}
+
+is also valid, but will print out all existing orders and then terminate. We
+call it a *relational* query, as opposed to *streaming*. It has traditional
+SQL semantics.
+
+`Orders` is special, in that it has both a stream and a table. If you try to run
+a streaming query on a table, or a relational query on a stream, Calcite gives
+an error:
+
+{% highlight sql %}
+SELECT * FROM Shipments;
+
+ERROR: Cannot convert stream 'SHIPMENTS' to a table
+
+SELECT STREAM * FROM Products;
+
+ERROR: Cannot convert table 'PRODUCTS' to a stream
+{% endhighlight %}
+
+# Filtering rows
+
+Just as in regular SQL, you use a `WHERE` clause to filter rows:
+
+{% highlight sql %}
+SELECT STREAM *
+FROM Orders
+WHERE units > 3;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 10:17:00 |        30 |       5 |     4
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:09:30 |        40 |      11 |    12
+ 11:24:11 |        10 |      12 |     4
+{% endhighlight %}
+
+# Projecting expressions
+
+Use expressions in the `SELECT` clause to choose which columns to return or
+compute expressions:
+
+{% highlight sql %}
+SELECT STREAM rowtime,
+  'An order for ' || units || ' '
+    || CASE units WHEN 1 THEN 'unit' ELSE 'units' END
+    || ' of product #' || productId AS description
+FROM Orders;
+
+  rowtime | description
+----------+---------------------------------------
+ 10:17:00 | An order for 4 units of product #30
+ 10:17:05 | An order for 1 unit of product #10
+ 10:18:05 | An order for 2 units of product #20
+ 10:18:07 | An order for 20 units of product #30
+ 11:02:00 | An order by 6 units of product #10
+ 11:04:00 | An order by 1 unit of product #10
+ 11:09:30 | An order for 12 units of product #40
+ 11:24:11 | An order by 4 units of product #10
+{% endhighlight %}
+
+We recommend that you always include the `rowtime` column in the `SELECT`
+clause. Having a sorted timestamp in each stream and streaming query makes it
+possible to do advanced calculations later, such as `GROUP BY` and `JOIN`.
+
+# Tumbling windows
+
+There are several ways to compute aggregate functions on streams. The
+differences are:
+
+* How many rows come out for each row in?
+* Does each incoming value appear in one total, or more?
+* What defines the "window", the set of rows that contribute to a given output row?
+* Is the result a stream or a relation?
+
+There are various window types:
+
+* tumbling window (GROUP BY)
+* hopping window (multi GROUP BY)
+* sliding window (window functions)
+* cascading window (window functions)
+
+and the following diagram shows the kinds of query in which to use them:
+
+![Window types]({{ site.baseurl }}/img/window-types.png)
+
+First we'll look a *tumbling window*, which is defined by a streaming
+`GROUP BY`. Here is an example:
+
+{% highlight sql %}
+SELECT STREAM CEIL(rowtime TO HOUR) AS rowtime,
+  productId,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY CEIL(rowtime TO HOUR), productId;
+
+  rowtime | productId |       c | units
+----------+-----------+---------+-------
+ 11:00:00 |        30 |       2 |    24
+ 11:00:00 |        10 |       1 |     1
+ 11:00:00 |        20 |       1 |     7
+ 12:00:00 |        10 |       3 |    11
+ 12:00:00 |        40 |       1 |    12
+{% endhighlight %}
+
+The result is a stream. At 11 o'clock, Calcite emits a sub-total for every
+`productId` that had an order since 10 o'clock, timestamped 11 o'clock.
+At 12 o'clock, it will emit
+the orders that occurred between 11:00 and 12:00. Each input row contributes to
+only one output row.
+
+How did Calcite know that the 10:00:00 sub-totals were complete at 11:00:00,
+so that it could emit them? It knows that `rowtime` is increasing, and it knows
+that `CEIL(rowtime TO HOUR)` is also increasing. So, once it has seen a row
+at or after 11:00:00, it will never see a row that will contribute to a 10:00:00
+total.
+
+A column or expression that is increasing or decreasing is said to be
+*monotonic*.
+
+If column or expression has values that are slightly out of order,
+and the stream has a mechanism (such as punctuation or watermarks)
+to declare that a particular value will never be seen again, then
+the column or expression is said to be *quasi-monotonic*.
+
+Without a monotonic or quasi-monotonic expression in the `GROUP BY` clause,
+Calcite is
+not able to make progress, and it will not allow the query:
+
+{% highlight sql %}
+SELECT STREAM productId,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY productId;
+
+ERROR: Streaming aggregation requires at least one monotonic expression in GROUP BY clause
+{% endhighlight %}
+
+Monotonic and quasi-monotonic columns need to be declared in the schema.
+The monotonicity is
+enforced when records enter the stream and assumed by queries that read from
+that stream. We recommend that you give each stream a timestamp column called
+`rowtime`, but you can declare others to be monotonic, `orderId`, for example.
+
+We discuss punctuation, watermarks, and other ways of making progress
+<a href="#punctuation">below</a>.
+
+# Tumbling windows, improved
+
+The previous example of tumbling windows was easy to write because the window
+was one hour. For intervals that are not a whole time unit, say 2 hours or
+2 hours and 17 minutes, you cannot use `CEIL`, and the expression gets more
+complicated.
+
+Calcite supports an alternative syntax for tumbling windows:
+
+{% highlight sql %}
+SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
+  productId,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;
+
+  rowtime | productId |       c | units
+----------+-----------+---------+-------
+ 11:00:00 |        30 |       2 |    24
+ 11:00:00 |        10 |       1 |     1
+ 11:00:00 |        20 |       1 |     7
+ 12:00:00 |        10 |       3 |    11
+ 12:00:00 |        40 |       1 |    12
+{% endhighlight %}
+
+As you can see, it returns the same results as the previous query. The `TUMBLE`
+function returns a grouping key that is the same for all the rows that will end
+up in a given summary row; the `TUMBLE_END` function takes the same arguments
+and returns the time at which that window ends;
+there is also a `TUMBLE_START` function.
+
+`TUMBLE` has an optional parameter to align the window.
+In the following example,
+we use a 30 minute interval and 0:12 as the alignment time,
+so the query emits summaries at 12 and 42 minutes past each hour:
+
+{% highlight sql %}
+SELECT STREAM
+  TUMBLE_END(rowtime, INTERVAL '30' MINUTE, TIME '0:12') AS rowtime,
+  productId,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY TUMBLE(rowtime, INTERVAL '30' MINUTE, TIME '0:12'),
+  productId;
+
+  rowtime | productId |       c | units
+----------+-----------+---------+-------
+ 10:42:00 |        30 |       2 |    24
+ 10:42:00 |        10 |       1 |     1
+ 10:42:00 |        20 |       1 |     7
+ 11:12:00 |        10 |       2 |     7
+ 11:12:00 |        40 |       1 |    12
+ 11:42:00 |        10 |       1 |     4
+{% endhighlight %}
+
+# Hopping windows
+
+Hopping windows are a generalization of tumbling windows that allow data to
+be kept in a window for a longer than the emit interval.
+
+For example, the following query emits a row timestamped 11:00 containing data
+from 08:00 to 11:00 (or 10:59.9 if we're being pedantic),
+and a row timestamped 12:00 containing data from 09:00
+to 12:00.
+
+{% highlight sql %}
+SELECT STREAM
+  HOP_END(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR) AS rowtime,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY HOP(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR);
+
+  rowtime |        c | units
+----------+----------+-------
+ 11:00:00 |        4 |    27
+ 12:00:00 |        8 |    50
+{% endhighlight %}
+
+In this query, because the retain period is 3 times the emit period, every input
+row contributes to exactly 3 output rows. Imagine that the `HOP` function
+generates a collection of group keys for incoming row, and places its values
+in the accumulators of each of those group keys. For example,
+`HOP(10:18:00, INTERVAL '1' HOUR, INTERVAL '3')` generates 3 periods
+
+```[08:00, 09:00)
+[09:00, 10:00)
+[10:00, 11:00)
+```
+
+This raises the possibility of allowing user-defined partitioning functions
+for users who are not happy with the built-in functions `HOP` and `TUMBLE`.
+
+We can build complex complex expressions such as an exponentially decaying
+moving average:
+
+{% highlight sql %}
+SELECT STREAM HOP_END(rowtime),
+  productId,
+  SUM(unitPrice * EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))
+   / SUM(EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))
+FROM Orders
+GROUP BY HOP(rowtime, INTERVAL '1' SECOND, INTERVAL '1' HOUR),
+  productId
+{% endhighlight %}
+
+Emits:
+
+* a row at `11:00:00` containing rows in `[10:00:00, 11:00:00)`;
+* a row at `11:00:01` containing rows in `[10:00:01, 11:00:01)`.
+
+The expression weighs recent orders more heavily than older orders.
+Extending the window from 1 hour to 2 hours or 1 year would have
+virtually no effect on the accuracy of the result (but use more memory
+and compute).
+
+Note that we use `HOP_START` inside an aggregate function (`SUM`) because it
+is a value that is constant for all rows within a sub-total. This
+would not be allowed for typical aggregate functions (`SUM`, `COUNT`
+etc.).
+
+If you are familiar with `GROUPING SETS`, you may notice that partitioning
+functions can be seen as a generalization of `GROUPING SETS`, in that they
+allow an input row to contribute to multiple sub-totals.
+The auxiliary functions for `GROUPING SETS`,
+such as `GROUPING()` and `GROUP_ID`,
+can be used inside aggregate functions, so it is not surprising that
+`HOP_START` and `HOP_END` can be used in the same way.
+
+# GROUPING SETS
+
+`GROUPING SETS` is valid for a streaming query provided that every
+grouping set contains a monotonic or quasi-monotonic expression.
+
+`CUBE` and `ROLLUP` are not valid for streaming query, because they will
+produce at least one grouping set that aggregates everything (like
+`GROUP BY ()`).
+
+# Filtering after aggregation
+
+As in standard SQL, you can apply a `HAVING` clause to filter rows emitted by
+a streaming `GROUP BY`:
+
+{% highlight sql %}
+SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
+  productId
+FROM Orders
+GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId
+HAVING COUNT(*) > 2 OR SUM(units) > 10;
+
+  rowtime | productId
+----------+-----------
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+{% endhighlight %}
+
+# Sub-queries, views and SQL's closure property
+
+The previous `HAVING` query can be expressed using a `WHERE` clause on a
+sub-query:
+
+{% highlight sql %}
+SELECT STREAM rowtime, productId
+FROM (
+  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
+    productId,
+    COUNT(*) AS c,
+    SUM(units) AS su
+  FROM Orders
+  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId)
+WHERE c > 2 OR su > 10;
+
+  rowtime | productId
+----------+-----------
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+{% endhighlight %}
+
+`HAVING` was introduced in the early days of SQL, when a way was needed to
+perform a filter *after* aggregation. (Recall that `WHERE` filters rows before
+they enter the `GROUP BY` clause.)
+
+Since then, SQL has become a mathematically closed language, which means that
+any operation you can perform on a table can also perform on a query.
+
+The *closure property* of SQL is extremely powerful. Not only does it render
+`HAVING` obsolete (or, at least, reduce it to syntactic sugar), it makes views
+possible:
+
+{% highlight sql %}
+CREATE VIEW HourlyOrderTotals (rowtime, productId, c, su) AS
+  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR),
+    productId,
+    COUNT(*),
+    SUM(units)
+  FROM Orders
+  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;
+
+SELECT STREAM rowtime, productId
+FROM HourlyOrderTotals
+WHERE c > 2 OR su > 10;
+
+  rowtime | productId
+----------+-----------
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+{% endhighlight %}
+
+Sub-queries in the `FROM` clause are sometimes referred to as "inline views",
+but really, they are more fundamental than views. Views are just a convenient
+way to carve your SQL into manageable chunks by giving the pieces names and
+storing them in the metadata repository.
+
+Many people find that nested queries and views are even more useful on streams
+than they are on relations. Streaming queries are pipelines of
+operators all running continuously, and often those pipelines get quite long.
+Nested queries and views help to express and manage those pipelines.
+
+And, by the way, a `WITH` clause can accomplish the same as a sub-query or
+a view:
+
+{% highlight sql %}
+WITH HourlyOrderTotals (rowtime, productId, c, su) AS (
+  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR),
+    productId,
+    COUNT(*),
+    SUM(units)
+  FROM Orders
+  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId)
+SELECT STREAM rowtime, productId
+FROM HourlyOrderTotals
+WHERE c > 2 OR su > 10;
+
+  rowtime | productId
+----------+-----------
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+{% endhighlight %}
+
+# Converting between streams and relations
+
+Look back at the definition of the `HourlyOrderTotals` view.
+Is the view a stream or a relation?
+
+It does not contain the `STREAM` keyword, so it is a relation.
+However, it is a relation that can be converted into a stream.
+
+You can use it in both relational and streaming queries:
+
+{% highlight sql %}
+# A relation; will query the historic Orders table.
+# Returns the largest number of product #10 ever sold in one hour.
+SELECT max(su)
+FROM HourlyOrderTotals
+WHERE productId = 10;
+
+# A stream; will query the Orders stream.
+# Returns every hour in which at least one product #10 was sold.
+SELECT STREAM rowtime
+FROM HourlyOrderTotals
+WHERE productId = 10;
+{% endhighlight %}
+
+This approach is not limited to views and sub-queries.
+Following the approach set out in CQL [<a href="#ref1">1</a>], every query
+in streaming SQL is defined as a relational query and converted to a stream
+using the `STREAM` keyword in the top-most `SELECT`.
+
+If the `STREAM` keyword is present in sub-queries or view definitions, it has no
+effect.
+
+At query preparation time, Calcite figures out whether the relations referenced
+in the query can be converted to streams or historical relations.
+
+Sometimes a stream makes available some of its history (say the last 24 hours of
+data in an Apache Kafka [<a href="#ref2">2</a>] topic)
+but not all. At run time, Calcite figures out whether there is sufficient
+history to run the query, and if not, gives an error.
+
+# The "pie chart" problem: Relational queries on streams
+
+One particular case where you need to convert a stream to a relation
+occurs in what I call the "pie chart problem". Imagine that you need to
+write a web page with a chart, like the following, that summarizes the
+number of orders for each product over the last hour.
+
+![Pie chart]({{ site.baseurl }}/img/pie-chart.png)
+
+But the `Orders` stream only contains a few records, not an hour's summary.
+We need to run a relational query on the history of the stream:
+
+{% highlight sql %}
+SELECT productId, count(*)
+FROM Orders
+WHERE rowtime BETWEEN current_timestamp - INTERVAL '1' HOUR
+              AND current_timestamp;
+{% endhighlight %}
+
+If the history of the `Orders` stream is being spooled to the `Orders` table,
+we can answer the query, albeit at a high cost. Better, if we can tell the
+system to materialize one hour summary into a table,
+maintain it continuously as the stream flows,
+and automatically rewrite queries to use the table.
+
+# Sorting
+
+The story for `ORDER BY` is similar to `GROUP BY`.
+The syntax looks like regular SQL, but Calcite must be sure that it can deliver
+timely results. It therefore requires a monotonic expression on the leading edge
+of your `ORDER BY` key.
+
+{% highlight sql %}
+SELECT STREAM CEIL(rowtime TO hour) AS rowtime, productId, orderId, units
+FROM Orders
+ORDER BY CEIL(rowtime TO hour) ASC, units DESC;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 10:00:00 |        30 |       8 |    20
+ 10:00:00 |        30 |       5 |     4
+ 10:00:00 |        20 |       7 |     2
+ 10:00:00 |        10 |       6 |     1
+ 11:00:00 |        40 |      11 |    12
+ 11:00:00 |        10 |       9 |     6
+ 11:00:00 |        10 |      12 |     4
+ 11:00:00 |        10 |      10 |     1
+{% endhighlight %}
+
+Most queries will return results in the order that they were inserted,
+because the engine is using streaming algorithms, but you should not rely on it.
+For example, consider this:
+
+{% highlight sql %}
+SELECT STREAM *
+FROM Orders
+WHERE productId = 10
+UNION ALL
+SELECT STREAM *
+FROM Orders
+WHERE productId = 30;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 10:17:05 |        10 |       6 |     1
+ 10:17:00 |        30 |       5 |     4
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:24:11 |        10 |      12 |     4
+{% endhighlight %}
+
+The rows with `productId` = 30 are apparently out of order, probably because
+the `Orders` stream was partitioned on `productId` and the partitioned streams
+sent their data at different times.
+
+If you require a particular ordering, add an explicit `ORDER BY`:
+
+{% highlight sql %}
+SELECT STREAM *
+FROM Orders
+WHERE productId = 10
+UNION ALL
+SELECT STREAM *
+FROM Orders
+WHERE productId = 30
+ORDER BY rowtime;
+
+  rowtime | productId | orderId | units
+----------+-----------+---------+-------
+ 10:17:00 |        30 |       5 |     4
+ 10:17:05 |        10 |       6 |     1
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:24:11 |        10 |      12 |     4
+{% endhighlight %}
+
+Calcite will probably implement the `UNION ALL` by merging using `rowtime`,
+which is only slightly less efficient.
+
+You only need to add an `ORDER BY` to the outermost query. If you need to,
+say, perform `GROUP BY` after a `UNION ALL`, Calcite will add an `ORDER BY`
+implicitly, in order to make the GROUP BY algorithm possible.
+
+# Table constructor
+
+The `VALUES` clause creates an inline table with a given set of rows.
+
+Streaming is disallowed. The set of rows never changes, and therefore a stream
+would never return any rows.
+
+{% highlight sql %}
+> SELECT STREAM * FROM (VALUES (1, 'abc'));
+
+ERROR: Cannot stream VALUES
+{% endhighlight %}
+
+# Sliding windows
+
+Standard SQL features so-called "analytic functions" that can be used in the
+`SELECT` clause. Unlike `GROUP BY`, these do not collapse records. For each
+record that goes in, one record comes out. But the aggregate function is based
+on a window of many rows.
+
+Let's look at an example.
+
+{% highlight sql %}
+SELECT STREAM rowtime,
+  productId,
+  units,
+  SUM(units) OVER (ORDER BY rowtime RANGE INTERVAL '1' HOUR PRECEDING) unitsLastHour
+FROM Orders;
+{% endhighlight %}
+
+The feature packs a lot of power with little effort. You can have multiple
+functions in the `SELECT` clause, based on multiple window specifications.
+
+The following example returns orders whose average order size over the last
+10 minutes is greater than the average order size for the last week.
+
+{% highlight sql %}
+SELECT STREAM *
+FROM (
+  SELECT STREAM rowtime,
+    productId,
+    units,
+    AVG(units) OVER product (RANGE INTERVAL '10' MINUTE PRECEDING) AS m10,
+    AVG(units) OVER product (RANGE INTERVAL '7' DAY PRECEDING) AS d7
+  FROM Orders
+  WINDOW product AS (
+    ORDER BY rowtime
+    PARTITION BY productId))
+WHERE m10 > d7;
+{% endhighlight %}
+
+For conciseness, here we use a syntax where you partially define a window
+using a `WINDOW` clause and then refine the window in each `OVER` clause.
+You could also define all windows in the `WINDOW` clause, or all windows inline,
+if you wish.
+
+But the real power goes beyond syntax. Behind the scenes, this query is
+maintaining two tables, and adding and removing values from sub-totals using
+with FIFO queues. But you can access those tables without introducing a join
+into the query.
+
+Some other features of the windowed aggregation syntax:
+
+* You can define windows based on row count.
+* The window can reference rows that have not yet arrived.
+  (The stream will wait until they have arrived).
+* You can compute order-dependent functions such as `RANK` and median.
+
+# Cascading windows
+
+What if we want a query that returns a result for every record, like a
+sliding window, but resets totals on a fixed time period, like a
+tumbling window? Such a pattern is called a *cascading window*. Here
+is an example:
+
+{% highlight sql %}
+SELECT STREAM rowtime,
+  productId,
+  units,
+  SUM(units) OVER (PARTITION BY FLOOR(rowtime TO HOUR)) AS unitsSinceTopOfHour
+FROM Orders;
+{% endhighlight %}
+
+It looks similar to a sliding window query, but the monotonic
+expression occurs within the `PARTITION BY` clause of the window. As
+the rowtime moves from from 10:59:59 to 11:00:00,
+`FLOOR(rowtime TO HOUR)` changes from 10:00:00 to 11:00:00,
+and therefore a new partition starts.
+The first row to arrive in the new hour will start a
+new total; the second row will have a total that consists of two rows,
+and so on.
+
+Calcite knows that the old partition will never be used again, so
+removes all sub-totals for that partition from its internal storage.
+
+Analytic functions that using cascading and sliding windows can be
+combined in the same query.
+
+# Joining streams to tables
+
+There are two kinds of join where streams are concerned: stream-to-table
+join and stream-to-stream join.
+
+A stream-to-table join is straightforward if the contents of the table
+are not changing. This query enriches a stream of orders with
+each product's list price:
+
+{% highlight sql %}
+SELECT STREAM o.rowtime, o.productId, o.orderId, o.units,
+  p.name, p.unitPrice
+FROM Orders AS o
+JOIN Products AS p
+  ON o.productId = p.productId;
+
+  rowtime | productId | orderId | units | name   | unitPrice
+----------+-----------+---------+-------+ -------+-----------
+ 10:17:00 |        30 |       5 |     4 | Cheese |        17
+ 10:17:05 |        10 |       6 |     1 | Beer   |      0.25
+ 10:18:05 |        20 |       7 |     2 | Wine   |         6
+ 10:18:07 |        30 |       8 |    20 | Cheese |        17
+ 11:02:00 |        10 |       9 |     6 | Beer   |      0.25
+ 11:04:00 |        10 |      10 |     1 | Beer   |      0.25
+ 11:09:30 |        40 |      11 |    12 | Bread  |       100
+ 11:24:11 |        10 |      12 |     4 | Beer   |      0.25
+{% endhighlight %}
+
+What should happen if the table is changing? For example,
+suppose the unit price of product 10 is increased to 0.35 at 11:00.
+Orders placed before 11:00 should have the old price, and orders
+placed after 11:00 should reflect the new price.
+
+One way to implement this is to have a table that keeps every version
+with a start and end effective date, `ProductVersions` in the following
+example:
+
+{% highlight sql %}
+SELECT STREAM *
+FROM Orders AS o
+JOIN ProductVersions AS p
+  ON o.productId = p.productId
+  AND o.rowtime BETWEEN p.startDate AND p.endDate
+
+  rowtime | productId | orderId | units | productId1 |   name | unitPrice
+----------+-----------+---------+-------+ -----------+--------+-----------
+ 10:17:00 |        30 |       5 |     4 |         30 | Cheese |        17
+ 10:17:05 |        10 |       6 |     1 |         10 | Beer   |      0.25
+ 10:18:05 |        20 |       7 |     2 |         20 | Wine   |         6
+ 10:18:07 |        30 |       8 |    20 |         30 | Cheese |        17
+ 11:02:00 |        10 |       9 |     6 |         10 | Beer   |      0.35
+ 11:04:00 |        10 |      10 |     1 |         10 | Beer   |      0.35
+ 11:09:30 |        40 |      11 |    12 |         40 | Bread  |       100
+ 11:24:11 |        10 |      12 |     4 |         10 | Beer   |      0.35
+{% endhighlight %}
+
+The other way to implement this is to use a database with temporal support
+(the ability to find the contents of the database as it was at any moment
+in the past), and the system needs to know that the `rowtime` column of
+the `Orders` stream corresponds to the transaction timestamp of the
+`Products` table.
+
+For many applications, it is not worth the cost and effort of temporal
+support or a versioned table. It is acceptable to the application that
+the query gives different results when replayed: in this example, on replay,
+all orders of product 10 are assigned the later unit price, 0.35.
+
+# Joining streams to streams
+
+It makes sense to join two streams if the join condition somehow forces
+them to remain a finite distance from one another. In the following query,
+the ship date is within one hour of the order date:
+
+{% highlight sql %}
+SELECT STREAM o.rowtime, o.productId, o.orderId, s.rowtime AS shipTime
+FROM Orders AS o
+JOIN Shipments AS s
+  ON o.orderId = p.orderId
+  AND s.rowtime BETWEEN o.rowtime AND o.rowtime + INTERVAL '1' HOUR;
+
+  rowtime | productId | orderId | shipTime
+----------+-----------+---------+----------
+ 10:17:00 |        30 |       5 | 10:55:00
+ 10:17:05 |        10 |       6 | 10:20:00
+ 11:02:00 |        10 |       9 | 11:58:00
+ 11:24:11 |        10 |      12 | 11:44:00
+{% endhighlight %}
+
+Note that quite a few orders do not appear, because they did not ship
+within an hour. By the time the system receives order 10, timestamped 11:24:11,
+it has already removed orders up to and including order 8, timestamped 10:18:07,
+from its hash table.
+
+As you can see, the "lock step", tying together monotonic or quasi-monotonic
+columns of the two streams, is necessary for the system to make progress.
+It will refuse to execute a query if it cannot deduce a lock step.
+
+# DML
+
+It's not only queries that make sense against streams;
+it also makes sense to run DML statements (`INSERT`, `UPDATE`, `DELETE`,
+and also their rarer cousins `UPSERT` and `REPLACE`) against streams.
+
+DML is useful because it allows you do materialize streams
+or tables based on streams,
+and therefore save effort when values are used often.
+
+Consider how streaming applications often consist of pipelines of queries,
+each query transforming input stream(s) to output stream(s).
+The component of a pipeline can be a view:
+
+{% highlight sql %}
+CREATE VIEW LargeOrders AS
+SELECT STREAM * FROM Orders WHERE units > 1000;
+{% endhighlight %}
+
+or a standing `INSERT` statement:
+
+{% highlight sql %}
+INSERT INTO LargeOrders
+SELECT STREAM * FROM Orders WHERE units > 1000;
+{% endhighlight %}
+
+These look similar, and in both cases the next step(s) in the pipeline
+can read from `LargeOrders` without worrying how it was populated.
+There is a difference in efficiency: the `INSERT` statement does the 
+same work no matter how many consumers there are; the view does work
+proportional to the number of consumers, and in particular, does no 
+work if there are no consumers.
+
+Other forms of DML make sense for streams. For example, the following
+standing `UPSERT` statement maintains a table that materializes a summary
+of the last hour of orders:
+
+{% highlight sql %}
+UPSERT INTO OrdersSummary
+SELECT STREAM productId,
+  COUNT(*) OVER lastHour AS c
+FROM Orders
+WINDOW lastHour AS (
+  PARTITION BY productId
+  ORDER BY rowtime
+  RANGE INTERVAL '1' HOUR PRECEDING)
+{% endhighlight %}
+
+# Punctuation
+
+Punctuation[<a href="#ref5">5</a>] allows a stream query to make progress
+even if there are not enough values in a monotonic key to push the results out.
+
+(I prefer the term "rowtime bounds",
+and watermarks[<a href="#ref6">6</a>] are a related concept,
+but for these purposes, punctuation will suffice.)
+
+If a stream has punctuation enabled then it may not be sorted but is
+nevertheless sortable. So, for the purposes of semantics, it is sufficient
+to work in terms of sorted streams.
+
+By the way, an out-of-order stream is also sortable if it is *t-sorted*
+(i.e. every record is guaranteed to arrive within *t* seconds of its
+timestamp) or *k-sorted* (i.e. every record is guaranteed to be no more
+than *k* positions out of order). So queries on these streams can be
+planned similarly to queries on streams with punctuation.
+
+And, we often want to aggregate over attributes that are not
+time-based but are nevertheless monotonic. "The number of times a team
+has shifted between winning-state and losing-state" is one such
+monotonic attribute. The system needs to figure out for itself that it
+is safe to aggregate over such an attribute; punctuation does not add
+any extra information.
+
+I have in mind some metadata (cost metrics) for the planner:
+
+1. Is this stream sorted on a given attribute (or attributes)?
+2. Is it possible to sort the stream on a given attribute? (For finite
+   relations, the answer is always "yes"; for streams it depends on the
+   existence of punctuation, or linkage between the attributes and the
+   sort key.)
+3. What latency do we need to introduce in order to perform that sort?
+4. What is the cost (in CPU, memory etc.) of performing that sort?
+
+We already have (1), in [BuiltInMetadata.Collation]({{ site.apiRoot }}/org/apache/calcite/rel/metadata/BuiltInMetadata.Collation.html).
+For (2), the answer is always "true" for finite relations.
+But we'll need to implement (2), (3) and (4) for streams.
+
+# State of the stream
+
+Not all concepts in this article have been implemented in Calcite.
+And others may be implemented in Calcite but not in a particular adapter
+such as SamzaSQL [<a href="#ref3">3</a>] [<a href="#ref4">4</a>].
+
+## Implemented
+
+* Streaming `SELECT`, `WHERE`, `GROUP BY`, `HAVING`, `UNION ALL`, `ORDER BY`
+* `FLOOR` and `CEIL` functions
+* Monotonicity
+* Streaming `VALUES` is disallowed
+
+## Not implemented
+
+The following features are presented in this document as if Calcite
+supports them, but in fact it does not (yet). Full support means
+that the reference implementation supports the feature (including
+negative cases) and the TCK tests it.
+
+* Stream-to-stream `JOIN`
+* Stream-to-table `JOIN`
+* Stream on view
+* Streaming `UNION ALL` with `ORDER BY` (merge)
+* Relational query on stream
+* Streaming windowed aggregation (sliding and cascading windows)
+* Check that `STREAM` in sub-queries and views is ignored
+* Check that streaming `ORDER BY` cannot have `OFFSET` or `LIMIT`
+* Limited history; at run time, check that there is sufficient history
+  to run the query.
+* [Quasi-monotonicity](https://issues.apache.org/jira/browse/CALCITE-1096)
+* `HOP` and `TUMBLE` (and auxiliary `HOP_START`, `HOP_END`,
+  `TUMBLE_START`, `TUMBLE_END`) functions
+
+## To do in this document
+
+* Re-visit whether you can stream `VALUES`
+* `OVER` clause to define window on stream
+* Consider whether to allow `CUBE` and `ROLLUP` in streaming queries,
+  with an understanding that some levels of aggregation will never complete
+  (because they have no monotonic expressions) and thus will never be emitted.
+* Fix the `UPSERT` example to remove records for products that have not
+  occurred in the last hour.
+* DML that outputs to multiple streams; perhaps an extension to the standard
+  `REPLACE` statement. 
+
+# Functions
+
+The following functions are not present in standard SQL
+but are defined in streaming SQL.
+
+Scalar functions:
+
+* `FLOOR(dateTime TO intervalType)` rounds a date, time or timestamp value
+  down to a given interval type
+* `CEIL(dateTime TO intervalType)` rounds a date, time or timestamp value
+  up to a given interval type
+
+Partitioning functions:
+
+* `HOP(t, emit, retain)` returns a collection of group keys for a row
+  to be part of a hopping window
+* `HOP(t, emit, retain, align)` returns a collection of group keys for a row
+  to be part of a hopping window with a given alignment
+* `TUMBLE(t, emit)` returns a group key for a row
+  to be part of a tumbling window
+* `TUMBLE(t, emit, align)` returns a group key for a row
+  to be part of a tumbling window with a given alignment
+
+`TUMBLE(t, e)` is equivalent to `TUMBLE(t, e, TIME '00:00:00')`.
+
+`TUMBLE(t, e, a)` is equivalent to `HOP(t, e, e, a)`.
+
+`HOP(t, e, r)` is equivalent to `HOP(t, e, r, TIME '00:00:00')`.
+
+# References
+
+* [<a name="ref1">1</a>]
+  <a href="http://ilpubs.stanford.edu:8090/758/">Arvind Arasu, Shivnath Babu,
+  and Jennifer Widom (2003) The CQL Continuous Query
+  Language: Semantic Foundations and Query Execution</a>.
+* [<a name="ref2">2</a>]
+  <a href="http://kafka.apache.org/documentation.html">Apache Kafka</a>.
+* [<a name="ref3">3</a>] <a href="http://samza.apache.org">Apache Samza</a>.
+* [<a name="ref4">4</a>] <a href="https://github.com/milinda/samza-sql">SamzaSQL</a>.
+* [<a name="ref5">5</a>]
+  <a href="http://www.whitworth.edu/academic/department/mathcomputerscience/faculty/tuckerpeter/pdf/117896_final.pdf">Peter
+  A. Tucker, David Maier, Tim Sheard, and Leonidas Fegaras (2003) Exploiting
+  Punctuation Semantics in Continuous Data Streams</a>.
+* [<a name="ref6">6</a>]
+  <a href="http://research.google.com/pubs/pub41378.html">Tyler Akidau,
+  Alex Balikov, Kaya Bekiroglu, Slava Chernyak, Josh Haberman, Reuven Lax,
+  Sam McVeety, Daniel Mills, Paul Nordstrom, and Sam Whittle (2013)
+  MillWheel: Fault-Tolerant Stream Processing at Internet Scale</a>.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/site/_docs/testapi.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/testapi.md b/avatica/site/_docs/testapi.md
new file mode 100644
index 0000000..661f374
--- /dev/null
+++ b/avatica/site/_docs/testapi.md
@@ -0,0 +1,28 @@
+---
+title: Test API
+layout: external
+external_url: /testapidocs
+---
+{% comment %}
+Ideally, we want to use {{ site.apiRoot }} instead of hardcoding
+the above external_url value, but I don't believe there's a way to do that
+{% endcomment %}
+
+<!--
+{% comment %}
+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.
+{% endcomment %}
+-->


[46/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
deleted file mode 100644
index ff95a45..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
+++ /dev/null
@@ -1,626 +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.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaSqlException;
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.ConnectionSpec;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-import org.apache.calcite.avatica.remote.Service.Response;
-import org.apache.calcite.avatica.server.AvaticaJsonHandler;
-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.base.Throwables;
-import com.google.common.cache.Cache;
-
-import org.junit.AfterClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.sql.Array;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.instanceOf;
-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.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/** Tests covering {@link RemoteMeta}. */
-@RunWith(Parameterized.class)
-public class RemoteMetaTest {
-  private static final Random RANDOM = new Random();
-  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
-
-  // Keep a reference to the servers we start to clean them up after
-  private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
-
-  private final HttpServer server;
-  private final String url;
-  private final int port;
-  private final Driver.Serialization serialization;
-
-  @Parameters
-  public static List<Object[]> parameters() throws Exception {
-    List<Object[]> params = new ArrayList<>();
-
-    final String[] mainArgs = { FullyRemoteJdbcMetaFactory.class.getName() };
-
-    // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
-
-    final HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
-      @Override public AvaticaJsonHandler createHandler(Service service) {
-        return new AvaticaJsonHandler(service);
-      }
-    });
-    params.add(new Object[] {jsonServer, Driver.Serialization.JSON});
-    ACTIVE_SERVERS.add(jsonServer);
-
-    final HttpServer protobufServer = Main.start(mainArgs, 0, new HandlerFactory() {
-      @Override public AvaticaProtobufHandler createHandler(Service service) {
-        return new AvaticaProtobufHandler(service);
-      }
-    });
-    params.add(new Object[] {protobufServer, Driver.Serialization.PROTOBUF});
-
-    ACTIVE_SERVERS.add(protobufServer);
-
-    return params;
-  }
-
-  public RemoteMetaTest(HttpServer server, Driver.Serialization serialization) {
-    this.server = server;
-    this.port = this.server.getPort();
-    this.serialization = serialization;
-    url = "jdbc:avatica:remote:url=http://localhost:" + port + ";serialization="
-        + serialization.name();
-  }
-
-  @AfterClass public static void afterClass() throws Exception {
-    for (HttpServer server : ACTIVE_SERVERS) {
-      if (server != null) {
-        server.stop();
-      }
-    }
-  }
-
-  private static Meta getMeta(AvaticaConnection conn) throws Exception {
-    Field f = AvaticaConnection.class.getDeclaredField("meta");
-    f.setAccessible(true);
-    return (Meta) f.get(conn);
-  }
-
-  private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
-    final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
-    Method m =
-        AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
-            AvaticaStatement.class, String.class, long.class);
-    m.setAccessible(true);
-    return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
-  }
-
-  private static Connection getConnection(JdbcMeta m, String id) throws Exception {
-    Field f = JdbcMeta.class.getDeclaredField("connectionCache");
-    f.setAccessible(true);
-    //noinspection unchecked
-    Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
-    return connectionCache.getIfPresent(id);
-  }
-
-  @Test public void testRemoteExecuteMaxRowCount() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      final AvaticaStatement statement = conn.createStatement();
-      prepareAndExecuteInternal(conn, statement,
-        "select * from (values ('a', 1), ('b', 2))", 0);
-      ResultSet rs = statement.getResultSet();
-      int count = 0;
-      while (rs.next()) {
-        count++;
-      }
-      assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
-      assertEquals("Check result set meta is still there",
-        rs.getMetaData().getColumnCount(), 2);
-      rs.close();
-      statement.close();
-      conn.close();
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  /** Test case for
-   * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
-   * HTTP error 413 when sending a long string to the Avatica server</a>. */
-  @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      // Before the bug was fixed, a value over 7998 caused an HTTP 413.
-      // 16K bytes, I guess.
-      checkLargeQuery(8);
-      checkLargeQuery(240);
-      checkLargeQuery(8000);
-      checkLargeQuery(240000);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private void checkLargeQuery(int n) throws Exception {
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      final AvaticaStatement statement = conn.createStatement();
-      final String frenchDisko = "It said human existence is pointless\n"
-          + "As acts of rebellious solidarity\n"
-          + "Can bring sense in this world\n"
-          + "La resistance!\n";
-      final String sql = "select '"
-          + longString(frenchDisko, n)
-          + "' as s from (values 'x')";
-      prepareAndExecuteInternal(conn, statement, sql, -1);
-      ResultSet rs = statement.getResultSet();
-      int count = 0;
-      while (rs.next()) {
-        count++;
-      }
-      assertThat(count, is(1));
-      rs.close();
-      statement.close();
-      conn.close();
-    }
-  }
-
-  /** Creates a string of exactly {@code length} characters by concatenating
-   * {@code fragment}. */
-  private static String longString(String fragment, int length) {
-    assert fragment.length() > 0;
-    final StringBuilder buf = new StringBuilder();
-    while (buf.length() < length) {
-      buf.append(fragment);
-    }
-    buf.setLength(length);
-    return buf.toString();
-  }
-
-  @Test public void testRemoteConnectionProperties() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      String id = conn.id;
-      final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
-      assertFalse("remote connection map should start ignorant", m.containsKey(id));
-      // force creating a connection object on the remote side.
-      try (final Statement stmt = conn.createStatement()) {
-        assertTrue("creating a statement starts a local object.", m.containsKey(id));
-        assertTrue(stmt.execute("select count(1) from EMP"));
-      }
-      Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
-      final boolean defaultRO = remoteConn.isReadOnly();
-      final boolean defaultAutoCommit = remoteConn.getAutoCommit();
-      final String defaultCatalog = remoteConn.getCatalog();
-      final String defaultSchema = remoteConn.getSchema();
-      conn.setReadOnly(!defaultRO);
-      assertTrue("local changes dirty local state", m.get(id).isDirty());
-      assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
-      conn.setAutoCommit(!defaultAutoCommit);
-      assertEquals("remote connection has not been touched",
-          defaultAutoCommit, remoteConn.getAutoCommit());
-
-      // further interaction with the connection will force a sync
-      try (final Statement stmt = conn.createStatement()) {
-        assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
-        assertFalse("local values should be clean", m.get(id).isDirty());
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testRemoteStatementInsert() throws Exception {
-    final String t = AvaticaUtils.unique("TEST_TABLE2");
-    AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
-    Statement statement = conn.createStatement();
-    final String create =
-        String.format("create table if not exists %s ("
-            + "  id int not null, msg varchar(255) not null)", t);
-    int status = statement.executeUpdate(create);
-    assertEquals(status, 0);
-
-    statement = conn.createStatement();
-    final String update = String.format("insert into %s values ('%d', '%s')",
-        t, RANDOM.nextInt(Integer.MAX_VALUE), UUID.randomUUID());
-    status = statement.executeUpdate(update);
-    assertEquals(status, 1);
-  }
-
-  @Test public void testBigints() throws Exception {
-    final String table = "TESTBIGINTS";
-    ConnectionSpec.getDatabaseLock().lock();
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
-        Statement stmt = conn.createStatement()) {
-      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + table));
-      assertFalse(stmt.execute("CREATE TABLE " + table + " (id BIGINT)"));
-      assertFalse(stmt.execute("INSERT INTO " + table + " values(10)"));
-      ResultSet results = conn.getMetaData().getColumns(null, null, table, null);
-      assertTrue(results.next());
-      assertEquals(table, results.getString(3));
-      // ordinal position
-      assertEquals(1L, results.getLong(17));
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testOpenConnectionWithProperties() throws Exception {
-    // This tests that username and password are used for creating a connection on the
-    // server. If this was not the case, it would succeed.
-    try {
-      DriverManager.getConnection(url, "john", "doe");
-      fail("expected exception");
-    } catch (RuntimeException e) {
-      assertEquals("Remote driver error: RuntimeException: "
-          + "java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification"
-          + " - not found: john"
-          + " -> SQLInvalidAuthorizationSpecException: invalid authorization specification - "
-          + "not found: john"
-          + " -> HsqlException: invalid authorization specification - not found: john",
-          e.getMessage());
-    }
-  }
-
-  @Test public void testRemoteConnectionsAreDifferent() throws SQLException {
-    Connection conn1 = DriverManager.getConnection(url);
-    Statement stmt = conn1.createStatement();
-    stmt.execute("DECLARE LOCAL TEMPORARY TABLE"
-        + " buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100))");
-    stmt.execute("insert into buffer(id, textdata) values(1, 'abc')");
-    stmt.executeQuery("select * from buffer");
-
-    // The local temporary table is local to the connection above, and should
-    // not be visible on another connection
-    Connection conn2 = DriverManager.getConnection(url);
-    Statement stmt2 = conn2.createStatement();
-    try {
-      stmt2.executeQuery("select * from buffer");
-      fail("expected exception");
-    } catch (Exception e) {
-      assertEquals("Error -1 (00000) : Error while executing SQL \"select * from buffer\": "
-          + "Remote driver error: RuntimeException: java.sql.SQLSyntaxErrorException: "
-          + "user lacks privilege or object not found: BUFFER -> "
-          + "SQLSyntaxErrorException: user lacks privilege or object not found: BUFFER -> "
-          + "HsqlException: user lacks privilege or object not found: BUFFER",
-          e.getMessage());
-    }
-  }
-
-  @Ignore("[CALCITE-942] AvaticaConnection should fail-fast when closed.")
-  @Test public void testRemoteConnectionClosing() throws Exception {
-    AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
-    // Verify connection is usable
-    conn.createStatement();
-    conn.close();
-
-    // After closing the connection, it should not be usable anymore
-    try {
-      conn.createStatement();
-      fail("expected exception");
-    } catch (SQLException e) {
-      assertThat(e.getMessage(),
-          containsString("Connection is closed"));
-    }
-  }
-
-  @Test public void testExceptionPropagation() throws Exception {
-    final String sql = "SELECT * from EMP LIMIT FOOBARBAZ";
-    ConnectionSpec.getDatabaseLock().lock();
-    try (final AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
-        final Statement stmt = conn.createStatement()) {
-      try {
-        // invalid SQL
-        stmt.execute(sql);
-        fail("Expected an AvaticaSqlException");
-      } catch (AvaticaSqlException e) {
-        assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, e.getErrorCode());
-        assertEquals(ErrorResponse.UNKNOWN_SQL_STATE, e.getSQLState());
-        assertTrue("Message should contain original SQL, was '" + e.getMessage() + "'",
-            e.getMessage().contains(sql));
-        assertEquals(1, e.getStackTraces().size());
-        final String stacktrace = e.getStackTraces().get(0);
-        final String substring = "unexpected token: FOOBARBAZ";
-        assertTrue("Message should contain '" + substring + "', was '" + e.getMessage() + ",",
-            stacktrace.contains(substring));
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testRemoteColumnsMeta() throws Exception {
-    // Verify all columns are retrieved, thus that frame-based fetching works correctly for columns
-    int rowCount = 0;
-    try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
-      ResultSet rs = conn.getMetaData().getColumns(null, null, null, null);
-      while (rs.next()) {
-        rowCount++;
-      }
-      rs.close();
-
-      // The implicitly created statement should have been closed
-      assertTrue(rs.getStatement().isClosed());
-    }
-    // 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();
-    }
-  }
-
-  @Test public void testBinaryAndStrings() throws Exception {
-    final String tableName = "testbinaryandstrs";
-    final byte[] data = "asdf".getBytes(StandardCharsets.UTF_8);
-    ConnectionSpec.getDatabaseLock().lock();
-    try (final Connection conn = DriverManager.getConnection(url);
-        final Statement stmt = conn.createStatement()) {
-      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
-      assertFalse(stmt.execute("CREATE TABLE " + tableName + "(id int, bin BINARY(4))"));
-      try (final PreparedStatement prepStmt = conn.prepareStatement(
-          "INSERT INTO " + tableName + " values(1, ?)")) {
-        prepStmt.setBytes(1, data);
-        assertFalse(prepStmt.execute());
-      }
-      try (ResultSet results = stmt.executeQuery("SELECT id, bin from " + tableName)) {
-        assertTrue(results.next());
-        assertEquals(1, results.getInt(1));
-        // byte comparison should work
-        assertArrayEquals("Bytes were " + Arrays.toString(results.getBytes(2)),
-            data, results.getBytes(2));
-        // as should string
-        assertEquals(new String(data, StandardCharsets.UTF_8), results.getString(2));
-        assertFalse(results.next());
-      }
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testLocalStackTraceHasServerStackTrace() {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      Statement statement = DriverManager.getConnection(url).createStatement();
-      statement.executeQuery("SELECT * FROM BOGUS_TABLE_DEF_DOESNT_EXIST");
-    } catch (SQLException e) {
-      // Verify that we got the expected exception
-      assertThat(e, instanceOf(AvaticaSqlException.class));
-
-      // Attempt to verify that we got a "server-side" class in the stack.
-      assertThat(Throwables.getStackTraceAsString(e),
-          containsString(JdbcMeta.class.getName()));
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testServerAddressInResponse() throws Exception {
-    ConnectionSpec.getDatabaseLock().lock();
-    try {
-      URL url = new URL("http://localhost:" + this.port);
-      AvaticaHttpClient httpClient = new AvaticaHttpClientImpl(url);
-      byte[] request;
-
-      Service.OpenConnectionRequest jsonReq = new Service.OpenConnectionRequest(
-          UUID.randomUUID().toString(), Collections.<String, String>emptyMap());
-      switch (this.serialization) {
-      case JSON:
-        request = JsonService.MAPPER.writeValueAsBytes(jsonReq);
-        break;
-      case PROTOBUF:
-        ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
-        request = pbTranslation.serializeRequest(jsonReq);
-        break;
-      default:
-        throw new IllegalStateException("Should not reach here");
-      }
-
-      byte[] response = httpClient.send(request);
-      Service.OpenConnectionResponse openCnxnResp;
-      switch (this.serialization) {
-      case JSON:
-        openCnxnResp = JsonService.MAPPER.readValue(response,
-            Service.OpenConnectionResponse.class);
-        break;
-      case PROTOBUF:
-        ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
-        Response genericResp = pbTranslation.parseResponse(response);
-        assertTrue("Expected an OpenConnnectionResponse, but got " + genericResp.getClass(),
-            genericResp instanceof Service.OpenConnectionResponse);
-        openCnxnResp = (Service.OpenConnectionResponse) genericResp;
-        break;
-      default:
-        throw new IllegalStateException("Should not reach here");
-      }
-
-      String hostname = InetAddress.getLocalHost().getHostName();
-
-      assertNotNull(openCnxnResp.rpcMetadata);
-      assertEquals(hostname + ":" + this.port, openCnxnResp.rpcMetadata.serverAddress);
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  @Test public void testCommitRollback() throws Exception {
-    final String productTable = "commitrollback_products";
-    final String salesTable = "commitrollback_sales";
-    ConnectionSpec.getDatabaseLock().lock();
-    try (final Connection conn = DriverManager.getConnection(url);
-        final Statement stmt = conn.createStatement()) {
-      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + productTable));
-      assertFalse(
-          stmt.execute(
-              String.format("CREATE TABLE %s(id integer, stock integer)", productTable)));
-      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + salesTable));
-      assertFalse(
-          stmt.execute(
-              String.format("CREATE TABLE %s(id integer, units_sold integer)", salesTable)));
-
-      final int productId = 1;
-      // No products and no sales
-      assertFalse(
-          stmt.execute(
-              String.format("INSERT INTO %s VALUES(%d, 0)", productTable, productId)));
-      assertFalse(
-          stmt.execute(
-              String.format("INSERT INTO %s VALUES(%d, 0)", salesTable, productId)));
-
-      conn.setAutoCommit(false);
-      PreparedStatement productStmt = conn.prepareStatement(
-          String.format("UPDATE %s SET stock = stock + ? WHERE id = ?", productTable));
-      PreparedStatement salesStmt = conn.prepareStatement(
-          String.format("UPDATE %s SET units_sold = units_sold + ? WHERE id = ?", salesTable));
-
-      // No stock
-      assertEquals(0, getInventory(conn, productTable, productId));
-
-      // Set a stock of 10 for product 1
-      productStmt.setInt(1, 10);
-      productStmt.setInt(2, productId);
-      productStmt.executeUpdate();
-
-      conn.commit();
-      assertEquals(10, getInventory(conn, productTable, productId));
-
-      // Sold 5 items (5 in stock, 5 sold)
-      productStmt.setInt(1, -5);
-      productStmt.setInt(2, productId);
-      productStmt.executeUpdate();
-      salesStmt.setInt(1, 5);
-      salesStmt.setInt(2, productId);
-      salesStmt.executeUpdate();
-
-      conn.commit();
-      // We will definitely see the updated values
-      assertEquals(5, getInventory(conn, productTable, productId));
-      assertEquals(5, getSales(conn, salesTable, productId));
-
-      // Update some "bad" values
-      productStmt.setInt(1, -10);
-      productStmt.setInt(2, productId);
-      productStmt.executeUpdate();
-      salesStmt.setInt(1, 10);
-      salesStmt.setInt(2, productId);
-      salesStmt.executeUpdate();
-
-      // We just went negative, nonsense. Better rollback.
-      conn.rollback();
-
-      // Should still have 5 and 5
-      assertEquals(5, getInventory(conn, productTable, productId));
-      assertEquals(5, getSales(conn, salesTable, productId));
-    } finally {
-      ConnectionSpec.getDatabaseLock().unlock();
-    }
-  }
-
-  private int getInventory(Connection conn, String productTable, int productId) throws Exception {
-    try (Statement stmt = conn.createStatement()) {
-      ResultSet results = stmt.executeQuery(
-          String.format("SELECT stock FROM %s WHERE id = %d", productTable, productId));
-      assertTrue(results.next());
-      return results.getInt(1);
-    }
-  }
-
-  private int getSales(Connection conn, String salesTable, int productId) throws Exception {
-    try (Statement stmt = conn.createStatement()) {
-      ResultSet results = stmt.executeQuery(
-          String.format("SELECT units_sold FROM %s WHERE id = %d", salesTable, productId));
-      assertTrue(results.next());
-      return results.getInt(1);
-    }
-  }
-
-  /** Factory that provides a {@link JdbcMeta}. */
-  public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
-
-    private static JdbcMeta instance = null;
-
-    private static JdbcMeta getInstance() {
-      if (instance == null) {
-        try {
-          instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
-              CONNECTION_SPEC.password);
-        } catch (SQLException e) {
-          throw new RuntimeException(e);
-        }
-      }
-      return instance;
-    }
-
-    @Override public Meta create(List<String> args) {
-      return getInstance();
-    }
-  }
-}
-
-// End RemoteMetaTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
deleted file mode 100644
index 3504e02..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/server/HandlerFactoryTest.java
+++ /dev/null
@@ -1,58 +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.server;
-
-import org.apache.calcite.avatica.remote.Driver.Serialization;
-import org.apache.calcite.avatica.remote.Service;
-
-import org.eclipse.jetty.server.Handler;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests the {@link HandlerFactory} implementation.
- */
-public class HandlerFactoryTest {
-
-  private HandlerFactory factory;
-  private Service service;
-
-  @Before
-  public void setup() {
-    this.factory = new HandlerFactory();
-    this.service = Mockito.mock(Service.class);
-  }
-
-  @Test
-  public void testJson() {
-    Handler handler = factory.getHandler(service, Serialization.JSON);
-    assertTrue("Expected an implementation of the AvaticaHandler, "
-        + "but got " + handler.getClass(), handler instanceof AvaticaJsonHandler);
-  }
-
-  @Test
-  public void testProtobuf() {
-    Handler handler = factory.getHandler(service, Serialization.PROTOBUF);
-    assertTrue("Expected an implementation of the AvaticaProtobufHandler, "
-        + "but got " + handler.getClass(), handler instanceof AvaticaProtobufHandler);
-  }
-}
-
-// End HandlerFactoryTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java b/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
deleted file mode 100644
index 4a0c26c..0000000
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
+++ /dev/null
@@ -1,37 +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.test;
-
-import org.apache.calcite.avatica.RemoteDriverTest;
-
-import org.junit.runner.RunWith;
-
-import org.junit.runners.Suite;
-
-/**
- * Avatica test suite.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    AvaticaUtilsTest.class,
-    ConnectStringParserTest.class,
-    RemoteDriverTest.class
-})
-public class AvaticaSuite {
-}
-
-// End AvaticaSuite.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica-server/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/resources/log4j.properties b/avatica-server/src/test/resources/log4j.properties
deleted file mode 100644
index 834e2db..0000000
--- a/avatica-server/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +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.
-
-# Root logger is configured at INFO and is sent to A1
-log4j.rootLogger=INFO, A1
-
-# A1 goes to the console
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# Set the pattern for each log message
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p - %m%n

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/LICENSE
----------------------------------------------------------------------
diff --git a/avatica/LICENSE b/avatica/LICENSE
new file mode 100644
index 0000000..f7b9863
--- /dev/null
+++ b/avatica/LICENSE
@@ -0,0 +1,268 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+
+
+
+
+-----------------------------------------------------------------------
+
+APACHE CALCITE SUBCOMPONENTS:
+
+The Apache Calcite project contains subcomponents with separate copyright
+notices and license terms. Your use of the source code for the these
+subcomponents is subject to the terms and conditions of the following
+licenses.
+
+-----------------------------------------------------------------------
+ The MIT License
+-----------------------------------------------------------------------
+
+The Apache Calcite project bundles the following files under the MIT License:
+
+- site
+    Parts of the web site generated by Jekyll (http://jekyllrb.com/)
+    Copyright (c) 2008-2015 Tom Preston-Werner
+- site/_sass/_font-awesome.scss
+    Font-awesome css files v4.1.0 (http://fortawesome.github.io/Font-Awesome/)
+    Copyright (c) 2013  Dave Gandy
+- site/_sass/_normalize.scss
+    normalize.css v3.0.2 | git.io/normalize
+    Copyright (c) Nicolas Gallagher and Jonathan Neal
+- site/_sass/_gridism.scss
+    Gridism: A simple, responsive, and handy CSS grid by @cobyism
+    https://github.com/cobyism/gridism
+    Copyright (c) 2013 Coby Chapple
+- site/js/html5shiv.min.js
+    HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem
+- site/js/respond.min.js
+    Respond.js v1.4.2: min/max-width media query polyfill
+    Copyright 2013 Scott Jehl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----------------------------------------------------------------------
+ The Open Font License
+-----------------------------------------------------------------------
+
+The Apache Calcite project bundles the following fonts under the
+SIL Open Font License (OFL) - http://scripts.sil.org/OFL/
+
+- site/fonts/fontawesome-webfont.*
+   Font-awesome font files v4.0.3 (http://fortawesome.github.io/Font-Awesome/)

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/NOTICE
----------------------------------------------------------------------
diff --git a/avatica/NOTICE b/avatica/NOTICE
new file mode 100644
index 0000000..989c480
--- /dev/null
+++ b/avatica/NOTICE
@@ -0,0 +1,10 @@
+Apache Calcite
+Copyright 2012-2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This product is based on source code originally developed
+by DynamoBI Corporation, LucidEra Inc., SQLstream Inc. and others
+under the auspices of the Eigenbase Foundation
+and released as the LucidDB project.

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/core/pom.xml b/avatica/core/pom.xml
new file mode 100644
index 0000000..192d2dd
--- /dev/null
+++ b/avatica/core/pom.xml
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica-parent</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>calcite-avatica</artifactId>
+  <packaging>jar</packaging>
+  <name>Calcite Avatica</name>
+  <description>JDBC driver framework.</description>
+
+  <properties>
+    <top.dir>${project.basedir}/..</top.dir>
+  </properties>
+
+  <dependencies>
+    <!-- Make sure that there are no dependencies on other calcite modules,
+         or on libraries other than Jackson. -->
+    <dependency>
+      <groupId>org.apache.calcite</groupId>
+      <artifactId>calcite-avatica-metrics</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <versionRange>[2.12.1,)</versionRange>
+                    <goals>
+                      <goal>check</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>analyze</id>
+            <goals>
+              <goal>analyze-only</goal>
+            </goals>
+            <configuration>
+              <failOnWarning>true</failOnWarning>
+              <!-- ignore "unused but declared" warnings -->
+              <ignoredUnusedDeclaredDependencies>
+                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+              </ignoredUnusedDeclaredDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Parent module has the same plugin and does the work of
+           generating -sources.jar for each project. But without the
+           plugin declared here, IDEs don't know the sources are
+           available. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Produce a tests jar so that avatica-server/pom.xml can reference for suite.
+           TODO: remove after moving over to annotation-based TestSuite definitions. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>non-root-resources</id>
+            <goals>
+              <goal>process</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <relocations>
+                <relocation>
+                  <pattern>com.google.protobuf</pattern>
+                  <shadedPattern>org.apache.calcite.avatica.com.google.protobuf</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.http</pattern>
+                  <shadedPattern>org.apache.calcite.avatica.org.apache.http</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.commons</pattern>
+                  <shadedPattern>org.apache.calcite.avatica.org.apache.commons</shadedPattern>
+                </relocation>
+              </relocations>
+              <createDependencyReducedPom>false</createDependencyReducedPom>
+              <transformers>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
+                    <addHeader>false</addHeader>
+                </transformer>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
+                  <resources>
+                    <resource>LICENSE.txt</resource>
+                  </resources>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java b/avatica/core/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
new file mode 100644
index 0000000..62c4dd2
--- /dev/null
+++ b/avatica/core/src/main/java/com/google/protobuf/HBaseZeroCopyByteString.java
@@ -0,0 +1,77 @@
+/*
+ * 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 com.google.protobuf;
+
+/**
+ * Helper class to extract byte arrays from {@link ByteString} without copy.
+ *
+ * Without this protobufs would force us to copy every single byte array out
+ * of the objects de-serialized from the wire (which already do one copy, on
+ * top of the copies the JVM does to go from kernel buffer to C buffer and
+ * from C buffer to JVM buffer).
+ *
+ * Graciously copied from Apache HBase.
+ */
+public final class HBaseZeroCopyByteString extends LiteralByteString {
+  // Gotten from AsyncHBase code base with permission.
+  /** Private constructor so this class cannot be instantiated. */
+  private HBaseZeroCopyByteString() {
+    super(null);
+    throw new UnsupportedOperationException("Should never be here.");
+  }
+
+  /**
+   * Wraps a byte array in a {@link ByteString} without copying it.
+   *
+   * @param array The byte array to wrap
+   * @return a ByteString wrapping the <code>array</code>
+   */
+  public static ByteString wrap(final byte[] array) {
+    return new LiteralByteString(array);
+  }
+
+  /**
+   * Wraps a subset of a byte array in a {@link ByteString} without copying it.
+   *
+   * @param array The byte array to wrap
+   * @param offset the start of data in the array
+   * @param length The number of bytes of data at <code>offset</code>
+   * @return a ByteString wrapping the <code>array</code>
+   */
+  public static ByteString wrap(final byte[] array, int offset, int length) {
+    return new BoundedByteString(array, offset, length);
+  }
+
+
+  /**
+   * Extracts the byte array from the given {@link ByteString} without copy.
+   * @param buf A buffer from which to extract the array.  This buffer must be
+   * actually an instance of a {@code LiteralByteString}.
+   *
+   * @param buf <code>ByteString</code> to access
+   * @return The underlying byte array of the ByteString
+   */
+  public static byte[] zeroCopyGetBytes(final ByteString buf) {
+    if (buf instanceof LiteralByteString) {
+      return ((LiteralByteString) buf).bytes;
+    }
+    throw new UnsupportedOperationException("Need a LiteralByteString, got a "
+                                            + buf.getClass().getName());
+  }
+}
+
+// End HBaseZeroCopyByteString.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/com/google/protobuf/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/com/google/protobuf/package-info.java b/avatica/core/src/main/java/com/google/protobuf/package-info.java
new file mode 100644
index 0000000..92f110e
--- /dev/null
+++ b/avatica/core/src/main/java/com/google/protobuf/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Avatica-custom classes to access protected classes in Google Protobuf.
+ */
+@PackageMarker
+package com.google.protobuf;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
new file mode 100644
index 0000000..df03b03
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaClientRuntimeException.java
@@ -0,0 +1,94 @@
+/*
+ * 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.remote.AvaticaRuntimeException;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The client-side representation of {@link AvaticaRuntimeException}. This exception is not intended
+ * for consumption by clients, {@link AvaticaSqlException} serves that purpose. This exception only
+ * exists to pass the original error attributes to a higher level of execution without modifying
+ * existing exception-handling logic.
+ */
+public class AvaticaClientRuntimeException extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+  private final int errorCode;
+  private final String sqlState;
+  private final AvaticaSeverity severity;
+  private final List<String> serverExceptions;
+  private final RpcMetadataResponse metadata;
+
+  public AvaticaClientRuntimeException(String errorMessage, int errorCode, String sqlState,
+      AvaticaSeverity severity, List<String> serverExceptions, RpcMetadataResponse metadata) {
+    super(errorMessage);
+    this.errorCode = errorCode;
+    this.sqlState = sqlState;
+    this.severity = severity;
+    this.serverExceptions = serverExceptions;
+    this.metadata = metadata;
+  }
+
+  public AvaticaClientRuntimeException(String message, Throwable cause) {
+    super(message, cause);
+    errorCode = ErrorResponse.UNKNOWN_ERROR_CODE;
+    sqlState = ErrorResponse.UNKNOWN_SQL_STATE;
+    severity = AvaticaSeverity.UNKNOWN;
+    serverExceptions = Collections.singletonList("");
+    metadata = null;
+  }
+
+  public int getErrorCode() {
+    return errorCode;
+  }
+
+  public String getSqlState() {
+    return sqlState;
+  }
+
+  public AvaticaSeverity getSeverity() {
+    return severity;
+  }
+
+  public List<String> getServerExceptions() {
+    return serverExceptions;
+  }
+
+  public RpcMetadataResponse getRpcMetadata() {
+    return metadata;
+  }
+
+  @Override public String toString() {
+    StringBuilder sb = new StringBuilder(64);
+    sb.append(getClass().getSimpleName()).append(": ")
+    .append(getMessage()).append(". Error ").append(getErrorCode())
+    .append(" (").append(sqlState).append(") ").append(getSeverity()).append("\n\n");
+    for (String serverException : getServerExceptions()) {
+      sb.append(serverException).append("\n");
+    }
+    return sb.toString();
+  }
+
+}
+
+// End AvaticaClientRuntimeException.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
new file mode 100644
index 0000000..2d89f45
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
@@ -0,0 +1,696 @@
+/*
+ * 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.Meta.MetaResultSet;
+import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.OpenConnectionRequest;
+import org.apache.calcite.avatica.remote.TypedValue;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of JDBC connection
+ * for the Avatica framework.
+ *
+ * <p>Abstract to allow newer versions of JDBC to add methods.
+ */
+public abstract class AvaticaConnection implements Connection {
+
+  /** The name of the sole column returned by DML statements, containing
+   * the number of rows modified. */
+  public static final String ROWCOUNT_COLUMN_NAME = "ROWCOUNT";
+
+  public static final String NUM_EXECUTE_RETRIES_KEY = "avatica.statement.retries";
+  public static final String NUM_EXECUTE_RETRIES_DEFAULT = "5";
+
+  /** The name of the sole column returned by an EXPLAIN statement.
+   *
+   * <p>Actually Avatica does not care what this column is called, but here is
+   * a useful place to define a suggested value. */
+  public static final String PLAN_COLUMN_NAME = "PLAN";
+
+  protected int statementCount;
+  private boolean closed;
+  private int holdability;
+  private int networkTimeout;
+
+  public final String id;
+  public final Meta.ConnectionHandle handle;
+  protected final UnregisteredDriver driver;
+  protected final AvaticaFactory factory;
+  final String url;
+  protected final Properties info;
+  protected final Meta meta;
+  protected final AvaticaDatabaseMetaData metaData;
+  public final Helper helper = Helper.INSTANCE;
+  public final Map<InternalProperty, Object> properties = new HashMap<>();
+  public final Map<Integer, AvaticaStatement> statementMap =
+      new ConcurrentHashMap<>();
+  protected final long maxRetriesPerExecute;
+
+  /**
+   * Creates an AvaticaConnection.
+   *
+   * <p>Not public; method is called only from the driver or a derived
+   * class.</p>
+   *
+   * @param driver Driver
+   * @param factory Factory for JDBC objects
+   * @param url Server URL
+   * @param info Other connection properties
+   */
+  protected AvaticaConnection(UnregisteredDriver driver,
+      AvaticaFactory factory,
+      String url,
+      Properties info) {
+    this.id = UUID.randomUUID().toString();
+    this.handle = new Meta.ConnectionHandle(this.id);
+    this.driver = driver;
+    this.factory = factory;
+    this.url = url;
+    this.info = info;
+    this.meta = driver.createMeta(this);
+    this.metaData = factory.newDatabaseMetaData(this);
+    this.holdability = metaData.getResultSetHoldability();
+    this.maxRetriesPerExecute = getNumStatementRetries(info);
+  }
+
+  /** Computes the number of retries
+   * {@link AvaticaStatement#executeInternal(Meta.Signature, boolean)}
+   * should retry before failing. */
+  long getNumStatementRetries(Properties props) {
+    return Long.valueOf(Objects.requireNonNull(props)
+        .getProperty(NUM_EXECUTE_RETRIES_KEY, NUM_EXECUTE_RETRIES_DEFAULT));
+  }
+
+  /** Returns a view onto this connection's configuration properties. Code
+   * in Avatica and derived projects should use this view rather than calling
+   * {@link java.util.Properties#getProperty(String)}. Derived projects will
+   * almost certainly subclass {@link ConnectionConfig} with their own
+   * properties. */
+  public ConnectionConfig config() {
+    return new ConnectionConfigImpl(info);
+  }
+
+  /**
+   * Opens the connection on the server.
+   */
+  public void openConnection() {
+    // Open the connection on the server
+    this.meta.openConnection(handle, OpenConnectionRequest.serializeProperties(info));
+  }
+
+  // Connection methods
+
+  public AvaticaStatement createStatement() throws SQLException {
+    //noinspection MagicConstant
+    return createStatement(ResultSet.TYPE_FORWARD_ONLY,
+        ResultSet.CONCUR_READ_ONLY,
+        holdability);
+  }
+
+  public PreparedStatement prepareStatement(String sql) throws SQLException {
+    //noinspection MagicConstant
+    return prepareStatement(
+        sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
+        holdability);
+  }
+
+  public CallableStatement prepareCall(String sql) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public String nativeSQL(String sql) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setAutoCommit(boolean autoCommit) throws SQLException {
+    meta.connectionSync(handle, new ConnectionPropertiesImpl().setAutoCommit(autoCommit));
+  }
+
+  public boolean getAutoCommit() throws SQLException {
+    return unbox(sync().isAutoCommit(), true);
+  }
+
+  public void commit() throws SQLException {
+    meta.commit(handle);
+  }
+
+  public void rollback() throws SQLException {
+    meta.rollback(handle);
+  }
+
+  public void close() throws SQLException {
+    if (!closed) {
+      closed = true;
+
+      // Per specification, if onConnectionClose throws, this method will throw
+      // a SQLException, but statement will still be closed.
+      try {
+        meta.closeConnection(handle);
+        driver.handler.onConnectionClose(this);
+      } catch (RuntimeException e) {
+        throw helper.createException("While closing connection", e);
+      }
+    }
+  }
+
+  public boolean isClosed() throws SQLException {
+    return closed;
+  }
+
+  public DatabaseMetaData getMetaData() throws SQLException {
+    return metaData;
+  }
+
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    meta.connectionSync(handle, new ConnectionPropertiesImpl().setReadOnly(readOnly));
+  }
+
+  public boolean isReadOnly() throws SQLException {
+    return unbox(sync().isReadOnly(), true);
+  }
+
+  public void setCatalog(String catalog) throws SQLException {
+    meta.connectionSync(handle, new ConnectionPropertiesImpl().setCatalog(catalog));
+  }
+
+  public String getCatalog() {
+    return sync().getCatalog();
+  }
+
+  public void setTransactionIsolation(int level) throws SQLException {
+    meta.connectionSync(handle, new ConnectionPropertiesImpl().setTransactionIsolation(level));
+  }
+
+  public int getTransactionIsolation() throws SQLException {
+    //noinspection MagicConstant
+    return unbox(sync().getTransactionIsolation(), TRANSACTION_NONE);
+  }
+
+  public SQLWarning getWarnings() throws SQLException {
+    return null;
+  }
+
+  public void clearWarnings() throws SQLException {
+    // no-op since connection pooling often calls this.
+  }
+
+  public Statement createStatement(
+      int resultSetType, int resultSetConcurrency) throws SQLException {
+    //noinspection MagicConstant
+    return createStatement(resultSetType, resultSetConcurrency, holdability);
+  }
+
+  public PreparedStatement prepareStatement(
+      String sql,
+      int resultSetType,
+      int resultSetConcurrency) throws SQLException {
+    //noinspection MagicConstant
+    return prepareStatement(
+        sql, resultSetType, resultSetConcurrency, holdability);
+  }
+
+  public CallableStatement prepareCall(
+      String sql,
+      int resultSetType,
+      int resultSetConcurrency) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Map<String, Class<?>> getTypeMap() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setHoldability(int holdability) throws SQLException {
+    if (!(holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT
+        || holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
+      throw new SQLException("invalid value");
+    }
+    this.holdability = holdability;
+  }
+
+  public int getHoldability() throws SQLException {
+    return holdability;
+  }
+
+  public Savepoint setSavepoint() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Savepoint setSavepoint(String name) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void rollback(Savepoint savepoint) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public AvaticaStatement createStatement(
+      int resultSetType,
+      int resultSetConcurrency,
+      int resultSetHoldability) throws SQLException {
+    return factory.newStatement(this, null, resultSetType, resultSetConcurrency,
+        resultSetHoldability);
+  }
+
+  public PreparedStatement prepareStatement(
+      String sql,
+      int resultSetType,
+      int resultSetConcurrency,
+      int resultSetHoldability) throws SQLException {
+    try {
+      final Meta.StatementHandle h = meta.prepare(handle, sql, -1);
+      return factory.newPreparedStatement(this, h, h.signature, resultSetType,
+          resultSetConcurrency, resultSetHoldability);
+    } catch (RuntimeException e) {
+      throw helper.createException("while preparing SQL: " + sql, e);
+    }
+  }
+
+  public CallableStatement prepareCall(
+      String sql,
+      int resultSetType,
+      int resultSetConcurrency,
+      int resultSetHoldability) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public PreparedStatement prepareStatement(
+      String sql, int autoGeneratedKeys) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public PreparedStatement prepareStatement(
+      String sql, int[] columnIndexes) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public PreparedStatement prepareStatement(
+      String sql, String[] columnNames) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Clob createClob() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Blob createBlob() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public NClob createNClob() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public SQLXML createSQLXML() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public boolean isValid(int timeout) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setClientInfo(String name, String value)
+      throws SQLClientInfoException {
+    throw helper.clientInfo();
+  }
+
+  public void setClientInfo(Properties properties)
+      throws SQLClientInfoException {
+    throw helper.clientInfo();
+  }
+
+  public String getClientInfo(String name) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Properties getClientInfo() throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Array createArrayOf(String typeName, Object[] elements)
+      throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public Struct createStruct(String typeName, Object[] attributes)
+      throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setSchema(String schema) throws SQLException {
+    meta.connectionSync(handle, new ConnectionPropertiesImpl().setSchema(schema));
+  }
+
+  public String getSchema() {
+    return sync().getSchema();
+  }
+
+  public void abort(Executor executor) throws SQLException {
+    throw helper.unsupported();
+  }
+
+  public void setNetworkTimeout(
+      Executor executor, int milliseconds) throws SQLException {
+    this.networkTimeout = milliseconds;
+  }
+
+  public int getNetworkTimeout() throws SQLException {
+    return networkTimeout;
+  }
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (iface.isInstance(this)) {
+      return iface.cast(this);
+    }
+    throw helper.createException(
+        "does not implement '" + iface + "'");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return iface.isInstance(this);
+  }
+
+  /** Returns the time zone of this connection. Determines the offset applied
+   * when converting datetime values from the database into
+   * {@link java.sql.Timestamp} values. */
+  public TimeZone getTimeZone() {
+    final String timeZoneName = config().timeZone();
+    return timeZoneName == null
+        ? TimeZone.getDefault()
+        : TimeZone.getTimeZone(timeZoneName);
+  }
+
+  /**
+   * Executes a prepared query, closing any previously open result set.
+   *
+   * @param statement     Statement
+   * @param signature     Prepared query
+   * @param firstFrame    First frame of rows, or null if we need to execute
+   * @param state         The state used to create the given result
+   * @param isUpdate      Was the caller context via {@link PreparedStatement#executeUpdate()}.
+   * @return Result set
+   * @throws java.sql.SQLException if a database error occurs
+   */
+  protected ResultSet executeQueryInternal(AvaticaStatement statement,
+      Meta.Signature signature, Meta.Frame firstFrame, QueryState state, boolean isUpdate)
+      throws SQLException {
+    // Close the previous open result set, if there is one.
+    Meta.Frame frame = firstFrame;
+    Meta.Signature signature2 = signature;
+
+    synchronized (statement) {
+      if (statement.openResultSet != null) {
+        final AvaticaResultSet rs = statement.openResultSet;
+        statement.openResultSet = null;
+        try {
+          rs.close();
+        } catch (Exception e) {
+          throw helper.createException(
+              "Error while closing previous result set", e);
+        }
+      }
+
+      try {
+        if (statement.isWrapperFor(AvaticaPreparedStatement.class)) {
+          final AvaticaPreparedStatement pstmt = (AvaticaPreparedStatement) statement;
+          Meta.StatementHandle handle = pstmt.handle;
+          if (isUpdate) {
+            // Make a copy of the StatementHandle, nulling out the Signature.
+            // CALCITE-1086 we don't need to send the Signature to the server
+            // when we're only performing an update. Saves on serialization.
+            handle = new Meta.StatementHandle(handle.connectionId, handle.id, null);
+          }
+          final Meta.ExecuteResult executeResult =
+              meta.execute(handle, pstmt.getParameterValues(),
+                  statement.getFetchSize());
+          final MetaResultSet metaResultSet = executeResult.resultSets.get(0);
+          frame = metaResultSet.firstFrame;
+          statement.updateCount = metaResultSet.updateCount;
+          signature2 = executeResult.resultSets.get(0).signature;
+        }
+      } catch (Exception e) {
+        e.printStackTrace();
+        throw helper.createException(e.getMessage(), e);
+      }
+
+      final TimeZone timeZone = getTimeZone();
+      if (frame == null && signature2 == null && statement.updateCount != -1) {
+        statement.openResultSet = null;
+      } else {
+        // Duplicative SQL, for support non-prepared statements
+        statement.openResultSet =
+            factory.newResultSet(statement, state, signature2, timeZone, frame);
+      }
+    }
+    // Release the monitor before executing, to give another thread the
+    // opportunity to call cancel.
+    try {
+      if (statement.openResultSet != null) {
+        statement.openResultSet.execute();
+        isUpdateCapable(statement);
+      }
+    } catch (Exception e) {
+      throw helper.createException(
+          "exception while executing query: " + e.getMessage(), e);
+    }
+    return statement.openResultSet;
+  }
+
+  /** Returns whether a a statement is capable of updates and if so,
+   * and the statement's {@code updateCount} is still -1, proceeds to
+   * get updateCount value from statement's resultSet.
+   *
+   * <p>Handles "ROWCOUNT" object as Number or List
+   *
+   * @param statement Statement
+   * @throws SQLException on error
+   */
+  private void isUpdateCapable(final AvaticaStatement statement)
+      throws SQLException {
+    Meta.Signature signature = statement.getSignature();
+    if (signature == null || signature.statementType == null) {
+      return;
+    }
+    if (signature.statementType.canUpdate() && statement.updateCount == -1) {
+      statement.openResultSet.next();
+      Object obj = statement.openResultSet.getObject(ROWCOUNT_COLUMN_NAME);
+      if (obj instanceof Number) {
+        statement.updateCount = ((Number) obj).intValue();
+      } else if (obj instanceof List) {
+        @SuppressWarnings("unchecked")
+        final List<Number> numbers = (List<Number>) obj;
+        statement.updateCount = numbers.get(0).intValue();
+      } else {
+        throw helper.createException("Not a valid return result.");
+      }
+      statement.openResultSet = null;
+    }
+  }
+
+  protected Meta.ExecuteResult prepareAndExecuteInternal(
+      final AvaticaStatement statement, final String sql, long maxRowCount)
+      throws SQLException, NoSuchStatementException {
+    final Meta.PrepareCallback callback =
+        new Meta.PrepareCallback() {
+          public Object getMonitor() {
+            return statement;
+          }
+
+          public void clear() throws SQLException {
+            if (statement.openResultSet != null) {
+              final AvaticaResultSet rs = statement.openResultSet;
+              statement.openResultSet = null;
+              try {
+                rs.close();
+              } catch (Exception e) {
+                throw helper.createException(
+                    "Error while closing previous result set", e);
+              }
+            }
+          }
+
+          public void assign(Meta.Signature signature, Meta.Frame firstFrame,
+              long updateCount) throws SQLException {
+            statement.setSignature(signature);
+
+            if (updateCount != -1) {
+              statement.updateCount = updateCount;
+            } else {
+              final TimeZone timeZone = getTimeZone();
+              statement.openResultSet = factory.newResultSet(statement, new QueryState(sql),
+                  signature, timeZone, firstFrame);
+            }
+          }
+
+          public void execute() throws SQLException {
+            if (statement.openResultSet != null) {
+              statement.openResultSet.execute();
+              isUpdateCapable(statement);
+            }
+          }
+        };
+    return meta.prepareAndExecute(statement.handle, sql, maxRowCount, callback);
+  }
+
+  protected ResultSet createResultSet(Meta.MetaResultSet metaResultSet, QueryState state)
+      throws SQLException {
+    final Meta.StatementHandle h = new Meta.StatementHandle(
+        metaResultSet.connectionId, metaResultSet.statementId, null);
+    final AvaticaStatement statement = lookupStatement(h);
+    // These are all the metadata operations, no updates
+    ResultSet resultSet = executeQueryInternal(statement, metaResultSet.signature.sanitize(),
+        metaResultSet.firstFrame, state, false);
+    if (metaResultSet.ownStatement) {
+      resultSet.getStatement().closeOnCompletion();
+    }
+    return resultSet;
+  }
+
+  /** Creates a statement wrapper around an existing handle. */
+  protected AvaticaStatement lookupStatement(Meta.StatementHandle h)
+      throws SQLException {
+    final AvaticaStatement statement = statementMap.get(h.id);
+    if (statement != null) {
+      return statement;
+    }
+    //noinspection MagicConstant
+    return factory.newStatement(this, Objects.requireNonNull(h),
+        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, holdability);
+  }
+
+  // do not make public
+  protected static Trojan createTrojan() {
+    return new Trojan();
+  }
+
+  /** Converts a {@link Boolean} to a {@code boolean}, with a default value. */
+  private boolean unbox(Boolean b, boolean defaultValue) {
+    return b == null ? defaultValue : b;
+  }
+
+  /** Converts an {@link Integer} to an {@code int}, with a default value. */
+  private int unbox(Integer i, int defaultValue) {
+    return i == null ? defaultValue : i;
+  }
+
+  private Meta.ConnectionProperties sync() {
+    return meta.connectionSync(handle, new ConnectionPropertiesImpl());
+  }
+
+  /** A way to call package-protected methods. But only a sub-class of
+   * connection can create one. */
+  public static class Trojan {
+    // must be private
+    private Trojan() {
+    }
+
+    /** A means for anyone who has a trojan to call the protected method
+     * {@link org.apache.calcite.avatica.AvaticaResultSet#execute()}.
+     * @throws SQLException if execute fails for some reason. */
+    public ResultSet execute(AvaticaResultSet resultSet) throws SQLException {
+      return resultSet.execute();
+    }
+
+    /** A means for anyone who has a trojan to call the protected method
+     * {@link org.apache.calcite.avatica.AvaticaStatement#getParameterValues()}.
+     */
+    public List<TypedValue> getParameterValues(AvaticaStatement statement) {
+      return statement.getParameterValues();
+    }
+
+    /** A means for anyone who has a trojan to get the protected field
+     * {@link org.apache.calcite.avatica.AvaticaConnection#meta}. */
+    public Meta getMeta(AvaticaConnection connection) {
+      return connection.meta;
+    }
+  }
+
+  /**
+   * A Callable-like interface but without a "throws Exception".
+   *
+   * @param <T> The return type from {@code call}.
+   */
+  public interface CallableWithoutException<T> {
+    T call();
+  }
+
+  /**
+   * Invokes the given "callable", retrying the call when the server responds with an error
+   * denoting that the connection is missing on the server.
+   *
+   * @param callable The function to invoke.
+   * @return The value from the result of the callable.
+   */
+  public <T> T invokeWithRetries(CallableWithoutException<T> callable) {
+    RuntimeException lastException = null;
+    for (int i = 0; i < maxRetriesPerExecute; i++) {
+      try {
+        return callable.call();
+      } catch (AvaticaClientRuntimeException e) {
+        lastException = e;
+        if (ErrorResponse.MISSING_CONNECTION_ERROR_CODE == e.getErrorCode()) {
+          this.openConnection();
+          continue;
+        }
+        throw e;
+      }
+    }
+    if (null != lastException) {
+      throw lastException;
+    } else {
+      // Shouldn't ever happen.
+      throw new IllegalStateException();
+    }
+  }
+}
+
+// End AvaticaConnection.java


[15/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
deleted file mode 100644
index b57f36c..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
+++ /dev/null
@@ -1,1416 +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.AvaticaConnection.CallableWithoutException;
-import org.apache.calcite.avatica.remote.MetaDataOperation;
-import org.apache.calcite.avatica.util.Casing;
-import org.apache.calcite.avatica.util.Quoting;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.RowIdLifetime;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.calcite.avatica.InternalProperty.CASE_SENSITIVE;
-import static org.apache.calcite.avatica.InternalProperty.NULL_SORTING;
-import static org.apache.calcite.avatica.InternalProperty.NullSorting;
-import static org.apache.calcite.avatica.InternalProperty.QUOTED_CASING;
-import static org.apache.calcite.avatica.InternalProperty.QUOTING;
-import static org.apache.calcite.avatica.InternalProperty.UNQUOTED_CASING;
-
-/**
- * Implementation of {@link java.sql.DatabaseMetaData}
- * for the Avatica engine.
- *
- * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
- * it is instantiated using {@link AvaticaFactory#newDatabaseMetaData}.</p>
- */
-public class AvaticaDatabaseMetaData implements DatabaseMetaData {
-  private final AvaticaConnection connection;
-
-  protected  AvaticaDatabaseMetaData(AvaticaConnection connection) {
-    this.connection = connection;
-  }
-
-  // Helper methods
-
-  private NullSorting nullSorting() {
-    return NULL_SORTING.getEnum(getProperties(), NullSorting.class);
-  }
-
-  private Quoting quoting() {
-    return QUOTING.getEnum(getProperties(), Quoting.class);
-  }
-
-  private Casing unquotedCasing() {
-    return UNQUOTED_CASING.getEnum(getProperties(), Casing.class);
-  }
-
-  private Casing quotedCasing() {
-    return QUOTED_CASING.getEnum(getProperties(), Casing.class);
-  }
-
-  private boolean caseSensitive() {
-    return CASE_SENSITIVE.getBoolean(getProperties());
-  }
-
-  // JDBC methods
-
-  public boolean allProceduresAreCallable() throws SQLException {
-    return true;
-  }
-
-  public boolean allTablesAreSelectable() throws SQLException {
-    return true;
-  }
-
-  public String getURL() throws SQLException {
-    return connection.url;
-  }
-
-  public String getUserName() throws SQLException {
-    return connection.info.getProperty("user");
-  }
-
-  public boolean isReadOnly() throws SQLException {
-    return true;
-  }
-
-  public boolean nullsAreSortedHigh() throws SQLException {
-    return nullSorting() == NullSorting.HIGH;
-  }
-
-  public boolean nullsAreSortedLow() throws SQLException {
-    return nullSorting() == NullSorting.LOW;
-  }
-
-  public boolean nullsAreSortedAtStart() throws SQLException {
-    return nullSorting() == NullSorting.START;
-  }
-
-  public boolean nullsAreSortedAtEnd() throws SQLException {
-    return nullSorting() == NullSorting.END;
-  }
-
-  public String getDatabaseProductName() throws SQLException {
-    return connection.driver.version.productName;
-  }
-
-  public String getDatabaseProductVersion() throws SQLException {
-    return connection.driver.version.productVersion;
-  }
-
-  public String getDriverName() throws SQLException {
-    return connection.driver.version.name;
-  }
-
-  public String getDriverVersion() throws SQLException {
-    return connection.driver.version.versionString;
-  }
-
-  public int getDriverMajorVersion() {
-    return connection.driver.getMajorVersion();
-  }
-
-  public int getDriverMinorVersion() {
-    return connection.driver.getMinorVersion();
-  }
-
-  public boolean usesLocalFiles() throws SQLException {
-    return false;
-  }
-
-  public boolean usesLocalFilePerTable() throws SQLException {
-    return false;
-  }
-
-  public boolean storesMixedCaseIdentifiers() throws SQLException {
-    return !caseSensitive() && unquotedCasing() == Casing.UNCHANGED;
-  }
-
-  public boolean supportsMixedCaseIdentifiers() throws SQLException {
-    return caseSensitive() && unquotedCasing() == Casing.UNCHANGED;
-  }
-
-  public boolean storesUpperCaseIdentifiers() throws SQLException {
-    return unquotedCasing() == Casing.TO_UPPER;
-  }
-
-  public boolean storesLowerCaseIdentifiers() throws SQLException {
-    return unquotedCasing() == Casing.TO_LOWER;
-  }
-
-  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
-    return !caseSensitive() && quotedCasing() == Casing.UNCHANGED;
-  }
-
-  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
-    return caseSensitive() && quotedCasing() == Casing.UNCHANGED;
-  }
-
-  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
-    return quotedCasing() == Casing.TO_UPPER;
-  }
-
-  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
-    return quotedCasing() == Casing.TO_LOWER;
-  }
-
-  public String getIdentifierQuoteString() throws SQLException {
-    return quoting().string;
-  }
-
-  private Map<InternalProperty, Object> getProperties() {
-    return connection.properties;
-  }
-
-  public String getSQLKeywords() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<String>() {
-          public String call() {
-            return Meta.DatabaseProperty.GET_S_Q_L_KEYWORDS
-                .getProp(connection.meta, connection.handle, String.class);
-          }
-        });
-  }
-
-  public String getNumericFunctions() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<String>() {
-          public String call() {
-            return Meta.DatabaseProperty.GET_NUMERIC_FUNCTIONS
-                .getProp(connection.meta, connection.handle, String.class);
-          }
-        });
-  }
-
-  public String getStringFunctions() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<String>() {
-          public String call() {
-            return Meta.DatabaseProperty.GET_STRING_FUNCTIONS
-                .getProp(connection.meta, connection.handle, String.class);
-          }
-        });
-  }
-
-  public String getSystemFunctions() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<String>() {
-          public String call() {
-            return Meta.DatabaseProperty.GET_SYSTEM_FUNCTIONS
-                .getProp(connection.meta, connection.handle, String.class);
-          }
-        });
-  }
-
-  public String getTimeDateFunctions() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<String>() {
-          public String call() {
-            return Meta.DatabaseProperty.GET_TIME_DATE_FUNCTIONS
-                .getProp(connection.meta, connection.handle, String.class);
-          }
-        });
-  }
-
-  public String getSearchStringEscape() throws SQLException {
-    return "\\";
-  }
-
-  public String getExtraNameCharacters() throws SQLException {
-    return "";
-  }
-
-  public boolean supportsAlterTableWithAddColumn() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsAlterTableWithDropColumn() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsColumnAliasing() throws SQLException {
-    return true;
-  }
-
-  public boolean nullPlusNonNullIsNull() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsConvert() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsConvert(int fromType, int toType) throws SQLException {
-    return false; // TODO: more detail
-  }
-
-  public boolean supportsTableCorrelationNames() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsExpressionsInOrderBy() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsOrderByUnrelated() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsGroupBy() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsGroupByUnrelated() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsGroupByBeyondSelect() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsLikeEscapeClause() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsMultipleResultSets() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsMultipleTransactions() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsNonNullableColumns() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsMinimumSQLGrammar() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsCoreSQLGrammar() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsExtendedSQLGrammar() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsANSI92IntermediateSQL() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsANSI92FullSQL() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsOuterJoins() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsFullOuterJoins() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsLimitedOuterJoins() throws SQLException {
-    return true;
-  }
-
-  public String getSchemaTerm() throws SQLException {
-    return "schema";
-  }
-
-  public String getProcedureTerm() throws SQLException {
-    return "procedure";
-  }
-
-  public String getCatalogTerm() throws SQLException {
-    return "catalog";
-  }
-
-  public boolean isCatalogAtStart() throws SQLException {
-    return true;
-  }
-
-  public String getCatalogSeparator() throws SQLException {
-    return ".";
-  }
-
-  public boolean supportsSchemasInDataManipulation() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSchemasInProcedureCalls() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSchemasInTableDefinitions() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
-    return true; // except that we don't support index definitions
-  }
-
-  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
-    return true; // except that we don't support privilege definitions
-  }
-
-  public boolean supportsCatalogsInDataManipulation() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
-    return true; // except that we don't support index definitions
-  }
-
-  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
-    return true; // except that we don't support privilege definitions
-  }
-
-  public boolean supportsPositionedDelete() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsPositionedUpdate() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsSelectForUpdate() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsStoredProcedures() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsSubqueriesInComparisons() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSubqueriesInExists() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSubqueriesInIns() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsCorrelatedSubqueries() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsUnion() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsUnionAll() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  public int getMaxBinaryLiteralLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxCharLiteralLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnsInGroupBy() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnsInIndex() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnsInOrderBy() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnsInSelect() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxColumnsInTable() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxConnections() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxCursorNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxIndexLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxSchemaNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxProcedureNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxCatalogNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxRowSize() throws SQLException {
-    return 0;
-  }
-
-  public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
-    return false;
-  }
-
-  public int getMaxStatementLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxStatements() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxTableNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxTablesInSelect() throws SQLException {
-    return 0;
-  }
-
-  public int getMaxUserNameLength() throws SQLException {
-    return 0;
-  }
-
-  public int getDefaultTransactionIsolation() throws SQLException {
-    return connection.invokeWithRetries(
-        new CallableWithoutException<Integer>() {
-          public Integer call() {
-            return Meta.DatabaseProperty.GET_DEFAULT_TRANSACTION_ISOLATION
-                .getProp(connection.meta, connection.handle, Integer.class);
-          }
-        });
-  }
-
-  public boolean supportsTransactions() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsTransactionIsolationLevel(int level)
-      throws SQLException {
-    return level == Connection.TRANSACTION_NONE;
-  }
-
-  public boolean supportsDataDefinitionAndDataManipulationTransactions()
-      throws SQLException {
-    return false;
-  }
-
-  public boolean supportsDataManipulationTransactionsOnly()
-      throws SQLException {
-    return true;
-  }
-
-  public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
-    return true;
-  }
-
-  public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
-    return false;
-  }
-
-  public ResultSet getProcedures(
-      final String catalog,
-      final String schemaPattern,
-      final String procedureNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getProcedures(connection.handle, catalog, pat(schemaPattern),
-                        pat(procedureNamePattern)),
-                    new QueryState(MetaDataOperation.GET_PROCEDURES, catalog, schemaPattern,
-                        procedureNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getProcedureColumns(
-      final String catalog,
-      final String schemaPattern,
-      final String procedureNamePattern,
-      final String columnNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getProcedureColumns(connection.handle, catalog,
-                        pat(schemaPattern), pat(procedureNamePattern), pat(columnNamePattern)),
-                    new QueryState(MetaDataOperation.GET_PROCEDURE_COLUMNS, catalog, schemaPattern,
-                        procedureNamePattern, columnNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getTables(
-      final String catalog,
-      final String schemaPattern,
-      final String tableNamePattern,
-      final String[] types) throws SQLException {
-    final List<String> typeList = types == null ? null : Arrays.asList(types);
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getTables(connection.handle, catalog, pat(schemaPattern),
-                        pat(tableNamePattern), typeList),
-                    new QueryState(MetaDataOperation.GET_TABLES, catalog, schemaPattern,
-                        tableNamePattern, types));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  private static Meta.Pat pat(String schemaPattern) {
-    return Meta.Pat.of(schemaPattern);
-  }
-
-  public ResultSet getSchemas(
-      final String catalog, final String schemaPattern) throws SQLException {
-    // TODO: add a 'catch ... throw new SQLException' logic to this and other
-    // getXxx methods. Right now any error will throw a RuntimeException
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getSchemas(connection.handle, catalog, pat(schemaPattern)),
-                    new QueryState(MetaDataOperation.GET_SCHEMAS_WITH_ARGS, catalog,
-                        schemaPattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getSchemas() throws SQLException {
-    return getSchemas(null, null);
-  }
-
-  public ResultSet getCatalogs() throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(connection.meta.getCatalogs(connection.handle),
-                    new QueryState(MetaDataOperation.GET_CATALOGS));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getTableTypes() throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(connection.meta.getTableTypes(connection.handle),
-                    new QueryState(MetaDataOperation.GET_TABLE_TYPES));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getColumns(
-      final String catalog,
-      final String schemaPattern,
-      final String tableNamePattern,
-      final String columnNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getColumns(connection.handle, catalog, pat(schemaPattern),
-                        pat(tableNamePattern), pat(columnNamePattern)),
-                    new QueryState(MetaDataOperation.GET_COLUMNS, catalog, schemaPattern,
-                        tableNamePattern, columnNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getColumnPrivileges(
-      final String catalog,
-      final String schema,
-      final String table,
-      final String columnNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getColumnPrivileges(connection.handle, catalog, schema, table,
-                        pat(columnNamePattern)),
-                    new QueryState(MetaDataOperation.GET_COLUMN_PRIVILEGES, catalog, schema, table,
-                        columnNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getTablePrivileges(
-      final String catalog,
-      final String schemaPattern,
-      final String tableNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getTablePrivileges(connection.handle, catalog,
-                        pat(schemaPattern), pat(tableNamePattern)),
-                    new QueryState(MetaDataOperation.GET_TABLE_PRIVILEGES, catalog, schemaPattern,
-                        tableNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getBestRowIdentifier(
-      final String catalog,
-      final String schema,
-      final String table,
-      final int scope,
-      final boolean nullable) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getBestRowIdentifier(connection.handle, catalog, schema, table,
-                        scope, nullable),
-                    new QueryState(MetaDataOperation.GET_BEST_ROW_IDENTIFIER, catalog, table, scope,
-                        nullable));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getVersionColumns(
-      final String catalog, final String schema, final String table) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getVersionColumns(connection.handle, catalog, schema, table),
-                    new QueryState(MetaDataOperation.GET_VERSION_COLUMNS, catalog, schema, table));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getPrimaryKeys(
-      final String catalog, final String schema, final String table) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getPrimaryKeys(connection.handle, catalog, schema, table),
-                    new QueryState(MetaDataOperation.GET_PRIMARY_KEYS, catalog, schema, table));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getImportedKeys(
-      final String catalog, final String schema, final String table) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getImportedKeys(connection.handle, catalog, schema, table),
-                    new QueryState(MetaDataOperation.GET_IMPORTED_KEYS, catalog, schema, table));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getExportedKeys(
-      final String catalog, final String schema, final String table) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getExportedKeys(connection.handle, catalog, schema, table),
-                    new QueryState(MetaDataOperation.GET_EXPORTED_KEYS, catalog, schema, table));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getCrossReference(
-      final String parentCatalog,
-      final String parentSchema,
-      final String parentTable,
-      final String foreignCatalog,
-      final String foreignSchema,
-      final String foreignTable) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getCrossReference(connection.handle, parentCatalog,
-                        parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable),
-                    new QueryState(MetaDataOperation.GET_CROSS_REFERENCE, parentCatalog,
-                        parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getTypeInfo() throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(connection.meta.getTypeInfo(connection.handle),
-                    new QueryState(MetaDataOperation.GET_TYPE_INFO));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getIndexInfo(
-      final String catalog,
-      final String schema,
-      final String table,
-      final boolean unique,
-      final boolean approximate) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getIndexInfo(connection.handle, catalog, schema, table, unique,
-                        approximate),
-                    new QueryState(MetaDataOperation.GET_INDEX_INFO, catalog, schema, table, unique,
-                        approximate));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public boolean supportsResultSetType(int type) throws SQLException {
-    return type == ResultSet.TYPE_FORWARD_ONLY;
-  }
-
-  public boolean supportsResultSetConcurrency(
-      int type, int concurrency) throws SQLException {
-    return type == ResultSet.TYPE_FORWARD_ONLY
-        && concurrency == ResultSet.CONCUR_READ_ONLY;
-  }
-
-  public boolean ownUpdatesAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean ownDeletesAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean ownInsertsAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean othersUpdatesAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean othersDeletesAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean othersInsertsAreVisible(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean updatesAreDetected(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean deletesAreDetected(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean insertsAreDetected(int type) throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public boolean supportsBatchUpdates() throws SQLException {
-    return false;
-  }
-
-  public ResultSet getUDTs(
-      final String catalog,
-      final String schemaPattern,
-      final String typeNamePattern,
-      final int[] types) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getUDTs(connection.handle, catalog, pat(schemaPattern),
-                        pat(typeNamePattern), types),
-                    new QueryState(MetaDataOperation.GET_UDTS, catalog, schemaPattern,
-                        typeNamePattern, types));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public Connection getConnection() throws SQLException {
-    return connection;
-  }
-
-  public boolean supportsSavepoints() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsNamedParameters() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsMultipleOpenResults() throws SQLException {
-    return false;
-  }
-
-  public boolean supportsGetGeneratedKeys() throws SQLException {
-    return false;
-  }
-
-  public ResultSet getSuperTypes(
-      final String catalog,
-      final String schemaPattern,
-      final String typeNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getSuperTypes(connection.handle, catalog, pat(schemaPattern),
-                        pat(typeNamePattern)),
-                    new QueryState(MetaDataOperation.GET_SUPER_TYPES, catalog, schemaPattern,
-                        typeNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getSuperTables(
-      final String catalog,
-      final String schemaPattern,
-      final String tableNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getSuperTables(connection.handle, catalog, pat(schemaPattern),
-                        pat(tableNamePattern)),
-                    new QueryState(MetaDataOperation.GET_SUPER_TABLES, catalog, schemaPattern,
-                        tableNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getAttributes(
-      final String catalog,
-      final String schemaPattern,
-      final String typeNamePattern,
-      final String attributeNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getAttributes(connection.handle, catalog, pat(schemaPattern),
-                        pat(typeNamePattern), pat(attributeNamePattern)),
-                    new QueryState(MetaDataOperation.GET_ATTRIBUTES, catalog, schemaPattern,
-                        typeNamePattern, attributeNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public boolean supportsResultSetHoldability(int holdability)
-      throws SQLException {
-    throw connection.helper.todo();
-  }
-
-  public int getResultSetHoldability() {
-    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-  }
-
-  public int getDatabaseMajorVersion() throws SQLException {
-    return connection.driver.version.databaseMajorVersion;
-  }
-
-  public int getDatabaseMinorVersion() throws SQLException {
-    return connection.driver.version.databaseMinorVersion;
-  }
-
-  public int getJDBCMajorVersion() throws SQLException {
-    return connection.factory.getJdbcMajorVersion();
-  }
-
-  public int getJDBCMinorVersion() throws SQLException {
-    return connection.factory.getJdbcMinorVersion();
-  }
-
-  public int getSQLStateType() throws SQLException {
-    return sqlStateSQL;
-  }
-
-  public boolean locatorsUpdateCopy() throws SQLException {
-    return true;
-  }
-
-  public boolean supportsStatementPooling() throws SQLException {
-    return false;
-  }
-
-  public RowIdLifetime getRowIdLifetime() throws SQLException {
-    return RowIdLifetime.ROWID_UNSUPPORTED;
-  }
-
-  public boolean supportsStoredFunctionsUsingCallSyntax()
-      throws SQLException {
-    return true;
-  }
-
-  public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
-    return false;
-  }
-
-  public ResultSet getClientInfoProperties() throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getClientInfoProperties(connection.handle),
-                    new QueryState(MetaDataOperation.GET_CLIENT_INFO_PROPERTIES));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getFunctions(
-      final String catalog,
-      final String schemaPattern,
-      final String functionNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getFunctions(connection.handle, catalog, pat(schemaPattern),
-                        pat(functionNamePattern)),
-                    new QueryState(MetaDataOperation.GET_FUNCTIONS, catalog, schemaPattern,
-                        functionNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getFunctionColumns(
-      final String catalog,
-      final String schemaPattern,
-      final String functionNamePattern,
-      final String columnNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getFunctionColumns(connection.handle, catalog,
-                        pat(schemaPattern), pat(functionNamePattern), pat(columnNamePattern)),
-                    new QueryState(MetaDataOperation.GET_FUNCTION_COLUMNS, catalog,
-                        schemaPattern, functionNamePattern, columnNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public ResultSet getPseudoColumns(
-      final String catalog,
-      final String schemaPattern,
-      final String tableNamePattern,
-      final String columnNamePattern) throws SQLException {
-    try {
-      return connection.invokeWithRetries(
-          new CallableWithoutException<ResultSet>() {
-            public ResultSet call() {
-              try {
-                return connection.createResultSet(
-                    connection.meta.getPseudoColumns(connection.handle, catalog, pat(schemaPattern),
-                        pat(tableNamePattern), pat(columnNamePattern)),
-                    new QueryState(MetaDataOperation.GET_PSEUDO_COLUMNS, catalog, schemaPattern,
-                        tableNamePattern, columnNamePattern));
-              } catch (SQLException e) {
-                throw new RuntimeException(e);
-              }
-            }
-          });
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      if (cause instanceof SQLException) {
-        throw (SQLException) cause;
-      }
-      throw e;
-    }
-  }
-
-  public boolean generatedKeyAlwaysReturned() throws SQLException {
-    return false;
-  }
-
-  // implement Wrapper
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    if (iface.isInstance(this)) {
-      return iface.cast(this);
-    }
-    throw connection.helper.createException(
-        "does not implement '" + iface + "'");
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    return iface.isInstance(this);
-  }
-}
-
-// End AvaticaDatabaseMetaData.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
deleted file mode 100644
index 1a2a97f..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaFactory.java
+++ /dev/null
@@ -1,83 +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.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.Properties;
-import java.util.TimeZone;
-
-/**
- * Factory for JDBC objects.
- *
- * <p>There is an implementation for each supported JDBC version.</p>
- */
-public interface AvaticaFactory {
-  int getJdbcMajorVersion();
-
-  int getJdbcMinorVersion();
-
-  AvaticaConnection newConnection(
-      UnregisteredDriver driver,
-      AvaticaFactory factory,
-      String url,
-      Properties info) throws SQLException;
-
-  AvaticaStatement newStatement(AvaticaConnection connection,
-      /*@Nullable*/ Meta.StatementHandle h, int resultSetType,
-      int resultSetConcurrency, int resultSetHoldability) throws SQLException;
-
-  AvaticaPreparedStatement newPreparedStatement(AvaticaConnection connection,
-      /*@Nullable*/ Meta.StatementHandle h, Meta.Signature signature,
-      int resultSetType, int resultSetConcurrency, int resultSetHoldability)
-      throws SQLException;
-
-  /**
-   * Creates a result set. You will then need to call
-   * {@link AvaticaResultSet#execute()} on it.
-   *
-   * @param statement Statement
-   * @param state The state used to create this result set
-   * @param signature Prepared statement
-   * @param timeZone Time zone
-   * @param firstFrame Frame containing the first (or perhaps only) rows in the
-   *                   result, or null if an execute/fetch is required
-   * @return Result set
-   */
-  AvaticaResultSet newResultSet(AvaticaStatement statement, QueryState state,
-      Meta.Signature signature, TimeZone timeZone, Meta.Frame firstFrame)
-      throws SQLException;
-
-  /**
-   * Creates meta data for the database.
-   *
-   * @return Database meta data
-   */
-  AvaticaDatabaseMetaData newDatabaseMetaData(AvaticaConnection connection);
-
-  /**
-   * Creates meta data for a result set.
-   *
-   * @param statement Statement
-   * @param signature Prepared statement
-   * @return Result set meta data
-   */
-  ResultSetMetaData newResultSetMetaData(AvaticaStatement statement,
-      Meta.Signature signature) throws SQLException;
-}
-
-// End AvaticaFactory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
deleted file mode 100644
index f410dc8..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
+++ /dev/null
@@ -1,256 +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.InputStream;
-import java.io.Reader;
-import java.sql.NClob;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.util.Properties;
-import java.util.TimeZone;
-
-/**
- * Implementation of {@link AvaticaFactory} for JDBC 4.1 (corresponds to JDK
- * 1.7).
- */
-@SuppressWarnings("UnusedDeclaration")
-class AvaticaJdbc41Factory implements AvaticaFactory {
-  private final int major;
-  private final int minor;
-
-  /** Creates a JDBC factory. */
-  public AvaticaJdbc41Factory() {
-    this(4, 1);
-  }
-
-  /** Creates a JDBC factory with given major/minor version number. */
-  protected AvaticaJdbc41Factory(int major, int minor) {
-    this.major = major;
-    this.minor = minor;
-  }
-
-  public int getJdbcMajorVersion() {
-    return major;
-  }
-
-  public int getJdbcMinorVersion() {
-    return minor;
-  }
-
-  public AvaticaConnection newConnection(
-      UnregisteredDriver driver,
-      AvaticaFactory factory,
-      String url,
-      Properties info) {
-    return new AvaticaJdbc41Connection(driver, factory, url, info);
-  }
-
-  public AvaticaDatabaseMetaData newDatabaseMetaData(
-      AvaticaConnection connection) {
-    return new AvaticaJdbc41DatabaseMetaData(connection);
-  }
-
-  public AvaticaStatement newStatement(AvaticaConnection connection,
-      Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
-      int resultSetHoldability) {
-    return new AvaticaJdbc41Statement(connection, h, resultSetType,
-        resultSetConcurrency, resultSetHoldability);
-  }
-
-  public AvaticaPreparedStatement newPreparedStatement(
-      AvaticaConnection connection, Meta.StatementHandle h,
-      Meta.Signature signature, int resultSetType, int resultSetConcurrency,
-      int resultSetHoldability)
-      throws SQLException {
-    return new AvaticaJdbc41PreparedStatement(connection, h, signature,
-        resultSetType, resultSetConcurrency, resultSetHoldability);
-  }
-
-  public AvaticaResultSet newResultSet(AvaticaStatement statement,
-      QueryState state, Meta.Signature signature, TimeZone timeZone, Meta.Frame firstFrame) {
-    final ResultSetMetaData metaData =
-        newResultSetMetaData(statement, signature);
-    return new AvaticaResultSet(statement, state, signature, metaData, timeZone,
-        firstFrame);
-  }
-
-  public AvaticaResultSetMetaData newResultSetMetaData(
-      AvaticaStatement statement, Meta.Signature signature) {
-    return new AvaticaResultSetMetaData(statement, null, signature);
-  }
-
-  /** Implementation of Connection for JDBC 4.1. */
-  private static class AvaticaJdbc41Connection extends AvaticaConnection {
-    AvaticaJdbc41Connection(UnregisteredDriver driver,
-        AvaticaFactory factory,
-        String url,
-        Properties info) {
-      super(driver, factory, url, info);
-    }
-  }
-
-  /** Implementation of Statement for JDBC 4.1. */
-  private static class AvaticaJdbc41Statement extends AvaticaStatement {
-    public AvaticaJdbc41Statement(AvaticaConnection connection,
-        Meta.StatementHandle h, int resultSetType, int resultSetConcurrency,
-        int resultSetHoldability) {
-      super(connection, h, resultSetType, resultSetConcurrency,
-          resultSetHoldability);
-    }
-  }
-
-  /** Implementation of PreparedStatement for JDBC 4.1. */
-  private static class AvaticaJdbc41PreparedStatement
-      extends AvaticaPreparedStatement {
-    AvaticaJdbc41PreparedStatement(AvaticaConnection connection,
-        Meta.StatementHandle h, Meta.Signature signature, int resultSetType,
-        int resultSetConcurrency, int resultSetHoldability)
-        throws SQLException {
-      super(connection, h, signature, resultSetType, resultSetConcurrency,
-          resultSetHoldability);
-    }
-
-    public void setRowId(
-        int parameterIndex,
-        RowId x) throws SQLException {
-      getSite(parameterIndex).setRowId(x);
-    }
-
-    public void setNString(
-        int parameterIndex, String value) throws SQLException {
-      getSite(parameterIndex).setNString(value);
-    }
-
-    public void setNCharacterStream(
-        int parameterIndex,
-        Reader value,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setNCharacterStream(value, length);
-    }
-
-    public void setNClob(
-        int parameterIndex,
-        NClob value) throws SQLException {
-      getSite(parameterIndex).setNClob(value);
-    }
-
-    public void setClob(
-        int parameterIndex,
-        Reader reader,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setClob(reader, length);
-    }
-
-    public void setBlob(
-        int parameterIndex,
-        InputStream inputStream,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setBlob(inputStream, length);
-    }
-
-    public void setNClob(
-        int parameterIndex,
-        Reader reader,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setNClob(reader, length);
-    }
-
-    public void setSQLXML(
-        int parameterIndex, SQLXML xmlObject) throws SQLException {
-      getSite(parameterIndex).setSQLXML(xmlObject);
-    }
-
-    public void setAsciiStream(
-        int parameterIndex,
-        InputStream x,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setAsciiStream(x, length);
-    }
-
-    public void setBinaryStream(
-        int parameterIndex,
-        InputStream x,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setBinaryStream(x, length);
-    }
-
-    public void setCharacterStream(
-        int parameterIndex,
-        Reader reader,
-        long length) throws SQLException {
-      getSite(parameterIndex)
-          .setCharacterStream(reader, length);
-    }
-
-    public void setAsciiStream(
-        int parameterIndex, InputStream x) throws SQLException {
-      getSite(parameterIndex).setAsciiStream(x);
-    }
-
-    public void setBinaryStream(
-        int parameterIndex, InputStream x) throws SQLException {
-      getSite(parameterIndex).setBinaryStream(x);
-    }
-
-    public void setCharacterStream(
-        int parameterIndex, Reader reader) throws SQLException {
-      getSite(parameterIndex)
-          .setCharacterStream(reader);
-    }
-
-    public void setNCharacterStream(
-        int parameterIndex, Reader value) throws SQLException {
-      getSite(parameterIndex)
-          .setNCharacterStream(value);
-    }
-
-    public void setClob(
-        int parameterIndex,
-        Reader reader) throws SQLException {
-      getSite(parameterIndex).setClob(reader);
-    }
-
-    public void setBlob(
-        int parameterIndex, InputStream inputStream) throws SQLException {
-      getSite(parameterIndex).setBlob(inputStream);
-    }
-
-    public void setNClob(
-        int parameterIndex, Reader reader) throws SQLException {
-      getSite(parameterIndex).setNClob(reader);
-    }
-  }
-
-  /** Implementation of DatabaseMetaData for JDBC 4.1. */
-  private static class AvaticaJdbc41DatabaseMetaData
-      extends AvaticaDatabaseMetaData {
-    AvaticaJdbc41DatabaseMetaData(AvaticaConnection connection) {
-      super(connection);
-    }
-  }
-}
-
-// End AvaticaJdbc41Factory.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
deleted file mode 100644
index 3c5a9ab..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
+++ /dev/null
@@ -1,135 +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 com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.Objects;
-
-/**
- * Metadata for a parameter.
- */
-public class AvaticaParameter {
-  public final boolean signed;
-  public final int precision;
-  public final int scale;
-  public final int parameterType;
-  public final String typeName;
-  public final String className;
-  public final String name;
-
-  @JsonCreator
-  public AvaticaParameter(
-      @JsonProperty("signed") boolean signed,
-      @JsonProperty("precision") int precision,
-      @JsonProperty("scale") int scale,
-      @JsonProperty("parameterType") int parameterType,
-      @JsonProperty("typeName") String typeName,
-      @JsonProperty("className") String className,
-      @JsonProperty("name") String name) {
-    this.signed = signed;
-    this.precision = precision;
-    this.scale = scale;
-    this.parameterType = parameterType;
-    this.typeName = typeName;
-    this.className = className;
-    this.name = name;
-  }
-
-  public Common.AvaticaParameter toProto() {
-    Common.AvaticaParameter.Builder builder = Common.AvaticaParameter.newBuilder();
-
-    builder.setSigned(signed);
-    builder.setPrecision(precision);
-    builder.setScale(scale);
-    builder.setParameterType(parameterType);
-    builder.setTypeName(typeName);
-    builder.setClassName(className);
-    builder.setName(name);
-
-    return builder.build();
-  }
-
-  public static AvaticaParameter fromProto(Common.AvaticaParameter proto) {
-    return new AvaticaParameter(proto.getSigned(), proto.getPrecision(),
-        proto.getScale(), proto.getParameterType(), proto.getTypeName(),
-        proto.getClassName(), proto.getName());
-  }
-
-  @Override public int hashCode() {
-    return Objects.hash(className, name, parameterType, precision, scale,
-        signed, typeName);
-  }
-
-  @Override public boolean equals(Object obj) {
-    if (obj == this) {
-      return true;
-    }
-    if (obj instanceof AvaticaParameter) {
-      AvaticaParameter other = (AvaticaParameter) obj;
-
-      if (null == className) {
-        if (null != other.className) {
-          return false;
-        }
-      } else if (!className.equals(other.className)) {
-        return false;
-      }
-
-      if (null == name) {
-        if (null != other.name) {
-          return false;
-        }
-      } else if (!name.equals(other.name)) {
-        return false;
-      }
-
-      if (parameterType != other.parameterType) {
-        return false;
-      }
-
-      if (precision != other.precision) {
-        return false;
-      }
-
-      if (scale != other.scale) {
-        return false;
-      }
-
-      if (signed != other.signed) {
-        return false;
-      }
-
-      if (null == typeName) {
-        if (null != other.typeName) {
-          return false;
-        }
-      } else if (!typeName.equals(other.typeName)) {
-        return false;
-      }
-
-      return true;
-    }
-
-    return false;
-  }
-}
-
-// End AvaticaParameter.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
deleted file mode 100644
index f3a950a..0000000
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
+++ /dev/null
@@ -1,343 +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.Meta.Signature;
-import org.apache.calcite.avatica.remote.TypedValue;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
-
-/**
- * Implementation of {@link java.sql.PreparedStatement}
- * for the Avatica engine.
- *
- * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
- * it is instantiated using {@link AvaticaFactory#newPreparedStatement}.</p>
- */
-public abstract class AvaticaPreparedStatement
-    extends AvaticaStatement
-    implements PreparedStatement, ParameterMetaData {
-  private final ResultSetMetaData resultSetMetaData;
-  private Calendar calendar;
-  protected final TypedValue[] slots;
-
-  /**
-   * Creates an AvaticaPreparedStatement.
-   *
-   * @param connection Connection
-   * @param h Statement handle
-   * @param signature Result of preparing statement
-   * @param resultSetType Result set type
-   * @param resultSetConcurrency Result set concurrency
-   * @param resultSetHoldability Result set holdability
-   * @throws SQLException If fails due to underlying implementation reasons.
-   */
-  protected AvaticaPreparedStatement(AvaticaConnection connection,
-      Meta.StatementHandle h,
-      Meta.Signature signature,
-      int resultSetType,
-      int resultSetConcurrency,
-      int resultSetHoldability) throws SQLException {
-    super(connection, h, resultSetType, resultSetConcurrency,
-        resultSetHoldability, signature);
-    this.slots = new TypedValue[signature.parameters.size()];
-    this.resultSetMetaData =
-        connection.factory.newResultSetMetaData(this, signature);
-  }
-
-  @Override protected List<TypedValue> getParameterValues() {
-    return Arrays.asList(slots);
-  }
-
-  /** Returns a calendar in the connection's time zone, creating one the first
-   * time this method is called.
-   *
-   * <p>Uses the calendar to offset date-time values when calling methods such
-   * as {@link #setDate(int, Date)}.
-   *
-   * <p>A note on thread-safety. This method does not strictly need to be
-   * {@code synchronized}, because JDBC does not promise thread safety if
-   * different threads are accessing the same statement, or even different
-   * objects within a particular connection.
-   *
-   * <p>The calendar returned is to be used only within this statement, and
-   * JDBC only allows access to a statement from within one thread, so
-   * therefore does not need to be synchronized when accessed.
-   */
-  protected synchronized Calendar getCalendar() {
-    if (calendar == null) {
-      calendar = Calendar.getInstance(connection.getTimeZone());
-    }
-    return calendar;
-  }
-
-  // implement PreparedStatement
-
-  public ResultSet executeQuery() throws SQLException {
-    this.updateCount = -1;
-    final Signature sig = getSignature();
-    return getConnection().executeQueryInternal(this, sig, null,
-        new QueryState(sig.sql), false);
-  }
-
-  public ParameterMetaData getParameterMetaData() throws SQLException {
-    return this;
-  }
-
-  public final int executeUpdate() throws SQLException {
-    return (int) executeLargeUpdate();
-  }
-
-  public long executeLargeUpdate() throws SQLException {
-    getConnection().executeQueryInternal(this, null, null,
-        new QueryState(getSignature().sql), true);
-    return updateCount;
-  }
-
-  public void setNull(int parameterIndex, int sqlType) throws SQLException {
-    getSite(parameterIndex).setNull(sqlType);
-  }
-
-  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
-    getSite(parameterIndex).setBoolean(x);
-  }
-
-  public void setByte(int parameterIndex, byte x) throws SQLException {
-    getSite(parameterIndex).setByte(x);
-  }
-
-  public void setShort(int parameterIndex, short x) throws SQLException {
-    getSite(parameterIndex).setShort(x);
-  }
-
-  public void setInt(int parameterIndex, int x) throws SQLException {
-    getSite(parameterIndex).setInt(x);
-  }
-
-  public void setLong(int parameterIndex, long x) throws SQLException {
-    getSite(parameterIndex).setLong(x);
-  }
-
-  public void setFloat(int parameterIndex, float x) throws SQLException {
-    getSite(parameterIndex).setFloat(x);
-  }
-
-  public void setDouble(int parameterIndex, double x) throws SQLException {
-    getSite(parameterIndex).setDouble(x);
-  }
-
-  public void setBigDecimal(int parameterIndex, BigDecimal x)
-      throws SQLException {
-    getSite(parameterIndex).setBigDecimal(x);
-  }
-
-  public void setString(int parameterIndex, String x) throws SQLException {
-    getSite(parameterIndex).setString(x);
-  }
-
-  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
-    getSite(parameterIndex).setBytes(x);
-  }
-
-  public void setAsciiStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {
-    getSite(parameterIndex).setAsciiStream(x, length);
-  }
-
-  public void setUnicodeStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {
-    getSite(parameterIndex).setUnicodeStream(x, length);
-  }
-
-  public void setBinaryStream(int parameterIndex, InputStream x, int length)
-      throws SQLException {
-    getSite(parameterIndex).setBinaryStream(x, length);
-  }
-
-  public void clearParameters() throws SQLException {
-    for (int i = 0; i < slots.length; i++) {
-      slots[i] = null;
-    }
-  }
-
-  public void setObject(int parameterIndex, Object x, int targetSqlType)
-      throws SQLException {
-    getSite(parameterIndex).setObject(x, targetSqlType);
-  }
-
-  public void setObject(int parameterIndex, Object x) throws SQLException {
-    getSite(parameterIndex).setObject(x);
-  }
-
-  public boolean execute() throws SQLException {
-    this.updateCount = -1;
-    // We don't know if this is actually an update or a query, so call it a query so we pass the
-    // Signature to the server.
-    getConnection().executeQueryInternal(this, getSignature(), null,
-        new QueryState(getSignature().sql), false);
-    // Result set is null for DML or DDL.
-    // Result set is closed if user cancelled the query.
-    return openResultSet != null && !openResultSet.isClosed();
-  }
-
-  public void addBatch() throws SQLException {
-    throw connection.helper.unsupported();
-  }
-
-  public void setCharacterStream(int parameterIndex, Reader reader, int length)
-      throws SQLException {
-    getSite(parameterIndex).setCharacterStream(reader, length);
-  }
-
-  public void setRef(int parameterIndex, Ref x) throws SQLException {
-    getSite(parameterIndex).setRef(x);
-  }
-
-  public void setBlob(int parameterIndex, Blob x) throws SQLException {
-    getSite(parameterIndex).setBlob(x);
-  }
-
-  public void setClob(int parameterIndex, Clob x) throws SQLException {
-    getSite(parameterIndex).setClob(x);
-  }
-
-  public void setArray(int parameterIndex, Array x) throws SQLException {
-    getSite(parameterIndex).setArray(x);
-  }
-
-  public ResultSetMetaData getMetaData() {
-    return resultSetMetaData;
-  }
-
-  public void setDate(int parameterIndex, Date x, Calendar calendar)
-      throws SQLException {
-    getSite(parameterIndex).setDate(x, calendar);
-  }
-
-  public void setDate(int parameterIndex, Date x) throws SQLException {
-    setDate(parameterIndex, x, getCalendar());
-  }
-
-  public void setTime(int parameterIndex, Time x, Calendar calendar)
-      throws SQLException {
-    getSite(parameterIndex).setTime(x, calendar);
-  }
-
-  public void setTime(int parameterIndex, Time x) throws SQLException {
-    setTime(parameterIndex, x, getCalendar());
-  }
-
-  public void setTimestamp(int parameterIndex, Timestamp x, Calendar calendar)
-      throws SQLException {
-    getSite(parameterIndex).setTimestamp(x, calendar);
-  }
-
-  public void setTimestamp(int parameterIndex, Timestamp x)
-      throws SQLException {
-    setTimestamp(parameterIndex, x, getCalendar());
-  }
-
-  public void setNull(int parameterIndex, int sqlType, String typeName)
-      throws SQLException {
-    getSite(parameterIndex).setNull(sqlType, typeName);
-  }
-
-  public void setURL(int parameterIndex, URL x) throws SQLException {
-    getSite(parameterIndex).setURL(x);
-  }
-
-  public void setObject(int parameterIndex, Object x, int targetSqlType,
-      int scaleOrLength) throws SQLException {
-    getSite(parameterIndex).setObject(x, targetSqlType, scaleOrLength);
-  }
-
-  // implement ParameterMetaData
-
-  protected AvaticaParameter getParameter(int param) throws SQLException {
-    try {
-      return getSignature().parameters.get(param - 1);
-    } catch (IndexOutOfBoundsException e) {
-      //noinspection ThrowableResultOfMethodCallIgnored
-      throw connection.helper.toSQLException(
-          connection.helper.createException(
-              "parameter ordinal " + param + " out of range"));
-    }
-  }
-
-  protected AvaticaSite getSite(int param) throws SQLException {
-    final AvaticaParameter parameter = getParameter(param);
-    return new AvaticaSite(parameter, getCalendar(), param - 1, slots);
-  }
-
-  public int getParameterCount() {
-    return getSignature().parameters.size();
-  }
-
-  public int isNullable(int param) throws SQLException {
-    return ParameterMetaData.parameterNullableUnknown;
-  }
-
-  public boolean isSigned(int index) throws SQLException {
-    return getParameter(index).signed;
-  }
-
-  public int getPrecision(int index) throws SQLException {
-    return getParameter(index).precision;
-  }
-
-  public int getScale(int index) throws SQLException {
-    return getParameter(index).scale;
-  }
-
-  public int getParameterType(int index) throws SQLException {
-    return getParameter(index).parameterType;
-  }
-
-  public String getParameterTypeName(int index) throws SQLException {
-    return getParameter(index).typeName;
-  }
-
-  public String getParameterClassName(int index) throws SQLException {
-    return getParameter(index).className;
-  }
-
-  public int getParameterMode(int param) throws SQLException {
-    //noinspection UnusedDeclaration
-    AvaticaParameter paramDef = getParameter(param); // forces param range check
-    return ParameterMetaData.parameterModeIn;
-  }
-}
-
-// End AvaticaPreparedStatement.java


[27/59] [partial] calcite git commit: [CALCITE-1078] Detach avatica from the core calcite Maven project

Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/pom.xml b/avatica/pom.xml
index 3027df0..7a747fe 100644
--- a/avatica/pom.xml
+++ b/avatica/pom.xml
@@ -18,197 +18,772 @@ limitations under the License.
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>org.apache.calcite</groupId>
-    <artifactId>calcite</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>17</version>
+    <!-- Tell Maven that it's OK that we're not attached to the parent directory -->
+    <relativePath/>
   </parent>
 
-  <artifactId>calcite-avatica</artifactId>
-  <packaging>jar</packaging>
-  <name>Calcite Avatica</name>
-  <description>JDBC driver framework.</description>
+  <!-- The basics. -->
+  <groupId>org.apache.calcite.avatica</groupId>
+  <artifactId>calcite-avatica-parent</artifactId>
+  <packaging>pom</packaging>
+  <version>1.7.0-SNAPSHOT</version>
+
+  <!-- More project information. -->
+  <name>Avatica Project</name>
+  <description>Avatica is a JDBC driver framework which is a part of Apache Calcite</description>
+  <url>http://calcite.apache.org/avatica</url>
+  <inceptionYear>2012</inceptionYear>
+
+  <mailingLists>
+    <mailingList>
+      <name>Apache Calcite developers list</name>
+      <subscribe>dev-subscribe@calcite.apache.org</subscribe>
+      <unsubscribe>dev-unsubscribe@calcite.apache.org</unsubscribe>
+      <post>dev@calcite.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/calcite-dev</archive>
+    </mailingList>
+  </mailingLists>
 
   <properties>
-    <top.dir>${project.basedir}/..</top.dir>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <top.dir>${project.basedir}</top.dir>
+    <version.major>1</version.major>
+    <version.minor>6</version.minor>
+
+    <!-- This list is in alphabetical order. -->
+    <build-helper-maven-plugin.version>1.9</build-helper-maven-plugin.version>
+    <checksum-maven-plugin.version>1.2</checksum-maven-plugin.version>
+    <commons-lang3.version>3.2</commons-lang3.version>
+    <commons-logging.version>1.1.3</commons-logging.version>
+    <dropwizard-metrics3.version>3.1.2</dropwizard-metrics3.version>
+    <findbugs.version>1.3.9</findbugs.version>
+    <freemarker.version>2.3.19</freemarker.version>
+    <git-commit-id-plugin.version>2.1.9</git-commit-id-plugin.version>
+
+    <!-- We support guava versions as old as 14.0.1 (the version used by Hive)
+         but prefer more recent versions. -->
+    <guava.version>14.0.1</guava.version>
+    <h2.version>1.4.185</h2.version>
+    <hadoop.version>2.6.0</hadoop.version>
+    <hamcrest.version>1.3</hamcrest.version>
+    <hsqldb.version>2.3.1</hsqldb.version>
+    <httpclient.version>4.5.2</httpclient.version>
+    <httpcore.version>4.4.4</httpcore.version>
+    <hydromatic-toolbox.version>0.3</hydromatic-toolbox.version>
+    <jackson.version>2.6.3</jackson.version>
+    <jcip-annotations.version>1.0-1</jcip-annotations.version>
+    <jetty.version>9.2.7.v20150116</jetty.version>
+    <junit.version>4.12</junit.version>
+    <maven-checkstyle-plugin.version>2.12.1</maven-checkstyle-plugin.version>
+    <maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
+
+    <!-- keep failsafe version in sync with surefire; apache 17 has surefire 2.7.2 -->
+    <maven-failsafe-plugin.version>2.7.2</maven-failsafe-plugin.version>
+    <maven-scm-provider.version>1.9.1</maven-scm-provider.version>
+    <maven-shade-plugin.version>2.1</maven-shade-plugin.version>
+    <maven-source-plugin.version>2.4</maven-source-plugin.version>
+    <mockito-all.version>1.10.19</mockito-all.version>
+    <protobuf.version>3.0.0-beta-1</protobuf.version>
+    <scott-data-hsqldb.version>0.1</scott-data-hsqldb.version>
+    <servlet.version>3.0.1</servlet.version>
+    <slf4j.version>1.7.13</slf4j.version>
   </properties>
 
-  <dependencies>
-    <!-- Make sure that there are no dependencies on other calcite modules,
-         or on libraries other than Jackson. -->
-    <dependency>
-      <groupId>org.apache.calcite</groupId>
-      <artifactId>calcite-avatica-metrics</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.protobuf</groupId>
-      <artifactId>protobuf-java</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+  <issueManagement>
+    <system>Jira</system>
+    <url>https://issues.apache.org/jira/browse/CALCITE</url>
+  </issueManagement>
+
+  <scm>
+    <connection>scm:git:https://git-wip-us.apache.org/repos/asf/calcite.git</connection>
+    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/calcite.git</developerConnection>
+    <url>https://github.com/apache/calcite</url>
+    <tag>HEAD</tag>
+  </scm>
+
+  <modules>
+    <module>core</module>
+    <module>metrics</module>
+    <module>metrics-dropwizardmetrics3</module>
+    <module>noop-driver</module>
+    <module>server</module>
+  </modules>
+
+  <!-- No dependencies here. Declare dependency VERSIONS in
+       dependencyManagement, below, and each dependency in the module that uses
+       it. -->
+  <dependencies />
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- Sorted by groupId, artifactId; calcite dependencies first. -->
+      <dependency>
+        <groupId>org.apache.calcite</groupId>
+        <artifactId>calcite-avatica</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.calcite</groupId>
+        <artifactId>calcite-avatica-metrics</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.calcite</groupId>
+        <artifactId>calcite-avatica-noop</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.calcite</groupId>
+        <artifactId>calcite-avatica-server</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.calcite</groupId>
+        <artifactId>calcite-avatica</artifactId>
+        <version>${project.version}</version>
+        <type>test-jar</type>
+      </dependency>
+
+      <!-- Now third-party dependencies, sorted by groupId and artifactId. -->
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-core</artifactId>
+        <version>${jackson.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-annotations</artifactId>
+        <version>${jackson.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+        <version>${jackson.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.stephenc.jcip</groupId>
+        <artifactId>jcip-annotations</artifactId>
+        <version>${jcip-annotations.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.code.findbugs</groupId>
+        <artifactId>jsr305</artifactId>
+        <version>${findbugs.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.protobuf</groupId>
+        <artifactId>protobuf-java</artifactId>
+        <version>${protobuf.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.h2database</groupId>
+        <artifactId>h2</artifactId>
+        <version>${h2.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>javax.servlet-api</artifactId>
+        <version>${servlet.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>${junit.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>net.hydromatic</groupId>
+        <artifactId>scott-data-hsqldb</artifactId>
+        <version>${scott-data-hsqldb.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-lang3</artifactId>
+        <version>${commons-lang3.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-common</artifactId>
+        <version>${hadoop.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>${httpclient.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore</artifactId>
+        <version>${httpcore.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-all</artifactId>
+        <version>${mockito-all.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-core</artifactId>
+        <version>${hamcrest.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hsqldb</groupId>
+        <artifactId>hsqldb</artifactId>
+        <version>${hsqldb.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-server</artifactId>
+        <version>${jetty.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-util</artifactId>
+        <version>${jetty.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>${slf4j.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-log4j12</artifactId>
+        <version>${slf4j.version}</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
 
   <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <versionRange>[2.12.1,)</versionRange>
-                    <goals>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
     <plugins>
       <plugin>
-        <artifactId>maven-dependency-plugin</artifactId>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
         <executions>
           <execution>
-            <id>analyze</id>
+            <id>attach-sources</id>
+            <phase>verify</phase>
             <goals>
-              <goal>analyze-only</goal>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
             </goals>
-            <configuration>
-              <failOnWarning>true</failOnWarning>
-              <!-- ignore "unused but declared" warnings -->
-              <ignoredUnusedDeclaredDependencies>
-                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
-              </ignoredUnusedDeclaredDependencies>
-            </configuration>
           </execution>
         </executions>
       </plugin>
-      <!-- Parent module has the same plugin and does the work of
-           generating -sources.jar for each project. But without the
-           plugin declared here, IDEs don't know the sources are
-           available. -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-source-plugin</artifactId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
         <executions>
           <execution>
-            <id>attach-sources</id>
-            <phase>verify</phase>
+            <id>root-resources</id>
             <goals>
-              <goal>jar-no-fork</goal>
-              <goal>test-jar-no-fork</goal>
+              <goal>process</goal>
             </goals>
+            <configuration>
+              <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+              <resourceBundles>
+                <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>
+              </resourceBundles>
+            </configuration>
+          </execution>
+          <execution>
+            <id>non-root-resources</id>
+            <configuration>
+              <resourceBundles>
+                <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>
+              </resourceBundles>
+            </configuration>
           </execution>
         </executions>
       </plugin>
-
-      <!-- Produce a tests jar so that avatica-server/pom.xml can reference for suite.
-           TODO: remove after moving over to annotation-based TestSuite definitions. -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
         <executions>
           <execution>
+            <id>validate</id>
+            <phase>validate</phase>
+            <configuration>
+              <configLocation>${top.dir}/src/main/config/checkstyle/checker.xml</configLocation>
+              <suppressionsLocation>${top.dir}/src/main/config/checkstyle/suppressions.xml</suppressionsLocation>
+              <consoleOutput>true</consoleOutput>
+              <headerLocation>${top.dir}/src/main/config/checkstyle/header.txt</headerLocation>
+              <failOnViolation>true</failOnViolation>
+              <includeTestSourceDirectory>true</includeTestSourceDirectory>
+            </configuration>
             <goals>
-              <goal>test-jar</goal>
+              <goal>check</goal>
             </goals>
           </execution>
         </executions>
+        <dependencies>
+          <dependency>
+            <groupId>net.hydromatic</groupId>
+            <artifactId>toolbox</artifactId>
+            <version>${hydromatic-toolbox.version}</version>
+          </dependency>
+        </dependencies>
       </plugin>
       <plugin>
-        <artifactId>maven-remote-resources-plugin</artifactId>
+        <!-- override default version 2.8 for access to additional config settings -->
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>${maven-dependency-plugin.version}</version>
         <executions>
           <execution>
-            <id>non-root-resources</id>
+            <id>analyze</id>
             <goals>
-              <goal>process</goal>
+              <goal>analyze-only</goal>
             </goals>
+            <configuration>
+              <failOnWarning>true</failOnWarning>
+            </configuration>
           </execution>
         </executions>
       </plugin>
       <plugin>
+        <!-- This is the configuration used by "mvn javadoc:javadoc". It is
+             configured strict, so that it shows errors such as broken links in
+             javadoc on private methods. The configuration for "mvn site" is
+             under "reporting", and is more lenient. -->
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <links>
+            <link>http://docs.oracle.com/javase/8/docs/api/</link>
+          </links>
+          <tags>
+            <tag>
+              <name>sql.92</name>
+              <placement>a</placement>
+              <head>SQL 92 spec:</head>
+            </tag>
+            <tag>
+              <name>sql.99</name>
+              <placement>a</placement>
+              <head>SQL 99 spec:</head>
+            </tag>
+            <tag>
+              <name>sql.2003</name>
+              <placement>a</placement>
+              <head>SQL 2003 spec:</head>
+            </tag>
+            <tag>
+              <name>pre</name>
+            </tag>
+            <tag>
+              <name>post</name>
+            </tag>
+          </tags>
+          <show>private</show>
+        </configuration>
+      </plugin>
+      <plugin>
+        <!-- Override apache parent POM's definition of release
+             plugin. If we don't specify gitexe version, git doesn't
+             commit during release process. -->
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
+        <artifactId>maven-release-plugin</artifactId>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.maven.scm</groupId>
+            <artifactId>maven-scm-provider-gitexe</artifactId>
+            <version>${maven-scm-provider.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <!-- Make sure every sub-project has LICENSE, NOTICE and
+             git.properties in its jar's META-INF directory. -->
         <executions>
           <execution>
-            <phase>package</phase>
+            <id>add-resource</id>
+            <phase>generate-resources</phase>
             <goals>
-              <goal>shade</goal>
+              <goal>add-resource</goal>
+              <goal>add-test-resource</goal>
             </goals>
             <configuration>
-              <relocations>
-                <relocation>
-                  <pattern>com.google.protobuf</pattern>
-                  <shadedPattern>org.apache.calcite.avatica.com.google.protobuf</shadedPattern>
-                </relocation>
-                <relocation>
-                  <pattern>org.apache.http</pattern>
-                  <shadedPattern>org.apache.calcite.avatica.org.apache.http</shadedPattern>
-                </relocation>
-                <relocation>
-                  <pattern>org.apache.commons</pattern>
-                  <shadedPattern>org.apache.calcite.avatica.org.apache.commons</shadedPattern>
-                </relocation>
-              </relocations>
-              <createDependencyReducedPom>false</createDependencyReducedPom>
+              <resources>
+                <resource>
+                  <directory>${top.dir}</directory>
+                  <targetPath>META-INF</targetPath>
+                  <includes>
+                    <include>LICENSE</include>
+                    <include>NOTICE</include>
+                  </includes>
+                </resource>
+                <resource>
+                  <directory>${top.dir}/target</directory>
+                  <targetPath>META-INF</targetPath>
+                  <includes>
+                    <include>git.properties</include>
+                  </includes>
+                </resource>
+              </resources>
             </configuration>
           </execution>
         </executions>
       </plugin>
     </plugins>
+
+    <pluginManagement>
+      <plugins>
+        <!-- Sorted by groupId, artifactId. -->
+        <plugin>
+          <groupId>com.googlecode.fmpp-maven-plugin</groupId>
+          <artifactId>fmpp-maven-plugin</artifactId>
+          <version>${fmpp-maven-plugin.version}</version>
+          <dependencies>
+            <dependency>
+              <groupId>org.freemarker</groupId>
+              <artifactId>freemarker</artifactId>
+              <version>${freemarker.version}</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        <plugin>
+          <groupId>net.hydromatic</groupId>
+          <artifactId>hydromatic-resource-maven-plugin</artifactId>
+          <version>${hydromatic-resource.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>net.ju-n.maven.plugins</groupId>
+          <artifactId>checksum-maven-plugin</artifactId>
+          <version>${checksum-maven-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>${maven-checkstyle-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-failsafe-plugin</artifactId>
+          <version>${maven-failsafe-plugin.version}</version>
+          <executions>
+            <execution>
+              <id>failsafe-integration-test</id>
+              <goals>
+                <goal>integration-test</goal>
+              </goals>
+              <phase>integration-test</phase>
+              <configuration>
+                <threadCount>6</threadCount>
+                <parallel>both</parallel>
+                <argLine>-Xmx1024m</argLine>
+              </configuration>
+            </execution>
+            <execution>
+              <id>failsafe-verify</id>
+              <goals>
+                <goal>verify</goal>
+              </goals>
+              <phase>verify</phase>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-shade-plugin</artifactId>
+          <version>${maven-shade-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-source-plugin</artifactId>
+          <version>${maven-source-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <configuration>
+            <threadCount>1</threadCount>
+            <perCoreThreadCount>true</perCoreThreadCount>
+            <parallel>both</parallel>
+            <argLine>-Xmx1536m -XX:MaxPermSize=256m -Duser.timezone=${user.timezone}</argLine>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>build-helper-maven-plugin</artifactId>
+          <version>${build-helper-maven-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>javacc-maven-plugin</artifactId>
+          <version>${javacc-maven-plugin.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>pl.project13.maven</groupId>
+          <artifactId>git-commit-id-plugin</artifactId>
+          <version>${git-commit-id-plugin.version}</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
   </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <links>
+            <link>http://docs.oracle.com/javase/8/docs/api/</link>
+          </links>
+          <tags>
+            <tag>
+              <name>sql.92</name>
+              <placement>a</placement>
+              <head>SQL 92 spec:</head>
+            </tag>
+            <tag>
+              <name>sql.99</name>
+              <placement>a</placement>
+              <head>SQL 99 spec:</head>
+            </tag>
+            <tag>
+              <name>sql.2003</name>
+              <placement>a</placement>
+              <head>SQL 2003 spec:</head>
+            </tag>
+          </tags>
+          <additionalparam>-tag sql.2003:a:xxx</additionalparam>
+          <notimestamp>true</notimestamp>
+          <windowtitle>Apache Calcite Avatica API</windowtitle>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+  <repositories>
+    <repository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>http://repo.maven.apache.org/maven2</url>
+      <layout>default</layout>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+    </repository>
+    <repository>
+      <releases>
+        <enabled>true</enabled>
+        <updatePolicy>always</updatePolicy>
+        <checksumPolicy>warn</checksumPolicy>
+      </releases>
+      <id>conjars</id>
+      <name>Conjars</name>
+      <url>http://conjars.org/repo</url>
+      <layout>default</layout>
+    </repository>
+  </repositories>
+
+  <profiles>
+    <profile>
+      <!-- This profile adds/overrides few features of the 'apache-release'
+           profile in the parent pom. -->
+      <id>apache-release</id>
+      <build>
+        <plugins>
+          <!-- Apache-RAT checks for files without headers.
+               If run on a messy developer's sandbox, it will fail.
+               This serves as a reminder to only build a release in a clean
+               sandbox! -->
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <configuration>
+              <excludes>
+                <!-- The following files have file formats that do not
+                     admit comments, and therefore cannot contain
+                     license notices. -->
+                <exclude>src/main/resources/META-INF/services/java.sql.Driver</exclude>
+                <exclude>src/main/resources/META-INF/services/org.apache.calcite.avatica.metrics.MetricsSystemFactory</exclude>
+
+                <!-- Files generated by Jekyll. -->
+                <exclude>site/.sass-cache/**</exclude>
+                <exclude>site/_includes/anchor_links.html</exclude>
+                <exclude>site/_includes/docs_contents.html</exclude>
+                <exclude>site/_includes/docs_contents_mobile.html</exclude>
+                <exclude>site/_includes/docs_option.html</exclude>
+                <exclude>site/_includes/docs_ul.html</exclude>
+                <exclude>site/_includes/footer.html</exclude>
+                <exclude>site/_includes/header.html</exclude>
+                <exclude>site/_includes/news_contents.html</exclude>
+                <exclude>site/_includes/news_contents_mobile.html</exclude>
+                <exclude>site/_includes/news_item.html</exclude>
+                <exclude>site/_includes/primary-nav-items.html</exclude>
+                <exclude>site/_includes/section_nav.html</exclude>
+                <exclude>site/_includes/top.html</exclude>
+                <exclude>site/_layouts/default.html</exclude>
+                <exclude>site/_layouts/docs.html</exclude>
+                <exclude>site/_layouts/external.html</exclude>
+                <exclude>site/_layouts/news.html</exclude>
+                <exclude>site/_layouts/news_item.html</exclude>
+                <exclude>site/_layouts/page.html</exclude>
+                <exclude>site/_sass/**</exclude>
+                <exclude>site/css/screen.scss</exclude>
+                <exclude>site/fonts/**</exclude>
+                <exclude>site/js/**</exclude>
+
+                <!-- Images -->
+                <exclude>site/img/*.png</exclude>
+                <exclude>site/favicon.ico</exclude>
+              </excludes>
+            </configuration>
+            <executions>
+              <execution>
+                <phase>verify</phase>
+                <goals>
+                  <goal>check</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>net.ju-n.maven.plugins</groupId>
+            <artifactId>checksum-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>artifacts</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <algorithms>
+                <algorithm>MD5</algorithm>
+                <algorithm>SHA-1</algorithm>
+              </algorithms>
+              <failOnError>false</failOnError>
+            </configuration>
+          </plugin>
+          <!-- Override the parent assembly execution to customize the assembly
+               descriptor and final name. -->
+          <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>source-release-assembly</id>
+                <phase>none</phase>
+              </execution>
+              <execution>
+                <id>source-release-assembly-calcite</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <configuration>
+                  <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+                  <appendAssemblyId>false</appendAssemblyId>
+                  <descriptor>${top.dir}/src/main/config/assemblies/source-assembly.xml</descriptor>
+                  <finalName>apache-calcite-avatica-${project.version}-src</finalName>
+                  <tarLongFileMode>gnu</tarLongFileMode>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>it</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-failsafe-plugin</artifactId>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <!-- CALCITE-537: workaround for MRRESOURCES-91
+        Avoid overwrite of the destination file if the produced
+        contents is the same.
+        Apache pom overwrites NOTICE, DEPENDENCIES, and LICENSE files, however
+        we do not want recompile the module every time. -->
+      <id>skip-apache-licenses</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+        <file><exists>target/maven-shared-archive-resources/META-INF/LICENSE</exists></file>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-remote-resources-plugin</artifactId>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <!-- Generate git.properties on first build -->
+      <id>generate-git-id</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <!-- Note: <missing> here does NOT support interpolation,
+        so technically, this profile is active for sub-modules.
+        It would be nice to use ${top.dir}/target/... here, but
+        it is not possible.
+        However sub-modules lack .git folder, so no git.properties
+        is generated. -->
+        <file>
+          <missing>target/git.properties</missing>
+        </file>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>pl.project13.maven</groupId>
+            <artifactId>git-commit-id-plugin</artifactId>
+            <inherited>false</inherited>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>revision</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
+              <verbose>false</verbose>
+              <skipPoms>false</skipPoms>
+              <generateGitPropertiesFile>true</generateGitPropertiesFile>
+              <generateGitPropertiesFilename>target/git.properties</generateGitPropertiesFilename>
+              <failOnNoGitDirectory>false</failOnNoGitDirectory>
+              <gitDescribe>
+                <skip>false</skip>
+                <always>false</always>
+                <abbrev>7</abbrev>
+                <dirty>-dirty</dirty>
+                <forceLongFormat>true</forceLongFormat>
+              </gitDescribe>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/server/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/server/pom.xml b/avatica/server/pom.xml
new file mode 100644
index 0000000..63a390d
--- /dev/null
+++ b/avatica/server/pom.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.calcite.avatica</groupId>
+    <artifactId>calcite-avatica-parent</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>calcite-avatica-server</artifactId>
+  <packaging>jar</packaging>
+  <name>Calcite Avatica Server</name>
+  <description>JDBC server.</description>
+
+  <properties>
+    <top.dir>${project.basedir}/..</top.dir>
+  </properties>
+
+  <dependencies>
+    <!-- Sorted by groupId, artifactId; calcite dependencies first. Put versions
+         in dependencyManagement in the root POM, not here. -->
+    <dependency>
+      <groupId>org.apache.calcite</groupId>
+      <artifactId>calcite-avatica</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-util</artifactId>
+    </dependency>
+
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>org.apache.calcite</groupId>
+      <artifactId>calcite-avatica</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <!-- Used in RemoteDriverTest but dependency not detected by maven-dependency-plugin:2.8:analyze -->
+      <groupId>net.hydromatic</groupId>
+      <artifactId>scott-data-hsqldb</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <!-- Used in RemoteDriverTest but dependency not detected by maven-dependency-plugin:2.8:analyze -->
+      <groupId>org.hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.stephenc.jcip</groupId>
+      <artifactId>jcip-annotations</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <versionRange>[2.12.1,)</versionRange>
+                    <goals>
+                      <goal>check</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <!-- Parent module has the same plugin and does the work of
+           generating -sources.jar for each project. But without the
+           plugin declared here, IDEs don't know the sources are
+           available. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>jar-no-fork</goal>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>${maven-dependency-plugin.version}</version>
+        <!-- configurations do not cascade, so all of the definition from
+             ../pom.xml:build:plugin-management:plugins:plugin must be repeated in child poms -->
+        <executions>
+          <execution>
+            <id>analyze</id>
+            <goals>
+              <goal>analyze-only</goal>
+            </goals>
+            <configuration>
+              <failOnWarning>true</failOnWarning>
+              <!-- ignore "unused but declared" warnings -->
+              <ignoredUnusedDeclaredDependencies>
+                <ignoredUnusedDeclaredDependency>io.dropwizard.metrics:metrics-core</ignoredUnusedDeclaredDependency>
+                <ignoredUnusedDeclaredDependency>net.hydromatic:scott-data-hsqldb</ignoredUnusedDeclaredDependency>
+                <ignoredUnusedDeclaredDependency>org.hsqldb:hsqldb</ignoredUnusedDeclaredDependency>
+                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
+                <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+              </ignoredUnusedDeclaredDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>non-root-resources</id>
+            <goals>
+              <goal>process</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
new file mode 100644
index 0000000..dfe7f99
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -0,0 +1,976 @@
+/*
+ * 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.jdbc;
+
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.AvaticaPreparedStatement;
+import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.MetaImpl;
+import org.apache.calcite.avatica.MissingResultsException;
+import org.apache.calcite.avatica.NoSuchConnectionException;
+import org.apache.calcite.avatica.NoSuchStatementException;
+import org.apache.calcite.avatica.QueryState;
+import org.apache.calcite.avatica.SqlType;
+import org.apache.calcite.avatica.metrics.Gauge;
+import org.apache.calcite.avatica.metrics.MetricsSystem;
+import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.remote.TypedValue;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+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;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** Implementation of {@link Meta} upon an existing JDBC data source. */
+public class JdbcMeta implements Meta {
+  private static final Logger LOG = LoggerFactory.getLogger(JdbcMeta.class);
+
+  private static final String CONN_CACHE_KEY_BASE = "avatica.connectioncache";
+
+  private static final String STMT_CACHE_KEY_BASE = "avatica.statementcache";
+
+  /** Special value for {@code Statement#getLargeMaxRows()} that means fetch
+   * an unlimited number of rows in a single batch.
+   *
+   * <p>Any other negative value will return an unlimited number of rows but
+   * will do it in the default batch size, namely 100. */
+  public static final long UNLIMITED_COUNT = -2L;
+
+  // End of constants, start of member variables
+
+  final Calendar calendar = Calendar.getInstance();
+
+  /** Generates ids for statements. The ids are unique across all connections
+   * created by this JdbcMeta. */
+  private final AtomicInteger statementIdGenerator = new AtomicInteger();
+
+  private final String url;
+  private final Properties info;
+  private final Cache<String, Connection> connectionCache;
+  private final Cache<Integer, StatementInfo> statementCache;
+  private final MetricsSystem metrics;
+
+  /**
+   * Creates a JdbcMeta.
+   *
+   * @param url a database url of the form
+   *  <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
+   */
+  public JdbcMeta(String url) throws SQLException {
+    this(url, new Properties());
+  }
+
+  /**
+   * Creates a JdbcMeta.
+   *
+   * @param url a database url of the form
+   * <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
+   * @param user the database user on whose behalf the connection is being
+   *   made
+   * @param password the user's password
+   */
+  public JdbcMeta(final String url, final String user, final String password)
+      throws SQLException {
+    this(url, new Properties() {
+      {
+        put("user", user);
+        put("password", password);
+      }
+    });
+  }
+
+  public JdbcMeta(String url, Properties info) throws SQLException {
+    this(url, info, NoopMetricsSystem.getInstance());
+  }
+
+  /**
+   * Creates a JdbcMeta.
+   *
+   * @param url a database url of the form
+   * <code> jdbc:<em>subprotocol</em>:<em>subname</em></code>
+   * @param info a list of arbitrary string tag/value pairs as
+   * connection arguments; normally at least a "user" and
+   * "password" property should be included
+   */
+  public JdbcMeta(String url, Properties info, MetricsSystem metrics)
+      throws SQLException {
+    this.url = url;
+    this.info = info;
+    this.metrics = Objects.requireNonNull(metrics);
+
+    int concurrencyLevel = Integer.parseInt(
+        info.getProperty(ConnectionCacheSettings.CONCURRENCY_LEVEL.key(),
+            ConnectionCacheSettings.CONCURRENCY_LEVEL.defaultValue()));
+    int initialCapacity = Integer.parseInt(
+        info.getProperty(ConnectionCacheSettings.INITIAL_CAPACITY.key(),
+            ConnectionCacheSettings.INITIAL_CAPACITY.defaultValue()));
+    long maxCapacity = Long.parseLong(
+        info.getProperty(ConnectionCacheSettings.MAX_CAPACITY.key(),
+            ConnectionCacheSettings.MAX_CAPACITY.defaultValue()));
+    long connectionExpiryDuration = Long.parseLong(
+        info.getProperty(ConnectionCacheSettings.EXPIRY_DURATION.key(),
+            ConnectionCacheSettings.EXPIRY_DURATION.defaultValue()));
+    TimeUnit connectionExpiryUnit = TimeUnit.valueOf(
+        info.getProperty(ConnectionCacheSettings.EXPIRY_UNIT.key(),
+            ConnectionCacheSettings.EXPIRY_UNIT.defaultValue()));
+    this.connectionCache = CacheBuilder.newBuilder()
+        .concurrencyLevel(concurrencyLevel)
+        .initialCapacity(initialCapacity)
+        .maximumSize(maxCapacity)
+        .expireAfterAccess(connectionExpiryDuration, connectionExpiryUnit)
+        .removalListener(new ConnectionExpiryHandler())
+        .build();
+    LOG.debug("instantiated connection cache: {}", connectionCache.stats());
+
+    concurrencyLevel = Integer.parseInt(
+        info.getProperty(StatementCacheSettings.CONCURRENCY_LEVEL.key(),
+            StatementCacheSettings.CONCURRENCY_LEVEL.defaultValue()));
+    initialCapacity = Integer.parseInt(
+        info.getProperty(StatementCacheSettings.INITIAL_CAPACITY.key(),
+            StatementCacheSettings.INITIAL_CAPACITY.defaultValue()));
+    maxCapacity = Long.parseLong(
+        info.getProperty(StatementCacheSettings.MAX_CAPACITY.key(),
+            StatementCacheSettings.MAX_CAPACITY.defaultValue()));
+    connectionExpiryDuration = Long.parseLong(
+        info.getProperty(StatementCacheSettings.EXPIRY_DURATION.key(),
+            StatementCacheSettings.EXPIRY_DURATION.defaultValue()));
+    connectionExpiryUnit = TimeUnit.valueOf(
+        info.getProperty(StatementCacheSettings.EXPIRY_UNIT.key(),
+            StatementCacheSettings.EXPIRY_UNIT.defaultValue()));
+    this.statementCache = CacheBuilder.newBuilder()
+        .concurrencyLevel(concurrencyLevel)
+        .initialCapacity(initialCapacity)
+        .maximumSize(maxCapacity)
+        .expireAfterAccess(connectionExpiryDuration, connectionExpiryUnit)
+        .removalListener(new StatementExpiryHandler())
+        .build();
+
+    LOG.debug("instantiated statement cache: {}", statementCache.stats());
+
+    // Register some metrics
+    this.metrics.register(concat(JdbcMeta.class, "ConnectionCacheSize"), new Gauge<Long>() {
+      @Override public Long getValue() {
+        return connectionCache.size();
+      }
+    });
+
+    this.metrics.register(concat(JdbcMeta.class, "StatementCacheSize"), new Gauge<Long>() {
+      @Override public Long getValue() {
+        return statementCache.size();
+      }
+    });
+  }
+
+  /**
+   * Converts from JDBC metadata to Avatica columns.
+   */
+  protected static List<ColumnMetaData>
+  columns(ResultSetMetaData metaData) throws SQLException {
+    if (metaData == null) {
+      return Collections.emptyList();
+    }
+    final List<ColumnMetaData> columns = new ArrayList<>();
+    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);
+      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),
+              metaData.isCurrency(i), metaData.isNullable(i),
+              metaData.isSigned(i), metaData.getColumnDisplaySize(i),
+              metaData.getColumnLabel(i), metaData.getColumnName(i),
+              metaData.getSchemaName(i), metaData.getPrecision(i),
+              metaData.getScale(i), metaData.getTableName(i),
+              metaData.getCatalogName(i), t, metaData.isReadOnly(i),
+              metaData.isWritable(i), metaData.isDefinitelyWritable(i),
+              metaData.getColumnClassName(i));
+      columns.add(md);
+    }
+    return columns;
+  }
+
+  /**
+   * Converts from JDBC metadata to Avatica parameters
+   */
+  protected static List<AvaticaParameter> parameters(ParameterMetaData metaData)
+      throws SQLException {
+    if (metaData == null) {
+      return Collections.emptyList();
+    }
+    final List<AvaticaParameter> params = new ArrayList<>();
+    for (int i = 1; i <= metaData.getParameterCount(); i++) {
+      params.add(
+          new AvaticaParameter(metaData.isSigned(i), metaData.getPrecision(i),
+              metaData.getScale(i), metaData.getParameterType(i),
+              metaData.getParameterTypeName(i),
+              metaData.getParameterClassName(i), "?" + i));
+    }
+    return params;
+  }
+
+  protected static Signature signature(ResultSetMetaData metaData,
+      ParameterMetaData parameterMetaData, String sql,
+      Meta.StatementType statementType) throws  SQLException {
+    final CursorFactory cf = CursorFactory.LIST;  // because JdbcResultSet#frame
+    return new Signature(columns(metaData), sql, parameters(parameterMetaData),
+        null, cf, statementType);
+  }
+
+  protected static Signature signature(ResultSetMetaData metaData)
+      throws SQLException {
+    return signature(metaData, null, null, null);
+  }
+
+  public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
+    try {
+      final Map<DatabaseProperty, Object> map = new HashMap<>();
+      final DatabaseMetaData metaData = getConnection(ch.id).getMetaData();
+      for (DatabaseProperty p : DatabaseProperty.values()) {
+        addProperty(map, metaData, p);
+      }
+      return map;
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private static Object addProperty(Map<DatabaseProperty, Object> map,
+      DatabaseMetaData metaData, DatabaseProperty p) throws SQLException {
+    try {
+      return map.put(p, p.method.invoke(metaData));
+    } catch (IllegalAccessException | InvocationTargetException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getTables(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat tableNamePattern, List<String> typeList) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getTables(catalog, schemaPattern.s,
+              tableNamePattern.s, toArray(typeList));
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+    * Registers a StatementInfo for the given ResultSet, returning the id under
+    * which it is registered. This should be used for metadata ResultSets, which
+    * have an implicit statement created.
+    */
+  private int registerMetaStatement(ResultSet rs) throws SQLException {
+    final int id = statementIdGenerator.getAndIncrement();
+    StatementInfo statementInfo = new StatementInfo(rs.getStatement());
+    statementInfo.setResultSet(rs);
+    statementCache.put(id, statementInfo);
+    return id;
+  }
+
+  public MetaResultSet getColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat tableNamePattern, Pat columnNamePattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getColumns(catalog, schemaPattern.s,
+              tableNamePattern.s, columnNamePattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat schemaPattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getSchemas(catalog, schemaPattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getCatalogs(ConnectionHandle ch) {
+    try {
+      final ResultSet rs = getConnection(ch.id).getMetaData().getCatalogs();
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getTableTypes(ConnectionHandle ch) {
+    try {
+      final ResultSet rs = getConnection(ch.id).getMetaData().getTableTypes();
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getProcedures(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat procedureNamePattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getProcedures(catalog, schemaPattern.s,
+              procedureNamePattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getProcedureColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat procedureNamePattern, Pat columnNamePattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getProcedureColumns(catalog,
+              schemaPattern.s, procedureNamePattern.s, columnNamePattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getColumnPrivileges(ConnectionHandle ch, String catalog, String schema,
+      String table, Pat columnNamePattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getColumnPrivileges(catalog, schema,
+              table, columnNamePattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getTablePrivileges(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat tableNamePattern) {
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getTablePrivileges(catalog,
+              schemaPattern.s, tableNamePattern.s);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getBestRowIdentifier(ConnectionHandle ch, String catalog, String schema,
+      String table, int scope, boolean nullable) {
+    LOG.trace("getBestRowIdentifier catalog:{} schema:{} table:{} scope:{} nullable:{}", catalog,
+        schema, table, scope, nullable);
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getBestRowIdentifier(catalog, schema,
+              table, scope, nullable);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getVersionColumns(ConnectionHandle ch, String catalog, String schema,
+      String table) {
+    LOG.trace("getVersionColumns catalog:{} schema:{} table:{}", catalog, schema, table);
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getVersionColumns(catalog, schema, table);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getPrimaryKeys(ConnectionHandle ch, String catalog, String schema,
+      String table) {
+    LOG.trace("getPrimaryKeys catalog:{} schema:{} table:{}", catalog, schema, table);
+    try {
+      final ResultSet rs =
+          getConnection(ch.id).getMetaData().getPrimaryKeys(catalog, schema, table);
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getImportedKeys(ConnectionHandle ch, String catalog, String schema,
+      String table) {
+    return null;
+  }
+
+  public MetaResultSet getExportedKeys(ConnectionHandle ch, String catalog, String schema,
+      String table) {
+    return null;
+  }
+
+  public MetaResultSet getCrossReference(ConnectionHandle ch, String parentCatalog,
+      String parentSchema, String parentTable, String foreignCatalog,
+      String foreignSchema, String foreignTable) {
+    return null;
+  }
+
+  public MetaResultSet getTypeInfo(ConnectionHandle ch) {
+    try {
+      final ResultSet rs = getConnection(ch.id).getMetaData().getTypeInfo();
+      int stmtId = registerMetaStatement(rs);
+      return JdbcResultSet.create(ch.id, stmtId, rs);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public MetaResultSet getIndexInfo(ConnectionHandle ch, String catalog, String schema,
+      String table, boolean unique, boolean approximate) {
+    return null;
+  }
+
+  public MetaResultSet getUDTs(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat typeNamePattern, int[] types) {
+    return null;
+  }
+
+  public MetaResultSet getSuperTypes(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat typeNamePattern) {
+    return null;
+  }
+
+  public MetaResultSet getSuperTables(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat tableNamePattern) {
+    return null;
+  }
+
+  public MetaResultSet getAttributes(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat typeNamePattern, Pat attributeNamePattern) {
+    return null;
+  }
+
+  public MetaResultSet getClientInfoProperties(ConnectionHandle ch) {
+    return null;
+  }
+
+  public MetaResultSet getFunctions(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat functionNamePattern) {
+    return null;
+  }
+
+  public MetaResultSet getFunctionColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat functionNamePattern, Pat columnNamePattern) {
+    return null;
+  }
+
+  public MetaResultSet getPseudoColumns(ConnectionHandle ch, String catalog, Pat schemaPattern,
+      Pat tableNamePattern, Pat columnNamePattern) {
+    return null;
+  }
+
+  public Iterable<Object> createIterable(StatementHandle handle, QueryState state,
+      Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
+    return null;
+  }
+
+  protected Connection getConnection(String id) throws SQLException {
+    if (id == null) {
+      throw new NullPointerException("Connection id is null.");
+    }
+    Connection conn = connectionCache.getIfPresent(id);
+    if (conn == null) {
+      throw new NoSuchConnectionException("Connection not found: invalid id, closed, or expired: "
+          + id);
+    }
+    return conn;
+  }
+
+  public StatementHandle createStatement(ConnectionHandle ch) {
+    try {
+      final Connection conn = getConnection(ch.id);
+      final Statement statement = conn.createStatement();
+      final int id = statementIdGenerator.getAndIncrement();
+      statementCache.put(id, new StatementInfo(statement));
+      StatementHandle h = new StatementHandle(ch.id, id, null);
+      LOG.trace("created statement {}", h);
+      return h;
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  @Override public void closeStatement(StatementHandle h) {
+    StatementInfo info = statementCache.getIfPresent(h.id);
+    if (info == null || info.statement == null) {
+      LOG.debug("client requested close unknown statement {}", h);
+      return;
+    }
+    LOG.trace("closing statement {}", h);
+    try {
+      ResultSet results = info.getResultSet();
+      if (info.isResultSetInitialized() && null != results) {
+        results.close();
+      }
+      info.statement.close();
+    } catch (SQLException e) {
+      throw propagate(e);
+    } finally {
+      statementCache.invalidate(h.id);
+    }
+  }
+
+  @Override public void openConnection(ConnectionHandle ch,
+      Map<String, String> info) {
+    Properties fullInfo = new Properties();
+    fullInfo.putAll(this.info);
+    if (info != null) {
+      fullInfo.putAll(info);
+    }
+
+    synchronized (this) {
+      try {
+        if (connectionCache.asMap().containsKey(ch.id)) {
+          throw new RuntimeException("Connection already exists: " + ch.id);
+        }
+        Connection conn = DriverManager.getConnection(url, fullInfo);
+        connectionCache.put(ch.id, conn);
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  @Override public void closeConnection(ConnectionHandle ch) {
+    Connection conn = connectionCache.getIfPresent(ch.id);
+    if (conn == null) {
+      LOG.debug("client requested close unknown connection {}", ch);
+      return;
+    }
+    LOG.trace("closing connection {}", ch);
+    try {
+      conn.close();
+    } catch (SQLException e) {
+      throw propagate(e);
+    } finally {
+      connectionCache.invalidate(ch.id);
+    }
+  }
+
+  protected void apply(Connection conn, ConnectionProperties connProps)
+      throws SQLException {
+    if (connProps.isAutoCommit() != null) {
+      conn.setAutoCommit(connProps.isAutoCommit());
+    }
+    if (connProps.isReadOnly() != null) {
+      conn.setReadOnly(connProps.isReadOnly());
+    }
+    if (connProps.getTransactionIsolation() != null) {
+      conn.setTransactionIsolation(connProps.getTransactionIsolation());
+    }
+    if (connProps.getCatalog() != null) {
+      conn.setCatalog(connProps.getCatalog());
+    }
+    if (connProps.getSchema() != null) {
+      conn.setSchema(connProps.getSchema());
+    }
+  }
+
+  @Override public ConnectionProperties connectionSync(ConnectionHandle ch,
+      ConnectionProperties connProps) {
+    LOG.trace("syncing properties for connection {}", ch);
+    try {
+      Connection conn = getConnection(ch.id);
+      ConnectionPropertiesImpl props = new ConnectionPropertiesImpl(conn).merge(connProps);
+      if (props.isDirty()) {
+        apply(conn, props);
+        props.setDirty(false);
+      }
+      return props;
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  RuntimeException propagate(Throwable e) {
+    if (e instanceof RuntimeException) {
+      throw (RuntimeException) e;
+    } else if (e instanceof Error) {
+      throw (Error) e;
+    } else {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public StatementHandle prepare(ConnectionHandle ch, String sql,
+      long maxRowCount) {
+    try {
+      final Connection conn = getConnection(ch.id);
+      final PreparedStatement statement = conn.prepareStatement(sql);
+      final int id = statementIdGenerator.getAndIncrement();
+      Meta.StatementType statementType = null;
+      if (statement.isWrapperFor(AvaticaPreparedStatement.class)) {
+        final AvaticaPreparedStatement avaticaPreparedStatement;
+        avaticaPreparedStatement =
+            statement.unwrap(AvaticaPreparedStatement.class);
+        statementType = avaticaPreparedStatement.getStatementType();
+      }
+      statementCache.put(id, new StatementInfo(statement));
+      StatementHandle h = new StatementHandle(ch.id, id,
+          signature(statement.getMetaData(), statement.getParameterMetaData(),
+              sql, statementType));
+      LOG.trace("prepared statement {}", h);
+      return h;
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
+      long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
+    try {
+      final StatementInfo info = statementCache.getIfPresent(h.id);
+      if (info == null) {
+        throw new NoSuchStatementException(h);
+      }
+      final Statement statement = info.statement;
+      // Special handling of maxRowCount as JDBC 0 is unlimited, our meta 0 row
+      if (maxRowCount > 0) {
+        AvaticaUtils.setLargeMaxRows(statement, maxRowCount);
+      } else if (maxRowCount < 0) {
+        statement.setMaxRows(0);
+      }
+      boolean ret = statement.execute(sql);
+      info.setResultSet(statement.getResultSet());
+      // Either execute(sql) returned true or the resultSet was null
+      assert ret || null == info.getResultSet();
+      final List<MetaResultSet> resultSets = new ArrayList<>();
+      if (null == info.getResultSet()) {
+        // Create a special result set that just carries update count
+        resultSets.add(
+            JdbcResultSet.count(h.connectionId, h.id,
+                AvaticaUtils.getLargeUpdateCount(statement)));
+      } else {
+        resultSets.add(
+            JdbcResultSet.create(h.connectionId, h.id, info.getResultSet(), maxRowCount));
+      }
+      LOG.trace("prepAndExec statement {}", h);
+      // TODO: review client to ensure statementId is updated when appropriate
+      return new ExecuteResult(resultSets);
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  public boolean syncResults(StatementHandle sh, QueryState state, long offset)
+      throws NoSuchStatementException {
+    try {
+      final Connection conn = getConnection(sh.connectionId);
+      final StatementInfo info = statementCache.getIfPresent(sh.id);
+      if (null == info) {
+        throw new NoSuchStatementException(sh);
+      }
+      final Statement statement = info.statement;
+      // Let the state recreate the necessary ResultSet on the Statement
+      info.setResultSet(state.invoke(conn, statement));
+
+      if (null != info.getResultSet()) {
+        // If it is non-null, try to advance to the requested offset.
+        return info.advanceResultSetToOffset(info.getResultSet(), offset);
+      }
+
+      // No results, nothing to do. Client can move on.
+      return false;
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  public Frame fetch(StatementHandle h, long offset, int fetchMaxRowCount) throws
+      NoSuchStatementException, MissingResultsException {
+    LOG.trace("fetching {} offset:{} fetchMaxRowCount:{}", h, offset, fetchMaxRowCount);
+    try {
+      final StatementInfo statementInfo = statementCache.getIfPresent(h.id);
+      if (null == statementInfo) {
+        // Statement might have expired, or never existed on this server.
+        throw new NoSuchStatementException(h);
+      }
+
+      if (!statementInfo.isResultSetInitialized()) {
+        // The Statement exists, but the results are missing. Need to call syncResults(...)
+        throw new MissingResultsException(h);
+      }
+      if (statementInfo.getResultSet() == null) {
+        return Frame.EMPTY;
+      } else {
+        return JdbcResultSet.frame(statementInfo, statementInfo.getResultSet(), offset,
+            fetchMaxRowCount, calendar);
+      }
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  private static String[] toArray(List<String> typeList) {
+    if (typeList == null) {
+      return null;
+    }
+    return typeList.toArray(new String[typeList.size()]);
+  }
+
+  @Override public ExecuteResult execute(StatementHandle h,
+      List<TypedValue> parameterValues, long maxRowCount) throws NoSuchStatementException {
+    try {
+      if (MetaImpl.checkParameterValueHasNull(parameterValues)) {
+        throw new SQLException("exception while executing query: unbound parameter");
+      }
+
+      final StatementInfo statementInfo = statementCache.getIfPresent(h.id);
+      if (null == statementInfo) {
+        throw new NoSuchStatementException(h);
+      }
+      final List<MetaResultSet> resultSets;
+      final PreparedStatement preparedStatement =
+          (PreparedStatement) statementInfo.statement;
+
+      if (parameterValues != null) {
+        for (int i = 0; i < parameterValues.size(); i++) {
+          TypedValue o = parameterValues.get(i);
+          preparedStatement.setObject(i + 1, o.toJdbc(calendar));
+        }
+      }
+
+      if (preparedStatement.execute()) {
+        final Meta.Frame frame;
+        final Signature signature2;
+        if (preparedStatement.isWrapperFor(AvaticaPreparedStatement.class)) {
+          signature2 = h.signature;
+        } else {
+          h.signature = signature(preparedStatement.getMetaData(),
+              preparedStatement.getParameterMetaData(), h.signature.sql,
+              Meta.StatementType.SELECT);
+          signature2 = h.signature;
+        }
+
+        // Make sure we set this for subsequent fetch()'s to find the result set.
+        statementInfo.setResultSet(preparedStatement.getResultSet());
+
+        if (statementInfo.getResultSet() == null) {
+          frame = Frame.EMPTY;
+          resultSets = Collections.<MetaResultSet>singletonList(
+              JdbcResultSet.empty(h.connectionId, h.id, signature2));
+        } else {
+          resultSets = Collections.<MetaResultSet>singletonList(
+              JdbcResultSet.create(h.connectionId, h.id, statementInfo.getResultSet(),
+                  maxRowCount, signature2));
+        }
+      } else {
+        resultSets = Collections.<MetaResultSet>singletonList(
+            JdbcResultSet.count(h.connectionId, h.id, preparedStatement.getUpdateCount()));
+      }
+
+      return new ExecuteResult(resultSets);
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  @Override public void commit(ConnectionHandle ch) {
+    try {
+      final Connection conn = getConnection(ch.id);
+      conn.commit();
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  @Override public void rollback(ConnectionHandle ch) {
+    try {
+      final Connection conn = getConnection(ch.id);
+      conn.rollback();
+    } catch (SQLException e) {
+      throw propagate(e);
+    }
+  }
+
+  /** Configurable statement cache settings. */
+  public enum StatementCacheSettings {
+    /** JDBC connection property for setting connection cache concurrency level. */
+    CONCURRENCY_LEVEL(STMT_CACHE_KEY_BASE + ".concurrency", "100"),
+
+    /** JDBC connection property for setting connection cache initial capacity. */
+    INITIAL_CAPACITY(STMT_CACHE_KEY_BASE + ".initialcapacity", "1000"),
+
+    /** JDBC connection property for setting connection cache maximum capacity. */
+    MAX_CAPACITY(STMT_CACHE_KEY_BASE + ".maxcapacity", "10000"),
+
+    /** JDBC connection property for setting connection cache expiration duration.
+     *
+     * <p>Used in conjunction with {@link #EXPIRY_UNIT}.</p>
+     */
+    EXPIRY_DURATION(STMT_CACHE_KEY_BASE + ".expirydiration", "5"),
+
+    /** JDBC connection property for setting connection cache expiration unit.
+     *
+     * <p>Used in conjunction with {@link #EXPIRY_DURATION}.</p>
+     */
+    EXPIRY_UNIT(STMT_CACHE_KEY_BASE + ".expiryunit", TimeUnit.MINUTES.name());
+
+    private final String key;
+    private final String defaultValue;
+
+    StatementCacheSettings(String key, String defaultValue) {
+      this.key = key;
+      this.defaultValue = defaultValue;
+    }
+
+    /** The configuration key for specifying this setting. */
+    public String key() {
+      return key;
+    }
+
+    /** The default value for this setting. */
+    public String defaultValue() {
+      return defaultValue;
+    }
+  }
+
+  /** Configurable connection cache settings. */
+  public enum ConnectionCacheSettings {
+    /** JDBC connection property for setting connection cache concurrency level. */
+    CONCURRENCY_LEVEL(CONN_CACHE_KEY_BASE + ".concurrency", "10"),
+
+    /** JDBC connection property for setting connection cache initial capacity. */
+    INITIAL_CAPACITY(CONN_CACHE_KEY_BASE + ".initialcapacity", "100"),
+
+    /** JDBC connection property for setting connection cache maximum capacity. */
+    MAX_CAPACITY(CONN_CACHE_KEY_BASE + ".maxcapacity", "1000"),
+
+    /** JDBC connection property for setting connection cache expiration duration. */
+    EXPIRY_DURATION(CONN_CACHE_KEY_BASE + ".expiryduration", "10"),
+
+    /** JDBC connection property for setting connection cache expiration unit. */
+    EXPIRY_UNIT(CONN_CACHE_KEY_BASE + ".expiryunit", TimeUnit.MINUTES.name());
+
+    private final String key;
+    private final String defaultValue;
+
+    ConnectionCacheSettings(String key, String defaultValue) {
+      this.key = key;
+      this.defaultValue = defaultValue;
+    }
+
+    /** The configuration key for specifying this setting. */
+    public String key() {
+      return key;
+    }
+
+    /** The default value for this setting. */
+    public String defaultValue() {
+      return defaultValue;
+    }
+  }
+
+  /** Callback for {@link #connectionCache} member expiration. */
+  private class ConnectionExpiryHandler
+      implements RemovalListener<String, Connection> {
+
+    public void onRemoval(RemovalNotification<String, Connection> notification) {
+      String connectionId = notification.getKey();
+      Connection doomed = notification.getValue();
+      LOG.debug("Expiring connection {} because {}", connectionId, notification.getCause());
+      try {
+        if (doomed != null) {
+          doomed.close();
+        }
+      } catch (Throwable t) {
+        LOG.info("Exception thrown while expiring connection {}", connectionId, t);
+      }
+    }
+  }
+
+  /** Callback for {@link #statementCache} member expiration. */
+  private class StatementExpiryHandler
+      implements RemovalListener<Integer, StatementInfo> {
+    public void onRemoval(RemovalNotification<Integer, StatementInfo> notification) {
+      Integer stmtId = notification.getKey();
+      StatementInfo doomed = notification.getValue();
+      if (doomed == null) {
+        // log/throw?
+        return;
+      }
+      LOG.debug("Expiring statement {} because {}", stmtId, notification.getCause());
+      try {
+        if (doomed.getResultSet() != null) {
+          doomed.getResultSet().close();
+        }
+        if (doomed.statement != null) {
+          doomed.statement.close();
+        }
+      } catch (Throwable t) {
+        LOG.info("Exception thrown while expiring statement {}", stmtId, t);
+      }
+    }
+  }
+}
+
+// End JdbcMeta.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/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
new file mode 100644
index 0000000..6630124
--- /dev/null
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
@@ -0,0 +1,215 @@
+/*
+ * 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.jdbc;
+
+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}.
+ *
+ *  @see org.apache.calcite.avatica.jdbc.JdbcMeta */
+class JdbcResultSet extends Meta.MetaResultSet {
+  protected JdbcResultSet(String connectionId, int statementId,
+      boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame) {
+    this(connectionId, statementId, ownStatement, signature, firstFrame, -1L);
+  }
+
+  protected JdbcResultSet(String connectionId, int statementId,
+      boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame,
+      long updateCount) {
+    super(connectionId, statementId, ownStatement, signature, firstFrame, updateCount);
+  }
+
+  /** Creates a result set. */
+  public static JdbcResultSet create(String connectionId, int statementId,
+      ResultSet resultSet) {
+    // -1 still limits to 100 but -2 does not limit to any number
+    return create(connectionId, statementId, resultSet,
+        JdbcMeta.UNLIMITED_COUNT);
+  }
+
+  /** Creates a result set with maxRowCount.
+   *
+   * <p>If {@code maxRowCount} is -2 ({@link JdbcMeta#UNLIMITED_COUNT}),
+   * returns an unlimited number of rows in a single frame; any other
+   * negative value (typically -1) returns an unlimited number of rows
+   * in frames of the default frame size. */
+  public static JdbcResultSet create(String connectionId, int statementId,
+      ResultSet resultSet, long maxRowCount) {
+    try {
+      Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
+      return create(connectionId, statementId, resultSet, maxRowCount, sig);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static JdbcResultSet create(String connectionId, int statementId,
+      ResultSet resultSet, long maxRowCount, Meta.Signature signature) {
+    try {
+      final Calendar calendar = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
+      final int fetchRowCount;
+      if (maxRowCount == JdbcMeta.UNLIMITED_COUNT) {
+        fetchRowCount = -1;
+      } else if (maxRowCount < 0L) {
+        fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
+      } else if (maxRowCount > AvaticaStatement.DEFAULT_FETCH_SIZE) {
+        fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
+      } else {
+        fetchRowCount = (int) maxRowCount;
+      }
+      final Meta.Frame firstFrame = frame(null, resultSet, 0, fetchRowCount, calendar);
+      if (firstFrame.done) {
+        resultSet.close();
+      }
+      return new JdbcResultSet(connectionId, statementId, true, signature,
+          firstFrame);
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /** Creates a empty result set with empty frame */
+  public static JdbcResultSet empty(String connectionId, int statementId,
+      Meta.Signature signature) {
+    return new JdbcResultSet(connectionId, statementId, true, signature,
+        Meta.Frame.EMPTY);
+  }
+
+  /** Creates a result set that only has an update count. */
+  public static JdbcResultSet count(String connectionId, int statementId,
+      int updateCount) {
+    return new JdbcResultSet(connectionId, statementId, true, null, null, updateCount);
+  }
+
+  /** Creates a frame containing a given number or unlimited number of rows
+   * from a result set. */
+  static Meta.Frame frame(StatementInfo info, ResultSet resultSet, long offset,
+      int fetchMaxRowCount, Calendar calendar) throws SQLException {
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    final int columnCount = metaData.getColumnCount();
+    final int[] types = new int[columnCount];
+    for (int i = 0; i < types.length; i++) {
+      types[i] = metaData.getColumnType(i + 1);
+    }
+    final List<Object> rows = new ArrayList<>();
+    // Meta prepare/prepareAndExecute 0 return 0 row and done
+    boolean done = fetchMaxRowCount == 0;
+    for (int i = 0; fetchMaxRowCount < 0 || i < fetchMaxRowCount; i++) {
+      final boolean hasRow;
+      if (null != info) {
+        hasRow = info.next();
+      } else {
+        hasRow = resultSet.next();
+      }
+      if (!hasRow) {
+        done = true;
+        resultSet.close();
+        break;
+      }
+      Object[] columns = new Object[columnCount];
+      for (int j = 0; j < columnCount; j++) {
+        columns[j] = getValue(resultSet, types[j], j, calendar);
+      }
+      rows.add(columns);
+    }
+    return new Meta.Frame(offset, done, rows);
+  }
+
+  private static Object getValue(ResultSet resultSet, int type, int j,
+      Calendar calendar) throws SQLException {
+    switch (type) {
+    case Types.BIGINT:
+      final long aLong = resultSet.getLong(j + 1);
+      return aLong == 0 && resultSet.wasNull() ? null : aLong;
+    case Types.INTEGER:
+      final int anInt = resultSet.getInt(j + 1);
+      return anInt == 0 && resultSet.wasNull() ? null : anInt;
+    case Types.SMALLINT:
+      final short aShort = resultSet.getShort(j + 1);
+      return aShort == 0 && resultSet.wasNull() ? null : aShort;
+    case Types.TINYINT:
+      final byte aByte = resultSet.getByte(j + 1);
+      return aByte == 0 && resultSet.wasNull() ? null : aByte;
+    case Types.DOUBLE:
+    case Types.FLOAT:
+      final double aDouble = resultSet.getDouble(j + 1);
+      return aDouble == 0D && resultSet.wasNull() ? null : aDouble;
+    case Types.REAL:
+      final float aFloat = resultSet.getFloat(j + 1);
+      return aFloat == 0D && resultSet.wasNull() ? null : aFloat;
+    case Types.DATE:
+      final Date aDate = resultSet.getDate(j + 1, calendar);
+      return aDate == null
+          ? null
+          : (int) (aDate.getTime() / DateTimeUtils.MILLIS_PER_DAY);
+    case Types.TIME:
+      final Time aTime = resultSet.getTime(j + 1, calendar);
+      return aTime == null
+          ? null
+          : (int) (aTime.getTime() % DateTimeUtils.MILLIS_PER_DAY);
+    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);
+    }
+  }
+}
+
+// End JdbcResultSet.java