Repository: phoenix Updated Branches: refs/heads/4.0 2bcc1d148 -> b07658e87
PHOENIX-1171 Dropping the index is not verifying the associated table Conflicts: phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/b07658e8 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/b07658e8 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/b07658e8 Branch: refs/heads/4.0 Commit: b07658e8791cebf59ec45beeac56ec7ca5252a4d Parents: 2bcc1d1 Author: James Taylor <jtay...@salesforce.com> Authored: Thu Aug 14 12:58:12 2014 -0700 Committer: James Taylor <jtay...@salesforce.com> Committed: Thu Aug 14 20:37:46 2014 -0700 ---------------------------------------------------------------------- .../java/org/apache/phoenix/end2end/ViewIT.java | 37 ++++++++++++++++++++ .../phoenix/end2end/index/IndexMetadataIT.java | 12 ++++++- .../coprocessor/MetaDataEndpointImpl.java | 22 ++++++------ .../org/apache/phoenix/util/MetaDataUtil.java | 4 ++- .../phoenix/compile/ViewCompilerTest.java | 12 +++---- 5 files changed, 69 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/b07658e8/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java index 1d022e5..d79535a 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java @@ -29,6 +29,7 @@ import java.sql.SQLException; import org.apache.phoenix.exception.SQLExceptionCode; import org.apache.phoenix.schema.ReadOnlyTableException; +import org.apache.phoenix.schema.TableNotFoundException; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -233,4 +234,40 @@ public class ViewIT extends BaseViewIT { } assertEquals(4, count); } + + @Test + public void testViewAndTableInDifferentSchemas() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE s1.t (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)"; + conn.createStatement().execute(ddl); + ddl = "CREATE VIEW s2.v1 (v2 VARCHAR) AS SELECT * FROM s1.t WHERE k > 5"; + conn.createStatement().execute(ddl); + ddl = "CREATE VIEW v2 (v2 VARCHAR) AS SELECT * FROM s1.t WHERE k > 5"; + conn.createStatement().execute(ddl); + ddl = "DROP VIEW v1"; + try { + conn.createStatement().execute(ddl); + fail(); + } catch (TableNotFoundException ignore) { + } + ddl = "DROP VIEW s2.v1"; + conn.createStatement().execute(ddl); + ddl = "DROP VIEW s2.v2"; + try { + conn.createStatement().execute(ddl); + fail(); + } catch (TableNotFoundException ignore) { + } + ddl = "DROP TABLE s1.t"; + try { + conn.createStatement().execute(ddl); + fail(); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode()); + } + ddl = "DROP VIEW v2"; + conn.createStatement().execute(ddl); + ddl = "DROP TABLE s1.t"; + conn.createStatement().execute(ddl); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/b07658e8/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java index 35232b5..2547844 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java @@ -45,6 +45,7 @@ import org.apache.phoenix.schema.AmbiguousColumnException; import org.apache.phoenix.schema.PIndexState; import org.apache.phoenix.schema.PTableKey; import org.apache.phoenix.schema.PTableType; +import org.apache.phoenix.schema.TableNotFoundException; import org.apache.phoenix.util.PropertiesUtil; import org.apache.phoenix.util.SchemaUtil; import org.apache.phoenix.util.StringUtil; @@ -115,7 +116,7 @@ public class IndexMetadataIT extends BaseHBaseManagedTimeIT { } @Test - public void testIndexCreation() throws Exception { + public void testIndexCreateDrop() throws Exception { Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); conn.setAutoCommit(false); @@ -259,6 +260,15 @@ public class IndexMetadataIT extends BaseHBaseManagedTimeIT { assertIndexInfoMetadata(rs, INDEX_DATA_SCHEMA, MUTABLE_INDEX_DATA_TABLE, "IDX2", 8, "B:INT_COL2", null); assertFalse(rs.next()); + // Create another table in the same schema + String diffTableNameInSameSchema = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + MUTABLE_INDEX_DATA_TABLE + "2"; + conn.createStatement().execute("CREATE TABLE " + diffTableNameInSameSchema + "(k INTEGER PRIMARY KEY)"); + try { + conn.createStatement().execute("DROP INDEX IDX1 ON " + diffTableNameInSameSchema); + fail("Should have realized index IDX1 is not on the table"); + } catch (TableNotFoundException ignore) { + + } ddl = "DROP TABLE " + INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + MUTABLE_INDEX_DATA_TABLE; stmt = conn.prepareStatement(ddl); stmt.execute(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/b07658e8/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java index 4066070..b99483b 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java @@ -30,6 +30,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAM import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FAMILY_NAME_INDEX; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS_BYTES; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED_BYTES; @@ -50,7 +51,6 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT_BYTE import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT_BYTES; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_TYPE_BYTES; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES; import static org.apache.phoenix.schema.PTableType.INDEX; import static org.apache.phoenix.util.SchemaUtil.getVarCharLength; import static org.apache.phoenix.util.SchemaUtil.getVarChars; @@ -928,7 +928,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } List<ImmutableBytesPtr> invalidateList = new ArrayList<ImmutableBytesPtr>(); result = - doDropTable(key, tenantIdBytes, schemaName, tableName, + doDropTable(key, tenantIdBytes, schemaName, tableName, parentTableName, PTableType.fromSerializedValue(tableType), tableMetadata, invalidateList, locks, tableNamesToDelete); if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) { @@ -959,7 +959,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } private MetaDataMutationResult doDropTable(byte[] key, byte[] tenantId, byte[] schemaName, - byte[] tableName, PTableType tableType, List<Mutation> rowsToDelete, + byte[] tableName, byte[] parentTableName, PTableType tableType, List<Mutation> rowsToDelete, List<ImmutableBytesPtr> invalidateList, List<RowLock> locks, List<byte[]> tableNamesToDelete) throws IOException, SQLException { long clientTimeStamp = MetaDataUtil.getClientTimeStamp(rowsToDelete); @@ -990,6 +990,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } return new MetaDataMutationResult(MutationCode.TABLE_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null); } + // Make sure we're not deleting the "wrong" child + if (!Arrays.equals(parentTableName, table.getParentTableName() == null ? null : table.getParentTableName().getBytes())) { + return new MetaDataMutationResult(MutationCode.TABLE_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null); + } // Since we don't allow back in time DDL, we know if we have a table it's the one // we want to delete. FIXME: we shouldn't need a scan here, but should be able to // use the table to generate the Delete markers. @@ -1040,7 +1044,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso rowsToDelete.add(delete); acquireLock(region, indexKey, locks); MetaDataMutationResult result = - doDropTable(indexKey, tenantId, schemaName, indexName, PTableType.INDEX, + doDropTable(indexKey, tenantId, schemaName, indexName, tableName, PTableType.INDEX, rowsToDelete, invalidateList, locks, tableNamesToDelete); if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) { return result; @@ -1215,11 +1219,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } catch (ColumnNotFoundException e) { if (addingPKColumn) { // Add all indexes to invalidate list, as they will all be - // adding - // the same PK column - // No need to lock them, as we have the parent table lock at - // this - // point + // adding the same PK column. No need to lock them, as we + // have the parent table lock at this point. for (PTable index : table.getIndexes()) { invalidateList.add(new ImmutableBytesPtr(SchemaUtil .getTableKey(tenantId, index.getSchemaName() @@ -1315,7 +1316,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso // Drop the link between the data table and the // index table additionalTableMetaData.add(new Delete(linkKey, clientTimeStamp)); - doDropTable(indexKey, tenantId, index.getSchemaName().getBytes(), index.getTableName().getBytes(), + doDropTable(indexKey, tenantId, index.getSchemaName().getBytes(), index.getTableName().getBytes(), tableName, index.getType(), additionalTableMetaData, invalidateList, locks, tableNamesToDelete); // TODO: return in result? } else { @@ -1384,6 +1385,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso done.run(builder.build()); } + @SuppressWarnings("deprecation") @Override public void updateIndexState(RpcController controller, UpdateIndexStateRequest request, RpcCallback<MetaDataResponse> done) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/b07658e8/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java index 215a2b1..545394d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java @@ -141,10 +141,12 @@ public class MetaDataUtil { } byte[][] rowKeyMetaData = new byte[3][]; getTenantIdAndSchemaAndTableName(tableMetadata, rowKeyMetaData); + byte[] schemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX]; byte[] tableName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]; Mutation m = getParentTableHeaderRow(tableMetadata); getVarChars(m.getRow(), 3, rowKeyMetaData); - if (Bytes.compareTo(tableName, rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]) == 0) { + if ( Bytes.compareTo(schemaName, rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX]) == 0 + && Bytes.compareTo(tableName, rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]) == 0) { return null; } return rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]; http://git-wip-us.apache.org/repos/asf/phoenix/blob/b07658e8/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java index 651d58d..7a0bac6 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java @@ -80,25 +80,25 @@ public class ViewCompilerTest extends BaseConnectionlessQueryTest { public void testViewInvalidation() throws Exception { Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); PhoenixConnection conn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); - String ct = "CREATE TABLE t (k1 INTEGER NOT NULL, k2 VARCHAR, v VARCHAR, CONSTRAINT pk PRIMARY KEY (k1,k2))"; + String ct = "CREATE TABLE s1.t (k1 INTEGER NOT NULL, k2 VARCHAR, v VARCHAR, CONSTRAINT pk PRIMARY KEY (k1,k2))"; conn.createStatement().execute(ct); - conn.createStatement().execute("CREATE VIEW v3 AS SELECT * FROM t WHERE v = 'bar'"); + conn.createStatement().execute("CREATE VIEW s2.v3 AS SELECT * FROM s1.t WHERE v = 'bar'"); // TODO: should it be an error to remove columns from a VIEW that we're defined there? // TOOD: should we require an ALTER VIEW instead of ALTER TABLE? - conn.createStatement().execute("ALTER VIEW v3 DROP COLUMN v"); + conn.createStatement().execute("ALTER VIEW s2.v3 DROP COLUMN v"); try { - conn.createStatement().executeQuery("SELECT * FROM v3"); + conn.createStatement().executeQuery("SELECT * FROM s2.v3"); fail(); } catch (ColumnNotFoundException e) { } // No error, as v still exists in t - conn.createStatement().execute("CREATE VIEW v4 AS SELECT * FROM t WHERE v = 'bas'"); + conn.createStatement().execute("CREATE VIEW s2.v4 AS SELECT * FROM s1.t WHERE v = 'bas'"); // No error, even though view is invalid - conn.createStatement().execute("DROP VIEW v3"); + conn.createStatement().execute("DROP VIEW s2.v3"); }