Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4089d25

Browse files
committed
Fix plpgsql so that variables of composite types (rowtypes) can be
declared without having to write %ROWTYPE. If the declared type ofa variable is a composite type, it'll be taken to be a row variableautomatically.
1 parent982430f commit4089d25

File tree

4 files changed

+99
-106
lines changed

4 files changed

+99
-106
lines changed

‎doc/src/sgml/plpgsql.sgml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.17 2003/04/07 01:29:25 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.18 2003/04/27 22:21:22 tgl Exp $
33
-->
44

55
<chapter id="plpgsql">
@@ -541,7 +541,8 @@ user_id users.user_id%TYPE;
541541
<title>Row Types</title>
542542

543543
<synopsis>
544-
<replaceable>name</replaceable> <replaceable>tablename</replaceable><literal>%ROWTYPE</literal>;
544+
<replaceable>name</replaceable> <replaceable>table_name</replaceable><literal>%ROWTYPE</literal>;
545+
<replaceable>name</replaceable> <replaceable>composite_type_name</replaceable>;
545546
</synopsis>
546547

547548
<para>
@@ -550,17 +551,20 @@ user_id users.user_id%TYPE;
550551
can hold a whole row of a <command>SELECT</> or <command>FOR</>
551552
query result, so long as that query's column set matches the
552553
declared type of the variable.
553-
<replaceable>tablename</replaceable> must be an existing table or
554-
view name in the database. The individual fields of the row value
554+
The individual fields of the row value
555555
are accessed using the usual dot notation, for example
556556
<literal>rowvar.field</literal>.
557557
</para>
558558

559559
<para>
560-
Presently, a row variable can only be declared using the
561-
<literal>%ROWTYPE</literal> notation; although one might expect a
562-
bare table name to work as a type declaration, it won't be accepted
563-
within <application>PL/pgSQL</application> functions.
560+
A row variable can be declared to have the same type as the rows of
561+
an existing table or view, by using the
562+
<replaceable>table_name</replaceable><literal>%ROWTYPE</literal>
563+
notation; or it can be declared by giving a composite type's name.
564+
(Since every table has an associated datatype of the same name,
565+
it actually does not matter in <productname>PostgreSQL</> whether you
566+
write <literal>%ROWTYPE</literal> or not. But the form with
567+
<literal>%ROWTYPE</literal> is more portable.)
564568
</para>
565569

566570
<para>

‎src/pl/plpgsql/src/gram.y

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.41 2003/03/25 03:16:40 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.42 2003/04/27 22:21:22 tgl Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -307,36 +307,64 @@ decl_stmt: '<' '<' opt_lblname '>' '>'
307307

