summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorGeir Storli <geirst@yahooinc.com>2023-11-30 11:11:15 +0100
committerGitHub <noreply@github.com>2023-11-30 11:11:15 +0100
commit690f060bf5b5b5a22d747ecd5c8a66179dd4bd58 (patch)
tree4fb5c4f151599eb46c1eab79fd054575cd50b8ef /container-search
parent0a1f86f20af0eb57e4cb1381f2491f47a711b715 (diff)
parent8a14e1290e46a5e8ccee017fdb2b9d01c64c0cac (diff)
Merge pull request #29496 from vespa-engine/toregge/limit-yql-in-operator-to-integer-and-string-fields
Limit yql in operator to string and integer fields.
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/Index.java7
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/YqlParser.java9
-rw-r--r--container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java4
-rw-r--r--container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java14
4 files changed, 27 insertions, 7 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/Index.java b/container-search/src/main/java/com/yahoo/prelude/Index.java
index d05ef279972..e59c4b80fc6 100644
--- a/container-search/src/main/java/com/yahoo/prelude/Index.java
+++ b/container-search/src/main/java/com/yahoo/prelude/Index.java
@@ -47,6 +47,7 @@ public class Index {
private boolean normalize = false;
private boolean literalBoost = false;
private boolean numerical = false;
+ private boolean integer = false;
private boolean string = false;
private boolean predicate = false;
@@ -132,6 +133,8 @@ public class Index {
if (command.startsWith("type tensor(") || command.startsWith("type tensor<")) { // TODO: Type info can replace numerical, predicate, multivalue
setTensor(true);
+ } else if (command.equals("integer")) {
+ setInteger(true);
} else if ("fullurl".equals(command)) {
setUriIndex(true);
} else if ("urlhost".equals(command)) {
@@ -315,6 +318,10 @@ public class Index {
public boolean isString() { return string; }
+ public void setInteger(boolean integer) { this.integer = integer; }
+
+ public boolean isInteger() { return integer; }
+
public void setPredicate(boolean isPredicate) { this.predicate = isPredicate; }
public boolean isPredicate() { return predicate; }
diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
index 5e1dfb99479..4ea221446a4 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
@@ -415,7 +415,11 @@ public class YqlParser implements Parser {
private Item buildIn(OperatorNode<ExpressionOperator> ast) {
String field = getIndex(ast.getArgument(0));
- boolean stringField = indexFactsSession.getIndex(field).isString();
+ var index = indexFactsSession.getIndex(field);
+ boolean stringField = index.isString();
+ if (!index.isInteger() && !stringField)
+ throw new IllegalArgumentException("The in operator is only supported for integer and string fields. The field " +
+ field + " is not of these types");
Item item = null;
if (stringField) {
item = fillStringIn(ast, ast.getArgument(1), new StringInItem(field));
@@ -638,7 +642,8 @@ public class YqlParser implements Parser {
for (var value : values) {
switch (value.getOperator()) {
case LITERAL -> {
- Long tokenValue = value.getArgument(0, Number.class).longValue();
+ Number numberTokenValue = value.getArgument(0, Number.class);
+ Long tokenValue = (numberTokenValue instanceof Integer) ? numberTokenValue.longValue() : Long.class.cast(numberTokenValue);
out.addToken(tokenValue);
}
case VARREF -> {
diff --git a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java
index 6aac2faa4e9..87bc602f072 100644
--- a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java
@@ -49,7 +49,9 @@ public class VespaSerializerTestCase {
static private IndexFacts createIndexFactsForInTest() {
SearchDefinition sd = new SearchDefinition("sourceA");
- sd.addIndex(new Index("field"));
+ Index fieldIndex = new Index("field");
+ fieldIndex.setInteger(true);
+ sd.addIndex(fieldIndex);
Index stringIndex = new Index("string");
stringIndex.setString(true);
sd.addIndex(stringIndex);
diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
index bd29e2afd53..178163cf961 100644
--- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
@@ -82,10 +82,14 @@ public class YqlParserTestCase {
static private IndexFacts createIndexFactsForInTest() {
SearchDefinition sd = new SearchDefinition("default");
- sd.addIndex(new Index("field"));
+ Index fieldIndex = new Index("field");
+ fieldIndex.setInteger(true);
+ sd.addIndex(fieldIndex);
Index stringIndex = new Index("string");
stringIndex.setString(true);
sd.addIndex(stringIndex);
+ Index floatIndex = new Index("float");
+ sd.addIndex(floatIndex);
return new IndexFacts(new IndexModel(sd));
}
@@ -1183,10 +1187,9 @@ public class YqlParserTestCase {
parser.setUserQuery(createUserQuery());
query = parse("select * from sources * where string in ('a','b', @foostring)");
assertStringInItem("string", new String[]{"a","b","might","this", "work"}, query);
- parser.setUserQuery(createUserQuery());
- query = parse("select * from sources * where field in (29.9, -7.4)");
- assertNumericInItem("field", new long[]{-7, 29}, query);
parser.setUserQuery(null);
+ assertParseFail("select * from sources * where field in (29.9, -7.4)",
+ new ClassCastException("Cannot cast java.lang.Double to java.lang.Long"));
assertParseFail("select * from sources * where string in ('a', 25L)",
new ClassCastException("Cannot cast java.lang.Long to java.lang.String"));
assertParseFail("select * from sources * where field in ('a', 25L)",
@@ -1195,6 +1198,9 @@ public class YqlParserTestCase {
new IllegalArgumentException("Field 'nofield' does not exist."));
assertParseFail("select * from sources * where field not in (25)",
new IllegalArgumentException("Expected AND, CALL, CONTAINS, EQ, GT, GTEQ, IN, LT, LTEQ or OR, got NOT_IN."));
+ assertParseFail("select * from sources * where float in (25)",
+ new IllegalArgumentException("The in operator is only supported for integer and string fields. " +
+ "The field float is not of these types"));
}
private static void assertNumericInItem(String field, long[] values, QueryTree query) {