summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@verizonmedia.com>2020-02-18 16:12:29 +0100
committerTor Brede Vekterli <vekterli@verizonmedia.com>2020-02-18 16:12:29 +0100
commit3a31bbacf009d3b260ad134304a94a007fff743b (patch)
tree805a7f42d34dba3eb5d16a55c1105d28c7afa8ad /document
parent297220b20a517f18ee0cb084475d058eb1a7c50a (diff)
Ensure well-defined semantics for non-commutative field comparisons
Diffstat (limited to 'document')
-rw-r--r--document/src/main/java/com/yahoo/document/select/rule/ComparisonNode.java24
-rw-r--r--document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java17
2 files changed, 38 insertions, 3 deletions
diff --git a/document/src/main/java/com/yahoo/document/select/rule/ComparisonNode.java b/document/src/main/java/com/yahoo/document/select/rule/ComparisonNode.java
index 47599e53ece..8f52c29e84d 100644
--- a/document/src/main/java/com/yahoo/document/select/rule/ComparisonNode.java
+++ b/document/src/main/java/com/yahoo/document/select/rule/ComparisonNode.java
@@ -144,9 +144,9 @@ public class ComparisonNode implements ExpressionNode {
return new ResultList(Result.INVALID);
}
} else if (oLeft instanceof AttributeNode.VariableValueList) {
- return evaluateListAndSingle((AttributeNode.VariableValueList)oLeft, oRight);
+ return evaluateLhsListAndRhsSingle((AttributeNode.VariableValueList)oLeft, oRight);
} else if (oRight instanceof AttributeNode.VariableValueList) {
- return evaluateListAndSingle((AttributeNode.VariableValueList)oRight, oLeft);
+ return evaluateLhsSingleAndRhsList(oLeft, (AttributeNode.VariableValueList)oRight);
}
return new ResultList(evaluateBool(oLeft, oRight));
}
@@ -197,7 +197,7 @@ public class ComparisonNode implements ExpressionNode {
}
}
- private ResultList evaluateListAndSingle(AttributeNode.VariableValueList lhs, Object rhs) {
+ private ResultList evaluateLhsListAndRhsSingle(AttributeNode.VariableValueList lhs, Object rhs) {
if (rhs == null && lhs == null) {
return new ResultList(Result.TRUE);
}
@@ -215,6 +215,24 @@ public class ComparisonNode implements ExpressionNode {
return retVal;
}
+ private ResultList evaluateLhsSingleAndRhsList(Object lhs, AttributeNode.VariableValueList rhs) {
+ if (rhs == null && lhs == null) {
+ return new ResultList(Result.TRUE);
+ }
+
+ if (rhs == null || lhs == null) {
+ return new ResultList(Result.FALSE);
+ }
+
+ ResultList retVal = new ResultList();
+ for (ResultList.VariableValue value : rhs) {
+ Result result = evaluateBool(lhs, value.getValue());
+ retVal.add((FieldPathIteratorHandler.VariableMap)value.getVariables().clone(), result);
+ }
+
+ return retVal;
+ }
+
/**
* Evaluate this expression on two operands, given that they are not invalid.
*
diff --git a/document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java b/document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java
index 0212be8542e..4e591cdfbd4 100644
--- a/document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java
+++ b/document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java
@@ -704,6 +704,23 @@ public class DocumentSelectorTestCase {
}
@Test
+ public void using_non_commutative_comparison_operator_with_field_value_is_well_defined() throws ParseException {
+ var documents = createDocs();
+ // Doc 0 contains 24 in `hint` field.
+ assertEquals(Result.FALSE, evaluate("25 <= test.hint", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("24 <= test.hint", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("25 > test.hint", documents.get(0)));
+ assertEquals(Result.FALSE, evaluate("24 > test.hint", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("24 >= test.hint", documents.get(0)));
+
+ assertEquals(Result.FALSE, evaluate("test.hint <= 23", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("test.hint <= 24", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("test.hint > 23", documents.get(0)));
+ assertEquals(Result.FALSE, evaluate("test.hint > 24", documents.get(0)));
+ assertEquals(Result.TRUE, evaluate("test.hint >= 24", documents.get(0)));
+ }
+
+ @Test
public void imported_field_references_are_treated_as_valid_field_with_missing_value() throws ParseException {
var documents = createDocs();
assertEquals(Result.TRUE, evaluate("test.my_imported_field == null", documents.get(0)));