Repository: phoenix Updated Branches: refs/heads/4.x-HBase-0.98 46250e672 -> 189a55e59
PHOENIX-3900 Backward compatibility fails with TNF exception when deleting table with a view Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/189a55e5 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/189a55e5 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/189a55e5 Branch: refs/heads/4.x-HBase-0.98 Commit: 189a55e59288b6c7674da5a499dc17532cc8a07d Parents: 46250e6 Author: Thomas <[email protected]> Authored: Wed May 31 14:10:28 2017 -0700 Committer: Thomas <[email protected]> Committed: Thu Jun 1 11:06:38 2017 -0700 ---------------------------------------------------------------------- .../coprocessor/MetaDataEndpointImpl.java | 144 +++++++++++-------- 1 file changed, 83 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/189a55e5/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 8957fb9..550b133 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 @@ -1652,31 +1652,24 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso return null; } - private void findAllChildViews(HRegion region, byte[] tenantId, PTable table, TableViewFinderResult result, long clientTimeStamp) throws IOException, SQLException { - TableViewFinderResult currResult = findChildViews(region, tenantId, table); + private void findAllChildViews(HRegion region, byte[] tenantId, PTable table, + TableViewFinder result, long clientTimeStamp) throws IOException, SQLException { + TableViewFinder currResult = findChildViews(region, tenantId, table); result.addResult(currResult); - for (Result viewResult : currResult.getResults()) { - byte[][] rowViewKeyMetaData = new byte[5][]; - getVarChars(viewResult.getRow(), 5, rowViewKeyMetaData); - byte[] viewtenantId = rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]; - byte[] viewSchema = SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); - byte[] viewTable = SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); - byte[] tableKey = - SchemaUtil.getTableKey(viewtenantId, - viewSchema, - viewTable); + for (ViewInfo viewInfo : currResult.getViewInfoList()) { + byte[] viewtenantId = viewInfo.getTenantId(); + byte[] viewSchema = viewInfo.getSchemaName(); + byte[] viewTable = viewInfo.getViewName(); + byte[] tableKey = SchemaUtil.getTableKey(viewtenantId, viewSchema, viewTable); ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(tableKey); - PTable view = - loadTable(env, tableKey, cacheKey, clientTimeStamp, - clientTimeStamp); + PTable view = loadTable(env, tableKey, cacheKey, clientTimeStamp, clientTimeStamp); findAllChildViews(region, viewtenantId, view, result, clientTimeStamp); } } - // TODO remove this in 4.13 release @Deprecated - private TableViewFinderResult findChildViews_deprecated(HRegion region, byte[] tenantId, PTable table, byte[] linkTypeBytes) throws IOException { + private TableViewFinder findChildViews_deprecated(HRegion region, byte[] tenantId, PTable table, byte[] linkTypeBytes) throws IOException { byte[] schemaName = table.getSchemaName().getBytes(); byte[] tableName = table.getTableName().getBytes(); boolean isMultiTenant = table.isMultiTenant(); @@ -1716,7 +1709,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso try { boolean allViewsInCurrentRegion = true; int numOfChildViews = 0; - List<Result> results = Lists.newArrayList(); + List<ViewInfo> viewInfoList = Lists.newArrayList(); ResultScanner scanner = hTable.getScanner(scan); try { for (Result result = scanner.next(); (result != null); result = scanner.next()) { @@ -1728,9 +1721,14 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso if (checkTableKeyInRegion(key, region) != null) { allViewsInCurrentRegion = false; } - results.add(result); + byte[][] rowKeyMetaData = new byte[3][]; + getVarChars(result.getRow(), 3, rowKeyMetaData); + byte[] viewTenantId = rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX]; + byte[] viewSchemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX]; + byte[] viewName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]; + viewInfoList.add(new ViewInfo(viewTenantId, viewSchemaName, viewName)); } - TableViewFinderResult tableViewFinderResult = new TableViewFinderResult(results); + TableViewFinder tableViewFinderResult = new TableViewFinder(viewInfoList); if (numOfChildViews > 0 && !allViewsInCurrentRegion) { tableViewFinderResult.setAllViewsNotInSingleRegion(); } @@ -1743,7 +1741,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } } - private TableViewFinderResult findChildViews_4_11(HRegion region, byte[] tenantId, byte[] schemaName, byte[] tableName) throws IOException { + private TableViewFinder findChildViews_4_11(HRegion region, byte[] tenantId, byte[] schemaName, byte[] tableName) throws IOException { Scan scan = new Scan(); byte[] startRow = SchemaUtil.getTableKey(tenantId, schemaName, tableName); byte[] stopRow = ByteUtil.nextKey(startRow); @@ -1766,7 +1764,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso try { boolean allViewsInCurrentRegion = true; int numOfChildViews = 0; - List<Result> results = Lists.newArrayList(); + List<ViewInfo> viewInfoList = Lists.newArrayList(); ResultScanner scanner = hTable.getScanner(scan); try { for (Result result = scanner.next(); (result != null); result = scanner.next()) { @@ -1778,9 +1776,14 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso if (checkTableKeyInRegion(key, region) != null) { allViewsInCurrentRegion = false; } - results.add(result); + byte[][] rowViewKeyMetaData = new byte[5][]; + getVarChars(result.getRow(), 5, rowViewKeyMetaData); + byte[] viewTenantId = rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]; + byte[] viewSchemaName = SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); + byte[] viewName = SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); + viewInfoList.add(new ViewInfo(viewTenantId, viewSchemaName, viewName)); } - TableViewFinderResult tableViewFinderResult = new TableViewFinderResult(results); + TableViewFinder tableViewFinderResult = new TableViewFinder(viewInfoList); if (numOfChildViews > 0 && !allViewsInCurrentRegion) { tableViewFinderResult.setAllViewsNotInSingleRegion(); } @@ -1796,7 +1799,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso private static final byte[] PHYSICAL_TABLE_BYTES = new byte[] { PTable.LinkType.PHYSICAL_TABLE.getSerializedValue() }; - private TableViewFinderResult findChildViews(HRegion region, byte[] tenantId, PTable table) + private TableViewFinder findChildViews(HRegion region, byte[] tenantId, PTable table) throws IOException, SQLException { byte[] tableKey = SchemaUtil.getTableKey(ByteUtil.EMPTY_BYTE_ARRAY, @@ -1944,7 +1947,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso if (tableType == PTableType.TABLE || tableType == PTableType.SYSTEM) { // Handle any child views that exist - TableViewFinderResult tableViewFinderResult = findChildViews(region, tenantId, table); + TableViewFinder tableViewFinderResult = findChildViews(region, tenantId, table); if (tableViewFinderResult.hasViews()) { if (isCascade) { if (tableViewFinderResult.allViewsInMultipleRegions()) { @@ -1954,12 +1957,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso EnvironmentEdgeManager.currentTimeMillis(), null); } else if (tableViewFinderResult.allViewsInSingleRegion()) { // Recursively delete views - safe as all the views as all in the same region - for (Result viewResult : tableViewFinderResult.getResults()) { - byte[][] rowViewKeyMetaData = new byte[5][]; - getVarChars(viewResult.getRow(), 5, rowViewKeyMetaData); - byte[] viewTenantId = rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]; - byte[] viewSchemaName = SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); - byte[] viewName = SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); + for (ViewInfo viewInfo : tableViewFinderResult.getViewInfoList()) { + byte[] viewTenantId = viewInfo.getTenantId(); + byte[] viewSchemaName = viewInfo.getSchemaName(); + byte[] viewName = viewInfo.getViewName(); byte[] viewKey = SchemaUtil.getTableKey(viewTenantId, viewSchemaName, viewName); Delete delete = new Delete(viewKey, clientTimeStamp); rowsToDelete.add(delete); @@ -2310,7 +2311,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } private MetaDataMutationResult addColumnsAndTablePropertiesToChildViews(PTable basePhysicalTable, List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName, - List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, TableViewFinderResult childViewsResult, + List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, TableViewFinder childViewsResult, HRegion region, List<RowLock> locks) throws IOException, SQLException { List<PutWithOrdinalPosition> columnPutsForBaseTable = Lists.newArrayListWithExpectedSize(tableMetadata.size()); Map<TableProperty, Cell> tablePropertyCellMap = Maps.newHashMapWithExpectedSize(tableMetadata.size()); @@ -2347,15 +2348,13 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } // Sort the puts by ordinal position Collections.sort(columnPutsForBaseTable); - for (Result viewResult : childViewsResult.getResults()) { + for (ViewInfo viewInfo : childViewsResult.getViewInfoList()) { short deltaNumPkColsSoFar = 0; short columnsAddedToView = 0; short columnsAddedToBaseTable = 0; - byte[][] rowViewKeyMetaData = new byte[5][]; - getVarChars(viewResult.getRow(), 5, rowViewKeyMetaData); - byte[] tenantId = rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]; - byte[] schema = SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); - byte[] table = SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); + byte[] tenantId = viewInfo.getTenantId(); + byte[] schema = viewInfo.getSchemaName(); + byte[] table = viewInfo.getViewName(); byte[] viewKey = SchemaUtil.getTableKey(tenantId, schema, table); // lock the rows corresponding to views so that no other thread can modify the view meta-data @@ -2659,7 +2658,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso PTable basePhysicalTable, List<RowLock> locks, List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName, List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, - TableViewFinderResult childViewsResult, List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete) + TableViewFinder childViewsResult, List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete) throws IOException, SQLException { List<Delete> columnDeletesForBaseTable = new ArrayList<>(tableMetadata.size()); // Isolate the deletes relevant to dropping columns. Also figure out what kind of columns @@ -2675,13 +2674,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso } } } - for (Result viewResult : childViewsResult.getResults()) { + for (ViewInfo viewInfo : childViewsResult.getViewInfoList()) { short numColsDeleted = 0; - byte[][] rowViewKeyMetaData = new byte[5][]; - getVarChars(viewResult.getRow(), 5, rowViewKeyMetaData); - byte[] viewTenantId = rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]; - byte[] viewSchemaName = SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); - byte[] viewName = SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes(); + byte[] viewTenantId = viewInfo.getTenantId(); + byte[] viewSchemaName = viewInfo.getSchemaName(); + byte[] viewName = viewInfo.getViewName(); byte[] viewKey = SchemaUtil.getTableKey(viewTenantId, viewSchemaName, viewName); // lock the rows corresponding to views so that no other thread can modify the view @@ -2979,7 +2976,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso // Size for worst case - all new columns are PK column List<Mutation> mutationsForAddingColumnsToViews = Lists.newArrayListWithExpectedSize(tableMetaData.size() * ( 1 + table.getIndexes().size())); if (type == PTableType.TABLE || type == PTableType.SYSTEM) { - TableViewFinderResult childViewsResult = new TableViewFinderResult(); + TableViewFinder childViewsResult = new TableViewFinder(); findAllChildViews(region, tenantId, table, childViewsResult, clientTimeStamp); if (childViewsResult.hasViews()) { /* @@ -3003,7 +3000,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), null); } else { - mutationsForAddingColumnsToViews = new ArrayList<>(childViewsResult.getResults().size() * tableMetaData.size()); + mutationsForAddingColumnsToViews = new ArrayList<>(childViewsResult.getViewInfoList().size() * tableMetaData.size()); MetaDataMutationResult mutationResult = addColumnsAndTablePropertiesToChildViews(table, tableMetaData, mutationsForAddingColumnsToViews, schemaName, tableName, invalidateList, clientTimeStamp, childViewsResult, region, locks); // return if we were not able to add the column successfully @@ -3255,7 +3252,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso PTableType type = table.getType(); if (type == PTableType.TABLE || type == PTableType.SYSTEM) { - TableViewFinderResult childViewsResult = new TableViewFinderResult(); + TableViewFinder childViewsResult = new TableViewFinder(); findAllChildViews(region, tenantId, table, childViewsResult, clientTimeStamp); if (childViewsResult.hasViews()) { MetaDataMutationResult mutationResult = @@ -3637,52 +3634,77 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso return checkKeyInRegion(key, region, MutationCode.SCHEMA_NOT_IN_REGION); } + + private static class ViewInfo { + private byte[] tenantId; + private byte[] schemaName; + private byte[] viewName; + + public ViewInfo(byte[] tenantId, byte[] schemaName, byte[] viewName) { + super(); + this.tenantId = tenantId; + this.schemaName = schemaName; + this.viewName = viewName; + } + + public byte[] getTenantId() { + return tenantId; + } + + public byte[] getSchemaName() { + return schemaName; + } + + public byte[] getViewName() { + return viewName; + } + } /** * Certain operations, such as DROP TABLE are not allowed if there a table has child views. * This class wraps the Results of a scanning the Phoenix Metadata for child views for a specific table * and stores an additional flag for whether whether SYSTEM.CATALOG has split across multiple regions. */ - private static class TableViewFinderResult { + private static class TableViewFinder { - private List<Result> results = Lists.newArrayList(); + private List<ViewInfo> viewInfoList = Lists.newArrayList(); private boolean allViewsNotInSingleRegion = false; - private TableViewFinderResult() { + private TableViewFinder() { } - private TableViewFinderResult(List<Result> results) { - this.results = results; + private TableViewFinder(List<ViewInfo> viewInfoList) { + this.viewInfoList = viewInfoList; } public boolean hasViews() { - return !results.isEmpty(); + return !viewInfoList.isEmpty(); } private void setAllViewsNotInSingleRegion() { allViewsNotInSingleRegion = true; } - private List<Result> getResults() { - return results; + private List<ViewInfo> getViewInfoList() { + return viewInfoList; } /** * Returns true is the table has views and they are all in the same HBase region. */ private boolean allViewsInSingleRegion() { - return results.size() > 0 && !allViewsNotInSingleRegion; + return viewInfoList.size() > 0 && !allViewsNotInSingleRegion; } /** * Returns true is the table has views and they are all NOT in the same HBase region. */ private boolean allViewsInMultipleRegions() { - return results.size() > 0 && allViewsNotInSingleRegion; + return viewInfoList.size() > 0 && allViewsNotInSingleRegion; } - private void addResult(TableViewFinderResult result) { - this.results.addAll(result.getResults()); + private void addResult(TableViewFinder result) { + this.viewInfoList.addAll(result.getViewInfoList()); if (result.allViewsInMultipleRegions()) { this.setAllViewsNotInSingleRegion(); }
