Tracked findings from lowering a common set of topk-shaped SQL and PromQL queries (#20–#25) point to two structural gaps in how L3 IR is produced today.
1. Cross-language equivalence tests
Semantically equivalent SQL and PromQL queries should produce identical L3 IR. Right now there are no tests asserting this, so the two lowerers can drift silently.
Concretely: lower_sql(S2) == lower_promql(P1) should hold — both express "top-k series by count". The existing promql_equivalence.rs is the right home.
These tests cost nothing to add and act as the spec for what L3 is supposed to look like. Write them first, let them fail, then fix the lowerers.
2. Shared post-lowering canonicalization pass
The heavy-hitter gate (detect count-ranked topk → emit Aggregate(TopK)) is duplicated across the SQL and PromQL lowerers with slightly different recognition logic. That's why:
A single canonicalize(expr: QueryExpr) -> QueryExpr that both lowerers pass their output through fixes S1, closes the S2/P1 structural gap, and ensures future language paths get the normalization for free.
Order
Write the equivalence tests first (they document the intended canonical form). Then implement the canonicalization pass until the tests pass.
Related
Tracked findings from lowering a common set of topk-shaped SQL and PromQL queries (#20–#25) point to two structural gaps in how L3 IR is produced today.
1. Cross-language equivalence tests
Semantically equivalent SQL and PromQL queries should produce identical L3 IR. Right now there are no tests asserting this, so the two lowerers can drift silently.
Concretely:
lower_sql(S2) == lower_promql(P1)should hold — both express "top-k series by count". The existingpromql_equivalence.rsis the right home.These tests cost nothing to add and act as the spec for what L3 is supposed to look like. Write them first, let them fail, then fix the lowerers.
2. Shared post-lowering canonicalization pass
The heavy-hitter gate (detect count-ranked topk → emit
Aggregate(TopK)) is duplicated across the SQL and PromQL lowerers with slightly different recognition logic. That's why:ORDER BY alias DESC LIMIT k) slips through in SQL but S2 (ORDER BY COUNT(*) DESC LIMIT k) doesn't (SQL heavy-hitter gate misses count-ranked topk when COUNT is aliased #20)A single
canonicalize(expr: QueryExpr) -> QueryExprthat both lowerers pass their output through fixes S1, closes the S2/P1 structural gap, and ensures future language paths get the normalization for free.Order
Write the equivalence tests first (they document the intended canonical form). Then implement the canonicalization pass until the tests pass.
Related
topk byover instant vector errorstopkover cross-series agg unsupported