You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2016/10/07 19:15:58 UTC

[43/48] phoenix git commit: Fix merge conflicts

Fix merge conflicts


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

Branch: refs/heads/calcite
Commit: 7ca8e4b39647a056d91b627689d9d496b6136f18
Parents: ac544b4 34ba28e
Author: maryannxue <ma...@gmail.com>
Authored: Fri Oct 7 10:37:45 2016 -0700
Committer: maryannxue <ma...@gmail.com>
Committed: Fri Oct 7 10:37:45 2016 -0700

----------------------------------------------------------------------
 ...ritesAndUncompressedWALInHBase_094_9_IT.java |  45 --
 .../apache/phoenix/calcite/BaseCalciteIT.java   |  21 +
 .../org/apache/phoenix/calcite/CalciteIT.java   |  12 +-
 .../StatisticsCollectionRunTrackerIT.java       |  38 +-
 .../phoenix/end2end/AbsFunctionEnd2EndIT.java   |   2 +-
 .../AlterMultiTenantTableWithViewsIT.java       |  16 +-
 .../apache/phoenix/end2end/AlterSessionIT.java  |  59 +-
 .../apache/phoenix/end2end/AlterTableIT.java    |  68 +-
 .../phoenix/end2end/AlterTableWithViewsIT.java  |  30 +-
 .../phoenix/end2end/AppendOnlySchemaIT.java     |  24 +-
 .../phoenix/end2end/ArithmeticQueryIT.java      |  36 +-
 .../phoenix/end2end/ArrayAppendFunctionIT.java  |  18 +-
 .../phoenix/end2end/ArrayConcatFunctionIT.java  |  16 +-
 .../phoenix/end2end/ArrayFillFunctionIT.java    |  76 +-
 .../phoenix/end2end/ArrayPrependFunctionIT.java |  68 +-
 .../end2end/ArrayToStringFunctionIT.java        |  22 +-
 .../phoenix/end2end/ArraysWithNullsIT.java      |  32 +-
 .../apache/phoenix/end2end/AutoCommitIT.java    |   2 +-
 .../phoenix/end2end/AutoPartitionViewsIT.java   |  18 +-
 .../org/apache/phoenix/end2end/BaseJoinIT.java  | 456 +++++++++++
 .../BaseOwnClusterClientManagedTimeIT.java      |  29 -
 .../BaseOwnClusterHBaseManagedTimeIT.java       |  29 -
 .../phoenix/end2end/BaseOwnClusterIT.java       |   7 +
 .../apache/phoenix/end2end/BaseParallelIT.java  |  69 --
 .../end2end/BaseTenantSpecificTablesIT.java     |  87 +-
 .../end2end/BaseTenantSpecificViewIndexIT.java  |  12 +-
 .../org/apache/phoenix/end2end/BaseViewIT.java  |  92 +--
 .../apache/phoenix/end2end/BinaryRowKeyIT.java  |   6 +-
 .../phoenix/end2end/CSVCommonsLoaderIT.java     |  20 +-
 .../phoenix/end2end/CbrtFunctionEnd2EndIT.java  |  27 +-
 .../phoenix/end2end/CoalesceFunctionIT.java     |  20 +-
 .../end2end/ConvertTimezoneFunctionIT.java      |  14 +-
 .../end2end/CountDistinctCompressionIT.java     |   2 +-
 .../phoenix/end2end/CsvBulkLoadToolIT.java      |   2 +-
 .../org/apache/phoenix/end2end/DateTimeIT.java  |  68 +-
 .../phoenix/end2end/DecodeFunctionIT.java       |  12 +-
 .../org/apache/phoenix/end2end/DeleteIT.java    |  26 +-
 .../phoenix/end2end/DisableLocalIndexIT.java    |  26 +-
 .../phoenix/end2end/DistinctPrefixFilterIT.java |  26 +-
 .../apache/phoenix/end2end/DynamicColumnIT.java |  19 +-
 .../apache/phoenix/end2end/DynamicFamilyIT.java |   4 +-
 .../apache/phoenix/end2end/DynamicUpsertIT.java |   2 +-
 .../phoenix/end2end/EncodeFunctionIT.java       |   8 +-
 .../phoenix/end2end/EvaluationOfORIT.java       |   2 +-
 .../phoenix/end2end/ExecuteStatementsIT.java    |   6 +-
 .../phoenix/end2end/ExpFunctionEnd2EndIT.java   |   4 +-
 .../phoenix/end2end/FirstValueFunctionIT.java   |  14 +-
 .../phoenix/end2end/FlappingAlterTableIT.java   |  97 +++
 .../phoenix/end2end/FlappingLocalIndexIT.java   | 300 +++++++
 .../end2end/GetSetByteBitFunctionEnd2EndIT.java |   8 +-
 .../apache/phoenix/end2end/GroupByCaseIT.java   |  59 +-
 .../org/apache/phoenix/end2end/HashJoinIT.java  | 808 +++++++++----------
 .../phoenix/end2end/HashJoinLocalIndexIT.java   |  70 +-
 .../apache/phoenix/end2end/HashJoinMoreIT.java  |  28 +-
 .../org/apache/phoenix/end2end/InListIT.java    |  10 +-
 .../phoenix/end2end/InMemoryOrderByIT.java      |  42 -
 .../apache/phoenix/end2end/IndexExtendedIT.java |  36 +-
 .../apache/phoenix/end2end/InstrFunctionIT.java |  16 +-
 .../org/apache/phoenix/end2end/IsNullIT.java    |   6 +-
 .../org/apache/phoenix/end2end/KeyOnlyIT.java   | 127 +--
 .../phoenix/end2end/LastValueFunctionIT.java    |  22 +-
 .../phoenix/end2end/LikeExpressionIT.java       |  26 +-
 .../phoenix/end2end/LnLogFunctionEnd2EndIT.java |   4 +-
 .../apache/phoenix/end2end/MD5FunctionIT.java   |   6 +-
 .../org/apache/phoenix/end2end/MapReduceIT.java |   8 +-
 .../phoenix/end2end/MappingTableDataTypeIT.java |   2 +-
 .../end2end/MinMaxAggregateFunctionIT.java      |   2 +-
 .../phoenix/end2end/ModulusExpressionIT.java    |  10 +-
 .../phoenix/end2end/MultiCfQueryExecIT.java     | 306 +++----
 .../end2end/NamespaceSchemaMappingIT.java       |   2 +-
 .../phoenix/end2end/NthValueFunctionIT.java     |  22 +-
 .../end2end/OctetLengthFunctionEnd2EndIT.java   |   2 +-
 .../org/apache/phoenix/end2end/OrderByIT.java   |  16 +-
 .../phoenix/end2end/ParallelIteratorsIT.java    | 112 +--
 .../phoenix/end2end/ParallelRunListener.java    |  42 +
 .../end2end/ParallelStatsDisabledIT.java        |  14 +-
 .../phoenix/end2end/ParallelStatsEnabledIT.java |  24 +-
 .../apache/phoenix/end2end/PercentileIT.java    |  15 +-
 .../phoenix/end2end/PhoenixRuntimeIT.java       |  18 +-
 .../phoenix/end2end/PowerFunctionEnd2EndIT.java |  19 +-
 .../apache/phoenix/end2end/PrimitiveTypeIT.java |  18 +-
 .../org/apache/phoenix/end2end/QueryMoreIT.java |   8 +-
 .../apache/phoenix/end2end/QueryTimeoutIT.java  |   2 +-
 .../phoenix/end2end/QueryWithLimitIT.java       |  11 +-
 .../phoenix/end2end/QueryWithOffsetIT.java      |  78 +-
 .../apache/phoenix/end2end/RTrimFunctionIT.java |   2 +-
 .../org/apache/phoenix/end2end/ReadOnlyIT.java  |   2 +-
 .../end2end/RegexpReplaceFunctionIT.java        |   2 +-
 .../phoenix/end2end/RegexpSplitFunctionIT.java  |   2 +-
 .../phoenix/end2end/RegexpSubstrFunctionIT.java |   2 +-
 .../apache/phoenix/end2end/RenewLeaseIT.java    |   2 +-
 .../phoenix/end2end/ReverseFunctionIT.java      |   2 +-
 .../apache/phoenix/end2end/ReverseScanIT.java   |   4 +-
 .../phoenix/end2end/RoundFloorCeilFuncIT.java   |   2 +-
 .../phoenix/end2end/SerialIteratorsIT.java      |  21 +-
 .../phoenix/end2end/ServerExceptionIT.java      |   2 +-
 .../phoenix/end2end/SignFunctionEnd2EndIT.java  |  27 +-
 .../end2end/SkipScanAfterManualSplitIT.java     |  39 +-
 .../apache/phoenix/end2end/SkipScanQueryIT.java |  22 +-
 .../apache/phoenix/end2end/SortMergeJoinIT.java | 471 +++++------
 .../phoenix/end2end/SortMergeJoinMoreIT.java    |  36 +-
 .../org/apache/phoenix/end2end/SortOrderIT.java |  88 +-
 .../phoenix/end2end/SpillableGroupByIT.java     | 127 ++-
 .../phoenix/end2end/SpooledOrderByIT.java       |  40 -
 .../phoenix/end2end/SpooledSortMergeJoinIT.java |  45 --
 .../phoenix/end2end/SpooledTmpFileDeleteIT.java |  64 +-
 .../phoenix/end2end/SqrtFunctionEnd2EndIT.java  |   4 +-
 .../phoenix/end2end/StatementHintsIT.java       |   2 +-
 .../end2end/StatsCollectionDisabledIT.java      |  79 --
 .../end2end/StatsCollectorAbstractIT.java       |  77 --
 .../phoenix/end2end/StatsCollectorIT.java       | 239 ++++--
 .../StatsCollectorWithSplitsAndMultiCFIT.java   | 186 -----
 .../apache/phoenix/end2end/StoreNullsIT.java    |  76 +-
 .../org/apache/phoenix/end2end/StringIT.java    |  10 +-
 .../end2end/StringToArrayFunctionIT.java        |  99 +--
 .../org/apache/phoenix/end2end/SubqueryIT.java  | 297 +++----
 .../end2end/SubqueryUsingSortMergeJoinIT.java   | 456 ++---------
 .../apache/phoenix/end2end/TenantIdTypeIT.java  |   2 +-
 .../end2end/TenantSpecificTablesDDLIT.java      | 272 +++----
 .../end2end/TenantSpecificTablesDMLIT.java      | 269 ++----
 .../end2end/TenantSpecificViewIndexIT.java      |  20 +-
 .../end2end/TimezoneOffsetFunctionIT.java       |  14 +-
 .../phoenix/end2end/ToCharFunctionIT.java       |   6 +-
 .../phoenix/end2end/ToDateFunctionIT.java       |   2 +-
 .../phoenix/end2end/TransactionalViewIT.java    |  57 +-
 .../org/apache/phoenix/end2end/UnionAllIT.java  |  80 +-
 .../org/apache/phoenix/end2end/UpgradeIT.java   | 181 +++--
 .../phoenix/end2end/UpsertBigValuesIT.java      |   8 +-
 .../end2end/UpsertSelectAutoCommitIT.java       |  10 +-
 .../apache/phoenix/end2end/UpsertValuesIT.java  |   2 +-
 .../org/apache/phoenix/end2end/UseSchemaIT.java |  16 +-
 .../phoenix/end2end/UserDefinedFunctionsIT.java | 155 +++-
 .../java/org/apache/phoenix/end2end/ViewIT.java | 249 +++---
 .../end2end/index/AsyncIndexDisabledIT.java     |  17 +-
 .../phoenix/end2end/index/BaseLocalIndexIT.java |  80 ++
 .../index/ChildViewsUseParentViewIndexIT.java   |  20 +-
 .../phoenix/end2end/index/DropMetadataIT.java   |  64 +-
 .../index/GlobalIndexOptimizationIT.java        |  48 +-
 .../phoenix/end2end/index/ImmutableIndexIT.java |  31 +-
 .../index/ImmutableIndexWithStatsIT.java        |  26 +-
 .../end2end/index/IndexExpressionIT.java        |  87 +-
 .../apache/phoenix/end2end/index/IndexIT.java   | 111 ++-
 .../phoenix/end2end/index/IndexMetadataIT.java  |  35 +-
 .../phoenix/end2end/index/LocalIndexIT.java     | 356 +-------
 .../end2end/index/MutableIndexFailureIT.java    |   6 +-
 .../phoenix/end2end/index/MutableIndexIT.java   |  93 +--
 .../end2end/index/ReadOnlyIndexFailureIT.java   |   4 +-
 .../phoenix/end2end/index/SaltedIndexIT.java    |  43 +-
 .../phoenix/end2end/index/ViewIndexIT.java      |  33 +-
 .../end2end/index/txn/MutableRollbackIT.java    |  58 +-
 .../phoenix/end2end/index/txn/RollbackIT.java   |  33 +-
 .../end2end/index/txn/TxWriteFailureIT.java     |   4 +-
 .../salted/SaltedTableUpsertSelectIT.java       |  22 +-
 .../salted/SaltedTableVarLengthRowKeyIT.java    |   2 +-
 .../apache/phoenix/execute/PartialCommitIT.java |   5 +
 .../phoenix/iterate/PhoenixQueryTimeoutIT.java  |  52 +-
 .../iterate/RoundRobinResultIteratorIT.java     |  48 +-
 .../RoundRobinResultIteratorWithStatsIT.java    |   4 +-
 .../phoenix/monitoring/PhoenixMetricsIT.java    |   4 +-
 .../apache/phoenix/rpc/PhoenixClientRpcIT.java  |   4 +-
 .../apache/phoenix/rpc/PhoenixServerRpcIT.java  |   4 +-
 .../org/apache/phoenix/rpc/UpdateCacheIT.java   |  41 +-
 .../phoenix/rpc/UpdateCacheWithScnIT.java       |   3 +-
 .../apache/phoenix/trace/BaseTracingTestIT.java |  14 -
 .../trace/PhoenixTableMetricsWriterIT.java      |   4 +-
 .../phoenix/trace/PhoenixTraceReaderIT.java     |   4 +-
 .../phoenix/trace/PhoenixTracingEndToEndIT.java |  24 +-
 .../apache/phoenix/trace/TracingTestUtil.java   |   8 +-
 .../phoenix/tx/FlappingTransactionIT.java       | 328 ++++++++
 .../org/apache/phoenix/tx/TransactionIT.java    | 363 +--------
 .../org/apache/phoenix/tx/TxCheckpointIT.java   |  51 +-
 .../phoenix/calcite/PhoenixPrepareImpl.java     |  10 +-
 .../phoenix/compile/StatementContext.java       |   2 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  53 ++
 .../phoenix/coprocessor/MetaDataProtocol.java   |  17 +
 .../coprocessor/generated/MetaDataProtos.java   | 353 ++++++--
 .../coprocessor/generated/PTableProtos.java     | 779 +++++++-----------
 .../exception/RetriableUpgradeException.java    |  31 +
 .../exception/UpgradeInProgressException.java   |   3 +-
 .../exception/UpgradeNotRequiredException.java  |   3 +-
 .../exception/UpgradeRequiredException.java     |   3 +-
 .../hbase/index/table/CachingHTableFactory.java | 104 ++-
 .../index/table/CoprocessorHTableFactory.java   |   6 +
 .../hbase/index/table/HTableFactory.java        |   4 +-
 .../hbase/index/write/IndexWriterUtils.java     |   3 +
 .../write/ParallelWriterIndexCommitter.java     |  21 +-
 .../TrackingParallelWriterIndexCommitter.java   |  18 +-
 .../index/PhoenixIndexFailurePolicy.java        |   2 +-
 .../apache/phoenix/parse/ParseNodeRewriter.java |  16 +-
 .../phoenix/query/ConnectionQueryServices.java  |   2 +-
 .../query/ConnectionQueryServicesImpl.java      |  32 +-
 .../query/ConnectionlessQueryServicesImpl.java  |   8 +-
 .../query/DelegateConnectionQueryServices.java  |   4 +-
 .../phoenix/query/QueryServicesOptions.java     |   8 +-
 .../apache/phoenix/schema/MetaDataClient.java   |  88 +-
 .../org/apache/phoenix/schema/PTableImpl.java   |  13 +-
 .../java/org/apache/phoenix/util/DateUtil.java  |   2 +-
 .../org/apache/phoenix/util/MetaDataUtil.java   |   4 +
 .../java/org/apache/phoenix/util/QueryUtil.java |   2 +-
 .../phoenix/compile/JoinQueryCompilerTest.java  |  35 +
 .../TenantSpecificViewIndexCompileTest.java     |   4 +-
 .../hbase/index/write/FakeTableFactory.java     |   9 +-
 .../index/write/TestCachingHTableFactory.java   |  37 +-
 .../hbase/index/write/TestIndexWriter.java      |  24 +-
 .../index/write/TestParalleIndexWriter.java     |  16 +-
 .../write/TestParalleWriterIndexCommitter.java  |  15 +-
 .../apache/phoenix/jdbc/PhoenixDriverTest.java  |   2 +
 .../phoenix/jdbc/SecureUserConnectionsTest.java |  27 +-
 .../query/BaseConnectionlessQueryTest.java      |  28 +-
 .../java/org/apache/phoenix/query/BaseTest.java | 413 ++--------
 .../phoenix/query/QueryServicesTestImpl.java    |   2 +
 .../java/org/apache/phoenix/util/TestUtil.java  | 101 ++-
 .../org/apache/phoenix/flume/PhoenixSinkIT.java |  31 +-
 .../phoenix/flume/RegexEventSerializerIT.java   |  16 +-
 .../apache/phoenix/pherf/ResultBaseTestIT.java  |  12 +-
 .../apache/phoenix/pherf/SchemaReaderIT.java    |   4 +-
 .../java/org/apache/phoenix/pig/BasePigIT.java  |   6 +-
 phoenix-protocol/src/main/MetaDataService.proto |   3 +
 phoenix-protocol/src/main/PTable.proto          |   2 +
 .../phoenix/end2end/QueryServerBasicsIT.java    |   2 +-
 pom.xml                                         | 101 ++-
 221 files changed, 6018 insertions(+), 6555 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
