[ https://issues.apache.org/jira/browse/AMQ-5281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Grigroy Sobko updated AMQ-5281: ------------------------------- Description: Due to JmsMessage specification : http://docs.oracle.com/javaee/1.4/api/javax/jms/Message.html There are rules how unknown Values evaluates. There how AND operator should handle unknown: - UNKNOWN AND FALSE => FALSE - FALSE AND UNKNOWN => FALSE And that's how it is handled in ActiveMQ: - UNKNOWN AND FALSE => UNKNOWN (!!!) - FALSE AND UNKNOWN => FALSE I've wrote test to reproduce this: {code} package org.activemq.test; import org.apache.activemq.command.ActiveMQMessage; import org.apache.activemq.command.ActiveMQTopic; import org.apache.activemq.filter.BooleanExpression; import org.apache.activemq.filter.MessageEvaluationContext; import org.apache.activemq.selector.SelectorParser; import org.junit.Before; import org.junit.Test; import javax.jms.JMSException; import javax.jms.Message; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class SelectorUnknownHandlingTest { private Message message; @Before public void setUp() throws Exception { message = createMessage(); } @Test public void testUnknown() throws Exception { // Some unset property with gt operator => unknown assertSelectorEvaluatesToUnknown(message, "(unknownProp > 0)"); } @Test public void testUnknownAndFalse() throws Exception { // false and unknown => false assertSelectorEvaluatesToFalse(message, "(falseProp AND unknownProp > 0)"); // THIS ASSERTION FAILS !! IT EVALUATES TO UNKNOWN INSTEAD // unknown and false => false assertSelectorEvaluatesToFalse(message, "(unknownProp > 0 AND falseProp)"); } @Test public void testUnknownOrTrue() throws Exception { // unknown or true => true assertSelectorEvaluatesToTrue(message, "(unknownProp > 0 OR trueProp)"); // true or unknown => true assertSelectorEvaluatesToTrue(message, "(trueProp OR unknownProp > 0)"); } private void assertSelectorEvaluatesToUnknown(Message message, String selector) throws JMSException { assertSelector(message, selector, false); assertSelector(message, "not(" + selector + ")", false); } private void assertSelectorEvaluatesToFalse(Message message, String selector) throws JMSException { assertSelector(message, selector, false); assertSelector(message, "not(" + selector + ")", true); } private void assertSelectorEvaluatesToTrue(Message message, String selector) throws JMSException { assertSelector(message, selector, true); assertSelector(message, "not(" + selector + ")", false); } protected Message createMessage() throws JMSException { Message message = createMessage("FOO.BAR"); message.setJMSType("selector-test"); message.setJMSMessageID("connection:1:1:1:1"); message.setBooleanProperty("trueProp", true); message.setBooleanProperty("falseProp", false); return message; } protected void assertSelector(Message message, String text, boolean expected) throws JMSException { BooleanExpression selector = SelectorParser.parse(text); assertTrue("Created a valid selector", selector != null); MessageEvaluationContext context = new MessageEvaluationContext(); context.setMessageReference((org.apache.activemq.command.Message)message); boolean value = selector.matches(context); assertEquals("Selector for: " + text, expected, value); } protected Message createMessage(String subject) throws JMSException { ActiveMQMessage message = new ActiveMQMessage(); message.setJMSDestination(new ActiveMQTopic(subject)); return message; } } {code} was: Due to JmsMessage specification : http://docs.oracle.com/javaee/1.4/api/javax/jms/Message.html There are rules how unknown Values evaluates. There how AND operator should handle unknown: UNKNOWN AND FALSE => FALSE FALSE AND UNKNOWN => FALSE And that's how it is handled in ActiveMQ: UNKNOWN AND FALSE => UNKNOWN (!!!) FALSE AND UNKNOWN => FALSE I've wrote test to reproduce this: {code} package org.activemq.test; import org.apache.activemq.command.ActiveMQMessage; import org.apache.activemq.command.ActiveMQTopic; import org.apache.activemq.filter.BooleanExpression; import org.apache.activemq.filter.MessageEvaluationContext; import org.apache.activemq.selector.SelectorParser; import org.junit.Before; import org.junit.Test; import javax.jms.JMSException; import javax.jms.Message; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class SelectorUnknownHandlingTest { private Message message; @Before public void setUp() throws Exception { message = createMessage(); } @Test public void testUnknown() throws Exception { // Some unset property with gt operator => unknown assertSelectorEvaluatesToUnknown(message, "(unknownProp > 0)"); } @Test public void testUnknownAndFalse() throws Exception { // false and unknown => false assertSelectorEvaluatesToFalse(message, "(falseProp AND unknownProp > 0)"); // THIS ASSERTION FAILS !! IT EVALUATES TO UNKNOWN INSTEAD // unknown and false => false assertSelectorEvaluatesToFalse(message, "(unknownProp > 0 AND falseProp)"); } @Test public void testUnknownOrTrue() throws Exception { // unknown or true => true assertSelectorEvaluatesToTrue(message, "(unknownProp > 0 OR trueProp)"); // true or unknown => true assertSelectorEvaluatesToTrue(message, "(trueProp OR unknownProp > 0)"); } private void assertSelectorEvaluatesToUnknown(Message message, String selector) throws JMSException { assertSelector(message, selector, false); assertSelector(message, "not(" + selector + ")", false); } private void assertSelectorEvaluatesToFalse(Message message, String selector) throws JMSException { assertSelector(message, selector, false); assertSelector(message, "not(" + selector + ")", true); } private void assertSelectorEvaluatesToTrue(Message message, String selector) throws JMSException { assertSelector(message, selector, true); assertSelector(message, "not(" + selector + ")", false); } protected Message createMessage() throws JMSException { Message message = createMessage("FOO.BAR"); message.setJMSType("selector-test"); message.setJMSMessageID("connection:1:1:1:1"); message.setBooleanProperty("trueProp", true); message.setBooleanProperty("falseProp", false); return message; } protected void assertSelector(Message message, String text, boolean expected) throws JMSException { BooleanExpression selector = SelectorParser.parse(text); assertTrue("Created a valid selector", selector != null); MessageEvaluationContext context = new MessageEvaluationContext(); context.setMessageReference((org.apache.activemq.command.Message)message); boolean value = selector.matches(context); assertEquals("Selector for: " + text, expected, value); } protected Message createMessage(String subject) throws JMSException { ActiveMQMessage message = new ActiveMQMessage(); message.setJMSDestination(new ActiveMQTopic(subject)); return message; } } {code} > Incorrect handling of unknown values in selectors > ------------------------------------------------- > > Key: AMQ-5281 > URL: https://issues.apache.org/jira/browse/AMQ-5281 > Project: ActiveMQ > Issue Type: Bug > Affects Versions: 5.8.0 > Reporter: Grigroy Sobko > > Due to JmsMessage specification : > http://docs.oracle.com/javaee/1.4/api/javax/jms/Message.html > There are rules how unknown Values evaluates. > There how AND operator should handle unknown: > - UNKNOWN AND FALSE => FALSE > - FALSE AND UNKNOWN => FALSE > And that's how it is handled in ActiveMQ: > - UNKNOWN AND FALSE => UNKNOWN (!!!) > - FALSE AND UNKNOWN => FALSE > I've wrote test to reproduce this: > {code} > package org.activemq.test; > import org.apache.activemq.command.ActiveMQMessage; > import org.apache.activemq.command.ActiveMQTopic; > import org.apache.activemq.filter.BooleanExpression; > import org.apache.activemq.filter.MessageEvaluationContext; > import org.apache.activemq.selector.SelectorParser; > import org.junit.Before; > import org.junit.Test; > import javax.jms.JMSException; > import javax.jms.Message; > import static org.junit.Assert.assertEquals; > import static org.junit.Assert.assertTrue; > public class SelectorUnknownHandlingTest { > private Message message; > @Before > public void setUp() throws Exception { > message = createMessage(); > } > @Test > public void testUnknown() throws Exception { > // Some unset property with gt operator => unknown > assertSelectorEvaluatesToUnknown(message, "(unknownProp > 0)"); > } > @Test > public void testUnknownAndFalse() throws Exception { > // false and unknown => false > assertSelectorEvaluatesToFalse(message, "(falseProp AND unknownProp > > 0)"); > // THIS ASSERTION FAILS !! IT EVALUATES TO UNKNOWN INSTEAD > // unknown and false => false > assertSelectorEvaluatesToFalse(message, "(unknownProp > 0 AND > falseProp)"); > } > @Test > public void testUnknownOrTrue() throws Exception { > // unknown or true => true > assertSelectorEvaluatesToTrue(message, "(unknownProp > 0 OR > trueProp)"); > // true or unknown => true > assertSelectorEvaluatesToTrue(message, "(trueProp OR unknownProp > > 0)"); > } > private void assertSelectorEvaluatesToUnknown(Message message, String > selector) throws JMSException { > assertSelector(message, selector, false); > assertSelector(message, "not(" + selector + ")", false); > } > private void assertSelectorEvaluatesToFalse(Message message, String > selector) throws JMSException { > assertSelector(message, selector, false); > assertSelector(message, "not(" + selector + ")", true); > } > private void assertSelectorEvaluatesToTrue(Message message, String > selector) throws JMSException { > assertSelector(message, selector, true); > assertSelector(message, "not(" + selector + ")", false); > } > protected Message createMessage() throws JMSException { > Message message = createMessage("FOO.BAR"); > message.setJMSType("selector-test"); > message.setJMSMessageID("connection:1:1:1:1"); > message.setBooleanProperty("trueProp", true); > message.setBooleanProperty("falseProp", false); > return message; > } > protected void assertSelector(Message message, String text, boolean > expected) throws JMSException { > BooleanExpression selector = SelectorParser.parse(text); > assertTrue("Created a valid selector", selector != null); > MessageEvaluationContext context = new MessageEvaluationContext(); > > context.setMessageReference((org.apache.activemq.command.Message)message); > boolean value = selector.matches(context); > assertEquals("Selector for: " + text, expected, value); > } > protected Message createMessage(String subject) throws JMSException { > ActiveMQMessage message = new ActiveMQMessage(); > message.setJMSDestination(new ActiveMQTopic(subject)); > return message; > } > } > {code} -- This message was sent by Atlassian JIRA (v6.2#6252)