You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by sh...@apache.org on 2024/04/08 19:00:41 UTC
(phoenix) 01/01: Merge branch 'master' into PHOENIX-6883-feature
This is an automated email from the ASF dual-hosted git repository.
shahrs87 pushed a commit to branch PHOENIX-6883-feature
in repository https://gitbox.apache.org/repos/asf/phoenix.git
commit 124d7dbbf58452f726acc453770369b5932ae618
Merge: 4d42c915e1 d8f6e6ea53
Author: Rushabh Shah <ru...@rushabh-ltmflld.internal.salesforce.com>
AuthorDate: Mon Apr 8 12:00:09 2024 -0700
Merge branch 'master' into PHOENIX-6883-feature
.asf.yaml | 23 +-
.../phoenix/compile/ExplainPlanAttributes.java | 21 +-
.../org/apache/phoenix/compile/QueryCompiler.java | 17 +-
.../phoenix/compile/ServerBuildIndexCompiler.java | 1 +
.../ServerBuildTransformingTableCompiler.java | 1 +
.../BaseScannerRegionObserverConstants.java | 2 +-
.../coprocessorclient/MetaDataProtocol.java | 2 +-
.../apache/phoenix/exception/SQLExceptionCode.java | 1 +
.../phoenix/iterate/BaseResultIterators.java | 57 +++-
.../iterate/DefaultParallelScanGrouper.java | 11 +
.../phoenix/iterate/ParallelScanGrouper.java | 16 +
.../phoenix/iterate/ScanningResultIterator.java | 5 +-
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 3 +
.../apache/phoenix/optimize/QueryOptimizer.java | 5 +-
.../phoenix/query/ConnectionQueryServices.java | 15 +
.../phoenix/query/ConnectionQueryServicesImpl.java | 103 +++++--
.../query/ConnectionlessQueryServicesImpl.java | 16 +-
.../query/DelegateConnectionQueryServices.java | 9 +
.../org/apache/phoenix/query/QueryConstants.java | 2 +
.../org/apache/phoenix/query/QueryServices.java | 7 +
.../org/apache/phoenix/schema/DelegateTable.java | 6 +
.../org/apache/phoenix/schema/MetaDataClient.java | 71 ++++-
.../java/org/apache/phoenix/schema/PTable.java | 5 +
.../java/org/apache/phoenix/schema/PTableImpl.java | 28 +-
.../org/apache/phoenix/schema/TableProperty.java | 24 ++
.../phoenix/schema/transform/TransformClient.java | 1 +
.../java/org/apache/phoenix/util/MetaDataUtil.java | 14 +
.../java/org/apache/phoenix/util/ScanUtil.java | 15 +
phoenix-core-client/src/main/protobuf/PTable.proto | 1 +
.../coprocessor/BaseScannerRegionObserver.java | 50 ++-
.../coprocessor/GlobalIndexRegionScanner.java | 4 +-
.../phoenix/coprocessor/MetaDataEndpointImpl.java | 121 +++++++-
.../UngroupedAggregateRegionObserver.java | 4 +-
.../iterate/MapReduceParallelScanGrouper.java | 48 ++-
.../PhoenixServerBuildIndexInputFormat.java | 1 +
.../mapreduce/index/IndexScrutinyMapper.java | 3 +-
.../phoenix/mapreduce/index/IndexScrutinyTool.java | 31 +-
.../mapreduce/util/PhoenixConfigurationUtil.java | 14 +
.../org/apache/phoenix/end2end/AlterTableIT.java | 106 ++++++-
.../end2end/BaseTenantSpecificViewIndexIT.java | 4 +-
.../org/apache/phoenix/end2end/CreateTableIT.java | 78 +++++
.../end2end/ExplainPlanWithStatsDisabledIT.java | 340 +++++++++++++++++++++
.../end2end/IndexRepairRegionScannerIT.java | 111 ++++---
.../phoenix/end2end/IndexScrutinyToolBaseIT.java | 7 +-
.../end2end/IndexScrutinyWithMaxLookbackIT.java | 120 ++++++--
.../end2end/IndexToolForNonTxGlobalIndexIT.java | 61 ++++
.../phoenix/end2end/MaxLookbackExtendedIT.java | 75 ++++-
.../org/apache/phoenix/end2end/MaxLookbackIT.java | 251 +++++++++++++++
.../end2end/RowValueConstructorOffsetIT.java | 26 ++
.../org/apache/phoenix/end2end/TableTTLIT.java | 34 ++-
.../phoenix/end2end/TenantSpecificTablesDDLIT.java | 57 ++++
.../end2end/TenantSpecificViewIndexSaltedIT.java | 33 +-
.../it/java/org/apache/phoenix/end2end/ViewIT.java | 85 ++++++
.../org/apache/phoenix/end2end/ViewMetadataIT.java | 34 +++
.../phoenix/end2end/index/IndexMetadataIT.java | 24 ++
.../phoenix/end2end/index/PartialIndexIT.java | 47 +++
.../index/UncoveredGlobalIndexRegionScannerIT.java | 43 +++
.../phoenix/end2end/salted/SaltedTableIT.java | 32 ++
.../phoenix/end2end/transform/TransformToolIT.java | 144 ++++++++-
.../phoenix/iterate/PhoenixQueryTimeoutIT.java | 55 ++++
.../monitoring/PhoenixTableLevelMetricsIT.java | 14 +
.../it/resources/compatible_client_versions.json | 8 +-
.../src/it/resources/log4j2-test.properties | 45 ---
.../TestingMapReduceParallelScanGrouper.java | 10 +
.../java/org/apache/phoenix/query/BaseTest.java | 44 +++
.../query/ConnectionQueryServicesImplTest.java | 46 ++-
.../org/apache/phoenix/query/QueryPlanTest.java | 12 +-
.../java/org/apache/phoenix/util/TestUtil.java | 4 +-
.../src/test/resources/log4j2-test.properties | 8 +-
pom.xml | 42 ++-
70 files changed, 2471 insertions(+), 287 deletions(-)
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 40da589976,0e78202c43..d4e2fd7552
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@@ -3365,9 -3321,10 +3384,10 @@@ public class MetaDataClient
.setStreamingTopicName(streamingTopicName)
.setIndexWhere(statement.getWhereClause() == null ? null
: statement.getWhereClause().toString())
+ .setMaxLookbackAge(maxLookbackAge)
.build();
result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
- addTableToCache(result);
+ addTableToCache(result, false);
return table;
} catch (Throwable e) {
TableMetricsManager.updateMetricsForSystemCatalogTableMethod(tableNameNode.toString(),
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 2885de65ea,128bca0d7f..2623d7709e
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@@ -218,7 -219,7 +219,8 @@@ public class PTableImpl implements PTab
private String indexWhere;
private Expression indexWhereExpression;
private Set<ColumnReference> indexWhereColumns;
+ private Long maxLookbackAge;
+ private Map<PTableKey, Long> ancestorLastDDLTimestampMap;
public static class Builder {
private PTableKey key;
@@@ -285,8 -286,8 +287,8 @@@
private String externalSchemaId;
private String streamingTopicName;
private String indexWhere;
+ private Long maxLookbackAge;
-
+ private Map<PTableKey, Long> ancestorLastDDLTimestampMap = new HashMap<>();
-
// Used to denote which properties a view has explicitly modified
private BitSet viewModifiedPropSet = new BitSet(3);
// Optionally set columns for the builder, but not for the actual PTable
@@@ -713,10 -714,14 +715,19 @@@
return this;
}
+ public Builder setMaxLookbackAge(Long maxLookbackAge) {
+ if (maxLookbackAge != null) {
+ propertyValues.put(MAX_LOOKBACK_AGE, String.valueOf(maxLookbackAge));
+ }
+ this.maxLookbackAge = maxLookbackAge;
+ return this;
+ }
+
+ public Builder setAncestorLastDDLTimestampMap(Map<PTableKey, Long> map) {
+ this.ancestorLastDDLTimestampMap = map;
+ return this;
+ }
++
/**
* Populate derivable attributes of the PTable
* @return PTableImpl.Builder object
@@@ -1008,7 -1013,7 +1019,8 @@@
this.externalSchemaId = builder.externalSchemaId;
this.streamingTopicName = builder.streamingTopicName;
this.indexWhere = builder.indexWhere;
+ this.maxLookbackAge = builder.maxLookbackAge;
+ this.ancestorLastDDLTimestampMap = builder.ancestorLastDDLTimestampMap;
}
// When cloning table, ignore the salt column as it will be added back in the constructor
@@@ -1090,7 -1095,7 +1102,8 @@@
.setExternalSchemaId(table.getExternalSchemaId())
.setStreamingTopicName(table.getStreamingTopicName())
.setIndexWhere(table.getIndexWhere())
- .setMaxLookbackAge(table.getMaxLookbackAge());
++ .setMaxLookbackAge(table.getMaxLookbackAge())
+ .setAncestorLastDDLTimestampMap(table.getAncestorLastDDLTimestampMap());
}
@Override
@@@ -2384,11 -2397,11 +2405,16 @@@
return indexWhere;
}
+ @Override
+ public Long getMaxLookbackAge() {
+ return maxLookbackAge;
+ }
+
+ @Override
+ public Map<PTableKey, Long> getAncestorLastDDLTimestampMap() {
+ return ancestorLastDDLTimestampMap;
+ }
+
private void buildIndexWhereExpression(PhoenixConnection connection) throws SQLException {
PhoenixPreparedStatement
pstmt =
diff --cc phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 6eb7577e95,bdba476a90..d9d200a4d8
--- a/phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@@ -83,7 -84,9 +84,10 @@@ import static org.apache.phoenix.jdbc.P
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID_DATA_TYPE_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_TYPE_BYTES;
+import static org.apache.phoenix.query.QueryServices.SKIP_SYSTEM_TABLES_EXISTENCE_CHECK;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MAX_LOOKBACK_AGE_BYTES;
+ import static org.apache.phoenix.schema.PTable.LinkType.PHYSICAL_TABLE;
+ import static org.apache.phoenix.schema.PTable.LinkType.VIEW_INDEX_PARENT_TABLE;
import static org.apache.phoenix.schema.PTableImpl.getColumnsToClone;
import static org.apache.phoenix.schema.PTableType.INDEX;
import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
@@@ -3459,19 -3513,32 +3550,45 @@@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES
}
}
+ private void invalidateServerMetadataCache(List<InvalidateServerMetadataCacheRequest> requests)
+ throws Throwable {
+ Properties properties = new Properties();
+ // Skip checking of system table existence since the system tables should have created
+ // by now.
+ properties.setProperty(SKIP_SYSTEM_TABLES_EXISTENCE_CHECK, "true");
+ try (PhoenixConnection connection = QueryUtil.getConnectionOnServer(properties,
- env.getConfiguration()).unwrap(PhoenixConnection.class)) {
++ env.getConfiguration()).unwrap(PhoenixConnection.class)) {
+ ConnectionQueryServices queryServices = connection.getQueryServices();
+ queryServices.invalidateServerMetadataCache(requests);
+ }
+ }
+
+ private boolean hasInheritableTablePropertyChanged(PTable newTable, PTable oldTable) {
+ return ! Objects.equals(newTable.getMaxLookbackAge(), oldTable.getMaxLookbackAge());
+ }
+
+ private void invalidateAllChildTablesAndIndexes(PTable table, List<PTable> childViews) {
+ List<ImmutableBytesPtr> invalidateList = new ArrayList<ImmutableBytesPtr>();
+ if (table.getIndexes() != null) {
+ for(PTable index: table.getIndexes()) {
+ invalidateList.add(new ImmutableBytesPtr(SchemaUtil.getTableKey(index)));
+ }
+ }
+ for(PTable childView: childViews) {
+ invalidateList.add(new ImmutableBytesPtr(SchemaUtil.getTableKey(childView)));
+ if (childView.getIndexes() != null) {
+ for(PTable viewIndex: childView.getIndexes()) {
+ invalidateList.add(new ImmutableBytesPtr(SchemaUtil.getTableKey(viewIndex)));
+ }
+ }
+ }
+ Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache =
+ GlobalCache.getInstance(this.env).getMetaDataCache();
+ for(ImmutableBytesPtr invalidateKey: invalidateList) {
+ metaDataCache.invalidate(invalidateKey);
+ }
+ }
+
/**
* Removes the table from the server side cache
*/
diff --cc phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java
index 47b0818953,cb07031ac5..c32a8e2d4f
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java
@@@ -1374,120 -1375,36 +1378,150 @@@ public class ViewMetadataIT extends Spl
assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
}
+ @Test
+ public void testAncestorLastDDLMapPopulatedInViewAndIndexHierarchy() throws SQLException {
+ String baseTable = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String view1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String view2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+ String view3 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName());
+ String view4 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String index1 = generateUniqueName();
+ String index2 = generateUniqueName();
+ String tenant1 = TENANT1;
+ String tenant2 = TENANT2;
+ /* baseTable
+ / | \ \
+ view1(tenant1) view3(tenant2) index1(global) view4(global)
+ /
+ view2(tenant1)
+ /
+ index2(tenant1)
+ */
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+ conn.createStatement().execute(baseTableDDL);
+ String index1DDL = "CREATE INDEX " + index1 + " ON " + baseTable + "(V1)";
+ conn.createStatement().execute(index1DDL);
+
+
+ try (Connection tenant1Conn = getTenantConnection(tenant1)) {
+ String view1DDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
+ tenant1Conn.createStatement().execute(view1DDL);
+
+ String view2DDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + view1;
+ tenant1Conn.createStatement().execute(view2DDL);
+
+ String index2DDL = "CREATE INDEX " + index2 + " ON " + view2 + "(V1)";
+ tenant1Conn.createStatement().execute(index2DDL);
+ }
+
+ try (Connection tenant2Conn = getTenantConnection(tenant2)) {
+ String view3DDL = "CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable;
+ tenant2Conn.createStatement().execute(view3DDL);
+ }
+
+ String view4DDL = "CREATE VIEW " + view4 + " AS SELECT * FROM " + baseTable;
+ conn.createStatement().execute(view4DDL);
+
+ //validate ancestor->last_ddl_timestamps maps
+ PTable basePTable = PhoenixRuntime.getTable(conn, baseTable);
+ Long baseTableLastDDLTimestamp = basePTable.getLastDDLTimestamp();
+ PTableKey baseTableKey = new PTableKey(null, baseTable);
+ //base table map should be empty
+ Map<PTableKey,Long> map = basePTable.getAncestorLastDDLTimestampMap();
+ assertEquals(0, map.size());
+
+ //global view
+ map = PhoenixRuntime.getTable(conn, view4).getAncestorLastDDLTimestampMap();
+ assertEquals(1, map.size());
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+
+ //global index in cache and in parent PTable
+ PTable index1PTable = PhoenixRuntime.getTable(conn, SchemaUtil.getTableName(SCHEMA1, index1));
+ map = index1PTable.getAncestorLastDDLTimestampMap();
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ assertEquals(1, basePTable.getIndexes().size());
+ map = basePTable.getIndexes().get(0).getAncestorLastDDLTimestampMap();
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+
+ //tenant2 view
+ try (Connection tenant2Conn = getTenantConnection(tenant2)) {
+ map = PhoenixRuntime.getTable(tenant2Conn, view3).getAncestorLastDDLTimestampMap();
+ assertEquals(1, map.size());
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ }
+ try (Connection tenant1Conn = getTenantConnection(tenant1)) {
+ //tenant1 view
+ PTable view1PTable = PhoenixRuntime.getTable(tenant1Conn, view1);
+ map = view1PTable.getAncestorLastDDLTimestampMap();
+ assertEquals(1, map.size());
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ //tenant1 child view
+ PTableKey view1Key = new PTableKey(view1PTable.getTenantId(), view1);
+ map = PhoenixRuntime.getTable(tenant1Conn, view2).getAncestorLastDDLTimestampMap();
+ assertEquals(2, map.size());
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ assertEquals(view1PTable.getLastDDLTimestamp(), map.get(view1Key));
+ //tenant1 child view index in cache and in child view PTable
+ PTable view2PTable = PhoenixRuntime.getTable(tenant1Conn, view2);
+ PTableKey view2Key = new PTableKey(view2PTable.getTenantId(), view2);
+ PTable index2PTable = PhoenixRuntime.getTable(tenant1Conn, SchemaUtil.getTableName(SCHEMA3, index2));
+ map = index2PTable.getAncestorLastDDLTimestampMap();
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ assertEquals(view2PTable.getLastDDLTimestamp(), map.get(view2Key));
+ assertEquals(2, view2PTable.getIndexes().size());
+ for (PTable index : view2PTable.getIndexes()) {
+ // inherited index
+ if (index.getTableName().getString().equals(index1)) {
+ map = index.getAncestorLastDDLTimestampMap();
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ } else {
+ // view index
+ map = index.getAncestorLastDDLTimestampMap();
+ assertEquals(baseTableLastDDLTimestamp, map.get(baseTableKey));
+ assertEquals(view2PTable.getLastDDLTimestamp(), map.get(view2Key));
+ }
+ }
+ }
+ }
+ }
+
+ private Connection getTenantConnection(String tenantId) throws SQLException {
+ Properties tenantProps = new Properties();
+ tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+ return DriverManager.getConnection(getUrl(), tenantProps);
+ }
+
+ @Test
+ public void testAlterViewAndViewIndexMaxLookbackAgeFails() throws Exception {
+ String schemaName = generateUniqueName();
+ String dataTableName = generateUniqueName();
+ String fullDataTableName = SchemaUtil.getTableName(schemaName, dataTableName);
+ try(Connection conn = DriverManager.getConnection(getUrl());
+ Statement stmt = conn.createStatement()) {
+ String ddl = "CREATE TABLE " + fullDataTableName + " (ID VARCHAR NOT NULL PRIMARY KEY, COL1 INTEGER)";
+ stmt.execute(ddl);
+ assertNull(queryTableLevelMaxLookbackAge(fullDataTableName));
+ String viewName = generateUniqueName();
+ String fullViewName = SchemaUtil.getTableName(schemaName, viewName);
+ ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullDataTableName;
+ stmt.execute(ddl);
+ assertNull(queryTableLevelMaxLookbackAge(fullViewName));
+ String alterViewDdl = "ALTER VIEW " + fullViewName + " SET MAX_LOOKBACK_AGE = 300";
+ SQLException err = assertThrows(SQLException.class, () -> stmt.execute(alterViewDdl));
+ assertEquals(VIEW_WITH_PROPERTIES.getErrorCode(), err.getErrorCode());
+ String viewIndexName = generateUniqueName();
+ String fullViewIndexName = SchemaUtil.getTableName(schemaName, viewIndexName);
+ ddl = "CREATE INDEX " + viewIndexName + " ON " + fullViewName + " (COL1)";
+ stmt.execute(ddl);
+ assertNull(queryTableLevelMaxLookbackAge(fullViewIndexName));
+ String alterViewIndexDdl = "ALTER INDEX " + viewIndexName + " ON " + fullViewName +
+ " ACTIVE SET MAX_LOOKBACK_AGE = 300";
+ err = assertThrows(SQLException.class, () -> stmt.execute(alterViewIndexDdl));
+ assertEquals(MAX_LOOKBACK_AGE_SUPPORTED_FOR_TABLES_ONLY.getErrorCode(), err.getErrorCode());
+ }
+ }
+
private void assertPKs(ResultSet rs, String[] expectedPKs)
throws SQLException {
List<String> pkCols = newArrayListWithExpectedSize(expectedPKs.length);
diff --cc phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index 9018246cd5,76175e4dc9..18892db735
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@@ -142,10 -145,9 +147,11 @@@ import org.apache.phoenix.end2end.Paral
import org.apache.phoenix.end2end.ParallelStatsDisabledTest;
import org.apache.phoenix.end2end.ParallelStatsEnabledIT;
import org.apache.phoenix.end2end.ParallelStatsEnabledTest;
+import org.apache.phoenix.end2end.PhoenixRegionServerEndpointTestImpl;
+import org.apache.phoenix.end2end.ServerMetadataCacheTestImpl;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
+ import org.apache.phoenix.hbase.index.IndexRegionObserver;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver;