From 1acc74d2d9c55a98123f0e33a1823c98f15865e0 Mon Sep 17 00:00:00 2001 From: Aleksandr Cupacenko Date: Sat, 14 Sep 2024 15:08:46 +0300 Subject: [PATCH] stream_processor: fix operator precedence for logical operations Signed-off-by: Aleksandr Cupacenko revert definition removal Signed-off-by: Aleksandr Cupacenko add operator precedence unit tests correct precedencer order --- src/stream_processor/parser/sql.y | 6 +++++- tests/internal/include/sp_cb_functions.h | 20 ++++++++++++++++++++ tests/internal/include/sp_select_keys.h | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/stream_processor/parser/sql.y b/src/stream_processor/parser/sql.y index 866f95cc023..0b85011e730 100644 --- a/src/stream_processor/parser/sql.y +++ b/src/stream_processor/parser/sql.y @@ -1,4 +1,4 @@ -%name-prefix="flb_sp_" // replace with %define api.prefix {flb_sp_} +%name-prefix "flb_sp_" // replace with %define api.prefix {flb_sp_} %define api.pure full %define parse.error verbose %parse-param { struct flb_sp_cmd *cmd }; @@ -98,6 +98,10 @@ void yyerror(struct flb_sp_cmd *cmd, const char *query, void *scanner, const cha %type aggregate_func %type COUNT AVG SUM MAX MIN TIMESERIES_FORECAST +/* Define operator precedence and associativity for logical operations in conditions */ +%left OR // Lowest precedence for OR +%left AND // Middle precedence for AND +%right NOT // Highest precedence for NOT %destructor { flb_free ($$); } IDENTIFIER diff --git a/tests/internal/include/sp_cb_functions.h b/tests/internal/include/sp_cb_functions.h index 346a4bb7e12..bb45f63a531 100644 --- a/tests/internal/include/sp_cb_functions.h +++ b/tests/internal/include/sp_cb_functions.h @@ -206,6 +206,26 @@ static void cb_record_not_contains(int id, struct task_check *check, TEST_CHECK(ret == 0); } +static void cb_select_and_or_precedence(int id, struct task_check *check, + char *buf, size_t size) +{ + int ret; + + /* Expect all 11 rows */ + ret = mp_count_rows(buf, size); + TEST_CHECK_(ret == 11, "expected 11 rows but got %d", ret); +} + +static void cb_select_not_precedence(int id, struct task_check *check, + char *buf, size_t size) +{ + int ret; + + /* Expect all 11 rows */ + ret = mp_count_rows(buf, size); + TEST_CHECK_(ret == 11, "expected 11 rows but got %d", ret); +} + /* Callback functions to perform checks over results */ static void cb_select_sub_blue(int id, struct task_check *check, char *buf, size_t size) diff --git a/tests/internal/include/sp_select_keys.h b/tests/internal/include/sp_select_keys.h index ba3c809f3ad..83e363677ea 100644 --- a/tests/internal/include/sp_select_keys.h +++ b/tests/internal/include/sp_select_keys.h @@ -126,6 +126,20 @@ struct task_check select_keys_checks[] = { "SELECT id FROM TAG:'samples' WHERE @record.contains(x);", cb_record_not_contains, }, + + /* Operator precedence */ + { + 18, 0, 0, 0, + "and_or_precedence", + "SELECT id FROM STREAM:FLB WHERE false AND true OR true;", + cb_select_and_or_precedence, + }, + { + 19, 0, 0, 0, + "not_precedence", + "SELECT id FROM STREAM:FLB WHERE NOT true OR true;", + cb_select_not_precedence, + }, }; #endif