summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/qpid/broker/SelectorExpression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/src/qpid/broker/SelectorExpression.cpp')
-rw-r--r--qpid/cpp/src/qpid/broker/SelectorExpression.cpp69
1 files changed, 50 insertions, 19 deletions
diff --git a/qpid/cpp/src/qpid/broker/SelectorExpression.cpp b/qpid/cpp/src/qpid/broker/SelectorExpression.cpp
index 5b8621b518..62de067396 100644
--- a/qpid/cpp/src/qpid/broker/SelectorExpression.cpp
+++ b/qpid/cpp/src/qpid/broker/SelectorExpression.cpp
@@ -67,8 +67,10 @@
*
* ComparisonExpression ::= PrimaryExpression "IS" "NULL" |
* PrimaryExpression "IS" "NOT" "NULL" |
- * PrimaryExpression "LIKE" LiteralString [ "ESCAPE" LiteralString ]
- * PrimaryExpression "NOT" "LIKE" LiteralString [ "ESCAPE" LiteralString ]
+ * PrimaryExpression "LIKE" LiteralString [ "ESCAPE" LiteralString ] |
+ * PrimaryExpression "NOT" "LIKE" LiteralString [ "ESCAPE" LiteralString ] |
+ * PrimaryExpression "BETWEEN" PrimaryExpression "AND" PrimaryExpression |
+ * PrimaryExpression "NOT" "BETWEEN" PrimaryExpression "AND" PrimaryExpression |
* PrimaryExpression ComparisonOpsOps PrimaryExpression |
* "NOT" ComparisonExpression |
* "(" OrExpression ")"
@@ -318,6 +320,34 @@ public:
}
};
+class BetweenExpression : public BoolExpression {
+ boost::scoped_ptr<Expression> e;
+ boost::scoped_ptr<Expression> l;
+ boost::scoped_ptr<Expression> u;
+
+public:
+ BetweenExpression(Expression* e_, Expression* l_, Expression* u_) :
+ e(e_),
+ l(l_),
+ u(u_)
+ {}
+
+ void repr(ostream& os) const {
+ os << *e << " BETWEEN " << *l << " AND " << *u;
+ }
+
+ BoolOrNone eval_bool(const SelectorEnv& env) const {
+ Value ve(e->eval(env));
+ if (unknown(ve)) return BN_UNKNOWN;
+ Value vl(l->eval(env));
+ if (unknown(vl)) return BN_UNKNOWN;
+ if (ve<vl) return BN_FALSE;
+ Value vu(u->eval(env));
+ if (unknown(vu)) return BN_UNKNOWN;
+ return BoolOrNone(ve<=vu);
+ }
+};
+
// Expression types...
class Literal : public Expression {
@@ -570,23 +600,25 @@ BoolExpression* parseSpecialComparisons(Tokeniser& tokeniser, std::auto_ptr<Expr
switch (tokeniser.nextToken().type) {
case T_LIKE: {
const Token t = tokeniser.nextToken();
- if ( t.type==T_STRING ) {
- // Check for "ESCAPE"
- if ( tokeniser.nextToken().type==T_ESCAPE ) {
- const Token e = tokeniser.nextToken();
- if ( e.type==T_STRING ) {
- return new LikeExpression(e1.release(), t.val, e.val);
- } else {
- return 0;
- }
- } else {
- tokeniser.returnTokens();
- return new LikeExpression(e1.release(), t.val);
- }
+ if ( t.type!=T_STRING ) return 0;
+ // Check for "ESCAPE"
+ if ( tokeniser.nextToken().type==T_ESCAPE ) {
+ const Token e = tokeniser.nextToken();
+ if ( e.type!=T_STRING ) return 0;
+ return new LikeExpression(e1.release(), t.val, e.val);
} else {
- return 0;
+ tokeniser.returnTokens();
+ return new LikeExpression(e1.release(), t.val);
}
}
+ case T_BETWEEN: {
+ std::auto_ptr<Expression> lower(parsePrimaryExpression(tokeniser));
+ if ( !lower.get() ) return 0;
+ if ( tokeniser.nextToken().type!=T_AND ) return 0;
+ std::auto_ptr<Expression> upper(parsePrimaryExpression(tokeniser));
+ if ( !upper.get() ) return 0;
+ return new BetweenExpression(e1.release(), lower.release(), upper.release());
+ }
default:
return 0;
}
@@ -628,11 +660,10 @@ BoolExpression* parseComparisonExpression(Tokeniser& tokeniser)
if (!e.get()) return 0;
return new UnaryBooleanExpression<BoolExpression>(&notOp, e.release());
}
+ case T_BETWEEN:
case T_LIKE: {
tokeniser.returnTokens();
- std::auto_ptr<BoolExpression> e(parseSpecialComparisons(tokeniser, e1));
- if (!e.get()) return 0;
- return e.release();
+ return parseSpecialComparisons(tokeniser, e1);
}
default:
break;