-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Fix UnresolvedException on PromQL by(step) grouping #145307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,7 +55,7 @@ public class PromqlCommand extends UnaryPlan | |
| /** | ||
| * The name of the column containing the step value (aka time bucket) in range queries. | ||
| */ | ||
| public static final String STEP_COLUMN_NAME = "step"; | ||
| private static final String STEP_COLUMN_NAME = "step"; | ||
|
|
||
| private final LogicalPlan promqlPlan; | ||
| private final Literal start; | ||
|
|
@@ -407,6 +407,21 @@ public void postAnalysisVerification(Failures failures) { | |
| if (agg.grouping() == AcrossSeriesAggregate.Grouping.WITHOUT && usesWithoutGrouping(agg.child())) { | ||
| failures.add(fail(agg, "nested WITHOUT over WITHOUT is not supported at this time [{}]", agg.sourceText())); | ||
| } | ||
| // Reject labels whose name collides with the built-in step column. | ||
| // If this proves too restrictive, we could add an option to rename the built-in step column. | ||
| for (Attribute grouping : agg.groupings()) { | ||
| if (stepColumnName().equals(grouping.name())) { | ||
| failures.add( | ||
| fail( | ||
| agg, | ||
| "label [{}] collides with the built-in [{}] output column [{}]", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine as a stopgap, but I wonder if we can differentiate between the two. Maybe we can implicitly add an alias to the label, to avoid the conflict?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What do you have in mind there? That'll still change the name of the output column, so I'm not sure if that'll work. |
||
| stepColumnName(), | ||
| stepColumnName(), | ||
| agg.sourceText() | ||
| ) | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| case PromqlFunctionCall functionCall -> { | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
|
|
||
| package org.elasticsearch.xpack.esql.optimizer.promql; | ||
|
|
||
| import org.elasticsearch.xpack.esql.VerificationException; | ||
| import org.elasticsearch.xpack.esql.core.expression.Alias; | ||
| import org.elasticsearch.xpack.esql.core.expression.Attribute; | ||
| import org.elasticsearch.xpack.esql.core.expression.Expressions; | ||
|
|
@@ -83,6 +84,18 @@ public void testNonExistentFieldsOptimizesToEmptyPlan() { | |
| }); | ||
| } | ||
|
|
||
| public void testGroupByStepCollision() { | ||
| // "step" as a BY label collides with the built-in step output column. | ||
| // If this proves too restrictive, we could add an option to rename the built-in step column. | ||
| for (String query : List.of( | ||
| "PROMQL index=k8s step=1m result=(sum by (step) (network.eth0.rx))", | ||
| "PROMQL index=k8s step=1m result=(sum by (step, pod) (network.eth0.rx))" | ||
| )) { | ||
| var e = expectThrows(VerificationException.class, () -> planPromql(query)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this converted to 4xx or 5xx? Can't recall where the mapping is defined.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validation errors are always client errors (4xx). |
||
| assertThat(e.getMessage(), containsString("label [step] collides with the built-in [step] output column")); | ||
| } | ||
| } | ||
|
|
||
| public void testGroupByNonExistentLabel() { | ||
| var plan = planPromql("PROMQL index=k8s step=1m result=(sum by (non_existent_label) (network.eth0.rx))"); | ||
| // equivalent to avg(network.eth0.rx) since the label does not exist | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@felixbarny , I know this is already merged, but this doesn't look right. Unresolved attributes must not be present when output is called.
The javadoc for the output method states:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't the primary fix but a defensive check. Maybe too defensive in this case...
Maybe better to fail early or add something like an
assert resolved()here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've created a PR to add the assert: #145525