Explorar o código

Merge pull request #8827 from lafirest/fix/sql_placeholder

fix(placeholder): allow placeholders in sql to be wrapped by quotes
JianBo He %!s(int64=3) %!d(string=hai) anos
pai
achega
47648b3874

+ 7 - 3
apps/emqx_plugin_libs/src/emqx_placeholder.erl

@@ -39,7 +39,7 @@
     sql_data/1
 ]).
 
--define(EX_PLACE_HOLDER, "(\\$\\{[a-zA-Z0-9\\._]+\\})").
+-define(EX_PLACE_HOLDER, "(\\$\\{[a-zA-Z0-9\\._]+\\}|\"\\$\\{[a-zA-Z0-9\\._]+\\}\")").
 %% Space and CRLF
 -define(EX_WITHE_CHARS, "\\s").
 
@@ -235,7 +235,9 @@ get_phld_var(Phld, Data) ->
     emqx_rule_maps:nested_get(Phld, Data).
 
 preproc_var_re(#{placeholders := PHs}) ->
-    "(" ++ string:join([ph_to_re(PH) || PH <- PHs], "|") ++ ")";
+    Res = [ph_to_re(PH) || PH <- PHs],
+    QuoteRes = ["\"" ++ Re ++ "\"" || Re <- Res],
+    "(" ++ string:join(Res ++ QuoteRes, "|") ++ ")";
 preproc_var_re(#{}) ->
     ?EX_PLACE_HOLDER.
 
@@ -292,7 +294,9 @@ parse_nested(Attr) ->
     end.
 
 unwrap(<<"${", Val/binary>>) ->
-    binary:part(Val, {0, byte_size(Val) - 1}).
+    binary:part(Val, {0, byte_size(Val) - 1});
+unwrap(<<"\"${", Val/binary>>) ->
+    binary:part(Val, {0, byte_size(Val) - 2}).
 
 quote_sql(Str) ->
     quote(Str, <<"\\\\'">>).

+ 1 - 1
apps/emqx_plugin_libs/src/emqx_plugin_libs.app.src

@@ -1,7 +1,7 @@
 %% -*- mode: erlang -*-
 {application, emqx_plugin_libs, [
     {description, "EMQX Plugin utility libs"},
-    {vsn, "4.3.2"},
+    {vsn, "4.3.3"},
     {modules, []},
     {applications, [kernel, stdlib]},
     {env, []}

+ 15 - 0
apps/emqx_plugin_libs/test/emqx_placeholder_SUITE.erl

@@ -150,6 +150,21 @@ t_preproc_sql6(_) ->
         emqx_placeholder:proc_sql(ParamsTokens, Selected)
     ).
 
+t_preproc_sql7(_) ->
+    Selected = #{a => <<"a">>, b => <<"b">>},
+    {PrepareStatement, ParamsTokens} = emqx_placeholder:preproc_sql(
+        <<"a:\"${a}\",b:\"${b}\"">>,
+        #{
+            replace_with => '$n',
+            placeholders => [<<"${a}">>]
+        }
+    ),
+    ?assertEqual(<<"a:$1,b:\"${b}\"">>, PrepareStatement),
+    ?assertEqual(
+        [<<"a">>],
+        emqx_placeholder:proc_sql(ParamsTokens, Selected)
+    ).
+
 t_preproc_tmpl_deep(_) ->
     Selected = #{a => <<"1">>, b => 1, c => 1.0, d => #{d1 => <<"hi">>}},