diff --git a/src/promql/src/extension_plan/empty_metric.rs b/src/promql/src/extension_plan/empty_metric.rs index f4c33cf30f63..74d25d8ebb8f 100644 --- a/src/promql/src/extension_plan/empty_metric.rs +++ b/src/promql/src/extension_plan/empty_metric.rs @@ -104,8 +104,8 @@ impl EmptyMetric { .map(|expr| { physical_planner.create_physical_expr( expr, - &self.result_schema, - &ArrowSchema::from(self.result_schema.as_ref()), + &self.time_index_schema, + &ArrowSchema::from(self.time_index_schema.as_ref()), session_state, ) }) diff --git a/src/promql/src/planner.rs b/src/promql/src/planner.rs index e8d9d79bc6d5..17d222c2aa58 100644 --- a/src/promql/src/planner.rs +++ b/src/promql/src/planner.rs @@ -77,6 +77,10 @@ const DEFAULT_FIELD_COLUMN: &str = "value"; /// Special modifier to project field columns under multi-field mode const FIELD_COLUMN_MATCHER: &str = "__field__"; +/// default value column name for prometheus metrics. +/// This is the same with the constant defined in `servers` +const GREPTIME_VALUE: &str = "greptime_value"; + #[derive(Default, Debug, Clone)] struct PromPlannerContext { // query parameters @@ -292,13 +296,13 @@ impl PromPlanner { let left_field_columns = self.ctx.field_columns.clone(); let left_table_ref: OwnedTableReference = self.ctx.table_name.clone().unwrap_or_default().into(); - let left_tag_cols = self.ctx.tag_columns.clone(); + let left_context = self.ctx.clone(); let right_input = self.prom_expr_to_plan(*rhs.clone()).await?; let right_field_columns = self.ctx.field_columns.clone(); let right_table_ref: OwnedTableReference = self.ctx.table_name.clone().unwrap_or_default().into(); - let right_tag_cols = self.ctx.tag_columns.clone(); + let right_context = self.ctx.clone(); // TODO(ruihang): avoid join if left and right are the same table @@ -307,8 +311,8 @@ impl PromPlanner { return self.set_op_on_non_field_columns( left_input, right_input, - left_tag_cols, - right_tag_cols, + left_context, + right_context, *op, modifier, ); @@ -1333,6 +1337,8 @@ impl PromPlanner { // reuse `SPECIAL_TIME_FUNCTION` as name of time index column self.ctx.time_index_column = Some(SPECIAL_TIME_FUNCTION.to_string()); self.ctx.table_name = Some(String::new()); + self.ctx.tag_columns = vec![]; + self.ctx.field_columns = vec![GREPTIME_VALUE.to_string()]; Ok(LogicalPlan::Extension(Extension { node: Arc::new( EmptyMetric::new( @@ -1340,7 +1346,7 @@ impl PromPlanner { self.ctx.end, self.ctx.interval, SPECIAL_TIME_FUNCTION.to_string(), - DEFAULT_FIELD_COLUMN.to_string(), + GREPTIME_VALUE.to_string(), Some(DfExpr::Literal(ScalarValue::Float64(Some(lit)))), ) .context(DataFusionPlanningSnafu)?, @@ -1536,19 +1542,35 @@ impl PromPlanner { /// Build a set operator (AND/OR/UNLESS) fn set_op_on_non_field_columns( - &self, + &mut self, left: LogicalPlan, right: LogicalPlan, - left_tag_cols: Vec, - right_tag_cols: Vec, + left_context: PromPlannerContext, + right_context: PromPlannerContext, op: TokenType, modifier: &Option, ) -> Result { - let mut left_tag_col_set = left_tag_cols.into_iter().collect::>(); - let mut right_tag_col_set = right_tag_cols.into_iter().collect::>(); + let mut left_tag_col_set = left_context + .tag_columns + .iter() + .cloned() + .collect::>(); + let mut right_tag_col_set = right_context + .tag_columns + .iter() + .cloned() + .collect::>(); if matches!(op.id(), token::T_LOR) { - return self.or_operator(left, right, left_tag_col_set, right_tag_col_set, modifier); + return self.or_operator( + left, + right, + left_tag_col_set, + right_tag_col_set, + left_context, + right_context, + modifier, + ); } // apply modifier @@ -1630,19 +1652,22 @@ impl PromPlanner { .build() .context(DataFusionPlanningSnafu), token::T_LOR => { - self.or_operator(left, right, left_tag_col_set, right_tag_col_set, modifier) + unreachable!() } _ => UnexpectedTokenSnafu { token: op }.fail(), } } // TODO(ruihang): change function name + #[allow(clippy::too_many_arguments)] fn or_operator( - &self, + &mut self, left: LogicalPlan, right: LogicalPlan, left_tag_cols_set: HashSet, right_tag_cols_set: HashSet, + left_context: PromPlannerContext, + right_context: PromPlannerContext, modifier: &Option, ) -> Result { // prepare hash sets @@ -1668,18 +1693,37 @@ impl PromPlanner { .as_ref() .map(|r| r.to_string()) .unwrap_or_default(); + let left_time_index_column = + left_context + .time_index_column + .clone() + .with_context(|| TimeIndexNotFoundSnafu { + table: left_qualifier_string.clone(), + })?; + let right_time_index_column = + right_context + .time_index_column + .clone() + .with_context(|| TimeIndexNotFoundSnafu { + table: right_qualifier_string.clone(), + })?; // step 0: fill all columns in output schema - let all_columns_set = left + let mut all_columns_set = left .schema() .fields() .iter() .chain(right.schema().fields().iter()) .map(|field| field.name().clone()) .collect::>(); + // remove time index column + all_columns_set.remove(&left_time_index_column); + all_columns_set.remove(&right_time_index_column); let mut all_columns = all_columns_set.into_iter().collect::>(); // sort to ensure the generated schema is not volatile all_columns.sort_unstable(); + // use left time index column name as the result time index column name + all_columns.insert(0, left_time_index_column.clone()); // step 1: align schema using project, fill non-exist columns with null let left_proj_exprs = all_columns.iter().map(|col| { @@ -1689,13 +1733,21 @@ impl PromPlanner { DfExpr::Column(Column::new(left_qualifier.clone(), col)) } }); - let right_proj_exprs = all_columns.iter().map(|col| { + let right_time_index_expr = DfExpr::Column(Column::new( + right_qualifier.clone(), + right_time_index_column, + )) + .alias(left_time_index_column.clone()); + let right_proj_exprs_without_time_index = all_columns.iter().skip(1).map(|col| { if tags_not_in_right.contains(col) { DfExpr::Literal(ScalarValue::Utf8(None)).alias(col.to_string()) } else { DfExpr::Column(Column::new(right_qualifier.clone(), col)) } }); + let right_proj_exprs = [right_time_index_expr] + .into_iter() + .chain(right_proj_exprs_without_time_index); let left_projected = LogicalPlanBuilder::from(left) .project(left_proj_exprs) @@ -1736,13 +1788,17 @@ impl PromPlanner { left_projected, right_projected, match_columns, - self.ctx.time_index_column.clone().unwrap(), + left_time_index_column.clone(), schema, ); let result = LogicalPlan::Extension(Extension { node: Arc::new(union_distinct_on), }); + // step 4: update context + self.ctx.time_index_column = Some(left_time_index_column); + self.ctx.tag_columns = all_tags.into_iter().collect(); + Ok(result) } diff --git a/tests/cases/standalone/common/promql/set_operation.result b/tests/cases/standalone/common/promql/set_operation.result index 15a7a865a317..31a0a6638fd7 100644 --- a/tests/cases/standalone/common/promql/set_operation.result +++ b/tests/cases/standalone/common/promql/set_operation.result @@ -6,7 +6,7 @@ create table http_requests ( job string, instance string, g string, -- for `group` - val double, + greptime_value double, primary key (job, instance, g) ); @@ -32,7 +32,7 @@ Affected Rows: 0 create table vector_matching_a( ts timestamp time index, l string primary key, - val double, + greptime_value double, ); Affected Rows: 0 @@ -49,12 +49,12 @@ Affected Rows: 2 -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} and http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 0 | canary | 300.0 | -| 1970-01-01T00:50:00 | app | 0 | canary | 700.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 0 | canary | 300.0 | +| 1970-01-01T00:50:00 | app | 0 | canary | 700.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and http_requests{instance="0"} -- {group="canary", instance="0", job="api-server"} 301 @@ -62,12 +62,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} and http_requests{instance -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and http_requests{instance="0"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and on(instance, job) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -75,12 +75,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and http_requests{in -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance, job) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and on(instance) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -88,12 +88,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance, job -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -101,12 +101,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance) htt -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group, job) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -114,12 +114,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g) http -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g, job) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m http_requests{group="canary"} or http_requests{group="production"} -- http_requests{group="canary", instance="0", job="api-server"} 300 @@ -133,18 +133,18 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g, job) -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} or http_requests{g="production"}; -+------------+----------+-----+---------------------+-------+ -| g | instance | job | ts | val | -+------------+----------+-----+---------------------+-------+ -| canary | 0 | api | 1970-01-01T00:50:00 | 300.0 | -| canary | 0 | app | 1970-01-01T00:50:00 | 700.0 | -| canary | 1 | api | 1970-01-01T00:50:00 | 400.0 | -| canary | 1 | app | 1970-01-01T00:50:00 | 800.0 | -| production | 0 | api | 1970-01-01T00:50:00 | 100.0 | -| production | 0 | app | 1970-01-01T00:50:00 | 500.0 | -| production | 1 | api | 1970-01-01T00:50:00 | 200.0 | -| production | 1 | app | 1970-01-01T00:50:00 | 600.0 | -+------------+----------+-----+---------------------+-------+ ++---------------------+------------+----------------+----------+-----+ +| ts | g | greptime_value | instance | job | ++---------------------+------------+----------------+----------+-----+ +| 1970-01-01T00:50:00 | canary | 300.0 | 0 | api | +| 1970-01-01T00:50:00 | canary | 400.0 | 1 | api | +| 1970-01-01T00:50:00 | canary | 700.0 | 0 | app | +| 1970-01-01T00:50:00 | canary | 800.0 | 1 | app | +| 1970-01-01T00:50:00 | production | 100.0 | 0 | api | +| 1970-01-01T00:50:00 | production | 200.0 | 1 | api | +| 1970-01-01T00:50:00 | production | 500.0 | 0 | app | +| 1970-01-01T00:50:00 | production | 600.0 | 1 | app | ++---------------------+------------+----------------+----------+-----+ -- # On overlap the rhs samples must be dropped. -- eval instant at 50m (http_requests{group="canary"} + 1) or http_requests{instance="1"} @@ -157,7 +157,7 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} or http_requests{g="produc -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or http_requests{instance="1"}; -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named http_requests.val. Valid fields are http_requests.job, http_requests.instance, http_requests.g, http_requests.ts, "val + Float64(1)". +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named http_requests.greptime_value. Valid fields are http_requests.job, http_requests.instance, http_requests.g, http_requests.ts, "greptime_value + Float64(1)". -- # Matching only on instance excludes everything that has instance=0/1 but includes -- # entries without the instance label. @@ -172,7 +172,7 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- NOT SUPPORTED: `or` tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or on(instance) (http_requests or cpu_count or vector_matching_a); -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.val. Valid fields are cpu_count.ts. +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.greptime_value. Valid fields are cpu_count.ts. -- eval instant at 50m (http_requests{group="canary"} + 1) or ignoring(l, group, job) (http_requests or cpu_count or vector_matching_a) -- {group="canary", instance="0", job="api-server"} 301 @@ -185,7 +185,7 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- NOT SUPPORTED: `or` tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or ignoring(l, g, job) (http_requests or cpu_count or vector_matching_a); -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.val. Valid fields are cpu_count.ts. +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.greptime_value. Valid fields are cpu_count.ts. -- eval instant at 50m http_requests{group="canary"} unless http_requests{instance="0"} -- http_requests{group="canary", instance="1", job="api-server"} 400 @@ -193,12 +193,12 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m http_requests{group="canary"} unless on(job) http_requests{instance="0"} tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job) http_requests{instance="0"}; @@ -212,12 +212,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job) http_reques -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job, instance) http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m http_requests{group="canary"} unless ignoring(group, instance) http_requests{instance="0"} tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g, instance) http_requests{instance="0"}; @@ -231,12 +231,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g, instanc -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g) http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- # https://github.com/prometheus/prometheus/issues/1489 -- eval instant at 50m http_requests AND ON (dummy) vector(1) @@ -251,7 +251,7 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g) http_re -- NOT SUPPORTED: `vector()` tql eval (3000, 3000, '1s') http_requests AND ON (dummy) vector(1); -Error: 1004(InvalidArguments), Unsupported expr type: vector +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named time. Valid fields are http_requests.ts, http_requests.job, http_requests.instance, http_requests.g, http_requests.greptime_value. -- eval instant at 50m http_requests AND IGNORING (group, instance, job) vector(1) -- http_requests{group="canary", instance="0", job="api-server"} 300 @@ -265,7 +265,7 @@ Error: 1004(InvalidArguments), Unsupported expr type: vector -- NOT SUPPORTED: `vector()` tql eval (3000, 3000, '1s') http_requests AND IGNORING (g, instance, job) vector(1); -Error: 1004(InvalidArguments), Unsupported expr type: vector +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named time. Valid fields are http_requests.ts, http_requests.job, http_requests.instance, http_requests.g, http_requests.greptime_value. drop table http_requests; @@ -280,7 +280,7 @@ drop table vector_matching_a; Affected Rows: 0 -- the following cases are not from Prometheus. -create table t1 (ts timestamp time index, job string primary key, val double); +create table t1 (ts timestamp time index, job string primary key, greptime_value double); Affected Rows: 0 @@ -288,7 +288,7 @@ insert into t1 values (0, "a", 1.0), (500000, "b", 2.0), (1000000, "a", 3.0), (1 Affected Rows: 4 -create table t2 (ts timestamp time index, val double); +create table t2 (ts timestamp time index, greptime_value double); Affected Rows: 0 @@ -299,102 +299,102 @@ Affected Rows: 7 -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or on () t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or on (job) t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or on () t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or on(job) t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ drop table t1; diff --git a/tests/cases/standalone/common/promql/set_operation.sql b/tests/cases/standalone/common/promql/set_operation.sql index 6a71711bd896..521791a02c4f 100644 --- a/tests/cases/standalone/common/promql/set_operation.sql +++ b/tests/cases/standalone/common/promql/set_operation.sql @@ -7,7 +7,7 @@ create table http_requests ( job string, instance string, g string, -- for `group` - val double, + greptime_value double, primary key (job, instance, g) ); @@ -27,7 +27,7 @@ create table cpu_count(ts timestamp time index); create table vector_matching_a( ts timestamp time index, l string primary key, - val double, + greptime_value double, ); insert into vector_matching_a values @@ -176,11 +176,11 @@ drop table vector_matching_a; -- the following cases are not from Prometheus. -create table t1 (ts timestamp time index, job string primary key, val double); +create table t1 (ts timestamp time index, job string primary key, greptime_value double); insert into t1 values (0, "a", 1.0), (500000, "b", 2.0), (1000000, "a", 3.0), (1500000, "c", 4.0); -create table t2 (ts timestamp time index, val double); +create table t2 (ts timestamp time index, greptime_value double); insert into t2 values (0, 0), (300000, 0), (600000, 0), (900000, 0), (1200000, 0), (1500000, 0), (1800000, 0);