This is an automated email from the ASF dual-hosted git repository.

Gabriel39 pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new ca02e7b3839 [fix](regression) Stabilize external table guardrail cases 
(#66509)
ca02e7b3839 is described below

commit ca02e7b38399201ea8fec4716de350fac5031fe4
Author: Gabriel <[email protected]>
AuthorDate: Fri Aug 7 09:35:16 2026 +0800

    [fix](regression) Stabilize external table guardrail cases (#66509)
    
    ### What problem does this PR solve?
    
    The external-table regression suite had two environment-dependent
    failures:
    
    - The Paimon guardrail case attempted to create a table with an empty
    field name. Paimon rejects empty and whitespace-only field names while
    constructing the table schema, before Doris can scan it.
    - The Iceberg Variant case required more than one scanner to report
    rows. File scanner tasks pull ranges dynamically, so minimum scanner
    concurrency does not guarantee that every scheduled scanner consumes
    rows from a small multi-file fixture.
    
    ### What is changed?
    
    - Remove the unsupported empty-field Paimon fixture and its expected
    results. Delimiter-rich field names remain covered end to end, while
    empty-segment framing remains covered by the codec unit test.
    - Keep the parallel Iceberg Variant correctness query, but remove the
    assertion on nondeterministic per-scanner range assignment.
    
    ### Validation
    
    - `test_paimon_jni_reader_guardrails`: passed
    - `test_iceberg_variant_read`: passed twice consecutively
    
    ### Release note
    
    None. These are test-only corrections.
---
 .../paimon/test_paimon_jni_reader_guardrails.out           |  6 ------
 .../iceberg/test_iceberg_variant_read.groovy               | 14 +++-----------
 .../paimon/test_paimon_jni_reader_guardrails.groovy        |  7 ++-----
 3 files changed, 5 insertions(+), 22 deletions(-)

diff --git 
a/regression-test/data/external_table_p0/paimon/test_paimon_jni_reader_guardrails.out
 
b/regression-test/data/external_table_p0/paimon/test_paimon_jni_reader_guardrails.out
index b149c4535db..363efe80f40 100644
--- 
a/regression-test/data/external_table_p0/paimon/test_paimon_jni_reader_guardrails.out
+++ 
b/regression-test/data/external_table_p0/paimon/test_paimon_jni_reader_guardrails.out
@@ -7,16 +7,10 @@
 1      east,01 nested-one      east,01 a:1
 2      west,02 nested-two      west,02 b:2
 
--- !scanner_v1_empty_identifier --
-empty-name
-
 -- !scanner_v2_quoted_nested --
 1      east,01 nested-one      east,01 a:1
 2      west,02 nested-two      west,02 b:2
 
--- !scanner_v2_empty_identifier --
-empty-name
-
 -- !catalog_override_physical_batch --
 1
 
diff --git 
a/regression-test/suites/external_table_p0/iceberg/test_iceberg_variant_read.groovy
 
b/regression-test/suites/external_table_p0/iceberg/test_iceberg_variant_read.groovy
index 72f0c73e23c..fb2fecb5ac2 100644
--- 
a/regression-test/suites/external_table_p0/iceberg/test_iceberg_variant_read.groovy
+++ 
b/regression-test/suites/external_table_p0/iceberg/test_iceberg_variant_read.groovy
@@ -482,17 +482,6 @@ public class AppendVariantEqualityDelete {
         }
         return sum
     }
-    def profileInfoValues = { String profile, String infoName ->
-        Pattern pattern = Pattern.compile(
-                Pattern.quote(infoName) + ":\\s*\\[([^\\]]*)\\]")
-        Matcher matcher = pattern.matcher(profile)
-        if (!matcher.find()) {
-            return []
-        }
-        return matcher.group(1).split(",").collect { String value -> 
value.trim() }
-                .findAll { String value -> !value.isEmpty() }
-                .collect { String value -> Long.parseLong(value.replace(",", 
"")) }
-    }
     def getProfileByToken = { String token, List<String> positiveCounters = [] 
->
         String lastProfile = profileAction.getProfileBySql(token, 
positiveCounters)
         if (positiveCounters.every { String counter -> counterSum(lastProfile, 
counter) > 0 }) {
@@ -649,6 +638,9 @@ public class AppendVariantEqualityDelete {
     sql "set parallel_pipeline_task_num=4"
     sql "set max_file_scanners_concurrency=8"
     sql "set min_file_scanners_concurrency=4"
+    // Scanner tasks pull file ranges dynamically, so minimum concurrency does 
not guarantee that
+    // every scheduled scanner consumes rows. Validate parallel correctness 
without pinning the
+    // scheduler's nondeterministic range assignment.
     order_qt_variant_multi_file_parallel """
         SELECT id,
                CAST(v['shared'] AS INT),
diff --git 
a/regression-test/suites/external_table_p0/paimon/test_paimon_jni_reader_guardrails.groovy
 
b/regression-test/suites/external_table_p0/paimon/test_paimon_jni_reader_guardrails.groovy
index 0f8780e2e6b..e6167d39db8 100644
--- 
a/regression-test/suites/external_table_p0/paimon/test_paimon_jni_reader_guardrails.groovy
+++ 
b/regression-test/suites/external_table_p0/paimon/test_paimon_jni_reader_guardrails.groovy
@@ -72,6 +72,8 @@ suite("test_paimon_jni_reader_guardrails", 
"p0,external,paimon") {
     """))
 
     try {
+        // Paimon rejects empty field names, so E2E framing coverage uses 
supported
+        // delimiter-rich identifiers; empty-segment decoding remains 
unit-tested.
         spark_paimon_multi """
             create database if not exists paimon.${dbName};
             drop table if exists paimon.${dbName}.quoted_reader_options;
@@ -103,9 +105,6 @@ suite("test_paimon_jni_reader_guardrails", 
"p0,external,paimon") {
             partitioned by (part)
             tblproperties ('scan.manifest.parallelism'='0');
             insert into paimon.${dbName}.unsafe_physical_manifest values (1, 
10);
-            drop table if exists paimon.${dbName}.empty_identifier;
-            create table paimon.${dbName}.empty_identifier (`` string) using 
paimon;
-            insert into paimon.${dbName}.empty_identifier values 
('empty-name');
         """
 
         sql "switch ${catalogName}"
@@ -129,7 +128,6 @@ suite("test_paimon_jni_reader_guardrails", 
"p0,external,paimon") {
                 from quoted_reader_options
                 order by id
         """
-        qt_scanner_v1_empty_identifier "select * from empty_identifier"
         sql "set enable_file_scanner_v2=true"
         order_qt_scanner_v2_quoted_nested """
                 select id, `region,code`, `nested#value`.`hash#name`,
@@ -137,7 +135,6 @@ suite("test_paimon_jni_reader_guardrails", 
"p0,external,paimon") {
                 from quoted_reader_options
                 order by id
         """
-        qt_scanner_v2_empty_identifier "select * from empty_identifier"
 
         // The safe catalog value must override the physical read.batch-size=0 
value.
         order_qt_catalog_override_physical_batch "select * from 
unsafe_physical_batch order by id"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to