From 8cee9a9e47c18648c74cf2368dfc6d1d8204929e Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Mon, 17 Jan 2022 13:48:59 +0800 Subject: [PATCH] fix(rule): compare to null variables should return false --- .../src/emqx_rule_runtime.erl | 5 ++++ .../test/emqx_rule_engine_SUITE.erl | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index 080a36511..de853d7e2 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/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)); diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index ae003b4a4..4b8afea40 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/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 "