diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index a75f413607b72f20373b54fe32245670cc3d8f44..5bb8c1808cf8f56595df75a7680e3a84b933f782 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 bd7328666fe80156da10e7addde4eebb76f12df8..d1342a473b22deaa78aa4b3034de9a64e61ea9c9 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 6e07ede951c40abedd55577997ba9f7cce78717b..e6e2d4a146f06a3b72d706a88b5af9da397e2481 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 99cd9f242bc2934a54c1f667010bb4a6d8d0959e..d9e089641f26f4f5cba4e8e0aa7a7e04ea43e602 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 d98ff79005179a596cf0a268f07510313d9c1c10..b97579e36fe41424d121266ef6634344daabe60e 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);