@@ -46,9 +46,6 @@ parse({described, Descriptor, {utf8, JmsSelector}}) ->
4646eval ({ApplicationProperties , Ast }, Msg ) ->
4747 State = case ApplicationProperties of
4848 true ->
49- % % This AST references application-properties.
50- % % Since we will probably dereference during evaluation,
51- % % for performance reasons let's parse them here only once.
5249 AppProps = mc :routing_headers (Msg , []),
5350 {AppProps , Msg };
5451 false ->
@@ -128,27 +125,21 @@ eval0({'not', Expr}, Msg) ->
128125 end ;
129126
130127% % Comparison operators
131- eval0 ({'=' = Op , Expr1 , Expr2 }, Msg ) ->
132- compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
133- eval0 ({'<>' = Op , Expr1 , Expr2 }, Msg ) ->
134- compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
135- eval0 ({'>' = Op , Expr1 , Expr2 }, Msg ) ->
136- compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
137- eval0 ({'<' = Op , Expr1 , Expr2 }, Msg ) ->
138- compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
139- eval0 ({'>=' = Op , Expr1 , Expr2 }, Msg ) ->
140- compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
141- eval0 ({'<=' = Op , Expr1 , Expr2 }, Msg ) ->
128+ eval0 ({Op , Expr1 , Expr2 }, Msg )
129+ when Op =:= '=' orelse
130+ Op =:= '<>' orelse
131+ Op =:= '>' orelse
132+ Op =:= '<' orelse
133+ Op =:= '>=' orelse
134+ Op =:= '<=' ->
142135 compare (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
143136
144137% % Arithmetic operators
145- eval0 ({'+' = Op , Expr1 , Expr2 }, Msg ) ->
146- arithmetic (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
147- eval0 ({'-' = Op , Expr1 , Expr2 }, Msg ) ->
148- arithmetic (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
149- eval0 ({'*' = Op , Expr1 , Expr2 }, Msg ) ->
150- arithmetic (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
151- eval0 ({'/' = Op , Expr1 , Expr2 }, Msg ) ->
138+ eval0 ({Op , Expr1 , Expr2 }, Msg )
139+ when Op =:= '+' orelse
140+ Op =:= '-' orelse
141+ Op =:= '*' orelse
142+ Op =:= '/' ->
152143 arithmetic (Op , eval0 (Expr1 , Msg ), eval0 (Expr2 , Msg ));
153144
154145% % Unary operators
@@ -171,7 +162,6 @@ eval0({'between', Expr, From, To}, Msg) ->
171162 FromVal = eval0 (From , Msg ),
172163 ToVal = eval0 (To , Msg ),
173164 between (Value , FromVal , ToVal );
174-
175165eval0 ({'not_between' , Expr , From , To }, Msg ) ->
176166 case eval0 ({'between' , Expr , From , To }, Msg ) of
177167 true -> false ;
@@ -182,7 +172,6 @@ eval0({'not_between', Expr, From, To}, Msg) ->
182172eval0 ({'in' , Expr , ValueList }, Msg ) ->
183173 Value = eval0 (Expr , Msg ),
184174 is_in (Value , ValueList );
185-
186175eval0 ({'not_in' , Expr , ValueList }, Msg ) ->
187176 case eval0 ({'in' , Expr , ValueList }, Msg ) of
188177 true -> false ;
@@ -192,7 +181,6 @@ eval0({'not_in', Expr, ValueList}, Msg) ->
192181
193182eval0 ({'is_null' , Expr }, Msg ) ->
194183 eval0 (Expr , Msg ) =:= undefined ;
195-
196184eval0 ({'is_not_null' , Expr }, Msg ) ->
197185 eval0 (Expr , Msg ) =/= undefined ;
198186
@@ -202,20 +190,15 @@ eval0({'like', Expr, {pattern, Pattern}}, Msg) ->
202190 true -> like (Subject , Pattern );
203191 false -> undefined
204192 end ;
205-
206193eval0 ({'not_like' , Expr , Pattern }, Msg ) ->
207194 case eval0 ({'like' , Expr , Pattern }, Msg ) of
208195 true -> false ;
209196 false -> true ;
210197 _ -> undefined
211198 end .
212199
213- % % Helper functions
214-
215200% % "Comparison or arithmetic with an unknown value always yields an unknown value."
216- compare (_ , undefined , _ ) ->
217- undefined ;
218- compare (_ , _ , undefined ) ->
201+ compare (_Op , Left , Right ) when Left =:= undefined orelse Right =:= undefined ->
219202 undefined ;
220203% % "Only like type values can be compared.
221204% % One exception is that it is valid to compare exact numeric values and approximate numeric values.
@@ -237,9 +220,7 @@ compare(_, _, _) ->
237220 % % the value of the operation is false."
238221 false .
239222
240- arithmetic (_ , undefined , _ ) ->
241- undefined ;
242- arithmetic (_ , _ , undefined ) ->
223+ arithmetic (_Op , Left , Right ) when Left =:= undefined orelse Right =:= undefined ->
243224 undefined ;
244225arithmetic ('+' , Left , Right ) when is_number (Left ) andalso is_number (Right ) ->
245226 Left + Right ;
@@ -334,7 +315,7 @@ jms_selector_to_list(JmsSelector) ->
334315 String when is_list (String ) ->
335316 {ok , String };
336317 Error ->
337- rabbit_log :warning (" JMS message selector ~p is not UTF-8: ~p " ,
318+ rabbit_log :warning (" JMS message selector ~p is not UTF-8 encoded : ~p " ,
338319 [JmsSelector , Error ]),
339320 error
340321 end .
@@ -383,7 +364,7 @@ transform_ast(Ast0, JmsSelector) ->
383364 ({Op , _Ident , _Pattern , _Escape } = Node )
384365 when Op =:= 'like' orelse
385366 Op =:= 'not_like' ->
386- transform_pattern (Node );
367+ transform_pattern_node (Node );
387368 (Node ) ->
388369 Node
389370 end , Ast0 ) of
@@ -407,29 +388,24 @@ has_binary_identifier(Ast) ->
407388% % we will optimise message evaluation by using Erlang pattern matching.
408389% % Otherwise, we will match with a regex. Even though we compile regexes,
409390% % they are slower compared to Erlang pattern matching.
410- transform_pattern ({Op , Ident , Pattern , Escape }) ->
411- Pat = case analyze_pattern (Pattern , Escape ) of
412- regex ->
413- Re = jms_pattern_to_regex (Pattern , Escape , []),
414- case re :compile (" ^" ++ Re ++ " $" , [unicode ]) of
415- {ok , CompiledRe } ->
416- CompiledRe ;
417- {error , Reason } ->
418- throw ({invalid_pattern , Reason })
419- end ;
420- NoRegex ->
421- NoRegex
422- end ,
391+ transform_pattern_node ({Op , Ident , Pattern , Escape }) ->
392+ Pat = transform_pattern (Pattern , Escape ),
423393 {Op , Ident , {pattern , Pat }}.
424394
425- analyze_pattern (Pattern , Escape ) ->
395+ transform_pattern (Pattern , Escape ) ->
426396 case scan_wildcards (Pattern , Escape ) of
427397 {none , Chars } ->
428398 {exact , unicode :characters_to_binary (Chars )};
429399 {single_percent , Chars , PercentPos } ->
430- analyze_percent (Chars , PercentPos );
400+ single_percent (Chars , PercentPos );
431401 regex ->
432- regex
402+ Re = jms_pattern_to_regex (Pattern , Escape , []),
403+ case re :compile (" ^" ++ Re ++ " $" , [unicode ]) of
404+ {ok , CompiledRe } ->
405+ CompiledRe ;
406+ {error , Reason } ->
407+ throw ({invalid_pattern , Reason })
408+ end
433409 end .
434410
435411scan_wildcards (Pattern , Escape ) ->
@@ -458,15 +434,15 @@ scan_wildcards_1([$% | _], _, _, _) ->
458434scan_wildcards_1 ([Char | Rest ], Escape , Acc , PctPos ) ->
459435 scan_wildcards_1 (Rest , Escape , [check_char (Char ) | Acc ], PctPos ).
460436
461- analyze_percent (Chars , 0 ) ->
437+ single_percent (Chars , 0 ) ->
462438 % % % at start - suffix match
463439 Bin = unicode :characters_to_binary (Chars ),
464440 {suffix , byte_size (Bin ), Bin };
465- analyze_percent (Chars , Pos ) when length (Chars ) =:= Pos ->
441+ single_percent (Chars , Pos ) when length (Chars ) =:= Pos ->
466442 % % % at end - prefix match
467443 Bin = unicode :characters_to_binary (Chars ),
468444 {prefix , byte_size (Bin ), Bin };
469- analyze_percent (Chars , Pos ) ->
445+ single_percent (Chars , Pos ) ->
470446 % % % in middle - prefix and suffix match
471447 {Prefix , Suffix } = lists :split (Pos , Chars ),
472448 PrefixBin = unicode :characters_to_binary (Prefix ),
0 commit comments