Skip to content

Commit

Permalink
Refactor relevance search functions
Browse files Browse the repository at this point in the history
- Update QueryStringTest to check for SyntaxCheckException.
SyntaxCheckException is correct when incorrect # of parameters
See opensearch-project#604 (comment)
for reference.

- Introduce MultiFieldQuery and SingleFieldQuery base classes.

- Extract FunctionResolver interface. FunctionResolver is now
 DefaultFunctionResolver. RelevanceFunctionResolver is a simplified
 function resolver for relevance search functions.
- Removed tests from FilterQueryBuilderTest that verified exceptions
 thrown for invalid function calls.
 These scenarios are now handled by RelevanceQuery::build.

Signed-off-by: MaxKsyunz <maxk@bitquilltech.com>
  • Loading branch information
MaxKsyunz committed Aug 18, 2022
1 parent 8103d9f commit e76dc6e
Show file tree
Hide file tree
Showing 39 changed files with 703 additions and 550 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import org.opensearch.sql.data.type.ExprCoreType;
import org.opensearch.sql.expression.function.BuiltinFunctionName;
import org.opensearch.sql.expression.function.BuiltinFunctionRepository;
import org.opensearch.sql.expression.function.DefaultFunctionResolver;
import org.opensearch.sql.expression.function.FunctionBuilder;
import org.opensearch.sql.expression.function.FunctionName;
import org.opensearch.sql.expression.function.FunctionResolver;
import org.opensearch.sql.expression.function.FunctionSignature;

/**
Expand All @@ -44,6 +44,7 @@
public class AggregatorFunction {
/**
* Register Aggregation Function.
*
* @param repository {@link BuiltinFunctionRepository}.
*/
public static void register(BuiltinFunctionRepository repository) {
Expand All @@ -58,9 +59,9 @@ public static void register(BuiltinFunctionRepository repository) {
repository.register(stddevPop());
}

private static FunctionResolver avg() {
private static DefaultFunctionResolver avg() {
FunctionName functionName = BuiltinFunctionName.AVG.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)),
Expand All @@ -69,18 +70,18 @@ private static FunctionResolver avg() {
);
}

private static FunctionResolver count() {
private static DefaultFunctionResolver count() {
FunctionName functionName = BuiltinFunctionName.COUNT.getName();
FunctionResolver functionResolver = new FunctionResolver(functionName,
DefaultFunctionResolver functionResolver = new DefaultFunctionResolver(functionName,
ExprCoreType.coreTypes().stream().collect(Collectors.toMap(
type -> new FunctionSignature(functionName, Collections.singletonList(type)),
type -> arguments -> new CountAggregator(arguments, INTEGER))));
return functionResolver;
}

private static FunctionResolver sum() {
private static DefaultFunctionResolver sum() {
FunctionName functionName = BuiltinFunctionName.SUM.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)),
Expand All @@ -95,9 +96,9 @@ private static FunctionResolver sum() {
);
}

private static FunctionResolver min() {
private static DefaultFunctionResolver min() {
FunctionName functionName = BuiltinFunctionName.MIN.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)),
Expand All @@ -121,9 +122,9 @@ private static FunctionResolver min() {
.build());
}

private static FunctionResolver max() {
private static DefaultFunctionResolver max() {
FunctionName functionName = BuiltinFunctionName.MAX.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)),
Expand All @@ -148,9 +149,9 @@ private static FunctionResolver max() {
);
}

private static FunctionResolver varSamp() {
private static DefaultFunctionResolver varSamp() {
FunctionName functionName = BuiltinFunctionName.VARSAMP.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)),
Expand All @@ -159,9 +160,9 @@ private static FunctionResolver varSamp() {
);
}

private static FunctionResolver varPop() {
private static DefaultFunctionResolver varPop() {
FunctionName functionName = BuiltinFunctionName.VARPOP.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)),
Expand All @@ -170,9 +171,9 @@ private static FunctionResolver varPop() {
);
}

private static FunctionResolver stddevSamp() {
private static DefaultFunctionResolver stddevSamp() {
FunctionName functionName = BuiltinFunctionName.STDDEV_SAMP.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)),
Expand All @@ -181,9 +182,9 @@ private static FunctionResolver stddevSamp() {
);
}

