This is an automated email from the ASF dual-hosted git repository. gjacoby pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/master by this push: new 2d88e78 PHOENIX-5317 Upserting rows into child views with pk fails when the base view has an index on it 2d88e78 is described below commit 2d88e786eb80fa5c1d9e74c55c6d0c464738c4f2 Author: Sandeep Guggilam <sguggi...@sandeepg-ltm.internal.salesforce.com> AuthorDate: Thu Mar 12 11:26:55 2020 -0700 PHOENIX-5317 Upserting rows into child views with pk fails when the base view has an index on it Signed-off-by: Geoffrey Jacoby <gjac...@apache.org> --- .../phoenix/end2end/MetaDataEndpointImplIT.java | 83 ++++++++++++- .../coprocessor/generated/ServerCachingProtos.java | 129 ++++++++++++++++++--- .../org/apache/phoenix/index/IndexMaintainer.java | 46 ++++++-- .../src/main/ServerCachingService.proto | 1 + 4 files changed, 227 insertions(+), 32 deletions(-) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MetaDataEndpointImplIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MetaDataEndpointImplIT.java index 75af5f8..6724da9 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MetaDataEndpointImplIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MetaDataEndpointImplIT.java @@ -10,18 +10,18 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Properties; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.TableName; -import org.apache.phoenix.end2end.ParallelStatsDisabledIT; -import org.apache.phoenix.util.TableViewFinderResult; -import org.apache.phoenix.util.ViewUtil; import org.apache.phoenix.exception.SQLExceptionCode; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.schema.PColumn; import org.apache.phoenix.schema.PTable; import org.apache.phoenix.schema.TableNotFoundException; import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.TableViewFinderResult; +import org.apache.phoenix.util.ViewUtil; import org.junit.Test; import com.google.common.base.Joiner; @@ -96,6 +96,83 @@ public class MetaDataEndpointImplIT extends ParallelStatsDisabledIT { assertColumnNamesEqual(PhoenixRuntime.getTable(conn, childMostView.getName().getString()), "PK2", "V1", "V2", "CARRIER", "DROPPED_CALLS"); } + + @Test + public void testUpsertIntoChildViewWithPKAndIndex() throws Exception { + String baseTable = generateUniqueName(); + String view = generateUniqueName(); + String childView = generateUniqueName(); + + try (Connection conn = DriverManager.getConnection(getUrl())) { + String baseTableDDL = "CREATE TABLE IF NOT EXISTS " + baseTable + + " (TENANT_ID VARCHAR NOT NULL, KEY_PREFIX CHAR(3) NOT NULL, " + + "V1 VARCHAR CONSTRAINT PK PRIMARY KEY(TENANT_ID, KEY_PREFIX)) " + + "VERSIONS=1, IMMUTABLE_ROWS=TRUE"; + conn.createStatement().execute(baseTableDDL); + String view1DDL = "CREATE VIEW IF NOT EXISTS " + view + + "(V2 VARCHAR NOT NULL,V3 BIGINT NOT NULL, " + + "V4 VARCHAR CONSTRAINT PKVIEW PRIMARY KEY(V2, V3)) AS SELECT * FROM " + + baseTable + " WHERE KEY_PREFIX = '0CY'"; + conn.createStatement().execute(view1DDL); + + // Create an Index on the base view + String view1Index = generateUniqueName() + "_IDX"; + conn.createStatement().execute("CREATE INDEX " + view1Index + + " ON " + view + " (V2, V3) include (V1, V4)"); + + // Create a child view with primary key constraint + String childViewDDL = "CREATE VIEW IF NOT EXISTS " + childView + + " (V5 VARCHAR NOT NULL, V6 VARCHAR NOT NULL CONSTRAINT PK PRIMARY KEY " + + "(V5, V6)) AS SELECT * FROM " + view; + conn.createStatement().execute(childViewDDL); + + String upsert = "UPSERT INTO " + childView + " (TENANT_ID, V2, V3, V5, V6) " + + "VALUES ('00D005000000000', 'zzzzz', 10, 'zzzzz', 'zzzzz')"; + conn.createStatement().executeUpdate(upsert); + conn.commit(); + } + } + + @Test + public void testUpsertIntoTenantChildViewWithPKAndIndex() throws Exception { + String baseTable = generateUniqueName(); + String view = generateUniqueName(); + String childView = generateUniqueName(); + String tenantId = "TENANT"; + + try (Connection conn = DriverManager.getConnection(getUrl())) { + String baseTableDDL = "CREATE TABLE IF NOT EXISTS " + baseTable + + " (TENANT_ID VARCHAR NOT NULL, KEY_PREFIX CHAR(3) NOT NULL, " + + "V1 VARCHAR CONSTRAINT PK PRIMARY KEY(TENANT_ID, KEY_PREFIX)) " + + "MULTI_TENANT=TRUE, VERSIONS=1, IMMUTABLE_ROWS=TRUE"; + conn.createStatement().execute(baseTableDDL); + String view1DDL = "CREATE VIEW IF NOT EXISTS " + view + + "(V2 VARCHAR NOT NULL,V3 BIGINT NOT NULL, " + + "V4 VARCHAR CONSTRAINT PKVIEW PRIMARY KEY(V2, V3)) AS SELECT * FROM " + + baseTable + " WHERE KEY_PREFIX = '0CY'"; + conn.createStatement().execute(view1DDL); + + // Create an Index on the base view + String view1Index = generateUniqueName() + "_IDX"; + conn.createStatement().execute("CREATE INDEX " + view1Index + + " ON " + view + " (V2, V3) include (V1, V4)"); + + // Create a child view with primary key constraint owned by tenant + Properties tenantProps = new Properties(); + tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); + try (Connection tenantConn = DriverManager.getConnection(getUrl(), tenantProps)) { + String childViewDDL = "CREATE VIEW IF NOT EXISTS " + childView + + " (V5 VARCHAR NOT NULL, V6 VARCHAR NOT NULL CONSTRAINT PK PRIMARY KEY " + + "(V5, V6)) AS SELECT * FROM " + view; + conn.createStatement().execute(childViewDDL); + } + + String upsert = "UPSERT INTO " + childView + " (TENANT_ID, V2, V3, V5, V6) " + + "VALUES ('00D005000000000', 'zzzzz', 10, 'zzzzz', 'zzzzz')"; + conn.createStatement().executeUpdate(upsert); + conn.commit(); + } + } @Test public void testGettingOneChild() throws Exception { diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/ServerCachingProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/ServerCachingProtos.java index 138be15..3fd01a2 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/ServerCachingProtos.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/ServerCachingProtos.java @@ -2167,6 +2167,16 @@ public final class ServerCachingProtos { * <code>optional int32 viewIndexIdType = 22;</code> */ int getViewIndexIdType(); + + // optional int32 indexDataColumnCount = 23 [default = -1]; + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + boolean hasIndexDataColumnCount(); + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + int getIndexDataColumnCount(); } /** * Protobuf type {@code IndexMaintainer} @@ -2365,6 +2375,11 @@ public final class ServerCachingProtos { viewIndexIdType_ = input.readInt32(); break; } + case 184: { + bitField0_ |= 0x00020000; + indexDataColumnCount_ = input.readInt32(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -2865,6 +2880,22 @@ public final class ServerCachingProtos { return viewIndexIdType_; } + // optional int32 indexDataColumnCount = 23 [default = -1]; + public static final int INDEXDATACOLUMNCOUNT_FIELD_NUMBER = 23; + private int indexDataColumnCount_; + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public boolean hasIndexDataColumnCount() { + return ((bitField0_ & 0x00020000) == 0x00020000); + } + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public int getIndexDataColumnCount() { + return indexDataColumnCount_; + } + private void initFields() { saltBuckets_ = 0; isMultiTenant_ = false; @@ -2888,6 +2919,7 @@ public final class ServerCachingProtos { encodingScheme_ = 0; immutableStorageScheme_ = 0; viewIndexIdType_ = 0; + indexDataColumnCount_ = -1; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -3051,6 +3083,9 @@ public final class ServerCachingProtos { if (((bitField0_ & 0x00010000) == 0x00010000)) { output.writeInt32(22, viewIndexIdType_); } + if (((bitField0_ & 0x00020000) == 0x00020000)) { + output.writeInt32(23, indexDataColumnCount_); + } getUnknownFields().writeTo(output); } @@ -3153,6 +3188,10 @@ public final class ServerCachingProtos { size += com.google.protobuf.CodedOutputStream .computeInt32Size(22, viewIndexIdType_); } + if (((bitField0_ & 0x00020000) == 0x00020000)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(23, indexDataColumnCount_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -3271,6 +3310,11 @@ public final class ServerCachingProtos { result = result && (getViewIndexIdType() == other.getViewIndexIdType()); } + result = result && (hasIndexDataColumnCount() == other.hasIndexDataColumnCount()); + if (hasIndexDataColumnCount()) { + result = result && (getIndexDataColumnCount() + == other.getIndexDataColumnCount()); + } result = result && getUnknownFields().equals(other.getUnknownFields()); return result; @@ -3372,6 +3416,10 @@ public final class ServerCachingProtos { hash = (37 * hash) + VIEWINDEXIDTYPE_FIELD_NUMBER; hash = (53 * hash) + getViewIndexIdType(); } + if (hasIndexDataColumnCount()) { + hash = (37 * hash) + INDEXDATACOLUMNCOUNT_FIELD_NUMBER; + hash = (53 * hash) + getIndexDataColumnCount(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -3550,6 +3598,8 @@ public final class ServerCachingProtos { bitField0_ = (bitField0_ & ~0x00100000); viewIndexIdType_ = 0; bitField0_ = (bitField0_ & ~0x00200000); + indexDataColumnCount_ = -1; + bitField0_ = (bitField0_ & ~0x00400000); return this; } @@ -3691,6 +3741,10 @@ public final class ServerCachingProtos { to_bitField0_ |= 0x00010000; } result.viewIndexIdType_ = viewIndexIdType_; + if (((from_bitField0_ & 0x00400000) == 0x00400000)) { + to_bitField0_ |= 0x00020000; + } + result.indexDataColumnCount_ = indexDataColumnCount_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -3872,6 +3926,9 @@ public final class ServerCachingProtos { if (other.hasViewIndexIdType()) { setViewIndexIdType(other.getViewIndexIdType()); } + if (other.hasIndexDataColumnCount()) { + setIndexDataColumnCount(other.getIndexDataColumnCount()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -5669,6 +5726,39 @@ public final class ServerCachingProtos { return this; } + // optional int32 indexDataColumnCount = 23 [default = -1]; + private int indexDataColumnCount_ = -1; + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public boolean hasIndexDataColumnCount() { + return ((bitField0_ & 0x00400000) == 0x00400000); + } + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public int getIndexDataColumnCount() { + return indexDataColumnCount_; + } + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public Builder setIndexDataColumnCount(int value) { + bitField0_ |= 0x00400000; + indexDataColumnCount_ = value; + onChanged(); + return this; + } + /** + * <code>optional int32 indexDataColumnCount = 23 [default = -1];</code> + */ + public Builder clearIndexDataColumnCount() { + bitField0_ = (bitField0_ & ~0x00400000); + indexDataColumnCount_ = -1; + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:IndexMaintainer) } @@ -8795,7 +8885,7 @@ public final class ServerCachingProtos { "ength\030\003 \002(\005\"4\n\017ColumnReference\022\016\n\006family" + "\030\001 \002(\014\022\021\n\tqualifier\030\002 \002(\014\"4\n\nColumnInfo\022" + "\022\n\nfamilyName\030\001 \001(\t\022\022\n\ncolumnName\030\002 \002(\t\"" + - "\337\005\n\017IndexMaintainer\022\023\n\013saltBuckets\030\001 \002(\005" + + "\201\006\n\017IndexMaintainer\022\023\n\013saltBuckets\030\001 \002(\005" + "\022\025\n\risMultiTenant\030\002 \002(\010\022\023\n\013viewIndexId\030\003" + " \001(\014\022(\n\016indexedColumns\030\004 \003(\0132\020.ColumnRef" + "erence\022 \n\030indexedColumnTypeOrdinal\030\005 \003(\005", @@ -8813,23 +8903,24 @@ public final class ServerCachingProtos { "\timmutable\030\022 \002(\010\022&\n\021indexedColumnInfo\030\023 " + "\003(\0132\013.ColumnInfo\022\026\n\016encodingScheme\030\024 \002(\005" + "\022\036\n\026immutableStorageScheme\030\025 \002(\005\022\027\n\017view" + - "IndexIdType\030\026 \001(\005\"\370\001\n\025AddServerCacheRequ" + - "est\022\020\n\010tenantId\030\001 \001(\014\022\017\n\007cacheId\030\002 \002(\014\022)" + - "\n\010cachePtr\030\003 \002(\0132\027.ImmutableBytesWritabl" + - "e\022)\n\014cacheFactory\030\004 \002(\0132\023.ServerCacheFac" + - "tory\022\017\n\007txState\030\005 \001(\014\022\"\n\032hasProtoBufInde" + - "xMaintainer\030\006 \001(\010\022\025\n\rclientVersion\030\007 \001(\005", - "\022\032\n\022usePersistentCache\030\010 \001(\010\"(\n\026AddServe" + - "rCacheResponse\022\016\n\006return\030\001 \002(\010\"=\n\030Remove" + - "ServerCacheRequest\022\020\n\010tenantId\030\001 \001(\014\022\017\n\007" + - "cacheId\030\002 \002(\014\"+\n\031RemoveServerCacheRespon" + - "se\022\016\n\006return\030\001 \002(\0102\245\001\n\024ServerCachingServ" + - "ice\022A\n\016addServerCache\022\026.AddServerCacheRe" + - "quest\032\027.AddServerCacheResponse\022J\n\021remove" + - "ServerCache\022\031.RemoveServerCacheRequest\032\032" + - ".RemoveServerCacheResponseBG\n(org.apache" + - ".phoenix.coprocessor.generatedB\023ServerCa", - "chingProtosH\001\210\001\001\240\001\001" + "IndexIdType\030\026 \001(\005\022 \n\024indexDataColumnCoun" + + "t\030\027 \001(\005:\002-1\"\370\001\n\025AddServerCacheRequest\022\020\n" + + "\010tenantId\030\001 \001(\014\022\017\n\007cacheId\030\002 \002(\014\022)\n\010cach" + + "ePtr\030\003 \002(\0132\027.ImmutableBytesWritable\022)\n\014c" + + "acheFactory\030\004 \002(\0132\023.ServerCacheFactory\022\017" + + "\n\007txState\030\005 \001(\014\022\"\n\032hasProtoBufIndexMaint", + "ainer\030\006 \001(\010\022\025\n\rclientVersion\030\007 \001(\005\022\032\n\022us" + + "ePersistentCache\030\010 \001(\010\"(\n\026AddServerCache" + + "Response\022\016\n\006return\030\001 \002(\010\"=\n\030RemoveServer" + + "CacheRequest\022\020\n\010tenantId\030\001 \001(\014\022\017\n\007cacheI" + + "d\030\002 \002(\014\"+\n\031RemoveServerCacheResponse\022\016\n\006" + + "return\030\001 \002(\0102\245\001\n\024ServerCachingService\022A\n" + + "\016addServerCache\022\026.AddServerCacheRequest\032" + + "\027.AddServerCacheResponse\022J\n\021removeServer" + + "Cache\022\031.RemoveServerCacheRequest\032\032.Remov" + + "eServerCacheResponseBG\n(org.apache.phoen", + "ix.coprocessor.generatedB\023ServerCachingP" + + "rotosH\001\210\001\001\240\001\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -8859,7 +8950,7 @@ public final class ServerCachingProtos { internal_static_IndexMaintainer_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_IndexMaintainer_descriptor, - new java.lang.String[] { "SaltBuckets", "IsMultiTenant", "ViewIndexId", "IndexedColumns", "IndexedColumnTypeOrdinal", "DataTableColRefForCoveredColumns", "IndexTableColRefForCoveredColumns", "IsLocalIndex", "IndexTableName", "RowKeyOrderOptimizable", "DataTableEmptyKeyValueColFamily", "EmptyKeyValueColFamily", "IndexedExpressions", "RowKeyMetadata", "NumDataTableColFamilies", "IndexWalDisabled", "IndexRowKeyByteSize", "Immutable", "IndexedColumnInfo", "EncodingScheme", "Imm [...] + new java.lang.String[] { "SaltBuckets", "IsMultiTenant", "ViewIndexId", "IndexedColumns", "IndexedColumnTypeOrdinal", "DataTableColRefForCoveredColumns", "IndexTableColRefForCoveredColumns", "IsLocalIndex", "IndexTableName", "RowKeyOrderOptimizable", "DataTableEmptyKeyValueColFamily", "EmptyKeyValueColFamily", "IndexedExpressions", "RowKeyMetadata", "NumDataTableColFamilies", "IndexWalDisabled", "IndexRowKeyByteSize", "Immutable", "IndexedColumnInfo", "EncodingScheme", "Imm [...] internal_static_AddServerCacheRequest_descriptor = getDescriptor().getMessageTypes().get(4); internal_static_AddServerCacheRequest_fieldAccessorTable = new 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 2d8bfc9..8c9a2d9 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 @@ -108,6 +108,7 @@ import org.apache.phoenix.util.EncodedColumnsUtil; import org.apache.phoenix.util.ExpressionUtil; import org.apache.phoenix.util.IndexUtil; import org.apache.phoenix.util.MetaDataUtil; +import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.SchemaUtil; import org.apache.phoenix.util.TransactionUtil; import org.apache.phoenix.util.TrustedByteArrayOutputStream; @@ -340,6 +341,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { private Set<ColumnReference> allColumns; // TODO remove this in the next major release private List<PDataType> indexedColumnTypes; + private int indexDataColumnCount; private RowKeyMetaData rowKeyMetaData; private byte[] indexTableName; private int nIndexSaltBuckets; @@ -422,17 +424,34 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } indexedExpressionCount++; } - int indexPkColumnCount = this.dataRowKeySchema.getFieldCount() + indexedExpressionCount - (this.isDataTableSalted ? 1 : 0) - (this.isMultiTenant ? 1 : 0); - this.rowKeyMetaData = newRowKeyMetaData(indexPkColumnCount); - BitSet bitSet = this.rowKeyMetaData.getViewConstantColumnBitSet(); int dataPosOffset = (isDataTableSalted ? 1 : 0) + (this.isMultiTenant ? 1 : 0); - int nDataPKColumns = dataRowKeySchema.getFieldCount() - dataPosOffset; + // For indexes on views, we need to remember which data columns are "constants" // These are the values in a VIEW where clause. For these, we don't put them in the // index, as they're the same for every row in the index. The data table can be // either a VIEW or PROJECTED List<PColumn>dataPKColumns = dataTable.getPKColumns(); + this.indexDataColumnCount = dataPKColumns.size(); + // We need to get the PK column for the table on which the index is created + if (!dataTable.getName().equals(index.getParentName())) { + try { + String tenantId = (index.getTenantId() != null) ? + index.getTenantId().getString() : null; + PTable indexTable = PhoenixRuntime.getTable(connection, + tenantId, index.getParentName().getString()); + this.indexDataColumnCount = indexTable.getPKColumns().size(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + int indexPkColumnCount = this.indexDataColumnCount + + indexedExpressionCount - (this.isDataTableSalted ? 1 : 0) - (this.isMultiTenant ? 1 : 0); + this.rowKeyMetaData = newRowKeyMetaData(indexPkColumnCount); + BitSet bitSet = this.rowKeyMetaData.getViewConstantColumnBitSet(); + + int nDataPKColumns = this.indexDataColumnCount - dataPosOffset; for (int i = dataPosOffset; i < dataPKColumns.size(); i++) { PColumn dataPKColumn = dataPKColumns.get(i); if (dataPKColumn.getViewConstant() != null) { @@ -620,7 +639,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } // Write index row key - for (int i = dataPosOffset; i < dataRowKeySchema.getFieldCount(); i++) { + for (int i = dataPosOffset; i < indexDataColumnCount; i++) { Boolean hasValue=dataRowKeySchema.next(ptr, i, maxRowKeyOffset); // Ignore view constants from the data table, as these // don't need to appear in the index (as they're the @@ -1377,6 +1396,10 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { maintainer.indexedColumnTypes.add(PDataType.values()[typeOrdinal]); } maintainer.indexTableName = proto.getIndexTableName().toByteArray(); + maintainer.indexDataColumnCount = dataTableRowKeySchema.getFieldCount(); + if (proto.getIndexDataColumnCount() != -1) { + maintainer.indexDataColumnCount = proto.getIndexDataColumnCount(); + } maintainer.rowKeyOrderOptimizable = proto.getRowKeyOrderOptimizable(); maintainer.dataEmptyKeyValueCF = proto.getDataTableEmptyKeyValueColFamily().toByteArray(); ServerCachingProtos.ImmutableBytesWritable emptyKeyValueColFamily = proto.getEmptyKeyValueColFamily(); @@ -1512,6 +1535,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } } builder.setIsLocalIndex(maintainer.isLocalIndex); + builder.setIndexDataColumnCount(maintainer.indexDataColumnCount); builder.setIndexTableName(ByteStringer.wrap(maintainer.indexTableName)); builder.setRowKeyOrderOptimizable(maintainer.rowKeyOrderOptimizable); builder.setDataTableEmptyKeyValueColFamily(ByteStringer.wrap(maintainer.dataEmptyKeyValueCF)); @@ -1627,7 +1651,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { Arrays.fill(dataPkPosition, EXPRESSION_NOT_PRESENT); int numViewConstantColumns = 0; BitSet viewConstantColumnBitSet = rowKeyMetaData.getViewConstantColumnBitSet(); - for (int i = dataPkOffset; i < dataRowKeySchema.getFieldCount(); i++) { + for (int i = dataPkOffset; i < indexDataColumnCount; i++) { if (!viewConstantColumnBitSet.get(i)) { int indexPkPosition = rowKeyMetaData.getIndexPkPosition(i-dataPkOffset); this.dataPkPosition[indexPkPosition] = i; @@ -1663,11 +1687,12 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } private int getIndexPkColumnCount() { - return getIndexPkColumnCount(dataRowKeySchema, indexedExpressions.size(), isDataTableSalted, isMultiTenant); + return getIndexPkColumnCount(indexDataColumnCount, indexedExpressions.size(), + isDataTableSalted, isMultiTenant); } - private static int getIndexPkColumnCount(RowKeySchema rowKeySchema, int numIndexExpressions, boolean isDataTableSalted, boolean isMultiTenant) { - return rowKeySchema.getFieldCount() + numIndexExpressions - (isDataTableSalted ? 1 : 0) - (isMultiTenant ? 1 : 0); + private static int getIndexPkColumnCount(int indexDataColumnCount, int numIndexExpressions, boolean isDataTableSalted, boolean isMultiTenant) { + return indexDataColumnCount + numIndexExpressions - (isDataTableSalted ? 1 : 0) - (isMultiTenant ? 1 : 0); } private RowKeyMetaData newRowKeyMetaData() { @@ -1675,7 +1700,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> { } private static RowKeyMetaData newRowKeyMetaData(IndexMaintainer i, RowKeySchema rowKeySchema, int numIndexExpressions, boolean isDataTableSalted, boolean isMultiTenant) { - int indexPkColumnCount = getIndexPkColumnCount(rowKeySchema, numIndexExpressions, isDataTableSalted, isMultiTenant); + int indexPkColumnCount = getIndexPkColumnCount(i.indexDataColumnCount, numIndexExpressions, + isDataTableSalted, isMultiTenant); return indexPkColumnCount < 0xFF ? i.new ByteSizeRowKeyMetaData() : i.new IntSizedRowKeyMetaData(); } diff --git a/phoenix-protocol/src/main/ServerCachingService.proto b/phoenix-protocol/src/main/ServerCachingService.proto index 5891d25..fbe151a 100644 --- a/phoenix-protocol/src/main/ServerCachingService.proto +++ b/phoenix-protocol/src/main/ServerCachingService.proto @@ -63,6 +63,7 @@ message IndexMaintainer { required int32 encodingScheme = 20; required int32 immutableStorageScheme = 21; optional int32 viewIndexIdType = 22 ; + optional int32 indexDataColumnCount = 23 [default = -1]; } message AddServerCacheRequest {