fix: handle PromQL time binary aggregation (#8398)

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
This commit is contained in:
jeremyhi
2026-07-02 19:18:58 +08:00
committed by GitHub
parent ba073045e2
commit fc7a9bf56d
3 changed files with 66 additions and 2 deletions

View File

@@ -2465,8 +2465,10 @@ impl PromPlanner {
plan: &LogicalPlan,
out: &mut BTreeSet<String>,
) -> Result<()> {
if let LogicalPlan::TableScan(scan) = plan {
let table = planner.table_from_source(&scan.source)?;
// Derived PromQL plans may contain non-Greptime scans without row-key metadata.
if let LogicalPlan::TableScan(scan) = plan
&& let Ok(table) = planner.table_from_source(&scan.source)
{
for col in table.table_info().meta.row_key_column_names() {
if col != DATA_SCHEMA_TABLE_ID_COLUMN_NAME
&& col != DATA_SCHEMA_TSID_COLUMN_NAME
@@ -6576,6 +6578,51 @@ mod test {
assert!(!aggr_line.contains(DATA_SCHEMA_TSID_COLUMN_NAME));
}
#[tokio::test]
async fn aggregate_over_binary_time_function_expr() {
for op in ["sum", "min", "max", "avg"] {
let prom_expr = parser::parse(&format!(
"{op} by (tag_0, tag_1, tag_2) (time() - some_metric)"
))
.unwrap();
let eval_stmt = EvalStmt {
expr: prom_expr,
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),
};
let table_provider = build_test_table_provider_with_tsid(
&[(DEFAULT_SCHEMA_NAME.to_string(), "some_metric".to_string())],
3,
1,
)
.await;
let plan =
PromPlanner::stmt_to_plan(table_provider, &eval_stmt, &build_query_engine_state())
.await
.unwrap();
let plan_str = plan.display_indent_schema().to_string();
let aggr_line = plan_str
.lines()
.find(|line| line.contains("Aggregate: groupBy="))
.unwrap();
assert!(aggr_line.contains(op), "{plan_str}");
assert!(aggr_line.contains("first_value"), "{plan_str}");
assert!(
!plan
.schema()
.fields()
.iter()
.any(|field| { field.name() == DATA_SCHEMA_TSID_COLUMN_NAME })
);
}
}
#[tokio::test]
async fn topk_by_does_not_partition_by_tsid() {
let prom_expr = parser::parse("topk by (__tsid) (1, some_metric)").unwrap();

View File

@@ -691,6 +691,19 @@ TQL EVAL (0, 5, '5s') rate(tsid_binary_join_left[5s]) / tsid_binary_join_left;
+------+-----+----+----------------------------------------------------------------------------+
+------+-----+----+----------------------------------------------------------------------------+
-- Regression for aggregating a binary expression over `time()` and a TSID-backed metric.
-- SQLNESS SORT_RESULT 3 1
TQL EVAL (0, 5, '5s') sum by (host, job) (time() - tsid_binary_join_left);
+-------+------+---------------------+-------------------------------------------------------------------+
| host | job | ts | sum(.time / Float64(1000) - tsid_binary_join_left.greptime_value) |
+-------+------+---------------------+-------------------------------------------------------------------+
| host1 | job1 | 1970-01-01T00:00:00 | -12.0 |
| host1 | job1 | 1970-01-01T00:00:05 | -10.0 |
| host2 | job2 | 1970-01-01T00:00:00 | -18.0 |
| host2 | job2 | 1970-01-01T00:00:05 | -16.0 |
+-------+------+---------------------+-------------------------------------------------------------------+
DROP TABLE tsid_binary_join_third;
Affected Rows: 0

View File

@@ -252,6 +252,10 @@ TQL EVAL (0, 5, '5s') (tsid_binary_join_left or tsid_binary_join_right) / tsid_b
-- SQLNESS SORT_RESULT 3 1
TQL EVAL (0, 5, '5s') rate(tsid_binary_join_left[5s]) / tsid_binary_join_left;
-- Regression for aggregating a binary expression over `time()` and a TSID-backed metric.
-- SQLNESS SORT_RESULT 3 1
TQL EVAL (0, 5, '5s') sum by (host, job) (time() - tsid_binary_join_left);
DROP TABLE tsid_binary_join_third;
DROP TABLE tsid_binary_join_right_by_job;
DROP TABLE tsid_binary_join_right;