From 09f3d72d2dd20d6df56ab7871bf817bd7e1da9f0 Mon Sep 17 00:00:00 2001 From: yihong Date: Thu, 24 Jul 2025 11:30:59 +0800 Subject: [PATCH] fix: closee issue #6555 return empty result (#6569) * fix: closee issue #6555 return empty result Signed-off-by: yihong0618 * fix: only start one instance one regrex sqlness test (#6570) Signed-off-by: yihong0618 * refactor: refactor partition mod to use PartitionExpr instead of PartitionDef (#6554) * refactor: refactor partition mod to use PartitionExpr instead of PartitionDef Signed-off-by: Zhenchi * fix snafu Signed-off-by: Zhenchi * Puts expression into PbPartition Signed-off-by: Zhenchi * address comments Signed-off-by: Zhenchi * fix compile Signed-off-by: Zhenchi * update proto Signed-off-by: Zhenchi * add serde test Signed-off-by: Zhenchi * add serde test Signed-off-by: Zhenchi --------- Signed-off-by: Zhenchi * fix: address comments Signed-off-by: yihong0618 --------- Signed-off-by: yihong0618 Signed-off-by: Zhenchi Co-authored-by: Zhenchi Signed-off-by: evenyag --- src/query/src/promql/planner.rs | 61 +++++++++++++++++-- .../common/promql/simple_histogram.result | 31 ++++++++++ .../common/promql/simple_histogram.sql | 17 ++++++ 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/query/src/promql/planner.rs b/src/query/src/promql/planner.rs index 09eaf1c879..a5d7ce38ca 100644 --- a/src/query/src/promql/planner.rs +++ b/src/query/src/promql/planner.rs @@ -2334,10 +2334,14 @@ impl PromPlanner { let input_plan = self.prom_expr_to_plan(&input, session_state).await?; if !self.ctx.has_le_tag() { - return ColumnNotFoundSnafu { - col: LE_COLUMN_NAME.to_string(), - } - .fail(); + // Return empty result instead of error when 'le' column is not found + // This handles the case when histogram metrics don't exist + return Ok(LogicalPlan::EmptyRelation( + datafusion::logical_expr::EmptyRelation { + produce_one_row: false, + schema: Arc::new(DFSchema::empty()), + }, + )); } let time_index_column = self.ctx @@ -4728,4 +4732,53 @@ Filter: up.field_0 IS NOT NULL [timestamp:Timestamp(Millisecond, None), field_0: assert_eq!(plan.display_indent_schema().to_string(), expected); } + + #[tokio::test] + async fn test_histogram_quantile_missing_le_column() { + let mut eval_stmt = EvalStmt { + expr: PromExpr::NumberLiteral(NumberLiteral { val: 1.0 }), + start: UNIX_EPOCH, + end: UNIX_EPOCH + .checked_add(Duration::from_secs(100_000)) + .unwrap(), + interval: Duration::from_secs(5), + lookback_delta: Duration::from_secs(1), + }; + + // Test case: histogram_quantile with a table that doesn't have 'le' column + let case = r#"histogram_quantile(0.99, sum by(pod,instance,le) (rate(non_existent_histogram_bucket{instance=~"xxx"}[1m])))"#; + + let prom_expr = parser::parse(case).unwrap(); + eval_stmt.expr = prom_expr; + + // Create a table provider with a table that doesn't have 'le' column + let table_provider = build_test_table_provider_with_fields( + &[( + DEFAULT_SCHEMA_NAME.to_string(), + "non_existent_histogram_bucket".to_string(), + )], + &["pod", "instance"], // Note: no 'le' column + ) + .await; + + // Should return empty result instead of error + let result = + PromPlanner::stmt_to_plan(table_provider, &eval_stmt, &build_session_state()).await; + + // This should succeed now (returning empty result) instead of failing with "Cannot find column le" + assert!( + result.is_ok(), + "Expected successful plan creation with empty result, but got error: {:?}", + result.err() + ); + + // Verify that the result is an EmptyRelation + let plan = result.unwrap(); + match plan { + LogicalPlan::EmptyRelation(_) => { + // This is what we expect + } + _ => panic!("Expected EmptyRelation, but got: {:?}", plan), + } + } } diff --git a/tests/cases/standalone/common/promql/simple_histogram.result b/tests/cases/standalone/common/promql/simple_histogram.result index 96ef263ad5..1409e7834a 100644 --- a/tests/cases/standalone/common/promql/simple_histogram.result +++ b/tests/cases/standalone/common/promql/simple_histogram.result @@ -332,3 +332,34 @@ drop table histogram4_bucket; Affected Rows: 0 +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, fff) (rate(greptime_servers_postgres_query_elapsed_bucket{instance=~"xxx"}[1m]))); + +++ +++ + +-- test case where table exists but doesn't have 'le' column should raise error +CREATE TABLE greptime_servers_postgres_query_elapsed_no_le ( + pod STRING, + instance STRING, + t TIMESTAMP TIME INDEX, + v DOUBLE, + PRIMARY KEY (pod, instance) +); + +Affected Rows: 0 + +-- should return empty result instead of error when 'le' column is missing +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, le) (rate(greptime_servers_postgres_query_elapsed_no_le{instance=~"xxx"}[1m]))); + +++ +++ + +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, fbf) (rate(greptime_servers_postgres_query_elapsed_no_le{instance=~"xxx"}[1m]))); + +++ +++ + +drop table greptime_servers_postgres_query_elapsed_no_le; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/promql/simple_histogram.sql b/tests/cases/standalone/common/promql/simple_histogram.sql index 1a085c1dfd..d6dde4cb69 100644 --- a/tests/cases/standalone/common/promql/simple_histogram.sql +++ b/tests/cases/standalone/common/promql/simple_histogram.sql @@ -187,3 +187,20 @@ insert into histogram4_bucket values tql eval (2900, 3000, '100s') histogram_quantile(0.9, histogram4_bucket); drop table histogram4_bucket; + +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, fff) (rate(greptime_servers_postgres_query_elapsed_bucket{instance=~"xxx"}[1m]))); + +-- test case where table exists but doesn't have 'le' column should raise error +CREATE TABLE greptime_servers_postgres_query_elapsed_no_le ( + pod STRING, + instance STRING, + t TIMESTAMP TIME INDEX, + v DOUBLE, + PRIMARY KEY (pod, instance) +); + +-- should return empty result instead of error when 'le' column is missing +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, le) (rate(greptime_servers_postgres_query_elapsed_no_le{instance=~"xxx"}[1m]))); +tql eval(0, 10, '10s') histogram_quantile(0.99, sum by(pod,instance, fbf) (rate(greptime_servers_postgres_query_elapsed_no_le{instance=~"xxx"}[1m]))); + +drop table greptime_servers_postgres_query_elapsed_no_le;