Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Support of nested function calls in new engine #1175

Open
wants to merge 52 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
599a8ab
Support long literals (#2)
FreCap May 6, 2021
8b942a6
Adding support to NOT REGEXP_QUERY, which is currently failing when r…
FreCap May 6, 2021
b021028
Merge branch 'opendistro-for-elasticsearch:develop' into develop
FreCap May 20, 2021
4a5f712
In support (#3)
FreCap May 22, 2021
f6d62d3
Date Autocast for new engine
FreCap Jun 1, 2021
862b9c4
Merge branch 'develop' into date-autocast-new-engine
FreCap Jun 1, 2021
a6e0935
Date Autocast for new engine
FreCap Jun 1, 2021
08f83b6
Merge remote-tracking branch 'freRemote/date-autocast-new-engine' int…
FreCap Jun 1, 2021
4910e2d
Date Autocast for new engine
FreCap Jun 1, 2021
76248c7
Adding field comparison in Legacy Engine
FreCap Jun 7, 2021
3a93478
Adding support for much more permissive date parsing for ExprTimestam…
FreCap Jun 12, 2021
656ea2a
Merge pull request #2 from FreCap/add-support-timestamp-without-t
FreCap Jun 12, 2021
0284f03
Legacy: field comparison, adding support to <> operator (behave as !=)
FreCap Jun 19, 2021
69b82eb
Merge branch 'date-autocast-new-engine' into comparison-datecast
FreCap Jun 30, 2021
19bedb2
Fixing date after merge
FreCap Jul 1, 2021
e0928c4
Revert "In support (#3)"
FreCap Jul 1, 2021
ea83334
Allowing customizing the number of nested results through config
FreCap Jul 8, 2021
6645080
Merge branch 'comparison-datecast' into nestedLimit-comparison-datecast
FreCap Jul 21, 2021
6114478
Improved support of jdbc format for nested fields in SELECT statements
Aug 13, 2021
1a9d1aa
Improved support of jdbc format for nested fields in SELECT statements
Aug 13, 2021
880c258
Now jdbc format takes into account limit (if it exists) when flatteni…
Aug 15, 2021
5072613
Updated some variable names for clarity's sake
Aug 15, 2021
4a70d84
Merge branch 'jdbc-nested' into nestedLimit-comparison-datecast
Aug 15, 2021
501ab9f
Test commit
Aug 15, 2021
7df68e4
Update actions to run on next LTS Ubuntu version
Aug 15, 2021
a17f901
Update actions to run on next LTS Ubuntu version
Aug 15, 2021
b670e86
Merge branch 'nestedLimit-comparison-datecast' into enforceLimit-nest…
Aug 15, 2021
953ad26
Implemented "greatest" and "least" functions in old engine
cip999 Aug 21, 2021
83107e0
Implemented "greatest" and "least" functions in old engine
cip999 Aug 22, 2021
f5ea58b
Merge branch 'jdbc-nested' into greatestLeastFunctions
cip999 Aug 22, 2021
3644545
Merge branch 'greatestFunction-temp' into greatestLeastFunctions
cip999 Aug 22, 2021
89a6567
Added "datetime_format" URL parameter to handle jdbj date and time fo…
Aug 18, 2021
209664b
Added "datetime_format" URL parameter to handle jdbj date and time fo…
Aug 18, 2021
b412e9a
Added "datetime_format" URL parameter to handle jdbj date and time fo…
Aug 18, 2021
fdfec15
Added "datetime_format" URL parameter to handle jdbj date and time fo…
Aug 18, 2021
39380c2
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
60da9ed
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
ea616d8
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
b6b925d
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
8fb065c
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
8c99a03
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
e892bda
Added "datetime_format" URL parameter to handle jdbc date and time fo…
cip999 Aug 20, 2021
ccbbe49
Massive refactoring of modules handling SQL functions to allow for ne…
cip999 Aug 24, 2021
92ca579
Merge branch 'SQLFunctionsEncapsulation-temp' into SQLFunctionsEncaps…
cip999 Aug 24, 2021
9f91648
Massive refactoring of modules handling SQL functions to allow for ne…
cip999 Aug 24, 2021
76a357f
Merge branch 'SQLFunctionsEncapsulation-temp' into SQLFunctionsEncaps…
cip999 Aug 24, 2021
27450a7
Massive refactoring of modules handling SQL functions to allow for ne…
cip999 Aug 25, 2021
86a7e3e
Merge branch 'SQLFunctionsEncapsulation-temp' into SQLFunctionsEncaps…
cip999 Aug 25, 2021
3d10353
Massive refactoring of modules handling SQL functions to allow for ne…
cip999 Aug 25, 2021
c406750
Merge branch 'SQLFunctionsEncapsulation-temp' into SQLFunctionsEncaps…
cip999 Aug 25, 2021
6b7ef8b
Fixed bug in SQL comparison functions implementation
cip999 Aug 26, 2021
e6bc19e
Merge branch 'SQLFunctionsEncapsulation-temp' into SQLFunctionsEncaps…
cip999 Aug 26, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/sql-cli-release-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
build:

runs-on: [ubuntu-16.04]
runs-on: [ubuntu-18.04]
defaults:
run:
working-directory: sql-cli
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sql-cli-test-and-build-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [pull_request, push]
jobs:
build:

runs-on: [ubuntu-16.04]
runs-on: [ubuntu-18.04]
defaults:
run:
working-directory: sql-cli
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sql-jdbc-push-jdbc-maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
upload-jdbc-jar:
runs-on: [ubuntu-16.04]
runs-on: [ubuntu-18.04]
defaults:
run:
working-directory: sql-jdbc
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sql-release-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
java: [14]

name: Build and Release SQL Plugin
runs-on: [ubuntu-16.04]
runs-on: [ubuntu-18.04]

steps:
- name: Checkout SQL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.amazon.opendistroforelasticsearch.sql.data.type.ExprCoreType;
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprType;
import com.amazon.opendistroforelasticsearch.sql.data.utils.ExprDateFormatters;
import com.amazon.opendistroforelasticsearch.sql.exception.SemanticCheckException;
import com.google.common.base.Objects;
import java.time.Instant;
Expand All @@ -26,37 +27,21 @@
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class ExprDatetimeValue extends AbstractExprValue {
private final LocalDateTime datetime;

private static final DateTimeFormatter FORMATTER_VARIABLE_MICROS;
private static final int MIN_FRACTION_SECONDS = 0;
private static final int MAX_FRACTION_SECONDS = 6;

static {
FORMATTER_VARIABLE_MICROS = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.appendFraction(
ChronoField.MICRO_OF_SECOND,
MIN_FRACTION_SECONDS,
MAX_FRACTION_SECONDS,
true)
.toFormatter();
}

/**
* Constructor with datetime string as input.
*/
public ExprDatetimeValue(String datetime) {
try {
this.datetime = LocalDateTime.parse(datetime, FORMATTER_VARIABLE_MICROS);
this.datetime = LocalDateTime.parse(datetime,
ExprDateFormatters.TOLERANT_PARSER_DATE_TIME_FORMATTER);
} catch (DateTimeParseException e) {
throw new SemanticCheckException(String.format("datetime:%s in unsupported format, please "
+ "use yyyy-MM-dd HH:mm:ss[.SSSSSS]", datetime));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprCoreType;
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprType;
import com.amazon.opendistroforelasticsearch.sql.exception.SemanticCheckException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
Expand Down Expand Up @@ -80,6 +81,11 @@ public LocalTime timeValue() {
}
}

@Override
public Instant timestampValue() {
return new ExprTimestampValue(value).timestampValue();
}

@Override
public String toString() {
return String.format("\"%s\"", value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.amazon.opendistroforelasticsearch.sql.data.type.ExprCoreType;
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprType;
import com.amazon.opendistroforelasticsearch.sql.data.utils.ExprDateFormatters;
import com.amazon.opendistroforelasticsearch.sql.exception.SemanticCheckException;
import java.time.Instant;
import java.time.LocalDate;
Expand All @@ -45,14 +46,22 @@ public class ExprTimestampValue extends AbstractExprValue {
/**
* todo. only support timestamp in format yyyy-MM-dd HH:mm:ss.
*/
private static final DateTimeFormatter FORMATTER_WITNOUT_NANO = DateTimeFormatter
private static final DateTimeFormatter FORMATTER_WITHOUT_NANO = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter FORMATTER_WITHOUT_TIME = DateTimeFormatter
.ofPattern("yyyy-MM-dd");
private final Instant timestamp;

private String datetimeFormat = ALWAYS_INCLUDE_TIME;

private static final DateTimeFormatter FORMATTER_VARIABLE_MICROS;
private static final int MIN_FRACTION_SECONDS = 0;
private static final int MAX_FRACTION_SECONDS = 6;

public static final String ALWAYS_INCLUDE_TIME = "always_include_time";
public static final String NEVER_INCLUDE_TIME = "never_include_time";
public static final String INCLUDE_TIME_WHEN_NONZERO = "include_time_when_nonzero";

static {
FORMATTER_VARIABLE_MICROS = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
Expand All @@ -69,7 +78,8 @@ public class ExprTimestampValue extends AbstractExprValue {
*/
public ExprTimestampValue(String timestamp) {
try {
this.timestamp = LocalDateTime.parse(timestamp, FORMATTER_VARIABLE_MICROS)
this.timestamp = LocalDateTime.parse(timestamp,
ExprDateFormatters.TOLERANT_PARSER_DATE_TIME_FORMATTER)
.atZone(ZONE)
.toInstant();
} catch (DateTimeParseException e) {
Expand All @@ -81,9 +91,29 @@ public ExprTimestampValue(String timestamp) {

@Override
public String value() {
return timestamp.getNano() == 0 ? FORMATTER_WITNOUT_NANO.withZone(ZONE)
.format(timestamp.truncatedTo(ChronoUnit.SECONDS))
: FORMATTER_VARIABLE_MICROS.withZone(ZONE).format(timestamp);
switch (datetimeFormat) {
case NEVER_INCLUDE_TIME:
return valueWithoutTime();

case INCLUDE_TIME_WHEN_NONZERO:
LocalTime time = timeValue();
return (time.getHour() + time.getMinute() + time.getSecond() == 0)
? valueWithoutTime() : valueWithTime();

case ALWAYS_INCLUDE_TIME:
default:
return valueWithTime();
}
}

private String valueWithTime() {
return timestamp.getNano() == 0 ? FORMATTER_WITHOUT_NANO.withZone(ZONE)
.format(timestamp.truncatedTo(ChronoUnit.SECONDS))
: FORMATTER_VARIABLE_MICROS.withZone(ZONE).format(timestamp);
}

private String valueWithoutTime() {
return FORMATTER_WITHOUT_TIME.withZone(ZONE).format(timestamp);
}

@Override
Expand Down Expand Up @@ -130,4 +160,9 @@ public boolean equal(ExprValue other) {
public int hashCode() {
return Objects.hashCode(timestamp);
}

public void setDatetimeFormat(String format) {
this.datetimeFormat = format;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,8 @@ public static List<ExprCoreType> coreTypes() {
public static List<ExprType> numberTypes() {
return ImmutableList.of(INTEGER, LONG, FLOAT, DOUBLE);
}

public static List<ExprType> dateTypes() {
return ImmutableList.of(DATE, DATETIME, TIMESTAMP, TIME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
*/

package com.amazon.opendistroforelasticsearch.sql.elasticsearch.data.value;
package com.amazon.opendistroforelasticsearch.sql.data.utils;

import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
Expand All @@ -37,7 +37,7 @@
* Reference org.elasticsearch.common.time.DateFormatters.
*/
@UtilityClass
public class ElasticsearchDateFormatters {
public class ExprDateFormatters {

public static final DateTimeFormatter TIME_ZONE_FORMATTER_NO_COLON =
new DateTimeFormatterBuilder()
Expand Down Expand Up @@ -73,7 +73,16 @@ public class ElasticsearchDateFormatters {
new DateTimeFormatterBuilder()
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
.optionalStart()

// otherwise use space
.optionalStart()
.appendLiteral(' ')
.optionalEnd()
// optional T
.optionalStart()
.appendLiteral('T')
.optionalEnd()

.optionalStart()
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
.optionalStart()
Expand All @@ -82,13 +91,18 @@ public class ElasticsearchDateFormatters {
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)

// optional millis with dot
.optionalStart()
.appendFraction(NANO_OF_SECOND, 1, 9, true)
.optionalEnd()

// otherwise optional millis use with comma
.optionalStart()
.appendLiteral(',')
.appendFraction(NANO_OF_SECOND, 1, 9, false)
.optionalEnd()

.optionalEnd()
.optionalEnd()
.optionalStart()
Expand All @@ -104,4 +118,11 @@ public class ElasticsearchDateFormatters {

public static final DateTimeFormatter SQL_LITERAL_DATE_TIME_FORMAT = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");

public static final DateTimeFormatter TOLERANT_PARSER_DATE_TIME_FORMATTER =
new DateTimeFormatterBuilder()
.appendOptional(STRICT_DATE_OPTIONAL_TIME_FORMATTER)
.appendOptional(SQL_LITERAL_DATE_TIME_FORMAT)
.appendOptional(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
.toFormatter();
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,26 @@

import com.amazon.opendistroforelasticsearch.sql.data.model.ExprBooleanValue;
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprValue;
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprValueUtils;
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprCoreType;
import com.amazon.opendistroforelasticsearch.sql.expression.function.BuiltinFunctionName;
import com.amazon.opendistroforelasticsearch.sql.expression.function.BuiltinFunctionRepository;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionBuilder;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionDSL;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionName;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionResolver;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionSignature;
import com.amazon.opendistroforelasticsearch.sql.expression.function.SerializableFunction;
import com.amazon.opendistroforelasticsearch.sql.utils.OperatorUtils;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import java.io.Serializable;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.tuple.Pair;


/**
* The definition of binary predicate function
Expand Down Expand Up @@ -192,53 +202,44 @@ private static FunctionResolver notEqual() {
}

private static FunctionResolver less() {
return FunctionDSL
.define(BuiltinFunctionName.LESS.getName(), ExprCoreType.coreTypes().stream()
.map(type -> FunctionDSL
.impl(FunctionDSL
.nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) < 0)),
BOOLEAN,
type, type))
.collect(
Collectors.toList()));
return FunctionDSL.define(BuiltinFunctionName.LESS.getName(),
getComparisonFunctions((Function<Integer, Boolean> & Serializable) value -> value < 0));
}

private static FunctionResolver lte() {
return FunctionDSL
.define(BuiltinFunctionName.LTE.getName(), ExprCoreType.coreTypes().stream()
.map(type -> FunctionDSL
.impl(
FunctionDSL
.nullMissingHandling(
(v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) <= 0)),
BOOLEAN,
type, type))
.collect(
Collectors.toList()));
return FunctionDSL.define(BuiltinFunctionName.LTE.getName(),
getComparisonFunctions((Function<Integer, Boolean> & Serializable) value -> value <= 0));
}

private static FunctionResolver greater() {
return FunctionDSL
.define(BuiltinFunctionName.GREATER.getName(), ExprCoreType.coreTypes().stream()
.map(type -> FunctionDSL
.impl(FunctionDSL
.nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) > 0)),
BOOLEAN, type, type))
.collect(
Collectors.toList()));
return FunctionDSL.define(BuiltinFunctionName.GREATER.getName(),
getComparisonFunctions((Function<Integer, Boolean> & Serializable) value -> value > 0));
}

private static FunctionResolver gte() {
return FunctionDSL
.define(BuiltinFunctionName.GTE.getName(), ExprCoreType.coreTypes().stream()
.map(type -> FunctionDSL
.impl(
FunctionDSL.nullMissingHandling(
(v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) >= 0)),
BOOLEAN,
type, type))
.collect(
Collectors.toList()));
return FunctionDSL.define(BuiltinFunctionName.GTE.getName(),
getComparisonFunctions((Function<Integer, Boolean> & Serializable) value -> value >= 0));
}

private static List<SerializableFunction<FunctionName, Pair<FunctionSignature, FunctionBuilder>>>
getComparisonFunctions(Function<Integer, Boolean> f) {
List<SerializableFunction<FunctionName, Pair<FunctionSignature, FunctionBuilder>>>
comparisonFunctions = ExprCoreType.coreTypes()
.stream()
.map(type -> FunctionDSL.impl(FunctionDSL.nullMissingHandling(
(v1, v2) -> ExprBooleanValue.of(f.apply(v1.compareTo(v2)))), BOOLEAN, type, type))
.collect(Collectors.toList());

// all string to date conversions
comparisonFunctions.addAll(ExprCoreType.dateTypes()
.stream()
.map(type -> FunctionDSL.impl(FunctionDSL.nullMissingHandling((v1, v2) -> {
// casting V2 from string to whatever type v1 is
ExprValue v2Casted = ExprValueUtils.fromObjectValue(v2.value(), (ExprCoreType) v1.type());
return ExprBooleanValue.of(f.apply(v1.compareTo(v2Casted)));
}), BOOLEAN, type, STRING))
.collect(Collectors.toList()));
return comparisonFunctions;
}

private static FunctionResolver like() {
Expand Down
Loading