test: verify native LastRow predicates and overflow through SQL

Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com>
This commit is contained in:
discord9
2026-09-10 17:48:46 +08:00
parent 1495a6acc7
commit 10eda8d580
2 changed files with 242 additions and 21 deletions
@@ -30,6 +30,67 @@ INSERT INTO native_time_us VALUES
Affected Rows: 18
-- The native projection and exact 1ms-lookback bounds must reach the scan;
-- the 1s+tick row must not displace 201.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (RepartitionExec:.*) RepartitionExec: REDACTED
-- SQLNESS REPLACE native_time_us.__table_id\s*=\s*UInt32\(\d+\) native_time_us.__table_id=UInt32(REDACTED)
TQL EXPLAIN (1, 1, '1s', '1ms') native_time_us{series="exact"};
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| plan_type | plan |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| logical_plan | MergeScan [is_placeholder=false, remote_input=[ |
| | PromInstantManipulate: range=[1000..1000], lookback=[1], interval=[1000], time index=[ts] |
| | PromSeriesDivide: tags=["series"] |
| | Sort: native_time_us.series ASC NULLS FIRST, native_time_us.ts ASC NULLS FIRST |
| | Projection: native_time_us.val, native_time_us.series, native_time_us.ts |
| | Filter: native_time_us.series = Utf8("exact") AND native_time_us.ts > TimestampMicrosecond(999000, None) AND native_time_us.ts <= TimestampMicrosecond(1000000, None) |
| | TableScan: native_time_us, partial_filters=[native_time_us.series = Utf8("exact"), native_time_us.ts > TimestampMicrosecond(999000, None), native_time_us.ts <= TimestampMicrosecond(1000000, None)] |
| | ]] |
| physical_plan | CooperativeExec |
| | MergeScanExec: REDACTED
| | |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- The actual memtable scan must use LastRow { after_merge: true } with native
-- 1ms-lookback bounds; it must select exact 1s rather than the future tick.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (-+) -
-- SQLNESS REPLACE (\s\s+) _
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '1ms') native_time_us{series="exact"};
+-+-+-+
| stage | node | plan_|
+-+-+-+
| 0_| 0_|_CooperativeExec metrics=[]_|
|_|_|_MergeScanExec: REDACTED
|_|_|_|
| 1_| 0_|_PromInstantManipulateExec: range=[1000..1000], lookback=[1], interval=[1000], time index=[ts] metrics=[output_rows: 1, REDACTED
|_|_|_PromSeriesDivideExec: tags=["series"] metrics=[output_rows: 1, REDACTED
|_|_|_ProjectionExec: expr=[val@2 as val, series@1 as series, ts@0 as ts] metrics=[output_rows: 1, REDACTED
|_|_|_CooperativeExec metrics=[]_|
|_|_|_SeriesScan: region=REDACTED, {"partition_count":{"count":1, "mem_ranges":1, "files":0, "file_ranges":0}, "selector":"LastRow { after_merge: true }", "distribution":"PerSeries", "projection": ["ts", "series", "val"], "filters": ["series = Dictionary(UInt32, Utf8(\"exact\"))", "ts > TimestampMicrosecond(999000, None)", "ts <= TimestampMicrosecond(1000000, None)"], "REDACTED
|_|_|_|
|_|_| Total rows: 1_|
+-+-+-+
-- The same-series future tick is in the memtable, while exact 1s remains selected.
TQL EVAL (1, 1, '1s', '1ms') native_time_us{series="exact"};
+-------+--------+---------------------+
| val | series | ts |
+-------+--------+---------------------+
| 201.0 | exact | 1970-01-01T00:00:01 |
+-------+--------+---------------------+
-- Future-only selection is empty before flushing, exercising the memtable path.
TQL EVAL (1, 1, '1s', '300s') native_time_us{series="future"};
@@ -44,8 +105,8 @@ ADMIN FLUSH_TABLE('native_time_us');
| 0 |
+-------------------------------------+
-- At 1s, selection keeps an exact native timestamp.
TQL EVAL (1, 1, '1s', '300s') native_time_us{series="exact"};
-- The exact native sample remains selected from the flushed SST.
TQL EVAL (1, 1, '1s', '1ms') native_time_us{series="exact"};
+-------+--------+---------------------+
| val | series | ts |
@@ -195,6 +256,67 @@ INSERT INTO native_time_ns VALUES
Affected Rows: 18
-- The native projection and exact 1ms-lookback bounds must reach the scan;
-- the 1s+tick row must not displace 201.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (RepartitionExec:.*) RepartitionExec: REDACTED
-- SQLNESS REPLACE native_time_ns.__table_id\s*=\s*UInt32\(\d+\) native_time_ns.__table_id=UInt32(REDACTED)
TQL EXPLAIN (1, 1, '1s', '1ms') native_time_ns{series="exact"};
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| plan_type | plan |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| logical_plan | MergeScan [is_placeholder=false, remote_input=[ |
| | PromInstantManipulate: range=[1000..1000], lookback=[1], interval=[1000], time index=[ts] |
| | PromSeriesDivide: tags=["series"] |
| | Sort: native_time_ns.series ASC NULLS FIRST, native_time_ns.ts ASC NULLS FIRST |
| | Projection: native_time_ns.val, native_time_ns.series, native_time_ns.ts |
| | Filter: native_time_ns.series = Utf8("exact") AND native_time_ns.ts > TimestampNanosecond(999000000, None) AND native_time_ns.ts <= TimestampNanosecond(1000000000, None) |
| | TableScan: native_time_ns, partial_filters=[native_time_ns.series = Utf8("exact"), native_time_ns.ts > TimestampNanosecond(999000000, None), native_time_ns.ts <= TimestampNanosecond(1000000000, None)] |
| | ]] |
| physical_plan | CooperativeExec |
| | MergeScanExec: REDACTED
| | |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- The actual memtable scan must use LastRow { after_merge: true } with native
-- 1ms-lookback bounds; it must select exact 1s rather than the future tick.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (-+) -
-- SQLNESS REPLACE (\s\s+) _
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '1ms') native_time_ns{series="exact"};
+-+-+-+
| stage | node | plan_|
+-+-+-+
| 0_| 0_|_CooperativeExec metrics=[]_|
|_|_|_MergeScanExec: REDACTED
|_|_|_|
| 1_| 0_|_PromInstantManipulateExec: range=[1000..1000], lookback=[1], interval=[1000], time index=[ts] metrics=[output_rows: 1, REDACTED
|_|_|_PromSeriesDivideExec: tags=["series"] metrics=[output_rows: 1, REDACTED
|_|_|_ProjectionExec: expr=[val@2 as val, series@1 as series, ts@0 as ts] metrics=[output_rows: 1, REDACTED
|_|_|_CooperativeExec metrics=[]_|
|_|_|_SeriesScan: region=REDACTED, {"partition_count":{"count":1, "mem_ranges":1, "files":0, "file_ranges":0}, "selector":"LastRow { after_merge: true }", "distribution":"PerSeries", "projection": ["ts", "series", "val"], "filters": ["series = Dictionary(UInt32, Utf8(\"exact\"))", "ts > TimestampNanosecond(999000000, None)", "ts <= TimestampNanosecond(1000000000, None)"], "REDACTED
|_|_|_|
|_|_| Total rows: 1_|
+-+-+-+
-- The same-series future tick is in the memtable, while exact 1s remains selected.
TQL EVAL (1, 1, '1s', '1ms') native_time_ns{series="exact"};
+-------+--------+---------------------+
| val | series | ts |
+-------+--------+---------------------+
| 201.0 | exact | 1970-01-01T00:00:01 |
+-------+--------+---------------------+
-- Future-only selection is empty before flushing, exercising the memtable path.
TQL EVAL (1, 1, '1s', '300s') native_time_ns{series="future"};
@@ -209,8 +331,8 @@ ADMIN FLUSH_TABLE('native_time_ns');
| 0 |
+-------------------------------------+
-- At 1s, selection keeps an exact native timestamp.
TQL EVAL (1, 1, '1s', '300s') native_time_ns{series="exact"};
-- The exact native sample remains selected from the flushed SST.
TQL EVAL (1, 1, '1s', '1ms') native_time_ns{series="exact"};
+-------+--------+---------------------+
| val | series | ts |
@@ -330,6 +452,100 @@ DROP TABLE native_time_ns;
Affected Rows: 0
-- An unrepresentable native lower bound must not discard its representable upper bound.
-- The upper filter must reach LastRow so the 1ms-future row cannot hide the eligible row.
CREATE TABLE native_time_ns_lower_overflow (
ts TIMESTAMP(9) TIME INDEX,
series STRING PRIMARY KEY,
val DOUBLE,
);
Affected Rows: 0
INSERT INTO native_time_ns_lower_overflow VALUES
(-9223200000000000000, 'exact', 1),
(-9223199999999000000, 'exact', 2);
Affected Rows: 2
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE native_time_ns_lower_overflow.__table_id\s*=\s*UInt32\(\d+\) native_time_ns_lower_overflow.__table_id=UInt32(REDACTED)
TQL EXPLAIN (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| plan_type | plan |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| logical_plan | MergeScan [is_placeholder=false, remote_input=[ |
| | PromInstantManipulate: range=[0..0], lookback=[172800000], interval=[1000], time index=[ts] |
| | PromSeriesNormalize: offset=[9223200000000], time index=[ts], filter NaN: [false] |
| | PromSeriesDivide: tags=["series"] |
| | Sort: native_time_ns_lower_overflow.series ASC NULLS FIRST, native_time_ns_lower_overflow.ts ASC NULLS FIRST |
| | Projection: native_time_ns_lower_overflow.val, native_time_ns_lower_overflow.series, native_time_ns_lower_overflow.ts |
| | Filter: native_time_ns_lower_overflow.series = Utf8("exact") AND native_time_ns_lower_overflow.ts <= TimestampNanosecond(-9223200000000000000, None) |
| | TableScan: native_time_ns_lower_overflow, partial_filters=[native_time_ns_lower_overflow.series = Utf8("exact"), native_time_ns_lower_overflow.ts <= TimestampNanosecond(-9223200000000000000, None)] |
| | ]] |
| physical_plan | CooperativeExec |
| | MergeScanExec: REDACTED
| | |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (-+) -
-- SQLNESS REPLACE (\s\s+) _
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
+-+-+-+
| stage | node | plan_|
+-+-+-+
| 0_| 0_|_CooperativeExec metrics=[]_|
|_|_|_MergeScanExec: REDACTED
|_|_|_|
| 1_| 0_|_PromInstantManipulateExec: range=[0..0], lookback=[172800000], interval=[1000], time index=[ts] metrics=[output_rows: 1, REDACTED
|_|_|_PromSeriesNormalizeExec: offset=[9223200000000], time index=[ts], filter NaN: [false] metrics=[output_rows: 1, REDACTED
|_|_|_PromSeriesDivideExec: tags=["series"] metrics=[output_rows: 1, REDACTED
|_|_|_ProjectionExec: expr=[val@2 as val, series@1 as series, ts@0 as ts] metrics=[output_rows: 1, REDACTED
|_|_|_CooperativeExec metrics=[]_|
|_|_|_SeriesScan: region=REDACTED, {"partition_count":{"count":1, "mem_ranges":1, "files":0, "file_ranges":0}, "selector":"LastRow { after_merge: true }", "distribution":"PerSeries", "projection": ["ts", "series", "val"], "filters": ["series = Dictionary(UInt32, Utf8(\"exact\"))", "ts <= TimestampNanosecond(-9223200000000000000, None)"], "REDACTED
|_|_|_|
|_|_| Total rows: 1_|
+-+-+-+
-- The representable upper bound selects only the exact row.
TQL EVAL (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
+-----+--------+---------------------+
| val | series | ts |
+-----+--------+---------------------+
| 1.0 | exact | 1970-01-01T00:00:00 |
+-----+--------+---------------------+
ADMIN FLUSH_TABLE('native_time_ns_lower_overflow');
+----------------------------------------------------+
| ADMIN FLUSH_TABLE('native_time_ns_lower_overflow') |
+----------------------------------------------------+
| 0 |
+----------------------------------------------------+
TQL EVAL (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
+-----+--------+---------------------+
| val | series | ts |
+-----+--------+---------------------+
| 1.0 | exact | 1970-01-01T00:00:00 |
+-----+--------+---------------------+
DROP TABLE native_time_ns_lower_overflow;
Affected Rows: 0
-- Second precision is promoted before applying fractional-second offsets.
CREATE TABLE native_time_sec (ts TIMESTAMP(0) TIME INDEX, val DOUBLE);
@@ -27,17 +27,17 @@ INSERT INTO native_time_us VALUES
(1000000, 'window', 3),
(1000001, 'window', 4);
-- The native projection and exact zero-lookback bounds must reach the scan;
-- The native projection and exact 1ms-lookback bounds must reach the scan;
-- the 1s+tick row must not displace 201.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (RepartitionExec:.*) RepartitionExec: REDACTED
-- SQLNESS REPLACE native_time_us.__table_id\s*=\s*UInt32\(\d+\) native_time_us.__table_id=UInt32(REDACTED)
TQL EXPLAIN (1, 1, '1s', '0s') native_time_us{series="exact"};
TQL EXPLAIN (1, 1, '1s', '1ms') native_time_us{series="exact"};
-- The actual memtable scan must use LastRow { after_merge: true } with native
-- zero-lookback bounds; it must select exact 1s rather than the future tick.
-- 1ms-lookback bounds; it must select exact 1s rather than the future tick.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (-+) -
@@ -45,10 +45,11 @@ TQL EXPLAIN (1, 1, '1s', '0s') native_time_us{series="exact"};
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '0s') native_time_us{series="exact"};
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '1ms') native_time_us{series="exact"};
-- The same-series future tick is in the memtable, while exact 1s remains selected.
TQL EVAL (1, 1, '1s', '0s') native_time_us{series="exact"};
TQL EVAL (1, 1, '1s', '1ms') native_time_us{series="exact"};
-- Future-only selection is empty before flushing, exercising the memtable path.
TQL EVAL (1, 1, '1s', '300s') native_time_us{series="future"};
@@ -56,7 +57,7 @@ TQL EVAL (1, 1, '1s', '300s') native_time_us{series="future"};
ADMIN FLUSH_TABLE('native_time_us');
-- The exact native sample remains selected from the flushed SST.
TQL EVAL (1, 1, '1s', '0s') native_time_us{series="exact"};
TQL EVAL (1, 1, '1s', '1ms') native_time_us{series="exact"};
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_us{series="future"});
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_us{series="exact"});
@@ -112,17 +113,17 @@ INSERT INTO native_time_ns VALUES
(1000000000, 'window', 3),
(1000000001, 'window', 4);
-- The native projection and exact zero-lookback bounds must reach the scan;
-- The native projection and exact 1ms-lookback bounds must reach the scan;
-- the 1s+tick row must not displace 201.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (RepartitionExec:.*) RepartitionExec: REDACTED
-- SQLNESS REPLACE native_time_ns.__table_id\s*=\s*UInt32\(\d+\) native_time_ns.__table_id=UInt32(REDACTED)
TQL EXPLAIN (1, 1, '1s', '0s') native_time_ns{series="exact"};
TQL EXPLAIN (1, 1, '1s', '1ms') native_time_ns{series="exact"};
-- The actual memtable scan must use LastRow { after_merge: true } with native
-- zero-lookback bounds; it must select exact 1s rather than the future tick.
-- 1ms-lookback bounds; it must select exact 1s rather than the future tick.
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE (-+) -
@@ -130,10 +131,11 @@ TQL EXPLAIN (1, 1, '1s', '0s') native_time_ns{series="exact"};
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '0s') native_time_ns{series="exact"};
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (1, 1, '1s', '1ms') native_time_ns{series="exact"};
-- The same-series future tick is in the memtable, while exact 1s remains selected.
TQL EVAL (1, 1, '1s', '0s') native_time_ns{series="exact"};
TQL EVAL (1, 1, '1s', '1ms') native_time_ns{series="exact"};
-- Future-only selection is empty before flushing, exercising the memtable path.
TQL EVAL (1, 1, '1s', '300s') native_time_ns{series="future"};
@@ -141,7 +143,7 @@ TQL EVAL (1, 1, '1s', '300s') native_time_ns{series="future"};
ADMIN FLUSH_TABLE('native_time_ns');
-- The exact native sample remains selected from the flushed SST.
TQL EVAL (1, 1, '1s', '0s') native_time_ns{series="exact"};
TQL EVAL (1, 1, '1s', '1ms') native_time_ns{series="exact"};
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_ns{series="future"});
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_ns{series="exact"});
@@ -179,14 +181,14 @@ CREATE TABLE native_time_ns_lower_overflow (
val DOUBLE,
);
INSERT INTO native_time_ns_lower_overflow VALUES
(-9223372036854000000, 'exact', 1),
(-9223372036853000000, 'exact', 2);
(-9223200000000000000, 'exact', 1),
(-9223199999999000000, 'exact', 2);
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
-- SQLNESS REPLACE native_time_ns_lower_overflow.__table_id\s*=\s*UInt32\(\d+\) native_time_ns_lower_overflow.__table_id=UInt32(REDACTED)
TQL EXPLAIN (0, 0, '1s', '300s') native_time_ns_lower_overflow{series="exact"} offset 9223372036854ms;
TQL EXPLAIN (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
-- SQLNESS REPLACE (RoundRobinBatch.*) REDACTED
-- SQLNESS REPLACE (Hash.*) REDACTED
@@ -195,10 +197,13 @@ TQL EXPLAIN (0, 0, '1s', '300s') native_time_ns_lower_overflow{series="exact"} o
-- SQLNESS REPLACE (peers.*) REDACTED
-- SQLNESS REPLACE region=\d+\(\d+,\s+\d+\) region=REDACTED
-- SQLNESS REPLACE (flat_format.*) REDACTED
TQL ANALYZE VERBOSE (0, 0, '1s', '300s') native_time_ns_lower_overflow{series="exact"} offset 9223372036854ms;
-- SQLNESS REPLACE (elapsed_compute.*) REDACTED
TQL ANALYZE VERBOSE (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
-- The representable upper bound selects only the exact row.
TQL EVAL (0, 0, '1s', '300s') native_time_ns_lower_overflow{series="exact"} offset 9223372036854ms;
TQL EVAL (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
ADMIN FLUSH_TABLE('native_time_ns_lower_overflow');
TQL EVAL (0, 0, '1s', '2d') native_time_ns_lower_overflow{series="exact"} offset 106750d;
DROP TABLE native_time_ns_lower_overflow;
-- Second precision is promoted before applying fractional-second offsets.