From 56b4de51ec731ee1835e6e16c0d0db5ef2969137 Mon Sep 17 00:00:00 2001 From: lukeman Date: Tue, 23 Jul 2024 16:49:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=8F=82=E6=95=B0=E6=8E=A7?= =?UTF-8?q?=E5=88=B6prior=E7=9A=84=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/gram.y | 55 ++++++++++--------- src/common/backend/utils/misc/guc/guc_sql.cpp | 3 +- src/include/miscadmin.h | 4 +- src/test/regress/expected/sw_bugfix-2.out | 36 +++++++++++- src/test/regress/sql/sw_bugfix-2.sql | 5 ++ 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index a75f413607..5bb8c1808c 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -26619,12 +26619,19 @@ client_logic_type: */ a_expr: c_expr { $$ = $1; } | PRIOR '(' a_expr ')' - { - List *argList = list_make1($3); - FuncCall *funcNode = MakePriorAsFunc(); - funcNode->args = argList; - $$ = (Node *)funcNode; - } + { + if (PRIOR_FUNCTION_FIRST || !IsA($3, ColumnRef) || ((ColumnRef*)$3)->prior) { + List *argList = list_make1($3); + FuncCall *funcNode = MakePriorAsFunc(); + funcNode->args = argList; + $$ = (Node *)funcNode; + } else { + ColumnRef *col = (ColumnRef *)$3; + col->prior = true; + col->location = 0; + $$ = (Node *)col; + } + } | a_expr TYPECAST Typename { $$ = makeTypeCast($1, $3, @2); } | a_expr COLLATE collate_name @@ -27288,15 +27295,22 @@ c_expr: columnref %prec UMINUS { $$ = $1; } | AexprConst { $$ = $1; } | PRIOR '(' columnref ')' { - ColumnRef *col = (ColumnRef *)$3; - col->prior = true; - /* - * Setting the location to a non-default 0 - * to indicate that this is a parenthetical - * case of PRIOR reference. - */ - col->location = 0; - $$ = (Node *)col; + if (PRIOR_FUNCTION_FIRST) { + List *argList = list_make1($3); + FuncCall *funcNode = MakePriorAsFunc(); + funcNode->args = argList; + $$ = (Node *)funcNode; + } else { + ColumnRef *col = (ColumnRef *)$3; + col->prior = true; + /* + * Setting the location to a non-default 0 + * to indicate that this is a parenthetical + * case of PRIOR reference. + */ + col->location = 0; + $$ = (Node *)col; + } } | PRIOR '(' c_expr ',' func_arg_list ')' { @@ -29370,16 +29384,7 @@ target_el: a_expr AS ColLabel $$->indirection = NIL; $$->val = (Node *)$1; $$->location = @1; - - ColumnRef* cr = (ColumnRef*) $1; - /* PRIOR(x) in target list implies func call */ - if (IsA($1, ColumnRef) && cr->prior && cr->location == 0) { - FuncCall *fn = MakePriorAsFunc(); - cr->prior = false; - fn->args = list_make1(cr); - $$->val = (Node *)fn; - } - } + } | '*' { ColumnRef *n = makeNode(ColumnRef); diff --git a/src/common/backend/utils/misc/guc/guc_sql.cpp b/src/common/backend/utils/misc/guc/guc_sql.cpp index bd7328666f..d1342a473b 100755 --- a/src/common/backend/utils/misc/guc/guc_sql.cpp +++ b/src/common/backend/utils/misc/guc/guc_sql.cpp @@ -396,7 +396,8 @@ static const struct behavior_compat_entry behavior_compat_options[OPT_MAX] = { {"update_unusable_unique_index_on_iud", OPT_UPDATE_UNUSABLE_UNIQUE_INDEX_ON_IUD}, {"prefer_parse_cursor_parentheses_as_expr", OPT_PREFER_PARSE_CURSOR_PARENTHESES_AS_EXPR}, {"update_global_index_on_partition_change", OPT_UPDATE_GLOBAL_INDEX_ON_PARTITION_CHANGE}, - {"float_as_numeric", OPT_FLOAT_AS_NUMERIC} + {"float_as_numeric", OPT_FLOAT_AS_NUMERIC}, + {"prior_function_first", OPT_PRIOR_FUNCTION_FIRST} }; // increase SQL_IGNORE_STRATEGY_NUM if we need more strategy diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 6e07ede951..e6e2d4a146 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -218,7 +218,8 @@ extern bool contain_backend_version(uint32 version_number); #define OPT_PREFER_PARSE_CURSOR_PARENTHESES_AS_EXPR (1LL << 31) #define OPT_UPDATE_GLOBAL_INDEX_ON_PARTITION_CHANGE (1LL << 32) #define OPT_FLOAT_AS_NUMERIC (1LL << 33) -#define OPT_MAX 34 +#define OPT_PRIOR_FUNCTION_FIRST (1LL << 34) +#define OPT_MAX 35 #define PLPSQL_OPT_FOR_LOOP 1 #define PLPSQL_OPT_OUTPARAM 2 @@ -266,6 +267,7 @@ extern bool contain_backend_version(uint32 version_number); #define PREFER_PARSE_CURSOR_PARENTHESES_AS_EXPR (u_sess->utils_cxt.behavior_compat_flags & OPT_PREFER_PARSE_CURSOR_PARENTHESES_AS_EXPR) #define UPDATE_GLOBAL_INDEX_ON_PARTITION_CHANGE (u_sess->utils_cxt.behavior_compat_flags & OPT_UPDATE_GLOBAL_INDEX_ON_PARTITION_CHANGE) #define FLOAT_AS_NUMERIC (u_sess->utils_cxt.behavior_compat_flags & OPT_FLOAT_AS_NUMERIC) +#define PRIOR_FUNCTION_FIRST (u_sess->utils_cxt.behavior_compat_flags & OPT_PRIOR_FUNCTION_FIRST) /* define database compatibility Attribute */ typedef struct { diff --git a/src/test/regress/expected/sw_bugfix-2.out b/src/test/regress/expected/sw_bugfix-2.out index 99cd9f242b..d9e089641f 100755 --- a/src/test/regress/expected/sw_bugfix-2.out +++ b/src/test/regress/expected/sw_bugfix-2.out @@ -1397,27 +1397,61 @@ select t1.id,t1.pid,t2.id from test_hcb_ptb t1 join test_hcb_ptb t2 on t1.id=t2. create or replace function prior(id int) returns int LANGUAGE plpgsql AS $$ begin + raise info 'invoke prior function'; return id*3; end; $$; select id,pid,prior(level) from test_hcb_ptb where prior(id)>10 start with id=141 connect by prior pid=id; + id | pid | level +-----+-----+------- + 131 | 121 | 0 + 121 | 111 | 1 + 111 | 11 | 2 + 11 | 1 | 3 + 1 | 0 | 4 +(5 rows) + +set behavior_compat_options = 'prior_function_first'; +select id,pid,prior(level) from test_hcb_ptb where prior(id)>10 start + with id=141 connect by prior pid=id; +INFO: invoke prior function +INFO: invoke prior function +CONTEXT: referenced column: prior +INFO: invoke prior function +INFO: invoke prior function +CONTEXT: referenced column: prior +INFO: invoke prior function +INFO: invoke prior function +CONTEXT: referenced column: prior +INFO: invoke prior function +INFO: invoke prior function +CONTEXT: referenced column: prior +INFO: invoke prior function +INFO: invoke prior function +CONTEXT: referenced column: prior +INFO: invoke prior function id | pid | prior -----+-----+------- + 141 | 131 | 3 131 | 121 | 6 121 | 111 | 9 111 | 11 | 12 11 | 1 | 15 - 1 | 0 | 18 (5 rows) +set behavior_compat_options = ''; select prior(1+1); +INFO: invoke prior function +CONTEXT: referenced column: prior prior ------- 6 (1 row) select prior(1); +INFO: invoke prior function +CONTEXT: referenced column: prior prior ------- 3 diff --git a/src/test/regress/sql/sw_bugfix-2.sql b/src/test/regress/sql/sw_bugfix-2.sql index d98ff79005..b97579e36f 100644 --- a/src/test/regress/sql/sw_bugfix-2.sql +++ b/src/test/regress/sql/sw_bugfix-2.sql @@ -473,11 +473,16 @@ select t1.id,t1.pid,t2.id from test_hcb_ptb t1 join test_hcb_ptb t2 on t1.id=t2. create or replace function prior(id int) returns int LANGUAGE plpgsql AS $$ begin + raise info 'invoke prior function'; return id*3; end; $$; select id,pid,prior(level) from test_hcb_ptb where prior(id)>10 start with id=141 connect by prior pid=id; +set behavior_compat_options = 'prior_function_first'; +select id,pid,prior(level) from test_hcb_ptb where prior(id)>10 start + with id=141 connect by prior pid=id; +set behavior_compat_options = ''; select prior(1+1); select prior(1); select prior(1,1); -- Gitee