-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
SQL: Fix ORDER BY YEAR() function #51562
Changes from 5 commits
34d31f3
94251c9
2aa1aee
1875e76
801ca3e
e50c2fd
88553db
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 |
---|---|---|
|
@@ -22,6 +22,9 @@ | |
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction; | ||
import org.elasticsearch.xpack.ql.expression.function.grouping.GroupingFunction; | ||
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction; | ||
import org.elasticsearch.xpack.ql.expression.predicate.logical.BinaryLogic; | ||
import org.elasticsearch.xpack.ql.expression.predicate.logical.Not; | ||
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparison; | ||
import org.elasticsearch.xpack.ql.plan.logical.Aggregate; | ||
import org.elasticsearch.xpack.ql.plan.logical.Filter; | ||
import org.elasticsearch.xpack.ql.plan.logical.Limit; | ||
|
@@ -39,6 +42,8 @@ | |
import org.elasticsearch.xpack.sql.expression.function.aggregate.Max; | ||
import org.elasticsearch.xpack.sql.expression.function.aggregate.Min; | ||
import org.elasticsearch.xpack.sql.expression.function.aggregate.TopHits; | ||
import org.elasticsearch.xpack.sql.expression.predicate.nulls.IsNotNull; | ||
import org.elasticsearch.xpack.sql.expression.predicate.nulls.IsNull; | ||
import org.elasticsearch.xpack.sql.plan.logical.Distinct; | ||
import org.elasticsearch.xpack.sql.plan.logical.LocalRelation; | ||
import org.elasticsearch.xpack.sql.plan.logical.Pivot; | ||
|
@@ -253,7 +258,7 @@ Collection<Failure> verify(LogicalPlan plan) { | |
} | ||
|
||
checkForScoreInsideFunctions(p, localFailures); | ||
checkNestedUsedInGroupByOrHaving(p, localFailures); | ||
checkNestedUsedInGroupByOrHavingOrWhereOrOrderBy(p, localFailures, attributeRefs); | ||
checkForGeoFunctionsOnDocValues(p, localFailures); | ||
checkPivot(p, localFailures, attributeRefs); | ||
|
||
|
@@ -722,33 +727,61 @@ private static void checkForScoreInsideFunctions(LogicalPlan p, Set<Failure> loc | |
Function.class)); | ||
} | ||
|
||
private static void checkNestedUsedInGroupByOrHaving(LogicalPlan p, Set<Failure> localFailures) { | ||
private static void checkNestedUsedInGroupByOrHavingOrWhereOrOrderBy(LogicalPlan p, Set<Failure> localFailures, | ||
AttributeMap<Expression> attributeRefs) { | ||
List<FieldAttribute> nested = new ArrayList<>(); | ||
Consumer<FieldAttribute> match = fa -> { | ||
Consumer<FieldAttribute> matchNested = fa -> { | ||
if (fa.isNested()) { | ||
nested.add(fa); | ||
} | ||
}; | ||
Consumer<Expression> checkForNested = e -> | ||
attributeRefs.getOrDefault(e, e).forEachUp(matchNested, FieldAttribute.class); | ||
Consumer<ScalarFunction> checkForNestedInFcuntion = f -> f.arguments().forEach( | ||
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. Typo in the variable name: |
||
arg -> arg.forEachUp(matchNested, FieldAttribute.class)); | ||
|
||
// nested fields shouldn't be used in aggregates or having (yet) | ||
p.forEachDown(a -> a.groupings().forEach(agg -> agg.forEachUp(match, FieldAttribute.class)), Aggregate.class); | ||
|
||
p.forEachDown(a -> a.groupings().forEach(agg -> agg.forEachUp(checkForNested)), Aggregate.class); | ||
if (!nested.isEmpty()) { | ||
localFailures.add( | ||
fail(nested.get(0), "Grouping isn't (yet) compatible with nested fields " + new AttributeSet(nested).names())); | ||
nested.clear(); | ||
} | ||
|
||
// check in having | ||
p.forEachDown(f -> { | ||
if (f.child() instanceof Aggregate) { | ||
f.condition().forEachUp(match, FieldAttribute.class); | ||
} | ||
}, Filter.class); | ||
|
||
p.forEachDown(f -> f.forEachDown(a -> f.condition().forEachUp(checkForNested), Aggregate.class), Filter.class); | ||
if (!nested.isEmpty()) { | ||
localFailures.add( | ||
fail(nested.get(0), "HAVING isn't (yet) compatible with nested fields " + new AttributeSet(nested).names())); | ||
nested.clear(); | ||
} | ||
|
||
// check in where (scalars not allowed) | ||
p.forEachDown(f -> f.condition().forEachUp(e -> | ||
attributeRefs.getOrDefault(e, e).forEachUp(sf -> { | ||
if (sf instanceof BinaryComparison == false && | ||
sf instanceof IsNull == false && | ||
sf instanceof IsNotNull == false && | ||
sf instanceof Not == false && | ||
sf instanceof BinaryLogic== false) { | ||
checkForNestedInFcuntion.accept(sf); | ||
}}, ScalarFunction.class) | ||
), Filter.class); | ||
if (!nested.isEmpty()) { | ||
localFailures.add( | ||
fail(nested.get(0), "WHERE isn't (yet) compatible with scalar functions on nested fields " + | ||
new AttributeSet(nested).names())); | ||
nested.clear(); | ||
} | ||
|
||
// check in order by (scalars not allowed) | ||
p.forEachDown(ob -> ob.order().forEach(o -> o.forEachUp(e -> | ||
attributeRefs.getOrDefault(e, e).forEachUp(checkForNestedInFcuntion, ScalarFunction.class) | ||
)), OrderBy.class); | ||
if (!nested.isEmpty()) { | ||
localFailures.add( | ||
fail(nested.get(0), "ORDER BY isn't (yet) compatible with scalar functions on nested fields " + | ||
new AttributeSet(nested).names())); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -695,21 +695,8 @@ protected PhysicalPlan rule(OrderExec plan) { | |
// scalar functions typically require script ordering | ||
if (orderExpression instanceof ScalarFunction) { | ||
ScalarFunction sf = (ScalarFunction) orderExpression; | ||
// is there an expression to order by? | ||
if (sf.orderBy() != null) { | ||
Expression orderBy = sf.orderBy(); | ||
if (orderBy instanceof NamedExpression) { | ||
orderBy = qContainer.aliases().getOrDefault(orderBy, orderBy); | ||
qContainer = qContainer | ||
.addSort(new AttributeSort(((NamedExpression) orderBy).toAttribute(), direction, missing)); | ||
} else if (orderBy.foldable() == false) { | ||
// ignore constant | ||
throw new PlanningException("does not know how to order by expression {}", orderBy); | ||
} | ||
} else { | ||
Comment on lines
-699
to
-709
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. I don't understand why this logic is removed. We removed the faulty support for sorting on nested fields that needs scripting, but why is this block of code associated with nested fields? 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 code was especially for Scalar Functions in case the |
||
// nope, use scripted sorting | ||
qContainer = qContainer.addSort(new ScriptSort(sf.asScript(), direction, missing)); | ||
} | ||
// nope, use scripted sorting | ||
qContainer = qContainer.addSort(new ScriptSort(sf.asScript(), direction, missing)); | ||
} | ||
// score | ||
else if (orderExpression instanceof Score) { | ||
|
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.
Capital letters for
length
?