From 9f3f132608a1c045db91209d0747e4ba197cdbe0 Mon Sep 17 00:00:00 2001 From: leiziwei Date: Sat, 14 Sep 2024 17:18:10 +0800 Subject: [PATCH] =?UTF-8?q?record=E6=9F=A5=E8=AF=A2=E4=BC=AA=E5=88=97?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/gram.y | 17 +++++- .../interfaces/ecpg/preproc/ecpg.trailer | 13 ++++ src/common/interfaces/ecpg/preproc/ecpg.type | 1 + src/common/interfaces/ecpg/preproc/parse.pl | 1 + .../expected/plpgsql_cursor_rowtype.out | 59 +++++++++++++++++++ .../regress/sql/plpgsql_cursor_rowtype.sql | 43 ++++++++++++++ 6 files changed, 132 insertions(+), 2 deletions(-) diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index ea91ef32e..bdea1d8c4 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -704,7 +704,7 @@ static char* IdentResolveToChar(char *ident, core_yyscan_t yyscanner); %type Sconst comment_text notify_payload %type RoleId TypeOwner opt_granted_by opt_boolean_or_string ColId_or_Sconst definer_user definer_expression UserId %type var_list guc_value_extension_list -%type ColId ColLabel var_name type_function_name param_name charset_collate_name +%type ColId ColLabel ColLabel_with_rownum var_name type_function_name param_name charset_collate_name %type var_value zone_value %type unreserved_keyword type_func_name_keyword @@ -29653,7 +29653,7 @@ database_name: access_method: ColId { $$ = $1; }; -attr_name: ColLabel { $$ = $1; }; +attr_name: ColLabel_with_rownum { $$ = $1; }; index_name: ColId { $$ = $1; }; @@ -29916,6 +29916,19 @@ ColLabel: IDENT $$ = pstrdup($1); } ; +ColLabel_with_rownum: IDENT + { + $$ = IdentResolveToChar($1, yyscanner); + } + | '\''IDENT'\'' { $$ = $2; } + | unreserved_keyword { $$ = pstrdup($1); } + | col_name_keyword { $$ = pstrdup($1); } + | type_func_name_keyword { $$ = pstrdup($1); } + | reserved_keyword + { + $$ = pstrdup($1); + } + ; DelimiterStmt: DELIMITER delimiter_str_names END_OF_INPUT { diff --git a/src/common/interfaces/ecpg/preproc/ecpg.trailer b/src/common/interfaces/ecpg/preproc/ecpg.trailer index a6ad4a217..70622f624 100644 --- a/src/common/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/common/interfaces/ecpg/preproc/ecpg.trailer @@ -1571,6 +1571,19 @@ ColLabel: ECPGColLabel { $$ = $1; } | ECPGunreserved_interval { $$ = $1; } ; +ColLabel_with_rownum: ECPGColLabel { $$ = $1; } + | ECPGTypeName { $$ = $1; } + | CHAR_P { $$ = mm_strdup("char"); } + | CURRENT_P { $$ = mm_strdup("current"); } + | INPUT_P { $$ = mm_strdup("input"); } + | INT_P { $$ = mm_strdup("int"); } + | TO { $$ = mm_strdup("to"); } + | UNION { $$ = mm_strdup("union"); } + | VALUES { $$ = mm_strdup("values"); } + | ECPGCKeywords { $$ = $1; } + | ECPGunreserved_interval { $$ = $1; } + ; + ECPGColLabel: ECPGColLabelCommon { $$ = $1; } | unreserved_keyword { $$ = $1; } | reserved_keyword { $$ = $1; } diff --git a/src/common/interfaces/ecpg/preproc/ecpg.type b/src/common/interfaces/ecpg/preproc/ecpg.type index ac6aa000a..bcb85e50e 100644 --- a/src/common/interfaces/ecpg/preproc/ecpg.type +++ b/src/common/interfaces/ecpg/preproc/ecpg.type @@ -47,6 +47,7 @@ %type civarind %type ColId %type ColLabel +%type ColLabel_with_rownum %type connect_options %type connection_object %type connection_target diff --git a/src/common/interfaces/ecpg/preproc/parse.pl b/src/common/interfaces/ecpg/preproc/parse.pl index d92195c3d..bde6de13a 100644 --- a/src/common/interfaces/ecpg/preproc/parse.pl +++ b/src/common/interfaces/ecpg/preproc/parse.pl @@ -74,6 +74,7 @@ my %replace_types = ( 'type_function_name' => 'ignore', 'AnonyBlockStmt' => 'ignore', 'ColLabel' => 'ignore', + 'ColLabel_with_rownum' => 'ignore', 'Sconst' => 'ignore',); # these replace_line commands excise certain keywords from the core keyword diff --git a/src/test/regress/expected/plpgsql_cursor_rowtype.out b/src/test/regress/expected/plpgsql_cursor_rowtype.out index dead19aa7..2d615e860 100644 --- a/src/test/regress/expected/plpgsql_cursor_rowtype.out +++ b/src/test/regress/expected/plpgsql_cursor_rowtype.out @@ -65,6 +65,65 @@ END; NOTICE: Result: (,,,,,) drop table test_2 cascade; set behavior_compat_options='allow_procedure_compile_check,disable_record_type_in_dml'; +create table t_CurRowtype_Def_Case0001(col1 int primary key,col2 varchar(100)); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_currowtype_def_case0001_pkey" for table "t_currowtype_def_case0001" +insert into t_CurRowtype_Def_Case0001 values(1,'one'); +insert into t_CurRowtype_Def_Case0001 values(2,'two'); +insert into t_CurRowtype_Def_Case0001 values(3,'three'); +insert into t_CurRowtype_Def_Case0001 values(4,NULL); +--创建游标rowtype,select 伪列;expect:成功,输出4行 +declare + cursor cur_CurRowtype_Def_Case0001_1 is select col1,col2,rownum from t_CurRowtype_Def_Case0001; + source cur_CurRowtype_Def_Case0001_1%rowtype; +begin + open cur_CurRowtype_Def_Case0001_1; + loop + fetch cur_CurRowtype_Def_Case0001_1 into source; + exit when cur_CurRowtype_Def_Case0001_1%notfound; + raise notice '% , % ,% ',source.col1,source.col2,source.rownum; + end loop; + close cur_CurRowtype_Def_Case0001_1; +end; +/ +NOTICE: 1 , one ,1 +NOTICE: 2 , two ,2 +NOTICE: 3 , three ,3 +NOTICE: 4 , ,4 +drop table t_CurRowtype_Def_Case0001; +create table t_CurRowtype_Def_Case0002(col1 int primary key,rownum varchar(100)); +ERROR: syntax error at or near "rownum" +LINE 1: ...le t_CurRowtype_Def_Case0002(col1 int primary key,rownum var... + ^ +create table t_CurRowtype_Def_Case0002(col1 int primary key); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_currowtype_def_case0002_pkey" for table "t_currowtype_def_case0002" +insert into t_CurRowtype_Def_Case0002 values(1); +select t_CurRowtype_Def_Case0002.rownum from t_CurRowtype_Def_Case0002; +ERROR: column t_currowtype_def_case0002.rownum does not exist +LINE 1: select t_CurRowtype_Def_Case0002.rownum from t_CurRowtype_De... + ^ +CONTEXT: referenced column: rownum +select rownum from t_CurRowtype_Def_Case0002; + rownum +-------- + 1 +(1 row) + +drop table t_CurRowtype_Def_Case0002; +CREATE TYPE type_record AS ( + first text, + rownum int4 +) ; +ERROR: syntax error at or near "rownum" +LINE 3: rownum int4 + ^ +DECLARE + type rectype is record(rownum int,row2 text); + source rectype := (2, 'dsaw'); +BEGIN + raise notice '% , %',source.row2,source.rownum; +END; +/ +NOTICE: dsaw , 2 -- Prohibit virtual column insertion create table t1(col1 varchar(10),col varchar(10)); create table t2(col1 varchar(10),col varchar(10)); diff --git a/src/test/regress/sql/plpgsql_cursor_rowtype.sql b/src/test/regress/sql/plpgsql_cursor_rowtype.sql index b6a149f81..66eb7aad3 100644 --- a/src/test/regress/sql/plpgsql_cursor_rowtype.sql +++ b/src/test/regress/sql/plpgsql_cursor_rowtype.sql @@ -70,6 +70,49 @@ drop table test_2 cascade; set behavior_compat_options='allow_procedure_compile_check,disable_record_type_in_dml'; +create table t_CurRowtype_Def_Case0001(col1 int primary key,col2 varchar(100)); +insert into t_CurRowtype_Def_Case0001 values(1,'one'); +insert into t_CurRowtype_Def_Case0001 values(2,'two'); +insert into t_CurRowtype_Def_Case0001 values(3,'three'); +insert into t_CurRowtype_Def_Case0001 values(4,NULL); + +--创建游标rowtype,select 伪列;expect:成功,输出4行 +declare + cursor cur_CurRowtype_Def_Case0001_1 is select col1,col2,rownum from t_CurRowtype_Def_Case0001; + source cur_CurRowtype_Def_Case0001_1%rowtype; +begin + open cur_CurRowtype_Def_Case0001_1; + loop + fetch cur_CurRowtype_Def_Case0001_1 into source; + exit when cur_CurRowtype_Def_Case0001_1%notfound; + raise notice '% , % ,% ',source.col1,source.col2,source.rownum; + end loop; + close cur_CurRowtype_Def_Case0001_1; +end; +/ + +drop table t_CurRowtype_Def_Case0001; + +create table t_CurRowtype_Def_Case0002(col1 int primary key,rownum varchar(100)); +create table t_CurRowtype_Def_Case0002(col1 int primary key); +insert into t_CurRowtype_Def_Case0002 values(1); +select t_CurRowtype_Def_Case0002.rownum from t_CurRowtype_Def_Case0002; +select rownum from t_CurRowtype_Def_Case0002; +drop table t_CurRowtype_Def_Case0002; + +CREATE TYPE type_record AS ( + first text, + rownum int4 +) ; + +DECLARE + type rectype is record(rownum int,row2 text); + source rectype := (2, 'dsaw'); +BEGIN + raise notice '% , %',source.row2,source.rownum; +END; +/ + -- Prohibit virtual column insertion create table t1(col1 varchar(10),col varchar(10)); create table t2(col1 varchar(10),col varchar(10));