// region observer to generate the index rows based on the data rows as we scan
if (index.getIndexType() == IndexType.LOCAL) {
final PhoenixStatement statement = new PhoenixStatement(connection);
String tableName = getFullTableName(dataTableRef);
String query = "SELECT count(*) FROM " + tableName;
QueryPlan plan = statement.compileQuery(query);
TableRef tableRef = plan.getContext().getResolver().getTables().get(0);
// Set attribute on scan that UngroupedAggregateRegionObserver will switch on.
// We'll detect that this attribute was set the server-side and write the index
// rows per region as a result. The value of the attribute will be our persisted
// index maintainers.
// Define the LOCAL_INDEX_BUILD as a new static in BaseScannerRegionObserver
Scan scan = plan.getContext().getScan();
try {
scan.setTimeRange(dataTableRef.getLowerBoundTimeStamp(), Long.MAX_VALUE);
} catch (IOException e) {
throw new SQLException(e);
}
ImmutableBytesWritable ptr = new ImmutableBytesWritable();
PTable dataTable = tableRef.getTable();
List<PTable> indexes = Lists.newArrayListWithExpectedSize(1);
// Only build newly created index.
indexes.add(index);
IndexMaintainer.serialize(dataTable, ptr, indexes);
scan.setAttribute(BaseScannerRegionObserver.LOCAL_INDEX_BUILD, ByteUtil.copyKeyBytesIfNecessary(ptr));
// By default, we'd use a FirstKeyOnly filter as nothing else needs to be projected for count(*).
// However, in this case, we need to project all of the data columns that contribute to the index.
IndexMaintainer indexMaintainer = index.getIndexMaintainer(dataTable);
for (ColumnReference columnRef : indexMaintainer.getAllColumns()) {
scan.addColumn(columnRef.getFamily(), columnRef.getQualifier());
}
Cell kv = plan.iterator().next().getValue(0);
ImmutableBytesWritable tmpPtr = new ImmutableBytesWritable(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength());
// A single Cell will be returned with the count(*) - we decode that here
long rowCount = PDataType.LONG.getCodec().decodeLong(tmpPtr, SortOrder.getDefault());
// The contract is to return a MutationState that contains the number of rows modified. In this
// case, it's the number of rows in the data table which corresponds to the number of index
// rows that were added.
state = new MutationState(0, connection, rowCount);
} else {
PostIndexDDLCompiler compiler = new PostIndexDDLCompiler(connection, dataTableRef);
MutationPlan plan = compiler.compile(index);
try {
plan.getContext().setScanTimeRange(new TimeRange(dataTableRef.getLowerBoundTimeStamp(), Long.MAX_VALUE));
} catch (IOException e) {
throw new SQLException(e);
}
state = connection.getQueryServices().updateData(plan);
}