forked from elastic/elasticsearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SQL: refactor In predicate moving it to QL project (elastic#52870) (e…
…lastic#52938) * Move In, InPipe and InProcessor out of SQL to the common QL project. * Move tests classes to the QL project. * Create SQL dedicated In class to handle SQL specific data types. * Update SQL classes to use the InPipe and InProcessor QL classes. * Extract common Foldables methods in QL project. * Be more explicit when folding and converting a foldable value, by removing most of the code inside Foldables class. (cherry picked from commit 7425042)
- Loading branch information
Showing
21 changed files
with
270 additions
and
222 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/expression/Foldables.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.ql.expression; | ||
|
||
import org.elasticsearch.xpack.ql.QlIllegalArgumentException; | ||
|
||
public abstract class Foldables { | ||
|
||
public static Object valueOf(Expression e) { | ||
if (e.foldable()) { | ||
return e.fold(); | ||
} | ||
throw new QlIllegalArgumentException("Cannot determine value for {}", e); | ||
} | ||
} |
172 changes: 172 additions & 0 deletions
172
...src/main/java/org/elasticsearch/xpack/ql/expression/predicate/operator/comparison/In.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.ql.expression.predicate.operator.comparison; | ||
|
||
import org.elasticsearch.xpack.ql.expression.Expression; | ||
import org.elasticsearch.xpack.ql.expression.Expressions; | ||
import org.elasticsearch.xpack.ql.expression.Foldables; | ||
import org.elasticsearch.xpack.ql.expression.Nullability; | ||
import org.elasticsearch.xpack.ql.expression.TypeResolutions; | ||
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction; | ||
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe; | ||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate; | ||
import org.elasticsearch.xpack.ql.tree.NodeInfo; | ||
import org.elasticsearch.xpack.ql.tree.Source; | ||
import org.elasticsearch.xpack.ql.type.DataType; | ||
import org.elasticsearch.xpack.ql.type.DataTypeConverter; | ||
import org.elasticsearch.xpack.ql.type.DataTypes; | ||
import org.elasticsearch.xpack.ql.util.CollectionUtils; | ||
|
||
import java.util.ArrayList; | ||
import java.util.LinkedHashSet; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.stream.Collectors; | ||
|
||
import static org.elasticsearch.common.logging.LoggerMessageFormat.format; | ||
import static org.elasticsearch.xpack.ql.expression.gen.script.ParamsBuilder.paramsBuilder; | ||
import static org.elasticsearch.xpack.ql.util.StringUtils.ordinal; | ||
|
||
public class In extends ScalarFunction { | ||
|
||
private final Expression value; | ||
private final List<Expression> list; | ||
|
||
public In(Source source, Expression value, List<Expression> list) { | ||
super(source, CollectionUtils.combine(list, value)); | ||
this.value = value; | ||
this.list = new ArrayList<>(new LinkedHashSet<>(list)); | ||
} | ||
|
||
@Override | ||
protected NodeInfo<In> info() { | ||
return NodeInfo.create(this, In::new, value(), list()); | ||
} | ||
|
||
@Override | ||
public Expression replaceChildren(List<Expression> newChildren) { | ||
if (newChildren.size() < 2) { | ||
throw new IllegalArgumentException("expected at least [2] children but received [" + newChildren.size() + "]"); | ||
} | ||
return new In(source(), newChildren.get(newChildren.size() - 1), newChildren.subList(0, newChildren.size() - 1)); | ||
} | ||
|
||
public Expression value() { | ||
return value; | ||
} | ||
|
||
public List<Expression> list() { | ||
return list; | ||
} | ||
|
||
@Override | ||
public DataType dataType() { | ||
return DataTypes.BOOLEAN; | ||
} | ||
|
||
@Override | ||
public Nullability nullable() { | ||
return Nullability.UNKNOWN; | ||
} | ||
|
||
@Override | ||
public boolean foldable() { | ||
return Expressions.foldable(children()) || | ||
(Expressions.foldable(list) && list().stream().allMatch(Expressions::isNull)); | ||
} | ||
|
||
@Override | ||
public Boolean fold() { | ||
// Optimization for early return and Query folding to LocalExec | ||
if (Expressions.isNull(value) || list.size() == 1 && Expressions.isNull(list.get(0))) { | ||
return null; | ||
} | ||
return InProcessor.apply(value.fold(), foldAndConvertListOfValues(list, value.dataType())); | ||
} | ||
|
||
@Override | ||
public ScriptTemplate asScript() { | ||
ScriptTemplate leftScript = asScript(value); | ||
|
||
// fold & remove duplicates | ||
List<Object> values = new ArrayList<>(new LinkedHashSet<>(foldAndConvertListOfValues(list, value.dataType()))); | ||
|
||
return new ScriptTemplate( | ||
formatTemplate(format("{sql}.","in({}, {})", leftScript.template())), | ||
paramsBuilder() | ||
.script(leftScript.params()) | ||
.variable(values) | ||
.build(), | ||
dataType()); | ||
} | ||
|
||
protected List<Object> foldAndConvertListOfValues(List<Expression> list, DataType dataType) { | ||
List<Object> values = new ArrayList<>(list.size()); | ||
for (Expression e : list) { | ||
values.add(DataTypeConverter.convert(Foldables.valueOf(e), dataType)); | ||
} | ||
return values; | ||
} | ||
|
||
protected boolean areCompatible(DataType left, DataType right) { | ||
return DataTypes.areCompatible(left, right); | ||
} | ||
|
||
@Override | ||
protected Pipe makePipe() { | ||
return new InPipe(source(), this, children().stream().map(Expressions::pipe).collect(Collectors.toList())); | ||
} | ||
|
||
@Override | ||
protected TypeResolution resolveType() { | ||
TypeResolution resolution = TypeResolutions.isExact(value, functionName(), Expressions.ParamOrdinal.DEFAULT); | ||
if (resolution.unresolved()) { | ||
return resolution; | ||
} | ||
|
||
for (Expression ex : list) { | ||
if (ex.foldable() == false) { | ||
return new TypeResolution(format(null, "Comparisons against variables are not (currently) supported; offender [{}] in [{}]", | ||
Expressions.name(ex), | ||
sourceText())); | ||
} | ||
} | ||
|
||
DataType dt = value.dataType(); | ||
for (int i = 0; i < list.size(); i++) { | ||
Expression listValue = list.get(i); | ||
if (areCompatible(dt, listValue.dataType()) == false) { | ||
return new TypeResolution(format(null, "{} argument of [{}] must be [{}], found value [{}] type [{}]", | ||
ordinal(i + 1), | ||
sourceText(), | ||
dt.typeName(), | ||
Expressions.name(listValue), | ||
listValue.dataType().typeName())); | ||
} | ||
} | ||
|
||
return super.resolveType(); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(value, list); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null || getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
|
||
In other = (In) obj; | ||
return Objects.equals(value, other.value) | ||
&& Objects.equals(list, other.list); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 0 additions & 63 deletions
63
x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/Foldables.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.