diff --git a/apps/emqx_rule_engine/src/emqx_rule_utils.erl b/apps/emqx_rule_engine/src/emqx_rule_utils.erl index ba3d4e841..b4fa0e6fc 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_utils.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_utils.erl @@ -26,6 +26,7 @@ , preproc_sql/1 , preproc_sql/2 , proc_sql/2 + , proc_sql_param_str/2 ]). %% type converting @@ -142,6 +143,11 @@ preproc_sql(Sql, ReplaceWith) -> proc_sql(Tokens, Data) -> proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => fun sql_data/1}). +-spec(proc_sql_param_str(tmpl_token(), map()) -> binary()). +proc_sql_param_str(Tokens, Data) -> + iolist_to_binary( + proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => fun quote/1})). + %% backward compatibility for hot upgrading from =< e4.2.1 get_phld_var(Fun, Data) when is_function(Fun) -> Fun(Data); @@ -232,6 +238,13 @@ sql_data(Bool) when is_boolean(Bool) -> Bool; sql_data(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8); sql_data(Map) when is_map(Map) -> emqx_json:encode(Map). +quote(List) when is_list(List) -> [$', List, $']; +quote(Bin) when is_binary(Bin) -> [$', Bin, $']; +quote(Num) when is_number(Num) -> bin(Num); +quote(Bool) when is_boolean(Bool) -> bin(Bool); +quote(Atom) when is_atom(Atom) -> [$', atom_to_binary(Atom, utf8), $']; +quote(Map) when is_map(Map) -> [$', emqx_json:encode(Map), $']. + str(Bin) when is_binary(Bin) -> binary_to_list(Bin); str(Num) when is_number(Num) -> number_to_list(Num); str(Atom) when is_atom(Atom) -> atom_to_list(Atom); diff --git a/apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl index f6f71ba68..006320ad8 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl @@ -110,3 +110,9 @@ t_preproc_sql2(_) -> {PrepareStatement, ParamsTokens} = emqx_rule_utils:preproc_sql(<<"a:$a,b:b},c:{c},d:${d">>, '?'), ?assertEqual(<<"a:$a,b:b},c:{c},d:${d">>, PrepareStatement), ?assertEqual([], emqx_rule_utils:proc_sql(ParamsTokens, Selected)). + +t_preproc_sql3(_) -> + Selected = #{a => <<"1">>, b => 1, c => 1.0, d => #{d1 => <<"hi">>}}, + ParamsTokens = emqx_rule_utils:preproc_tmpl(<<"a:${a},b:${b},c:${c},d:${d}">>), + ?assertEqual(<<"a:'1',b:1,c:1.0,d:'{\"d1\":\"hi\"}'">>, + emqx_rule_utils:proc_sql_param_str(ParamsTokens, Selected)).