This is an automated email from the ASF dual-hosted git repository.
dakirily pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git
The following commit(s) were added to refs/heads/main by this push:
new 953e3d6786 QPID-8761: [Broker-J] QueryEvaluationException: Objects of
types 'null' and 'String' can not be compared (#448)
953e3d6786 is described below
commit 953e3d67862a6a1e5f96a710996ab3eaad5eec5f
Author: Daniil Kirilyuk <[email protected]>
AuthorDate: Sun Sep 20 03:31:05 2026 +0200
QPID-8761: [Broker-J] QueryEvaluationException: Objects of types 'null' and
'String' can not be compared (#448)
---
broker-plugins/query-engine/pom.xml | 6 +++
.../comparison/AbstractComparisonExpression.java | 13 +++++
.../expression/comparison/EqualExpression.java | 10 ++--
.../comparison/GreaterThanExpression.java | 2 +-
.../comparison/GreaterThanOrEqualExpression.java | 2 +-
.../expression/comparison/LessThanExpression.java | 2 +-
.../comparison/LessThanOrEqualExpression.java | 2 +-
.../expression/comparison/EqualExpressionTest.java | 55 ++++++++++++----------
.../comparison/GreaterThanExpressionTest.java | 45 +++++++++---------
.../GreaterThanOrEqualExpressionTest.java | 45 +++++++++---------
.../comparison/LessThanExpressionTest.java | 45 +++++++++---------
.../comparison/LessThanOrEqualExpressionTest.java | 45 +++++++++---------
12 files changed, 143 insertions(+), 129 deletions(-)
diff --git a/broker-plugins/query-engine/pom.xml
b/broker-plugins/query-engine/pom.xml
index 4bb8356769..902ae45a86 100644
--- a/broker-plugins/query-engine/pom.xml
+++ b/broker-plugins/query-engine/pom.xml
@@ -52,6 +52,12 @@
<artifactId>qpid-broker-plugins-access-control</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/AbstractComparisonExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/AbstractComparisonExpression.java
index 21aefb4696..0ca3745025 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/AbstractComparisonExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/AbstractComparisonExpression.java
@@ -86,6 +86,19 @@ public abstract class AbstractComparisonExpression<T, R>
extends AbstractExpress
super(children);
}
+ /**
+ * Returns true if one of the operands is null and false otherwise
+ *
+ * @param left Left operand
+ * @param right Right operand
+ *
+ * @return true if one of the operands is null and false otherwise
+ */
+ protected boolean hasNullOperand(final Object left, final Object right)
+ {
+ return left == null || right == null;
+ }
+
/**
* Evaluates value to a boolean result
*
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpression.java
index f13900f20e..ea8f6ed475 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpression.java
@@ -84,6 +84,11 @@ public class EqualExpression<T, R> extends
AbstractComparisonExpression<T, Boole
return Boolean.FALSE;
}
+ if (hasNullOperand(left, right))
+ {
+ return left == right;
+ }
+
if (!_typeValidator.test(left) || !_typeValidator.test(right))
{
throw QueryEvaluationException.of(
@@ -93,11 +98,6 @@ public class EqualExpression<T, R> extends
AbstractComparisonExpression<T, Boole
);
}
- if ((left == null) ^ (right == null))
- {
- return Boolean.FALSE;
- }
-
if ((left == right) || Objects.equals(left, right))
{
return Boolean.TRUE;
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpression.java
index 11f558686b..04d24014af 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpression.java
@@ -78,7 +78,7 @@ public class GreaterThanExpression<T, R> extends
AbstractComparisonExpression<T,
final R left = evaluateChild(0, value);
final R right = evaluateChild(1, value);
- if (right instanceof EmptySetExpression)
+ if (right instanceof EmptySetExpression || hasNullOperand(left, right))
{
return Boolean.FALSE;
}
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpression.java
index 1128e00678..bb94945313 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpression.java
@@ -79,7 +79,7 @@ public class GreaterThanOrEqualExpression<T, R> extends
AbstractComparisonExpres
final R left = evaluateChild(0, value);
final R right = evaluateChild(1, value);
- if (right instanceof EmptySetExpression)
+ if (right instanceof EmptySetExpression || hasNullOperand(left, right))
{
return Boolean.FALSE;
}
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpression.java
index 0ab403ecb1..c3bf6f1999 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpression.java
@@ -79,7 +79,7 @@ public class LessThanExpression<T, R> extends
AbstractComparisonExpression<T, Bo
final R left = evaluateChild(0, value);
final R right = evaluateChild(1, value);
- if (right instanceof EmptySetExpression)
+ if (right instanceof EmptySetExpression || hasNullOperand(left, right))
{
return Boolean.FALSE;
}
diff --git
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpression.java
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpression.java
index 341b6ebfd0..2d894e22b6 100644
---
a/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpression.java
+++
b/broker-plugins/query-engine/src/main/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpression.java
@@ -78,7 +78,7 @@ public class LessThanOrEqualExpression<T, R> extends
AbstractComparisonExpressio
final R left = evaluateChild(0, value);
final R right = evaluateChild(1, value);
- if (right instanceof EmptySetExpression)
+ if (right instanceof EmptySetExpression || hasNullOperand(left, right))
{
return Boolean.FALSE;
}
diff --git
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpressionTest.java
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpressionTest.java
index ac917ab1dd..6cb09add45 100644
---
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpressionTest.java
+++
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/EqualExpressionTest.java
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
import org.apache.qpid.server.query.engine.TestBroker;
import org.apache.qpid.server.query.engine.exception.QueryEvaluationException;
@@ -222,32 +224,37 @@ public class EqualExpressionTest
}
}
- @Test()
- public void comparingNulls()
+ @ParameterizedTest
+ @CsvSource(value =
{
- String query = "select 1 = null as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'Integer' and 'null' can not be
compared", e.getMessage());
- }
+ "1 = null, false",
+ "null = 1, false",
+ "'test' = null, false",
+ "null = 'test', false",
+ "(null + 1) = 1, false",
+ "1 = (null + 1), false",
+ "null = (select name from queue where 1 = 0), false",
+ "null = null, true"
+ }, quoteCharacter = '"')
+ public void comparingNulls(final String expression, final boolean expected)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select " + expression + " as result").getResults();
+ assertEquals(1, result.size(), expression);
+ assertEquals(expected, result.get(0).get("result"), expression);
+ }
- query = "select null = 'test' as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'null' and 'String' can not be
compared", e.getMessage());
- }
+ @ParameterizedTest
+ @CsvSource(value =
+ {
+ "description = 'test description 2', 10",
+ "'test description 2' = description, 10",
+ "description = 'missing', 0"
+ }, quoteCharacter = '"')
+ public void filteringNullableFields(final String predicate, final int
expected)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select count(*) as cnt from queue where " +
predicate).getResults();
+ assertEquals(1, result.size(), predicate);
+ assertEquals(expected, result.get(0).get("cnt"), predicate);
}
@Test()
diff --git
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpressionTest.java
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpressionTest.java
index 76b4a7f82a..a3f00f4b9e 100644
---
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpressionTest.java
+++
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanExpressionTest.java
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.apache.qpid.server.query.engine.TestBroker;
import org.apache.qpid.server.query.engine.exception.QueryEvaluationException;
@@ -194,31 +196,26 @@ public class GreaterThanExpressionTest
}
}
- @Test()
- public void comparingNulls()
+ @ParameterizedTest
+ @ValueSource(strings =
{
- String query = "select 1 > null as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'Integer' and 'null' can not be
compared", e.getMessage());
- }
+ "1 > null", "null > 1", "'test' > null", "null > 'test'",
+ "null > null", "(null + 1) > 1", "1 > (null + 1)",
+ "null > (select name from queue where 1 = 0)"
+ })
+ public void comparingNulls(final String expression)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select " + expression + " as result").getResults();
+ assertEquals(1, result.size(), expression);
+ assertEquals(false, result.get(0).get("result"), expression);
+ }
- query = "select null > 'test' as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'null' and 'String' can not be
compared", e.getMessage());
- }
+ @ParameterizedTest
+ @ValueSource(strings = { "description > 'test description 2'", "'test
description 2' > description" })
+ public void filteringNullableFields(final String predicate)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select count(*) as cnt from queue where " +
predicate).getResults();
+ assertEquals(1, result.size(), predicate);
+ assertEquals(10, result.get(0).get("cnt"), predicate);
}
}
diff --git
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpressionTest.java
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpressionTest.java
index 3a82d0b351..dead008ea3 100644
---
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpressionTest.java
+++
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/GreaterThanOrEqualExpressionTest.java
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.apache.qpid.server.query.engine.TestBroker;
import org.apache.qpid.server.query.engine.exception.QueryEvaluationException;
@@ -224,31 +226,26 @@ public class GreaterThanOrEqualExpressionTest
}
}
- @Test()
- public void comparingNulls()
+ @ParameterizedTest
+ @ValueSource(strings =
{
- String query = "select 1 >= null as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'Integer' and 'null' can not be
compared", e.getMessage());
- }
+ "1 >= null", "null >= 1", "'test' >= null", "null >= 'test'",
+ "null >= null", "(null + 1) >= 1", "1 >= (null + 1)",
+ "null >= (select name from queue where 1 = 0)"
+ })
+ public void comparingNulls(final String expression)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select " + expression + " as result").getResults();
+ assertEquals(1, result.size(), expression);
+ assertEquals(false, result.get(0).get("result"), expression);
+ }
- query = "select null >= 'test' as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'null' and 'String' can not be
compared", e.getMessage());
- }
+ @ParameterizedTest
+ @ValueSource(strings = { "description >= 'test description 2'", "'test
description 2' >= description" })
+ public void filteringNullableFields(final String predicate)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select count(*) as cnt from queue where " +
predicate).getResults();
+ assertEquals(1, result.size(), predicate);
+ assertEquals(20, result.get(0).get("cnt"), predicate);
}
}
diff --git
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpressionTest.java
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpressionTest.java
index f56d97d01a..69ae4c76ef 100644
---
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpressionTest.java
+++
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanExpressionTest.java
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.apache.qpid.server.query.engine.TestBroker;
import org.apache.qpid.server.query.engine.exception.QueryEvaluationException;
@@ -194,31 +196,26 @@ public class LessThanExpressionTest
}
}
- @Test()
- public void comparingNulls()
+ @ParameterizedTest
+ @ValueSource(strings =
{
- String query = "select 1 < null as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'Integer' and 'null' can not be
compared", e.getMessage());
- }
+ "1 < null", "null < 1", "'test' < null", "null < 'test'",
+ "null < null", "(null + 1) < 1", "1 < (null + 1)",
+ "null < (select name from queue where 1 = 0)"
+ })
+ public void comparingNulls(final String expression)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select " + expression + " as result").getResults();
+ assertEquals(1, result.size(), expression);
+ assertEquals(false, result.get(0).get("result"), expression);
+ }
- query = "select null < 'test' as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'null' and 'String' can not be
compared", e.getMessage());
- }
+ @ParameterizedTest
+ @ValueSource(strings = { "description < 'test description 2'", "'test
description 2' < description" })
+ public void filteringNullableFields(final String predicate)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select count(*) as cnt from queue where " +
predicate).getResults();
+ assertEquals(1, result.size(), predicate);
+ assertEquals(10, result.get(0).get("cnt"), predicate);
}
}
diff --git
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpressionTest.java
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpressionTest.java
index 8d9b08cc5d..588cceedd4 100644
---
a/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpressionTest.java
+++
b/broker-plugins/query-engine/src/test/java/org/apache/qpid/server/query/engine/parsing/expression/comparison/LessThanOrEqualExpressionTest.java
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.apache.qpid.server.query.engine.TestBroker;
import org.apache.qpid.server.query.engine.exception.QueryEvaluationException;
@@ -264,31 +266,26 @@ public class LessThanOrEqualExpressionTest
}
}
- @Test()
- public void comparingNulls()
+ @ParameterizedTest
+ @ValueSource(strings =
{
- String query = "select 1 <= null as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'Integer' and 'null' can not be
compared", e.getMessage());
- }
+ "1 <= null", "null <= 1", "'test' <= null", "null <= 'test'",
+ "null <= null", "(null + 1) <= 1", "1 <= (null + 1)",
+ "null <= (select name from queue where 1 = 0)"
+ })
+ public void comparingNulls(final String expression)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select " + expression + " as result").getResults();
+ assertEquals(1, result.size(), expression);
+ assertEquals(false, result.get(0).get("result"), expression);
+ }
- query = "select null <= 'test' as result from queue";
- try
- {
- _queryEvaluator.execute(query);
- fail("Expected exception not thrown");
- }
- catch (Exception e)
- {
- assertEquals(QueryEvaluationException.class, e.getClass());
- assertEquals("Objects of types 'null' and 'String' can not be
compared", e.getMessage());
- }
+ @ParameterizedTest
+ @ValueSource(strings = { "description <= 'test description 2'", "'test
description 2' <= description" })
+ public void filteringNullableFields(final String predicate)
+ {
+ final List<Map<String, Object>> result =
_queryEvaluator.execute("select count(*) as cnt from queue where " +
predicate).getResults();
+ assertEquals(1, result.size(), predicate);
+ assertEquals(20, result.get(0).get("cnt"), predicate);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]