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/05/09 15:37:15 UTC
[1/2] calcite git commit: [CALCITE-1190] Avatica TCK for
cross-version compatibility testing
Repository: calcite
Updated Branches:
refs/heads/master 9deff987b -> 2197f7dc3
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/resources/META-INF/LICENSE b/avatica/tck/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..0720b21
--- /dev/null
+++ b/avatica/tck/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,251 @@
+
+ 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 AVATICA SUBCOMPONENTS:
+
+The Apache Calcite Avatica 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 HSQLDB, which is available
+under the following "3-clause BSD" license:
+
+ Copyright (c) 2001-2016, The HSQL Development Group
+ 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 the HSQL Development Group 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 HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ 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.
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/resources/example_config.yml
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/resources/example_config.yml b/avatica/tck/src/main/resources/example_config.yml
new file mode 100644
index 0000000..b6b255e
--- /dev/null
+++ b/avatica/tck/src/main/resources/example_config.yml
@@ -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.
+---
+# https://repository.apache.org/content/repositories/snapshots/org/apache/calcite/avatica/avatica-tck/1.8.0-SNAPSHOT
+tck_jar: /home/user/avatica-tck-1.8.0-SNAPSHOT-shaded.jar
+
+# Global template, can be overriden in each version. <url> is automatically replaced by the framework
+client_url_template: jdbc:avatica:remote;url=<url>;serialization=PROTOBUF
+
+# Specifies all versions to be tested against one another
+versions:
+ # The user _must_ fill in the port number for the Avatica server for each version
+ v1.6.0:
+ # https://repository.apache.org/content/repositories/releases/org/apache/calcite/calcite-avatica/1.6.0/calcite-avatica-1.6.0.jar
+ client_jar: /home/user/calcite-avatica-1.6.0.jar
+ server_url: http://localhost:XXXXX
+
+ v1.7.1:
+ # https://repository.apache.org/content/repositories/releases/org/apache/calcite/avatica/avatica/1.7.1/avatica-1.7.1.jar
+ client_jar: /home/user/avatica-1.7.1.jar
+ server_url: http://localhost:XXXXX
+
+ v1.8.0-SNAPSHOT:
+ # https://repository.apache.org/content/repositories/snapshots/org/apache/calcite/avatica/avatica/1.8.0-SNAPSHOT/
+ client_jar: /home/user/avatica-1.8.0-SNAPSHOT.jar
+ server_url: http://localhost:XXXXX
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/resources/log4j.properties b/avatica/tck/src/main/resources/log4j.properties
new file mode 100644
index 0000000..68a9cc2
--- /dev/null
+++ b/avatica/tck/src/main/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.calcite.avatica.tck.shaded.org.apache.log4j.ConsoleAppender
+
+# Set the pattern for each log message
+log4j.appender.A1.layout=org.apache.calcite.avatica.tck.shaded.org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c{2} - %m%n
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/ruby/test_runner.rb
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/ruby/test_runner.rb b/avatica/tck/src/main/ruby/test_runner.rb
new file mode 100755
index 0000000..e0b9d73
--- /dev/null
+++ b/avatica/tck/src/main/ruby/test_runner.rb
@@ -0,0 +1,125 @@
+#!/usr/bin/env ruby
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 'logger'
+require 'yaml'
+
+PASSED = "\033[32mPassed\033[0m"
+FAILED = "\033[31mFailed\033[0m"
+
+VERSIONS_KEY = 'versions'
+CLIENT_JAR_KEY = 'client_jar'
+SERVER_URL_KEY = 'server_url'
+CLIENT_URL_TEMPLATE_KEY = 'client_url_template'
+
+TCK_JAR_KEY = 'tck_jar'
+
+# Special key for the client URL template to substitute the server's url
+URL_REPLACEMENT_HOLDER = '<url>'
+
+LOG = Logger.new(STDOUT)
+LOG.level = Logger::WARN
+
+
+def usage()
+ puts "usage: test_runner.rb configuration.yml"
+end
+
+def run_test(tck_jar, client, server)
+ client_jar = client[:config][CLIENT_JAR_KEY]
+ client_url = client[:config][CLIENT_URL_TEMPLATE_KEY]
+ server_url = server[:config][SERVER_URL_KEY]
+
+ puts "\nRunning #{client[:name]} against #{server[:name]}"
+
+ if server_url.end_with? 'X'
+ LOG.error("Fill in the port for server version '#{server_url}' in the YAML configuration file")
+ return false
+ end
+
+ # Make a copy here to be sure to not affect other tests
+ LOG.debug("Updating server url #{server_url} in #{client_url}")
+ client_url = client_url.gsub(URL_REPLACEMENT_HOLDER, server_url)
+
+ cmd = "java -cp '#{tck_jar}:#{client_jar}' org.apache.calcite.avatica.tck.TestRunner -u '#{client_url}'"
+ puts "Java command: '#{cmd}'"
+ success = system(cmd)
+
+ puts "Test of #{client[:name]} against #{server[:name]} " + (success ? PASSED : FAILED)
+ return success
+end
+
+unless ARGV.size == 1
+ usage()
+ raise ArgumentError.new('YAML configuration file is required as the only argument')
+end
+
+# Parse the configuration file
+config_file = ARGV[0]
+config = YAML.load_file(config_file)
+
+# The Avatica TCK jar
+tck_jar = config[TCK_JAR_KEY]
+if tck_jar.nil?
+ raise "Configuration file does not contain '#{TCK_JAR_KEY}' key"
+end
+
+# A client url template specified globally, can be overriden in the version
+global_url_template = config[CLIENT_URL_TEMPLATE_KEY]
+
+# Map of version name to jar/configuration
+all_versions = config[VERSIONS_KEY]
+if all_versions.nil?
+ raise "Configuration file does not contain '#{VERSIONS_KEY}' key"
+end
+
+# Push down the global client url template to each version when applicable
+all_versions.each do |version|
+ if version.length != 2
+ LOG.warn("Unexpected number of arguments for version: #{version.to_s}")
+ end
+ version_config = version[1]
+ if version_config[CLIENT_URL_TEMPLATE_KEY].nil? and not global_url_template.nil?
+ version_config[CLIENT_URL_TEMPLATE_KEY] = global_url_template
+ end
+end
+
+# Convert from a hash to an array of pairs
+all_versions = all_versions.collect{ |k,v| {:name=>k, :config=>v} }
+
+# Compute the "identity" mapping as a sanity check
+identity_versions = all_versions.collect {|x| [x, x]}
+
+# Create a cartesian product of the pairs, dropping entries where the pairs are equal
+all_pairs = all_versions.product(all_versions).select {|x| x[0][:name] != x[1][:name]}
+
+puts "Running identity test as a sanity check (client and server at the same version)"
+
+identity_outcomes = identity_versions.collect{|pair| {:client => pair[0][:name], :server=>pair[1][:name], :result=>run_test(tck_jar, pair[0], pair[1])}}
+
+puts "\nRunning cross-version tests"
+
+# Run the TCK against each pair
+outcomes = all_pairs.collect{|pair| {:client=>pair[0][:name], :server=>pair[1][:name], :result=>run_test(tck_jar, pair[0], pair[1])}}
+
+puts "\n-------------------------------------\nSummary:\n\n"
+
+puts "Identity test scenarios (ran #{identity_outcomes.size})\n\n"
+identity_outcomes.each{|outcome| puts "Testing identity for version #{outcome[:client]}: #{(outcome[:result] ? PASSED : FAILED)}"}
+
+puts "\nAll test scenarios (ran #{all_pairs.size})\n\n"
+outcomes.each{|outcome| puts "Testing client #{outcome[:client]} against server #{outcome[:server]}: #{(outcome[:result] ? PASSED : FAILED)}"}
[2/2] calcite git commit: [CALCITE-1190] Avatica TCK for
cross-version compatibility testing
Posted by el...@apache.org.
[CALCITE-1190] Avatica TCK for cross-version compatibility testing
Also includes a standalone Avatica server implementation which
uses HSQLDB to simplify testing. README and site updated with
more information about compatibility and the TCK.
Closes apache/calcite#227
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/2197f7dc
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/2197f7dc
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/2197f7dc
Branch: refs/heads/master
Commit: 2197f7dc34035f63c50b12eeebf4758d44e09c43
Parents: 9deff98
Author: Josh Elser <el...@apache.org>
Authored: Mon May 9 11:24:46 2016 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Mon May 9 11:30:15 2016 -0400
----------------------------------------------------------------------
avatica/pom.xml | 13 +
avatica/site/_data/docs.yml | 1 +
avatica/site/_docs/compatibility.md | 105 +++++++
avatica/standalone-server/.gitignore | 1 +
avatica/standalone-server/pom.xml | 195 +++++++++++++
.../calcite/avatica/hsqldb/HsqldbServer.java | 134 +++++++++
.../calcite/avatica/hsqldb/package-info.java | 26 ++
.../src/main/resources/META-INF/LICENSE | 251 +++++++++++++++++
.../resources/META-INF/services/java.sql.Driver | 1 +
.../src/main/resources/log4j.properties | 24 ++
avatica/tck/.gitignore | 1 +
avatica/tck/README.md | 80 ++++++
avatica/tck/pom.xml | 223 +++++++++++++++
.../calcite/avatica/tck/PackageMarker.java | 37 +++
.../apache/calcite/avatica/tck/TestRunner.java | 274 +++++++++++++++++++
.../calcite/avatica/tck/package-info.java | 24 ++
.../calcite/avatica/tck/tests/BaseTckTest.java | 56 ++++
.../calcite/avatica/tck/tests/InsertTest.java | 213 ++++++++++++++
.../calcite/avatica/tck/tests/MetadataTest.java | 132 +++++++++
.../calcite/avatica/tck/tests/package-info.java | 26 ++
avatica/tck/src/main/resources/META-INF/LICENSE | 251 +++++++++++++++++
.../tck/src/main/resources/example_config.yml | 38 +++
avatica/tck/src/main/resources/log4j.properties | 24 ++
avatica/tck/src/main/ruby/test_runner.rb | 125 +++++++++
24 files changed, 2255 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/pom.xml b/avatica/pom.xml
index 64719db..e258476 100644
--- a/avatica/pom.xml
+++ b/avatica/pom.xml
@@ -76,6 +76,7 @@ limitations under the License.
<hydromatic-toolbox.version>0.3</hydromatic-toolbox.version>
<jackson.version>2.6.3</jackson.version>
<jcip-annotations.version>1.0-1</jcip-annotations.version>
+ <jcommander.version>1.48</jcommander.version>
<jetty.version>9.2.15.v20160210</jetty.version>
<junit.version>4.12</junit.version>
<kerby.version>1.0.0-RC2</kerby.version>
@@ -112,6 +113,8 @@ limitations under the License.
<module>metrics-dropwizardmetrics3</module>
<module>noop-driver</module>
<module>server</module>
+ <module>tck</module>
+ <module>standalone-server</module>
</modules>
<!-- No dependencies here. Declare dependency VERSIONS in
@@ -139,6 +142,11 @@ limitations under the License.
</dependency>
<dependency>
<groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-tck</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
<artifactId>avatica-server</artifactId>
<version>${project.version}</version>
</dependency>
@@ -151,6 +159,11 @@ limitations under the License.
<!-- Now third-party dependencies, sorted by groupId and artifactId. -->
<dependency>
+ <groupId>com.beust</groupId>
+ <artifactId>jcommander</artifactId>
+ <version>${jcommander.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/site/_data/docs.yml
----------------------------------------------------------------------
diff --git a/avatica/site/_data/docs.yml b/avatica/site/_data/docs.yml
index 787588d..4b63d20 100644
--- a/avatica/site/_data/docs.yml
+++ b/avatica/site/_data/docs.yml
@@ -27,6 +27,7 @@
- protobuf_reference
- howto
- security
+ - compatibility
- title: Meta
docs:
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/site/_docs/compatibility.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/compatibility.md b/avatica/site/_docs/compatibility.md
new file mode 100644
index 0000000..18ae3a6
--- /dev/null
+++ b/avatica/site/_docs/compatibility.md
@@ -0,0 +1,105 @@
+---
+layout: docs
+title: Compatibility
+sidebar_title: Compatibility
+permalink: /docs/compatibility.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 %}
+-->
+
+Given Avatica's client-server model, it is no surprise that compatibility is
+important to the users and developers of Apache Calcite Avatica. This document
+defines what guarantees are made by Avatica with respect to compatibility
+between Avatica client and server across versions. This document is still a work
+in progress with many areas still requiring definition. Contributions are always
+welcome.
+
+## Avatica Technology Compatibility Kit (TCK)
+
+The [Avatica TCK project][github-tck] is a framework designed to automatically
+test an Avatica client against an Avatica server. A collection of JUnit tests,
+a YAML configuration file, and a Ruby script defines the TCK.
+The JUnit tests invoke specific portions of both the client and
+server components of Avatica to verify that they work as expected. The Ruby
+script uses the YAML configuration file to define the set of
+client and server version pairs to run the JUnit tests against.
+
+In the YAML configuration file, a name (e.g. `1.6.0`) and the following three
+items define an Avatica version:
+
+1. A filesystem path to an Avatica client jar (e.g. groupId=org.apache.calcite.avatica, artifactId=avatica)
+2. A URL to a running instance of an Avatica server
+3. A JDBC URL template to the Avatica server for the Avatica client JDBC driver.
+
+Users of the TCK define the collection of versions (defined by the above
+information) and the location of the [avatica-tck][github-tck] jar by a YAML
+configuration file. An [example YAML configuration file][github-tck-yml-file] is
+bundled with the project.
+
+Traditionally, Avatica does not provide any implementation of the Avatica server
+as the value in Avatica is recognized in the integrating project (e.g. Apache
+Drill or Apache Phoenix). However, for the purposes of compatibility testing, it
+makes sense that Avatica provides a standalone server instance. A new artifact
+is introduced to Avatica with the original TCK codebase called
+[avatica-standalone-server][github-standalone-server]. This artifact is a
+runnable jar (e.g. `java -jar`) which starts an instance of the Avatica server
+on a random port using the in-memory [HSQLDB database](http://hsqldb.org/). This
+artifacts makes it extremely simple to start a version of the Avatica server for
+the specific version of Avatica to be tested.
+
+As mentioned, the Ruby script is the entry point for the TCK. Invoking the Ruby
+script which prints a summary of testing each specified version against itself and
+all other versions in the YAML configuration. An example summary is presented
+below which is the result of testing versions 1.6.0, 1.7.1 and 1.8.0-SNAPSHOT:
+
+```
+Summary:
+
+Identity test scenarios (ran 3)
+
+Testing identity for version v1.6.0: Passed
+Testing identity for version v1.7.1: Passed
+Testing identity for version v1.8.0-SNAPSHOT: Failed
+
+All test scenarios (ran 6)
+
+Testing client v1.6.0 against server v1.7.1: Passed
+Testing client v1.6.0 against server v1.8.0-SNAPSHOT: Failed
+Testing client v1.7.1 against server v1.6.0: Passed
+Testing client v1.7.1 against server v1.8.0-SNAPSHOT: Failed
+Testing client v1.8.0-SNAPSHOT against server v1.6.0: Failed
+Testing client v1.8.0-SNAPSHOT against server v1.7.1: Failed
+```
+
+It is not always expected that all tested version-pairs will pass unless the
+test is written with specific knowledge about past bugs in Avatica itself. While
+Avatica tries to handle all of these edge cases implicitly, it is not always
+feasible or desirable to do so. Adding new test cases is as easy as writing a
+JUnit test case in the [TCK module][github-tck-tests], but there is presently no
+automation around verifying the test cases as a part of the Maven build.
+
+For more information on running this TCK, including specific instructions for
+running the TCK, reference the provided [README][github-tck-readme] file.
+
+[github-tck]: https://github.com/apache/calcite/tree/master/avatica/tck
+[github-tck-tests]: https://github.com/apache/calcite/tree/master/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests
+[github-standalone-server]: https://github.com/apache/calcite/tree/master/avatica/standalone-server
+[github-tck-readme]: https://github.com/apache/calcite/tree/master/avatica/tck/README.md
+[github-tck-yml-file]: https://github.com/apache/calcite/tree/master/avatica/tck/src/main/resources/example_config.yml
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/.gitignore
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/.gitignore b/avatica/standalone-server/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/avatica/standalone-server/.gitignore
@@ -0,0 +1 @@
+/target/
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/pom.xml b/avatica/standalone-server/pom.xml
new file mode 100644
index 0000000..5a11086
--- /dev/null
+++ b/avatica/standalone-server/pom.xml
@@ -0,0 +1,195 @@
+<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>avatica-parent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>avatica-standalone-server</artifactId>
+ <name>Avatica Standalone Server</name>
+ <description>A Stadnalone Avatica Server Implementation</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.avatica</groupId>
+ <artifactId>avatica</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.beust</groupId>
+ <artifactId>jcommander</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>scott-data-hsqldb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </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-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>net.hydromatic:scott-data-hsqldb</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.hsqldb:hsqldb</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
+ </ignoredUnusedDeclaredDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- Create a standalone JAR capable of running the server -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <artifactSet>
+ <excludes>
+ <exclude>com.google.protobuf:protobuf-java</exclude>
+ <exclude>org.apache.httpcomponents:*</exclude>
+ <exclude>commons-codec:commons-codec</exclude>
+ </excludes>
+ </artifactSet>
+ <createDependencyReducedPom>false</createDependencyReducedPom>
+ <relocations>
+ <relocation>
+ <pattern>com.beust</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.com.beust</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>com.fasterxml</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.com.fasterxml</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>com.google.common</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.com.google.common</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>javax.servlet</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.javax.servlet</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>net.hydromatic</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.net.hydromatic</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.apache.log4j</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.org.apache.log4j</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.eclipse.jetty</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.org.eclipse.jetty</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.hsqldb</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.org.hsqldb</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.slf4j</pattern>
+ <shadedPattern>org.apache.calcite.avatica.hsqldb.shaded.org.slf4j</shadedPattern>
+ </relocation>
+ </relocations>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <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>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.calcite.avatica.hsqldb.HsqldbServer</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/HsqldbServer.java
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/HsqldbServer.java b/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/HsqldbServer.java
new file mode 100644
index 0000000..dbd632c
--- /dev/null
+++ b/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/HsqldbServer.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.hsqldb;
+
+import org.apache.calcite.avatica.jdbc.JdbcMeta;
+import org.apache.calcite.avatica.remote.Driver.Serialization;
+import org.apache.calcite.avatica.remote.LocalService;
+import org.apache.calcite.avatica.server.HttpServer;
+
+import com.beust.jcommander.IStringConverter;
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+
+import net.hydromatic.scott.data.hsqldb.ScottHsqldb;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An Avatica server for HSQLDB.
+ */
+public class HsqldbServer {
+ private static final Logger LOG = LoggerFactory.getLogger(HsqldbServer.class);
+
+ @Parameter(names = { "-p", "--port" }, required = false,
+ description = "Port the server should bind")
+ private int port = 0;
+
+ @Parameter(names = { "-s", "--serialization" }, required = false,
+ description = "Serialization method to use", converter = SerializationConverter.class)
+ private Serialization serialization = Serialization.PROTOBUF;
+
+ private HttpServer server;
+
+ public void start() {
+ if (null != server) {
+ LOG.error("The server was already started");
+ System.exit(ExitCodes.ALREADY_STARTED.ordinal());
+ return;
+ }
+
+ try {
+ // Set up Julian's ScottDB for HSQLDB
+ JdbcMeta meta = new JdbcMeta(ScottHsqldb.URI, ScottHsqldb.USER, ScottHsqldb.PASSWORD);
+ LocalService service = new LocalService(meta);
+
+ // Construct the server
+ this.server = new HttpServer.Builder()
+ .withHandler(service, serialization)
+ .withPort(port)
+ .build();
+
+ // Then start it
+ server.start();
+
+ LOG.info("Started Avatica server on port {} with serialization {}", server.getPort(),
+ serialization);
+ } catch (Exception e) {
+ LOG.error("Failed to start Avatica server", e);
+ System.exit(ExitCodes.START_FAILED.ordinal());
+ }
+ }
+
+ public void stop() {
+ if (null != server) {
+ server.stop();
+ server = null;
+ }
+ }
+
+ public void join() throws InterruptedException {
+ server.join();
+ }
+
+ public static void main(String[] args) {
+ final HsqldbServer server = new HsqldbServer();
+ new JCommander(server, args);
+
+ server.start();
+
+ // Try to clean up when the server is stopped.
+ Runtime.getRuntime().addShutdownHook(
+ new Thread(new Runnable() {
+ @Override public void run() {
+ LOG.info("Stopping server");
+ server.stop();
+ LOG.info("Server stopped");
+ }
+ }));
+
+ try {
+ server.join();
+ } catch (InterruptedException e) {
+ // Reset interruption
+ Thread.currentThread().interrupt();
+ // And exit now.
+ return;
+ }
+ }
+
+ /**
+ * Converter from String to Serialization.
+ */
+ private static class SerializationConverter implements IStringConverter<Serialization> {
+ @Override public Serialization convert(String value) {
+ return Serialization.valueOf(value.toUpperCase());
+ }
+ }
+
+ /**
+ * Codes for exit conditions
+ */
+ private enum ExitCodes {
+ NORMAL,
+ ALREADY_STARTED, // 1
+ START_FAILED; // 2
+ }
+}
+
+// End HsqldbServer.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/package-info.java b/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/package-info.java
new file mode 100644
index 0000000..da97815
--- /dev/null
+++ b/avatica/standalone-server/src/main/java/org/apache/calcite/avatica/hsqldb/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 for HSQLDB.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.hsqldb;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/src/main/resources/META-INF/LICENSE b/avatica/standalone-server/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..0720b21
--- /dev/null
+++ b/avatica/standalone-server/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,251 @@
+
+ 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 AVATICA SUBCOMPONENTS:
+
+The Apache Calcite Avatica 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 HSQLDB, which is available
+under the following "3-clause BSD" license:
+
+ Copyright (c) 2001-2016, The HSQL Development Group
+ 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 the HSQL Development Group 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 HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ 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.
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/src/main/resources/META-INF/services/java.sql.Driver
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/src/main/resources/META-INF/services/java.sql.Driver b/avatica/standalone-server/src/main/resources/META-INF/services/java.sql.Driver
new file mode 100644
index 0000000..7b95c3f
--- /dev/null
+++ b/avatica/standalone-server/src/main/resources/META-INF/services/java.sql.Driver
@@ -0,0 +1 @@
+org.apache.calcite.avatica.hsqldb.shaded.org.hsqldb.jdbcDriver
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/standalone-server/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/avatica/standalone-server/src/main/resources/log4j.properties b/avatica/standalone-server/src/main/resources/log4j.properties
new file mode 100644
index 0000000..bc1bda9
--- /dev/null
+++ b/avatica/standalone-server/src/main/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.calcite.avatica.hsqldb.shaded.org.apache.log4j.ConsoleAppender
+
+# Set the pattern for each log message
+log4j.appender.A1.layout=org.apache.calcite.avatica.hsqldb.shaded.org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c{2} - %m%n
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/.gitignore
----------------------------------------------------------------------
diff --git a/avatica/tck/.gitignore b/avatica/tck/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/avatica/tck/.gitignore
@@ -0,0 +1 @@
+/target/
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/README.md
----------------------------------------------------------------------
diff --git a/avatica/tck/README.md b/avatica/tck/README.md
new file mode 100644
index 0000000..d8025ef
--- /dev/null
+++ b/avatica/tck/README.md
@@ -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.
+-->
+
+# Apache Calcite Avatica Technology Compatibility Kit (TCK)
+
+The Avatica TCK is a framework to test the compatibilty between
+various versions of Avatica clients and servers.
+
+The TCK is configured by a YAML file which specifies a TCK framework
+jar and a list of Avatica client and server versions. Each version
+must specify the path to a client jar, the URL of the server for
+that version, and a template for the JDBC url.
+
+An example YAML configuration file is provided ([example_config.yml][example-config-yml])
+which can be used as a starting point for users to fill out. Most elements are
+straightforward to understand; however, it does require that you provide a URL
+to a running Avatica server for each version to be tested.
+
+## Running a standalone Avatica server
+
+To make it easy to run a standalone Avatica server, an instance of the Avatica
+server running against an in-memory SQL database (HSQLDB) is provided starting
+in version 1.8.0. The `avatica-hsqldb-server-1.8.0-SNAPSHOT-shaded.jar` artifact
+can be used to start an Avatica server on a random port (printed to the console).
+
+ `java -jar avatica-hsqldb-server-1.8.0-SNAPSHOT-shaded.jar`
+
+For convenience in testing against earlier versions of Avatica, the following
+repository can be used to simplify building the same instance of a standalone
+HSQLDB-backed Avatica server https://github.com/joshelser/legacy-avatica-hsqldb-server
+
+Follow the instructions in the [README][legacy-readme] to build a standalone jar
+against a specific version of Calcite/Avatica which can be used as specified above.
+
+## Running the TCK
+
+A ruby script, [test_runner.rb][test-runner-script] is provided which consumes the modified YAML configuration
+file. This script will first run each provided version against itself as a sanity
+check for the tests itself (as the scope of what is implemented in Avatica does
+change over time), and then enumerate all possible combinations of client and server
+version.
+
+ `./test_runner.rb my_tck_config.yml`
+
+For example, if versions 1.6.0, 1.7.1 and 1.8.0-SNAPSHOT are defined in the YAML configuration
+file, the following identity tests will be run from client to server:
+
+* 1.6.0 to 1.6.0
+* 1.7.1 to 1.7.1
+* 1.8.0-SNAPSHOT to 1.8.0-SNAPSHOT
+
+while the following tests will be run for cross-version compatibility:
+
+* 1.6.0 to 1.7.1
+* 1.6.0 to 1.8.0-SNAPSHOT
+* 1.7.1 to 1.6.0
+* 1.7.1 to 1.8.0-SNAPSHOT
+* 1.8.0-SNAPSHOT to 1.6.0
+* 1.8.0-SNAPSHOT to 1.7.1
+
+Any errors encountered will be printed to the terminal. The final output of the script
+will be a summary of both the identity tests and the cross-version tests for easy consumption.
+
+[example-config-yml]: https://github.com/apache/calcite/tree/master/avatica/tck/src/main/resources/example_config.yml
+[legacy-readme]: https://github.com/joshelser/legacy-avatica-hsqldb-server/blob/master/README.md
+[test-runner-script]: https://github.com/apache/calcite/tree/master/avatica/tck/src/main/ruby/test_runner.rb
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/tck/pom.xml b/avatica/tck/pom.xml
new file mode 100644
index 0000000..0ddf1de
--- /dev/null
+++ b/avatica/tck/pom.xml
@@ -0,0 +1,223 @@
+<?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>avatica-parent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>avatica-tck</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Calcite Avatica Compatibility Kit</name>
+ <description>Library for testing compatibility of Avatica across versions.</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>com.beust</groupId>
+ <artifactId>jcommander</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ </dependency>
+ <!-- As long as we want to run compatibility checks again 1.6.0, we have to include these because
+ they weren't yet provided by the avatica client jar -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </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>
+ <!-- Create a standalone JAR capable of running the server -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <artifactSet>
+ <excludes>
+ <exclude>com.google.protobuf:protobuf-java</exclude>
+ <exclude>org.apache.httpcomponents:*</exclude>
+ <exclude>commons-codec:commons-codec</exclude>
+ </excludes>
+ </artifactSet>
+ <createDependencyReducedPom>false</createDependencyReducedPom>
+ <relocations>
+ <relocation>
+ <pattern>com.beust</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.com.beust</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>com.fasterxml</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.com.fasterxml</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>com.google.common</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.com.google.common</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>javax.servlet</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.javax.servlet</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>junit</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.junit</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>net.hydromatic</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.net.hydromatic</shadedPattern>
+ </relocation>
+ <!-- We bundle a log4j.properties file which will be looking in this relocated location -->
+ <relocation>
+ <pattern>org.apache.log4j</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.org.apache.log4j</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.eclipse.jetty</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.org.eclipse.jetty</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.hamcrest</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.org.hamcrest</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.hsqldb</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.org.hsqldb</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>org.junit</pattern>
+ <shadedPattern>org.apache.calcite.avatica.tck.shaded.org.junit</shadedPattern>
+ </relocation>
+ <!-- Intentionally not shading slf4j as it would break -->
+ </relocations>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <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>
+ <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.hamcrest:hamcrest-core</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.hsqldb:hsqldb</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
+ </ignoredUnusedDeclaredDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/PackageMarker.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/PackageMarker.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/PackageMarker.java
new file mode 100644
index 0000000..cb64e93
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/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.tck;
+
+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/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/TestRunner.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/TestRunner.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/TestRunner.java
new file mode 100644
index 0000000..9ada4a4
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/TestRunner.java
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.avatica.tck;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.ClassPath;
+import com.google.common.reflect.ClassPath.ClassInfo;
+
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Modifier;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Entry point for running an Avatica cross-version compatibility test.
+ */
+public class TestRunner implements Runnable {
+ private static final Logger LOG = LoggerFactory.getLogger(TestRunner.class);
+ private static final String ANSI_RESET = "\u001B[0m";
+ private static final String ANSI_RED = "\u001B[31m";
+ private static final String ANSI_GREEN = "\u001B[32m";
+
+ private static Driver driver;
+ private static String driverUrl;
+
+ @Parameter(names = { "-u", "--jdbcUrl" }, description = "JDBC URL for Avatica Driver")
+ private String jdbcUrl;
+
+ private JUnitCore junitCore;
+
+ /**
+ * Returns the {@link Connection} for tests to use.
+ *
+ * @return A JDBC Connection.
+ */
+ public static Connection getConnection() throws SQLException {
+ if (null == driver) {
+ throw new IllegalStateException("JDBC Driver is not initialized");
+ }
+
+ return driver.connect(driverUrl, new Properties());
+ }
+
+ @Override public void run() {
+ // Construct the Connection
+ initializeDriver();
+
+ if (null == driver) {
+ LOG.error("Failed to find driver for {}", jdbcUrl);
+ System.exit(TestRunnerExitCodes.NO_SUCH_DRIVER.ordinal());
+ return;
+ }
+
+ // Initialize JUnit
+ initializeJUnit();
+
+ // Enumerate available test cases
+ final List<Class<?>> testClasses = getAllTestClasses();
+
+ final TestResults globalResults = new TestResults();
+
+ // Run each test case
+ for (Class<?> testClass : testClasses) {
+ runSingleTest(globalResults, testClass);
+ }
+
+ System.out.println(globalResults.summarize());
+
+ if (globalResults.numFailed > 0) {
+ // Tests failed, don't exit normally
+ System.exit(TestRunnerExitCodes.FAILED_TESTS.ordinal());
+ } else {
+ // Exited normally
+ System.exit(TestRunnerExitCodes.NORMAL.ordinal());
+ }
+ }
+
+ /**
+ * Finds all tests to run for the TCK.
+ *
+ * @return A list of test classes to run.
+ */
+ List<Class<?>> getAllTestClasses() {
+ try {
+ ClassPath cp = ClassPath.from(getClass().getClassLoader());
+ ImmutableSet<ClassInfo> classes =
+ cp.getTopLevelClasses("org.apache.calcite.avatica.tck.tests");
+
+ List<Class<?>> testClasses = new ArrayList<>(classes.size());
+ for (ClassInfo classInfo : classes) {
+ if (classInfo.getSimpleName().equals("package-info")) {
+ continue;
+ }
+ Class<?> clz = Class.forName(classInfo.getName());
+ if (Modifier.isAbstract(clz.getModifiers())) {
+ // Ignore abstract classes
+ continue;
+ }
+ testClasses.add(clz);
+ }
+
+ return testClasses;
+ } catch (Exception e) {
+ LOG.error("Failed to instantiate test classes", e);
+ System.exit(TestRunnerExitCodes.TEST_CASE_INSTANTIATION.ordinal());
+ // Unreachable..
+ return null;
+ }
+ }
+
+ void initializeDriver() {
+ try {
+ // Make sure the Avatica Driver gets loaded
+ Class.forName("org.apache.calcite.avatica.remote.Driver");
+ driverUrl = jdbcUrl;
+ driver = DriverManager.getDriver(driverUrl);
+ } catch (SQLException e) {
+ LOG.error("Could not instantiate JDBC Driver with URL: '{}'", jdbcUrl, e);
+ System.exit(TestRunnerExitCodes.BAD_JDBC_URL.ordinal());
+ } catch (ClassNotFoundException e) {
+ LOG.error("Could not load Avatica Driver class", e);
+ System.exit(TestRunnerExitCodes.MISSING_DRIVER_CLASS.ordinal());
+ }
+ }
+
+ /**
+ * Sets up JUnit to run the tests for us.
+ */
+ void initializeJUnit() {
+ junitCore = new JUnitCore();
+
+ junitCore.addListener(new RunListener() {
+ @Override public void testStarted(Description description) throws Exception {
+ LOG.debug("Starting {}", description);
+ }
+
+ @Override public void testFinished(Description description) throws Exception {
+ LOG.debug("{}Finished {}{}", ANSI_GREEN, description, ANSI_RESET);
+ }
+
+ @Override public void testFailure(Failure failure) throws Exception {
+ LOG.info("{}Failed {}{}", ANSI_RED, failure.getDescription(), ANSI_RESET,
+ failure.getException());
+ }
+ });
+ }
+
+ /**
+ * Runs a single test class, adding its results to <code>globalResults</code>.
+ *
+ * @param globalResults A global record of test results.
+ * @param testClass The test class to run.
+ */
+ void runSingleTest(final TestResults globalResults, final Class<?> testClass) {
+ final String className = Objects.requireNonNull(testClass).getName();
+ LOG.info("{}Running {}{}", ANSI_GREEN, className, ANSI_RESET);
+
+ try {
+ Result result = junitCore.run(testClass);
+ globalResults.merge(testClass, result);
+ } catch (Exception e) {
+ // most likely JUnit issues, like no tests to run
+ LOG.error("{}Test failed: {}{}", ANSI_RED, className, ANSI_RESET, e);
+ }
+ }
+
+ public static void main(String[] args) {
+ TestRunner runner = new TestRunner();
+
+ // Parse the args, sets it on runner.
+ new JCommander(runner, args);
+
+ // Run the tests.
+ runner.run();
+ }
+
+ /**
+ * A container to track results from all tests executed.
+ */
+ private static class TestResults {
+ private int numRun = 0;
+ private int numFailed = 0;
+ private int numIgnored = 0;
+ private List<Failure> failures = new ArrayList<>();
+
+ /**
+ * Updates the current state of <code>this</code> with the <code>result</code>.
+ *
+ * @param testClass The test class executed.
+ * @param result The results of the test class execution.
+ * @return <code>this</code>
+ */
+ public TestResults merge(Class<?> testClass, Result result) {
+ LOG.info("Tests run: {}, Failures: {}, Skipped: {}, Time elapsed: {} - in {}",
+ result.getRunCount(), result.getFailureCount(), result.getIgnoreCount(),
+ TimeUnit.SECONDS.convert(result.getRunTime(), TimeUnit.MILLISECONDS),
+ testClass.getName());
+
+ numRun += result.getRunCount();
+ numFailed += result.getFailureCount();
+ numIgnored += result.getIgnoreCount();
+
+ // Collect the failures
+ if (!result.wasSuccessful()) {
+ failures.addAll(result.getFailures());
+ }
+
+ return this;
+ }
+
+ /**
+ * Constructs a human-readable summary of the success/failure of the tests executed.
+ *
+ * @return A summary in the form of a String.
+ */
+ public String summarize() {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append("\nTest Summary: Run: ").append(numRun).append(", Failed: ").append(numFailed);
+ sb.append(", Skipped: ").append(numIgnored);
+ if (numFailed > 0) {
+ sb.append(ANSI_RED).append("\n\nFailures:").append(ANSI_RESET).append("\n\n");
+ for (Failure failure : failures) {
+ sb.append(failure.getTestHeader()).append(" ").append(failure.getMessage()).append("\n");
+ }
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * ExitCodes set by {@link TestRunner}.
+ */
+ private enum TestRunnerExitCodes {
+ // Position is important, ordinal() is used!
+ NORMAL, // 0, all tests passed
+ BAD_JDBC_URL, // 1
+ TEST_CASE_INSTANTIATION, // 2
+ NO_SUCH_DRIVER, // 3
+ FAILED_TESTS, // 4
+ MISSING_DRIVER_CLASS; // 5
+ }
+}
+
+// End TestRunner.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/package-info.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/package-info.java
new file mode 100644
index 0000000..77c2d16
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/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 compatibility framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.tck;
+
+// End package-info.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/BaseTckTest.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/BaseTckTest.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/BaseTckTest.java
new file mode 100644
index 0000000..8799cf1
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/BaseTckTest.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.tck.tests;
+
+import org.apache.calcite.avatica.tck.TestRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+import java.sql.Connection;
+
+/**
+ * Base class for TCK tests.
+ */
+public abstract class BaseTckTest {
+
+ @Rule public TestName name = new TestName();
+
+ protected Connection connection;
+
+ @Before public void initializeConnection() throws Exception {
+ connection = TestRunner.getConnection();
+ }
+
+ @After public void closeConnection() throws Exception {
+ if (null != connection) {
+ connection.close();
+ }
+ }
+
+ protected Connection getConnection() {
+ return connection;
+ }
+
+ protected String getTableName() {
+ return getClass().getSimpleName() + "_" + name.getMethodName();
+ }
+}
+
+// End BaseTckTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/InsertTest.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/InsertTest.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/InsertTest.java
new file mode 100644
index 0000000..11c44d7
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/InsertTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.avatica.tck.tests;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Statement;
+import java.util.Arrays;
+
+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.assertTrue;
+
+/**
+ * Tests for <code>INSERT</code>.
+ */
+public class InsertTest extends BaseTckTest {
+
+ @Test public void simpleInsert() throws Exception {
+ final String tableName = getTableName();
+ try (Statement stmt = connection.createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName
+ + " (pk integer not null primary key, col1 varchar(10))";
+ assertFalse(stmt.execute(sql));
+
+ for (int i = 0; i < 10; i++) {
+ sql = "INSERT INTO " + tableName + " values (" + i + ", '" + i + "')";
+ assertEquals(1, stmt.executeUpdate(sql));
+ }
+
+ ResultSet results = stmt.executeQuery("SELECT * FROM " + tableName);
+ assertNotNull(results);
+ for (int i = 0; i < 10; i++) {
+ assertTrue(results.next());
+ assertEquals(i, results.getInt(1));
+ assertEquals(Integer.toString(i), results.getString(1));
+ }
+ assertFalse(results.next());
+ results.close();
+ }
+ }
+
+ @Test public void preparedStatementInsert() throws Exception {
+ final String tableName = getTableName();
+ final String insertSql = "INSERT INTO " + tableName + " values(?, ?)";
+ try (Statement stmt = connection.createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName
+ + " (pk integer not null primary key, col1 varchar(10))";
+ assertFalse(stmt.execute(sql));
+
+ try (PreparedStatement pstmt = connection.prepareStatement(insertSql)) {
+ for (int i = 0; i < 10; i++) {
+ pstmt.setInt(1, i);
+ pstmt.setString(2, "a_" + Integer.toString(i));
+ assertEquals(1, pstmt.executeUpdate());
+ }
+ }
+
+ ResultSet results = stmt.executeQuery("SELECT COUNT(pk) from " + tableName);
+ assertNotNull(results);
+ assertTrue(results.next());
+ assertEquals(10, results.getInt(1));
+
+ results = stmt.executeQuery("SELECT * from " + tableName);
+ assertNotNull(results);
+ for (int i = 0; i < 10; i++) {
+ assertTrue(results.next());
+ assertEquals(i, results.getInt(1));
+ assertEquals("a_" + i, results.getString(2));
+ }
+ assertFalse(results.next());
+ results.close();
+ }
+ }
+
+ @Test public void batchInsert() throws Exception {
+ final String tableName = getTableName();
+ try (Statement stmt = connection.createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName
+ + " (pk integer not null primary key, col1 varchar(10))";
+ assertFalse(stmt.execute(sql));
+
+ for (int i = 0; i < 10; i++) {
+ sql = "INSERT INTO " + tableName + " values (" + i + ", '" + i + "')";
+ try {
+ stmt.addBatch(sql);
+ } catch (SQLFeatureNotSupportedException e) {
+ // batch isn't supported in this version, gracefully ignore,
+ Assume.assumeTrue("Batch update is not support by the client", false);
+ }
+ }
+
+ int[] updateCounts = stmt.executeBatch();
+ int[] expectedUpdateCounts = new int[10];
+ Arrays.fill(expectedUpdateCounts, 1);
+ assertArrayEquals(expectedUpdateCounts, updateCounts);
+
+ ResultSet results = stmt.executeQuery("SELECT * FROM " + tableName);
+ assertNotNull(results);
+ for (int i = 0; i < 10; i++) {
+ assertTrue(results.next());
+ assertEquals(i, results.getInt(1));
+ assertEquals(Integer.toString(i), results.getString(1));
+ }
+ assertFalse(results.next());
+ results.close();
+ }
+ }
+
+ @Test public void preparedBatchInsert() throws Exception {
+ final String tableName = getTableName();
+ final String insertSql = "INSERT INTO " + tableName + " values(?, ?)";
+ try (Statement stmt = connection.createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName
+ + " (pk integer not null primary key, col1 varchar(10))";
+ assertFalse(stmt.execute(sql));
+
+ try (PreparedStatement pstmt = connection.prepareStatement(insertSql)) {
+ for (int i = 0; i < 10; i++) {
+ pstmt.setInt(1, i);
+ pstmt.setString(2, "a_" + Integer.toString(i));
+ try {
+ pstmt.addBatch();
+ } catch (SQLFeatureNotSupportedException e) {
+ // batch isn't supported in this version, gracefully ignore,
+ Assume.assumeTrue("Batch update is not support by the client", false);
+ }
+ }
+
+ int[] updateCounts = pstmt.executeBatch();
+ int[] expectedUpdateCounts = new int[10];
+ Arrays.fill(expectedUpdateCounts, 1);
+ assertArrayEquals(expectedUpdateCounts, updateCounts);
+ }
+
+ ResultSet results = stmt.executeQuery("SELECT COUNT(pk) from " + tableName);
+ assertNotNull(results);
+ assertTrue(results.next());
+ assertEquals(10, results.getInt(1));
+
+ results = stmt.executeQuery("SELECT * from " + tableName);
+ assertNotNull(results);
+ for (int i = 0; i < 10; i++) {
+ assertTrue(results.next());
+ assertEquals(i, results.getInt(1));
+ assertEquals("a_" + i, results.getString(2));
+ }
+ assertFalse(results.next());
+ results.close();
+ }
+ }
+
+ @Test public void commitAndRollback() throws Exception {
+ final String tableName = getTableName();
+
+ // Disable autoCommit
+ connection.setAutoCommit(false);
+ assertFalse(connection.getAutoCommit());
+
+ try (Statement stmt = connection.createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName
+ + " (pk integer not null primary key, col1 varchar(10))";
+ assertFalse(stmt.execute(sql));
+
+ for (int i = 0; i < 10; i++) {
+ sql = "INSERT INTO " + tableName + " values (" + i + ", '" + i + "')";
+ assertEquals(1, stmt.executeUpdate(sql));
+ if (i == 4) {
+ // Rollback after the first 5 updates
+ connection.rollback();
+ }
+ }
+ connection.commit();
+
+ ResultSet results = stmt.executeQuery("SELECT * FROM " + tableName);
+ assertNotNull(results);
+ for (int i = 5; i < 10; i++) {
+ assertTrue(results.next());
+ assertEquals(i, results.getInt(1));
+ assertEquals(Integer.toString(i), results.getString(1));
+ }
+ assertFalse(results.next());
+ results.close();
+ }
+ }
+}
+
+// End InsertTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/MetadataTest.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/MetadataTest.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/MetadataTest.java
new file mode 100644
index 0000000..9c92ec0
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/MetadataTest.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.tck.tests;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Statement;
+import java.sql.Types;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for metadata operations (parameter, resultset).
+ */
+public class MetadataTest extends BaseTckTest {
+
+ @Test public void parameterMetadata() throws Exception {
+ final String tableName = getTableName();
+ try (Statement stmt = getConnection().createStatement()) {
+ assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
+ String sql = "CREATE TABLE " + tableName + " (pk integer not null primary key, "
+ + "col1 DECIMAL(10, 5), col2 boolean not null)";
+ assertFalse(stmt.execute(sql));
+
+ String insertSql = "INSERT INTO " + tableName + " values(?, ?, ?)";
+ try (PreparedStatement pstmt = getConnection().prepareStatement(insertSql)) {
+ ParameterMetaData params = pstmt.getParameterMetaData();
+ assertEquals(3, params.getParameterCount());
+
+ assertEquals(Types.INTEGER, params.getParameterType(1));
+ assertTrue(params.isSigned(1));
+ assertTrue(ParameterMetaData.parameterNoNulls == params.isNullable(1)
+ || ParameterMetaData.parameterNullableUnknown == params.isNullable(1));
+
+ assertEquals(Types.DECIMAL, params.getParameterType(2));
+ assertTrue(params.isSigned(2));
+ assertTrue(ParameterMetaData.parameterNullable == params.isNullable(2)
+ || ParameterMetaData.parameterNullableUnknown == params.isNullable(2));
+ assertEquals(10, params.getPrecision(2));
+ assertEquals(5, params.getScale(2));
+
+ assertEquals(Types.BOOLEAN, params.getParameterType(3));
+ assertFalse(params.isSigned(3));
+ assertTrue(ParameterMetaData.parameterNoNulls == params.isNullable(3)
+ || ParameterMetaData.parameterNullableUnknown == params.isNullable(3));
+
+ // CALCITE-1103 <1.8.0 server mishandled the protobuf translation from BIG_DECIMAL to NUMBER
+ pstmt.setInt(1, Integer.MAX_VALUE);
+ pstmt.setBigDecimal(2, new BigDecimal("12345.12345"));
+ pstmt.setBoolean(3, true);
+ assertEquals(1, pstmt.executeUpdate());
+
+ pstmt.setInt(1, Integer.MIN_VALUE);
+ pstmt.setBigDecimal(2, new BigDecimal("54321.54321"));
+ pstmt.setBoolean(3, false);
+ assertEquals(1, pstmt.executeUpdate());
+ }
+
+ ResultSet results = stmt.executeQuery("SELECT * FROM " + tableName + " ORDER BY pk");
+ assertNotNull(results);
+ ResultSetMetaData resultMetadata = results.getMetaData();
+ // Verify result metadata
+ assertEquals(3, resultMetadata.getColumnCount());
+
+ assertTrue(ParameterMetaData.parameterNoNulls == resultMetadata.isNullable(1)
+ || ParameterMetaData.parameterNullableUnknown == resultMetadata.isNullable(1));
+ assertEquals(Types.INTEGER, resultMetadata.getColumnType(1));
+ assertTrue(resultMetadata.isSigned(1));
+
+ assertTrue(ParameterMetaData.parameterNullable == resultMetadata.isNullable(2)
+ || ParameterMetaData.parameterNullableUnknown == resultMetadata.isNullable(2));
+ assertEquals(Types.DECIMAL, resultMetadata.getColumnType(2));
+ assertTrue(resultMetadata.isSigned(2));
+ assertEquals(10, resultMetadata.getPrecision(2));
+ assertEquals(5, resultMetadata.getScale(2));
+
+ assertTrue(ParameterMetaData.parameterNoNulls == resultMetadata.isNullable(3)
+ || ParameterMetaData.parameterNullableUnknown == resultMetadata.isNullable(3));
+ assertEquals(Types.BOOLEAN, resultMetadata.getColumnType(3));
+ assertFalse(resultMetadata.isSigned(3));
+
+ // Verify the results
+ assertTrue(results.next());
+ assertEquals(Integer.MIN_VALUE, results.getInt(1));
+ // CALCITE-1103 protobuf truncated decimal value
+ BigDecimal buggyDecimalValue = new BigDecimal("54321.00000");
+ BigDecimal expectedDecimalValue = new BigDecimal("54321.54321");
+ BigDecimal actualDecimalValue = results.getBigDecimal(2);
+ assertTrue("Unexpected decimal value of " + actualDecimalValue,
+ expectedDecimalValue.equals(actualDecimalValue)
+ || buggyDecimalValue.equals(actualDecimalValue));
+ assertEquals(false, results.getBoolean(3));
+
+ assertTrue(results.next());
+ assertEquals(Integer.MAX_VALUE, results.getInt(1));
+ // CALCITE-1103 protobuf truncated decimal value
+ buggyDecimalValue = new BigDecimal("12345.00000");
+ expectedDecimalValue = new BigDecimal("12345.12345");
+ actualDecimalValue = results.getBigDecimal(2);
+ assertTrue("Unexpected decimal value of " + actualDecimalValue,
+ expectedDecimalValue.equals(actualDecimalValue)
+ || buggyDecimalValue.equals(actualDecimalValue));
+ assertEquals(true, results.getBoolean(3));
+
+ assertFalse(results.next());
+ }
+ }
+}
+
+// End MetadataTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/2197f7dc/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/package-info.java b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/package-info.java
new file mode 100644
index 0000000..940a1bd
--- /dev/null
+++ b/avatica/tck/src/main/java/org/apache/calcite/avatica/tck/tests/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.
+ */
+
+/**
+ * Tests for the Avatica compatibility framework.
+ */
+@PackageMarker
+package org.apache.calcite.avatica.tck.tests;
+
+import org.apache.calcite.avatica.tck.PackageMarker;
+
+// End package-info.java