Просмотр исходного кода

Merge pull request #6763 from terry-xiaoyu/fix_rulesql_compare_to_undefined

fix(rule): compare to null variables should return false
Shawn 4 лет назад
Родитель
Сommit
d7105401a3

+ 5 - 0
apps/emqx_rule_engine/src/emqx_rule_runtime.erl

@@ -218,6 +218,11 @@ match_conditions({Op, L, R}, Data) when ?is_comp(Op) ->
 match_conditions({}, _Data) ->
     true.
 
+%% compare to an undefined variable
+compare(Op, undefined, undefined) ->
+    do_compare(Op, undefined, undefined);
+compare(_Op, L, R) when L == undefined; R == undefined ->
+    false;
 %% comparing numbers against strings
 compare(Op, L, R) when is_number(L), is_binary(R) ->
     do_compare(Op, L, number(R));

+ 30 - 0
apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl

@@ -87,6 +87,7 @@ groups() ->
        t_sqlparse_array_range_1,
        t_sqlparse_array_range_2,
        t_sqlparse_true_false,
+       t_sqlparse_undefined_variable,
        t_sqlparse_new_map
       ]},
      {events, [],
@@ -1219,6 +1220,35 @@ t_sqlparse_true_false(_Config) ->
                    <<"c">> := [true]
                    }, Res00).
 
+t_sqlparse_undefined_variable(_Config) ->
+    %% undefined == undefined
+    Sql00 = "select "
+            "a, b "
+            "from \"t/#\" "
+            "where a = b"
+            ,
+    {ok, Res00} = emqx_rule_sqltester:test(
+                    #{sql => Sql00, context => #{payload => <<"">>, topic => <<"t/a">>}}),
+    ?assertMatch(#{}, Res00),
+    ?assertEqual(0, map_size(Res00)),
+    %% undefined compare to non-undefined variables should return false
+    Sql01 = "select "
+            "a, b "
+            "from \"t/#\" "
+            "where a > b"
+            ,
+    {error, nomatch} = emqx_rule_sqltester:test(
+                    #{sql => Sql01,
+                      context => #{payload => <<"{\"b\":1}">>, topic => <<"t/a">>}}),
+    Sql02 = "select "
+            "a < b as c "
+            "from \"t/#\" "
+            ,
+    {ok, Res02} = emqx_rule_sqltester:test(
+                    #{sql => Sql02,
+                      context => #{payload => <<"{\"b\":1}">>, topic => <<"t/a">>}}),
+    ?assertMatch(#{<<"c">> := false}, Res02).
+
 t_sqlparse_new_map(_Config) ->
     %% construct a range without 'as'
     Sql00 = "select "