diff options
author | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2020-02-18 16:12:29 +0100 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2020-02-18 16:12:29 +0100 |
commit | 3a31bbacf009d3b260ad134304a94a007fff743b (patch) | |
tree | 805a7f42d34dba3eb5d16a55c1105d28c7afa8ad /document | |
parent | 297220b20a517f18ee0cb084475d058eb1a7c50a (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.java | 24 | ||||
-rw-r--r-- | document/src/test/java/com/yahoo/document/select/DocumentSelectorTestCase.java | 17 |
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))); |