Repository: phoenix Updated Branches: refs/heads/master 4f6ee74c0 -> 5097982b0
PHOENIX-2276 Creating index on a global view on a multi-tenant table fails with NPE Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/5097982b Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/5097982b Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/5097982b Branch: refs/heads/master Commit: 5097982b00b36b74fb328afaab02159e81b21af0 Parents: 4f6ee74 Author: Samarth <[email protected]> Authored: Thu Jun 16 15:14:25 2016 -0700 Committer: Samarth <[email protected]> Committed: Thu Jun 16 15:14:25 2016 -0700 ---------------------------------------------------------------------- .../end2end/BaseTenantSpecificViewIndexIT.java | 4 +- .../end2end/TenantSpecificViewIndexIT.java | 2 +- .../phoenix/end2end/index/ViewIndexIT.java | 34 ++++ .../apache/phoenix/cache/ServerCacheClient.java | 40 ++-- .../apache/phoenix/compile/DeleteCompiler.java | 8 +- .../apache/phoenix/compile/UpsertCompiler.java | 40 ++-- .../apache/phoenix/compile/WhereOptimizer.java | 29 +-- .../apache/phoenix/execute/BaseQueryPlan.java | 4 +- .../apache/phoenix/index/IndexMaintainer.java | 18 +- .../query/ConnectionQueryServicesImpl.java | 194 ++++++++++++++++++- .../apache/phoenix/schema/MetaDataClient.java | 21 +- .../org/apache/phoenix/util/MetaDataUtil.java | 2 +- .../org/apache/phoenix/util/PhoenixRuntime.java | 3 +- .../java/org/apache/phoenix/util/ScanUtil.java | 8 +- .../TenantSpecificViewIndexCompileTest.java | 6 +- .../util/TenantIdByteConversionTest.java | 2 +- 16 files changed, 323 insertions(+), 92 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/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 9f25531..0703e82 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 @@ -140,9 +140,9 @@ public class BaseTenantSpecificViewIndexIT extends BaseHBaseManagedTimeIT { + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); } else { String expected = saltBuckets == null ? - "CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['" + tenantId + "',-32768,'" + valuePrefix + "v2-1']\n" + "CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [-32768,'" + tenantId + "','" + valuePrefix + "v2-1']\n" + " SERVER FILTER BY FIRST KEY ONLY" : - "CLIENT PARALLEL 3-WAY RANGE SCAN OVER _IDX_T [0,'" + tenantId + "',-32768,'" + valuePrefix + "v2-1']\n" + "CLIENT PARALLEL 3-WAY RANGE SCAN OVER _IDX_T [0,-32768,'" + tenantId + "','" + valuePrefix + "v2-1']\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT"; assertEquals(expected, QueryUtil.getExplainPlan(rs)); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java index 69d9140..f468d20 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java @@ -206,7 +206,7 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT { assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + Bytes.toString(MetaDataUtil.getViewIndexPhysicalName(SchemaUtil .getPhysicalHBaseTableName(tableName, isNamespaceMapped, PTableType.TABLE).getBytes())) - + " ['" + tenantId + "',-32768,'f']\n" + " SERVER FILTER BY FIRST KEY ONLY", + + " [-32768,'" + tenantId + "','f']\n" + " SERVER FILTER BY FIRST KEY ONLY", QueryUtil.getExplainPlan(rs)); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java index 7b6e476..4da62de 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.sql.Connection; +import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -33,9 +34,11 @@ import java.util.Properties; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.phoenix.compile.QueryPlan; import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT; import org.apache.phoenix.end2end.Shadower; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; +import org.apache.phoenix.jdbc.PhoenixStatement; import org.apache.phoenix.query.QueryServices; import org.apache.phoenix.schema.PNameFactory; import org.apache.phoenix.util.MetaDataUtil; @@ -191,4 +194,35 @@ public class ViewIndexIT extends BaseHBaseManagedTimeIT { assertTrue(rs.next()); assertFalse(rs.next()); } + + @Test + public void testCreatingIndexOnGlobalView() throws Exception { + String baseTable = "testCreatingIndexOnGlobalView".toUpperCase(); + String globalView = "globalView".toUpperCase(); + String globalViewIdx = "globalView_idx".toUpperCase(); + try (Connection conn = DriverManager.getConnection(getUrl())) { + conn.createStatement().execute("CREATE TABLE " + baseTable + " (TENANT_ID CHAR(15) NOT NULL, PK2 DATE NOT NULL, PK3 INTEGER NOT NULL, KV1 VARCHAR, KV2 VARCHAR, KV3 CHAR(15) CONSTRAINT PK PRIMARY KEY(TENANT_ID, PK2 ROW_TIMESTAMP, PK3)) MULTI_TENANT=true"); + conn.createStatement().execute("CREATE VIEW " + globalView + " AS SELECT * FROM " + baseTable); + conn.createStatement().execute("CREATE INDEX " + globalViewIdx + " ON " + globalView + " (PK3 DESC, KV3) INCLUDE (KV1)"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + globalView + " (TENANT_ID, PK2, PK3, KV1, KV3) VALUES (?, ?, ?, ?, ?)"); + stmt.setString(1, "tenantId"); + stmt.setDate(2, new Date(100)); + stmt.setInt(3, 1); + stmt.setString(4, "KV1"); + stmt.setString(5, "KV3"); + stmt.executeUpdate(); + conn.commit(); + + // Verify that query against the global view index works + stmt = conn.prepareStatement("SELECT KV1 FROM " + globalView + " WHERE PK3 = ? AND KV3 = ?"); + stmt.setInt(1, 1); + stmt.setString(2, "KV3"); + ResultSet rs = stmt.executeQuery(); + QueryPlan plan = stmt.unwrap(PhoenixStatement.class).getQueryPlan(); + assertTrue(plan.getTableRef().getTable().getName().getString().equals(globalViewIdx)); + assertTrue(rs.next()); + assertEquals("KV1", rs.getString(1)); + assertFalse(rs.next()); + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java b/phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java index aea15c2..d88b094 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java @@ -195,18 +195,22 @@ public class ServerCacheClient { BlockingRpcCallback<AddServerCacheResponse> rpcCallback = new BlockingRpcCallback<AddServerCacheResponse>(); AddServerCacheRequest.Builder builder = AddServerCacheRequest.newBuilder(); - if(connection.getTenantId() != null){ + final byte[] tenantIdBytes; + if(cacheUsingTable.isMultiTenant()) { try { - byte[] tenantIdBytes = + tenantIdBytes = connection.getTenantId() == null ? null : ScanUtil.getTenantIdBytes( cacheUsingTable.getRowKeySchema(), - cacheUsingTable.getBucketNum()!=null, - connection.getTenantId(), - cacheUsingTable.isMultiTenant()); - builder.setTenantId(ByteStringer.wrap(tenantIdBytes)); + cacheUsingTable.getBucketNum() != null, + connection.getTenantId(), cacheUsingTable.getViewIndexId() != null); } catch (SQLException e) { - new IOException(e); + throw new IOException(e); } + } else { + tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes(); + } + if (tenantIdBytes != null) { + builder.setTenantId(ByteStringer.wrap(tenantIdBytes)); } builder.setCacheId(ByteStringer.wrap(cacheId)); builder.setCachePtr(org.apache.phoenix.protobuf.ProtobufUtil.toProto(cachePtr)); @@ -325,20 +329,24 @@ public class ServerCacheClient { BlockingRpcCallback<RemoveServerCacheResponse> rpcCallback = new BlockingRpcCallback<RemoveServerCacheResponse>(); RemoveServerCacheRequest.Builder builder = RemoveServerCacheRequest.newBuilder(); - if(connection.getTenantId() != null){ + final byte[] tenantIdBytes; + if(cacheUsingTable.isMultiTenant()) { try { - byte[] tenantIdBytes = + tenantIdBytes = connection.getTenantId() == null ? null : ScanUtil.getTenantIdBytes( cacheUsingTable.getRowKeySchema(), - cacheUsingTable.getBucketNum()!=null, - connection.getTenantId(), - cacheUsingTable.isMultiTenant()); - builder.setTenantId(ByteStringer.wrap(tenantIdBytes)); + cacheUsingTable.getBucketNum() != null, + connection.getTenantId(), cacheUsingTable.getViewIndexId() != null); } catch (SQLException e) { - new IOException(e); + throw new IOException(e); } - } - builder.setCacheId(ByteStringer.wrap(cacheId)); + } else { + tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes(); + } + if (tenantIdBytes != null) { + builder.setTenantId(ByteStringer.wrap(tenantIdBytes)); + } + builder.setCacheId(ByteStringer.wrap(cacheId)); instance.removeServerCache(controller, builder.build(), rpcCallback); if(controller.getFailedOn() != null) { throw controller.getFailedOn(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java index 696b74f..504f994 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java @@ -107,7 +107,7 @@ public class DeleteCompiler { PName tenantId = connection.getTenantId(); byte[] tenantIdBytes = null; if (tenantId != null) { - tenantIdBytes = ScanUtil.getTenantIdBytes(table.getRowKeySchema(), table.getBucketNum() != null, tenantId); + tenantIdBytes = ScanUtil.getTenantIdBytes(table.getRowKeySchema(), table.getBucketNum() != null, tenantId, table.getViewIndexId() != null); } final boolean isAutoCommit = connection.getAutoCommit(); ConnectionQueryServices services = connection.getQueryServices(); @@ -125,12 +125,12 @@ public class DeleteCompiler { boolean isSharedViewIndex = table.getViewIndexId() != null; int offset = (table.getBucketNum() == null ? 0 : 1); byte[][] values = new byte[pkColumns.size()][]; - if (isMultiTenant) { - values[offset++] = tenantIdBytes; - } if (isSharedViewIndex) { values[offset++] = MetaDataUtil.getViewIndexIdDataType().toBytes(table.getViewIndexId()); } + if (isMultiTenant) { + values[offset++] = tenantIdBytes; + } try (PhoenixResultSet rs = new PhoenixResultSet(iterator, projector, childContext)) { int rowCount = 0; while (rs.next()) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java index 7d60cd5..be6499b 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java @@ -334,18 +334,18 @@ public class UpsertCompiler { targetColumns = Lists.newArrayListWithExpectedSize(columnIndexesToBe.length); targetColumns.addAll(Collections.<PColumn>nCopies(columnIndexesToBe.length, null)); int minPKPos = 0; - if (isTenantSpecific) { - PColumn tenantColumn = table.getPKColumns().get(minPKPos); - columnIndexesToBe[minPKPos] = tenantColumn.getPosition(); - targetColumns.set(minPKPos, tenantColumn); - minPKPos++; - } if (isSharedViewIndex) { PColumn indexIdColumn = table.getPKColumns().get(minPKPos); columnIndexesToBe[minPKPos] = indexIdColumn.getPosition(); targetColumns.set(minPKPos, indexIdColumn); minPKPos++; } + if (isTenantSpecific) { + PColumn tenantColumn = table.getPKColumns().get(minPKPos); + columnIndexesToBe[minPKPos] = tenantColumn.getPosition(); + targetColumns.set(minPKPos, tenantColumn); + minPKPos++; + } for (int i = posOffset, j = 0; i < allColumnsToBe.size(); i++) { PColumn column = allColumnsToBe.get(i); if (SchemaUtil.isPKColumn(column)) { @@ -375,6 +375,13 @@ public class UpsertCompiler { Arrays.fill(pkSlotIndexesToBe, -1); // TODO: necessary? So we'll get an AIOB exception if it's not replaced BitSet pkColumnsSet = new BitSet(table.getPKColumns().size()); int i = 0; + if (isSharedViewIndex) { + PColumn indexIdColumn = table.getPKColumns().get(i + posOffset); + columnIndexesToBe[i] = indexIdColumn.getPosition(); + pkColumnsSet.set(pkSlotIndexesToBe[i] = i + posOffset); + targetColumns.set(i, indexIdColumn); + i++; + } // Add tenant column directly, as we don't want to resolve it as this will fail if (isTenantSpecific) { PColumn tenantColumn = table.getPKColumns().get(i + posOffset); @@ -383,13 +390,6 @@ public class UpsertCompiler { targetColumns.set(i, tenantColumn); i++; } - if (isSharedViewIndex) { - PColumn indexIdColumn = table.getPKColumns().get(i + posOffset); - columnIndexesToBe[i] = indexIdColumn.getPosition(); - pkColumnsSet.set(pkSlotIndexesToBe[i] = i + posOffset); - targetColumns.set(i, indexIdColumn); - i++; - } for (ColumnName colName : columnNodes) { ColumnRef ref = resolver.resolveColumn(null, colName.getFamilyName(), colName.getColumnName()); PColumn column = ref.getColumn(); @@ -820,13 +820,13 @@ public class UpsertCompiler { ///////////////////////////////////////////////////////////////////// final byte[][] values = new byte[nValuesToSet][]; int nodeIndex = 0; - if (isTenantSpecific) { - PName tenantId = connection.getTenantId(); - values[nodeIndex++] = ScanUtil.getTenantIdBytes(table.getRowKeySchema(), table.getBucketNum() != null, tenantId); - } if (isSharedViewIndex) { values[nodeIndex++] = MetaDataUtil.getViewIndexIdDataType().toBytes(table.getViewIndexId()); } + if (isTenantSpecific) { + PName tenantId = connection.getTenantId(); + values[nodeIndex++] = ScanUtil.getTenantIdBytes(table.getRowKeySchema(), table.getBucketNum() != null, tenantId, isSharedViewIndex); + } final int nodeIndexOffset = nodeIndex; // Allocate array based on size of all columns in table, @@ -1015,12 +1015,12 @@ public class UpsertCompiler { return select; } List<AliasedNode> selectNodes = newArrayListWithCapacity(select.getSelect().size() + 1 + addViewColumns.size()); - if (table.isMultiTenant() && tenantId != null) { - selectNodes.add(new AliasedNode(null, new LiteralParseNode(tenantId))); - } if (table.getViewIndexId() != null) { selectNodes.add(new AliasedNode(null, new LiteralParseNode(table.getViewIndexId()))); } + if (table.isMultiTenant() && tenantId != null) { + selectNodes.add(new AliasedNode(null, new LiteralParseNode(tenantId))); + } selectNodes.addAll(select.getSelect()); for (PColumn column : addViewColumns) { byte[] byteValue = column.getViewConstant(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java index e1e3c53..8c2a216 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java @@ -114,8 +114,10 @@ public class WhereOptimizer { boolean isSalted = nBuckets != null; RowKeySchema schema = table.getRowKeySchema(); boolean isMultiTenant = tenantId != null && table.isMultiTenant(); + boolean isSharedIndex = table.getViewIndexId() != null; + if (isMultiTenant) { - tenantIdBytes = ScanUtil.getTenantIdBytes(schema, isSalted, tenantId); + tenantIdBytes = ScanUtil.getTenantIdBytes(schema, isSalted, tenantId, isSharedIndex); } if (whereClause == null && (tenantId == null || !table.isMultiTenant()) && table.getViewIndexId() == null) { @@ -187,6 +189,19 @@ public class WhereOptimizer { pkPos++; } + // Add unique index ID for shared indexes on views. This ensures + // that different indexes don't interleave. + if (hasViewIndex) { + byte[] viewIndexBytes = MetaDataUtil.getViewIndexIdDataType().toBytes(table.getViewIndexId()); + KeyRange indexIdKeyRange = KeyRange.getKeyRange(viewIndexBytes); + cnf.add(singletonList(indexIdKeyRange)); + if (hasMinMaxRange) { + System.arraycopy(viewIndexBytes, 0, minMaxRangePrefix, minMaxRangeOffset, viewIndexBytes.length); + minMaxRangeOffset += viewIndexBytes.length; + } + pkPos++; + } + // Add tenant data isolation for tenant-specific tables if (isMultiTenant) { KeyRange tenantIdKeyRange = KeyRange.getKeyRange(tenantIdBytes); @@ -202,18 +217,6 @@ public class WhereOptimizer { } pkPos++; } - // Add unique index ID for shared indexes on views. This ensures - // that different indexes don't interleave. - if (hasViewIndex) { - byte[] viewIndexBytes = MetaDataUtil.getViewIndexIdDataType().toBytes(table.getViewIndexId()); - KeyRange indexIdKeyRange = KeyRange.getKeyRange(viewIndexBytes); - cnf.add(singletonList(indexIdKeyRange)); - if (hasMinMaxRange) { - System.arraycopy(viewIndexBytes, 0, minMaxRangePrefix, minMaxRangeOffset, viewIndexBytes.length); - minMaxRangeOffset += viewIndexBytes.length; - } - pkPos++; - } // Prepend minMaxRange with fixed column values so we can properly intersect the // range with the other range. http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java index 83e55ee..b940084 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java @@ -278,8 +278,8 @@ public abstract class BaseQueryPlan implements QueryPlan { tenantIdBytes = connection.getTenantId() == null ? null : ScanUtil.getTenantIdBytes( table.getRowKeySchema(), - table.getBucketNum()!=null, - connection.getTenantId()); + table.getBucketNum() != null, + connection.getTenantId(), table.getViewIndexId() != null); } else { tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes(); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java index 6a316d9..db823de 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java @@ -476,6 +476,11 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { // Skip data table salt byte int maxRowKeyOffset = rowKeyPtr.getOffset() + rowKeyPtr.getLength(); dataRowKeySchema.iterator(rowKeyPtr, ptr, dataPosOffset); + + if (viewIndexId != null) { + output.write(viewIndexId); + } + if (isMultiTenant) { dataRowKeySchema.next(ptr, dataPosOffset, maxRowKeyOffset); output.write(ptr.get(), ptr.getOffset(), ptr.getLength()); @@ -484,9 +489,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } dataPosOffset++; } - if (viewIndexId != null) { - output.write(viewIndexId); - } // Write index row key for (int i = dataPosOffset; i < dataRowKeySchema.getFieldCount(); i++) { @@ -714,11 +716,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { nIndexedColumns--; } int dataPosOffset = isDataTableSalted ? 1 : 0 ; - if (isMultiTenant) { - Field field = dataRowKeySchema.getField(dataPosOffset++); - builder.addField(field, field.isNullable(), field.getSortOrder()); - nIndexedColumns--; - } if (viewIndexId != null) { nIndexedColumns--; builder.addField(new PDatum() { @@ -750,6 +747,11 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { }, false, SortOrder.getDefault()); } + if (isMultiTenant) { + Field field = dataRowKeySchema.getField(dataPosOffset++); + builder.addField(field, field.isNullable(), field.getSortOrder()); + nIndexedColumns--; + } Field[] indexFields = new Field[nIndexedColumns]; BitSet viewConstantColumnBitSet = this.rowKeyMetaData.getViewConstantColumnBitSet(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java index 56bd50c..d1cbdfc 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java @@ -21,7 +21,17 @@ import static org.apache.hadoop.hbase.HColumnDescriptor.TTL; import static org.apache.phoenix.coprocessor.MetaDataProtocol.PHOENIX_MAJOR_VERSION; import static org.apache.phoenix.coprocessor.MetaDataProtocol.PHOENIX_MINOR_VERSION; import static org.apache.phoenix.coprocessor.MetaDataProtocol.PHOENIX_PATCH_NUMBER; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ORDINAL_POSITION; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME; import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID; import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_DROP_METADATA; import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RENEW_LEASE_ENABLED; import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RENEW_LEASE_THREAD_POOL_SIZE; @@ -31,6 +41,8 @@ import static org.apache.phoenix.util.UpgradeUtil.upgradeTo4_5_0; import java.io.IOException; import java.lang.ref.WeakReference; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; @@ -156,6 +168,7 @@ import org.apache.phoenix.schema.PMetaDataImpl; import org.apache.phoenix.schema.PName; import org.apache.phoenix.schema.PNameFactory; import org.apache.phoenix.schema.PTable; +import org.apache.phoenix.schema.PTable.IndexType; import org.apache.phoenix.schema.PTableKey; import org.apache.phoenix.schema.PTableType; import org.apache.phoenix.schema.ReadOnlyTableException; @@ -893,7 +906,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement private static interface RetriableOperation { boolean checkForCompletion() throws TimeoutException, IOException; - String getOperatioName(); + String getOperationName(); } private void pollForUpdatedTableDescriptor(final HBaseAdmin admin, final HTableDescriptor newTableDescriptor, @@ -901,7 +914,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement checkAndRetry(new RetriableOperation() { @Override - public String getOperatioName() { + public String getOperationName() { return "UpdateOrNewTableDescriptor"; } @@ -932,7 +945,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement // Else, we swallow the exception and retry till we reach maxRetries. if (numTries == 1 || numTries == maxRetries) { watch.stop(); - TimeoutException toThrow = new TimeoutException("Operation " + op.getOperatioName() + TimeoutException toThrow = new TimeoutException("Operation " + op.getOperationName() + " didn't complete because of exception. Time elapsed: " + watch.elapsedMillis()); toThrow.initCause(ex); throw toThrow; @@ -945,13 +958,13 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement watch.stop(); if (!success) { - throw new TimeoutException("Operation " + op.getOperatioName() + " didn't complete within " + throw new TimeoutException("Operation " + op.getOperationName() + " didn't complete within " + watch.elapsedMillis() + " ms " + (numTries > 1 ? ("after trying " + numTries + (numTries > 1 ? "times." : "time.")) : "")); } else { if (logger.isDebugEnabled()) { logger.debug("Operation " - + op.getOperatioName() + + op.getOperationName() + " completed within " + watch.elapsedMillis() + "ms " @@ -2493,6 +2506,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0, PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA + " " + PBoolean.INSTANCE.getSqlTypeName()); + metaConnection = disableViewIndexes(metaConnection); ConnectionQueryServicesImpl.this.removeTable(null, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, null, MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0); @@ -2710,6 +2724,176 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement } return metaConnection; } + + private PhoenixConnection disableViewIndexes(PhoenixConnection connParam) throws SQLException, IOException, InterruptedException, TimeoutException { + Properties props = PropertiesUtil.deepCopy(connParam.getClientInfo()); + Long originalScn = null; + String str = props.getProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB); + if (str != null) { + originalScn = Long.valueOf(str); + } + // don't use the passed timestamp as scn because we want to query all view indexes up to now. + props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(HConstants.LATEST_TIMESTAMP)); + Set<String> physicalTables = new HashSet<>(); + SQLException sqlEx = null; + PhoenixConnection globalConnection = null; + PhoenixConnection toReturn = null; + try { + globalConnection = new PhoenixConnection(connParam, this, props); + String tenantId = null; + try (HBaseAdmin admin = getAdmin()) { + String fetchViewIndexes = "SELECT " + TENANT_ID + ", " + TABLE_SCHEM + ", " + TABLE_NAME + + ", " + DATA_TABLE_NAME + " FROM " + SYSTEM_CATALOG_NAME + " WHERE " + VIEW_INDEX_ID + + " IS NOT NULL AND " + INDEX_TYPE + "<>" + IndexType.LOCAL.getSerializedValue(); + String disableIndexDDL = "ALTER INDEX %s ON %s DISABLE"; + try (ResultSet rs = globalConnection.createStatement().executeQuery(fetchViewIndexes)) { + while (rs.next()) { + tenantId = rs.getString(1); + String indexSchema = rs.getString(2); + String indexName = rs.getString(3); + String viewName = rs.getString(4); + String fullIndexName = SchemaUtil.getTableName(indexSchema, indexName); + PTable viewPTable = null; + // Disable the view index and truncate the underlying hbase table. + // Users would need to rebuild the view indexes. + if (tenantId != null && !tenantId.isEmpty()) { + Properties newProps = PropertiesUtil.deepCopy(globalConnection.getClientInfo()); + newProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); + PTable indexPTable = null; + try (PhoenixConnection tenantConnection = new PhoenixConnection(globalConnection, this, newProps)) { + viewPTable = PhoenixRuntime.getTable(tenantConnection, viewName); + tenantConnection.createStatement().execute(String.format(disableIndexDDL, fullIndexName, viewName)); + indexPTable = PhoenixRuntime.getTable(tenantConnection, fullIndexName); + } + + int offset = indexPTable.getBucketNum() != null ? 1 : 0; + int existingTenantIdPosition = ++offset; // positions are stored 1 based + int existingViewIdxIdPosition = ++offset; + int newTenantIdPosition = existingViewIdxIdPosition; + int newViewIdxPosition = existingTenantIdPosition; + String tenantIdColumn = indexPTable.getColumns().get(existingTenantIdPosition - 1).getName().getString(); + int index = 0; + String updatePosition = + "UPSERT INTO " + + SYSTEM_CATALOG_NAME + + " ( " + + TENANT_ID + + "," + + TABLE_SCHEM + + "," + + TABLE_NAME + + "," + + COLUMN_NAME + + "," + + COLUMN_FAMILY + + "," + + ORDINAL_POSITION + + ") SELECT " + + TENANT_ID + + "," + + TABLE_SCHEM + + "," + + TABLE_NAME + + "," + + COLUMN_NAME + + "," + + COLUMN_FAMILY + + "," + + "?" + + " FROM " + + SYSTEM_CATALOG_NAME + + " WHERE " + + TENANT_ID + + " = ? " + + " AND " + + TABLE_NAME + + " = ? " + + " AND " + + (indexSchema == null ? TABLE_SCHEM + " IS NULL" : TABLE_SCHEM + " = ? ") + + " AND " + + COLUMN_NAME + + " = ? "; + // update view index position + try (PreparedStatement s = globalConnection.prepareStatement(updatePosition)) { + index = 0; + s.setInt(++index, newViewIdxPosition); + s.setString(++index, tenantId); + s.setString(++index, indexName); + if (indexSchema != null) { + s.setString(++index, indexSchema); + } + s.setString(++index, MetaDataUtil.getViewIndexIdColumnName()); + s.executeUpdate(); + } + // update tenant id position + try (PreparedStatement s = globalConnection.prepareStatement(updatePosition)) { + index = 0; + s.setInt(++index, newTenantIdPosition); + s.setString(++index, tenantId); + s.setString(++index, indexName); + if (indexSchema != null) { + s.setString(++index, indexSchema); + } + s.setString(++index, tenantIdColumn); + s.executeUpdate(); + } + globalConnection.commit(); + } else { + viewPTable = PhoenixRuntime.getTable(globalConnection, viewName); + globalConnection.createStatement().execute(String.format(disableIndexDDL, fullIndexName, viewName)); + } + String indexPhysicalTableName = MetaDataUtil.getViewIndexTableName(viewPTable.getPhysicalName().getString()); + if (physicalTables.add(indexPhysicalTableName)) { + final TableName tableName = TableName.valueOf(indexPhysicalTableName); + admin.disableTableAsync(tableName); + checkAndRetry(new RetriableOperation() { + @Override + public boolean checkForCompletion() throws TimeoutException, + IOException { + return admin.isTableDisabled(tableName); + } + + @Override + public String getOperationName() { + return "Disable table: " + tableName.getNameAsString(); + } + + }); + admin.truncateTable(tableName, false); + } + } + } + } + if (originalScn != null) { + props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(originalScn)); + } + toReturn = new PhoenixConnection(globalConnection, this, props); + } catch (SQLException e) { + sqlEx = e; + } finally { + sqlEx = closeConnection(connParam, sqlEx); + sqlEx = closeConnection(globalConnection, sqlEx); + if (sqlEx != null) { + throw sqlEx; + } + } + return toReturn; + } + + + private static SQLException closeConnection(PhoenixConnection conn, SQLException sqlEx) { + SQLException toReturn = sqlEx; + try { + conn.close(); + } catch (SQLException e) { + if (toReturn != null) { + toReturn.setNextException(e); + } else { + toReturn = e; + } + } + return toReturn; + } /** * Forces update of SYSTEM.CATALOG by setting column to existing value http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java index cacf687..3a4010b 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java @@ -1316,16 +1316,6 @@ public class MetaDataClient { List<ColumnDefInPkConstraint> allPkColumns = Lists.newArrayListWithExpectedSize(unusedPkColumns.size()); List<ColumnDef> columnDefs = Lists.newArrayListWithExpectedSize(includedColumns.size() + indexParseNodeAndSortOrderList.size()); - if (dataTable.isMultiTenant()) { - // Add tenant ID column as first column in index - PColumn col = dataTable.getPKColumns().get(posOffset); - RowKeyColumnExpression columnExpression = new RowKeyColumnExpression(col, new RowKeyValueAccessor(pkColumns, posOffset), col.getName().getString()); - unusedPkColumns.remove(columnExpression); - PDataType dataType = IndexUtil.getIndexColumnDataType(col); - ColumnName colName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(col)); - allPkColumns.add(new ColumnDefInPkConstraint(colName, col.getSortOrder(), false)); - columnDefs.add(FACTORY.columnDef(colName, dataType.getSqlTypeName(), col.isNullable(), col.getMaxLength(), col.getScale(), false, SortOrder.getDefault(), col.getName().getString(), col.isRowTimestamp())); - } /* * Allocate an index ID in two circumstances: * 1) for a local index, as all local indexes will reside in the same HBase table @@ -1333,13 +1323,22 @@ public class MetaDataClient { */ if (isLocalIndex || (dataTable.getType() == PTableType.VIEW && dataTable.getViewType() != ViewType.MAPPED)) { allocateIndexId = true; - // Next add index ID column PDataType dataType = MetaDataUtil.getViewIndexIdDataType(); ColumnName colName = ColumnName.caseSensitiveColumnName(MetaDataUtil.getViewIndexIdColumnName()); allPkColumns.add(new ColumnDefInPkConstraint(colName, SortOrder.getDefault(), false)); columnDefs.add(FACTORY.columnDef(colName, dataType.getSqlTypeName(), false, null, null, false, SortOrder.getDefault(), null, false)); } + if (dataTable.isMultiTenant()) { + PColumn col = dataTable.getPKColumns().get(posOffset); + RowKeyColumnExpression columnExpression = new RowKeyColumnExpression(col, new RowKeyValueAccessor(pkColumns, posOffset), col.getName().getString()); + unusedPkColumns.remove(columnExpression); + PDataType dataType = IndexUtil.getIndexColumnDataType(col); + ColumnName colName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(col)); + allPkColumns.add(new ColumnDefInPkConstraint(colName, col.getSortOrder(), false)); + columnDefs.add(FACTORY.columnDef(colName, dataType.getSqlTypeName(), col.isNullable(), col.getMaxLength(), col.getScale(), false, SortOrder.getDefault(), col.getName().getString(), col.isRowTimestamp())); + } + PhoenixStatement phoenixStatment = new PhoenixStatement(connection); StatementContext context = new StatementContext(phoenixStatment, resolver); IndexExpressionCompiler expressionIndexCompiler = new IndexExpressionCompiler(context); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/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 9f2f9fa..ae81d37 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 @@ -93,7 +93,7 @@ public class MetaDataUtil { public static final String VIEW_INDEX_SEQUENCE_PREFIX = "_SEQ_"; public static final String VIEW_INDEX_SEQUENCE_NAME_PREFIX = "_ID_"; public static final byte[] VIEW_INDEX_SEQUENCE_PREFIX_BYTES = Bytes.toBytes(VIEW_INDEX_SEQUENCE_PREFIX); - public static final String VIEW_INDEX_ID_COLUMN_NAME = "_INDEX_ID"; + private static final String VIEW_INDEX_ID_COLUMN_NAME = "_INDEX_ID"; public static final String PARENT_TABLE_KEY = "PARENT_TABLE"; public static final byte[] PARENT_TABLE_KEY_BYTES = Bytes.toBytes("PARENT_TABLE"); http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java index 8cc536b..e68c8d4 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java @@ -1056,7 +1056,8 @@ public class PhoenixRuntime { throw new SQLFeatureNotSupportedException(); } - int pkPosition = table.getBucketNum() == null ? 0 : 1; + // skip salt and viewIndexId columns. + int pkPosition = table.getBucketNum() == null ? 0 : 1 + (table.getViewIndexId() == null ? 0 : 1); List<PColumn> pkColumns = table.getPKColumns(); return new RowKeyColumnExpression(pkColumns.get(pkPosition), new RowKeyValueAccessor(pkColumns, pkPosition)); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java index f3e3d28..7a3014b 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java @@ -766,16 +766,16 @@ public class ScanUtil { return Bytes.compareTo(key, 0, nBytesToCheck, ZERO_BYTE_ARRAY, 0, nBytesToCheck) != 0; } - public static byte[] getTenantIdBytes(RowKeySchema schema, boolean isSalted, PName tenantId, boolean isMultiTenantTable) + public static byte[] getTenantIdBytes(RowKeySchema schema, boolean isSalted, PName tenantId, boolean isMultiTenantTable, boolean isSharedIndex) throws SQLException { return isMultiTenantTable ? - getTenantIdBytes(schema, isSalted, tenantId) + getTenantIdBytes(schema, isSalted, tenantId, isSharedIndex) : tenantId.getBytes(); } - public static byte[] getTenantIdBytes(RowKeySchema schema, boolean isSalted, PName tenantId) + public static byte[] getTenantIdBytes(RowKeySchema schema, boolean isSalted, PName tenantId, boolean isSharedIndex) throws SQLException { - int pkPos = isSalted ? 1 : 0; + int pkPos = (isSalted ? 1 : 0) + (isSharedIndex ? 1 : 0); Field field = schema.getField(pkPos); PDataType dataType = field.getDataType(); byte[] convertedValue; http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java index 63e513b..27c30fc 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java @@ -50,7 +50,7 @@ public class TenantSpecificViewIndexCompileTest extends BaseConnectionlessQueryT conn.createStatement().execute("CREATE INDEX i1 ON v(v2) INCLUDE(v1)"); ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v1,v2 FROM v WHERE v2 > 'a' ORDER BY v2"); - assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32768,'a'] - ['me',-32768,*]", + assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [-32768,'me','a'] - [-32768,'me',*]", QueryUtil.getExplainPlan(rs)); } @@ -194,7 +194,7 @@ public class TenantSpecificViewIndexCompileTest extends BaseConnectionlessQueryT conn.createStatement().execute("CREATE INDEX i1 ON v(v2)"); ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM v WHERE v2 > 'a' and k2 = 'a' ORDER BY v2,k2"); - assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32766,'a'] - ['me',-32766,*]\n" + + assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [-32766,'me','a'] - [-32766,'me',*]\n" + " SERVER FILTER BY FIRST KEY ONLY", QueryUtil.getExplainPlan(rs)); @@ -227,7 +227,7 @@ public class TenantSpecificViewIndexCompileTest extends BaseConnectionlessQueryT // Confirm that a read-only view on an updatable view still optimizes out the read-only parts of the updatable view ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM v2 WHERE v3 > 'a' and k2 = 'a' ORDER BY v3,k2"); - assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32767,'a'] - ['me',-32767,*]", + assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [-32767,'me','a'] - [-32767,'me',*]", QueryUtil.getExplainPlan(rs)); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/5097982b/phoenix-core/src/test/java/org/apache/phoenix/util/TenantIdByteConversionTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TenantIdByteConversionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TenantIdByteConversionTest.java index 4d433aa..fb70d22 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/util/TenantIdByteConversionTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TenantIdByteConversionTest.java @@ -61,7 +61,7 @@ public class TenantIdByteConversionTest { @Test public void test() { try { - byte[] actualTenantIdBytes = ScanUtil.getTenantIdBytes(schema, isSalted, tenantId); + byte[] actualTenantIdBytes = ScanUtil.getTenantIdBytes(schema, isSalted, tenantId, false); assertArrayEquals(expectedTenantIdBytes, actualTenantIdBytes); } catch (SQLException ex) { fail(ex.getMessage());