index 75bce4c,0000000..4c89f8d
mode 100644,000000..100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
@@@ -1,737 -1,0 +1,758 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + * http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.phoenix.calcite;
 +
 +import static org.apache.phoenix.util.PhoenixRuntime.PHOENIX_TEST_DRIVER_URL_PARAM;
 +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +import java.io.File;
 +import java.io.FileWriter;
 +import java.io.PrintWriter;
 +import java.sql.Connection;
 +import java.sql.Date;
 +import java.sql.DriverManager;
 +import java.sql.PreparedStatement;
 +import java.sql.ResultSet;
 +import java.sql.SQLException;
 +import java.sql.Statement;
 +import java.sql.Time;
 +import java.sql.Timestamp;
 +import java.text.DecimalFormat;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +
 +import org.apache.calcite.avatica.util.ArrayImpl;
 +import org.apache.calcite.config.CalciteConnectionProperty;
 +import org.apache.phoenix.calcite.rel.PhoenixRel;
 +import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
++import org.apache.phoenix.end2end.BaseJoinIT;
 +import org.apache.phoenix.query.QueryServices;
 +import org.apache.phoenix.schema.TableAlreadyExistsException;
 +import org.apache.phoenix.util.PhoenixRuntime;
 +import org.apache.phoenix.util.PropertiesUtil;
 +import org.apache.phoenix.util.QueryUtil;
 +import org.apache.phoenix.util.ReadOnlyProps;
 +import org.junit.Assert;
 +import org.junit.BeforeClass;
 +
 +import com.google.common.collect.Lists;
 +import com.google.common.collect.Maps;
 +
 +public class BaseCalciteIT extends BaseHBaseManagedTimeIT {
 +    
 +    @BeforeClass
 +    public static void doSetup() throws Exception {
 +        Map<String,String> props = Maps.newHashMapWithExpectedSize(5);
 +        props.put(QueryServices.STATS_USE_CURRENT_TIME_ATTRIB, Boolean.FALSE.toString());
 +        props.put(QueryServices.RUN_UPDATE_STATS_ASYNC, Boolean.FALSE.toString());
 +        props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(1000));
 +        props.put(QueryServices.THREAD_POOL_SIZE_ATTRIB, Integer.toString(200));
 +        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
 +    }
 +    
 +    public static Start start(boolean materializationEnabled, float rowCountFactor) {
 +        return new Start(getConnectionProps(materializationEnabled, rowCountFactor));
 +    }
 +    
 +    public static Start start(Properties props) {
 +        return new Start(props);
 +    }
 +    
 +    public static Start startPhoenixStandalone(Properties props) {
 +        return new Start(props) {
 +            Connection createConnection() throws Exception {
 +                return DriverManager.getConnection(
 +                        getOldUrl(), 
 +                        props);
 +            }
 +            
 +            String getExplainPlanString() {
 +                return "explain";
 +            }
 +        };
 +    }
 +
 +    public static class Start {
 +        protected final Properties props;
 +        private Connection connection;
 +        
 +        Start(Properties props) {
 +            this.props = props;
 +        }
 +
 +        Connection createConnection() throws Exception {
 +        	// FIXME Cannot get correct stats with 'test=true' property
 +        	final String testProp = PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM;
 +        	final String url = getUrl().replaceAll(testProp, "");
 +            return DriverManager.getConnection(url, props);
 +        }
 +        
 +        String getExplainPlanString() {
 +            return "explain plan for";
 +        }
 +
 +        public Sql sql(String sql) {
 +            return new Sql(this, sql);
 +        }
 +
 +        public Connection getConnection() {
 +            if (connection == null) {
 +                try {
 +                    connection = createConnection();
 +                } catch (Exception e) {
 +                    throw new RuntimeException(e);
 +                }
 +            }
 +            return connection;
 +        }
 +
 +        public void commit() {
 +            if (connection != null) {
 +                try {
 +                    connection.commit();
 +                } catch (SQLException e) {
 +                    throw new RuntimeException(e);
 +                }
 +            }
 +        }
 +
 +        public void close() {
 +            if (connection != null) {
 +                try {
 +                    connection.commit();
 +                    connection.close();
 +                } catch (SQLException e) {
 +                    throw new RuntimeException(e);
 +                }
 +            }
 +        }
 +    }
 +
 +    /** Fluid class for a test that has specified a SQL query. */
 +    static class Sql {
 +        private final Start start;
 +        private final String sql;
 +
 +        public Sql(Start start, String sql) {
 +            this.start = start;
 +            this.sql = sql;
 +        }
 +
 +        private static void populateResult(ResultSet resultSet, List<Object[]> list) throws SQLException {
 +            final int columnCount = resultSet.getMetaData().getColumnCount();
 +            while (resultSet.next()) {
 +                Object[] row = new Object[columnCount];
 +                for (int i = 0; i < columnCount; i++) {
 +                    row[i] = resultSet.getObject(i + 1);
 +                }
 +                list.add(row);
 +            }
 +        }
 +
 +        public Sql explainIs(String expected) throws SQLException {
 +            return checkExplain(expected, true);
 +        }
 +
 +        public Sql explainMatches(String expected) throws SQLException {
 +            return checkExplain(expected, false);
 +        }
 +
 +        private Sql checkExplain(String expected, boolean exact) throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            final ResultSet resultSet = statement.executeQuery(start.getExplainPlanString() + " " + sql);
 +            String explain = QueryUtil.getExplainPlan(resultSet);
 +            resultSet.close();
 +            statement.close();
 +            if (exact) {
 +                Assert.assertEquals(explain, expected);
 +            } else {
 +                Assert.assertTrue(
 +                        "Explain plan \"" + explain
 +                        + "\" does not match \"" + expected + "\"",
 +                        explain.matches(expected));
 +            }
 +            return this;
 +        }
 +
 +        public List<Object[]> getResult() throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            final ResultSet resultSet = statement.executeQuery(sql);
 +            final List<Object[]> list = Lists.newArrayList();
 +            populateResult(resultSet, list);
 +            resultSet.close();
 +            statement.close();
 +            return list;
 +        }
 +
 +        public Sql execute() throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            statement.execute(sql);
 +            statement.close();
 +            return this;
 +        }
 +        
 +        public Sql executeUpdate() throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            statement.executeUpdate(sql);
 +            statement.close();
 +            return this;
 +        }
 +        
 +        public PreparedStatement prepareStatement() throws SQLException {
 +            return start.getConnection().prepareStatement(sql);
 +        }
 +
 +        public void commit() {
 +            start.commit();
 +        }
 +
 +        public void close() {
 +            start.close();
 +        }
 +
 +        public Sql resultIs(Object[][] expected) throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            final ResultSet resultSet = statement.executeQuery(sql);
 +            checkResultOrdered(resultSet, expected);
 +            resultSet.close();
 +            statement.close();
 +            return this;
 +        }
 +
 +        public Sql resultIs(int orderedCount, Object[][] expected) throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            final ResultSet resultSet = statement.executeQuery(sql);
 +            checkResultUnordered(resultSet, expected, orderedCount, null);
 +            resultSet.close();
 +            statement.close();
 +            return this;
 +        }
 +
 +        public Sql resultIsSomeOf(int count, Object[][] expected) throws SQLException {
 +            final Statement statement = start.getConnection().createStatement();
 +            final ResultSet resultSet = statement.executeQuery(sql);
 +            checkResultUnordered(resultSet, expected, 0, count);
 +            resultSet.close();
 +            statement.close();
 +            return this;
 +        }
 +        
 +        public Sql sameResultAsPhoenixStandalone() throws SQLException {
 +            Start phoenixStart = startPhoenixStandalone(this.start.props);
 +            List<Object[]> result = phoenixStart.sql(this.sql).getResult();
 +            phoenixStart.close();
 +            return resultIs(result.toArray(new Object[result.size()][]));
 +        }
 +        
 +        public Sql sameResultAsPhoenixStandalone(int orderedCount) throws SQLException {
 +            Start phoenixStart = startPhoenixStandalone(this.start.props);
 +            List<Object[]> result = phoenixStart.sql(this.sql).getResult();
 +            phoenixStart.close();
 +            return resultIs(orderedCount, result.toArray(new Object[result.size()][]));
 +        }
 +        
 +        private void checkResultOrdered(ResultSet resultSet, Object[][] expected) throws SQLException {
 +            int expectedCount = expected.length;
 +            int count = 0;
 +            for (int i = 0; i < expectedCount; i++) {
 +                assertTrue(
 +                        "Expected " + expectedCount + " rows, but got " + count + " rows.",
 +                        resultSet.next());
 +                count++;
 +                Object[] row = expected[i];
 +                for (int j = 0; j < row.length; j++) {
 +                    Object obj = resultSet.getObject(j + 1);
 +                    Assert.assertEquals(canonicalize(row[j]), canonicalize(obj));
 +                }
 +            }
 +            assertFalse("Got more rows than expected.", resultSet.next());            
 +        }
 +        
 +        private void checkResultUnordered(ResultSet resultSet, Object[][] expected, int orderedCount, Integer checkContains) throws SQLException {
 +            List<List<Object>> expectedResults = Lists.newArrayList();
 +            List<List<Object>> actualResults = Lists.newArrayList();
 +            List<List<Object>> errorResults = Lists.newArrayList();
 +            int columnCount = expected.length > 0 ? expected[0].length : 0;
 +            for (Object[] e : expected) {
 +                List<Object> row = Lists.newArrayList();
 +                for (int i = orderedCount; i < e.length; i++) {
 +                    row.add(canonicalize(e[i]));
 +                }
 +                expectedResults.add(row);
 +            }
 +            while (resultSet.next()) {
 +                if (actualResults.size() >= expected.length) {
 +                    fail("Got more rows than expected after getting results: " + actualResults);
 +                }
 +                // check the ordered part
 +                Object[] row = expected[actualResults.size()];
 +                for (int i = 0; i < orderedCount; i++) {
 +                    Object obj = resultSet.getObject(i + 1);
 +                    Assert.assertEquals(canonicalize(row[i]), canonicalize(obj));
 +                }
 +                // check the unordered part
 +                List<Object> result = Lists.newArrayList();
 +                for (int i = orderedCount; i < columnCount; i++) {
 +                    result.add(canonicalize(resultSet.getObject(i+1)));
 +                }
 +                if (!expectedResults.remove(result)) {
 +                    errorResults.add(result);
 +                }
 +                actualResults.add(result);
 +            }
 +            boolean allContainedInExpected = errorResults.isEmpty();
 +            boolean allExpectedFound = checkContains == null ? expectedResults.isEmpty() : checkContains == actualResults.size();
 +            assertTrue(
 +                    (allContainedInExpected ? "" : "Could not find " + errorResults + " in expected results.\n") +
 +                    (allExpectedFound ? "" : 
 +                        (checkContains == null
 +                              ? ("Count not find " + expectedResults + " in actual results: " + actualResults + ".\n")
 +                              : ("Expected " + checkContains + " rows, but got " + actualResults.size() + " rows."))),
 +                    allContainedInExpected && allExpectedFound);
 +        }
 +        
 +        private Object canonicalize(Object obj) {
 +            if (obj == null) {
 +                return obj;
 +            }
 +            
 +            if (obj instanceof ArrayImpl) {
 +                return obj.toString();
 +            }
 +            
 +            if (obj.getClass().isArray()) {
 +                final StringBuilder buf = new StringBuilder("[");
 +                for (Object o : (Object[]) obj) {
 +                    if (buf.length() > 1) {
 +                        buf.append(", ");
 +                    }
 +                    String s = o.toString();
 +                    // Remove nano suffix
 +                    if (o instanceof Timestamp) {
 +                        s = s.substring(0, s.lastIndexOf('.'));
 +                    }
 +                    buf.append(s);
 +                }
 +                return buf.append("]").toString();
 +            }
 +            
 +            return obj;
 +        }
 +    }
 +
 +    private static final String FOODMART_SCHEMA = "     {\n"
 +            + "       type: 'jdbc',\n"
 +            + "       name: 'foodmart',\n"
 +            + "       jdbcDriver: 'org.hsqldb.jdbcDriver',\n"
 +            + "       jdbcUser: 'FOODMART',\n"
 +            + "       jdbcPassword: 'FOODMART',\n"
 +            + "       jdbcUrl: 'jdbc:hsqldb:res:foodmart',\n"
 +            + "       jdbcCatalog: null,\n"
 +            + "       jdbcSchema: 'foodmart'\n"
 +            + "     }";
 +    
 +    private static final String getPhoenixSchema() {
 +        return "    {\n"
 +            + "      name: 'phoenix',\n"
 +            + "      type: 'custom',\n"
 +            + "      factory: 'org.apache.phoenix.calcite.PhoenixSchema$Factory',\n"
 +            + "      operand: {\n"
 +            + "        url: \"" + getOldUrl() + "\"\n"
 +            + "      }\n"
 +            + "    }";
 +    }
 +
 +    protected static Connection connectUsingModel(Properties props) throws Exception {
 +        final File file = File.createTempFile("model", ".json");
 +        final String url = getOldUrl();
 +        final PrintWriter pw = new PrintWriter(new FileWriter(file));
 +        pw.print(
 +            "{\n"
 +                + "  version: '1.0',\n"
 +                + "  defaultSchema: 'HR',\n"
 +                + "  schemas: [\n"
 +                + "    {\n"
 +                + "      name: 'HR',\n"
 +                + "      type: 'custom',\n"
 +                + "      factory: 'org.apache.phoenix.calcite.PhoenixSchema$Factory',\n"
 +                + "      operand: {\n"
 +                + "        url: \"" + url + "\",\n"
 +                + "        user: \"scott\",\n"
 +                + "        password: \"tiger\"\n"
 +                + "      }\n"
 +                + "    }\n"
 +                + "  ]\n"
 +                + "}\n");
 +        pw.close();
 +        final Connection connection =
 +            DriverManager.getConnection("jdbc:phoenixcalcite:model=" + file.getAbsolutePath(), props);
 +        return connection;
 +    }
 +
 +    protected static Connection connectWithHsqldbUsingModel(Properties props) throws Exception {
 +        final File file = File.createTempFile("model", ".json");
 +        final PrintWriter pw = new PrintWriter(new FileWriter(file));
 +        pw.print(
 +            "{\n"
 +                + "  version: '1.0',\n"
 +                + "  defaultSchema: 'phoenix',\n"
 +                + "  schemas: [\n"
 +                + getPhoenixSchema() + ",\n"
 +                + FOODMART_SCHEMA + "\n"
 +                + "  ]\n"
 +                + "}\n");
 +        pw.close();
 +        final Connection connection =
 +            DriverManager.getConnection("jdbc:phoenixcalcite:model=" + file.getAbsolutePath(), props);
 +        return connection;
 +    }
 +
 +    protected static Properties getConnectionProps(boolean enableMaterialization, float rowCountFactor) {
 +        Properties props = new Properties();
 +        if (!enableMaterialization) {
 +            props.setProperty(
 +                    CalciteConnectionProperty.MATERIALIZATIONS_ENABLED.camelName(),
 +                    Boolean.toString(enableMaterialization));
 +        }
 +        props.setProperty(
 +                CalciteConnectionProperty.CREATE_MATERIALIZATIONS.camelName(),
 +                Boolean.toString(false));
 +        props.setProperty(PhoenixRel.ROW_COUNT_FACTOR, Float.toString(rowCountFactor));
 +        return props;
 +    }
 +    
 +    protected static final String SCORES_TABLE_NAME = "scores";
 +    
