http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java new file mode 100644 index 0000000..51d3b86 --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.end2end; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.curator.shaded.com.google.common.collect.Lists; +import org.apache.phoenix.query.BaseTest; +import org.apache.phoenix.util.ReadOnlyProps; +import org.apache.phoenix.util.SchemaUtil; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.google.common.collect.Maps; + +/** + * Base class for tests that run with split SYSTEM.CATALOG. + * + */ +@Category(SplitSystemCatalogTests.class) +public class SplitSystemCatalogIT extends BaseTest { + + protected static String SCHEMA1 = "SCHEMA1"; + protected static String SCHEMA2 = "SCHEMA2"; + protected static String SCHEMA3 = "SCHEMA3"; + protected static String SCHEMA4 = "SCHEMA4"; + + protected static String TENANT1 = "tenant1"; + protected static String TENANT2 = "tenant2"; + + @BeforeClass + public static void doSetup() throws Exception { + NUM_SLAVES_BASE = 6; + Map<String, String> props = Collections.emptyMap(); + boolean splitSystemCatalog = (driver == null); + setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator())); + // Split SYSTEM.CATALOG once after the mini-cluster is started + if (splitSystemCatalog) { + splitSystemCatalog(); + } + } + + protected static void splitSystemCatalog() throws SQLException, Exception { + try (Connection conn = DriverManager.getConnection(getUrl())) { + } + String tableName = "TABLE"; + String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, tableName); + String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, tableName); + String fullTableName3 = SchemaUtil.getTableName(SCHEMA3, tableName); + String fullTableName4 = SchemaUtil.getTableName(SCHEMA4, tableName); + ArrayList<String> tableList = Lists.newArrayList(fullTableName1, fullTableName2, fullTableName3); + Map<String, List<String>> tenantToTableMap = Maps.newHashMap(); + tenantToTableMap.put(null, tableList); + tenantToTableMap.put(TENANT1, Lists.newArrayList(fullTableName2, fullTableName3)); + tenantToTableMap.put(TENANT2, Lists.newArrayList(fullTableName4)); + splitSystemCatalog(tenantToTableMap); + } + +}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java new file mode 100644 index 0000000..27fc5c6 --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java @@ -0,0 +1,11 @@ +package org.apache.phoenix.end2end; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SplitSystemCatalogTests { +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java new file mode 100644 index 0000000..1226341 --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java @@ -0,0 +1,244 @@ +package org.apache.phoenix.end2end; + +import static org.apache.phoenix.util.TestUtil.analyzeTable; +import static org.apache.phoenix.util.TestUtil.getAllSplits; +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.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.Pair; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.jdbc.PhoenixConnection; +import org.apache.phoenix.query.KeyRange; +import org.apache.phoenix.query.QueryServices; +import org.apache.phoenix.schema.ReadOnlyTableException; +import org.apache.phoenix.util.ReadOnlyProps; +import org.apache.phoenix.util.ScanUtil; +import org.apache.phoenix.util.SchemaUtil; +import org.apache.phoenix.util.TestUtil; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.collect.Maps; + +@RunWith(Parameterized.class) +public class StatsEnabledSplitSystemCatalogIT extends BaseUniqueNamesOwnClusterIT { + + private String tableDDLOptions; + private boolean transactional; + + public StatsEnabledSplitSystemCatalogIT(boolean transactional) { + StringBuilder optionBuilder = new StringBuilder(); + this.transactional = transactional; + if (transactional) { + optionBuilder.append(" TRANSACTIONAL=true "); + } + this.tableDDLOptions = optionBuilder.toString(); + } + + @Parameters(name = "transactional = {0}") + public static Collection<Boolean> data() { + return Arrays.asList(new Boolean[] { false, true }); + } + + @BeforeClass + public static void doSetup() throws Exception { + NUM_SLAVES_BASE = 3; + Map<String, String> props = Maps.newHashMapWithExpectedSize(1); + props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(20)); + props.put(QueryServices.STATS_UPDATE_FREQ_MS_ATTRIB, Long.toString(5)); + props.put(QueryServices.USE_STATS_FOR_PARALLELIZATION, Boolean.toString(true)); + setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator())); + } + + /** + * Salted tests must be in their own test file to ensure that the underlying + * table is dropped. Otherwise, the splits may not be performed. + * TODO: we should throw in that case + * + * @throws Exception + */ + @Test + public void testSaltedUpdatableViewWithIndex() throws Exception { + testUpdatableViewWithIndex(3, false); + } + + @Test + public void testSaltedUpdatableViewWithLocalIndex() throws Exception { + testUpdatableViewWithIndex(3, true); + } + + @Test + public void testNonSaltedUpdatableViewWithIndex() throws Exception { + testUpdatableViewWithIndex(null, false); + } + + @Test + public void testNonSaltedUpdatableViewWithLocalIndex() throws Exception { + testUpdatableViewWithIndex(null, true); + } + + @Test + public void testUpdatableOnUpdatableView() throws Exception { + String fullTableName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + String fullViewName1 = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + String fullViewName2 = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + String ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE k3 = 2"; + ViewIT.testUpdatableView(fullTableName, fullViewName1, fullViewName2, ddl, null, tableDDLOptions); + Connection conn = DriverManager.getConnection(getUrl()); + ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2); + assertTrue(rs.next()); + assertEquals(1, rs.getInt(1)); + assertEquals(109, rs.getInt(2)); + assertEquals(2, rs.getInt(3)); + assertFalse(rs.next()); + + conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2) VALUES(122)"); + conn.commit(); + rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2 + " WHERE k2 >= 120"); + assertTrue(rs.next()); + assertEquals(1, rs.getInt(1)); + assertEquals(122, rs.getInt(2)); + assertEquals(2, rs.getInt(3)); + assertFalse(rs.next()); + + try { + conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2,k3) VALUES(123,3)"); + fail(); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode()); + } + + try { + conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2,k3) select k2, 3 from " + fullViewName1); + fail(); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode()); + } + } + + private void testUpdatableViewWithIndex(Integer saltBuckets, boolean localIndex) throws Exception { + String schemaName = TestUtil.DEFAULT_SCHEMA_NAME + "_" + generateUniqueName(); + String tableName = "T_" + generateUniqueName(); + String fullTableName = SchemaUtil.getTableName(schemaName, tableName); + String viewName = "V_" + generateUniqueName(); + ViewIT.testUpdatableView(fullTableName, viewName, null, null, saltBuckets, tableDDLOptions); + Pair<String, Scan> pair = ViewIT.testUpdatableViewIndex(fullTableName, saltBuckets, localIndex, viewName); + Scan scan = pair.getSecond(); + String physicalTableName = pair.getFirst(); + // Confirm that dropping the view also deletes the rows in the index + if (saltBuckets == null) { + try (Connection conn = DriverManager.getConnection(getUrl())) { + Table htable = conn.unwrap(PhoenixConnection.class).getQueryServices() + .getTable(Bytes.toBytes(physicalTableName)); + if (ScanUtil.isLocalIndex(scan)) { + ScanUtil.setLocalIndexAttributes(scan, 0, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, + scan.getStartRow(), scan.getStopRow()); + } + ResultScanner scanner = htable.getScanner(scan); + Result result = scanner.next(); + // Confirm index has rows + assertTrue(result != null && !result.isEmpty()); + + conn.createStatement().execute("DROP VIEW " + viewName); + + // Confirm index has no rows after view is dropped + scanner = htable.getScanner(scan); + result = scanner.next(); + assertTrue(result == null || result.isEmpty()); + } + } + } + + @Test + public void testReadOnlyOnReadOnlyView() throws Exception { + Connection earlierCon = DriverManager.getConnection(getUrl()); + Connection conn = DriverManager.getConnection(getUrl()); + String fullTableName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + String fullParentViewName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + String fullViewName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName()); + + String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE) "+ tableDDLOptions; + conn.createStatement().execute(ddl); + ddl = "CREATE VIEW " + fullParentViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5"; + conn.createStatement().execute(ddl); + ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullParentViewName + " WHERE k < 9"; + conn.createStatement().execute(ddl); + + try { + conn.createStatement().execute("UPSERT INTO " + fullParentViewName + " VALUES(1)"); + fail(); + } catch (ReadOnlyTableException e) { + + } + for (int i = 0; i < 10; i++) { + conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + i + ")"); + } + conn.commit(); + + analyzeTable(conn, fullParentViewName, transactional); + + List<KeyRange> splits = getAllSplits(conn, fullParentViewName); + assertEquals(4, splits.size()); + + int count = 0; + ResultSet rs = conn.createStatement().executeQuery("SELECT k FROM " + fullTableName); + while (rs.next()) { + assertEquals(count++, rs.getInt(1)); + } + assertEquals(10, count); + + count = 0; + rs = conn.createStatement().executeQuery("SELECT k FROM " + fullParentViewName); + while (rs.next()) { + count++; + assertEquals(count + 5, rs.getInt(1)); + } + assertEquals(4, count); + count = 0; + rs = earlierCon.createStatement().executeQuery("SELECT k FROM " + fullParentViewName); + while (rs.next()) { + count++; + assertEquals(count + 5, rs.getInt(1)); + } + assertEquals(4, count); + + try { + conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)"); + fail(); + } catch (ReadOnlyTableException e) { + + } finally { + conn.close(); + } + + conn = DriverManager.getConnection(getUrl()); + count = 0; + rs = conn.createStatement().executeQuery("SELECT k FROM " + fullViewName); + while (rs.next()) { + count++; + assertEquals(count + 5, rs.getInt(1)); + } + assertEquals(3, count); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java index 689eb20..aa2d971 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java @@ -17,6 +17,22 @@ */ package org.apache.phoenix.end2end; +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.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeoutException; + import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HConstants; @@ -28,7 +44,11 @@ import org.apache.phoenix.exception.UpgradeRequiredException; import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver; import org.apache.phoenix.jdbc.PhoenixTestDriver; -import org.apache.phoenix.query.*; +import org.apache.phoenix.query.ConnectionQueryServices; +import org.apache.phoenix.query.ConnectionQueryServicesImpl; +import org.apache.phoenix.query.QueryConstants; +import org.apache.phoenix.query.QueryServices; +import org.apache.phoenix.query.QueryServicesTestImpl; import org.apache.phoenix.util.ReadOnlyProps; import org.apache.phoenix.util.UpgradeUtil; import org.junit.After; @@ -36,14 +56,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.*; -import java.util.concurrent.TimeoutException; - -import static org.junit.Assert.*; - @Category(NeedsOwnMiniClusterTest.class) public class SystemCatalogCreationOnConnectionIT { private HBaseTestingUtility testUtil = null; @@ -60,11 +72,11 @@ public class SystemCatalogCreationOnConnectionIT { private static final Set<String> PHOENIX_SYSTEM_TABLES = new HashSet<>(Arrays.asList( "SYSTEM.CATALOG", "SYSTEM.SEQUENCE", "SYSTEM.STATS", "SYSTEM.FUNCTION", - "SYSTEM.MUTEX", "SYSTEM.LOG")); + "SYSTEM.MUTEX", "SYSTEM.LOG", "SYSTEM.CHILD_LINK")); private static final Set<String> PHOENIX_NAMESPACE_MAPPED_SYSTEM_TABLES = new HashSet<>( Arrays.asList("SYSTEM:CATALOG", "SYSTEM:SEQUENCE", "SYSTEM:STATS", "SYSTEM:FUNCTION", - "SYSTEM:MUTEX", "SYSTEM:LOG")); + "SYSTEM:MUTEX", "SYSTEM:LOG", "SYSTEM:CHILD_LINK")); private static class PhoenixSysCatCreationServices extends ConnectionQueryServicesImpl { http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java index 2c7b992..3133b56 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java @@ -23,6 +23,8 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.util.Collections; +import java.util.Map; import java.util.Properties; import org.apache.hadoop.hbase.DoNotRetryIOException; @@ -30,47 +32,49 @@ import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.RegionLocator; import org.apache.phoenix.query.BaseTest; +import org.apache.phoenix.query.QueryServices; import org.apache.phoenix.util.PhoenixRuntime; -import org.junit.After; +import org.apache.phoenix.util.ReadOnlyProps; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import com.google.common.collect.Maps; + @Category(NeedsOwnMiniClusterTest.class) public class SystemCatalogIT extends BaseTest { private HBaseTestingUtility testUtil = null; - - @After - public void cleanup() throws Exception { - if (null != testUtil) { - testUtil.shutdownMiniCluster(); - testUtil = null; - } - } + + @BeforeClass + public static void doSetup() throws Exception { + Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1); + serverProps.put(QueryServices.SYSTEM_CATALOG_SPLITTABLE, "false"); + Map<String, String> clientProps = Collections.emptyMap(); + setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), + new ReadOnlyProps(clientProps.entrySet().iterator())); + } /** - * Make sure that SYSTEM.CATALOG cannot be split, even with schemas and multi-tenant views + * Make sure that SYSTEM.CATALOG cannot be split if QueryServices.SYSTEM_CATALOG_SPLITTABLE is false */ @Test public void testSystemTableSplit() throws Exception { - testUtil = new HBaseTestingUtility(); - testUtil.startMiniCluster(1); + testUtil = getUtility(); for (int i=0; i<10; i++) { createTable("schema"+i+".table_"+i); } TableName systemCatalog = TableName.valueOf("SYSTEM.CATALOG"); RegionLocator rl = testUtil.getConnection().getRegionLocator(systemCatalog); assertEquals(rl.getAllRegionLocations().size(), 1); - - try{ - // now attempt to split SYSTEM.CATALOG - testUtil.getAdmin().split(systemCatalog); - - // make sure the split finishes (there's no synchronous splitting before HBase 2.x) - testUtil.getAdmin().disableTable(systemCatalog); - testUtil.getAdmin().enableTable(systemCatalog); - }catch(DoNotRetryIOException e){ - //table is not splittable - assert(e.getMessage().contains("NOT splittable")); + try { + // now attempt to split SYSTEM.CATALOG + testUtil.getAdmin().split(systemCatalog); + // make sure the split finishes (there's no synchronous splitting before HBase 2.x) + testUtil.getAdmin().disableTable(systemCatalog); + testUtil.getAdmin().enableTable(systemCatalog); + } catch (DoNotRetryIOException e) { + // table is not splittable + assert (e.getMessage().contains("NOT splittable")); } // test again... Must still be exactly one region. http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java index 1476b6c..6447cb5 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java @@ -379,11 +379,12 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT { connTenant2 = DriverManager.getConnection(PHOENIX_JDBC_TENANT_SPECIFIC_URL2, props); validateTenantViewIsDropped(connTenant2); + // TODO uncomment after PHOENIX-4764 is implemented // Validate Tenant Metadata is gone for the Tenant Table TENANT_TABLE_NAME - rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME), new String[] {PTableType.VIEW.getValue().getString()}); - assertFalse(rs.next()); - rs = meta.getTables(null, "", StringUtil.escapeLike(tenantTable2), new String[] {PTableType.VIEW.getValue().getString()}); - assertFalse(rs.next()); +// rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME), new String[] {PTableType.VIEW.getValue().getString()}); +// assertFalse(rs.next()); +// rs = meta.getTables(null, "", StringUtil.escapeLike(tenantTable2), new String[] {PTableType.VIEW.getValue().getString()}); +// assertFalse(rs.next()); rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME_NO_TENANT_TYPE_ID), new String[] {PTableType.VIEW.getValue().getString()}); assertTrue(rs.next()); @@ -491,6 +492,8 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT { assertTrue(rs.next()); assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE, PTableType.SYSTEM); assertTrue(rs.next()); + assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_TABLE, PTableType.SYSTEM); + assertTrue(rs.next()); assertTableMetaData(rs, SYSTEM_CATALOG_SCHEMA, SYSTEM_FUNCTION_TABLE, SYSTEM); assertTrue(rs.next()); assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_LOG_TABLE, PTableType.SYSTEM); @@ -530,7 +533,7 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT { assertTrue(rs.next()); // (tenant_id column is not visible in tenant-specific connection) assertColumnMetaData(rs, null, TENANT_TABLE_NAME, "tenant_type_id", 2); - assertEquals(1, rs.getInt(KEY_SEQ)); + assertEquals(1, rs.getShort(KEY_SEQ)); assertTrue(rs.next()); assertColumnMetaData(rs, null, TENANT_TABLE_NAME, "id", 3); assertTrue(rs.next()); http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java index d5da0aa..31f3569 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java @@ -29,20 +29,23 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.SQLException; +import java.util.List; +import java.util.Map; import java.util.Properties; import org.apache.hadoop.hbase.util.Bytes; import org.apache.phoenix.query.QueryServices; import org.apache.phoenix.schema.ColumnNotFoundException; import org.apache.phoenix.schema.PNameFactory; -import org.apache.phoenix.schema.PTableType; import org.apache.phoenix.util.MetaDataUtil; import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.QueryUtil; import org.apache.phoenix.util.SchemaUtil; import org.junit.Test; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { @@ -115,38 +118,40 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { } private void testMultiCFViewIndex(boolean localIndex, boolean isNamespaceEnabled) throws Exception { - String tableName = "XYZ." + generateUniqueName(); - String baseViewName = generateUniqueName() ; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewName2 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName()); createTableAndValidate(tableName, isNamespaceEnabled); - createViewAndIndexesWithTenantId(tableName, baseViewName, localIndex, "b", isNamespaceEnabled); - createViewAndIndexesWithTenantId(tableName, baseViewName, localIndex, "a", isNamespaceEnabled); - - String sequenceNameA = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName("a"), isNamespaceEnabled); - String sequenceNameB = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName("b"), isNamespaceEnabled); + String tenantId1 = TENANT1; + String tenantId2 = TENANT2; + createViewAndIndexesWithTenantId(tableName, viewName1, localIndex, tenantId1, isNamespaceEnabled); + createViewAndIndexesWithTenantId(tableName, viewName2, localIndex, tenantId2, isNamespaceEnabled); + + String sequenceNameA = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName(tenantId2), isNamespaceEnabled); + String sequenceNameB = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName(tenantId1), isNamespaceEnabled); String sequenceSchemaName = getViewIndexSequenceSchemaName(PNameFactory.newName(tableName), isNamespaceEnabled); - verifySequenceValue(isNamespaceEnabled? "a" : null, sequenceNameA, sequenceSchemaName, -32767); - verifySequenceValue(isNamespaceEnabled? "b" : null, sequenceNameB, sequenceSchemaName, -32767); + verifySequenceValue(isNamespaceEnabled? tenantId2 : null, sequenceNameA, sequenceSchemaName, -32767); + verifySequenceValue(isNamespaceEnabled? tenantId1 : null, sequenceNameB, sequenceSchemaName, -32767); Properties props = new Properties(); - props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "a"); + props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId2); try (Connection conn = DriverManager.getConnection(getUrl(), props)) { - conn.createStatement().execute("DROP VIEW " + baseViewName + "_a"); + conn.createStatement().execute("DROP VIEW " + viewName2); } - props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "b"); + props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId1); try (Connection conn = DriverManager.getConnection(getUrl(), props)) { - conn.createStatement().execute("DROP VIEW " + baseViewName + "_b"); + conn.createStatement().execute("DROP VIEW " + viewName1); } DriverManager.getConnection(getUrl()).createStatement().execute("DROP TABLE " + tableName + " CASCADE"); - verifySequenceNotExists(isNamespaceEnabled? "a" : null, sequenceNameA, sequenceSchemaName); - verifySequenceNotExists(isNamespaceEnabled? "b" : null, sequenceNameB, sequenceSchemaName); + verifySequenceNotExists(isNamespaceEnabled? tenantId2 : null, sequenceNameA, sequenceSchemaName); + verifySequenceNotExists(isNamespaceEnabled? tenantId1 : null, sequenceNameB, sequenceSchemaName); } - private void createViewAndIndexesWithTenantId(String tableName,String baseViewName, boolean localIndex, String tenantId, + private void createViewAndIndexesWithTenantId(String tableName, String viewName, boolean localIndex, String tenantId, boolean isNamespaceMapped) throws Exception { Properties props = new Properties(); - String viewName = baseViewName + "_" + tenantId; - String indexName = "idx_" + viewName; + String indexName = "I_"+ generateUniqueName(); if (tenantId != null) { props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); } @@ -239,15 +244,15 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { assertFalse(rs.next()); conn.close(); - } @Test public void testNonPaddedTenantId() throws Exception { - String tenantId1 = "org1"; - String tenantId2 = "org2"; - String tableName = generateUniqueName(); - String viewName = generateUniqueName(); + String tenantId1 = TENANT1; + String tenantId2 = TENANT2; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddl = "CREATE TABLE " + tableName + " (tenantId char(15) NOT NULL, pk1 varchar NOT NULL, pk2 INTEGER NOT NULL, val1 VARCHAR CONSTRAINT pk primary key (tenantId,pk1,pk2)) MULTI_TENANT = true"; Connection conn = DriverManager.getConnection(getUrl()); conn.createStatement().execute(ddl); @@ -288,10 +293,11 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { } @Test - public void testOverlappingDatesFilter() throws SQLException { - String tenantUrl = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1" + ";" + QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB + "=true"; - String tableName = generateUniqueName(); - String viewName = generateUniqueName(); + public void testOverlappingDatesFilter() throws Exception { + String tenantId = TENANT1; + String tenantUrl = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + tenantId + ";" + QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB + "=true"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); String ddl = "CREATE TABLE " + tableName + "(ORGANIZATION_ID CHAR(15) NOT NULL, " + "PARENT_TYPE CHAR(3) NOT NULL, " @@ -315,7 +321,9 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { + "ORDER BY PARENT_TYPE,CREATED_DATE LIMIT 501"; ResultSet rs = viewConn.createStatement().executeQuery(query); - String expectedPlanFormat = "CLIENT SERIAL 1-WAY RANGE SCAN OVER IDX ['tenant1 ','001','%s 00:00:00.001'] - ['tenant1 ','001','%s 00:00:00.000']" + "\n" + + String exptectedIndexName = SchemaUtil.getTableName(SCHEMA1, "IDX"); + String expectedPlanFormat = "CLIENT SERIAL 1-WAY RANGE SCAN OVER " + exptectedIndexName + + " ['tenant1 ','001','%s 00:00:00.001'] - ['tenant1 ','001','%s 00:00:00.000']" + "\n" + " SERVER FILTER BY FIRST KEY ONLY" + "\n" + " SERVER 501 ROW LIMIT" + "\n" + "CLIENT 501 ROW LIMIT"; http://git-wip-us.apache.org/repos/asf/phoenix/blob/d56fd3c9/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java index a558c21..80c92ea 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java @@ -17,13 +17,9 @@ */ package org.apache.phoenix.end2end; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.apache.phoenix.query.ConnectionQueryServicesImpl.UPGRADE_MUTEX; import static org.apache.phoenix.query.ConnectionQueryServicesImpl.UPGRADE_MUTEX_UNLOCKED; -import static org.apache.phoenix.query.QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT; -import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT; -import static org.apache.phoenix.util.UpgradeUtil.SELECT_BASE_COLUMN_COUNT_FROM_HEADER_ROW; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -36,8 +32,6 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collections; import java.util.Properties; import java.util.Set; import java.util.concurrent.Callable; @@ -46,11 +40,10 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.hadoop.hbase.HConstants; +import org.apache.curator.shaded.com.google.common.collect.Sets; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.snapshot.SnapshotCreationException; import org.apache.hadoop.hbase.util.Bytes; @@ -77,93 +70,10 @@ import org.apache.phoenix.util.PropertiesUtil; import org.apache.phoenix.util.SchemaUtil; import org.apache.phoenix.util.TestUtil; import org.apache.phoenix.util.UpgradeUtil; -import org.junit.Before; import org.junit.Test; -import com.google.common.collect.Sets; - public class UpgradeIT extends ParallelStatsDisabledIT { - private String tenantId; - - @Before - public void generateTenantId() { - tenantId = "T_" + generateUniqueName(); - } - - @Test - public void testUpgradeForTenantViewWithSameColumnsAsBaseTable() throws Exception { - String tableWithViewName = generateUniqueName(); - String viewTableName = generateUniqueName(); - testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.EQUAL); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", - ColumnDiff.EQUAL); - testViewUpgrade(true, tenantId, null, tableWithViewName + "3", viewTableName + "SCHEMA", viewTableName + "3", - ColumnDiff.EQUAL); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", viewTableName + "SCHEMA", viewTableName + "4", - ColumnDiff.EQUAL); - testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5", - ColumnDiff.EQUAL); - } - - @Test - public void testUpgradeForTenantViewWithMoreColumnsThanBaseTable() throws Exception { - String tableWithViewName = generateUniqueName(); - String viewTableName = generateUniqueName(); - testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", - ColumnDiff.MORE); - testViewUpgrade(true, tenantId, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3", - ColumnDiff.MORE); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4", - ColumnDiff.MORE); - testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5", - ColumnDiff.MORE); - } - - @Test - public void testUpgradeForViewWithSameColumnsAsBaseTable() throws Exception { - String tableWithViewName = generateUniqueName(); - String viewTableName = generateUniqueName(); - testViewUpgrade(false, null, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.EQUAL); - testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", - ColumnDiff.EQUAL); - testViewUpgrade(false, null, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3", - ColumnDiff.EQUAL); - testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4", - ColumnDiff.EQUAL); - testViewUpgrade(false, null, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5", - ColumnDiff.EQUAL); - } - - @Test - public void testUpgradeForViewWithMoreColumnsThanBaseTable() throws Exception { - String tableWithViewName = generateUniqueName(); - String viewTableName = generateUniqueName(); - testViewUpgrade(false, null, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE); - testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", ColumnDiff.MORE); - testViewUpgrade(false, null, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3", ColumnDiff.MORE); - testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4", - ColumnDiff.MORE); - testViewUpgrade(false, null, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5", - ColumnDiff.MORE); - } - - @Test - public void testSettingBaseColumnCountWhenBaseTableColumnDropped() throws Exception { - String tableWithViewName = generateUniqueName(); - String viewTableName = generateUniqueName(); - testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", - ColumnDiff.LESS); - testViewUpgrade(true, tenantId, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3", - ColumnDiff.LESS); - testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4", - ColumnDiff.LESS); - testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5", - ColumnDiff.LESS); - } - @Test public void testMapTableToNamespaceDuringUpgrade() throws SQLException, IOException, IllegalArgumentException, InterruptedException { @@ -234,7 +144,6 @@ public class UpgradeIT extends ParallelStatsDisabledIT { admin.close(); PhoenixConnection phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName); - UpgradeUtil.mapChildViewsToNamespace(phxConn, phoenixFullTableName,props); phxConn.close(); props = new Properties(); phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); @@ -367,7 +276,6 @@ public class UpgradeIT extends ParallelStatsDisabledIT { props.setProperty(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, Boolean.toString(false)); PhoenixConnection phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName); - UpgradeUtil.mapChildViewsToNamespace(phxConn,phoenixFullTableName,props); props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); // purge MetaDataCache except for system tables @@ -424,222 +332,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT { assertTrue(rs.next()); assertTrue(rs.getString(1).contains(hbaseTableName)); } - - - @Test - public void testSettingBaseColumnCountForMultipleViewsOnTable() throws Exception { - String baseSchema = "S_" + generateUniqueName(); - String baseTable = "T_" + generateUniqueName(); - String fullBaseTableName = SchemaUtil.getTableName(baseSchema, baseTable); - try (Connection conn = DriverManager.getConnection(getUrl())) { - String baseTableDDL = "CREATE TABLE " + fullBaseTableName + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 INTEGER, V2 INTEGER CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true"; - conn.createStatement().execute(baseTableDDL); - - String[] tenants = new String[] {"T_" + generateUniqueName(), "T_" + generateUniqueName()}; - Collections.sort(Arrays.asList(tenants)); - String[] tenantViews = new String[] {"V_" + generateUniqueName(), "V_" + generateUniqueName(), "V_" + generateUniqueName()}; - Collections.sort(Arrays.asList(tenantViews)); - String[] globalViews = new String[] {"G_" + generateUniqueName(), "G_" + generateUniqueName(), "G_" + generateUniqueName()}; - Collections.sort(Arrays.asList(globalViews)); - for (int i = 0; i < 2; i++) { - // Create views for tenants; - String tenant = tenants[i]; - try (Connection tenantConn = createTenantConnection(tenant)) { - String view = tenantViews[0]; - // view with its own column - String viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName; - tenantConn.createStatement().execute(viewDDL); - String addCols = "ALTER VIEW " + view + " ADD COL1 VARCHAR "; - tenantConn.createStatement().execute(addCols); - removeBaseColumnCountKV(tenant, null, view); - - // view that has the last base table column removed - view = tenantViews[1]; - viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName; - tenantConn.createStatement().execute(viewDDL); - String droplastBaseCol = "ALTER VIEW " + view + " DROP COLUMN V2"; - tenantConn.createStatement().execute(droplastBaseCol); - removeBaseColumnCountKV(tenant, null, view); - - // view that has the middle base table column removed - view = tenantViews[2]; - viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName; - tenantConn.createStatement().execute(viewDDL); - String dropMiddileBaseCol = "ALTER VIEW " + view + " DROP COLUMN V1"; - tenantConn.createStatement().execute(dropMiddileBaseCol); - removeBaseColumnCountKV(tenant, null, view); - } - } - - // create global views - try (Connection globalConn = DriverManager.getConnection(getUrl())) { - String globalView = globalViews[0]; - // view with its own column - String viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName; - globalConn.createStatement().execute(viewDDL); - String addCols = "ALTER VIEW " + globalView + " ADD COL1 VARCHAR "; - globalConn.createStatement().execute(addCols); - removeBaseColumnCountKV(null, null, globalView); - - // view that has the last base table column removed - globalView = globalViews[1]; - viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName; - globalConn.createStatement().execute(viewDDL); - String droplastBaseCol = "ALTER VIEW " + globalView + " DROP COLUMN V2"; - globalConn.createStatement().execute(droplastBaseCol); - removeBaseColumnCountKV(null, null, globalView); - - // view that has the middle base table column removed - globalView = globalViews[2]; - viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName; - globalConn.createStatement().execute(viewDDL); - String dropMiddileBaseCol = "ALTER VIEW " + globalView + " DROP COLUMN V1"; - globalConn.createStatement().execute(dropMiddileBaseCol); - removeBaseColumnCountKV(null, null, globalView); - } - - // run upgrade - upgradeTo4_5_0(conn); - - // Verify base column counts for tenant specific views - for (int i = 0; i < 2 ; i++) { - String tenantId = tenants[i]; - checkBaseColumnCount(tenantId, null, tenantViews[0], 4); - checkBaseColumnCount(tenantId, null, tenantViews[1], DIVERGED_VIEW_BASE_COLUMN_COUNT); - checkBaseColumnCount(tenantId, null, tenantViews[2], DIVERGED_VIEW_BASE_COLUMN_COUNT); - } - - // Verify base column count for global views - checkBaseColumnCount(null, null, globalViews[0], 4); - checkBaseColumnCount(null, null, globalViews[1], DIVERGED_VIEW_BASE_COLUMN_COUNT); - checkBaseColumnCount(null, null, globalViews[2], DIVERGED_VIEW_BASE_COLUMN_COUNT); - } - - } - - private static void upgradeTo4_5_0(Connection conn) throws SQLException { - PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); - pconn.setRunningUpgrade(true); - UpgradeUtil.upgradeTo4_5_0(pconn); - } - - private enum ColumnDiff { - MORE, EQUAL, LESS - }; - - private void testViewUpgrade(boolean tenantView, String tenantId, String baseTableSchema, - String baseTableName, String viewSchema, String viewName, ColumnDiff diff) - throws Exception { - if (tenantView) { - checkNotNull(tenantId); - } else { - checkArgument(tenantId == null); - } - Connection conn = DriverManager.getConnection(getUrl()); - String fullViewName = SchemaUtil.getTableName(viewSchema, viewName); - String fullBaseTableName = SchemaUtil.getTableName(baseTableSchema, baseTableName); - try { - int expectedBaseColumnCount; - conn.createStatement().execute( - "CREATE TABLE IF NOT EXISTS " + fullBaseTableName + " (" - + " TENANT_ID CHAR(15) NOT NULL, " + " PK1 integer NOT NULL, " - + "PK2 bigint NOT NULL, " + "CF1.V1 VARCHAR, " + "CF2.V2 VARCHAR, " - + "V3 CHAR(100) ARRAY[4] " - + " CONSTRAINT NAME_PK PRIMARY KEY (TENANT_ID, PK1, PK2)" - + " ) MULTI_TENANT= true"); - - // create a view with same columns as base table. - try (Connection conn2 = getConnection(tenantView, tenantId)) { - conn2.createStatement().execute( - "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullBaseTableName); - } - - if (diff == ColumnDiff.MORE) { - // add a column to the view - try (Connection conn3 = getConnection(tenantView, tenantId)) { - conn3.createStatement().execute( - "ALTER VIEW " + fullViewName + " ADD VIEW_COL1 VARCHAR"); - } - } - if (diff == ColumnDiff.LESS) { - try (Connection conn3 = getConnection(tenantView, tenantId)) { - conn3.createStatement().execute( - "ALTER VIEW " + fullViewName + " DROP COLUMN CF2.V2"); - } - expectedBaseColumnCount = DIVERGED_VIEW_BASE_COLUMN_COUNT; - } else { - expectedBaseColumnCount = 6; - } - - checkBaseColumnCount(tenantId, viewSchema, viewName, expectedBaseColumnCount); - checkBaseColumnCount(null, baseTableSchema, baseTableName, BASE_TABLE_BASE_COLUMN_COUNT); - - // remove base column count kv so we can check whether the upgrade code is setting the - // base column count correctly. - removeBaseColumnCountKV(tenantId, viewSchema, viewName); - removeBaseColumnCountKV(null, baseTableSchema, baseTableName); - - // assert that the removing base column count key value worked correctly. - checkBaseColumnCount(tenantId, viewSchema, viewName, 0); - checkBaseColumnCount(null, baseTableSchema, baseTableName, 0); - - // run upgrade - upgradeTo4_5_0(conn); - - checkBaseColumnCount(tenantId, viewSchema, viewName, expectedBaseColumnCount); - checkBaseColumnCount(null, baseTableSchema, baseTableName, BASE_TABLE_BASE_COLUMN_COUNT); - } finally { - conn.close(); - } - } - - private static void checkBaseColumnCount(String tenantId, String schemaName, String tableName, - int expectedBaseColumnCount) throws Exception { - checkNotNull(tableName); - Connection conn = DriverManager.getConnection(getUrl()); - String sql = SELECT_BASE_COLUMN_COUNT_FROM_HEADER_ROW; - sql = - String.format(sql, tenantId == null ? " IS NULL " : " = ? ", - schemaName == null ? "IS NULL" : " = ? "); - int paramIndex = 1; - PreparedStatement stmt = conn.prepareStatement(sql); - if (tenantId != null) { - stmt.setString(paramIndex++, tenantId); - } - if (schemaName != null) { - stmt.setString(paramIndex++, schemaName); - } - stmt.setString(paramIndex, tableName); - ResultSet rs = stmt.executeQuery(); - assertTrue(rs.next()); - assertEquals(expectedBaseColumnCount, rs.getInt(1)); - assertFalse(rs.next()); - } - - private static void - removeBaseColumnCountKV(String tenantId, String schemaName, String tableName) - throws Exception { - byte[] rowKey = - SchemaUtil.getTableKey(tenantId == null ? new byte[0] : Bytes.toBytes(tenantId), - schemaName == null ? new byte[0] : Bytes.toBytes(schemaName), - Bytes.toBytes(tableName)); - Put viewColumnDefinitionPut = new Put(rowKey, HConstants.LATEST_TIMESTAMP); - viewColumnDefinitionPut.addColumn(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, - PhoenixDatabaseMetaData.BASE_COLUMN_COUNT_BYTES, HConstants.LATEST_TIMESTAMP, null); - - try (PhoenixConnection conn = - (DriverManager.getConnection(getUrl())).unwrap(PhoenixConnection.class)) { - try (Table htable = - conn.getQueryServices().getTable( - Bytes.toBytes(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME))) { - RowMutations mutations = new RowMutations(rowKey); - mutations.add(viewColumnDefinitionPut); - htable.mutateRow(mutations); - } - } - } - @Test public void testUpgradeRequiredPreventsSQL() throws SQLException { String tableName = generateUniqueName(); @@ -710,8 +403,8 @@ public class UpgradeIT extends ParallelStatsDisabledIT { return true; } }; - try (PhoenixConnection phxConn = new PhoenixConnection(servicesWithUpgrade, - conn.unwrap(PhoenixConnection.class), HConstants.LATEST_TIMESTAMP)) { + try (PhoenixConnection phxConn = new PhoenixConnection(conn.unwrap(PhoenixConnection.class), + servicesWithUpgrade, conn.getClientInfo())) { // Because upgrade is required, this SQL should fail. try { phxConn.createStatement().executeQuery("SELECT * FROM " + tableName); @@ -842,7 +535,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT { } @Test - public void testAddParentChildLinks() throws Exception { + public void testMoveParentChildLinks() throws Exception { String schema = "S_" + generateUniqueName(); String table1 = "T_" + generateUniqueName(); String table2 = "T_" + generateUniqueName(); @@ -882,13 +575,16 @@ public class UpgradeIT extends ParallelStatsDisabledIT { Set<String> expectedChildLinkSet = getChildLinks(conn); // delete all the child links - conn.createStatement().execute("DELETE FROM SYSTEM.CATALOG WHERE LINK_TYPE = " + conn.createStatement().execute("DELETE FROM SYSTEM.CHILD_LINK WHERE LINK_TYPE = " + LinkType.CHILD_TABLE.getSerializedValue()); // re-create them by running the upgrade code PhoenixConnection phxMetaConn = metaConn.unwrap(PhoenixConnection.class); phxMetaConn.setRunningUpgrade(true); + // create the parent-> child links in SYSTEM.CATALOG UpgradeUtil.addParentToChildLinks(phxMetaConn); + // move the parent->child links to SYSTEM.CHILD_LINK + UpgradeUtil.moveChildLinks(phxMetaConn); Set<String> actualChildLinkSet = getChildLinks(conn); assertEquals("Unexpected child links", expectedChildLinkSet, actualChildLinkSet); @@ -898,7 +594,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT { private Set<String> getChildLinks(Connection conn) throws SQLException { ResultSet rs = conn.createStatement().executeQuery( - "SELECT TENANT_ID, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, COLUMN_FAMILY FROM SYSTEM.CATALOG WHERE LINK_TYPE = " + "SELECT TENANT_ID, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, COLUMN_FAMILY FROM SYSTEM.CHILD_LINK WHERE LINK_TYPE = " + LinkType.CHILD_TABLE.getSerializedValue()); Set<String> childLinkSet = Sets.newHashSet(); while (rs.next()) {