github-actions[bot] commented on code in PR #66297:
URL: https://github.com/apache/doris/pull/66297#discussion_r3698463998
##########
fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonSysExternalTable.java:
##########
@@ -135,19 +153,69 @@ public Table getSysPaimonTable() {
}
public Table getSysPaimonTable(TableScanParams scanParams) {
- Table table = getSysPaimonTable();
if (scanParams == null || !scanParams.isOptions()) {
- return table;
+ return getSysPaimonTable();
}
- Map<String, String> resolvedOptions = scanParams.getOrResolveMapParams(
- options ->
PaimonScanParams.resolveOptions(sourceTable.getBasePaimonTable(), options));
+ Map<String, String> resolvedOptions = resolvedOptions(scanParams);
if
(PaimonScanParams.getPinnedFileCreationTime(resolvedOptions).isPresent()) {
// Generic system-table wrappers cannot carry Paimon's
manifest-entry predicate.
// Reject the fallback instead of silently widening it to the
whole pinned snapshot.
throw new IllegalArgumentException(
"Paimon system tables cannot apply a creation-time file
filter.");
}
- return PaimonScanParams.applyOptions(table, resolvedOptions);
+ FileStoreTable effectiveDataTable = (FileStoreTable)
PaimonScanParams.applyOptions(
Review Comment:
[P1] Build OPTIONS system tables from the bound fence generation.
BindRelation stores the base table's exact relationSnapshot, but PaimonSource
ignores it for PaimonSysExternalTable and this path instead applies the
fence-injected snapshot selector to the wrapper's cached raw source. If
invalidation/schema ALTER separates those handles, the normal copy can rewind
to the snapshot's old schema instead of retaining the fence's latest-schema
table generation, making system-table binding/rows alias-order dependent. This
is the system-table counterpart left after the ordinary-relation fence fix.
Thread the fenced PaimonSnapshot.table through schema and scan construction and
use the no-time-travel projection semantics.
##########
fe/fe-core/src/test/java/org/apache/doris/tablefunction/PaimonTableValuedFunctionTest.java:
##########
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.tablefunction;
+
+import org.apache.doris.datasource.paimon.PaimonReaderOptions;
+
+import org.apache.paimon.CoreOptions;
+import org.apache.paimon.table.FileStoreTable;
+import org.apache.paimon.table.Table;
+import org.apache.paimon.table.system.PartitionsTable;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class PaimonTableValuedFunctionTest {
+
+ @Test
+ void testMetadataTableWrapsCpuCappedDataTable() {
+ int localCapacity = Runtime.getRuntime().availableProcessors();
+ Assumptions.assumeTrue(localCapacity <
PaimonReaderOptions.MAX_MANIFEST_PARALLELISM);
+ FileStoreTable dataTable = Mockito.mock(FileStoreTable.class);
+ FileStoreTable safeDataTable = Mockito.mock(FileStoreTable.class);
+ Mockito.when(dataTable.options()).thenReturn(Collections.singletonMap(
+ CoreOptions.SCAN_MANIFEST_PARALLELISM.key(),
String.valueOf(localCapacity + 1)));
+
Mockito.when(safeDataTable.options()).thenReturn(Collections.singletonMap(
+ CoreOptions.SCAN_MANIFEST_PARALLELISM.key(),
String.valueOf(localCapacity)));
+
Mockito.when(dataTable.copy(Mockito.anyMap())).thenReturn(safeDataTable);
Review Comment:
[P1] Stub the copy method this test actually drives. The assumption plus
configured localCapacity + 1 forces runtimeSafeTable into
normalizeManifestParallelism's over-cap branch, which calls
copyWithoutTimeTravel(...), not copy(...). Mockito therefore returns null here
and createRuntimeSafeSystemTable fails in validateEffectiveTable before
reaching these assertions on every host where the test runs; the final verify
also targets the wrong method. Stub/verify copyWithoutTimeTravel with the
expected cap map, as the other normalization tests do.
##########
fe/fe-core/src/main/java/org/apache/doris/tablefunction/PaimonTableValuedFunction.java:
##########
@@ -98,12 +101,27 @@ public PaimonTableValuedFunction(TableName
paimonTableName, String queryType) th
));
NameMapping buildNameMapping = externalTable.getOrBuildNameMapping();
- this.paimonSysTable =
paimonExternalCatalog.getPaimonTable(buildNameMapping,
- "main", queryType);
+ this.paimonSysTable = createRuntimeSafeSystemTable(
+ paimonExternalCatalog.getPaimonTable(buildNameMapping),
queryType);
this.schema = PaimonUtil.parseSchema(paimonSysTable,
paimonExternalCatalog.getEnableMappingVarbinary(),
paimonExternalCatalog.getEnableMappingTimestampTz());
}
+ static Table createRuntimeSafeSystemTable(Table dataTable, String
queryType) {
+ if (!(dataTable instanceof FileStoreTable)) {
+ throw new IllegalArgumentException("Paimon metadata queries
require a file-store data table.");
+ }
+ // System-table wrappers hide the data table that owns manifest
planning. Normalize the
+ // disposable data handle before wrapping it so metadata TVFs cannot
bypass the CPU cap.
+ FileStoreTable safeDataTable = (FileStoreTable)
PaimonReaderOptions.runtimeSafeTable(dataTable);
+ PaimonReaderOptions.validateEffectiveTable(safeDataTable);
+ Table systemTable = SystemTableLoader.load(queryType, safeDataTable);
Review Comment:
[P1] Keep the fallback pair as the direct source of the rebuilt $ro table.
When this handle is PrivilegedFileStoreTable(FallbackReadFileStoreTable(...))
and its manifest values already fit the local bound, runtimeSafeTable returns
that wrapper unchanged. Paimon 1.3.1 ReadOptimizedTable.newScan() only builds
FallbackReadScan when its immediate wrapped table is
FallbackReadFileStoreTable; behind the privilege delegate it takes the
single-table path and can omit fallback-only rows. The prior catalog
system-table lookup did not introduce this ordering, and PaimonSysExternalTable
already uses PaimonTableDecorators.unwrapToFallbackOrBase. Apply the same
invariant before SystemTableLoader.load and cover a privilege-around-fallback
query_type='ro'.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]