From 18043150bea8c294772f96949cf4fd3ae5b42d70 Mon Sep 17 00:00:00 2001 From: firest Date: Wed, 17 May 2023 10:55:47 +0800 Subject: [PATCH 1/2] fix: cannot access columns exported by FOREACH in DO clause --- apps/emqx_rule_engine/src/emqx_rule_runtime.erl | 4 ++-- .../emqx_rule_engine/test/emqx_rule_engine_SUITE.erl | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index d7412d03c..5b7f962fb 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -144,14 +144,14 @@ do_apply_rule( ) of true -> - Collection2 = filter_collection(Columns, InCase, DoEach, Collection), + Collection2 = filter_collection(ColumnsAndSelected, InCase, DoEach, Collection), case Collection2 of [] -> ok = emqx_metrics_worker:inc(rule_metrics, RuleId, 'failed.no_result'); _ -> ok = emqx_metrics_worker:inc(rule_metrics, RuleId, 'passed') end, - NewEnvs = maps:merge(Columns, Envs), + NewEnvs = maps:merge(ColumnsAndSelected, Envs), {ok, [handle_action_list(RuleId, Actions, Coll, NewEnvs) || Coll <- Collection2]}; false -> ok = emqx_metrics_worker:inc(rule_metrics, RuleId, 'failed.no_result'), 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 eb253e516..9c3e5513a 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -1735,11 +1735,12 @@ t_sqlparse_foreach_7(_Config) -> ) ). +-define(COLL, #{<<"info">> := [<<"haha">>, #{<<"name">> := <<"cmd1">>, <<"cmd">> := <<"1">>}]}). t_sqlparse_foreach_8(_Config) -> %% Verify foreach-do-incase and cascaded AS Sql = "foreach json_decode(payload) as p, p.sensors as s, s.collection as c, c.info as info " - "do info.cmd as msg_type, info.name as name " + "do info.cmd as msg_type, info.name as name, s, c " "incase is_map(info) " "from \"t/#\" " "where s.page = '2' ", @@ -1748,7 +1749,14 @@ t_sqlparse_foreach_8(_Config) -> "{\"info\":[\"haha\", {\"name\":\"cmd1\", \"cmd\":\"1\"}]} } }" >>, ?assertMatch( - {ok, [#{<<"name">> := <<"cmd1">>, <<"msg_type">> := <<"1">>}]}, + {ok, [ + #{ + <<"name">> := <<"cmd1">>, + <<"msg_type">> := <<"1">>, + <<"s">> := #{<<"page">> := 2, <<"collection">> := ?COLL}, + <<"c">> := ?COLL + } + ]}, emqx_rule_sqltester:test( #{ sql => Sql, From 1f7ede90a429c7a568965d688de3cfe0fef75cb0 Mon Sep 17 00:00:00 2001 From: firest Date: Wed, 17 May 2023 11:01:31 +0800 Subject: [PATCH 2/2] chore: update app version && changes --- apps/emqx_rule_engine/src/emqx_rule_engine.app.src | 2 +- changes/ce/fix-10728.en.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changes/ce/fix-10728.en.md diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.app.src b/apps/emqx_rule_engine/src/emqx_rule_engine.app.src index 94a48fb35..8dc78958a 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.app.src +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.app.src @@ -2,7 +2,7 @@ {application, emqx_rule_engine, [ {description, "EMQX Rule Engine"}, % strict semver, bump manually! - {vsn, "5.0.16"}, + {vsn, "5.0.17"}, {modules, []}, {registered, [emqx_rule_engine_sup, emqx_rule_engine]}, {applications, [kernel, stdlib, rulesql, getopt, emqx_ctl]}, diff --git a/changes/ce/fix-10728.en.md b/changes/ce/fix-10728.en.md new file mode 100644 index 000000000..82bd123e9 --- /dev/null +++ b/changes/ce/fix-10728.en.md @@ -0,0 +1,11 @@ +Fixed an issue where the rule engine was unable to access variables exported by `FOREACH` in the `DO` clause. + + Given a payload: `{"date": "2023-05-06", "array": ["a"]}`, as well as the following SQL statement: + ``` + FOREACH payload.date as date, payload.array as elem + DO date, elem + FROM "t/#" + ``` + Prior to the fix, the `date` variable exported by `FOREACH` could not be accessed in the `DO` clause of the above SQL, resulting in the following output for the SQL statement: + `[{"elem": "a","date": "undefined"}]`. + After the fix, the output of the SQL statement is: `[{"elem": "a","date": "2023-05-06"}]`