mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-17 17:32:30 +00:00
635 lines
35 KiB
Plaintext
635 lines
35 KiB
Plaintext
-- Regression coverage for instant and range selection on native microsecond and
|
|
-- nanosecond time indexes.
|
|
CREATE TABLE native_time_us (
|
|
ts TIMESTAMP(6) TIME INDEX,
|
|
series STRING PRIMARY KEY,
|
|
val DOUBLE,
|
|
);
|
|
|
|
Affected Rows: 0
|
|
|
|
INSERT INTO native_time_us VALUES
|
|
(1000001, 'future', 101),
|
|
(1000000, 'exact', 201),
|
|
(1000001, 'exact', 202),
|
|
(-299000000, 'lowerbound', 301),
|
|
(-298999999, 'lowerplus', 302),
|
|
(1000000, 'positive_lowerbound', 701),
|
|
(1000001, 'positive_lowerplus', 702),
|
|
(1000001, 'multi', 401),
|
|
(-1000000, 'offset', 501),
|
|
(0, 'offset', 502),
|
|
(1000000, 'offset', 503),
|
|
(999999, 'past', 602),
|
|
(999001, 'past', 601),
|
|
(0, 'window', 1),
|
|
(1, 'window', 2),
|
|
(2, 'window', 5),
|
|
(1000000, 'window', 3),
|
|
(1000001, 'window', 4);
|
|
|
|
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=[ |
|
|
| | Projection: native_time_us.val, native_time_us.series, native_time_us.ts |
|
|
| | Projection: native_time_us.val, native_time_us.series, native_time_us.ts, Utf8("native_time_us") FieldMetadata { inner: {"greptime:promql:role": "metric_name"} } AS __promql_metric_name |
|
|
| | 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"};
|
|
|
|
+-----+--------+----+
|
|
| val | series | ts |
|
|
+-----+--------+----+
|
|
+-----+--------+----+
|
|
|
|
ADMIN FLUSH_TABLE('native_time_us');
|
|
|
|
+-------------------------------------+
|
|
| ADMIN FLUSH_TABLE('native_time_us') |
|
|
+-------------------------------------+
|
|
| 0 |
|
|
+-------------------------------------+
|
|
|
|
-- The exact native sample remains selected from the flushed SST.
|
|
TQL EVAL (1, 1, '1s', '1ms') native_time_us{series="exact"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 201.0 | exact | 1970-01-01T00:00:01 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_us{series="future"});
|
|
|
|
+----+-------+--------+
|
|
| ts | value | series |
|
|
+----+-------+--------+
|
|
+----+-------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_us{series="exact"});
|
|
|
|
+---------------------+-------+--------+
|
|
| ts | value | series |
|
|
+---------------------+-------+--------+
|
|
| 1970-01-01T00:00:01 | 1.0 | exact |
|
|
+---------------------+-------+--------+
|
|
|
|
-- Instant lookback bounds are exclusive: these return only 302 and 702.
|
|
TQL EVAL (1, 1, '1s', '300s') native_time_us{series=~"lower.*"};
|
|
|
|
+-------+-----------+---------------------+
|
|
| val | series | ts |
|
|
+-------+-----------+---------------------+
|
|
| 302.0 | lowerplus | 1970-01-01T00:00:01 |
|
|
+-------+-----------+---------------------+
|
|
|
|
TQL EVAL (301, 301, '1s', '300s') native_time_us{series=~"positive_lower.*"};
|
|
|
|
+-------+--------------------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------------------+---------------------+
|
|
| 702.0 | positive_lowerplus | 1970-01-01T00:05:01 |
|
|
+-------+--------------------+---------------------+
|
|
|
|
-- The sub-millisecond point belongs only to the 2s evaluation step.
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
TQL EVAL (1, 2, '1s', '300s') native_time_us{series="multi"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 401.0 | multi | 1970-01-01T00:00:02 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- The latest native timestamp below 1s is retained even when inserts are unordered.
|
|
TQL EVAL (1, 1, '1s', '300s') native_time_us{series="past"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 602.0 | past | 1970-01-01T00:00:01 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- Offsets select native timestamps, including stored negative time.
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_us{series="offset"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 502.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_us{series="offset"} offset 1s;
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 501.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_us{series="offset"} offset -1s;
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 503.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- [1s] at 1s excludes 0 and 1s+tick, retaining 0+tick, 0+2ticks, and 1s.
|
|
TQL EVAL (1, 1, '1s', '300s') count_over_time(native_time_us{series="window"}[1s]);
|
|
|
|
+---------------------+------------------------------------+--------+
|
|
| ts | prom_count_over_time(ts_range,val) | series |
|
|
+---------------------+------------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 3.0 | window |
|
|
+---------------------+------------------------------------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') sum_over_time(native_time_us{series="window"}[1s]);
|
|
|
|
+---------------------+----------------------------------+--------+
|
|
| ts | prom_sum_over_time(ts_range,val) | series |
|
|
+---------------------+----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 10.0 | window |
|
|
+---------------------+----------------------------------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') last_over_time(native_time_us{series="window"}[1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 3.0 | window |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
-- The inner selector consumes native time; the subquery consumes ms evaluations.
|
|
TQL EVAL (1, 1, '1s') last_over_time((native_time_us{series="exact"})[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 201.0 | exact |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
-- Inner offsets are applied once when evaluating the subquery selector.
|
|
TQL EVAL (0, 0, '1s') last_over_time((native_time_us{series="offset"} offset 1s)[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:00 | 501.0 | offset |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
TQL EVAL (0, 0, '1s') last_over_time((native_time_us{series="offset"} offset -1s)[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:00 | 503.0 | offset |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
DROP TABLE native_time_us;
|
|
|
|
Affected Rows: 0
|
|
|
|
CREATE TABLE native_time_ns (
|
|
ts TIMESTAMP(9) TIME INDEX,
|
|
series STRING PRIMARY KEY,
|
|
val DOUBLE,
|
|
);
|
|
|
|
Affected Rows: 0
|
|
|
|
INSERT INTO native_time_ns VALUES
|
|
(1000000001, 'future', 101),
|
|
(1000000000, 'exact', 201),
|
|
(1000000001, 'exact', 202),
|
|
(-299000000000, 'lowerbound', 301),
|
|
(-298999999999, 'lowerplus', 302),
|
|
(1000000000, 'positive_lowerbound', 701),
|
|
(1000000001, 'positive_lowerplus', 702),
|
|
(1000000001, 'multi', 401),
|
|
(-1000000000, 'offset', 501),
|
|
(0, 'offset', 502),
|
|
(1000000000, 'offset', 503),
|
|
(999999000, 'past', 602),
|
|
(999001000, 'past', 601),
|
|
(0, 'window', 1),
|
|
(1, 'window', 2),
|
|
(2, 'window', 5),
|
|
(1000000000, 'window', 3),
|
|
(1000000001, 'window', 4);
|
|
|
|
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=[ |
|
|
| | Projection: native_time_ns.val, native_time_ns.series, native_time_ns.ts |
|
|
| | Projection: native_time_ns.val, native_time_ns.series, native_time_ns.ts, Utf8("native_time_ns") FieldMetadata { inner: {"greptime:promql:role": "metric_name"} } AS __promql_metric_name |
|
|
| | 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"};
|
|
|
|
+-----+--------+----+
|
|
| val | series | ts |
|
|
+-----+--------+----+
|
|
+-----+--------+----+
|
|
|
|
ADMIN FLUSH_TABLE('native_time_ns');
|
|
|
|
+-------------------------------------+
|
|
| ADMIN FLUSH_TABLE('native_time_ns') |
|
|
+-------------------------------------+
|
|
| 0 |
|
|
+-------------------------------------+
|
|
|
|
-- The exact native sample remains selected from the flushed SST.
|
|
TQL EVAL (1, 1, '1s', '1ms') native_time_ns{series="exact"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 201.0 | exact | 1970-01-01T00:00:01 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_ns{series="future"});
|
|
|
|
+----+-------+--------+
|
|
| ts | value | series |
|
|
+----+-------+--------+
|
|
+----+-------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') timestamp(native_time_ns{series="exact"});
|
|
|
|
+---------------------+-------+--------+
|
|
| ts | value | series |
|
|
+---------------------+-------+--------+
|
|
| 1970-01-01T00:00:01 | 1.0 | exact |
|
|
+---------------------+-------+--------+
|
|
|
|
-- Instant lookback bounds are exclusive: these return only 302 and 702.
|
|
TQL EVAL (1, 1, '1s', '300s') native_time_ns{series=~"lower.*"};
|
|
|
|
+-------+-----------+---------------------+
|
|
| val | series | ts |
|
|
+-------+-----------+---------------------+
|
|
| 302.0 | lowerplus | 1970-01-01T00:00:01 |
|
|
+-------+-----------+---------------------+
|
|
|
|
TQL EVAL (301, 301, '1s', '300s') native_time_ns{series=~"positive_lower.*"};
|
|
|
|
+-------+--------------------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------------------+---------------------+
|
|
| 702.0 | positive_lowerplus | 1970-01-01T00:05:01 |
|
|
+-------+--------------------+---------------------+
|
|
|
|
-- The sub-millisecond point belongs only to the 2s evaluation step.
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
TQL EVAL (1, 2, '1s', '300s') native_time_ns{series="multi"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 401.0 | multi | 1970-01-01T00:00:02 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- The latest native timestamp below 1s is retained even when inserts are unordered.
|
|
TQL EVAL (1, 1, '1s', '300s') native_time_ns{series="past"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 602.0 | past | 1970-01-01T00:00:01 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- Offsets select native timestamps, including stored negative time.
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_ns{series="offset"};
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 502.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_ns{series="offset"} offset 1s;
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 501.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
TQL EVAL (0, 0, '1s', '300s') native_time_ns{series="offset"} offset -1s;
|
|
|
|
+-------+--------+---------------------+
|
|
| val | series | ts |
|
|
+-------+--------+---------------------+
|
|
| 503.0 | offset | 1970-01-01T00:00:00 |
|
|
+-------+--------+---------------------+
|
|
|
|
-- [1s] at 1s excludes 0 and 1s+tick, retaining 0+tick, 0+2ticks, and 1s.
|
|
TQL EVAL (1, 1, '1s', '300s') count_over_time(native_time_ns{series="window"}[1s]);
|
|
|
|
+---------------------+------------------------------------+--------+
|
|
| ts | prom_count_over_time(ts_range,val) | series |
|
|
+---------------------+------------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 3.0 | window |
|
|
+---------------------+------------------------------------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') sum_over_time(native_time_ns{series="window"}[1s]);
|
|
|
|
+---------------------+----------------------------------+--------+
|
|
| ts | prom_sum_over_time(ts_range,val) | series |
|
|
+---------------------+----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 10.0 | window |
|
|
+---------------------+----------------------------------+--------+
|
|
|
|
TQL EVAL (1, 1, '1s', '300s') last_over_time(native_time_ns{series="window"}[1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 3.0 | window |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
-- The inner selector consumes native time; the subquery consumes ms evaluations.
|
|
TQL EVAL (1, 1, '1s') last_over_time((native_time_ns{series="exact"})[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:01 | 201.0 | exact |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
-- Inner offsets are applied once when evaluating the subquery selector.
|
|
TQL EVAL (0, 0, '1s') last_over_time((native_time_ns{series="offset"} offset 1s)[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:00 | 501.0 | offset |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
TQL EVAL (0, 0, '1s') last_over_time((native_time_ns{series="offset"} offset -1s)[1s:1s]);
|
|
|
|
+---------------------+-----------------------------------+--------+
|
|
| ts | prom_last_over_time(ts_range,val) | series |
|
|
+---------------------+-----------------------------------+--------+
|
|
| 1970-01-01T00:00:00 | 503.0 | offset |
|
|
+---------------------+-----------------------------------+--------+
|
|
|
|
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=[ |
|
|
| | Projection: native_time_ns_lower_overflow.val, native_time_ns_lower_overflow.series, native_time_ns_lower_overflow.ts |
|
|
| | Projection: native_time_ns_lower_overflow.val, native_time_ns_lower_overflow.series, native_time_ns_lower_overflow.ts, Utf8("native_time_ns_lower_overflow") FieldMetadata { inner: {"greptime:promql:role": "metric_name"} } AS __promql_metric_name |
|
|
| | 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);
|
|
|
|
Affected Rows: 0
|
|
|
|
INSERT INTO native_time_sec VALUES (0, 10), (1, 11), (2, 12);
|
|
|
|
Affected Rows: 3
|
|
|
|
TQL EVAL (1, 1, '1s', '1s') native_time_sec offset 500ms;
|
|
|
|
+------+---------------------+
|
|
| val | ts |
|
|
+------+---------------------+
|
|
| 10.0 | 1970-01-01T00:00:01 |
|
|
+------+---------------------+
|
|
|
|
TQL EVAL (1, 1, '1s', '1s') native_time_sec offset -500ms;
|
|
|
|
+------+---------------------+
|
|
| val | ts |
|
|
+------+---------------------+
|
|
| 11.0 | 1970-01-01T00:00:01 |
|
|
+------+---------------------+
|
|
|
|
-- `timestamp()` reports the timestamp of the selected sample (1s), without the offset applied.
|
|
TQL EVAL (1, 1, '1s', '1s') timestamp(native_time_sec offset -500ms);
|
|
|
|
+---------------------+-------+
|
|
| ts | value |
|
|
+---------------------+-------+
|
|
| 1970-01-01T00:00:01 | 1.0 |
|
|
+---------------------+-------+
|
|
|
|
DROP TABLE native_time_sec;
|
|
|
|
Affected Rows: 0
|
|
|