QL: Backport project to 7.x (#51497)

* Introduce reusable QL plugin for SQL and EQL (#50815)

Extract reusable functionality from SQL into its own dedicated project QL.
Implemented as a plugin, it provides common components across SQL and the upcoming EQL.

While this commit is fairly large, for the most part it's just a big file move from sql package to the newly introduced ql.

(cherry picked from commit ec1ac0d463bfa12a02c8174afbcdd6984345e8b4)

* SQL: Fix incomplete registration of geo NamedWritables

(cherry picked from commit e295763686f9592976e551e504fdad1d2a3a566d)

* QL: Extend NodeSubclass to read classes from jars (#50866)

As the test classes are spread across more than one project, the Gradle
classpath contains not just folders but also jars.
This commit allows the test class to explore the archive content and
load matching classes from said source.

(cherry picked from commit 25ad74928afcbf286dc58f7d430491b0af662f04)

* QL: Remove implicit conversion inside Literal (#50962)

Literal constructor makes an implicit conversion for each value given
which turns out has some subtle side-effects.
Improve MathProcessors to preserve numeric type where possible
Fix bug on issue compatibility between date and intervals
Preserve the source when folding inside the Optimizer

(cherry picked from commit 9b73e225b0aa07a23859550fb117bae571a2b672)

* QL: Refactor DataType for pluggability (#51328)

Change DataType from enum to class
Break DataType enums into QL (default) and SQL types
Make data type conversion pluggable so that new types can be introduced

As part of the process:
- static type conversion in QL package (such as Literal) has been
removed
- several utility classes have been broken into base (QL) and extended
(SQL) parts based on type awareness
- operators (+,-,/,*) are
- due to extensibility, serialization of arithmetic operation has been
slightly changed and pushed down to the operator executor itself

(cherry picked from commit aebda81b30e1563b877a8896309fd50633e0b663)

* Compilation fixes for 7.x
This commit is contained in:
Costin Leau 2020-01-27 22:03:58 +02:00 committed by GitHub
parent 3eae601b0b
commit e22f501018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
701 changed files with 10789 additions and 7214 deletions

View File

@ -0,0 +1,36 @@
evaluationDependsOn(xpackModule('core'))
apply plugin: 'elasticsearch.esplugin'
esplugin {
name 'x-pack-ql'
description 'Elasticsearch infrastructure plugin for EQL and SQL for Elasticsearch'
classname 'org.elasticsearch.xpack.ql.plugin.QlPlugin'
extendedPlugins = ['x-pack-core']
}
archivesBaseName = 'x-pack-ql'
dependencies {
compileOnly project(path: xpackModule('core'), configuration: 'default')
testCompile project(':test:framework')
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
}
configurations {
testArtifacts.extendsFrom testRuntime
}
task testJar(type: Jar) {
appendix 'test'
from sourceSets.test.output
}
artifacts {
// normal es plugins do not publish the jar but we need to since users need it for extensions
archives jar
testArtifacts testJar
}
// disable integration tests for now
integTest.enabled = false

View File

@ -0,0 +1,61 @@
/*
* 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;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.xpack.ql.tree.Source;
import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
public class ParsingException extends QlClientException {
private final int line;
private final int charPositionInLine;
public ParsingException(String message, Exception cause, int line, int charPositionInLine) {
super(message, cause);
this.line = line;
this.charPositionInLine = charPositionInLine;
}
public ParsingException(String message, Object... args) {
this(Source.EMPTY, message, args);
}
public ParsingException(Source source, String message, Object... args) {
super(message, args);
this.line = source.source().getLineNumber();
this.charPositionInLine = source.source().getColumnNumber();
}
public ParsingException(Exception cause, Source source, String message, Object... args) {
super(cause, message, args);
this.line = source.source().getLineNumber();
this.charPositionInLine = source.source().getColumnNumber();
}
public int getLineNumber() {
return line;
}
public int getColumnNumber() {
return charPositionInLine + 1;
}
public String getErrorMessage() {
return super.getMessage();
}
@Override
public RestStatus status() {
return RestStatus.BAD_REQUEST;
}
@Override
public String getMessage() {
return format("line {}:{}: {}", getLineNumber(), getColumnNumber(), getErrorMessage());
}
}

View File

@ -0,0 +1,29 @@
/*
* 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;
public abstract class QlClientException extends QlException {
protected QlClientException(String message, Object... args) {
super(message, args);
}
protected QlClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
protected QlClientException(String message, Throwable cause) {
super(message, cause);
}
protected QlClientException(Throwable cause, String message, Object... args) {
super(cause, message, args);
}
protected QlClientException(Throwable cause) {
super(cause);
}
}

View File

@ -3,28 +3,28 @@
* 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.sql;
package org.elasticsearch.xpack.ql;
import org.elasticsearch.ElasticsearchException;
public abstract class SqlException extends ElasticsearchException {
public SqlException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
public abstract class QlException extends ElasticsearchException {
public QlException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public SqlException(String message, Throwable cause) {
public QlException(String message, Throwable cause) {
super(message, cause);
}
public SqlException(String message, Object... args) {
public QlException(String message, Object... args) {
super(message, args);
}
public SqlException(Throwable cause, String message, Object... args) {
public QlException(Throwable cause, String message, Object... args) {
super(message, cause, args);
}
public SqlException(Throwable cause) {
public QlException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,32 @@
/*
* 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;
public class QlIllegalArgumentException extends QlServerException {
public QlIllegalArgumentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public QlIllegalArgumentException(String message, Throwable cause) {
super(message, cause);
}
public QlIllegalArgumentException(String message, Object... args) {
super(message, args);
}
public QlIllegalArgumentException(Throwable cause, String message, Object... args) {
super(cause, message, args);
}
public QlIllegalArgumentException(String message) {
super(message);
}
public QlIllegalArgumentException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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;
public abstract class QlServerException extends QlException {
protected QlServerException(String message, Object... args) {
super(message, args);
}
protected QlServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
protected QlServerException(String message, Throwable cause) {
super(message, cause);
}
protected QlServerException(Throwable cause, String message, Object... args) {
super(cause, message, args);
}
protected QlServerException(Throwable cause) {
super(cause);
}
}

View File

@ -3,7 +3,7 @@
* 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.sql.capabilities;
package org.elasticsearch.xpack.ql.capabilities;
public interface Resolvable {

View File

@ -3,7 +3,7 @@
* 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.sql.capabilities;
package org.elasticsearch.xpack.ql.capabilities;
public abstract class Resolvables {

View File

@ -3,7 +3,7 @@
* 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.sql.capabilities;
package org.elasticsearch.xpack.ql.capabilities;
public interface Unresolvable extends Resolvable {

View File

@ -3,15 +3,15 @@
* 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.sql.capabilities;
package org.elasticsearch.xpack.ql.capabilities;
import org.elasticsearch.xpack.sql.ServerSqlException;
import org.elasticsearch.xpack.ql.QlServerException;
/**
* Thrown when we accidentally attempt to resolve something on on an unresolved entity. Throwing this
* is always a bug.
*/
public class UnresolvedException extends ServerSqlException {
public class UnresolvedException extends QlServerException {
public UnresolvedException(String action, Object target) {
super("Invalid call to {} on an unresolved object {}", action, target);
}

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search;
package org.elasticsearch.xpack.ql.execution.search;
/**
* Reference to a ES aggregation (which can be either a GROUP BY or Metric agg).
@ -11,7 +11,7 @@ package org.elasticsearch.xpack.sql.execution.search;
public abstract class AggRef implements FieldExtraction {
@Override
public void collectFields(SqlSourceBuilder sourceBuilder) {
public void collectFields(QlSourceBuilder sourceBuilder) {
// Aggregations do not need any special fields
}

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search;
package org.elasticsearch.xpack.ql.execution.search;
import org.elasticsearch.search.builder.SearchSourceBuilder;
@ -17,7 +17,7 @@ public interface FieldExtraction {
* in order to fetch the field. This can include tracking the score,
* {@code _source} fields, doc values fields, and script fields.
*/
void collectFields(SqlSourceBuilder sourceBuilder);
void collectFields(QlSourceBuilder sourceBuilder);
/**
* Is this aggregation supported in an "aggregation only" query

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search;
package org.elasticsearch.xpack.ql.execution.search;
import org.elasticsearch.common.Strings;
import org.elasticsearch.script.Script;
@ -20,15 +20,15 @@ import java.util.Set;
* {@link FieldExtraction} that can "build" whatever needs to be extracted from
* the resulting ES document as a field.
*/
public class SqlSourceBuilder {
public class QlSourceBuilder {
// The LinkedHashMaps preserve the order of the fields in the response
final Set<String> sourceFields = new LinkedHashSet<>();
final Set<FieldAndFormat> docFields = new LinkedHashSet<>();
final Map<String, Script> scriptFields = new LinkedHashMap<>();
private final Set<String> sourceFields = new LinkedHashSet<>();
private final Set<FieldAndFormat> docFields = new LinkedHashSet<>();
private final Map<String, Script> scriptFields = new LinkedHashMap<>();
boolean trackScores = false;
public SqlSourceBuilder() {
public QlSourceBuilder() {
}
/**
@ -71,4 +71,8 @@ public class SqlSourceBuilder {
docFields.forEach(field -> sourceBuilder.docValueField(field.field, field.format));
scriptFields.forEach(sourceBuilder::scriptField);
}
public boolean noSource() {
return sourceFields.isEmpty();
}
}

View File

@ -0,0 +1,334 @@
/*
* 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.execution.search.extractor;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.index.mapper.IgnoredFieldMapper;
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypes;
import java.io.IOException;
import java.time.ZoneId;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.SCALED_FLOAT;
/**
* Extractor for ES fields. Works for both 'normal' fields but also nested ones (which require hitName to be set).
* The latter is used as metadata in assembling the results in the tabular response.
*/
public abstract class AbstractFieldHitExtractor implements HitExtractor {
private static final Version SWITCHED_FROM_DOCVALUES_TO_SOURCE_EXTRACTION = Version.V_7_4_0;
/**
* Source extraction requires only the (relative) field name, without its parent path.
*/
private static String[] sourcePath(String name, boolean useDocValue, String hitName) {
return useDocValue ? Strings.EMPTY_ARRAY : Strings
.tokenizeToStringArray(hitName == null ? name : name.substring(hitName.length() + 1), ".");
}
private final String fieldName, hitName;
private final String fullFieldName; // used to look at the _ignored section of the query response for the actual full field name
private final DataType dataType;
private final ZoneId zoneId;
private final boolean useDocValue;
private final boolean arrayLeniency;
private final String[] path;
protected AbstractFieldHitExtractor(String name, DataType dataType, ZoneId zoneId, boolean useDocValue) {
this(name, null, dataType, zoneId, useDocValue, null, false);
}
protected AbstractFieldHitExtractor(String name, DataType dataType, ZoneId zoneId, boolean useDocValue, boolean arrayLeniency) {
this(name, null, dataType, zoneId, useDocValue, null, arrayLeniency);
}
protected AbstractFieldHitExtractor(String name, String fullFieldName, DataType dataType, ZoneId zoneId, boolean useDocValue,
String hitName, boolean arrayLeniency) {
this.fieldName = name;
this.fullFieldName = fullFieldName;
this.dataType = dataType;
this.zoneId = zoneId;
this.useDocValue = useDocValue;
this.arrayLeniency = arrayLeniency;
this.hitName = hitName;
if (hitName != null) {
if (!name.contains(hitName)) {
throw new QlIllegalArgumentException("Hitname [{}] specified but not part of the name [{}]", hitName, name);
}
}
this.path = sourcePath(fieldName, useDocValue, hitName);
}
protected AbstractFieldHitExtractor(StreamInput in) throws IOException {
fieldName = in.readString();
if (in.getVersion().onOrAfter(SWITCHED_FROM_DOCVALUES_TO_SOURCE_EXTRACTION)) {
fullFieldName = in.readOptionalString();
} else {
fullFieldName = null;
}
String typeName = in.readOptionalString();
dataType = typeName != null ? loadTypeFromName(typeName) : null;
useDocValue = in.readBoolean();
hitName = in.readOptionalString();
arrayLeniency = in.readBoolean();
path = sourcePath(fieldName, useDocValue, hitName);
zoneId = readZoneId(in);
}
protected DataType loadTypeFromName(String typeName) {
return DataTypes.fromTypeName(typeName);
}
protected abstract ZoneId readZoneId(StreamInput in) throws IOException;
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(fieldName);
if (out.getVersion().onOrAfter(SWITCHED_FROM_DOCVALUES_TO_SOURCE_EXTRACTION)) {
out.writeOptionalString(fullFieldName);
}
out.writeOptionalString(dataType == null ? null : dataType.typeName());
out.writeBoolean(useDocValue);
out.writeOptionalString(hitName);
out.writeBoolean(arrayLeniency);
}
@Override
public Object extract(SearchHit hit) {
Object value = null;
if (useDocValue) {
DocumentField field = hit.field(fieldName);
if (field != null) {
value = unwrapMultiValue(field.getValues());
}
} else {
// if the field was ignored because it was malformed and ignore_malformed was turned on
if (fullFieldName != null
&& hit.getFields().containsKey(IgnoredFieldMapper.NAME)
&& isFromDocValuesOnly(dataType) == false
&& dataType.isNumeric()) {
/*
* ignore_malformed makes sense for extraction from _source for numeric fields only.
* And we check here that the data type is actually a numeric one to rule out
* any non-numeric sub-fields (for which the "parent" field should actually be extracted from _source).
* For example, in the case of a malformed number, a "byte" field with "ignore_malformed: true"
* with a "text" sub-field should return "null" for the "byte" parent field and the actual malformed
* data for the "text" sub-field. Also, the _ignored section of the response contains the full field
* name, thus the need to do the comparison with that and not only the field name.
*/
if (hit.getFields().get(IgnoredFieldMapper.NAME).getValues().contains(fullFieldName)) {
return null;
}
}
Map<String, Object> source = hit.getSourceAsMap();
if (source != null) {
value = extractFromSource(source);
}
}
return value;
}
protected Object unwrapMultiValue(Object values) {
if (values == null) {
return null;
}
if (values instanceof List) {
List<?> list = (List<?>) values;
if (list.isEmpty()) {
return null;
} else {
if (isPrimitive(list) == false) {
if (list.size() == 1 || arrayLeniency) {
return unwrapMultiValue(list.get(0));
} else {
throw new QlIllegalArgumentException("Arrays (returned by [{}]) are not supported", fieldName);
}
}
}
}
Object unwrapped = unwrapCustomValue(values);
if (unwrapped != null) {
return unwrapped;
}
// The Jackson json parser can generate for numerics - Integers, Longs, BigIntegers (if Long is not enough)
// and BigDecimal (if Double is not enough)
if (values instanceof Number || values instanceof String || values instanceof Boolean) {
if (dataType == null) {
return values;
}
if (dataType.isNumeric() && isFromDocValuesOnly(dataType) == false) {
if (dataType == DataTypes.DOUBLE || dataType == DataTypes.FLOAT || dataType == DataTypes.HALF_FLOAT) {
Number result = null;
try {
result = numberType(dataType).parse(values, true);
} catch(IllegalArgumentException iae) {
return null;
}
// docvalue_fields is always returning a Double value even if the underlying floating point data type is not Double
// even if we don't extract from docvalue_fields anymore, the behavior should be consistent
return result.doubleValue();
} else {
Number result = null;
try {
result = numberType(dataType).parse(values, true);
} catch(IllegalArgumentException iae) {
return null;
}
return result;
}
} else if (DataTypes.isString(dataType)) {
return values.toString();
} else {
return values;
}
}
throw new QlIllegalArgumentException("Type {} (returned by [{}]) is not supported", values.getClass().getSimpleName(), fieldName);
}
protected boolean isFromDocValuesOnly(DataType dataType) {
return dataType == KEYWORD // because of ignore_above.
|| dataType == DATETIME
|| dataType == SCALED_FLOAT; // because of scaling_factor
}
private static NumberType numberType(DataType dataType) {
return NumberType.valueOf(dataType.esType().toUpperCase(Locale.ROOT));
}
protected abstract Object unwrapCustomValue(Object values);
protected abstract boolean isPrimitive(List<?> list);
@SuppressWarnings({ "unchecked", "rawtypes" })
public Object extractFromSource(Map<String, Object> map) {
Object value = null;
// Used to avoid recursive method calls
// Holds the sub-maps in the document hierarchy that are pending to be inspected along with the current index of the `path`.
Deque<Tuple<Integer, Map<String, Object>>> queue = new ArrayDeque<>();
queue.add(new Tuple<>(-1, map));
while (!queue.isEmpty()) {
Tuple<Integer, Map<String, Object>> tuple = queue.removeLast();
int idx = tuple.v1();
Map<String, Object> subMap = tuple.v2();
// Find all possible entries by examining all combinations under the current level ("idx") of the "path"
// e.g.: If the path == "a.b.c.d" and the idx == 0, we need to check the current subMap against the keys:
// "b", "b.c" and "b.c.d"
StringJoiner sj = new StringJoiner(".");
for (int i = idx + 1; i < path.length; i++) {
sj.add(path[i]);
Object node = subMap.get(sj.toString());
if (node instanceof List) {
List listOfValues = (List) node;
// we can only do this optimization until the last element of our pass since geo points are using arrays
// and we don't want to blindly ignore the second element of array if arrayLeniency is enabled
if ((i < path.length - 1) && (listOfValues.size() == 1 || arrayLeniency)) {
// this is a List with a size of 1 e.g.: {"a" : [{"b" : "value"}]} meaning the JSON is a list with one element
// or a list of values with one element e.g.: {"a": {"b" : ["value"]}}
// in case of being lenient about arrays, just extract the first value in the array
node = listOfValues.get(0);
} else {
// a List of elements with more than one value. Break early and let unwrapMultiValue deal with the list
return unwrapMultiValue(node);
}
}
if (node instanceof Map) {
if (i < path.length - 1) {
// Add the sub-map to the queue along with the current path index
queue.add(new Tuple<>(i, (Map<String, Object>) node));
} else {
// We exhausted the path and got a map
// If it is an object - it will be handled in the value extractor
value = node;
}
} else if (node != null) {
if (i < path.length - 1) {
// If we reach a concrete value without exhausting the full path, something is wrong with the mapping
// e.g.: map is {"a" : { "b" : "value }} and we are looking for a path: "a.b.c.d"
throw new QlIllegalArgumentException("Cannot extract value [{}] from source", fieldName);
}
if (value != null) {
// A value has already been found so this means that there are more than one
// values in the document for the same path but different hierarchy.
// e.g.: {"a" : {"b" : {"c" : "value"}}}, {"a.b" : {"c" : "value"}}, ...
throw new QlIllegalArgumentException("Multiple values (returned by [{}]) are not supported", fieldName);
}
value = node;
}
}
}
return unwrapMultiValue(value);
}
@Override
public String hitName() {
return hitName;
}
public String fieldName() {
return fieldName;
}
public String fullFieldName() {
return fullFieldName;
}
public ZoneId zoneId() {
return zoneId;
}
public DataType dataType() {
return dataType;
}
@Override
public String toString() {
return fieldName + "@" + hitName + "@" + zoneId;
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
AbstractFieldHitExtractor other = (AbstractFieldHitExtractor) obj;
return fieldName.equals(other.fieldName)
&& hitName.equals(other.hitName)
&& useDocValue == other.useDocValue
&& arrayLeniency == other.arrayLeniency;
}
@Override
public int hashCode() {
return Objects.hash(fieldName, useDocValue, hitName, arrayLeniency);
}
}

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search.extractor;
package org.elasticsearch.xpack.ql.execution.search.extractor;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;

View File

@ -0,0 +1,28 @@
/*
* 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.execution.search.extractor;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry;
import java.util.ArrayList;
import java.util.List;
public final class BucketExtractors {
private BucketExtractors() {}
/**
* All of the named writeables needed to deserialize the instances of
* {@linkplain BucketExtractor}s.
*/
public static List<NamedWriteableRegistry.Entry> getNamedWriteables() {
List<NamedWriteableRegistry.Entry> entries = new ArrayList<>();
entries.add(new Entry(BucketExtractor.class, ComputingExtractor.NAME, ComputingExtractor::new));
entries.add(new Entry(BucketExtractor.class, ConstantExtractor.NAME, ConstantExtractor::new));
return entries;
}
}

View File

@ -3,14 +3,14 @@
* 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.sql.execution.search.extractor;
package org.elasticsearch.xpack.ql.execution.search.extractor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
import org.elasticsearch.xpack.sql.expression.gen.processor.HitExtractorProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.expression.gen.processor.HitExtractorProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import java.io.IOException;
import java.util.Objects;
@ -44,7 +44,8 @@ public class ComputingExtractor implements HitExtractor, BucketExtractor {
this.hitName = hitName;
}
ComputingExtractor(StreamInput in) throws IOException {
// Visibility required for tests
public ComputingExtractor(StreamInput in) throws IOException {
processor = in.readNamedWriteable(Processor.class);
hitName = in.readOptionalString();
}

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search.extractor;
package org.elasticsearch.xpack.ql.execution.search.extractor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search.extractor;
package org.elasticsearch.xpack.ql.execution.search.extractor;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.NamedWriteable;

View File

@ -3,7 +3,7 @@
* 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.sql.execution.search.extractor;
package org.elasticsearch.xpack.ql.execution.search.extractor;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry;
@ -22,9 +22,7 @@ public final class HitExtractors {
public static List<NamedWriteableRegistry.Entry> getNamedWriteables() {
List<NamedWriteableRegistry.Entry> entries = new ArrayList<>();
entries.add(new Entry(HitExtractor.class, ConstantExtractor.NAME, ConstantExtractor::new));
entries.add(new Entry(HitExtractor.class, FieldHitExtractor.NAME, FieldHitExtractor::new));
entries.add(new Entry(HitExtractor.class, ComputingExtractor.NAME, ComputingExtractor::new));
entries.add(new Entry(HitExtractor.class, ScoreExtractor.NAME, in -> ScoreExtractor.INSTANCE));
return entries;
}
}

View File

@ -3,11 +3,11 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.List;

View File

@ -3,10 +3,10 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.List;
import java.util.Objects;

View File

@ -3,7 +3,7 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import java.util.AbstractSet;
import java.util.Collection;

View File

@ -3,7 +3,7 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import java.util.Collection;
import java.util.Iterator;

View File

@ -3,15 +3,15 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.capabilities.Resolvable;
import org.elasticsearch.xpack.sql.capabilities.Resolvables;
import org.elasticsearch.xpack.sql.tree.Node;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.capabilities.Resolvable;
import org.elasticsearch.xpack.ql.capabilities.Resolvables;
import org.elasticsearch.xpack.ql.tree.Node;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.util.StringUtils;
import java.util.List;
@ -46,12 +46,17 @@ public abstract class Expression extends Node<Expression> implements Resolvable
}
public boolean resolved() {
return !failed;
return failed == false;
}
public String message() {
return message;
}
@Override
public String toString() {
return resolved() ? "" : message;
}
}
private TypeResolution lazyTypeResolution = null;
@ -69,7 +74,7 @@ public abstract class Expression extends Node<Expression> implements Resolvable
}
public Object fold() {
throw new SqlIllegalArgumentException("Should not fold expression");
throw new QlIllegalArgumentException("Should not fold expression");
}
public abstract Nullability nullable();

View File

@ -3,7 +3,7 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import java.util.Collection;
import java.util.Iterator;

View File

@ -3,15 +3,14 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.function.Function;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.AttributeInput;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.ConstantInput;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.DataTypes;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.function.Function;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.AttributeInput;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.ql.type.DataTypes;
import java.util.ArrayList;
import java.util.Collection;
@ -112,7 +111,7 @@ public final class Expressions {
}
public static boolean isNull(Expression e) {
return e.dataType() == DataType.NULL || (e.foldable() && e.fold() == null);
return e.dataType() == DataTypes.NULL || (e.foldable() && e.fold() == null);
}
public static List<String> names(Collection<? extends Expression> e) {
@ -165,7 +164,7 @@ public final class Expressions {
Set<Attribute> seenMultiFields = new LinkedHashSet<>();
for (Attribute a : attributes) {
if (!DataTypes.isUnsupported(a.dataType()) && a.dataType().isPrimitive()) {
if (DataTypes.isUnsupported(a.dataType()) == false && DataTypes.isPrimitive(a.dataType())) {
if (a instanceof FieldAttribute) {
FieldAttribute fa = (FieldAttribute) a;
// skip nested fields and seen multi-fields
@ -192,7 +191,7 @@ public final class Expressions {
if (e instanceof Function) {
return ((Function) e).asPipe();
}
throw new SqlIllegalArgumentException("Cannot create pipe for {}", e);
throw new QlIllegalArgumentException("Cannot create pipe for {}", e);
}
public static List<Pipe> pipe(List<Expression> expressions) {

View File

@ -3,14 +3,15 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.EsField;
import org.elasticsearch.xpack.sql.util.StringUtils;
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.DataTypes;
import org.elasticsearch.xpack.ql.type.EsField;
import org.elasticsearch.xpack.ql.util.StringUtils;
import java.util.Objects;
@ -53,7 +54,7 @@ public class FieldAttribute extends TypedAttribute {
FieldAttribute nestedPar = null;
if (parent != null) {
nestedPar = parent.nestedParent;
if (parent.dataType() == DataType.NESTED) {
if (parent.dataType() == DataTypes.NESTED) {
nestedPar = parent;
}
}
@ -103,7 +104,7 @@ public class FieldAttribute extends TypedAttribute {
}
@Override
protected Attribute clone(Source source, String name, DataType type, String qualifier, Nullability nullability, NameId id,
protected Attribute clone(Source source, String name, DataType type, String qualifier, Nullability nullability, NameId id,
boolean synthetic) {
FieldAttribute qualifiedParent = parent != null ? (FieldAttribute) parent.withQualifier(qualifier) : null;
return new FieldAttribute(source, qualifiedParent, name, field, qualifier, nullability, id, synthetic);

View File

@ -3,9 +3,9 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;

View File

@ -3,14 +3,13 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.DataTypeConversion;
import org.elasticsearch.xpack.sql.type.DataTypes;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
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.DataTypes;
import java.util.Objects;
@ -19,9 +18,9 @@ import java.util.Objects;
*/
public class Literal extends LeafExpression {
public static final Literal TRUE = Literal.of(Source.EMPTY, Boolean.TRUE);
public static final Literal FALSE = Literal.of(Source.EMPTY, Boolean.FALSE);
public static final Literal NULL = Literal.of(Source.EMPTY, null);
public static final Literal TRUE = new Literal(Source.EMPTY, Boolean.TRUE, DataTypes.BOOLEAN);
public static final Literal FALSE = new Literal(Source.EMPTY, Boolean.FALSE, DataTypes.BOOLEAN);
public static final Literal NULL = new Literal(Source.EMPTY, null, DataTypes.NULL);
private final Object value;
private final DataType dataType;
@ -29,7 +28,7 @@ public class Literal extends LeafExpression {
public Literal(Source source, Object value, DataType dataType) {
super(source);
this.dataType = dataType;
this.value = DataTypeConversion.convert(value, dataType);
this.value = value;
}
@Override
@ -94,23 +93,13 @@ public class Literal extends LeafExpression {
return toString() + "[" + dataType + "]";
}
/**
* Utility method for creating 'in-line' Literals (out of values instead of expressions).
*/
public static Literal of(Source source, Object value) {
if (value instanceof Literal) {
return (Literal) value;
}
return new Literal(source, value, DataTypes.fromJava(value));
}
/**
* Utility method for creating a literal out of a foldable expression.
* Throws an exception if the expression is not foldable.
*/
public static Literal of(Expression foldable) {
if (!foldable.foldable()) {
throw new SqlIllegalArgumentException("Foldable expression required for Literal creation; received unfoldable " + foldable);
throw new QlIllegalArgumentException("Foldable expression required for Literal creation; received unfoldable " + foldable);
}
if (foldable instanceof Literal) {

View File

@ -3,7 +3,7 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

View File

@ -3,9 +3,9 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Objects;

View File

@ -3,7 +3,7 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
public enum Nullability {
TRUE, // Whether the expression can become null

View File

@ -3,17 +3,17 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.List;
import java.util.Objects;
import static java.util.Collections.singletonList;
import static org.elasticsearch.xpack.sql.expression.TypeResolutions.isExact;
import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isExact;
public class Order extends Expression {

View File

@ -3,11 +3,11 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
/**
* Attribute based on a reference to an expression.

View File

@ -3,20 +3,22 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.expression.Expression.TypeResolution;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.EsField;
import org.elasticsearch.xpack.ql.expression.Expression.TypeResolution;
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypes;
import org.elasticsearch.xpack.ql.type.EsField;
import java.util.Locale;
import java.util.StringJoiner;
import java.util.function.Predicate;
import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
import static org.elasticsearch.xpack.sql.expression.Expressions.name;
import static org.elasticsearch.xpack.sql.type.DataType.BOOLEAN;
import static org.elasticsearch.xpack.ql.expression.Expressions.name;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.NULL;
public final class TypeResolutions {
@ -35,36 +37,14 @@ public final class TypeResolutions {
}
public static TypeResolution isString(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, DataType::isString, operationName, paramOrd, "string");
}
public static TypeResolution isDate(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, DataType::isDateBased, operationName, paramOrd, "date", "datetime");
}
public static TypeResolution isDateOrTime(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, DataType::isDateOrTimeBased, operationName, paramOrd, "date", "time", "datetime");
}
public static TypeResolution isNumericOrDate(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, dt -> dt.isNumeric() || dt.isDateBased(), operationName, paramOrd,
"date", "datetime", "numeric");
}
public static TypeResolution isNumericOrDateOrTime(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, dt -> dt.isNumeric() || dt.isDateOrTimeBased(), operationName, paramOrd,
"date", "time", "datetime", "numeric");
}
public static TypeResolution isGeo(Expression e, String operationName, ParamOrdinal paramOrd) {
return isType(e, DataType::isGeo, operationName, paramOrd, "geo_point", "geo_shape");
return isType(e, DataTypes::isString, operationName, paramOrd, "string");
}
public static TypeResolution isExact(Expression e, String message) {
if (e instanceof FieldAttribute) {
EsField.Exact exact = ((FieldAttribute) e).getExactInfo();
if (exact.hasExact() == false) {
return new TypeResolution(format(null, message, e.dataType().typeName, exact.errorMsg()));
return new TypeResolution(format(null, message, e.dataType().typeName(), exact.errorMsg()));
}
}
return TypeResolution.TYPE_RESOLVED;
@ -78,7 +58,7 @@ public final class TypeResolutions {
operationName,
paramOrd == null || paramOrd == ParamOrdinal.DEFAULT ?
"" : paramOrd.name().toLowerCase(Locale.ROOT) + " argument ",
e.dataType().typeName, exact.errorMsg()));
e.dataType().typeName(), exact.errorMsg()));
}
}
return TypeResolution.TYPE_RESOLVED;
@ -118,14 +98,14 @@ public final class TypeResolutions {
String operationName,
ParamOrdinal paramOrd,
String... acceptedTypes) {
return predicate.test(e.dataType()) || e.dataType().isNull() ?
return predicate.test(e.dataType()) || e.dataType() == NULL ?
TypeResolution.TYPE_RESOLVED :
new TypeResolution(format(null, "{}argument of [{}] must be [{}], found value [{}] type [{}]",
paramOrd == null || paramOrd == ParamOrdinal.DEFAULT ? "" : paramOrd.name().toLowerCase(Locale.ROOT) + " ",
operationName,
acceptedTypesForErrorMsg(acceptedTypes),
name(e),
e.dataType().typeName));
e.dataType().typeName()));
}
private static String acceptedTypesForErrorMsg(String... acceptedTypes) {

View File

@ -3,10 +3,10 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.Objects;

View File

@ -3,10 +3,10 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.List;
import java.util.Objects;

View File

@ -3,11 +3,11 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Objects;

View File

@ -3,14 +3,14 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.capabilities.Unresolvable;
import org.elasticsearch.xpack.sql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.CollectionUtils;
import org.elasticsearch.xpack.ql.capabilities.Unresolvable;
import org.elasticsearch.xpack.ql.capabilities.UnresolvedException;
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.util.CollectionUtils;
import java.util.List;
import java.util.Objects;

View File

@ -3,12 +3,12 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.capabilities.Unresolvable;
import org.elasticsearch.xpack.sql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.capabilities.Unresolvable;
import org.elasticsearch.xpack.ql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import java.util.List;

View File

@ -3,11 +3,11 @@
* 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.sql.expression;
package org.elasticsearch.xpack.ql.expression;
import org.elasticsearch.xpack.sql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Objects;

View File

@ -0,0 +1,36 @@
/*
* 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.function;
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction;
public class DefaultFunctionTypeRegistry implements FunctionTypeRegistry {
public static final DefaultFunctionTypeRegistry INSTANCE = new DefaultFunctionTypeRegistry();
private enum Types {
AGGREGATE(AggregateFunction.class),
SCALAR(ScalarFunction.class);
private Class<? extends Function> baseClass;
Types(Class<? extends Function> base) {
this.baseClass = base;
}
}
@Override
public String type(Class<? extends Function> clazz) {
for (Types type : Types.values()) {
if (type.baseClass.isAssignableFrom(clazz)) {
return type.name();
}
}
return "UNKNOWN";
}
}

View File

@ -3,15 +3,15 @@
* 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.sql.expression.function;
package org.elasticsearch.xpack.ql.expression.function;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Nullability;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.ConstantInput;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.Nullability;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Locale;

View File

@ -3,14 +3,13 @@
* 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.sql.expression.function;
package org.elasticsearch.xpack.ql.expression.function;
import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.ql.session.Configuration;
import java.util.List;
import java.util.Locale;
import static java.lang.String.format;
import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
public class FunctionDefinition {
/**
@ -29,16 +28,13 @@ public class FunctionDefinition {
*/
private final boolean extractViable;
private final Builder builder;
private final FunctionType type;
FunctionDefinition(String name, List<String> aliases, Class<? extends Function> clazz,
boolean datetime, Builder builder) {
FunctionDefinition(String name, List<String> aliases, Class<? extends Function> clazz, boolean datetime, Builder builder) {
this.name = name;
this.aliases = aliases;
this.clazz = clazz;
this.extractViable = datetime;
this.builder = builder;
this.type = FunctionType.of(clazz);
}
public String name() {
@ -49,11 +45,7 @@ public class FunctionDefinition {
return aliases;
}
public FunctionType type() {
return type;
}
Class<? extends Function> clazz() {
public Class<? extends Function> clazz() {
return clazz;
}
@ -70,6 +62,6 @@ public class FunctionDefinition {
@Override
public String toString() {
return format(Locale.ROOT, "%s(%s)", name, aliases.isEmpty() ? "" : aliases.size() == 1 ? aliases.get(0) : aliases );
return format(null, "{}({})", name, aliases.isEmpty() ? "" : aliases.size() == 1 ? aliases.get(0) : aliases);
}
}

View File

@ -0,0 +1,420 @@
/*
* 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.function;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.ql.ParsingException;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.session.Configuration;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.util.Check;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiFunction;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toList;
public class FunctionRegistry {
// list of functions grouped by type of functions (aggregate, statistics, math etc) and ordered alphabetically inside each group
// a single function will have one entry for itself with its name associated to its instance and, also, one entry for each alias
// it has with the alias name associated to the FunctionDefinition instance
private final Map<String, FunctionDefinition> defs = new LinkedHashMap<>();
private final Map<String, String> aliases = new HashMap<>();
public FunctionRegistry() {}
/**
* Register the given function definitions with this registry.
*/
public FunctionRegistry(FunctionDefinition... functions) {
register(functions);
}
public FunctionRegistry(FunctionDefinition[]... groupFunctions) {
for (FunctionDefinition[] group : groupFunctions) {
register(group);
}
}
protected void register(FunctionDefinition... functions) {
// temporary map to hold [function_name/alias_name : function instance]
Map<String, FunctionDefinition> batchMap = new HashMap<>();
for (FunctionDefinition f : functions) {
batchMap.put(f.name(), f);
for (String alias : f.aliases()) {
Object old = batchMap.put(alias, f);
if (old != null || defs.containsKey(alias)) {
throw new QlIllegalArgumentException("alias [" + alias + "] is used by "
+ "[" + (old != null ? old : defs.get(alias).name()) + "] and [" + f.name() + "]");
}
aliases.put(alias, f.name());
}
}
// sort the temporary map by key name and add it to the global map of functions
defs.putAll(batchMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.<Entry<String, FunctionDefinition>, String,
FunctionDefinition, LinkedHashMap<String, FunctionDefinition>> toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new)));
}
public FunctionDefinition resolveFunction(String functionName) {
FunctionDefinition def = defs.get(functionName);
if (def == null) {
throw new QlIllegalArgumentException(
"Cannot find function {}; this should have been caught during analysis",
functionName);
}
return def;
}
public String resolveAlias(String alias) {
String upperCase = alias.toUpperCase(Locale.ROOT);
return aliases.getOrDefault(upperCase, upperCase);
}
public boolean functionExists(String functionName) {
return defs.containsKey(functionName);
}
public Collection<FunctionDefinition> listFunctions() {
// It is worth double checking if we need this copy. These are immutable anyway.
return defs.values();
}
public Collection<FunctionDefinition> listFunctions(String pattern) {
// It is worth double checking if we need this copy. These are immutable anyway.
Pattern p = Strings.hasText(pattern) ? Pattern.compile(pattern.toUpperCase(Locale.ROOT)) : null;
return defs.entrySet().stream()
.filter(e -> p == null || p.matcher(e.getKey()).matches())
.map(e -> new FunctionDefinition(e.getKey(), emptyList(),
e.getValue().clazz(), e.getValue().extractViable(), e.getValue().builder()))
.collect(toList());
}
/**
* Build a {@linkplain FunctionDefinition} for a no-argument function that
* is not aware of time zone and does not support {@code DISTINCT}.
*/
protected static <T extends Function> FunctionDefinition def(Class<T> function,
java.util.function.Function<Source, T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (false == children.isEmpty()) {
throw new QlIllegalArgumentException("expects no arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.apply(source);
};
return def(function, builder, false, names);
}
/**
* Build a {@linkplain FunctionDefinition} for a no-argument function that
* is not aware of time zone, does not support {@code DISTINCT} and needs
* the cluster name (DATABASE()) or the user name (USER()).
*/
@SuppressWarnings("overloads")
protected static <T extends Function> FunctionDefinition def(Class<T> function,
ConfigurationAwareFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (false == children.isEmpty()) {
throw new QlIllegalArgumentException("expects no arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, cfg);
};
return def(function, builder, false, names);
}
protected interface ConfigurationAwareFunctionBuilder<T> {
T build(Source source, Configuration configuration);
}
/**
* Build a {@linkplain FunctionDefinition} for a one-argument function that
* is not aware of time zone, does not support {@code DISTINCT} and needs
* the configuration object.
*/
@SuppressWarnings("overloads")
protected static <T extends Function> FunctionDefinition def(Class<T> function,
UnaryConfigurationAwareFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() > 1) {
throw new QlIllegalArgumentException("expects exactly one argument");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
Expression ex = children.size() == 1 ? children.get(0) : null;
return ctorRef.build(source, ex, cfg);
};
return def(function, builder, false, names);
}
protected interface UnaryConfigurationAwareFunctionBuilder<T> {
T build(Source source, Expression exp, Configuration configuration);
}
/**
* Build a {@linkplain FunctionDefinition} for a unary function that is not
* aware of time zone and does not support {@code DISTINCT}.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
protected static <T extends Function> FunctionDefinition def(Class<T> function,
BiFunction<Source, Expression, T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 1) {
throw new QlIllegalArgumentException("expects exactly one argument");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.apply(source, children.get(0));
};
return def(function, builder, false, names);
}
/**
* Build a {@linkplain FunctionDefinition} for multi-arg function that
* is not aware of time zone and does not support {@code DISTINCT}.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
MultiFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children);
};
return def(function, builder, false, names);
}
protected interface MultiFunctionBuilder<T> {
T build(Source source, List<Expression> children);
}
/**
* Build a {@linkplain FunctionDefinition} for a unary function that is not
* aware of time zone but does support {@code DISTINCT}.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
DistinctAwareUnaryFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 1) {
throw new QlIllegalArgumentException("expects exactly one argument");
}
return ctorRef.build(source, children.get(0), distinct);
};
return def(function, builder, false, names);
}
protected interface DistinctAwareUnaryFunctionBuilder<T> {
T build(Source source, Expression target, boolean distinct);
}
/**
* Build a {@linkplain FunctionDefinition} for a unary function that
* operates on a datetime.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
DatetimeUnaryFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 1) {
throw new QlIllegalArgumentException("expects exactly one argument");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), cfg.zoneId());
};
return def(function, builder, true, names);
}
protected interface DatetimeUnaryFunctionBuilder<T> {
T build(Source source, Expression target, ZoneId zi);
}
/**
* Build a {@linkplain FunctionDefinition} for a binary function that
* requires a timezone.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function, DatetimeBinaryFunctionBuilder<T> ctorRef,
String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 2) {
throw new QlIllegalArgumentException("expects exactly two arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), children.get(1), cfg.zoneId());
};
return def(function, builder, false, names);
}
protected interface DatetimeBinaryFunctionBuilder<T> {
T build(Source source, Expression lhs, Expression rhs, ZoneId zi);
}
/**
* Build a {@linkplain FunctionDefinition} for a three-args function that
* requires a timezone.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function, DatetimeThreeArgsFunctionBuilder<T> ctorRef,
String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 3) {
throw new QlIllegalArgumentException("expects three arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), children.get(1), children.get(2), cfg.zoneId());
};
return def(function, builder, false, names);
}
protected interface DatetimeThreeArgsFunctionBuilder<T> {
T build(Source source, Expression first, Expression second, Expression third, ZoneId zi);
}
/**
* Build a {@linkplain FunctionDefinition} for a binary function that is
* not aware of time zone and does not support {@code DISTINCT}.
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
BinaryFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
boolean isBinaryOptionalParamFunction = OptionalArgument.class.isAssignableFrom(function);
if (isBinaryOptionalParamFunction && (children.size() > 2 || children.size() < 1)) {
throw new QlIllegalArgumentException("expects one or two arguments");
} else if (!isBinaryOptionalParamFunction && children.size() != 2) {
throw new QlIllegalArgumentException("expects exactly two arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), children.size() == 2 ? children.get(1) : null);
};
return def(function, builder, false, names);
}
protected interface BinaryFunctionBuilder<T> {
T build(Source source, Expression lhs, Expression rhs);
}
/**
* Main method to register a function/
* @param names Must always have at least one entry which is the method's primary name
*
*/
@SuppressWarnings("overloads")
public static FunctionDefinition def(Class<? extends Function> function, FunctionBuilder builder,
boolean datetime, String... names) {
Check.isTrue(names.length > 0, "At least one name must be provided for the function");
String primaryName = names[0];
List<String> aliases = Arrays.asList(names).subList(1, names.length);
FunctionDefinition.Builder realBuilder = (uf, distinct, cfg) -> {
try {
return builder.build(uf.source(), uf.children(), distinct, cfg);
} catch (QlIllegalArgumentException e) {
throw new ParsingException(uf.source(), "error building [" + primaryName + "]: " + e.getMessage(), e);
}
};
return new FunctionDefinition(primaryName, unmodifiableList(aliases), function, datetime, realBuilder);
}
protected interface FunctionBuilder {
Function build(Source source, List<Expression> children, boolean distinct, Configuration cfg);
}
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
ThreeParametersFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
boolean hasMinimumTwo = OptionalArgument.class.isAssignableFrom(function);
if (hasMinimumTwo && (children.size() > 3 || children.size() < 2)) {
throw new QlIllegalArgumentException("expects two or three arguments");
} else if (!hasMinimumTwo && children.size() != 3) {
throw new QlIllegalArgumentException("expects exactly three arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), children.get(1), children.size() == 3 ? children.get(2) : null);
};
return def(function, builder, false, names);
}
protected interface ThreeParametersFunctionBuilder<T> {
T build(Source source, Expression src, Expression exp1, Expression exp2);
}
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
FourParametersFunctionBuilder<T> ctorRef, String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) -> {
if (children.size() != 4) {
throw new QlIllegalArgumentException("expects exactly four arguments");
}
if (distinct) {
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
}
return ctorRef.build(source, children.get(0), children.get(1), children.get(2), children.get(3));
};
return def(function, builder, false, names);
}
protected interface FourParametersFunctionBuilder<T> {
T build(Source source, Expression src, Expression exp1, Expression exp2, Expression exp3);
}
/**
* Special method to create function definition for Cast as its
* signature is not compatible with {@link UnresolvedFunction}
*
* @return Cast function definition
*/
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
public static <T extends Function> FunctionDefinition def(Class<T> function,
CastFunctionBuilder<T> ctorRef,
String... names) {
FunctionBuilder builder = (source, children, distinct, cfg) ->
ctorRef.build(source, children.get(0), children.get(0).dataType());
return def(function, builder, false, names);
}
protected interface CastFunctionBuilder<T> {
T build(Source source, Expression expression, DataType dataType);
}
}

View File

@ -3,10 +3,10 @@
* 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.sql.expression;
// marker interface for expressions that are do not support null
// and thus are eliminated by it
public interface NullIntolerant {
package org.elasticsearch.xpack.ql.expression.function;
public interface FunctionTypeRegistry {
String type(Class<? extends Function> clazz);
}

View File

@ -3,11 +3,11 @@
* 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.sql.expression.function;
package org.elasticsearch.xpack.ql.expression.function;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.sql.expression.function.grouping.GroupingFunction;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.ql.expression.function.grouping.GroupingFunction;
public abstract class Functions {

View File

@ -0,0 +1,15 @@
/*
* 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.function;
/**
* Marker interface indicating that a function accepts one optional argument (typically the last one).
* This is used by the {@link FunctionRegistry} to perform validation of function declaration.
*/
public interface OptionalArgument {
}

View File

@ -3,20 +3,21 @@
* 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.sql.expression.function;
package org.elasticsearch.xpack.ql.expression.function;
import org.elasticsearch.xpack.sql.capabilities.Unresolvable;
import org.elasticsearch.xpack.sql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.expression.Nullability;
import org.elasticsearch.xpack.sql.expression.function.aggregate.Count;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
import org.elasticsearch.xpack.ql.capabilities.Unresolvable;
import org.elasticsearch.xpack.ql.capabilities.UnresolvedException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Literal;
import org.elasticsearch.xpack.ql.expression.Nullability;
import org.elasticsearch.xpack.ql.expression.function.aggregate.Count;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.session.Configuration;
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.DataTypes;
import org.elasticsearch.xpack.ql.util.StringUtils;
import java.util.LinkedHashSet;
import java.util.List;
@ -195,7 +196,7 @@ public class UnresolvedFunction extends Function implements Unresolvable {
// dedicated count optimization
if (uf.name.toUpperCase(Locale.ROOT).equals("COUNT")) {
return new UnresolvedFunction(uf.source(), uf.name(), uf.resolutionType,
singletonList(Literal.of(uf.arguments().get(0).source(), Integer.valueOf(1))));
singletonList(new Literal(uf.arguments().get(0).source(), Integer.valueOf(1), DataTypes.INTEGER)));
}
return uf;
}

View File

@ -3,18 +3,18 @@
* 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.sql.expression.function.aggregate;
package org.elasticsearch.xpack.ql.expression.function.aggregate;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.TypeResolutions;
import org.elasticsearch.xpack.sql.expression.function.Function;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.AggNameInput;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.util.CollectionUtils;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.TypeResolutions;
import org.elasticsearch.xpack.ql.expression.function.Function;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.AggNameInput;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
@ -61,7 +61,7 @@ public abstract class AggregateFunction extends Function {
@Override
public ScriptTemplate asScript() {
throw new SqlIllegalArgumentException("Aggregate functions cannot be scripted");
throw new QlIllegalArgumentException("Aggregate functions cannot be scripted");
}
@Override

View File

@ -0,0 +1,21 @@
/*
* 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.function.aggregate;
import org.elasticsearch.xpack.ql.expression.Expression;
import java.util.List;
/**
* Marker type for compound aggregates, that is an aggregate that provides multiple values (like Stats or Matrix)
*/
public interface CompoundAggregate {
Expression field();
List<Expression> arguments();
}

View File

@ -3,12 +3,13 @@
* 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.sql.expression.function.aggregate;
package org.elasticsearch.xpack.ql.expression.function.aggregate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.expression.Expression;
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.DataTypes;
import java.util.List;
import java.util.Objects;
@ -46,7 +47,7 @@ public class Count extends AggregateFunction {
@Override
public DataType dataType() {
return DataType.LONG;
return DataTypes.LONG;
}
@Override

View File

@ -3,7 +3,7 @@
* 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.sql.expression.function.aggregate;
package org.elasticsearch.xpack.ql.expression.function.aggregate;
// Agg 'enclosed' by another agg. Used for agg that return multiple embedded aggs (like MatrixStats)
public interface EnclosedAgg {

View File

@ -3,12 +3,13 @@
* 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.sql.expression.function.aggregate;
package org.elasticsearch.xpack.ql.expression.function.aggregate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.expression.Expression;
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.util.Check;
import java.util.List;
import java.util.Objects;
@ -16,19 +17,21 @@ import java.util.Objects;
public class InnerAggregate extends AggregateFunction {
private final AggregateFunction inner;
private final CompoundNumericAggregate outer;
private final CompoundAggregate outer;
private final String innerName;
// used when the result needs to be extracted from a map (like in MatrixAggs or Percentiles)
private final Expression innerKey;
public InnerAggregate(AggregateFunction inner, CompoundNumericAggregate outer) {
public InnerAggregate(AggregateFunction inner, CompoundAggregate outer) {
this(inner.source(), inner, outer, null);
}
public InnerAggregate(Source source, AggregateFunction inner, CompoundNumericAggregate outer, Expression innerKey) {
public InnerAggregate(Source source, AggregateFunction inner, CompoundAggregate outer, Expression innerKey) {
super(source, outer.field(), outer.arguments());
this.inner = inner;
this.outer = outer;
Check.isTrue(inner instanceof EnclosedAgg, "Inner function is not marked as Enclosed");
Check.isTrue(outer instanceof Expression, "CompoundAggregate is not an Expression");
this.innerName = ((EnclosedAgg) inner).innerName();
this.innerKey = innerKey;
}
@ -51,7 +54,7 @@ public class InnerAggregate extends AggregateFunction {
return inner;
}
public CompoundNumericAggregate outer() {
public CompoundAggregate outer() {
return outer;
}

View File

@ -3,16 +3,16 @@
* 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.sql.expression.function.grouping;
package org.elasticsearch.xpack.ql.expression.function.grouping;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.Function;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.AggNameInput;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.util.CollectionUtils;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.function.Function;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.AggNameInput;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
@ -54,7 +54,7 @@ public abstract class GroupingFunction extends Function {
@Override
public ScriptTemplate asScript() {
throw new SqlIllegalArgumentException("Grouping functions cannot be scripted");
throw new QlIllegalArgumentException("Grouping functions cannot be scripted");
}
@Override

View File

@ -3,12 +3,12 @@
* 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.sql.expression.function.scalar;
package org.elasticsearch.xpack.ql.expression.function.scalar;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.expression.gen.script.Scripts;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.expression.gen.script.Scripts;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.Arrays;
import java.util.List;

View File

@ -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.function.scalar;
// FIXME: accessor interface until making script generation pluggable
public interface IntervalScripting {
String script();
String value();
String typeName();
}

View File

@ -0,0 +1,147 @@
/*
* 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.function.scalar;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
import org.elasticsearch.xpack.ql.expression.function.Function;
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.ql.expression.function.grouping.GroupingFunction;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.expression.gen.script.Scripts;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.util.DateUtils;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.List;
import static java.util.Collections.emptyList;
import static org.elasticsearch.xpack.ql.expression.gen.script.ParamsBuilder.paramsBuilder;
/**
* A {@code ScalarFunction} is a {@code Function} that takes values from some
* operation and converts each to another value. An example would be
* {@code ABS()}, which takes one value at a time, applies a function to the
* value (abs) and returns a new value.
*/
public abstract class ScalarFunction extends Function {
protected ScalarFunction(Source source) {
super(source, emptyList());
}
protected ScalarFunction(Source source, List<Expression> fields) {
super(source, fields);
}
// used if the function is monotonic and thus does not have to be computed for ordering purposes
// null means the script needs to be used; expression means the field/expression to be used instead
public Expression orderBy() {
return null;
}
//
// Script generation
//
public ScriptTemplate asScript(Expression exp) {
if (exp.foldable()) {
return scriptWithFoldable(exp);
}
if (exp instanceof FieldAttribute) {
return scriptWithField((FieldAttribute) exp);
}
if (exp instanceof ScalarFunction) {
return scriptWithScalar((ScalarFunction) exp);
}
if (exp instanceof AggregateFunction) {
return scriptWithAggregate((AggregateFunction) exp);
}
if (exp instanceof GroupingFunction) {
return scriptWithGrouping((GroupingFunction) exp);
}
throw new QlIllegalArgumentException("Cannot evaluate script for expression {}", exp);
}
protected ScriptTemplate scriptWithFoldable(Expression foldable) {
Object fold = foldable.fold();
// FIXME: this needs to be refactored
//
// Custom type handling
//
// wrap intervals with dedicated methods for serialization
if (fold instanceof ZonedDateTime) {
ZonedDateTime zdt = (ZonedDateTime) fold;
return new ScriptTemplate(processScript("{sql}.asDateTime({})"), paramsBuilder().variable(DateUtils.toString(zdt)).build(),
dataType());
}
if (fold instanceof IntervalScripting) {
IntervalScripting is = (IntervalScripting) fold;
return new ScriptTemplate(processScript(is.script()), paramsBuilder().variable(is.value()).variable(is.typeName()).build(),
dataType());
}
if (fold instanceof OffsetTime) {
OffsetTime ot = (OffsetTime) fold;
return new ScriptTemplate(processScript("{sql}.asTime({})"), paramsBuilder().variable(ot.toString()).build(), dataType());
}
if (fold != null && fold.getClass().getSimpleName().equals("GeoShape")) {
return new ScriptTemplate(processScript("{sql}.stWktToSql({})"), paramsBuilder().variable(fold.toString()).build(), dataType());
}
return new ScriptTemplate(processScript("{}"),
paramsBuilder().variable(fold).build(),
dataType());
}
protected ScriptTemplate scriptWithScalar(ScalarFunction scalar) {
ScriptTemplate nested = scalar.asScript();
return new ScriptTemplate(processScript(nested.template()),
paramsBuilder().script(nested.params()).build(),
dataType());
}
protected ScriptTemplate scriptWithAggregate(AggregateFunction aggregate) {
String template = "{}";
return new ScriptTemplate(processScript(template),
paramsBuilder().agg(aggregate).build(),
dataType());
}
protected ScriptTemplate scriptWithGrouping(GroupingFunction grouping) {
String template = "{}";
return new ScriptTemplate(processScript(template),
paramsBuilder().grouping(grouping).build(),
dataType());
}
protected ScriptTemplate scriptWithField(FieldAttribute field) {
return new ScriptTemplate(processScript("doc[{}].value"),
paramsBuilder().variable(field.name()).build(),
dataType());
}
protected String processScript(String script) {
return formatTemplate(script);
}
protected String formatTemplate(String template) {
return Scripts.formatTemplate(template);
}
}

View File

@ -3,15 +3,15 @@
* 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.sql.expression.function.scalar;
package org.elasticsearch.xpack.ql.expression.function.scalar;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.ql.expression.gen.pipeline.UnaryPipe;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;

View File

@ -0,0 +1,93 @@
/*
* 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.function.scalar.whitelist;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.xpack.ql.expression.predicate.logical.BinaryLogicProcessor.BinaryLogicOperation;
import org.elasticsearch.xpack.ql.expression.predicate.logical.NotProcessor;
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation;
import org.elasticsearch.xpack.ql.util.StringUtils;
import java.util.Map;
public abstract class InternalQlScriptUtils {
//
// Utilities
//
// safe missing mapping/value extractor
public static <T> Object docValue(Map<String, ScriptDocValues<T>> doc, String fieldName) {
if (doc.containsKey(fieldName)) {
ScriptDocValues<T> docValues = doc.get(fieldName);
if (!docValues.isEmpty()) {
return docValues.get(0);
}
}
return null;
}
public static boolean nullSafeFilter(Boolean filter) {
return filter == null ? false : filter.booleanValue();
}
public static double nullSafeSortNumeric(Number sort) {
return sort == null ? 0.0d : sort.doubleValue();
}
public static String nullSafeSortString(Object sort) {
return sort == null ? StringUtils.EMPTY : sort.toString();
}
//
// Operators
//
//
// Logical
//
public static Boolean eq(Object left, Object right) {
return BinaryComparisonOperation.EQ.apply(left, right);
}
public static Boolean nulleq(Object left, Object right) {
return BinaryComparisonOperation.NULLEQ.apply(left, right);
}
public static Boolean neq(Object left, Object right) {
return BinaryComparisonOperation.NEQ.apply(left, right);
}
public static Boolean lt(Object left, Object right) {
return BinaryComparisonOperation.LT.apply(left, right);
}
public static Boolean lte(Object left, Object right) {
return BinaryComparisonOperation.LTE.apply(left, right);
}
public static Boolean gt(Object left, Object right) {
return BinaryComparisonOperation.GT.apply(left, right);
}
public static Boolean gte(Object left, Object right) {
return BinaryComparisonOperation.GTE.apply(left, right);
}
public static Boolean and(Boolean left, Boolean right) {
return BinaryLogicOperation.AND.apply(left, right);
}
public static Boolean or(Boolean left, Boolean right) {
return BinaryLogicOperation.OR.apply(left, right);
}
public static Boolean not(Boolean expression) {
return NotProcessor.apply(expression);
}
}

View File

@ -3,16 +3,16 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.execution.search.extractor.BucketExtractor;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.BucketExtractorProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.ChainingProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.execution.search.extractor.BucketExtractor;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.BucketExtractorProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.ChainingProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
public class AggExtractorInput extends LeafInput<BucketExtractor> {
@ -45,7 +45,7 @@ public class AggExtractorInput extends LeafInput<BucketExtractor> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
// Nothing to collect
}
}

View File

@ -3,11 +3,11 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
public class AggNameInput extends CommonNonExecutableInput<String> {
public AggNameInput(Source source, Expression expression, String context) {

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.AggRef;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.AggRef;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.Objects;

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Attribute;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Attribute;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
/**
* An input that must first be rewritten against the rest of the query
@ -36,7 +36,7 @@ public class AttributeInput extends NonExecutableInput<Attribute> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
// Nothing to extract
}
}

View File

@ -3,11 +3,11 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.Arrays;
import java.util.List;
@ -66,7 +66,7 @@ public abstract class BinaryPipe extends Pipe {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
left.collectFields(sourceBuilder);
right.collectFields(sourceBuilder);
}

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.Source;
/**
* Implementation common to most subclasses of
@ -22,7 +22,7 @@ abstract class CommonNonExecutableInput<T> extends NonExecutableInput<T> {
@Override
public final Processor asProcessor() {
throw new SqlIllegalArgumentException("Unresolved input - needs resolving first");
throw new QlIllegalArgumentException("Unresolved input - needs resolving first");
}
@Override
@ -31,7 +31,7 @@ abstract class CommonNonExecutableInput<T> extends NonExecutableInput<T> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
// Nothing to extract
}
}

View File

@ -3,14 +3,14 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.ConstantProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.ConstantProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
public class ConstantInput extends LeafInput<Object> {
@ -39,7 +39,7 @@ public class ConstantInput extends LeafInput<Object> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
// Nothing to collect
}
}

View File

@ -3,15 +3,15 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.execution.search.extractor.HitExtractor;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.HitExtractorProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.execution.search.extractor.HitExtractor;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.HitExtractorProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
public class HitExtractorInput extends LeafInput<HitExtractor> {
@ -40,7 +40,7 @@ public class HitExtractorInput extends LeafInput<HitExtractor> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
// No fields to collect
}
}

View File

@ -3,10 +3,10 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Objects;

View File

@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.ArrayList;
import java.util.List;

View File

@ -3,12 +3,12 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.Source;
public abstract class NonExecutableInput<T> extends LeafInput<T> {
NonExecutableInput(Source source, Expression expression, T context) {
@ -22,6 +22,6 @@ public abstract class NonExecutableInput<T> extends LeafInput<T> {
@Override
public Processor asProcessor() {
throw new SqlIllegalArgumentException("Unresolved input - needs resolving first");
throw new QlIllegalArgumentException("Unresolved input - needs resolving first");
}
}

View File

@ -3,17 +3,17 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.capabilities.Resolvable;
import org.elasticsearch.xpack.sql.capabilities.Resolvables;
import org.elasticsearch.xpack.sql.execution.search.FieldExtraction;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Attribute;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Node;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.capabilities.Resolvable;
import org.elasticsearch.xpack.ql.capabilities.Resolvables;
import org.elasticsearch.xpack.ql.execution.search.FieldExtraction;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Attribute;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.Node;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.ArrayList;
import java.util.List;
@ -47,7 +47,7 @@ public abstract class Pipe extends Node<Pipe> implements FieldExtraction, Resolv
}
@Override
public void collectFields(SqlSourceBuilder sourceBuilder) {
public void collectFields(QlSourceBuilder sourceBuilder) {
children().forEach(c -> c.collectFields(sourceBuilder));
}

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.FieldExtraction;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.FieldExtraction;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
public class ReferenceInput extends NonExecutableInput<FieldExtraction> {
public ReferenceInput(Source source, Expression expression, FieldExtraction context) {
@ -32,7 +32,7 @@ public class ReferenceInput extends NonExecutableInput<FieldExtraction> {
}
@Override
public final void collectFields(SqlSourceBuilder sourceBuilder) {
public final void collectFields(QlSourceBuilder sourceBuilder) {
context().collectFields(sourceBuilder);
}
}

View File

@ -3,14 +3,14 @@
* 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.sql.expression.gen.pipeline;
package org.elasticsearch.xpack.ql.expression.gen.pipeline;
import org.elasticsearch.xpack.sql.execution.search.SqlSourceBuilder;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.gen.processor.ChainingProcessor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.gen.processor.ChainingProcessor;
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.ql.tree.NodeInfo;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.List;
import java.util.Objects;
@ -74,7 +74,7 @@ public final class UnaryPipe extends Pipe {
}
@Override
public void collectFields(SqlSourceBuilder sourceBuilder) {
public void collectFields(QlSourceBuilder sourceBuilder) {
child.collectFields(sourceBuilder);
}

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.execution.search.extractor.BucketExtractor;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.execution.search.extractor.BucketExtractor;
import java.io.IOException;
import java.util.Objects;
@ -45,7 +45,7 @@ public class BucketExtractorProcessor implements Processor {
@Override
public Object process(Object input) {
if (!(input instanceof Bucket)) {
throw new SqlIllegalArgumentException("Expected an agg bucket but received {}", input);
throw new QlIllegalArgumentException("Expected an agg bucket but received {}", input);
}
return extractor.extract((Bucket) input);
}

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

View File

@ -0,0 +1,16 @@
/*
* 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.gen.processor;
import org.elasticsearch.common.io.stream.NamedWriteable;
/**
* Marker interface used by QL for pluggable constant serialization.
*/
public interface ConstantNamedWriteable extends NamedWriteable {
}

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.StreamInput;
@ -18,26 +18,17 @@ public class ConstantProcessor implements Processor {
private final Object constant;
private final boolean namedWriteable;
private final Class<?> clazz;
public ConstantProcessor(Object value) {
this.constant = value;
this.namedWriteable = value instanceof NamedWriteable;
this.clazz = namedWriteable ? value.getClass() : null;
}
@SuppressWarnings("unchecked")
public ConstantProcessor(StreamInput in) throws IOException {
namedWriteable = in.readBoolean();
if (namedWriteable) {
try {
clazz = ConstantProcessor.class.getClassLoader().loadClass(in.readString());
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
constant = in.readNamedWriteable((Class<NamedWriteable>) clazz);
constant = in.readNamedWriteable(ConstantNamedWriteable.class);
} else {
clazz = null;
constant = in.readGenericValue();
}
}
@ -46,7 +37,6 @@ public class ConstantProcessor implements Processor {
public void writeTo(StreamOutput out) throws IOException {
out.writeBoolean(namedWriteable);
if (namedWriteable) {
out.writeString(constant.getClass().getName());
out.writeNamedWriteable((NamedWriteable) constant);
} else {
out.writeGenericValue(constant);
@ -86,4 +76,4 @@ public class ConstantProcessor implements Processor {
public String toString() {
return "^" + constant;
}
}
}

View File

@ -4,19 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
import java.util.Objects;
import java.util.function.BiFunction;
/**
* Base class for definition binary processors based on functions (for applying) defined as enums (for serialization purposes).
* Base class for definition binary processors based on functions (for applying).
*/
public abstract class FunctionalBinaryProcessor<T, U, R, F extends Enum<F> & BiFunction<T, U, R>> extends BinaryProcessor {
public abstract class FunctionalBinaryProcessor<T, U, R, F extends BiFunction<T, U, R>> extends BinaryProcessor {
private final F function;
@ -34,11 +33,6 @@ public abstract class FunctionalBinaryProcessor<T, U, R, F extends Enum<F> & BiF
return function;
}
@Override
protected void doWrite(StreamOutput out) throws IOException {
out.writeEnum(function());
}
@SuppressWarnings("unchecked")
@Override
protected Object doProcess(Object left, Object right) {

View File

@ -0,0 +1,33 @@
/*
* 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.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
import java.util.function.BiFunction;
/**
* Base class for definition binary processors based on functions (for applying) defined as enums (for serialization purposes).
*/
public abstract class FunctionalEnumBinaryProcessor<T, U, R, F extends Enum<F> & BiFunction<T, U, R>>
extends FunctionalBinaryProcessor<T, U, R, F> {
protected FunctionalEnumBinaryProcessor(Processor left, Processor right, F function) {
super(left, right, function);
}
protected FunctionalEnumBinaryProcessor(StreamInput in, Reader<F> reader) throws IOException {
super(in, reader);
}
@Override
protected void doWrite(StreamOutput out) throws IOException {
out.writeEnum(function());
}
}

View File

@ -3,13 +3,13 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.execution.search.extractor.HitExtractor;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.execution.search.extractor.HitExtractor;
import java.io.IOException;
import java.util.Objects;
@ -45,7 +45,7 @@ public class HitExtractorProcessor implements Processor {
@Override
public Object process(Object input) {
if (!(input instanceof SearchHit)) {
throw new SqlIllegalArgumentException("Expected a SearchHit but received {}", input);
throw new QlIllegalArgumentException("Expected a SearchHit but received {}", input);
}
return extractor.extract((SearchHit) input);
}

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.NamedWriteable;

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.processor;
package org.elasticsearch.xpack.ql.expression.gen.processor;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

View File

@ -3,12 +3,13 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.sql.expression.function.aggregate.Count;
import org.elasticsearch.xpack.sql.expression.function.aggregate.InnerAggregate;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.ql.expression.function.aggregate.Count;
import org.elasticsearch.xpack.ql.expression.function.aggregate.InnerAggregate;
class Agg extends Param<AggregateFunction> {
@ -27,7 +28,7 @@ class Agg extends Param<AggregateFunction> {
if (agg instanceof InnerAggregate) {
InnerAggregate inner = (InnerAggregate) agg;
return Expressions.id(inner.outer()) + "." + inner.innerName();
return Expressions.id((Expression) inner.outer()) + "." + inner.innerName();
}
// Count needs special handling since in most cases it is not a dedicated aggregation
else if (agg instanceof Count) {

View File

@ -3,9 +3,9 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.xpack.sql.expression.function.grouping.GroupingFunction;
import org.elasticsearch.xpack.ql.expression.function.grouping.GroupingFunction;
class Grouping extends Param<GroupingFunction> {

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import java.util.Objects;

View File

@ -3,9 +3,9 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@ -113,7 +113,7 @@ public class Params {
flatten.add(p);
}
else {
throw new SqlIllegalArgumentException("Unsupported field {}", p);
throw new QlIllegalArgumentException("Unsupported field {}", p);
}
}
}

View File

@ -3,10 +3,10 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.xpack.sql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.sql.expression.function.grouping.GroupingFunction;
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.ql.expression.function.grouping.GroupingFunction;
import java.util.ArrayList;
import java.util.List;

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
class Script extends Param<Params> {

View File

@ -3,12 +3,13 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypes;
import org.elasticsearch.xpack.ql.util.StringUtils;
import java.util.List;
import java.util.Locale;
@ -27,7 +28,7 @@ public class ScriptTemplate {
private final DataType outputType;
public ScriptTemplate(String template) {
this(template, Params.EMPTY, DataType.KEYWORD);
this(template, Params.EMPTY, DataTypes.KEYWORD);
}
public ScriptTemplate(String template, Params params, DataType outputType) {

View File

@ -4,13 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
import org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalSqlScriptUtils;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypes;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
@ -19,20 +18,23 @@ import java.util.regex.Pattern;
import java.util.stream.Stream;
import static java.lang.String.format;
import static java.util.Collections.unmodifiableMap;
import static java.util.stream.Collectors.toMap;
import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder;
import static org.elasticsearch.xpack.ql.expression.gen.script.ParamsBuilder.paramsBuilder;
public final class Scripts {
public static final String DOC_VALUE = "doc[{}].value";
public static final String SQL_SCRIPTS = "{sql}";
public static final String PARAM = "{}";
// FIXME: this needs to be either renamed (drop Sql) or find a pluggable approach (through ScriptWeaver)
public static final String INTERNAL_SCRIPT_UTILS = "InternalSqlScriptUtils";
private Scripts() {}
private static final Map<Pattern, String> FORMATTING_PATTERNS = Collections.unmodifiableMap(Stream.of(
static final Map<Pattern, String> FORMATTING_PATTERNS = unmodifiableMap(Stream.of(
new SimpleEntry<>(DOC_VALUE, SQL_SCRIPTS + ".docValue(doc,{})"),
new SimpleEntry<>(SQL_SCRIPTS, InternalSqlScriptUtils.class.getSimpleName()),
new SimpleEntry<>(SQL_SCRIPTS, INTERNAL_SCRIPT_UTILS),
new SimpleEntry<>(PARAM, "params.%s"))
.collect(toMap(e -> Pattern.compile(e.getKey(), Pattern.LITERAL), Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new)));
@ -56,7 +58,7 @@ public final class Scripts {
return new ScriptTemplate(formatTemplate(
format(Locale.ROOT, "{sql}.nullSafeFilter(%s)", script.template())),
script.params(),
DataType.BOOLEAN);
DataTypes.BOOLEAN);
}
public static ScriptTemplate nullSafeSort(ScriptTemplate script) {
@ -68,11 +70,11 @@ public final class Scripts {
}
public static ScriptTemplate and(ScriptTemplate left, ScriptTemplate right) {
return binaryMethod("and", left, right, DataType.BOOLEAN);
return binaryMethod("and", left, right, DataTypes.BOOLEAN);
}
public static ScriptTemplate or(ScriptTemplate left, ScriptTemplate right) {
return binaryMethod("or", left, right, DataType.BOOLEAN);
return binaryMethod("or", left, right, DataTypes.BOOLEAN);
}
public static ScriptTemplate binaryMethod(String methodName, ScriptTemplate leftScript, ScriptTemplate rightScript,

View File

@ -3,7 +3,7 @@
* 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.sql.expression.gen.script;
package org.elasticsearch.xpack.ql.expression.gen.script;
class Var extends Param<Object> {

View File

@ -3,12 +3,12 @@
* 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.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.ql.tree.Source;
/**
* Operator is a specialized binary predicate where both sides have the compatible types

View File

@ -3,11 +3,11 @@
* 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.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.function.scalar.BinaryScalarFunction;
import org.elasticsearch.xpack.ql.tree.Source;
import java.util.Objects;

View File

@ -3,9 +3,9 @@
* 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.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction;
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction;
public interface Negatable<T extends ScalarFunction> {

View File

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import java.util.Locale;
import java.util.function.BiFunction;

View File

@ -3,12 +3,11 @@
* 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.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.predicate.logical.And;
import org.elasticsearch.xpack.sql.expression.predicate.logical.Or;
import org.elasticsearch.xpack.sql.plan.logical.LogicalPlan;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.predicate.logical.And;
import org.elasticsearch.xpack.ql.expression.predicate.logical.Or;
import java.util.ArrayList;
import java.util.List;
@ -113,9 +112,4 @@ public abstract class Predicates {
}
return diff.isEmpty() ? emptyList() : diff;
}
public static boolean canEvaluate(Expression exp, LogicalPlan plan) {
return exp.references().subsetOf(plan.outputSet());
}
}

View File

@ -3,23 +3,24 @@
* 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.sql.expression.predicate;
package org.elasticsearch.xpack.ql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Nullability;
import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.script.Params;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicPipe;
import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicProcessor.BinaryLogicOperation;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparison;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonPipe;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.ql.expression.Expression;
import org.elasticsearch.xpack.ql.expression.Expressions;
import org.elasticsearch.xpack.ql.expression.Nullability;
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.Params;
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.ql.expression.predicate.logical.BinaryLogicPipe;
import org.elasticsearch.xpack.ql.expression.predicate.logical.BinaryLogicProcessor.BinaryLogicOperation;
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparison;
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparisonPipe;
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation;
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.DataTypes;
import java.util.List;
import java.util.Locale;
@ -27,7 +28,7 @@ import java.util.Objects;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder;
import static org.elasticsearch.xpack.ql.expression.gen.script.ParamsBuilder.paramsBuilder;
// BETWEEN or range - is a mix of gt(e) AND lt(e)
public class Range extends ScalarFunction {
@ -118,7 +119,7 @@ public class Range extends ScalarFunction {
@Override
public DataType dataType() {
return DataType.BOOLEAN;
return DataTypes.BOOLEAN;
}
@Override
@ -144,7 +145,7 @@ public class Range extends ScalarFunction {
.script(upperScript.params())
.build();
return new ScriptTemplate(template, params, DataType.BOOLEAN);
return new ScriptTemplate(template, params, DataTypes.BOOLEAN);
}
@Override

Some files were not shown because too many files have changed in this diff Show More