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

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


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 8f912890df1 branch-4.0: [fix](be) Support TIMESTAMPTZ in TopN runtime 
predicate #63220 (#63236)
8f912890df1 is described below

commit 8f912890df1fc3c3e5dc84c856e39e7774c18773
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri May 15 21:08:29 2026 -0700

    branch-4.0: [fix](be) Support TIMESTAMPTZ in TopN runtime predicate #63220 
(#63236)
    
    Cherry-picked from #63220
    
    Co-authored-by: TengJianPing <[email protected]>
---
 be/src/runtime/runtime_predicate.cpp               |   2 +-
 .../timestamptz/test_timestamptz_sort.out          | 104 ++++++++++++++++
 .../timestamptz/test_timestamptz_sort.groovy       | 134 +++++++++++++++++++++
 3 files changed, 239 insertions(+), 1 deletion(-)

diff --git a/be/src/runtime/runtime_predicate.cpp 
b/be/src/runtime/runtime_predicate.cpp
index 0b28df34665..36e3e6cd5e6 100644
--- a/be/src/runtime/runtime_predicate.cpp
+++ b/be/src/runtime/runtime_predicate.cpp
@@ -78,7 +78,7 @@ Status RuntimePredicate::init_target(
 
 bool RuntimePredicate::_init(PrimitiveType type) {
     return is_int_or_bool(type) || is_decimal(type) || is_string_type(type) || 
is_date_type(type) ||
-           is_time_type(type) || is_ip(type) || is_varbinary(type);
+           is_time_type(type) || is_timestamptz_type(type) || is_ip(type) || 
is_varbinary(type);
 }
 
 Status RuntimePredicate::update(const Field& value) {
diff --git 
a/regression-test/data/datatype_p0/timestamptz/test_timestamptz_sort.out 
b/regression-test/data/datatype_p0/timestamptz/test_timestamptz_sort.out
index 41766708c9f..6b8b08de986 100644
--- a/regression-test/data/datatype_p0/timestamptz/test_timestamptz_sort.out
+++ b/regression-test/data/datatype_p0/timestamptz/test_timestamptz_sort.out
@@ -16,3 +16,107 @@
 -- !sort_offset_limit --
 3      2020-01-01 07:59:59+08:00
 
+-- !big_topn_asc --
+0      1970-01-01 08:00:00+08:00
+1      1970-01-01 08:00:01+08:00
+2      1970-01-01 08:00:02+08:00
+3      1970-01-01 08:00:03+08:00
+4      1970-01-01 08:00:04+08:00
+5      1970-01-01 08:00:05+08:00
+6      1970-01-01 08:00:06+08:00
+7      1970-01-01 08:00:07+08:00
+8      1970-01-01 08:00:08+08:00
+9      1970-01-01 08:00:09+08:00
+
+-- !big_topn_desc --
+9999   1970-01-01 10:46:39+08:00
+9998   1970-01-01 10:46:38+08:00
+9997   1970-01-01 10:46:37+08:00
+9996   1970-01-01 10:46:36+08:00
+9995   1970-01-01 10:46:35+08:00
+9994   1970-01-01 10:46:34+08:00
+9993   1970-01-01 10:46:33+08:00
+9992   1970-01-01 10:46:32+08:00
+9991   1970-01-01 10:46:31+08:00
+9990   1970-01-01 10:46:30+08:00
+
+-- !big_topn_offset --
+50     1970-01-01 08:00:50+08:00
+51     1970-01-01 08:00:51+08:00
+52     1970-01-01 08:00:52+08:00
+53     1970-01-01 08:00:53+08:00
+54     1970-01-01 08:00:54+08:00
+55     1970-01-01 08:00:55+08:00
+56     1970-01-01 08:00:56+08:00
+57     1970-01-01 08:00:57+08:00
+58     1970-01-01 08:00:58+08:00
+59     1970-01-01 08:00:59+08:00
+
+-- !big_count --
+10000
+
+-- !mixed_asc --
+5      2020-01-01 00:00:00+08:00
+8      2020-01-01 07:59:59+08:00
+6      2020-01-01 08:00:00+08:00
+2      2020-01-01 12:00:00+08:00
+4      2020-01-01 14:30:00+08:00
+
+-- !mixed_desc --
+10     2020-06-02 01:00:00+08:00
+9      2020-06-01 15:00:00+08:00
+3      2020-01-02 01:00:00+08:00
+1      2020-01-01 20:00:00+08:00
+7      2020-01-01 16:00:00+08:00
+
+-- !big_null_asc_first --
+0      \N
+97     \N
+194    \N
+291    \N
+388    \N
+485    \N
+582    \N
+679    \N
+776    \N
+873    \N
+
+-- !big_null_asc_last --
+1      1970-01-01 08:00:01+08:00
+2      1970-01-01 08:00:02+08:00
+3      1970-01-01 08:00:03+08:00
+4      1970-01-01 08:00:04+08:00
+5      1970-01-01 08:00:05+08:00
+6      1970-01-01 08:00:06+08:00
+7      1970-01-01 08:00:07+08:00
+8      1970-01-01 08:00:08+08:00
+9      1970-01-01 08:00:09+08:00
+10     1970-01-01 08:00:10+08:00
+
+-- !big_null_desc_first --
+0      \N
+97     \N
+194    \N
+291    \N
+388    \N
+485    \N
+582    \N
+679    \N
+776    \N
+873    \N
+
+-- !big_null_desc_last --
+9999   1970-01-01 10:46:39+08:00
+9998   1970-01-01 10:46:38+08:00
+9997   1970-01-01 10:46:37+08:00
+9996   1970-01-01 10:46:36+08:00
+9995   1970-01-01 10:46:35+08:00
+9994   1970-01-01 10:46:34+08:00
+9993   1970-01-01 10:46:33+08:00
+9992   1970-01-01 10:46:32+08:00
+9990   1970-01-01 10:46:30+08:00
+9989   1970-01-01 10:46:29+08:00
+
+-- !big_null_count --
+10000  9896
+
diff --git 
a/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_sort.groovy 
b/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_sort.groovy
index b88e16b82ba..6fd7e806d3e 100644
--- 
a/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_sort.groovy
+++ 
b/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_sort.groovy
@@ -50,4 +50,138 @@ suite("test_timestamptz_sort") {
     qt_sort_offset_limit """
         select * from timestamptz_sort_test order by tz asc limit 1 offset 1;
     """
+
+    // Exercise BE topn runtime predicate on TIMESTAMPTZ.
+    // topn_filter_ratio is amplified so that the FE generates a TopnFilter 
targeting the OlapScan
+    // regardless of row-count statistics; without TIMESTAMPTZ support in 
RuntimePredicate this
+    // query throws "meet invalid type, type=TIMESTAMPTZ" on the BE.
+    sql " set topn_filter_ratio = 1000000; "
+
+    // Larger dataset to exercise the BE topn runtime predicate over many 
segments / pages,
+    // so that the threshold tightens repeatedly and storage-layer pruning 
kicks in.
+    sql """ DROP TABLE IF EXISTS timestamptz_sort_big; """
+    sql """
+        CREATE TABLE timestamptz_sort_big (id INT, tz timestamptz)
+        DISTRIBUTED BY HASH(id) BUCKETS 4
+        PROPERTIES ("replication_num" = "1");
+    """
+    sql """
+        INSERT INTO timestamptz_sort_big
+        SELECT
+            cast(number as INT),
+            cast(from_unixtime(number) as timestamptz)
+        FROM numbers("number" = "10000");
+    """
+
+    // The plan must actually contain the TopN runtime predicate (TOPN OPT on 
OlapScanNode);
+    // otherwise the BE path under test is dormant and the query trivially 
passes for the wrong
+    // reason. We assert it on both asc and desc so flipping the order is also 
covered.
+    explain {
+        sql "select * from timestamptz_sort_big order by tz asc, id asc limit 
10;"
+        contains("TOPN OPT:")
+    }
+    explain {
+        sql "select * from timestamptz_sort_big order by tz desc, id asc limit 
10;"
+        contains("TOPN OPT:")
+    }
+
+    qt_big_topn_asc """
+        select * from timestamptz_sort_big order by tz asc, id asc limit 10;
+    """
+
+    qt_big_topn_desc """
+        select * from timestamptz_sort_big order by tz desc, id asc limit 10;
+    """
+
+    qt_big_topn_offset """
+        select * from timestamptz_sort_big order by tz asc, id asc limit 10 
offset 50;
+    """
+
+    qt_big_count """
+        select count(*) from timestamptz_sort_big;
+    """
+
+    // Mixed timezones: verify TopN orders by the absolute UTC instant, not 
the local display.
+    // Two pairs deliberately share local clock time but differ by offset; the 
+00:00 row is the
+    // *later* instant for the noon pair, and the +08:00 row is the *later* 
instant for the midnight
+    // pair. The sort must reflect the actual instant, not the local string.
+    sql """ DROP TABLE IF EXISTS timestamptz_sort_mixed; """
+    sql """
+        CREATE TABLE timestamptz_sort_mixed (id INT, tz timestamptz)
+        DISTRIBUTED BY HASH(id) BUCKETS 4
+        PROPERTIES ("replication_num" = "1");
+    """
+    sql """
+        insert into timestamptz_sort_mixed values
+            (1,  cast("2020-01-01 12:00:00 +00:00" as timestamptz)),
+            (2,  cast("2020-01-01 12:00:00 +08:00" as timestamptz)),
+            (3,  cast("2020-01-01 12:00:00 -05:00" as timestamptz)),
+            (4,  cast("2020-01-01 12:00:00 +05:30" as timestamptz)),
+            (5,  cast("2020-01-01 00:00:00 +08:00" as timestamptz)),
+            (6,  cast("2020-01-01 00:00:00 +00:00" as timestamptz)),
+            (7,  cast("2020-01-01 00:00:00 -08:00" as timestamptz)),
+            (8,  cast("2019-12-31 23:59:59 +00:00" as timestamptz)),
+            (9,  cast("2020-06-01 12:00:00 +05:00" as timestamptz)),
+            (10, cast("2020-06-01 12:00:00 -05:00" as timestamptz));
+    """
+
+    explain {
+        sql "select * from timestamptz_sort_mixed order by tz asc, id asc 
limit 5;"
+        contains("TOPN OPT:")
+    }
+
+    qt_mixed_asc """
+        select * from timestamptz_sort_mixed order by tz asc, id asc limit 5;
+    """
+
+    qt_mixed_desc """
+        select * from timestamptz_sort_mixed order by tz desc, id asc limit 5;
+    """
+
+    // Combined large-scale + nullable: 10k rows with periodic NULLs scattered 
through, exercising
+    // the topn runtime predicate together with NULLS FIRST / NULLS LAST 
semantics over many pages.
+    sql """ DROP TABLE IF EXISTS timestamptz_sort_big_null; """
+    sql """
+        CREATE TABLE timestamptz_sort_big_null (id INT, tz timestamptz NULL)
+        DISTRIBUTED BY HASH(id) BUCKETS 4
+        PROPERTIES ("replication_num" = "1");
+    """
+    sql """
+        INSERT INTO timestamptz_sort_big_null
+        SELECT
+            cast(number as INT),
+            case when number % 97 = 0 then null
+                 else cast(from_unixtime(number) as timestamptz)
+            end
+        FROM numbers("number" = "10000");
+    """
+
+    explain {
+        sql "select * from timestamptz_sort_big_null order by tz asc nulls 
first, id asc limit 10;"
+        contains("TOPN OPT:")
+    }
+    explain {
+        sql "select * from timestamptz_sort_big_null order by tz asc nulls 
last, id asc limit 10;"
+        contains("TOPN OPT:")
+    }
+
+    qt_big_null_asc_first """
+        select * from timestamptz_sort_big_null order by tz asc nulls first, 
id asc limit 10;
+    """
+
+    qt_big_null_asc_last """
+        select * from timestamptz_sort_big_null order by tz asc nulls last, id 
asc limit 10;
+    """
+
+    qt_big_null_desc_first """
+        select * from timestamptz_sort_big_null order by tz desc nulls first, 
id asc limit 10;
+    """
+
+    qt_big_null_desc_last """
+        select * from timestamptz_sort_big_null order by tz desc nulls last, 
id asc limit 10;
+    """
+
+    qt_big_null_count """
+        select count(*), count(tz) from timestamptz_sort_big_null;
+    """
 }


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

Reply via email to