Skip to content

Commit 47b7ea5

Browse files
committed
Allow lexicographical comparison of strings
AMQP SQL spec: "The left operand is of greater value than the right operand if: ... both operands are of type string or of type symbol (any combination is permitted) and the lexicographical rank of the left operand is greater than the lexicographical rank of the right operand." In contrast, in JMS: "String [...] comparison is restricted to = and <>."
1 parent 05233d2 commit 47b7ea5

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

deps/rabbit/src/rabbit_amqp_filter_sql.erl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,20 +180,23 @@ eval0({'like', Expr, {pattern, Pattern}}, Msg) ->
180180
%% "Comparison or arithmetic with an unknown value always yields an unknown value."
181181
compare(_Op, Left, Right) when Left =:= undefined orelse Right =:= undefined ->
182182
undefined;
183-
%% "Only like type values can be compared.
184-
%% One exception is that it is valid to compare exact numeric values and approximate numeric values.
185-
%% String and Boolean comparison is restricted to = and <>."
183+
%% "Only like type values can be compared. One exception is that it is valid to
184+
%% compare exact numeric values and approximate numeric values"
186185
compare('=', Left, Right) ->
187186
Left == Right;
188187
compare('<>', Left, Right) ->
189188
Left /= Right;
190-
compare('>', Left, Right) when is_number(Left) andalso is_number(Right) ->
189+
compare('>', Left, Right) when is_number(Left) andalso is_number(Right) orelse
190+
is_binary(Left) andalso is_binary(Right) ->
191191
Left > Right;
192-
compare('<', Left, Right) when is_number(Left) andalso is_number(Right) ->
192+
compare('<', Left, Right) when is_number(Left) andalso is_number(Right) orelse
193+
is_binary(Left) andalso is_binary(Right) ->
193194
Left < Right;
194-
compare('>=', Left, Right) when is_number(Left) andalso is_number(Right) ->
195+
compare('>=', Left, Right) when is_number(Left) andalso is_number(Right) orelse
196+
is_binary(Left) andalso is_binary(Right) ->
195197
Left >= Right;
196-
compare('<=', Left, Right) when is_number(Left) andalso is_number(Right) ->
198+
compare('<=', Left, Right) when is_number(Left) andalso is_number(Right) orelse
199+
is_binary(Left) andalso is_binary(Right) ->
197200
Left =< Right;
198201
compare(_, _, _) ->
199202
%% "If the comparison of non-like type values is attempted,

deps/rabbit/test/amqp_filter_sql_unit_SUITE.erl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,21 @@ comparison_operators(_Config) ->
123123
%% Greater than
124124
true = match("weight > 3", app_props()),
125125
false = match("weight > 5", app_props()),
126+
true = match("country > 'DE'", app_props()),
127+
false = match("country > 'US'", app_props()),
126128

127129
%% Less than
128130
true = match("weight < 10", app_props()),
129131
false = match("weight < 5", app_props()),
132+
true = match("country < 'US'", app_props()),
133+
false = match("country < 'DE'", app_props()),
130134

131135
%% Greater than or equal
132136
true = match("weight >= 5", app_props()),
133137
true = match("weight >= 4", app_props()),
134138
false = match("weight >= 6", app_props()),
139+
true = match("country >= 'UK'", app_props()),
140+
true = match("country >= 'DE'", app_props()),
135141
%% "Only like type values can be compared. One exception is that it is
136142
%% valid to compare exact numeric values and approximate numeric value"
137143
true = match("weight >= 5.0", app_props()),
@@ -149,8 +155,11 @@ comparison_operators(_Config) ->
149155
false = match("weight <= 4", app_props()),
150156
true = match("price <= 10.6", app_props()),
151157
false = match("price <= 10", app_props()),
158+
true = match("country <= 'US'", app_props()),
159+
true = match("country <= 'UK'", app_props()),
160+
false = match("country <= 'DE'", app_props()),
152161

153-
%% "String and Boolean comparison is restricted to = and <>."
162+
%% "Boolean comparison is restricted to = and <>."
154163
%% "If the comparison of non-like type values is attempted, the value of the operation is false."
155164
true = match("active = true", app_props()),
156165
true = match("premium = false", app_props()),
@@ -160,19 +169,15 @@ comparison_operators(_Config) ->
160169
false = match("premium >= 0", app_props()),
161170
false = match("premium <= 0", app_props()),
162171

163-
false = match("country >= 'UK'", app_props()),
164-
false = match("country > 'UA'", app_props()),
165-
false = match("country >= 'UA'", app_props()),
166-
false = match("country < 'UA'", app_props()),
167-
false = match("country <= 'UA'", app_props()),
168-
false = match("country < 'UL'", app_props()),
169-
false = match("country < true", app_props()),
170-
171172
false = match("weight = '5'", app_props()),
172173
false = match("weight >= '5'", app_props()),
173174
false = match("weight <= '5'", app_props()),
175+
false = match("country <= true", app_props()),
176+
false = match("country >= true", app_props()),
174177
false = match("country > 1", app_props()),
175-
false = match("country < 1", app_props()).
178+
false = match("country >= 1", app_props()),
179+
false = match("country < 1", app_props()),
180+
false = match("country <= 1", app_props()).
176181

177182
arithmetic_operators(_Config) ->
178183
%% Addition

0 commit comments

Comments
 (0)