http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java index ab3a4ab..e39d492 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java @@ -21,6 +21,8 @@ import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE; import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -33,37 +35,46 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Arrays; import java.util.Collection; -import java.util.Properties; +import java.util.List; import org.apache.commons.lang.ArrayUtils; -import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.HTable; +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.phoenix.coprocessor.TephraTransactionalProcessor; import org.apache.phoenix.exception.SQLExceptionCode; import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.query.QueryConstants; +import org.apache.phoenix.schema.ColumnNotFoundException; +import org.apache.phoenix.schema.PColumn; import org.apache.phoenix.schema.PName; import org.apache.phoenix.schema.PNameFactory; import org.apache.phoenix.schema.PTable; import org.apache.phoenix.schema.PTableKey; import org.apache.phoenix.schema.PTableType; -import org.apache.phoenix.util.PropertiesUtil; -import org.apache.phoenix.util.StringUtil; -import org.apache.phoenix.util.TestUtil; +import org.apache.phoenix.schema.TableNotFoundException; +import org.apache.phoenix.util.IndexUtil; +import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.SchemaUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import com.google.common.base.Function; +import com.google.common.collect.Lists; + @RunWith(Parameterized.class) -public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { - +public class AlterTableWithViewsIT extends SplitSystemCatalogIT { + private final boolean isMultiTenant; private final boolean columnEncoded; - - private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1"; - private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant2"; + private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT1; + private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT2; public AlterTableWithViewsIT(boolean isMultiTenant, boolean columnEncoded) { this.isMultiTenant = isMultiTenant; @@ -77,6 +88,14 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { { true, false }, { true, true } }); } + // transform PColumn to String + private Function<PColumn,String> function = new Function<PColumn,String>(){ + @Override + public String apply(PColumn input) { + return input.getName().getString(); + } + }; + private String generateDDL(String format) { return generateDDL("", format); } @@ -101,8 +120,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { public void testAddNewColumnsToBaseTableWithViews() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String tableName = generateUniqueName(); - String viewOfTable = tableName + "_VIEW"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(1) NOT NULL," + " COL1 integer NOT NULL," @@ -113,12 +133,13 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); // adding a new pk column and a new regular column conn.createStatement().execute("ALTER TABLE " + tableName + " ADD COL3 varchar(10) PRIMARY KEY, COL4 integer"); assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4"); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 7, 5, "ID", "COL1", "COL2", "COL3", "COL4", "VIEW_COL1", "VIEW_COL2"); + // add/drop column to a base table are no longer propagated to child views + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); } } @@ -126,9 +147,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { public void testAlterPropertiesOfParentTable() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String tableName = generateUniqueName(); - String viewOfTable1 = tableName + "_VIEW1"; - String viewOfTable2 = tableName + "_VIEW2"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewOfTable2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(1) NOT NULL," + " COL1 integer NOT NULL," @@ -138,11 +160,12 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { conn.createStatement().execute(generateDDL("UPDATE_CACHE_FREQUENCY=2", ddlFormat)); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName); + viewConn.createStatement().execute("ALTER VIEW " + viewOfTable2 + " SET UPDATE_CACHE_FREQUENCY = 1"); PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class); PTable table = phoenixConn.getTable(new PTableKey(null, tableName)); - PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; assertFalse(table.isImmutableRows()); assertEquals(2, table.getUpdateCacheFrequency()); PTable viewTable1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1)); @@ -166,7 +189,7 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { viewTable1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1)); assertTrue(viewTable1.isImmutableRows()); - assertEquals(3, viewTable1.getUpdateCacheFrequency()); + assertEquals(2, viewTable1.getUpdateCacheFrequency()); viewTable2 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable2)); assertTrue(viewTable2.isImmutableRows()); @@ -178,16 +201,20 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { ResultSet rs; DatabaseMetaData md = conn.getMetaData(); - rs = md.getTables("", "", StringUtil.escapeLike(tableName), null); + rs = + md.getTables("", SchemaUtil.getSchemaNameFromFullName(tableName), + SchemaUtil.getTableNameFromFullName(tableName), null); assertTrue(rs.next()); assertEquals(gpw, rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH)); - rs = md.getTables(null, "", StringUtil.escapeLike(viewOfTable1), null); + rs = md.getTables(null, SchemaUtil.getSchemaNameFromFullName(viewOfTable1), + SchemaUtil.getTableNameFromFullName(viewOfTable1), null); assertTrue(rs.next()); rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH); assertTrue(rs.wasNull()); - rs = md.getTables(null, "", StringUtil.escapeLike(viewOfTable2), null); + rs = md.getTables(null, SchemaUtil.getSchemaNameFromFullName(viewOfTable2), + SchemaUtil.getTableNameFromFullName(viewOfTable2), null); assertTrue(rs.next()); rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH); assertTrue(rs.wasNull()); @@ -198,8 +225,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { public void testDropColumnsFromBaseTableWithView() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String tableName = generateUniqueName(); - String viewOfTable = tableName + "_VIEW"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(1) NOT NULL," + " COL1 integer NOT NULL," + " COL2 bigint NOT NULL," + " COL3 varchar(10)," + " COL4 varchar(10)," + " COL5 varchar(10)," @@ -212,15 +240,16 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { viewConn.createStatement() .execute( "CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6, + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6, "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2"); // drop two columns from the base table conn.createStatement().execute("ALTER TABLE " + tableName + " DROP COLUMN COL3, COL5"); assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL4"); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 6, 4, - "ID", "COL1", "COL2", "COL4", "VIEW_COL1", "VIEW_COL2"); + // the columns will still exist in the view metadata , but are excluded while combining parent table columns + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6, + "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2"); } } @@ -230,33 +259,35 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { conn.setAutoCommit(false); viewConn.setAutoCommit(false); - String tableName = generateUniqueName(); - String viewOfTable = tableName + "_VIEW"; - + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(10) NOT NULL," + " COL1 integer NOT NULL," + " COL2 bigint NOT NULL," + + " COL3 varchar," + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)" + " ) %s"; conn.createStatement().execute(generateDDL(ddlFormat)); - assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); + assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256), VIEW_COL3 VARCHAR, VIEW_COL4 DECIMAL, VIEW_COL5 DECIMAL(10,2), VIEW_COL6 VARCHAR, CONSTRAINT pk PRIMARY KEY (VIEW_COL5, VIEW_COL6) ) AS SELECT * FROM " + tableName); - assertTableDefinition(conn,viewOfTable, PTableType.VIEW, tableName, 0, 9, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6"); + assertTableDefinition(viewConn,viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6"); // upsert single row into view - String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?, ?, ?, ?, ?)"; + String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?, ?, ?, ?, ?, ?)"; PreparedStatement stmt = viewConn.prepareStatement(dml); stmt.setString(1, "view1"); stmt.setInt(2, 12); stmt.setInt(3, 13); - stmt.setInt(4, 14); - stmt.setString(5, "view5"); + stmt.setString(4, "view4"); + stmt.setInt(5, 15); stmt.setString(6, "view6"); - stmt.setInt(7, 17); + stmt.setString(7, "view7"); stmt.setInt(8, 18); - stmt.setString(9, "view9"); + stmt.setInt(9, 19); + stmt.setString(10, "view10"); stmt.execute(); viewConn.commit(); @@ -297,8 +328,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { } // validate that there were no columns added to the table or view, if its table is column encoded the sequence number changes when we increment the cq counter - assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 9, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6"); + assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3"); + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6"); if (columnEncoded) { try { @@ -312,17 +343,19 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { else { // should succeed conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL4 DECIMAL, VIEW_COL2 VARCHAR(256)"); - assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL4", "VIEW_COL2"); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 9, 5, "ID", "COL1", "COL2", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6"); - + assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 6, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2"); + // even though we added columns to the base table, the view metadata remains the same as the base table metadata changes are no longer propagated to the chid view + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6"); + // query table ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName); assertTrue(rs.next()); assertEquals("view1", rs.getString("ID")); assertEquals(12, rs.getInt("COL1")); assertEquals(13, rs.getInt("COL2")); - assertEquals("view5", rs.getString("VIEW_COL2")); - assertEquals(17, rs.getInt("VIEW_COL4")); + assertEquals("view4", rs.getString("COL3")); + assertEquals("view6", rs.getString("VIEW_COL2")); + assertEquals(18, rs.getInt("VIEW_COL4")); assertFalse(rs.next()); // query view @@ -331,13 +364,20 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertEquals("view1", rs.getString("ID")); assertEquals(12, rs.getInt("COL1")); assertEquals(13, rs.getInt("COL2")); - assertEquals(14, rs.getInt("VIEW_COL1")); - assertEquals("view5", rs.getString("VIEW_COL2")); - assertEquals("view6", rs.getString("VIEW_COL3")); - assertEquals(17, rs.getInt("VIEW_COL4")); - assertEquals(18, rs.getInt("VIEW_COL5")); - assertEquals("view9", rs.getString("VIEW_COL6")); + assertEquals("view4", rs.getString("COL3")); + assertEquals(15, rs.getInt("VIEW_COL1")); + assertEquals("view6", rs.getString("VIEW_COL2")); + assertEquals("view7", rs.getString("VIEW_COL3")); + assertEquals(18, rs.getInt("VIEW_COL4")); + assertEquals(19, rs.getInt("VIEW_COL5")); + assertEquals("view10", rs.getString("VIEW_COL6")); assertFalse(rs.next()); + + // the base column count and ordinal positions of columns is updated in the ptable (at read time) + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; + PTable view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)); + assertEquals(isMultiTenant ? 5: 4, view.getBaseColumnCount()); + assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6"); } } } @@ -348,8 +388,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { conn.setAutoCommit(false); viewConn.setAutoCommit(false); - String tableName = generateUniqueName(); - String viewOfTable = tableName + "_VIEW"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(10) NOT NULL," @@ -359,9 +399,13 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { + " ) %s"; conn.createStatement().execute(generateDDL(ddlFormat)); assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); + PTable table = PhoenixRuntime.getTableNoCache(conn, tableName.toUpperCase()); + assertColumnsMatch(table.getColumns(), "ID", "COL1", "COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + PTable view = PhoenixRuntime.getTableNoCache(viewConn, viewOfTable.toUpperCase()); + assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); // upsert single row into view String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?)"; @@ -431,7 +475,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { // add the pk column of the view to the base table conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY"); assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + // even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG) + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); // query table ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName); @@ -452,6 +497,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertEquals(14, rs.getInt("VIEW_COL1")); assertEquals("view5", rs.getString("VIEW_COL2")); assertFalse(rs.next()); + + // the base column count is updated in the ptable + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; + view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)); + assertEquals(isMultiTenant ? 4 : 3, view.getBaseColumnCount()); } } @@ -459,9 +509,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { public void testAddExistingViewPkColumnToBaseTableWithMultipleViews() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String tableName = generateUniqueName(); - String viewOfTable1 = tableName + "_VIEW1"; - String viewOfTable2 = tableName + "_VIEW2"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewOfTable2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + "(" + " %s ID char(10) NOT NULL," + " COL1 integer NOT NULL," @@ -472,10 +523,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL3 VARCHAR(256), VIEW_COL4 DECIMAL(10,2) CONSTRAINT pk PRIMARY KEY (VIEW_COL3, VIEW_COL4)) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4"); + assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4"); try { // should fail because there are two view with different pk columns @@ -523,9 +574,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { conn.setAutoCommit(false); viewConn.setAutoCommit(false); viewConn2.setAutoCommit(false); - String tableName = generateUniqueName(); - String viewOfTable1 = tableName + "_VIEW1"; - String viewOfTable2 = tableName + "_VIEW2"; + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewOfTable2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + "(" + " %s ID char(10) NOT NULL," + " COL1 integer NOT NULL," @@ -536,11 +588,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); viewConn2.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName); - assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); - + assertTableDefinition(viewConn2, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + // upsert single row into both view String dml = "UPSERT INTO " + viewOfTable1 + " VALUES(?,?,?,?,?)"; PreparedStatement stmt = viewConn.prepareStatement(dml); @@ -590,8 +642,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY"); assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); - assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); - assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + // even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG) + assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); // query table ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName); @@ -620,22 +673,37 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertEquals(14, rs.getInt("VIEW_COL1")); assertEquals("view5", rs.getString("VIEW_COL2")); assertFalse(rs.next()); + + // the base column count is updated in the ptable + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; + PTable view1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1)); + PTable view2 = viewConn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable2)); + assertEquals(isMultiTenant ? 4 : 3, view1.getBaseColumnCount()); + assertEquals(isMultiTenant ? 4 : 3, view2.getBaseColumnCount()); } } - public void assertTableDefinition(Connection conn, String tableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception { + public void assertTableDefinition(Connection conn, String fullTableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception { int delta = isMultiTenant ? 1 : 0; String[] cols; - if (isMultiTenant) { + if (isMultiTenant && tableType!=PTableType.VIEW) { cols = (String[])ArrayUtils.addAll(new String[]{"TENANT_ID"}, columnNames); } else { cols = columnNames; } - AlterMultiTenantTableWithViewsIT.assertTableDefinition(conn, tableName, tableType, parentTableName, sequenceNumber, columnCount + delta, + AlterMultiTenantTableWithViewsIT.assertTableDefinition(conn, fullTableName, tableType, parentTableName, sequenceNumber, columnCount + delta, baseColumnCount==QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT ? baseColumnCount : baseColumnCount +delta, cols); } + public void assertColumnsMatch(List<PColumn> actual, String... expected) { + List<String> expectedCols = Lists.newArrayList(expected); + if (isMultiTenant) { + expectedCols.add(0, "TENANT_ID"); + } + assertEquals(expectedCols, Lists.transform(actual, function)); + } + public static String getSystemCatalogEntriesForTable(Connection conn, String tableName, String message) throws Exception { StringBuilder sb = new StringBuilder(message); sb.append("\n\n\n"); @@ -654,73 +722,78 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { } - @Test public void testAlteringViewThatHasChildViews() throws Exception { - String baseTable = generateUniqueName(); - String childView = baseTable + "cildView"; - String grandChildView = baseTable + "grandChildView"; + String baseTable = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String childView = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String grandChildView = SchemaUtil.getTableName(SCHEMA4, generateUniqueName()); try (Connection conn = DriverManager.getConnection(getUrl()); - Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + " (" - + " %s PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR " - + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK2)" - + " ) %s"; + Connection viewConn = + isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn) { + String ddlFormat = + "CREATE TABLE IF NOT EXISTS " + baseTable + " (" + + " %s PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR " + + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK2)" + " ) %s"; conn.createStatement().execute(generateDDL(ddlFormat)); String childViewDDL = "CREATE VIEW " + childView + " AS SELECT * FROM " + baseTable; viewConn.createStatement().execute(childViewDDL); + + PTable view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase()); + assertColumnsMatch(view.getColumns(), "PK2", "V1", "V2"); + String grandChildViewDDL = + "CREATE VIEW " + grandChildView + " AS SELECT * FROM " + childView; + viewConn.createStatement().execute(grandChildViewDDL); + String addColumnToChildViewDDL = "ALTER VIEW " + childView + " ADD CHILD_VIEW_COL VARCHAR"; viewConn.createStatement().execute(addColumnToChildViewDDL); - String grandChildViewDDL = - "CREATE VIEW " + grandChildView + " AS SELECT * FROM " + childView; - viewConn.createStatement().execute(grandChildViewDDL); + view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase()); + assertColumnsMatch(view.getColumns(), "PK2", "V1", "V2", "CHILD_VIEW_COL"); + + PTable gcView = PhoenixRuntime.getTableNoCache(viewConn, grandChildView.toUpperCase()); + assertColumnsMatch(gcView.getColumns(), "PK2", "V1", "V2", "CHILD_VIEW_COL"); // dropping base table column from child view should succeed String dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN V2"; viewConn.createStatement().execute(dropColumnFromChildView); + view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase()); + assertColumnsMatch(view.getColumns(), "PK2", "V1", "CHILD_VIEW_COL"); // dropping view specific column from child view should succeed dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN CHILD_VIEW_COL"; viewConn.createStatement().execute(dropColumnFromChildView); - + view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase()); + assertColumnsMatch(view.getColumns(), "PK2", "V1"); + // Adding column to view that has child views is allowed String addColumnToChildView = "ALTER VIEW " + childView + " ADD V5 VARCHAR"; viewConn.createStatement().execute(addColumnToChildView); - // V5 column should be visible now for childView - viewConn.createStatement().execute("SELECT V5 FROM " + childView); - - // However, column V5 shouldn't have propagated to grandChildView. Not till PHOENIX-2054 is fixed. - try { - viewConn.createStatement().execute("SELECT V5 FROM " + grandChildView); - } catch (SQLException e) { - assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode()); - } + // V5 column should be visible now for both childView and grandChildView + viewConn.createStatement().execute("SELECT V5 FROM " + childView); + viewConn.createStatement().execute("SELECT V5 FROM " + grandChildView); - // dropping column from the grand child view, however, should work. - String dropColumnFromGrandChildView = - "ALTER VIEW " + grandChildView + " DROP COLUMN CHILD_VIEW_COL"; - viewConn.createStatement().execute(dropColumnFromGrandChildView); + view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase()); + assertColumnsMatch(view.getColumns(), "PK2", "V1", "V5"); - // similarly, dropping column inherited from the base table should work. - dropColumnFromGrandChildView = "ALTER VIEW " + grandChildView + " DROP COLUMN V2"; - viewConn.createStatement().execute(dropColumnFromGrandChildView); + // grand child view should have the same columns + gcView = PhoenixRuntime.getTableNoCache(viewConn, grandChildView.toUpperCase()); + assertColumnsMatch(gcView.getColumns(), "PK2", "V1", "V5"); } } @Test public void testDivergedViewsStayDiverged() throws Exception { - String baseTable = generateUniqueName(); - String view1 = baseTable + "_VIEW1"; - String view2 = baseTable + "_VIEW2"; + String baseTable = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String view1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String view2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName()); try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ; Connection viewConn2 = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL2) : conn) { String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + " (" - + " %s PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR " + + " %s PK1 VARCHAR NOT NULL, V0 VARCHAR, V1 VARCHAR, V2 VARCHAR " + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK1)" + " ) %s"; conn.createStatement().execute(generateDDL(ddlFormat)); @@ -734,8 +807,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { // Drop the column inherited from base table to make it diverged String dropColumn = "ALTER VIEW " + view1 + " DROP COLUMN V2"; viewConn.createStatement().execute(dropColumn); + PTable table = PhoenixRuntime.getTableNoCache(viewConn, view1); + assertEquals(QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT, table.getBaseColumnCount()); - String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR"; + // Add a new regular column and pk column to the base table + String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR, PK2 VARCHAR PRIMARY KEY"; conn.createStatement().execute(alterBaseTable); // Column V3 shouldn't have propagated to the diverged view. @@ -749,6 +825,43 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { // However, column V3 should have propagated to the non-diverged view. sql = "SELECT V3 FROM " + view2; viewConn2.createStatement().execute(sql); + + // PK2 should be in both views + sql = "SELECT PK2 FROM " + view1; + viewConn.createStatement().execute(sql); + sql = "SELECT PK2 FROM " + view2; + viewConn2.createStatement().execute(sql); + + // Drop a column from the base table + alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V1"; + conn.createStatement().execute(alterBaseTable); + + // V1 should be dropped from both diverged and non-diverged views + sql = "SELECT V1 FROM " + view1; + try { + viewConn.createStatement().execute(sql); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode()); + } + sql = "SELECT V1 FROM " + view2; + try { + viewConn2.createStatement().execute(sql); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode()); + } + + // V0 should be still exist in both diverged and non-diverged views + sql = "SELECT V0 FROM " + view1; + viewConn.createStatement().execute(sql); + sql = "SELECT V0 FROM " + view2; + viewConn2.createStatement().execute(sql); + + // add the column that was dropped back to the view + String addColumn = "ALTER VIEW " + view1 + " ADD V2 VARCHAR"; + viewConn.createStatement().execute(addColumn); + // V2 should not exist in the view + sql = "SELECT V0 FROM " + view1; + viewConn.createStatement().execute(sql); } } @@ -756,8 +869,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { public void testMakeBaseTableTransactional() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1"); - String viewOfTable = baseTableName + "_VIEW"; + String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTableName + " (" + " %s ID char(1) NOT NULL," + " COL1 integer NOT NULL," @@ -768,11 +882,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTableDefinition(conn, baseTableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2"); viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM "+baseTableName); - assertTableDefinition(conn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); + assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2"); - PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class); - HTableInterface htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName)); + Table htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName)); assertFalse(htable.getTableDescriptor().getCoprocessors().contains(TephraTransactionalProcessor.class.getName())); assertFalse(phoenixConn.getTable(new PTableKey(null, baseTableName)).isTransactional()); assertFalse(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).isTransactional()); @@ -787,50 +901,50 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTrue(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).isTransactional()); } } - + @Test public void testAlterTablePropertyOnView() throws Exception { - try (Connection conn = DriverManager.getConnection(getUrl()); + try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1"); - String viewOfTable = baseTableName + "_VIEW"; - - String ddl = "CREATE TABLE " + baseTableName + " (\n" - +"%s ID VARCHAR(15) NOT NULL,\n" - + " COL1 integer NOT NULL," - +"CREATED_DATE DATE,\n" - +"CONSTRAINT PK PRIMARY KEY (%s ID, COL1)) %s"; - conn.createStatement().execute(generateDDL(ddl)); - ddl = "CREATE VIEW " + viewOfTable + " AS SELECT * FROM " + baseTableName; - viewConn.createStatement().execute(ddl); - - try { - viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET IMMUTABLE_ROWS = true"); - fail(); - } catch (SQLException e) { - assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode()); - } - - viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET UPDATE_CACHE_FREQUENCY = 100"); - viewConn.createStatement().execute("SELECT * FROM "+ viewOfTable); - PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; - assertEquals(100, viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).getUpdateCacheFrequency()); - - try { - viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET APPEND_ONLY_SCHEMA = true"); - fail(); - } catch (SQLException e) { - assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode()); - } - } + String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + + String ddl = "CREATE TABLE " + baseTableName + " (\n" + +"%s ID VARCHAR(15) NOT NULL,\n" + + " COL1 integer NOT NULL," + +"CREATED_DATE DATE,\n" + +"CONSTRAINT PK PRIMARY KEY (%s ID, COL1)) %s"; + conn.createStatement().execute(generateDDL(ddl)); + ddl = "CREATE VIEW " + viewOfTable + " AS SELECT * FROM " + baseTableName; + viewConn.createStatement().execute(ddl); + + try { + viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET IMMUTABLE_ROWS = true"); + fail(); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode()); + } + + viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET UPDATE_CACHE_FREQUENCY = 100"); + viewConn.createStatement().execute("SELECT * FROM "+ viewOfTable); + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; + assertEquals(100, viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).getUpdateCacheFrequency()); + + try { + viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET APPEND_ONLY_SCHEMA = true"); + fail(); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode()); + } + } } @Test public void testAlterAppendOnlySchema() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl()); Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { - String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1"); - String viewOfTable = baseTableName + "_VIEW"; + String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); String ddl = "CREATE TABLE " + baseTableName + " (\n" +"%s ID VARCHAR(15) NOT NULL,\n" @@ -843,7 +957,7 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class); PTable table = phoenixConn.getTable(new PTableKey(null, baseTableName)); - PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; assertFalse(table.isAppendOnlySchema()); PTable viewTable = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)); assertFalse(viewTable.isAppendOnlySchema()); @@ -866,45 +980,112 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT { assertTrue(viewTable.isAppendOnlySchema()); } } - + @Test - public void testAlterTableWithIndexesExtendPk() throws Exception { - Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES); - Connection conn = DriverManager.getConnection(getUrl(), props); - conn.setAutoCommit(false); - String tableName = generateUniqueName(); - String indexName1 = "I_" + generateUniqueName(); - String indexName2 = "I_" + generateUniqueName(); + public void testDroppingIndexedColDropsViewIndex() throws Exception { + try (Connection conn =DriverManager.getConnection(getUrl()); + Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { + String tableWithView = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewSchemaName = SchemaUtil.getSchemaNameFromFullName(viewOfTable); + String viewIndex1 = generateUniqueName(); + String viewIndex2 = generateUniqueName(); + String fullNameViewIndex1 = SchemaUtil.getTableName(viewSchemaName, viewIndex1); + String fullNameViewIndex2 = SchemaUtil.getTableName(viewSchemaName, viewIndex2); + + conn.setAutoCommit(false); + viewConn.setAutoCommit(false); + String ddlFormat = + "CREATE TABLE " + tableWithView + + " (%s k VARCHAR NOT NULL, v1 VARCHAR, v2 VARCHAR, v3 VARCHAR, v4 VARCHAR CONSTRAINT PK PRIMARY KEY(%s k))%s"; + conn.createStatement().execute(generateDDL(ddlFormat)); + viewConn.createStatement() + .execute( + "CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableWithView ); + // create an index with the column that will be dropped + viewConn.createStatement().execute("CREATE INDEX " + viewIndex1 + " ON " + viewOfTable + "(v2) INCLUDE (v4)"); + // create an index without the column that will be dropped + viewConn.createStatement().execute("CREATE INDEX " + viewIndex2 + " ON " + viewOfTable + "(v1) INCLUDE (v4)"); + // verify index was created + try { + viewConn.createStatement().execute("SELECT * FROM " + fullNameViewIndex1 ); + } catch (TableNotFoundException e) { + fail("Index on view was not created"); + } + + // upsert a single row + PreparedStatement stmt = viewConn.prepareStatement("UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?,?,?)"); + stmt.setString(1, "a"); + stmt.setString(2, "b"); + stmt.setString(3, "c"); + stmt.setString(4, "d"); + stmt.setString(5, "e"); + stmt.setInt(6, 1); + stmt.setString(7, "g"); + stmt.execute(); + viewConn.commit(); - try { - String ddl = "CREATE TABLE " + tableName + - " (ORG_ID CHAR(15) NOT NULL," + - " PARTITION_KEY CHAR(3) NOT NULL, " + - " ACTIVITY_DATE DATE NOT NULL, " + - " FK1_ID CHAR(15) NOT NULL, " + - " FK2_ID CHAR(15) NOT NULL, " + - " TYPE VARCHAR NOT NULL, " + - " IS_OPEN BOOLEAN " + - " CONSTRAINT PKVIEW PRIMARY KEY " + - "(" + - "ORG_ID, PARTITION_KEY, ACTIVITY_DATE, FK1_ID, FK2_ID, TYPE" + - "))"; - createTestTable(getUrl(), ddl); - - String idx1ddl = "CREATE INDEX " + indexName1 + " ON " + tableName + " (FK1_ID, ACTIVITY_DATE DESC) INCLUDE (IS_OPEN)"; - PreparedStatement stmt1 = conn.prepareStatement(idx1ddl); - stmt1.execute(); - - String idx2ddl = "CREATE INDEX " + indexName2 + " ON " + tableName + " (FK2_ID, ACTIVITY_DATE DESC) INCLUDE (IS_OPEN)"; - PreparedStatement stmt2 = conn.prepareStatement(idx2ddl); - stmt2.execute(); - - ddl = "ALTER TABLE " + tableName + " ADD SOURCE VARCHAR(25) NULL PRIMARY KEY"; - PreparedStatement stmt3 = conn.prepareStatement(ddl); - stmt3.execute(); - } finally { - conn.close(); + // verify the index was created + PhoenixConnection pconn = viewConn.unwrap(PhoenixConnection.class); + PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null; + PTable view = pconn.getTable(new PTableKey(tenantId, viewOfTable )); + PTable viewIndex = pconn.getTable(new PTableKey(tenantId, fullNameViewIndex1 )); + byte[] viewIndexPhysicalTable = viewIndex.getPhysicalName().getBytes(); + assertNotNull("Can't find view index", viewIndex); + assertEquals("Unexpected number of indexes ", 2, view.getIndexes().size()); + assertEquals("Unexpected index ", fullNameViewIndex1 , view.getIndexes().get(0).getName() + .getString()); + assertEquals("Unexpected index ", fullNameViewIndex2 , view.getIndexes().get(1).getName() + .getString()); + + // drop two columns + conn.createStatement().execute("ALTER TABLE " + tableWithView + " DROP COLUMN v2, v3 "); + + // verify columns were dropped + try { + conn.createStatement().execute("SELECT v2 FROM " + tableWithView ); + fail("Column should have been dropped"); + } catch (ColumnNotFoundException e) { + } + try { + conn.createStatement().execute("SELECT v3 FROM " + tableWithView ); + fail("Column should have been dropped"); + } catch (ColumnNotFoundException e) { + } + + // verify index metadata was dropped + try { + viewConn.createStatement().execute("SELECT * FROM " + fullNameViewIndex1 ); + fail("Index metadata should have been dropped"); + } catch (TableNotFoundException e) { + } + + pconn = viewConn.unwrap(PhoenixConnection.class); + view = pconn.getTable(new PTableKey(tenantId, viewOfTable )); + try { + viewIndex = pconn.getTable(new PTableKey(tenantId, fullNameViewIndex1 )); + fail("View index should have been dropped"); + } catch (TableNotFoundException e) { + } + assertEquals("Unexpected number of indexes ", 1, view.getIndexes().size()); + assertEquals("Unexpected index ", fullNameViewIndex2 , view.getIndexes().get(0).getName().getString()); + + // verify that the physical index view table is *not* dropped + conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(viewIndexPhysicalTable); + + // scan the physical table and verify there is a single row for the second local index + Scan scan = new Scan(); + HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(viewIndexPhysicalTable); + ResultScanner results = table.getScanner(scan); + Result result = results.next(); + assertNotNull(result); + PTable viewIndexPTable = pconn.getTable(new PTableKey(pconn.getTenantId(), fullNameViewIndex2)); + PColumn column = viewIndexPTable.getColumnForColumnName(IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4")); + byte[] cq = column.getColumnQualifierBytes(); + // there should be a single row belonging to VIEWINDEX2 + assertNotNull(fullNameViewIndex2 + " row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, cq)); + assertNull(results.next()); } } - + }
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java index d601beb..b39c4f0 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java @@ -109,7 +109,9 @@ public class AppendOnlySchemaIT extends ParallelStatsDisabledIT { } // verify getTable rpcs - verify(connectionQueryServices, sameClient ? never() : times(1)).getTable((PName)isNull(), eq(new byte[0]), eq(Bytes.toBytes(viewName)), anyLong(), anyLong()); + verify(connectionQueryServices, sameClient ? never() : times(1)).getTable( + (PName) isNull(), eq(new byte[0]), eq(Bytes.toBytes(viewName)), anyLong(), + anyLong(), eq(false), eq(false), (PTable) isNull()); // verify no create table rpcs verify(connectionQueryServices, never()).createTable(anyListOf(Mutation.class), http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java index c61d970..9bd689e 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java @@ -32,13 +32,12 @@ import java.util.Set; import org.apache.hadoop.hbase.util.Pair; import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.QueryUtil; +import org.apache.phoenix.util.SchemaUtil; import com.google.common.collect.Lists; -public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT { +public class BaseTenantSpecificViewIndexIT extends SplitSystemCatalogIT { - public static final String TENANT1_ID = "tenant1"; - public static final String TENANT2_ID = "tenant2"; public static final String NON_STRING_TENANT_ID = "1234"; protected Set<Pair<String, String>> tenantViewsToDelete = newHashSet(); @@ -48,12 +47,13 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT { } protected void testUpdatableView(Integer saltBuckets, boolean localIndex) throws Exception { - String tableName = generateUniqueName(); + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); createBaseTable(tableName, saltBuckets, true); - Connection conn = createTenantConnection(TENANT1_ID); + Connection conn = createTenantConnection(TENANT1); try { - String viewName = createAndPopulateTenantView(conn, TENANT1_ID, tableName, ""); - createAndVerifyIndex(conn, viewName, tableName, saltBuckets, TENANT1_ID, "", localIndex); + createAndPopulateTenantView(conn, TENANT1, tableName, "", viewName); + createAndVerifyIndex(conn, viewName, tableName, saltBuckets, TENANT1, "", localIndex); verifyViewData(conn, viewName, ""); } finally { try { conn.close();} catch (Exception ignored) {} @@ -61,11 +61,12 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT { } protected void testUpdatableViewNonString(Integer saltBuckets, boolean localIndex) throws Exception { - String tableName = generateUniqueName(); + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); createBaseTable(tableName, saltBuckets, false); Connection conn = createTenantConnection(NON_STRING_TENANT_ID); try { - String viewName = createAndPopulateTenantView(conn, NON_STRING_TENANT_ID, tableName, ""); + createAndPopulateTenantView(conn, NON_STRING_TENANT_ID, tableName, "", viewName); createAndVerifyIndexNonStringTenantId(conn, viewName, tableName, NON_STRING_TENANT_ID, ""); verifyViewData(conn, viewName, ""); } finally { @@ -78,20 +79,22 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT { } protected void testUpdatableViewsWithSameNameDifferentTenants(Integer saltBuckets, boolean localIndex) throws Exception { - String tableName = generateUniqueName(); + String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()); + String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName()); + String viewName2 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName()); createBaseTable(tableName, saltBuckets, true); - Connection conn1 = createTenantConnection(TENANT1_ID); - Connection conn2 = createTenantConnection(TENANT2_ID); + Connection conn1 = createTenantConnection(TENANT1); + Connection conn2 = createTenantConnection(TENANT2); try { String prefixForTenant1Data = "TI"; String prefixForTenant2Data = "TII"; // tenant views with same name for two different tables - String viewName1 = createAndPopulateTenantView(conn1, TENANT1_ID, tableName, prefixForTenant1Data); - String viewName2 = createAndPopulateTenantView(conn2, TENANT2_ID, tableName, prefixForTenant2Data); + createAndPopulateTenantView(conn1, TENANT1, tableName, prefixForTenant1Data, viewName1); + createAndPopulateTenantView(conn2, TENANT2, tableName, prefixForTenant2Data, viewName2); - createAndVerifyIndex(conn1, viewName1, tableName, saltBuckets, TENANT1_ID, prefixForTenant1Data, localIndex); - createAndVerifyIndex(conn2, viewName2, tableName, saltBuckets, TENANT2_ID, prefixForTenant2Data, localIndex); + createAndVerifyIndex(conn1, viewName1, tableName, saltBuckets, TENANT1, prefixForTenant1Data, localIndex); + createAndVerifyIndex(conn2, viewName2, tableName, saltBuckets, TENANT2, prefixForTenant2Data, localIndex); verifyViewData(conn1, viewName1, prefixForTenant1Data); verifyViewData(conn2, viewName2, prefixForTenant2Data); @@ -114,8 +117,7 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT { conn.close(); } - private String createAndPopulateTenantView(Connection conn, String tenantId, String baseTable, String valuePrefix) throws SQLException { - String viewName = generateUniqueName(); + private String createAndPopulateTenantView(Connection conn, String tenantId, String baseTable, String valuePrefix, String viewName) throws SQLException { String ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR) AS SELECT * FROM " + baseTable + " WHERE k1 = 1"; conn.createStatement().execute(ddl); tenantViewsToDelete.add(new Pair<String, String>(tenantId, viewName )); http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java index abaa2f6..0dc4410 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java @@ -692,7 +692,7 @@ public class ExplainPlanWithStatsEnabledIT extends ParallelStatsEnabledIT { assertTrue(info.getEstimateInfoTs() > 0); conn.createStatement() - .execute("ALTER TABLE " + viewName + " SET USE_STATS_FOR_PARALLELIZATION=true"); + .execute("ALTER VIEW " + viewName + " SET USE_STATS_FOR_PARALLELIZATION=true"); sql = "SELECT COUNT(*) FROM " + viewName; // query the view rs = conn.createStatement().executeQuery(sql); @@ -1202,33 +1202,44 @@ public class ExplainPlanWithStatsEnabledIT extends ParallelStatsEnabledIT { assertEquals("B", rs.getString(1)); } - @Test - public void testUseStatsForParallelizationProperyOnViewIndex() throws SQLException { - String tableName = generateUniqueName(); - String viewName = generateUniqueName(); - String tenantViewName = generateUniqueName(); - String viewIndexName = generateUniqueName(); - boolean useStats = !DEFAULT_USE_STATS_FOR_PARALLELIZATION; - try (Connection conn = DriverManager.getConnection(getUrl())) { - conn.createStatement() - .execute("create table " + tableName - + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY " - + "(tenantId, pk1)) MULTI_TENANT=true"); - try (Connection tenantConn = getTenantConnection("tenant1")) { - conn.createStatement().execute("CREATE VIEW " + viewName + " AS SELECT * FROM " + tableName); - conn.createStatement().execute("CREATE INDEX " + viewIndexName + " on " + viewName + " (v) "); - tenantConn.createStatement().execute("CREATE VIEW " + tenantViewName + " AS SELECT * FROM " + viewName); - conn.createStatement() - .execute("ALTER TABLE " + tableName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats); - // fetch the latest view ptable - PhoenixRuntime.getTableNoCache(tenantConn, viewName); - PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class); - PTable viewIndex = phxConn.getTable(new PTableKey(phxConn.getTenantId(), viewIndexName)); - assertEquals("USE_STATS_FOR_PARALLELIZATION property set incorrectly", useStats, - PhoenixConfigurationUtil - .getStatsForParallelizationProp(tenantConn.unwrap(PhoenixConnection.class), viewIndex)); - } - } - } + @Test + public void testUseStatsForParallelizationProperyOnViewIndex() throws SQLException { + String tableName = generateUniqueName(); + String viewName = generateUniqueName(); + String tenantViewName = generateUniqueName(); + String viewIndexName = generateUniqueName(); + boolean useStats = !DEFAULT_USE_STATS_FOR_PARALLELIZATION; + try (Connection conn = DriverManager.getConnection(getUrl())) { + conn.createStatement() + .execute("create table " + tableName + + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY " + + "(tenantId, pk1)) MULTI_TENANT=true"); + try (Connection tenantConn = getTenantConnection("tenant1")) { + conn.createStatement().execute("CREATE VIEW " + viewName + " AS SELECT * FROM " + tableName); + conn.createStatement().execute("CREATE INDEX " + viewIndexName + " on " + viewName + " (v) "); + tenantConn.createStatement().execute("CREATE VIEW " + tenantViewName + " AS SELECT * FROM " + viewName); + conn.createStatement() + .execute("ALTER TABLE " + tableName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats); + // changing a property on a base table does not change the property on a view + validatePropertyOnViewIndex(viewName, viewIndexName, !useStats, conn, tenantConn); + + // need to explicitly change the property on the view + conn.createStatement() + .execute("ALTER VIEW " + viewName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats); + validatePropertyOnViewIndex(viewName, viewIndexName, useStats, conn, tenantConn); + } + } + } + + private void validatePropertyOnViewIndex(String viewName, String viewIndexName, boolean useStats, Connection conn, + Connection tenantConn) throws SQLException, TableNotFoundException { + // fetch the latest view ptable + PhoenixRuntime.getTableNoCache(tenantConn, viewName); + PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class); + PTable viewIndex = phxConn.getTable(new PTableKey(phxConn.getTenantId(), viewIndexName)); + assertEquals("USE_STATS_FOR_PARALLELIZATION property set incorrectly", useStats, + PhoenixConfigurationUtil + .getStatsForParallelizationProp(tenantConn.unwrap(PhoenixConnection.class), viewIndex)); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java index 627e453..d253f6e 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java @@ -63,10 +63,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { 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 final String SCHEMA_NAME = "MIGRATETEST"; private static final String TABLE_NAME = SCHEMA_NAME + "." + MigrateSystemTablesToSystemNamespaceIT.class.getSimpleName().toUpperCase(); @@ -86,12 +86,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { final UserGroupInformation user4 = UserGroupInformation.createUserForTesting("user4", new String[0]); - - @Before - public final void doSetup() throws Exception { + public final void doSetup(boolean systemMappingEnabled) throws Exception { testUtil = new HBaseTestingUtility(); Configuration conf = testUtil.getConfiguration(); - enableNamespacesOnServer(conf); + enableNamespacesOnServer(conf, systemMappingEnabled); configureRandomHMasterPort(conf); testUtil.startMiniCluster(1); } @@ -110,9 +108,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { // Tests that client can create and read tables on a fresh HBase cluster with // system namespace mapping enabled from the start - @Test - public void freshClientsCreateNamespaceMappedSystemTables() throws IOException, InterruptedException { - + @Test + public void freshClientsCreateNamespaceMappedSystemTables() throws Exception { + doSetup(true); user1.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { @@ -137,9 +135,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { } // Tests that NEWER clients can read tables on HBase cluster after system tables are migrated - @Test - public void migrateSystemTablesInExistingCluster() throws IOException, InterruptedException { - + @Test + public void migrateSystemTablesInExistingCluster() throws Exception { + doSetup(false); user1.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { @@ -167,9 +165,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { // Tests that OLDER clients fail after system tables are migrated // Clients should be restarted with new properties which are consistent on both client and server - @Test - public void oldClientsAfterSystemTableMigrationShouldFail() throws IOException, InterruptedException { - + @Test + public void oldClientsAfterSystemTableMigrationShouldFail() throws Exception { + doSetup(true); user1.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { @@ -202,9 +200,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { // Tests that only one client can migrate the system table to system namespace // Migrate process acquires lock in SYSMUTEX table - @Test - public void onlyOneClientCanMigrate() throws IOException, InterruptedException, SQLException { - + @Test + public void onlyOneClientCanMigrate() throws Exception { + doSetup(false); user1.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { @@ -291,8 +289,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest { } } - private void enableNamespacesOnServer(Configuration conf) { + private void enableNamespacesOnServer(Configuration conf, boolean systemMappingEnabled) { conf.set(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString()); + conf.set(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, + systemMappingEnabled ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); } // For PHOENIX-4389 (Flapping tests SystemTablePermissionsIT and MigrateSystemTablesToSystemNamespaceIT) http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java index c93d2aa..255a8b2 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java @@ -174,30 +174,24 @@ public class PhoenixDriverIT extends BaseUniqueNamesOwnClusterIT { String schemaName = "S_" + generateUniqueName(); String tableName = "T_" + generateUniqueName(); String phoenixFullTableName = SchemaUtil.getTableName(schemaName, tableName); - String viewName1 = "VC_" + generateUniqueName(); - String viewName2 = "VB_" + generateUniqueName(); + String viewName1 = "VB_" + generateUniqueName(); + String viewName2 = "VC_" + generateUniqueName(); try (Connection conn = createConnection(null, false)) { conn.createStatement().execute("CREATE TABLE " + phoenixFullTableName + "(k VARCHAR not null, v INTEGER not null, f INTEGER, g INTEGER NULL, h INTEGER NULL CONSTRAINT pk PRIMARY KEY(k,v)) MULTI_TENANT=true"); } - try (Connection conn = createConnection("tenant1", false)) { - // create view - conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1 - + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName); - // create child view - conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2 - + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1); - } - String tenant2 = "tenant2"; - try (Connection conn = createConnection(tenant2, false)) { - // creating another view in a second tenant but same view name - conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1 - + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName); - // creating child view with a second tenant - conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2 - + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1); + String[] tenantIds = new String[] { "tenant1", "tenant2" }; + for (String tenantId : tenantIds) { + try (Connection conn = createConnection(tenantId, false)) { + // create view + conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1 + + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName); + // create child view + conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2 + + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1); + } } try (Connection conn = createConnection(null, true)) { @@ -209,14 +203,15 @@ public class PhoenixDriverIT extends BaseUniqueNamesOwnClusterIT { try (PhoenixConnection phxConn = DriverManager.getConnection(url, props).unwrap(PhoenixConnection.class)) { UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName); - UpgradeUtil.mapChildViewsToNamespace(phxConn, phoenixFullTableName, props); } // verify physical table link String physicalTableName = SchemaUtil.getPhysicalHBaseTableName(schemaName, tableName, true).getString(); - assertEquals(physicalTableName, getPhysicalTable(conn, tenant2, schemaName, viewName1)); - assertEquals(physicalTableName, getPhysicalTable(conn, tenant2, schemaName, viewName2)); + for (String tenantId : tenantIds) { + assertEquals(physicalTableName, getPhysicalTable(conn, tenantId, schemaName, viewName1)); + assertEquals(physicalTableName, getPhysicalTable(conn, tenantId, schemaName, viewName2)); + } } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java index 4f84304..90f9db6 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java @@ -19,6 +19,7 @@ package org.apache.phoenix.end2end; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_TABLE; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_TABLE; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE; import static org.apache.phoenix.util.TestUtil.ATABLE_NAME; @@ -162,6 +163,10 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT { assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); assertTrue(rs.next()); assertEquals(SYSTEM_CATALOG_SCHEMA, rs.getString("TABLE_SCHEM")); + assertEquals(SYSTEM_CHILD_LINK_TABLE, rs.getString("TABLE_NAME")); + assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); + assertTrue(rs.next()); + assertEquals(SYSTEM_CATALOG_SCHEMA, rs.getString("TABLE_SCHEM")); assertEquals(SYSTEM_FUNCTION_TABLE, rs.getString("TABLE_NAME")); assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); assertTrue(rs.next()); @@ -342,7 +347,7 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT { @Test public void testSchemaMetadataScan() throws SQLException { String table1 = generateUniqueName(); - String schema1 = generateUniqueName(); + String schema1 = "Z_" + generateUniqueName(); String fullTable1 = schema1 + "." + table1; ensureTableCreated(getUrl(), fullTable1, CUSTOM_ENTITY_DATA_FULL_NAME, null); String fullTable2 = generateUniqueName(); @@ -1095,7 +1100,7 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT { // Retrieve the database metadata DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getColumns(null, null, null, null); - rs.next(); + assertTrue(rs.next()); // Lookup column by name, this should return null but not throw an exception String remarks = rs.getString("REMARKS"); http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java deleted file mode 100644 index e7518f6..0000000 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.phoenix.end2end; - -import org.junit.Test; - - -public class SaltedViewIT extends BaseViewIT { - - public SaltedViewIT(boolean transactional) { - super(transactional); - } - - /** - * 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); - } -}