diff --git a/src/query/src/promql/planner.rs b/src/query/src/promql/planner.rs index 0edaf8328e..232ed2abf4 100644 --- a/src/query/src/promql/planner.rs +++ b/src/query/src/promql/planner.rs @@ -529,10 +529,7 @@ impl PromPlanner { (Some(mut expr), None) => { let input = self.prom_expr_to_plan(rhs, query_engine_state).await?; // check if the literal is a special time expr - if let Some(time_expr) = Self::try_build_special_time_expr( - lhs, - self.ctx.time_index_column.as_ref().unwrap(), - ) { + if let Some(time_expr) = self.try_build_special_time_expr_with_context(lhs) { expr = time_expr } let bin_expr_builder = |col: &String| { @@ -558,10 +555,7 @@ impl PromPlanner { (None, Some(mut expr)) => { let input = self.prom_expr_to_plan(lhs, query_engine_state).await?; // check if the literal is a special time expr - if let Some(time_expr) = Self::try_build_special_time_expr( - rhs, - self.ctx.time_index_column.as_ref().unwrap(), - ) { + if let Some(time_expr) = self.try_build_special_time_expr_with_context(rhs) { expr = time_expr } let bin_expr_builder = |col: &String| { @@ -2666,7 +2660,9 @@ impl PromPlanner { | PromExpr::Subquery(_) => None, PromExpr::Call(Call { func, .. }) => { if func.name == SPECIAL_TIME_FUNCTION { - Some(build_special_time_expr(SPECIAL_TIME_FUNCTION)) + // For time() function, don't treat it as a literal + // Let it be handled as a regular function call + None } else { None } @@ -2703,10 +2699,12 @@ impl PromPlanner { } } - fn try_build_special_time_expr(expr: &PromExpr, time_index_col: &str) -> Option { + fn try_build_special_time_expr_with_context(&self, expr: &PromExpr) -> Option { match expr { PromExpr::Call(Call { func, .. }) => { - if func.name == SPECIAL_TIME_FUNCTION { + if func.name == SPECIAL_TIME_FUNCTION + && let Some(time_index_col) = self.ctx.time_index_column.as_ref() + { Some(build_special_time_expr(time_index_col)) } else { None diff --git a/tests/cases/standalone/common/promql/time_fn.result b/tests/cases/standalone/common/promql/time_fn.result index f5ce129a60..104e90b7f8 100644 --- a/tests/cases/standalone/common/promql/time_fn.result +++ b/tests/cases/standalone/common/promql/time_fn.result @@ -28,19 +28,35 @@ tql eval (0.001, 1, '1s') time(); tql eval (0, 0, '1s') time() + 1; -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:00:00 | 1.0 | -+---------------------+-------+ ++---------------------+-----------------------------------+ +| time | time / Float64(1000) + Float64(1) | ++---------------------+-----------------------------------+ +| 1970-01-01T00:00:00 | 1.0 | ++---------------------+-----------------------------------+ tql eval (0, 0, '1s') 1 + time(); -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:00:00 | 1.0 | -+---------------------+-------+ ++---------------------+-----------------------------------+ +| time | Float64(1) + time / Float64(1000) | ++---------------------+-----------------------------------+ +| 1970-01-01T00:00:00 | 1.0 | ++---------------------+-----------------------------------+ + +tql eval (10000, 10000, '1s') time() * time(); + ++---------------------+-----------------------------------------------------+ +| time | lhs.time / Float64(1000) * rhs.time / Float64(1000) | ++---------------------+-----------------------------------------------------+ +| 1970-01-01T02:46:40 | 100000000.0 | ++---------------------+-----------------------------------------------------+ + +tql eval (10000, 10000, '1s') time() / time(); + ++---------------------+-----------------------------------------------------+ +| time | lhs.time / Float64(1000) / rhs.time / Float64(1000) | ++---------------------+-----------------------------------------------------+ +| 1970-01-01T02:46:40 | 1.0 | ++---------------------+-----------------------------------------------------+ -- expect error: parse error: comparisons between scalars must use BOOL modifier tql eval (0, 0, '1s') time() < 1; @@ -49,27 +65,27 @@ Error: 2000(InvalidSyntax), comparisons between scalars must use BOOL modifier tql eval (0, 0, '1s') time() < bool 1; -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:00:00 | 1.0 | -+---------------------+-------+ ++---------------------+-----------------------------------+ +| time | time / Float64(1000) < Float64(1) | ++---------------------+-----------------------------------+ +| 1970-01-01T00:00:00 | 1.0 | ++---------------------+-----------------------------------+ tql eval (0, 0, '1s') time() > bool 1; -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:00:00 | 0.0 | -+---------------------+-------+ ++---------------------+-----------------------------------+ +| time | time / Float64(1000) > Float64(1) | ++---------------------+-----------------------------------+ +| 1970-01-01T00:00:00 | 0.0 | ++---------------------+-----------------------------------+ tql eval (1000, 1000, '1s') time() + time(); -+---------------------+--------+ -| time | value | -+---------------------+--------+ -| 1970-01-01T00:16:40 | 2000.0 | -+---------------------+--------+ ++---------------------+-----------------------------------------------------+ +| time | lhs.time / Float64(1000) + rhs.time / Float64(1000) | ++---------------------+-----------------------------------------------------+ +| 1970-01-01T00:16:40 | 2000.0 | ++---------------------+-----------------------------------------------------+ -- expect error: parse error: comparisons between scalars must use BOOL modifier tql eval (1000, 1000, '1s') time() == time(); @@ -78,19 +94,19 @@ Error: 2000(InvalidSyntax), comparisons between scalars must use BOOL modifier tql eval (1000, 1000, '1s') time() == bool time(); -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:16:40 | 1.0 | -+---------------------+-------+ ++---------------------+-----------------------------------------------------+ +| time | lhs.time / Float64(1000) = rhs.time / Float64(1000) | ++---------------------+-----------------------------------------------------+ +| 1970-01-01T00:16:40 | 1.0 | ++---------------------+-----------------------------------------------------+ tql eval (1000, 1000, '1s') time() != bool time(); -+---------------------+-------+ -| time | value | -+---------------------+-------+ -| 1970-01-01T00:16:40 | 0.0 | -+---------------------+-------+ ++---------------------+------------------------------------------------------+ +| time | lhs.time / Float64(1000) != rhs.time / Float64(1000) | ++---------------------+------------------------------------------------------+ +| 1970-01-01T00:16:40 | 0.0 | ++---------------------+------------------------------------------------------+ -- time() with table create table metrics (ts timestamp time index, val double); @@ -103,57 +119,62 @@ Affected Rows: 4 tql eval (1, 2, '1s') time() + metrics; -+---------------------+--------------------------+ -| ts | ts / Float64(1000) + val | -+---------------------+--------------------------+ -| 1970-01-01T00:00:01 | 2.0 | -| 1970-01-01T00:00:02 | 4.0 | -+---------------------+--------------------------+ ++---------------------+-------------------------------------+ +| ts | .time / Float64(1000) + metrics.val | ++---------------------+-------------------------------------+ +| 1970-01-01T00:00:01 | 2.0 | +| 1970-01-01T00:00:02 | 4.0 | ++---------------------+-------------------------------------+ +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') time() == metrics; -+---------------------+-----+ -| ts | val | -+---------------------+-----+ -| 1970-01-01T00:00:01 | 1.0 | -| 1970-01-01T00:00:02 | 2.0 | -+---------------------+-----+ ++---------------------+----------------------+---------------------+-----+ +| time | time / Float64(1000) | ts | val | ++---------------------+----------------------+---------------------+-----+ +| 1970-01-01T00:00:01 | 1.0 | 1970-01-01T00:00:01 | 1.0 | +| 1970-01-01T00:00:02 | 2.0 | 1970-01-01T00:00:02 | 2.0 | ++---------------------+----------------------+---------------------+-----+ +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') time() == bool metrics; -+---------------------+--------------------------+ -| ts | ts / Float64(1000) = val | -+---------------------+--------------------------+ -| 1970-01-01T00:00:01 | 1.0 | -| 1970-01-01T00:00:02 | 1.0 | -+---------------------+--------------------------+ ++---------------------+-------------------------------------+ +| ts | .time / Float64(1000) = metrics.val | ++---------------------+-------------------------------------+ +| 1970-01-01T00:00:01 | 1.0 | +| 1970-01-01T00:00:02 | 1.0 | ++---------------------+-------------------------------------+ +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics + time(); -+---------------------+--------------------------+ -| ts | val + ts / Float64(1000) | -+---------------------+--------------------------+ -| 1970-01-01T00:00:01 | 2.0 | -| 1970-01-01T00:00:02 | 4.0 | -+---------------------+--------------------------+ ++---------------------+-------------------------------------+ +| time | metrics.val + .time / Float64(1000) | ++---------------------+-------------------------------------+ +| 1970-01-01T00:00:01 | 2.0 | +| 1970-01-01T00:00:02 | 4.0 | ++---------------------+-------------------------------------+ +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics == time(); -+---------------------+-----+ -| ts | val | -+---------------------+-----+ -| 1970-01-01T00:00:01 | 1.0 | -| 1970-01-01T00:00:02 | 2.0 | -+---------------------+-----+ ++---------------------+-----+---------------------+----------------------+ +| ts | val | time | time / Float64(1000) | ++---------------------+-----+---------------------+----------------------+ +| 1970-01-01T00:00:01 | 1.0 | 1970-01-01T00:00:01 | 1.0 | +| 1970-01-01T00:00:02 | 2.0 | 1970-01-01T00:00:02 | 2.0 | ++---------------------+-----+---------------------+----------------------+ +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics == bool time(); -+---------------------+--------------------------+ -| ts | val = ts / Float64(1000) | -+---------------------+--------------------------+ -| 1970-01-01T00:00:01 | 1.0 | -| 1970-01-01T00:00:02 | 1.0 | -+---------------------+--------------------------+ ++---------------------+-------------------------------------+ +| time | metrics.val = .time / Float64(1000) | ++---------------------+-------------------------------------+ +| 1970-01-01T00:00:01 | 1.0 | +| 1970-01-01T00:00:02 | 1.0 | ++---------------------+-------------------------------------+ -- other time-related functions tql eval (1, 2, '1s') hour(); diff --git a/tests/cases/standalone/common/promql/time_fn.sql b/tests/cases/standalone/common/promql/time_fn.sql index c89f4291bc..3307e74032 100644 --- a/tests/cases/standalone/common/promql/time_fn.sql +++ b/tests/cases/standalone/common/promql/time_fn.sql @@ -14,6 +14,10 @@ tql eval (0, 0, '1s') time() + 1; tql eval (0, 0, '1s') 1 + time(); +tql eval (10000, 10000, '1s') time() * time(); + +tql eval (10000, 10000, '1s') time() / time(); + -- expect error: parse error: comparisons between scalars must use BOOL modifier tql eval (0, 0, '1s') time() < 1; @@ -38,14 +42,19 @@ insert into metrics values (0, 0), (1000, 1), (2000, 2), (3000, 3); tql eval (1, 2, '1s') time() + metrics; +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') time() == metrics; +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') time() == bool metrics; +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics + time(); +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics == time(); +-- SQLNESS SORT_RESULT 3 1 tql eval (1, 2, '1s') metrics == bool time(); -- other time-related functions diff --git a/tests/cases/standalone/common/promql/timestamp_fn.result b/tests/cases/standalone/common/promql/timestamp_fn.result index a4b2b55e56..cb2f2306c2 100644 --- a/tests/cases/standalone/common/promql/timestamp_fn.result +++ b/tests/cases/standalone/common/promql/timestamp_fn.result @@ -95,13 +95,13 @@ tql eval (0, 60, '30s') timestamp(timestamp_test) > bool 30; -- Test timestamp() with time functions tql eval (0, 60, '30s') timestamp(timestamp_test) - time(); -+---------------------+----------------------------+ -| ts | value - ts / Float64(1000) | -+---------------------+----------------------------+ -| 1970-01-01T00:00:00 | 0.0 | -| 1970-01-01T00:00:30 | -29.0 | -| 1970-01-01T00:01:00 | 0.0 | -+---------------------+----------------------------+ ++---------------------+----------------------------------------------+ +| time | timestamp_test.value - .time / Float64(1000) | ++---------------------+----------------------------------------------+ +| 1970-01-01T00:00:00 | 0.0 | +| 1970-01-01T00:00:30 | -29.0 | +| 1970-01-01T00:01:00 | 0.0 | ++---------------------+----------------------------------------------+ -- Test timestamp() with other functions tql eval (0, 60, '30s') abs(timestamp(timestamp_test) - avg(timestamp(timestamp_test))) > 20;