You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by gj...@apache.org on 2020/03/17 18:30:41 UTC
[phoenix] branch 4.x updated: PHOENIX-5317 Upserting rows into
child views with pk fails when the base view has an index on it
This is an automated email from the ASF dual-hosted git repository.
gjacoby pushed a commit to branch 4.x
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.x by this push:
new 3713421 PHOENIX-5317 Upserting rows into child views with pk fails when the base view has an index on it
3713421 is described below
commit 37134215a47b1b4ed8fd426c112b4f4e4e41e8cd
Author: Sandeep Guggilam <sg...@sandeepg-ltm.internal.salesforce.com>
AuthorDate: Sun Mar 8 14:10:53 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 <gj...@apache.org>
---
.../phoenix/end2end/MetaDataEndpointImplIT.java | 82 ++++++++++++-
.../coprocessor/generated/ServerCachingProtos.java | 129 ++++++++++++++++++---
.../org/apache/phoenix/index/IndexMaintainer.java | 49 ++++++--
.../src/main/ServerCachingService.proto | 1 +
4 files changed, 230 insertions(+), 31 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 21ab6f8..dca4b6b 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
@@ -11,18 +11,19 @@ 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.hadoop.hbase.client.HTable;
-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;
@@ -113,6 +114,83 @@ public class MetaDataEndpointImplIT extends ParallelStatsDisabledIT {
// now lets check and make sure the columns are correct
assertColumnNamesEqual(PhoenixRuntime.getTable(conn, leftChild.toUpperCase()), "PK2", "V1", "V2", "CARRIER");
}
+
+ @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 testDroppingADerivedColumn() 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 dba165b..8d6b54c 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,35 @@ 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) {
@@ -440,6 +460,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
nDataPKColumns--;
}
}
+
this.indexTableName = indexTableName;
this.indexedColumnTypes = Lists.<PDataType>newArrayListWithExpectedSize(nIndexPKColumns-nDataPKColumns);
this.indexedExpressions = Lists.newArrayListWithExpectedSize(nIndexPKColumns-nDataPKColumns);
@@ -620,7 +641,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
@@ -1374,6 +1395,11 @@ 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();
@@ -1509,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));
@@ -1624,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;
@@ -1660,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() {
@@ -1672,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 {