private static FunctionResolver stddevPop() {
private static DefaultFunctionResolver stddevPop() {
FunctionName functionName = BuiltinFunctionName.STDDEV_POP.getName();
return new FunctionResolver(
return new DefaultFunctionResolver(
functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.opensearch.sql.data.model.ExprValue;
import org.opensearch.sql.expression.function.BuiltinFunctionName;
import org.opensearch.sql.expression.function.BuiltinFunctionRepository;
import org.opensearch.sql.expression.function.DefaultFunctionResolver;
import org.opensearch.sql.expression.function.FunctionName;
import org.opensearch.sql.expression.function.FunctionResolver;

Expand Down Expand Up @@ -94,7 +95,7 @@ public void register(BuiltinFunctionRepository repository) {
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME
*/

private FunctionResolver add_date(FunctionName functionName) {
private DefaultFunctionResolver add_date(FunctionName functionName) {
return define(functionName,
impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval),
DATETIME, STRING, INTERVAL),
Expand All @@ -110,7 +111,7 @@ private FunctionResolver add_date(FunctionName functionName) {
);
}

private FunctionResolver adddate() {
private DefaultFunctionResolver adddate() {
return add_date(BuiltinFunctionName.ADDDATE.getName());
}

Expand All @@ -119,15 +120,15 @@ private FunctionResolver adddate() {
* Also to construct a date type. The supported signatures:
* STRING/DATE/DATETIME/TIMESTAMP -> DATE
*/
private FunctionResolver date() {
private DefaultFunctionResolver date() {
return define(BuiltinFunctionName.DATE.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING),
impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATETIME),
impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIMESTAMP));
}

private FunctionResolver date_add() {
private DefaultFunctionResolver date_add() {
return add_date(BuiltinFunctionName.DATE_ADD.getName());
}

Expand All @@ -138,7 +139,7 @@ private FunctionResolver date_add() {
* (DATE, LONG) -> DATE
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME
*/
private FunctionResolver sub_date(FunctionName functionName) {
private DefaultFunctionResolver sub_date(FunctionName functionName) {
return define(functionName,
impl(nullMissingHandling(DateTimeFunction::exprSubDateInterval),
DATETIME, STRING, INTERVAL),
Expand All @@ -154,14 +155,14 @@ private FunctionResolver sub_date(FunctionName functionName) {
);
}

private FunctionResolver date_sub() {
private DefaultFunctionResolver date_sub() {
return sub_date(BuiltinFunctionName.DATE_SUB.getName());
}

/**
* DAY(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31).
*/
private FunctionResolver day() {
private DefaultFunctionResolver day() {
return define(BuiltinFunctionName.DAY.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME),
Expand All @@ -175,7 +176,7 @@ private FunctionResolver day() {
* return the name of the weekday for date, including Monday, Tuesday, Wednesday,
* Thursday, Friday, Saturday and Sunday.
*/
private FunctionResolver dayName() {
private DefaultFunctionResolver dayName() {
return define(BuiltinFunctionName.DAYNAME.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATETIME),
Expand All @@ -187,7 +188,7 @@ private FunctionResolver dayName() {
/**
* DAYOFMONTH(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31).
*/
private FunctionResolver dayOfMonth() {
private DefaultFunctionResolver dayOfMonth() {
return define(BuiltinFunctionName.DAYOFMONTH.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME),
Expand All @@ -200,7 +201,7 @@ private FunctionResolver dayOfMonth() {
* DAYOFWEEK(STRING/DATE/DATETIME/TIMESTAMP).
* return the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday).
*/
private FunctionResolver dayOfWeek() {
private DefaultFunctionResolver dayOfWeek() {
return define(BuiltinFunctionName.DAYOFWEEK.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATETIME),
Expand All @@ -213,7 +214,7 @@ private FunctionResolver dayOfWeek() {
* DAYOFYEAR(STRING/DATE/DATETIME/TIMESTAMP).
* return the day of the year for date (1-366).
*/
private FunctionResolver dayOfYear() {
private DefaultFunctionResolver dayOfYear() {
return define(BuiltinFunctionName.DAYOFYEAR.getName(),
impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATETIME),
Expand All @@ -225,15 +226,15 @@ private FunctionResolver dayOfYear() {
/**
* FROM_DAYS(LONG). return the date value given the day number N.
*/
private FunctionResolver from_days() {
private DefaultFunctionResolver from_days() {
return define(BuiltinFunctionName.FROM_DAYS.getName(),
impl(nullMissingHandling(DateTimeFunction::exprFromDays), DATE, LONG));
}

/**
* HOUR(STRING/TIME/DATETIME/TIMESTAMP). return the hour value for time.
*/
private FunctionResolver hour() {
private DefaultFunctionResolver hour() {
return define(BuiltinFunctionName.HOUR.getName(),
impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, STRING),
impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIME),
Expand All @@ -255,7 +256,7 @@ private FunctionResolver maketime() {
/**
* MICROSECOND(STRING/TIME/DATETIME/TIMESTAMP). return the microsecond value for time.
*/
private FunctionResolver microsecond() {
private DefaultFunctionResolver microsecond() {
return define(BuiltinFunctionName.MICROSECOND.getName(),
impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, STRING),
impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIME),
Expand All @@ -267,7 +268,7 @@ private FunctionResolver microsecond() {
/**
* MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time.
*/
private FunctionResolver minute() {
private DefaultFunctionResolver minute() {
return define(BuiltinFunctionName.MINUTE.getName(),
impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, STRING),
impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIME),
Expand All @@ -279,7 +280,7 @@ private FunctionResolver minute() {
/**
* MONTH(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-12).
*/
private FunctionResolver month() {
private DefaultFunctionResolver month() {
return define(BuiltinFunctionName.MONTH.getName(),
impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATETIME),
Expand All @@ -291,7 +292,7 @@ private FunctionResolver month() {
/**
* MONTHNAME(STRING/DATE/DATETIME/TIMESTAMP). return the full name of the month for date.
*/
private FunctionResolver monthName() {
private DefaultFunctionResolver monthName() {
return define(BuiltinFunctionName.MONTHNAME.getName(),
impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATE),
impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATETIME),
Expand All @@ -303,7 +304,7 @@ private FunctionResolver monthName() {
/**
* QUARTER(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-4).
*/
private FunctionResolver quarter() {
private DefaultFunctionResolver quarter() {
return define(BuiltinFunctionName.QUARTER.getName(),
impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATETIME),
Expand All @@ -315,7 +316,7 @@ private FunctionResolver quarter() {
/**
* SECOND(STRING/TIME/DATETIME/TIMESTAMP). return the second value for time.
*/
private FunctionResolver second() {
private DefaultFunctionResolver second() {
return define(BuiltinFunctionName.SECOND.getName(),
impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, STRING),
impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIME),
Expand All @@ -324,7 +325,7 @@ private FunctionResolver second() {
);
}

private FunctionResolver subdate() {
private DefaultFunctionResolver subdate() {
return sub_date(BuiltinFunctionName.SUBDATE.getName());
}

Expand All @@ -333,7 +334,7 @@ private FunctionResolver subdate() {
* Also to construct a time type. The supported signatures:
* STRING/DATE/DATETIME/TIME/TIMESTAMP -> TIME
*/
private FunctionResolver time() {
private DefaultFunctionResolver time() {
return define(BuiltinFunctionName.TIME.getName(),
impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, STRING),
impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATE),
Expand All @@ -345,7 +346,7 @@ private FunctionResolver time() {
/**
* TIME_TO_SEC(STRING/TIME/DATETIME/TIMESTAMP). return the time argument, converted to seconds.
*/
private FunctionResolver time_to_sec() {
private DefaultFunctionResolver time_to_sec() {
return define(BuiltinFunctionName.TIME_TO_SEC.getName(),
impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, STRING),
impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIME),
Expand All @@ -359,7 +360,7 @@ private FunctionResolver time_to_sec() {
* Also to construct a date type. The supported signatures:
* STRING/DATE/DATETIME/TIMESTAMP -> DATE
*/
private FunctionResolver timestamp() {
private DefaultFunctionResolver timestamp() {
return define(BuiltinFunctionName.TIMESTAMP.getName(),
impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, STRING),
impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, DATE),
Expand All @@ -370,7 +371,7 @@ private FunctionResolver timestamp() {
/**
* TO_DAYS(STRING/DATE/DATETIME/TIMESTAMP). return the day number of the given date.
*/
private FunctionResolver to_days() {
private DefaultFunctionResolver to_days() {
return define(BuiltinFunctionName.TO_DAYS.getName(),
impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, STRING),
impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, TIMESTAMP),
Expand All @@ -381,7 +382,7 @@ private FunctionResolver to_days() {
/**
* WEEK(DATE[,mode]). return the week number for date.
*/
private FunctionResolver week() {
private DefaultFunctionResolver week() {
return define(BuiltinFunctionName.WEEK.getName(),
impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATETIME),
Expand All @@ -397,7 +398,7 @@ private FunctionResolver week() {
/**
* YEAR(STRING/DATE/DATETIME/TIMESTAMP). return the year for date (1000-9999).
*/
private FunctionResolver year() {
private DefaultFunctionResolver year() {
return define(BuiltinFunctionName.YEAR.getName(),
impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATETIME),
Expand All @@ -414,7 +415,7 @@ private FunctionResolver year() {
* (DATETIME, STRING) -> STRING
* (TIMESTAMP, STRING) -> STRING
*/
private FunctionResolver date_format() {
private DefaultFunctionResolver date_format() {
return define(BuiltinFunctionName.DATE_FORMAT.getName(),
impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate),
STRING, STRING, STRING),
Expand Down Expand Up @@ -711,6 +712,7 @@ private ExprValue exprToDays(ExprValue date) {

/**
* Week for date implementation for ExprValue.
*
* @param date ExprValue of Date/Datetime/Timestamp/String type.
* @param mode ExprValue of Integer type.
*/
Expand All @@ -722,6 +724,7 @@ private ExprValue exprWeek(ExprValue date, ExprValue mode) {
/**
* Week for date implementation for ExprValue.
* When mode is not specified default value mode 0 is used for default_week_format.
*
* @param date ExprValue of Date/Datetime/Timestamp/String type.
* @return ExprValue.
*/
Expand Down
Loading

0 comments on commit e76dc6e

Please sign in to comment.