308308
decl_statement:decl_varnamedecl_constdecl_datatypedecl_notnulldecl_defval
309309
{
310-
PLpgSQL_var*new;
310+
if (!OidIsValid($3->typrelid))
311+
{
312+
/* Ordinary scalar datatype*/
313+
PLpgSQL_var*var;
311314

312-
new = malloc(sizeof(PLpgSQL_var));
313-
memset(new,0,sizeof(PLpgSQL_var));
315+
var = malloc(sizeof(PLpgSQL_var));
316+
memset(var,0,sizeof(PLpgSQL_var));
314317

315-
new->dtype= PLPGSQL_DTYPE_VAR;
316-
new->refname=$1.name;
317-
new->lineno=$1.lineno;
318+
var->dtype= PLPGSQL_DTYPE_VAR;
319+
var->refname=$1.name;
320+
var->lineno=$1.lineno;
318321

319-
new->datatype=$3;
320-
new->isconst=$2;
321-
new->notnull=$4;
322-
new->default_val =$5;
322+
var->datatype=$3;
323+
var->isconst=$2;
324+
var->notnull=$4;
325+
var->default_val =$5;
323326

324-
plpgsql_adddatum((PLpgSQL_datum *)new);
325-
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,new->varno,
326-
$1.name);
327+
plpgsql_adddatum((PLpgSQL_datum *)var);
328+
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
329+
var->varno,
330+
$1.name);
331+
}
332+
else
333+
{
334+
/* Composite type --- treat as rowtype*/
335+
PLpgSQL_row *row;
336+
337+
row = build_rowtype($3->typrelid);
338+
row->dtype= PLPGSQL_DTYPE_ROW;
339+
row->refname=$1.name;
340+
row->lineno=$1.lineno;
341+
342+
if ($2)
343+
elog(ERROR,"Rowtype variable cannot be CONSTANT");
344+
if ($4)
345+
elog(ERROR,"Rowtype variable cannot be NOT NULL");
346+
if ($5 !=NULL)
347+
elog(ERROR,"Default value for rowtype variable is not supported");
348+
349+
plpgsql_adddatum((PLpgSQL_datum *)row);
350+
plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
351+
row->rowno,
352+
$1.name);
353+
354+
}
327355
}
328356
|decl_varnameK_RECORD';'
329357
{
330-
PLpgSQL_rec*new;
358+
PLpgSQL_rec*var;
331359

332-
new = malloc(sizeof(PLpgSQL_rec));
360+
var = malloc(sizeof(PLpgSQL_rec));
333361

334-
new->dtype= PLPGSQL_DTYPE_REC;
335-
new->refname=$1.name;
336-
new->lineno=$1.lineno;
362+
var->dtype= PLPGSQL_DTYPE_REC;
363+
var->refname=$1.name;
364+
var->lineno=$1.lineno;
337365

338-
plpgsql_adddatum((PLpgSQL_datum *)new);
339-
plpgsql_ns_additem(PLPGSQL_NSTYPE_REC,new->recno,
366+
plpgsql_adddatum((PLpgSQL_datum *)var);
367+
plpgsql_ns_additem(PLPGSQL_NSTYPE_REC,var->recno,
340368
$1.name);
341369
}
342370
|decl_varnamedecl_rowtype';'

‎src/pl/plpgsql/src/pl_comp.c

Lines changed: 29 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.56 2003/04/2421:16:44 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.57 2003/04/27 22:21:22 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -81,7 +81,7 @@ PLpgSQL_function *plpgsql_curr_compile;
8181

8282

8383
staticvoidplpgsql_compile_error_callback(void*arg);
84-
staticPLpgSQL_row*build_rowtype(OidclassOid);
84+
staticPLpgSQL_type*build_datatype(HeapTupletypeTup,int32typmod);
8585

8686

8787
/*
@@ -275,19 +275,11 @@ plpgsql_compile(Oid fn_oid, int functype)
275275
*/
276276
var=malloc(sizeof(PLpgSQL_var));
277277
memset(var,0,sizeof(PLpgSQL_var));
278-
var->datatype=malloc(sizeof(PLpgSQL_type));
279-
memset(var->datatype,0,sizeof(PLpgSQL_type));
280278

281279
var->dtype=PLPGSQL_DTYPE_VAR;
282280
var->refname=strdup(buf);
283281
var->lineno=0;
284-
var->datatype->typname=strdup(NameStr(typeStruct->typname));
285-
var->datatype->typoid=procStruct->proargtypes[i];
286-
perm_fmgr_info(typeStruct->typinput,&(var->datatype->typinput));
287-
var->datatype->typelem=typeStruct->typelem;
288-
var->datatype->typbyval=typeStruct->typbyval;
289-
var->datatype->typlen=typeStruct->typlen;
290-
var->datatype->atttypmod=-1;
282+
var->datatype=build_datatype(typeTup,-1);
291283
var->isconst= true;
292284
var->notnull= false;
293285
var->default_val=NULL;
@@ -908,7 +900,6 @@ plpgsql_parse_wordtype(char *word)
908900
if (HeapTupleIsValid(typeTup))
909901
{
910902
Form_pg_typetypeStruct= (Form_pg_type)GETSTRUCT(typeTup);
911-
PLpgSQL_type*typ;
912903

913904
if (!typeStruct->typisdefined||
914905
typeStruct->typrelid!=InvalidOid)
@@ -918,17 +909,7 @@ plpgsql_parse_wordtype(char *word)
918909
returnT_ERROR;
919910
}
920911

921-
typ= (PLpgSQL_type*)malloc(sizeof(PLpgSQL_type));
922-
923-
typ->typname=strdup(NameStr(typeStruct->typname));
924-
typ->typoid=typeOid;
925-
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
926-
typ->typelem=typeStruct->typelem;
927-
typ->typbyval=typeStruct->typbyval;
928-
typ->typlen=typeStruct->typlen;
929-
typ->atttypmod=-1;
930-
931-
plpgsql_yylval.dtype=typ;
912+
plpgsql_yylval.dtype=build_datatype(typeTup,-1);
932913

933914
ReleaseSysCache(typeTup);
934915
pfree(cp[0]);
@@ -960,8 +941,6 @@ plpgsql_parse_dblwordtype(char *word)
960941
HeapTupleattrtup;
961942
Form_pg_attributeattrStruct;
962943
HeapTupletypetup;
963-
Form_pg_typetypeStruct;
964-
PLpgSQL_type*typ;
965944
char*cp[3];
966945
inti;
967946

@@ -1067,22 +1046,11 @@ plpgsql_parse_dblwordtype(char *word)
10671046
if (!HeapTupleIsValid(typetup))
10681047
elog(ERROR,"cache lookup for type %u of %s.%s failed",
10691048
attrStruct->atttypid,cp[0],cp[1]);
1070-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
10711049

10721050
/*
10731051
* Found that - build a compiler type struct and return it
10741052
*/
1075-
typ= (PLpgSQL_type*)malloc(sizeof(PLpgSQL_type));
1076-
1077-
typ->typname=strdup(NameStr(typeStruct->typname));
1078-
typ->typoid=attrStruct->atttypid;
1079-
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
1080-
typ->typelem=typeStruct->typelem;
1081-
typ->typbyval=typeStruct->typbyval;
1082-
typ->typlen=typeStruct->typlen;
1083-
typ->atttypmod=attrStruct->atttypmod;
1084-
1085-
plpgsql_yylval.dtype=typ;
1053+
plpgsql_yylval.dtype=build_datatype(typetup,attrStruct->atttypmod);
10861054

10871055
ReleaseSysCache(classtup);
10881056
ReleaseSysCache(attrtup);
@@ -1107,8 +1075,6 @@ plpgsql_parse_tripwordtype(char *word)
11071075
HeapTupleattrtup;
11081076
Form_pg_attributeattrStruct;
11091077
HeapTupletypetup;
1110-
Form_pg_typetypeStruct;
1111-
PLpgSQL_type*typ;
11121078
char*cp[2];
11131079
char*colname[1];
11141080
intqualified_att_len;
@@ -1192,22 +1158,11 @@ plpgsql_parse_tripwordtype(char *word)
11921158
if (!HeapTupleIsValid(typetup))
11931159
elog(ERROR,"cache lookup for type %u of %s.%s failed",
11941160
attrStruct->atttypid,cp[0],cp[1]);
1195-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
11961161

11971162
/*
11981163
* Found that - build a compiler type struct and return it
11991164
*/
1200-
typ= (PLpgSQL_type*)malloc(sizeof(PLpgSQL_type));
1201-
1202-
typ->typname=strdup(NameStr(typeStruct->typname));
1203-
typ->typoid=attrStruct->atttypid;
1204-
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
1205-
typ->typelem=typeStruct->typelem;
1206-
typ->typbyval=typeStruct->typbyval;
1207-
typ->typlen=typeStruct->typlen;
1208-
typ->atttypmod=attrStruct->atttypmod;
1209-
1210-
plpgsql_yylval.dtype=typ;
1165+
plpgsql_yylval.dtype=build_datatype(typetup,attrStruct->atttypmod);
12111166

12121167
ReleaseSysCache(classtup);
12131168
ReleaseSysCache(attrtup);
@@ -1296,7 +1251,7 @@ plpgsql_parse_dblwordrowtype(char *word)
12961251
/*
12971252
* Build a rowtype data structure given the pg_class OID.
12981253
*/
1299-
staticPLpgSQL_row*
1254+
PLpgSQL_row*
13001255
build_rowtype(OidclassOid)
13011256
{
13021257
PLpgSQL_row*row;
@@ -1341,7 +1296,6 @@ build_rowtype(Oid classOid)
13411296
HeapTupleattrtup;
13421297
Form_pg_attributeattrStruct;
13431298
HeapTupletypetup;
1344-
Form_pg_typetypeStruct;
13451299
constchar*attname;
13461300
PLpgSQL_var*var;
13471301

@@ -1365,7 +1319,6 @@ build_rowtype(Oid classOid)
13651319
if (!HeapTupleIsValid(typetup))
13661320
elog(ERROR,"cache lookup for type %u of %s.%s failed",
13671321
attrStruct->atttypid,relname,attname);
1368-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
13691322

13701323
/*
13711324
* Create the internal variable
@@ -1384,14 +1337,7 @@ build_rowtype(Oid classOid)
13841337
strcpy(var->refname,relname);
13851338
strcat(var->refname,".");
13861339
strcat(var->refname,attname);
1387-
var->datatype=malloc(sizeof(PLpgSQL_type));
1388-
var->datatype->typname=strdup(NameStr(typeStruct->typname));
1389-
var->datatype->typoid=attrStruct->atttypid;
1390-
perm_fmgr_info(typeStruct->typinput,&(var->datatype->typinput));
1391-
var->datatype->typelem=typeStruct->typelem;
1392-
var->datatype->typbyval=typeStruct->typbyval;
1393-
var->datatype->typlen=typeStruct->typlen;
1394-
var->datatype->atttypmod=attrStruct->atttypmod;
1340+
var->datatype=build_datatype(typetup,attrStruct->atttypmod);
13951341
var->isconst= false;
13961342
var->notnull= false;
13971343
var->default_val=NULL;
@@ -1428,7 +1374,6 @@ plpgsql_parse_datatype(char *string)
14281374
Oidtype_id;
14291375
int32typmod;
14301376
HeapTupletypeTup;
1431-
Form_pg_typetypeStruct;
14321377
PLpgSQL_type*typ;
14331378

14341379
/* Let the main parser try to parse it under standard SQL rules */
@@ -1440,20 +1385,34 @@ plpgsql_parse_datatype(char *string)
14401385
0,0,0);
14411386
if (!HeapTupleIsValid(typeTup))
14421387
elog(ERROR,"cache lookup failed for type %u",type_id);
1443-
typeStruct= (Form_pg_type)GETSTRUCT(typeTup);
1388+
1389+
typ=build_datatype(typeTup,typmod);
1390+
1391+
ReleaseSysCache(typeTup);
1392+
1393+
returntyp;
1394+
}
1395+
1396+
/*
1397+
* Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1398+
*/
1399+
staticPLpgSQL_type*
1400+
build_datatype(HeapTupletypeTup,int32typmod)
1401+
{
1402+
Form_pg_typetypeStruct= (Form_pg_type)GETSTRUCT(typeTup);
1403+
PLpgSQL_type*typ;
14441404

14451405
typ= (PLpgSQL_type*)malloc(sizeof(PLpgSQL_type));
14461406

14471407
typ->typname=strdup(NameStr(typeStruct->typname));
1448-
typ->typoid=type_id;
1449-
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
1450-
typ->typelem=typeStruct->typelem;
1451-
typ->typbyval=typeStruct->typbyval;
1408+
typ->typoid=HeapTupleGetOid(typeTup);
14521409
typ->typlen=typeStruct->typlen;
1410+
typ->typbyval=typeStruct->typbyval;
1411+
typ->typrelid=typeStruct->typrelid;
1412+
typ->typelem=typeStruct->typelem;
1413+
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
14531414
typ->atttypmod=typmod;
14541415

1455-
ReleaseSysCache(typeTup);
1456-
14571416
returntyp;
14581417
}
14591418

