Sync with master; Bug fix for ResultSet object of Float type; Walkaround for PHOENIX-2647
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/74409be8 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/74409be8 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/74409be8 Branch: refs/heads/calcite Commit: 74409be82c1224b0cefee1b1e6a64bb3d0491339 Parents: beb8b81 6af7dcb Author: maryannxue <[email protected]> Authored: Mon Feb 1 22:59:16 2016 -0500 Committer: maryannxue <[email protected]> Committed: Mon Feb 1 22:59:16 2016 -0500 ---------------------------------------------------------------------- phoenix-assembly/pom.xml | 2 +- phoenix-core/pom.xml | 2 +- .../apache/phoenix/calcite/BaseCalciteIT.java | 91 ++++++++-- .../org/apache/phoenix/calcite/CalciteIT.java | 140 ++++++++-------- .../apache/phoenix/calcite/CalciteIndexIT.java | 36 ++-- .../phoenix/end2end/CsvBulkLoadToolIT.java | 5 +- .../apache/phoenix/end2end/DerivedTableIT.java | 13 ++ .../phoenix/end2end/StatsCollectorIT.java | 73 ++++---- .../phoenix/end2end/TransactionalViewIT.java | 120 +++++++++++++ .../phoenix/end2end/index/ImmutableIndexIT.java | 123 +++++++++----- .../end2end/index/MutableIndexFailureIT.java | 6 +- .../apache/phoenix/execute/PartialCommitIT.java | 2 +- .../index/balancer/IndexLoadBalancerIT.java | 2 + .../org/apache/phoenix/tx/TransactionIT.java | 39 +---- .../ipc/controller/MetadataRpcController.java | 3 +- .../wal/BinaryCompatibleBaseDecoder.java | 110 ++++++++++++ .../regionserver/wal/IndexedWALEditCodec.java | 83 ++++++++- .../cache/aggcache/SpillableGroupByCache.java | 17 +- .../apache/phoenix/calcite/CalciteRuntime.java | 10 +- .../apache/phoenix/calcite/PhoenixSchema.java | 2 +- .../calcite/rel/PhoenixRelImplementorImpl.java | 4 +- .../apache/phoenix/compile/FromCompiler.java | 8 +- .../phoenix/compile/ListJarsQueryPlan.java | 2 +- .../phoenix/compile/OrderPreservingTracker.java | 6 +- .../compile/PostLocalIndexDDLCompiler.java | 104 ++++++++++++ .../apache/phoenix/compile/TraceQueryPlan.java | 2 +- .../apache/phoenix/compile/UnionCompiler.java | 2 +- .../phoenix/coprocessor/BaseRegionScanner.java | 11 +- .../GroupedAggregateRegionObserver.java | 38 +---- .../coprocessor/MetaDataEndpointImpl.java | 7 +- .../coprocessor/MetaDataRegionObserver.java | 8 +- .../phoenix/coprocessor/ScanRegionObserver.java | 17 +- .../UngroupedAggregateRegionObserver.java | 24 +-- .../coprocessor/generated/PTableProtos.java | 145 +++++++++++++--- .../phoenix/execute/ClientAggregatePlan.java | 2 +- .../apache/phoenix/execute/HashJoinPlan.java | 2 +- .../apache/phoenix/execute/MutationState.java | 84 +++++----- .../index/write/KillServerOnFailurePolicy.java | 5 +- .../index/PhoenixIndexFailurePolicy.java | 9 +- .../phoenix/iterate/BaseResultIterators.java | 2 +- .../apache/phoenix/jdbc/PhoenixStatement.java | 1 - .../phoenix/mapreduce/AbstractBulkLoadTool.java | 2 +- .../mapreduce/PhoenixRecordWritable.java | 28 ++-- .../query/ConnectionQueryServicesImpl.java | 82 ++------- .../org/apache/phoenix/query/QueryServices.java | 2 + .../phoenix/query/QueryServicesOptions.java | 11 +- .../apache/phoenix/schema/DelegateColumn.java | 5 + .../apache/phoenix/schema/MetaDataClient.java | 133 ++++++--------- .../java/org/apache/phoenix/schema/PColumn.java | 2 + .../org/apache/phoenix/schema/PColumnImpl.java | 21 ++- .../apache/phoenix/schema/PMetaDataImpl.java | 2 +- .../org/apache/phoenix/schema/SaltingUtil.java | 2 +- .../phoenix/execute/CorrelatePlanTest.java | 2 +- .../phoenix/execute/UnnestArrayPlanTest.java | 4 +- .../expression/ColumnExpressionTest.java | 8 +- .../phoenix/filter/SkipScanFilterTest.java | 62 +++---- .../iterate/AggregateResultScannerTest.java | 4 + .../phoenix/query/QueryServicesTestImpl.java | 4 +- phoenix-flume/pom.xml | 2 +- .../flume/serializer/RegexEventSerializer.java | 12 +- phoenix-pherf/pom.xml | 2 +- phoenix-pig/pom.xml | 2 +- .../phoenix/pig/PhoenixHBaseLoaderIT.java | 167 ++++++++++++++++++- .../phoenix/pig/PhoenixHBaseStorerIT.java | 37 ++++ .../apache/phoenix/pig/PhoenixHBaseLoader.java | 22 +-- .../apache/phoenix/pig/PhoenixHBaseStorage.java | 33 +++- .../org/apache/phoenix/pig/util/TypeUtil.java | 49 ++++-- .../pig/writable/PhoenixPigDBWritable.java | 121 -------------- .../apache/phoenix/pig/util/TypeUtilTest.java | 39 +++-- phoenix-protocol/src/main/MetaDataService.proto | 2 +- phoenix-protocol/src/main/PTable.proto | 1 + phoenix-server-client/pom.xml | 2 +- phoenix-server/pom.xml | 2 +- phoenix-spark/pom.xml | 5 +- phoenix-tracing-webapp/pom.xml | 2 +- pom.xml | 5 +- 76 files changed, 1448 insertions(+), 793 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/74409be8/phoenix-core/pom.xml ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/74409be8/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 55865f0,0000000..9afddab 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,440 -1,0 +1,503 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.assertEquals; +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.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; +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.end2end.BaseClientManagedTimeIT; ++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.ReadOnlyProps; ++import org.junit.BeforeClass; + +import com.google.common.collect.Lists; + +public class BaseCalciteIT extends BaseClientManagedTimeIT { + ++ @BeforeClass ++ public static void doSetup() throws Exception { ++ Map<String,String> props = getDefaultProps(); ++ props.put(QueryServices.RUN_UPDATE_STATS_ASYNC, Boolean.FALSE.toString()); ++ props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(1000)); ++ setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator())); ++ } ++ + public static Start start(boolean materializationEnabled) { + return new Start(getConnectionProps(materializationEnabled)); + } + + public static Start start(Properties props) { + return new Start(props); + } + + public static class Start { + protected final Properties props; + private Connection connection; + + Start(Properties props) { + this.props = props; + } + + Connection createConnection() throws Exception { + return DriverManager.getConnection( + "jdbc:phoenixcalcite:" + + getUrl().substring(PhoenixRuntime.JDBC_PROTOCOL.length() + 1), + props); + } + + 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 close() { + if (connection != null) { + try { + 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; + } + + public static List<Object[]> getResult(ResultSet resultSet) throws SQLException { + final List<Object[]> list = Lists.newArrayList(); + populateResult(resultSet, list); + return list; + } + + 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 { + final List<Object[]> list = getResult("explain plan for " + sql); + if (list.size() != 1) { + fail("explain should return 1 row, got " + list.size()); + } + String explain = (String) (list.get(0)[0]); + assertEquals(explain, expected); + return this; + } + + + public boolean execute() throws SQLException { + final Statement statement = start.getConnection().createStatement(); + final boolean execute = statement.execute(sql); + statement.close(); + return execute; + } + + public List<Object[]> getResult(String sql) throws SQLException { + final Statement statement = start.getConnection().createStatement(); + final ResultSet resultSet = statement.executeQuery(sql); + List<Object[]> list = getResult(resultSet); + resultSet.close(); + statement.close(); + return list; + } + + public void close() { + start.close(); + } + - public Sql resultIs(Object[]... expected) throws SQLException { ++ public Sql resultIs(boolean ordered, Object[][] expected) throws SQLException { + final Statement statement = start.getConnection().createStatement(); + final ResultSet resultSet = statement.executeQuery(sql); - for (int i = 0; i < expected.length; i++) { - assertTrue(resultSet.next()); ++ if (ordered) { ++ checkResultOrdered(resultSet, expected); ++ } else { ++ checkResultUnordered(resultSet, expected); ++ } ++ resultSet.close(); ++ statement.close(); ++ return this; ++ } ++ ++ 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); - if (obj instanceof ArrayImpl) { - assertEquals( - Arrays.toString((Object[]) row[j]), - obj.toString()); - } else { - assertEquals(row[j], obj); - } ++ assertEquals(canonicalize(row[j]), canonicalize(obj)); + } + } - assertFalse(resultSet.next()); - resultSet.close(); - statement.close(); - return this; ++ assertFalse("Got more rows than expected.", resultSet.next()); ++ } ++ ++ private void checkResultUnordered(ResultSet resultSet, Object[][] expected) 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 (Object o : e) { ++ row.add(canonicalize(o)); ++ } ++ expectedResults.add(row); ++ } ++ while (resultSet.next()) { ++ List<Object> result = Lists.newArrayList(); ++ for (int i = 0; i < columnCount; i++) { ++ result.add(canonicalize(resultSet.getObject(i+1))); ++ } ++ if (!expectedResults.remove(result)) { ++ errorResults.add(result); ++ } ++ actualResults.add(result); ++ } ++ assertTrue( ++ (expectedResults.isEmpty() ? "" : ("Count not find " + expectedResults + " in actual results: " + actualResults + ".\n")) + ++ (errorResults.isEmpty() ? "" : "Could not find " + errorResults + " in expected results.\n"), ++ errorResults.isEmpty() && expectedResults.isEmpty()); ++ } ++ ++ private Object canonicalize(Object obj) { ++ if (obj == null) { ++ return obj; ++ } ++ ++ if (obj instanceof ArrayImpl) { ++ return obj.toString(); ++ } ++ ++ if (obj.getClass().isArray()) { ++ return Arrays.toString((Object[]) obj); ++ } ++ ++ 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: \"" + getUrl() + "\"\n" + + " }\n" + + " }"; + } + + protected static Connection connectUsingModel(Properties props) throws Exception { + final File file = File.createTempFile("model", ".json"); + final String url = getUrl(); + 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) { + Properties props = new Properties(); + props.setProperty( + CalciteConnectionProperty.MATERIALIZATIONS_ENABLED.camelName(), + Boolean.toString(enableMaterialization)); + props.setProperty( + CalciteConnectionProperty.CREATE_MATERIALIZATIONS.camelName(), + Boolean.toString(false)); + return props; + } + + protected static final String SCORES_TABLE_NAME = "scores"; + + protected void initArrayTable() throws Exception { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), props); + try { + conn.createStatement().execute( + "CREATE TABLE " + SCORES_TABLE_NAME + + "(student_id INTEGER NOT NULL, subject_id INTEGER NOT NULL, scores INTEGER[] 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.execute(); + stmt.setInt(1, 2); + stmt.setInt(2, 1); + stmt.setArray(3, null); + stmt.execute(); + stmt.setInt(1, 3); + stmt.setInt(2, 2); + stmt.setArray(3, conn.createArrayOf("INTEGER", new Integer[] {87, 88, 80})); + 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 index) throws SQLException { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), 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(?, ?, ?, ?)"); + stmt.setInt(1, 1); + stmt.setInt(2, 2); + stmt.setInt(3, 3); + stmt.setInt(4, 4); + stmt.execute(); + stmt.setInt(1, 2); + stmt.setInt(2, 3); + stmt.setInt(3, 4); + stmt.setInt(4, 5); + stmt.execute(); + stmt.setInt(1, 3); + stmt.setInt(2, 4); + stmt.setInt(3, 5); + stmt.setInt(4, 6); + stmt.execute(); + conn.commit(); + + if (index != null) { + conn.createStatement().execute("CREATE " + index + " " + NOSALT_TABLE_SALTED_INDEX_NAME + " ON " + NOSALT_TABLE_NAME + " (col0) 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(?, ?, ?, ?)"); + stmt.setInt(1, 1); + stmt.setInt(2, 2); + stmt.setInt(3, 3); + stmt.setInt(4, 4); + stmt.execute(); + stmt.setInt(1, 2); + stmt.setInt(2, 3); + stmt.setInt(3, 4); + stmt.setInt(4, 5); + stmt.execute(); + stmt.setInt(1, 3); + stmt.setInt(2, 4); + stmt.setInt(3, 5); + stmt.setInt(4, 6); + 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) SALT_BUCKETS=4"); + 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 index) throws SQLException { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), 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(?, ?, ?, ?, ?)"); + stmt.setString(1, "10"); + stmt.setString(2, "2"); + stmt.setInt(3, 3); + stmt.setInt(4, 4); + stmt.setInt(5, 5); + stmt.execute(); + stmt.setString(1, "15"); + stmt.setString(2, "3"); + stmt.setInt(3, 4); + stmt.setInt(4, 5); + stmt.setInt(5, 6); + stmt.execute(); + stmt.setString(1, "20"); + stmt.setString(2, "4"); + stmt.setInt(3, 5); + stmt.setInt(4, 6); + stmt.setInt(5, 7); + stmt.execute(); + stmt.setString(1, "20"); + stmt.setString(2, "5"); + stmt.setInt(3, 6); + stmt.setInt(4, 7); + stmt.setInt(5, 8); + 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(getUrl(), 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(getUrl(), 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(); + } + } + +}
