Skip to content

Commit 064092d

Browse files
committed
feat(calcite): Register missing SQL V2 relevance functions in Calcite function table
Add SQL V2 relevance functions and aliases to PPLFuncImpTable so CalciteRelNodeVisitor can resolve them from SQL V2 AstBuilder. Aliases normalize to canonical operators (e.g. matchquery -> match). New functions: query, wildcard_query Aliases: wildcardquery, match_query, matchquery, matchphrase, matchphrasequery, multimatch, multimatchquery Not included: score/scorequery/score_query (needs dedicated visitor). Signed-off-by: Chen Dai <daichen@amazon.com>
1 parent 022464a commit 064092d

4 files changed

Lines changed: 100 additions & 49 deletions

File tree

api/src/test/java/org/opensearch/sql/api/UnifiedRelevanceSearchSqlV2Test.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,95 @@ public void matchCombinedWithBooleanFilter() {
132132
LogicalTableScan(table=[[catalog, employees]])
133133
""");
134134
}
135+
136+
@Test
137+
public void matchQuery() {
138+
givenQuery("SELECT * FROM catalog.employees WHERE match_query(name, 'John')")
139+
.assertPlan(
140+
"""
141+
LogicalFilter(condition=[match(MAP('field', $1), MAP('query', 'John':VARCHAR))])
142+
LogicalTableScan(table=[[catalog, employees]])
143+
""");
144+
}
145+
146+
@Test
147+
public void matchquery() {
148+
givenQuery("SELECT * FROM catalog.employees WHERE matchquery(name, 'John')")
149+
.assertPlan(
150+
"""
151+
LogicalFilter(condition=[match(MAP('field', $1), MAP('query', 'John':VARCHAR))])
152+
LogicalTableScan(table=[[catalog, employees]])
153+
""");
154+
}
155+
156+
@Test
157+
public void matchphrase() {
158+
givenQuery("SELECT * FROM catalog.employees WHERE matchphrase(name, 'John Doe')")
159+
.assertPlan(
160+
"""
161+
LogicalFilter(condition=[match_phrase(MAP('field', $1), MAP('query', 'John Doe':VARCHAR))])
162+
LogicalTableScan(table=[[catalog, employees]])
163+
""");
164+
}
165+
166+
@Test
167+
public void matchphrasequery() {
168+
givenQuery("SELECT * FROM catalog.employees WHERE matchphrasequery(name, 'John Doe')")
169+
.assertPlan(
170+
"""
171+
LogicalFilter(condition=[match_phrase(MAP('field', $1), MAP('query', 'John Doe':VARCHAR))])
172+
LogicalTableScan(table=[[catalog, employees]])
173+
""");
174+
}
175+
176+
@Test
177+
public void multimatch() {
178+
givenQuery("SELECT * FROM catalog.employees WHERE multimatch(['name', 'department'], 'John')")
179+
.assertPlan(
180+
"""
181+
LogicalFilter(condition=[multi_match(MAP('fields', MAP('name':VARCHAR, 1.0E0:DOUBLE, 'department':VARCHAR, 1.0E0:DOUBLE)), MAP('query', 'John':VARCHAR))])
182+
LogicalTableScan(table=[[catalog, employees]])
183+
""");
184+
}
185+
186+
@Test
187+
public void multimatchquery() {
188+
givenQuery(
189+
"SELECT * FROM catalog.employees WHERE multimatchquery(['name', 'department'], 'John')")
190+
.assertPlan(
191+
"""
192+
LogicalFilter(condition=[multi_match(MAP('fields', MAP('name':VARCHAR, 1.0E0:DOUBLE, 'department':VARCHAR, 1.0E0:DOUBLE)), MAP('query', 'John':VARCHAR))])
193+
LogicalTableScan(table=[[catalog, employees]])
194+
""");
195+
}
196+
197+
@Test
198+
public void query() {
199+
givenQuery("SELECT * FROM catalog.employees WHERE query('name:John')")
200+
.assertPlan(
201+
"""
202+
LogicalFilter(condition=[query(MAP('query', 'name:John':VARCHAR))])
203+
LogicalTableScan(table=[[catalog, employees]])
204+
""");
205+
}
206+
207+
@Test
208+
public void wildcardQuery() {
209+
givenQuery("SELECT * FROM catalog.employees WHERE wildcard_query(name, 'John*')")
210+
.assertPlan(
211+
"""
212+
LogicalFilter(condition=[wildcard_query(MAP('field', $1), MAP('query', 'John*':VARCHAR))])
213+
LogicalTableScan(table=[[catalog, employees]])
214+
""");
215+
}
216+
217+
@Test
218+
public void wildcardquery() {
219+
givenQuery("SELECT * FROM catalog.employees WHERE wildcardquery(name, 'John*')")
220+
.assertPlan(
221+
"""
222+
LogicalFilter(condition=[wildcard_query(MAP('field', $1), MAP('query', 'John*':VARCHAR))])
223+
LogicalTableScan(table=[[catalog, employees]])
224+
""");
225+
}
135226
}

core/src/main/java/org/opensearch/sql/calcite/utils/UserDefinedFunctionUtils.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,9 @@ public class UserDefinedFunctionUtils {
7676
TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR),
7777
createArrayType(TYPE_FACTORY, TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR), false));
7878
public static Set<String> SINGLE_FIELD_RELEVANCE_FUNCTION_SET =
79-
ImmutableSet.of(
80-
"match",
81-
"match_phrase",
82-
"match_bool_prefix",
83-
"match_phrase_prefix",
84-
"query",
85-
"wildcard_query",
86-
"wildcardquery",
87-
"score",
88-
"scorequery",
89-
"score_query",
90-
"match_query",
91-
"matchquery",
92-
"matchphrase",
93-
"matchphrasequery");
79+
ImmutableSet.of("match", "match_phrase", "match_bool_prefix", "match_phrase_prefix");
9480
public static Set<String> MULTI_FIELDS_RELEVANCE_FUNCTION_SET =
95-
ImmutableSet.of(
96-
"simple_query_string", "query_string", "multi_match", "multimatch", "multimatchquery");
81+
ImmutableSet.of("simple_query_string", "query_string", "multi_match");
9782
public static String IP_FUNCTION_NAME = "IP";
9883

9984
/**

core/src/main/java/org/opensearch/sql/expression/function/PPLBuiltinOperators.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -427,25 +427,6 @@ public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {
427427
public static final SqlOperator QUERY = RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("query");
428428
public static final SqlOperator WILDCARD_QUERY =
429429
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("wildcard_query");
430-
public static final SqlOperator WILDCARDQUERY =
431-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("wildcardquery");
432-
public static final SqlOperator SCORE = RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("score");
433-
public static final SqlOperator SCOREQUERY =
434-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("scorequery");
435-
public static final SqlOperator SCORE_QUERY =
436-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("score_query");
437-
public static final SqlOperator MATCH_QUERY =
438-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("match_query");
439-
public static final SqlOperator MATCHQUERY =
440-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("matchquery");
441-
public static final SqlOperator MATCHPHRASE =
442-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("matchphrase");
443-
public static final SqlOperator MATCHPHRASEQUERY =
444-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("matchphrasequery");
445-
public static final SqlOperator MULTIMATCH =
446-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("multimatch", false);
447-
public static final SqlOperator MULTIMATCHQUERY =
448-
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("multimatchquery", false);
449430
public static final SqlOperator NUMBER_TO_STRING =
450431
new NumberToStringFunction().toUDF("NUMBER_TO_STRING");
451432
public static final SqlOperator TONUMBER = new ToNumberFunction().toUDF("TONUMBER");

core/src/main/java/org/opensearch/sql/expression/function/PPLFuncImpTable.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,6 @@
205205
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RTRIM;
206206
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SCALAR_MAX;
207207
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SCALAR_MIN;
208-
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SCORE;
209-
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SCOREQUERY;
210-
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SCORE_QUERY;
211208
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SECOND;
212209
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SECOND_OF_MINUTE;
213210
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SEC_TO_TIME;
@@ -922,16 +919,13 @@ void populate() {
922919
registerOperator(MULTI_MATCH, PPLBuiltinOperators.MULTI_MATCH);
923920
registerOperator(QUERY, PPLBuiltinOperators.QUERY);
924921
registerOperator(WILDCARD_QUERY, PPLBuiltinOperators.WILDCARD_QUERY);
925-
registerOperator(WILDCARDQUERY, PPLBuiltinOperators.WILDCARDQUERY);
926-
registerOperator(SCORE, PPLBuiltinOperators.SCORE);
927-
registerOperator(SCOREQUERY, PPLBuiltinOperators.SCOREQUERY);
928-
registerOperator(SCORE_QUERY, PPLBuiltinOperators.SCORE_QUERY);
929-
registerOperator(MATCH_QUERY, PPLBuiltinOperators.MATCH_QUERY);
930-
registerOperator(MATCHQUERY, PPLBuiltinOperators.MATCHQUERY);
931-
registerOperator(MATCHPHRASE, PPLBuiltinOperators.MATCHPHRASE);
932-
registerOperator(MATCHPHRASEQUERY, PPLBuiltinOperators.MATCHPHRASEQUERY);
933-
registerOperator(MULTIMATCH, PPLBuiltinOperators.MULTIMATCH);
934-
registerOperator(MULTIMATCHQUERY, PPLBuiltinOperators.MULTIMATCHQUERY);
922+
registerOperator(WILDCARDQUERY, PPLBuiltinOperators.WILDCARD_QUERY);
923+
registerOperator(MATCH_QUERY, PPLBuiltinOperators.MATCH);
924+
registerOperator(MATCHQUERY, PPLBuiltinOperators.MATCH);
925+
registerOperator(MATCHPHRASE, PPLBuiltinOperators.MATCH_PHRASE);
926+
registerOperator(MATCHPHRASEQUERY, PPLBuiltinOperators.MATCH_PHRASE);
927+
registerOperator(MULTIMATCH, PPLBuiltinOperators.MULTI_MATCH);
928+
registerOperator(MULTIMATCHQUERY, PPLBuiltinOperators.MULTI_MATCH);
935929
registerOperator(REX_EXTRACT, PPLBuiltinOperators.REX_EXTRACT);
936930
registerOperator(REX_EXTRACT_MULTI, PPLBuiltinOperators.REX_EXTRACT_MULTI);
937931
registerOperator(REX_OFFSET, PPLBuiltinOperators.REX_OFFSET);

0 commit comments

Comments
 (0)