‎src/pl/plpgsql/src/plpgsql.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.34 2003/04/2421:16:44 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.35 2003/04/27 22:21:22 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -142,14 +142,15 @@ typedef struct
142142

143143

144144
typedefstruct
145-
{/* Postgresbasedata type*/
145+
{/* Postgres data type*/
146146
char*typname;
147-
Oidtypoid;
148-
FmgrInfotypinput;
149-
Oidtypelem;
150-
int16typlen;
147+
Oidtypoid;/* OID of the data type */
148+
int16typlen;/* stuff copied from its pg_type entry */
151149
booltypbyval;
152-
int32atttypmod;
150+
Oidtyprelid;
151+
Oidtypelem;
152+
FmgrInfotypinput;/* lookup info for typinput function */
153+
int32atttypmod;/* typmod (taken from someplace else) */
153154
}PLpgSQL_type;
154155

155156

@@ -600,6 +601,7 @@ extern intplpgsql_parse_tripwordtype(char *word);
600601
externintplpgsql_parse_wordrowtype(char*word);
601602
externintplpgsql_parse_dblwordrowtype(char*word);
602603
externPLpgSQL_type*plpgsql_parse_datatype(char*string);
604+
externPLpgSQL_row*build_rowtype(OidclassOid);
603605
externvoidplpgsql_adddatum(PLpgSQL_datum*new);
604606
externintplpgsql_add_initdatums(int**varnos);
605607
externvoidplpgsql_yyerror(constchar*s);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp