From 995025b5728e6c9a8bf833f5cab554b06ed4d60e Mon Sep 17 00:00:00 2001 From: Kjell Winblad Date: Mon, 29 May 2023 14:22:58 +0200 Subject: [PATCH 1/3] feat: add timezone_to_second/1 function to rule engine This commit adds the functions timezone_to_offset_seconds and its alias timezone_to_second to the rule engine. As the names suggests, these functions convert a timzone offset string such as "+02:00", "Z", "local" to an integer representing how many seconds that the given timezone differs from UTC. timezone_to_offset_seconds is the one of the two functions that should be advertised while timezone_to_second in kept for backwards compatibility with 4.X. Fixes: https://emqx.atlassian.net/browse/EMQX-10058 --- apps/emqx_machine/src/emqx_machine.app.src | 2 +- apps/emqx_rule_engine/src/emqx_rule_funcs.erl | 10 +++++++++- .../test/emqx_rule_funcs_SUITE.erl | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/emqx_machine/src/emqx_machine.app.src b/apps/emqx_machine/src/emqx_machine.app.src index 7cf0e4b53..5cfa80369 100644 --- a/apps/emqx_machine/src/emqx_machine.app.src +++ b/apps/emqx_machine/src/emqx_machine.app.src @@ -3,7 +3,7 @@ {id, "emqx_machine"}, {description, "The EMQX Machine"}, % strict semver, bump manually! - {vsn, "0.2.4"}, + {vsn, "0.2.5"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib, emqx_ctl]}, diff --git a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl index 73e2f78e7..a94aa0c8a 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl @@ -228,7 +228,9 @@ format_date/3, format_date/4, date_to_unix_ts/3, - date_to_unix_ts/4 + date_to_unix_ts/4, + timezone_to_second/1, + timezone_to_offset_seconds/1 ]). %% MongoDB specific date functions. These functions return a date tuple. The @@ -1104,6 +1106,12 @@ date_to_unix_ts(TimeUnit, Offset, FormatString, InputString) -> OffsetDelta = erlang:convert_time_unit(OffsetSecond, second, Unit), date_to_unix_ts(Unit, FormatString, InputString) - OffsetDelta. +timezone_to_second(TimeZone) -> + timezone_to_offset_seconds(TimeZone). + +timezone_to_offset_seconds(TimeZone) -> + emqx_calendar:offset_second(TimeZone). + %% @doc This is for sql funcs that should be handled in the specific modules. %% Here the emqx_rule_funcs module acts as a proxy, forwarding %% the function handling to the worker module. diff --git a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl index 9bb6e2e6f..525d60503 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl @@ -1012,6 +1012,25 @@ prop_format_date_fun() -> Args3DTUS = [<<"second">>, <<"+04:00">>, <<"--%m--%d--%Y---%H:%M:%S">>, Formatters3], Second == apply_func(date_to_unix_ts, Args3DTUS). +t_timezone_to_offset_seconds(_) -> + t_timezone_to_offset_seconds_helper(timezone_to_offset_seconds), + %% The timezone_to_second function is kept for compatibility with 4.X. + t_timezone_to_offset_seconds_helper(timezone_to_second). + +t_timezone_to_offset_seconds_helper(FunctionName) -> + ?assertEqual(120 * 60, apply_func(FunctionName, [<<"+02:00:00">>])), + ?assertEqual(-120 * 60, apply_func(FunctionName, [<<"-02:00:00">>])), + ?assertEqual(102, apply_func(FunctionName, [<<"+00:01:42">>])), + ?assertEqual(0, apply_func(FunctionName, [<<"z">>])), + ?assertEqual(0, apply_func(FunctionName, [<<"Z">>])), + ?assertEqual(42, apply_func(FunctionName, [42])), + ?assertEqual(0, apply_func(FunctionName, [undefined])), + %% Check that the following does not crash + apply_func(FunctionName, [<<"local">>]), + apply_func(FunctionName, ["local"]), + apply_func(FunctionName, [local]), + ok. + %%------------------------------------------------------------------------------ %% Utility functions %%------------------------------------------------------------------------------ From b87e0a2cdd6b5aa6807fd612826e3218c4c0bb85 Mon Sep 17 00:00:00 2001 From: Kjell Winblad Date: Mon, 29 May 2023 14:45:37 +0200 Subject: [PATCH 2/3] docs: add changelog entry --- changes/ce/feat-10858.en.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/ce/feat-10858.en.md diff --git a/changes/ce/feat-10858.en.md b/changes/ce/feat-10858.en.md new file mode 100644 index 000000000..1e2fa9fee --- /dev/null +++ b/changes/ce/feat-10858.en.md @@ -0,0 +1 @@ +A new utility function timezone_to_offset_seconds/1 has been added to the rule engine SQL language. This function converts a timezone string (for example, "+02:00", "Z" and "local") to the corresponding offset in seconds. From 354603da019317b38b1ffc797f019aa6c33a7fd8 Mon Sep 17 00:00:00 2001 From: Kjell Winblad Date: Mon, 29 May 2023 17:20:37 +0200 Subject: [PATCH 3/3] test: helper function was interpreted as a test function --- apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl index 525d60503..12110b206 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl @@ -1013,11 +1013,11 @@ prop_format_date_fun() -> Second == apply_func(date_to_unix_ts, Args3DTUS). t_timezone_to_offset_seconds(_) -> - t_timezone_to_offset_seconds_helper(timezone_to_offset_seconds), + timezone_to_offset_seconds_helper(timezone_to_offset_seconds), %% The timezone_to_second function is kept for compatibility with 4.X. - t_timezone_to_offset_seconds_helper(timezone_to_second). + timezone_to_offset_seconds_helper(timezone_to_second). -t_timezone_to_offset_seconds_helper(FunctionName) -> +timezone_to_offset_seconds_helper(FunctionName) -> ?assertEqual(120 * 60, apply_func(FunctionName, [<<"+02:00:00">>])), ?assertEqual(-120 * 60, apply_func(FunctionName, [<<"-02:00:00">>])), ?assertEqual(102, apply_func(FunctionName, [<<"+00:01:42">>])),