Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.opensearch.sql.ast.expression.RelevanceFieldList;
import org.opensearch.sql.ast.expression.Span;
import org.opensearch.sql.ast.expression.SpanUnit;
import org.opensearch.sql.ast.expression.UnresolvedArgument;
import org.opensearch.sql.ast.expression.UnresolvedExpression;
import org.opensearch.sql.ast.expression.When;
import org.opensearch.sql.ast.expression.WindowFunction;
Expand Down Expand Up @@ -669,6 +670,28 @@ public RexNode visitWhen(When node, CalcitePlanContext context) {

@Override
public RexNode visitRelevanceFieldList(RelevanceFieldList node, CalcitePlanContext context) {
throw new CalciteUnsupportedException("Relevance fields expression is unsupported in Calcite");
List<RexNode> varArgRexNodeList = new ArrayList<>();
node.getFieldList()
.forEach(
(k, v) -> {
varArgRexNodeList.add(
context.rexBuilder.makeLiteral(
k,
context.rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR),
true));
varArgRexNodeList.add(
context.rexBuilder.makeLiteral(
v,
context.rexBuilder.getTypeFactory().createSqlType(SqlTypeName.DOUBLE),
true));
});
return context.rexBuilder.makeCall(
SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR, varArgRexNodeList);
}

@Override
public RexNode visitUnresolvedArgument(UnresolvedArgument node, CalcitePlanContext context) {
RexNode value = analyze(node.getValue(), context);
return context.relBuilder.alias(value, node.getArgName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import static org.opensearch.sql.calcite.utils.OpenSearchTypeFactory.*;
import static org.opensearch.sql.calcite.utils.OpenSearchTypeFactory.ExprUDT.*;

import com.google.common.collect.ImmutableSet;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import javax.annotation.Nullable;
import org.apache.calcite.DataContext;
Expand Down Expand Up @@ -70,6 +72,10 @@ public class UserDefinedFunctionUtils {
TYPE_FACTORY.createMapType(
TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR),
createArrayType(TYPE_FACTORY, TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR), false));
public static Set<String> SINGLE_FIELD_RELEVANCE_FUNCTION_SET =
ImmutableSet.of("match", "match_phrase", "match_bool_prefix", "match_phrase_prefix");
public static Set<String> MULTI_FIELDS_RELEVANCE_FUNCTION_SET =
ImmutableSet.of("simple_query_string", "query_string", "multi_match");

public static RelBuilder.AggCall TransferUserDefinedAggFunction(
Class<? extends UserDefinedAggFunction> UDAF,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.opensearch.sql.expression.function.jsonUDF.JsonSetFunctionImpl;
import org.opensearch.sql.expression.function.udf.CryptographicFunction;
import org.opensearch.sql.expression.function.udf.GrokFunction;
import org.opensearch.sql.expression.function.udf.RelevanceQueryFunction;
import org.opensearch.sql.expression.function.udf.SpanFunction;
import org.opensearch.sql.expression.function.udf.condition.EarliestFunction;
import org.opensearch.sql.expression.function.udf.condition.LatestFunction;
Expand Down Expand Up @@ -327,6 +328,22 @@ public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {
public static final SqlOperator TRANSFORM = new TransformFunctionImpl().toUDF("transform");
public static final SqlOperator REDUCE = new ReduceFunctionImpl().toUDF("reduce");

private static final RelevanceQueryFunction RELEVANCE_QUERY_FUNCTION_INSTANCE =
new RelevanceQueryFunction();
public static final SqlOperator MATCH = RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("match");
public static final SqlOperator MATCH_PHRASE =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("match_phrase");
public static final SqlOperator MATCH_BOOL_PREFIX =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("match_bool_prefix");
public static final SqlOperator MATCH_PHRASE_PREFIX =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("match_phrase_prefix");
public static final SqlOperator SIMPLE_QUERY_STRING =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("simple_query_string");
public static final SqlOperator QUERY_STRING =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("query_string");
public static final SqlOperator MULTI_MATCH =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("multi_match");

/**
* Invoking an implementor registered in {@link RexImpTable}, need to use reflection since they're
* all private Use method directly in {@link BuiltInMethod} if possible, most operators'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
import static org.opensearch.sql.expression.function.BuiltinFunctionName.LTRIM;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MAKEDATE;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MAKETIME;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MATCH;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MATCH_BOOL_PREFIX;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MATCH_PHRASE;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MATCH_PHRASE_PREFIX;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MAX;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MD5;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MICROSECOND;
Expand All @@ -133,6 +137,7 @@
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MONTHNAME;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MONTH_OF_YEAR;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MULTIPLY;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MULTI_MATCH;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.NOT;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.NOTEQUAL;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.NOW;
Expand All @@ -146,6 +151,7 @@
import static org.opensearch.sql.expression.function.BuiltinFunctionName.POW;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.POWER;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.QUARTER;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.QUERY_STRING;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RADIANS;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RAND;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.REDUCE;
Expand All @@ -161,6 +167,7 @@
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SHA1;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SHA2;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIGN;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIMPLE_QUERY_STRING;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIN;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SPAN;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SQRT;
Expand Down Expand Up @@ -693,6 +700,13 @@ void populate() {
registerOperator(SHA2, PPLBuiltinOperators.SHA2);
registerOperator(CIDRMATCH, PPLBuiltinOperators.CIDRMATCH);
registerOperator(INTERNAL_GROK, PPLBuiltinOperators.GROK);
registerOperator(MATCH, PPLBuiltinOperators.MATCH);
registerOperator(MATCH_PHRASE, PPLBuiltinOperators.MATCH_PHRASE);
registerOperator(MATCH_BOOL_PREFIX, PPLBuiltinOperators.MATCH_BOOL_PREFIX);
registerOperator(MATCH_PHRASE_PREFIX, PPLBuiltinOperators.MATCH_PHRASE_PREFIX);
registerOperator(SIMPLE_QUERY_STRING, PPLBuiltinOperators.SIMPLE_QUERY_STRING);
registerOperator(QUERY_STRING, PPLBuiltinOperators.QUERY_STRING);
registerOperator(MULTI_MATCH, PPLBuiltinOperators.MULTI_MATCH);

// Register PPL Datetime UDF operator
registerOperator(TIMESTAMP, PPLBuiltinOperators.TIMESTAMP);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.expression.function.udf;

import com.google.common.collect.ImmutableList;
import java.util.List;
import org.apache.calcite.adapter.enumerable.NotNullImplementor;
import org.apache.calcite.adapter.enumerable.NullPolicy;
import org.apache.calcite.adapter.enumerable.RexToLixTranslator;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.rex.RexCall;
import org.apache.calcite.sql.type.CompositeOperandTypeChecker;
import org.apache.calcite.sql.type.OperandTypes;
import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlReturnTypeInference;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.opensearch.sql.expression.function.ImplementorUDF;
import org.opensearch.sql.expression.function.UDFOperandMetadata;

public class RelevanceQueryFunction extends ImplementorUDF {

public RelevanceQueryFunction() {
super(new RelevanceQueryImplementor(), NullPolicy.ANY);
}

@Override
public SqlReturnTypeInference getReturnTypeInference() {
return ReturnTypes.BOOLEAN;
}

/*
* Starting from the 3rd parameter, they are optional parameters for relevance queries.
* Different query has different parameter set, which will be validated in dedicated query builder
*/
@Override
public UDFOperandMetadata getOperandMetadata() {
return UDFOperandMetadata.wrap(
(CompositeOperandTypeChecker)
OperandTypes.family(
ImmutableList.of(
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING),
i -> i > 1 && i < 14) // Parameters 3-14 are optional
.or(
OperandTypes.family(
ImmutableList.of(
SqlTypeFamily.MAP,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING,
SqlTypeFamily.STRING),
i -> i > 1 && i < 25))); // Parameters 3-25 are optional
}

public static class RelevanceQueryImplementor implements NotNullImplementor {
@Override
public Expression implement(
RexToLixTranslator translator, RexCall call, List<Expression> translatedOperands) {
throw new UnsupportedOperationException(
"Relevance search query functions are only supported when they are pushed down");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@
CalciteJsonFunctionsIT.class,
CalciteLegacyAPICompatibilityIT.class,
CalciteLikeQueryIT.class,
CalciteMatchBoolPrefixIT.class,
CalciteMatchIT.class,
CalciteMatchPhraseIT.class,
CalciteMathematicalFunctionIT.class,
CalciteNewAddedCommandsIT.class,
CalciteNowLikeFunctionIT.class,
Expand Down Expand Up @@ -87,15 +84,12 @@
CalcitePPLTrendlineIT.class,
CalcitePrometheusDataSourceCommandsIT.class,
CalciteQueryAnalysisIT.class,
CalciteQueryStringIT.class,
CalciteRareCommandIT.class,
CalciteRelevanceFunctionIT.class,
CalciteRenameCommandIT.class,
CalciteResourceMonitorIT.class,
CalciteSearchCommandIT.class,
CalciteSettingsIT.class,
CalciteShowDataSourcesCommandIT.class,
CalciteSimpleQueryStringIT.class,
CalciteSortCommandIT.class,
CalciteStatsCommandIT.class,
CalciteSystemFunctionIT.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class CalciteMatchBoolPrefixIT extends MatchBoolPrefixIT {
public void init() throws Exception {
super.init();
enableCalcite();
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class CalciteMatchIT extends MatchIT {
public void init() throws Exception {
super.init();
enableCalcite();
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class CalciteMatchPhraseIT extends MatchPhraseIT {
public void init() throws Exception {
super.init();
enableCalcite();
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.calcite.remote;

import org.opensearch.sql.ppl.MatchPhrasePrefixIT;

public class CalciteMatchPhrasePrefixIT extends MatchPhrasePrefixIT {
@Override
public void init() throws Exception {
super.init();
enableCalcite();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.calcite.remote;

import org.opensearch.sql.ppl.MultiMatchIT;

public class CalciteMultiMatchIT extends MultiMatchIT {
@Override
public void init() throws Exception {
super.init();
enableCalcite();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class CalciteQueryStringIT extends QueryStringIT {
public void init() throws Exception {
super.init();
enableCalcite();
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class CalciteRelevanceFunctionIT extends RelevanceFunctionIT {
public void init() throws Exception {
super.init();
enableCalcite();
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ public class CalciteSimpleQueryStringIT extends SimpleQueryStringIT {
public void init() throws Exception {
super.init();
enableCalcite();
// Search Functions are not supported
// TODO: "https://github.com/opensearch-project/sql/issues/3462"
// disallowCalciteFallback();
disallowCalciteFallback();
}
}
29 changes: 29 additions & 0 deletions integ-test/src/test/java/org/opensearch/sql/ppl/ExplainIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -449,4 +449,33 @@ public void testStatsByTimeSpan() throws IOException {
explainQueryToString(
String.format("source=%s | stats count() by span(birthdate,1M)", TEST_INDEX_BANK)));
}

@Test
public void testSingleFieldRelevanceQueryFunctionExplain() throws IOException {
String expected =
isCalciteEnabled()
? loadFromFile("expectedOutput/calcite/explain_single_field_relevance_push.json")
: loadFromFile("expectedOutput/ppl/explain_single_field_relevance_push.json");

assertJsonEqualsIgnoreId(
expected,
explainQueryToString(
"source=opensearch-sql_test_index_account"
+ "| where match(email, '*@gmail.com', boost=1.0)"));
}

@Test
public void testMultiFieldsRelevanceQueryFunctionExplain() throws IOException {
String expected =
isCalciteEnabled()
? loadFromFile("expectedOutput/calcite/explain_multi_fields_relevance_push.json")
: loadFromFile("expectedOutput/ppl/explain_multi_fields_relevance_push.json");

assertJsonEqualsIgnoreId(
expected,
explainQueryToString(
"source=opensearch-sql_test_index_account"
+ "| where simple_query_string(['email', name 4.0], 'gmail',"
+ " default_operator='or', analyzer=english)"));
}
}
Loading
Loading