++    protected void initJoinTableValues(String url) throws Exception {
++        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
++        Connection conn = DriverManager.getConnection(url, props);
++        try {
++            for (String tableName : new String[] {
++                    BaseJoinIT.JOIN_CUSTOMER_TABLE_FULL_NAME,
++                    BaseJoinIT.JOIN_ITEM_TABLE_FULL_NAME,
++                    BaseJoinIT.JOIN_ORDER_TABLE_FULL_NAME,
++                    BaseJoinIT.JOIN_SUPPLIER_TABLE_FULL_NAME}) {
++                try {
++                    BaseJoinIT.createTable(conn, tableName, tableName);
++                } catch (TableAlreadyExistsException e) {
++                }
++                BaseJoinIT.initValues(conn, tableName, tableName);
++            }
++        } finally {
++            conn.close();
++        }
++    }
++    
 +    protected void initArrayTable(String url) throws Exception {
 +        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
 +        Connection conn = DriverManager.getConnection(url, props);
 +        try {
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + SCORES_TABLE_NAME
 +                    + "(student_id INTEGER NOT NULL, subject_id INTEGER NOT NULL, scores INTEGER[], exam_date DATE[], exam_time TIME[], exam_timestamp TIMESTAMP[] CONSTRAINT pk PRIMARY KEY (student_id, subject_id))");
 +            PreparedStatement stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + SCORES_TABLE_NAME
 +                    + " VALUES(?, ?, ?, ?, ?, ?)");
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 1);
 +            stmt.setArray(3, conn.createArrayOf("INTEGER", new Integer[] {85, 80, 82}));
 +            stmt.setArray(4, conn.createArrayOf("DATE", new Date[] {Date.valueOf("2016-3-22"), Date.valueOf("2016-5-23"), Date.valueOf("2016-7-24")}));
 +            stmt.setArray(5, conn.createArrayOf("TIME", new Time[] {Time.valueOf("15:30:28"), Time.valueOf("13:26:50"), Time.valueOf("16:20:00")}));
 +            stmt.setArray(6, conn.createArrayOf("TIMESTAMP", new Timestamp[] {Timestamp.valueOf("2016-3-22 15:30:28"), Timestamp.valueOf("2016-5-23 13:26:50"), Timestamp.valueOf("2016-7-24 16:20:00")}));
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 1);
 +            stmt.setArray(3, null);
 +            stmt.setArray(4, null);
 +            stmt.setArray(5, null);
 +            stmt.setArray(6, null);
 +            stmt.execute();
 +            stmt.setInt(1, 3);
 +            stmt.setInt(2, 2);
 +            stmt.setArray(3, conn.createArrayOf("INTEGER", new Integer[] {87, 88, 80}));
 +            stmt.setArray(4, conn.createArrayOf("DATE", new Date[] {Date.valueOf("2016-3-22"), Date.valueOf("2016-5-23"), Date.valueOf("2016-7-24")}));
 +            stmt.setArray(5, conn.createArrayOf("TIME", new Time[] {Time.valueOf("15:30:16"), Time.valueOf("13:26:52"), Time.valueOf("16:20:40")}));
 +            stmt.setArray(6, conn.createArrayOf("TIMESTAMP", new Timestamp[] {Timestamp.valueOf("2016-3-22 15:30:16"), Timestamp.valueOf("2016-5-23 13:26:52"), Timestamp.valueOf("2016-7-24 16:20:40")}));
 +            stmt.execute();
 +            conn.commit();
 +        } catch (TableAlreadyExistsException e) {
 +        }
 +        conn.close();        
 +    }
 +    
 +    protected static final String NOSALT_TABLE_NAME = "nosalt_test_table";
 +    protected static final String NOSALT_TABLE_SALTED_INDEX_NAME = "idxsalted_nosalt_test_table";
 +    protected static final String SALTED_TABLE_NAME = "salted_test_table";
 +    protected static final String SALTED_TABLE_NOSALT_INDEX_NAME = "idx_salted_test_table";
 +    protected static final String SALTED_TABLE_SALTED_INDEX_NAME = "idxsalted_salted_test_table";
 +    
 +    protected void initSaltedTables(String url, String index) throws SQLException {
 +        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
 +        Connection conn = DriverManager.getConnection(url, props);
 +        try {
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + NOSALT_TABLE_NAME + " (mypk0 INTEGER NOT NULL, mypk1 INTEGER NOT NULL, col0 INTEGER, col1 INTEGER CONSTRAINT pk PRIMARY KEY (mypk0, mypk1))");
 +            PreparedStatement stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + NOSALT_TABLE_NAME
 +                    + " VALUES(?, ?, ?, ?)");
 +            for (int i = 0; i < 1000; i++) {
 +                stmt.setInt(1, i + 1);
 +                stmt.setInt(2, i + 2);
 +                stmt.setInt(3, i + 3);
 +                stmt.setInt(4, i + 4);
 +                stmt.execute();
 +            }
 +            conn.commit();
 +            
 +            if (index != null) {
 +                conn.createStatement().execute(
 +                        "CREATE " + index + " " + NOSALT_TABLE_SALTED_INDEX_NAME + " ON " + NOSALT_TABLE_NAME + " (col0)"
 +                        + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4"));
 +                conn.commit();
 +            }
 +            
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + SALTED_TABLE_NAME + " (mypk0 INTEGER NOT NULL, mypk1 INTEGER NOT NULL, col0 INTEGER, col1 INTEGER CONSTRAINT pk PRIMARY KEY (mypk0, mypk1)) SALT_BUCKETS=4");
 +            stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + SALTED_TABLE_NAME
 +                    + " VALUES(?, ?, ?, ?)");
 +            for (int i = 0; i < 1000; i++) {
 +                stmt.setInt(1, i + 1);
 +                stmt.setInt(2, i + 2);
 +                stmt.setInt(3, i + 3);
 +                stmt.setInt(4, i + 4);
 +                stmt.execute();
 +            }
 +            conn.commit();
 +            
 +            if (index != null) {
 +                conn.createStatement().execute("CREATE " + index + " " + SALTED_TABLE_NOSALT_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col0)");
 +                conn.createStatement().execute(
 +                        "CREATE " + index + " " + SALTED_TABLE_SALTED_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col1) INCLUDE (col0)"
 +                        + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4"));
 +                conn.commit();
 +            }
 +        } catch (TableAlreadyExistsException e) {
 +        }
 +        conn.close();        
 +    }
 +    
 +    protected static final String KEY_ORDERING_TABLE_1_NAME = "key_ordering_test_table_1";
 +    protected static final String KEY_ORDERING_TABLE_2_NAME = "key_ordering_test_table_2";
 +    
 +    protected void initKeyOrderingTable(String url) throws Exception {
 +        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
 +        Connection conn = DriverManager.getConnection(url, props);
 +        try {
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + KEY_ORDERING_TABLE_1_NAME
 +                    + "(k0 BIGINT NOT NULL, k1 INTEGER NOT NULL, v0 INTEGER, v1 BIGINT CONSTRAINT pk PRIMARY KEY (k0 DESC, k1))");
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + KEY_ORDERING_TABLE_2_NAME
 +                    + "(k0 BIGINT NOT NULL, k1 BIGINT NOT NULL, v0 INTEGER, v1 BIGINT CONSTRAINT pk PRIMARY KEY (k0 DESC, k1 DESC))");
 +            PreparedStatement stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + KEY_ORDERING_TABLE_1_NAME
 +                    + " VALUES(?, ?, ?, ?)");
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 2);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 2);
 +            stmt.execute();
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 3);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 3);
 +            stmt.execute();
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 4);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 4);
 +            stmt.execute();
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 3);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 3);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            stmt.setInt(1, 3);
 +            stmt.setInt(2, 2);
 +            stmt.setInt(3, 3);
 +            stmt.setInt(4, 2);
 +            stmt.execute();
 +            stmt.setInt(1, 5);
 +            stmt.setInt(2, 2);
 +            stmt.setInt(3, 5);
 +            stmt.setInt(4, 2);
 +            stmt.execute();
 +            stmt.setInt(1, 5);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 5);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            conn.commit();
 +            stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + KEY_ORDERING_TABLE_2_NAME
 +                    + " VALUES(?, ?, ?, ?)");
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 2);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 2);
 +            stmt.execute();
 +            stmt.setInt(1, 1);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 1);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 2);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 2);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 3);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 3);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 4);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 4);
 +            stmt.execute();
 +            stmt.setInt(1, 2);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 2);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            stmt.setInt(1, 4);
 +            stmt.setInt(2, 3);
 +            stmt.setInt(3, 4);
 +            stmt.setInt(4, 3);
 +            stmt.execute();
 +            stmt.setInt(1, 5);
 +            stmt.setInt(2, 4);
 +            stmt.setInt(3, 5);
 +            stmt.setInt(4, 4);
 +            stmt.execute();
 +            stmt.setInt(1, 5);
 +            stmt.setInt(2, 5);
 +            stmt.setInt(3, 5);
 +            stmt.setInt(4, 5);
 +            stmt.execute();
 +            conn.commit();
 +        } catch (TableAlreadyExistsException e) {
 +        }
 +        conn.close();        
 +    }
 +    
 +    protected static final String MULTI_TENANT_TABLE = "multitenant_test_table";
 +    protected static final String MULTI_TENANT_TABLE_INDEX = "idx_multitenant_test_table";
 +    protected static final String MULTI_TENANT_VIEW1 = "s1.multitenant_test_view1";
 +    protected static final String MULTI_TENANT_VIEW1_INDEX = "idx_multitenant_test_view1";
 +    protected static final String MULTI_TENANT_VIEW2 = "s2.multitenant_test_view2";
 +    protected static final String MULTI_TENANT_VIEW2_INDEX = "idx_multitenant_test_view2";
 +    
 +    protected void initMultiTenantTables(String url, String index) throws SQLException {
 +        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
 +        Connection conn = DriverManager.getConnection(url, props);
 +        try {
 +            conn.createStatement().execute(
 +                    "CREATE TABLE " + MULTI_TENANT_TABLE + " (tenant_id VARCHAR NOT NULL, id VARCHAR NOT NULL, col0 INTEGER, col1 INTEGER, col2 INTEGER CONSTRAINT pk PRIMARY KEY (tenant_id, id)) MULTI_TENANT=true");
 +            PreparedStatement stmt = conn.prepareStatement(
 +                    "UPSERT INTO " + MULTI_TENANT_TABLE
 +                    + " VALUES(?, ?, ?, ?, ?)");
 +            DecimalFormat formatter = new DecimalFormat("0000");
 +            for (int i = 0; i < 1000; i++) {
 +                stmt.setString(1, "10");
 +                stmt.setString(2, formatter.format(2 + i));
 +                stmt.setInt(3, 3 + i);
 +                stmt.setInt(4, 4 + i);
 +                stmt.setInt(5, 5 + i);
 +                stmt.execute();
 +            }
 +            for (int i = 0; i < 1000; i++) {
 +                stmt.setString(1, "15");
 +                stmt.setString(2, formatter.format(3 + i));
 +                stmt.setInt(3, 4 + i);
 +                stmt.setInt(4, 5 + i);
 +                stmt.setInt(5, 6 + i);
 +                stmt.execute();
 +            }
 +            for (int i = 0; i < 1000; i++) {
 +                stmt.setString(1, "20");
 +                stmt.setString(2, formatter.format(4 + i));
 +                stmt.setInt(3, 5 + i);
 +                stmt.setInt(4, 6 + i);
 +                stmt.setInt(5, 7 + i);
 +                stmt.execute();
 +            }
 +            conn.commit();
 +            
 +            if (index != null) {
 +                conn.createStatement().execute(
 +                        "CREATE " + index + " " + MULTI_TENANT_TABLE_INDEX
 +                        + " ON " + MULTI_TENANT_TABLE + "(col1) INCLUDE (col0, col2)");
 +                conn.commit();
 +            }
 +            
 +            conn.close();
 +            props.setProperty("TenantId", "10");
 +            conn = DriverManager.getConnection(getOldUrl(), props);
 +            conn.createStatement().execute("CREATE VIEW " + MULTI_TENANT_VIEW1
 +                    + " AS select * from " + MULTI_TENANT_TABLE);
 +            conn.commit();
 +            
 +            if (index != null) {
 +                conn.createStatement().execute(
 +                        "CREATE " + index + " " + MULTI_TENANT_VIEW1_INDEX
 +                        + " ON " + MULTI_TENANT_VIEW1 + "(col0)");
 +                conn.commit();
 +            }
 +            
 +            conn.close();
 +            props.setProperty("TenantId", "20");
 +            conn = DriverManager.getConnection(getOldUrl(), props);
 +            conn.createStatement().execute("CREATE VIEW " + MULTI_TENANT_VIEW2
 +                    + " AS select * from " + MULTI_TENANT_TABLE + " where col2 > 7");
 +            conn.commit();
 +            
 +            if (index != null) {
 +                conn.createStatement().execute(
 +                        "CREATE " + index + " " + MULTI_TENANT_VIEW2_INDEX
 +                        + " ON " + MULTI_TENANT_VIEW2 + "(col0)");
 +                conn.commit();
 +            }
 +        } catch (TableAlreadyExistsException e) {
 +        } finally {
 +            conn.close();
 +        }
 +    }
 +
 +}