Skip to content

Commit a414438

Browse files
committed
Add validations for cases in full text functions and match operator
1 parent ec60f5f commit a414438

File tree

2 files changed

+76
-23
lines changed

2 files changed

+76
-23
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,10 @@ private static void checkFullTextFunctionsParents(Expression condition, Set<Fail
739739
failures.add(
740740
fail(
741741
condition,
742-
"Invalid condition [{}]. [{}] function can't be used with {}",
742+
"Invalid condition [{}]. [{}] {} can't be used with {}",
743743
condition.sourceText(),
744744
ftf.functionName(),
745+
ftf.functionType(),
745746
((Function) parent).functionName()
746747
)
747748
);

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,26 +1205,40 @@ public void testQueryStringFunctionsNotAllowedAfterCommands() throws Exception {
12051205

12061206
public void testQueryStringFunctionOnlyAllowedInWhere() throws Exception {
12071207
assertEquals("1:9: [QSTR] function is only supported in WHERE commands", error("row a = qstr(\"Anna\")"));
1208-
checkFullTextFunctionsOnlyAllowedInWhere("QSTR", "qstr(\"Anna\")");
1208+
checkFullTextFunctionsOnlyAllowedInWhere("QSTR", "qstr(\"Anna\")", "function");
12091209
}
12101210

12111211
public void testMatchFunctionOnlyAllowedInWhere() throws Exception {
1212-
checkFullTextFunctionsOnlyAllowedInWhere("MATCH", "match(first_name, \"Anna\")");
1212+
checkFullTextFunctionsOnlyAllowedInWhere("MATCH", "match(first_name, \"Anna\")", "function");
12131213
}
12141214

1215-
private void checkFullTextFunctionsOnlyAllowedInWhere(String functionName, String functionInvocation) throws Exception {
1215+
public void testMatchOperatornOnlyAllowedInWhere() throws Exception {
1216+
assumeTrue("skipping because MATCH operator is not enabled", EsqlCapabilities.Cap.MATCH_OPERATOR_COLON.isEnabled());
1217+
checkFullTextFunctionsOnlyAllowedInWhere(":", "first_name:\"Anna\"", "operator");
1218+
}
1219+
1220+
private void checkFullTextFunctionsOnlyAllowedInWhere(String functionName, String functionInvocation, String functionType)
1221+
throws Exception {
12161222
assertEquals(
1217-
"1:22: [" + functionName + "] function is only supported in WHERE commands",
1223+
"1:22: [" + functionName + "] " + functionType + " is only supported in WHERE commands",
12181224
error("from test | eval y = " + functionInvocation)
12191225
);
12201226
assertEquals(
1221-
"1:18: [" + functionName + "] function is only supported in WHERE commands",
1227+
"1:18: [" + functionName + "] " + functionType + " is only supported in WHERE commands",
12221228
error("from test | sort " + functionInvocation + " asc")
12231229
);
12241230
assertEquals(
1225-
"1:23: [" + functionName + "] function is only supported in WHERE commands",
1231+
"1:23: [" + functionName + "] " + functionType + " is only supported in WHERE commands",
12261232
error("from test | STATS c = " + functionInvocation + " BY first_name")
12271233
);
1234+
assertEquals(
1235+
"1:50: [" + functionName + "] " + functionType + " is only supported in WHERE commands",
1236+
error("from test | stats max_salary = max(salary) where " + functionInvocation)
1237+
);
1238+
assertEquals(
1239+
"1:47: [" + functionName + "] " + functionType + " is only supported in WHERE commands",
1240+
error("from test | stats max_salary = max(salary) by " + functionInvocation)
1241+
);
12281242
}
12291243

12301244
public void testQueryStringFunctionArgNotNullOrConstant() throws Exception {
@@ -1301,33 +1315,71 @@ private void checkWithDisjunctions(String functionName, String functionInvocatio
13011315
}
13021316

13031317
public void testQueryStringFunctionWithNonBooleanFunctions() {
1304-
checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"first_name: Anna\")");
1318+
checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"first_name: Anna\")", "function");
13051319
}
13061320

13071321
public void testMatchFunctionWithNonBooleanFunctions() {
1308-
checkFullTextFunctionsWithNonBooleanFunctions("MATCH", "match(first_name, \"Anna\")");
1322+
checkFullTextFunctionsWithNonBooleanFunctions("MATCH", "match(first_name, \"Anna\")", "function");
13091323
}
13101324

1311-
private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName, String functionInvocation) {
1325+
public void testMatchOperatorWithNonBooleanFunctions() {
1326+
assumeTrue("skipping because MATCH operator is not enabled", EsqlCapabilities.Cap.MATCH_OPERATOR_COLON.isEnabled());
1327+
checkFullTextFunctionsWithNonBooleanFunctions(":", "first_name:\"Anna\"", "operator");
1328+
}
1329+
1330+
private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName, String functionInvocation, String functionType) {
1331+
if (functionType.equals("operator") == false) {
1332+
// The following tests are only possible for functions from a parsing perspective
1333+
assertEquals(
1334+
"1:19: Invalid condition ["
1335+
+ functionInvocation
1336+
+ " is not null]. ["
1337+
+ functionName
1338+
+ "] "
1339+
+ functionType
1340+
+ " can't be used with ISNOTNULL",
1341+
error("from test | where " + functionInvocation + " is not null")
1342+
);
1343+
assertEquals(
1344+
"1:19: Invalid condition ["
1345+
+ functionInvocation
1346+
+ " is null]. ["
1347+
+ functionName
1348+
+ "] "
1349+
+ functionType
1350+
+ " can't be used with ISNULL",
1351+
error("from test | where " + functionInvocation + " is null")
1352+
);
1353+
assertEquals(
1354+
"1:19: Invalid condition ["
1355+
+ functionInvocation
1356+
+ " in (\"hello\", \"world\")]. ["
1357+
+ functionName
1358+
+ "] "
1359+
+ functionType
1360+
+ " can't be used with IN",
1361+
error("from test | where " + functionInvocation + " in (\"hello\", \"world\")")
1362+
);
1363+
}
13121364
assertEquals(
1313-
"1:19: Invalid condition ["
1365+
"1:19: Invalid condition [coalesce("
13141366
+ functionInvocation
1315-
+ " is not null]. ["
1367+
+ ", "
1368+
+ functionInvocation
1369+
+ ")]. ["
13161370
+ functionName
1317-
+ "] function can't be used with ISNOTNULL",
1318-
error("from test | where " + functionInvocation + " is not null")
1371+
+ "] "
1372+
+ functionType
1373+
+ " can't be used with COALESCE",
1374+
error("from test | where coalesce(" + functionInvocation + ", " + functionInvocation + ")")
13191375
);
13201376
assertEquals(
1321-
"1:19: Invalid condition [" + functionInvocation + " is null]. [" + functionName + "] function can't be used with ISNULL",
1322-
error("from test | where " + functionInvocation + " is null")
1323-
);
1324-
assertEquals(
1325-
"1:19: Invalid condition ["
1377+
"1:19: argument of [concat("
13261378
+ functionInvocation
1327-
+ " in (\"hello\", \"world\")]. ["
1328-
+ functionName
1329-
+ "] function can't be used with IN",
1330-
error("from test | where " + functionInvocation + " in (\"hello\", \"world\")")
1379+
+ ", \"a\")] must be [string], found value ["
1380+
+ functionInvocation
1381+
+ "] type [boolean]",
1382+
error("from test | where concat(" + functionInvocation + ", \"a\")")
13311383
);
13321384
}
13331385

0 commit comments

Comments
 (0)