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

Commit55ca02f

Browse files
committed
Restructure rowtype-parameter handling to eliminate need for possibly-
overflowable buffer for 'name%rowtype'; not to mention avoid problemswith mixed-case type names and other special cases.
1 parent77a7e99 commit55ca02f

File tree

1 file changed

+55
-38
lines changed

1 file changed

+55
-38
lines changed

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

Lines changed: 55 additions & 38 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.44 2002/08/08 01:36:04 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.45 2002/08/12 14:25:07 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -85,6 +85,9 @@ intplpgsql_DumpExecTree = 0;
8585
PLpgSQL_function*plpgsql_curr_compile;
8686

8787

88+
staticPLpgSQL_row*build_rowtype(OidclassOid);
89+
90+
8891
/*
8992
* This routine is a crock, and so is everyplace that calls it. The problem
9093
* is that the compiled form of a plpgsql function is allocated permanently
@@ -234,7 +237,9 @@ plpgsql_compile(Oid fn_oid, int functype)
234237
*/
235238
for (i=0;i<procStruct->pronargs;i++)
236239
{
237-
charbuf[256];
240+
charbuf[32];
241+
242+
sprintf(buf,"$%d",i+1);/* name for variable */
238243

239244
/*
240245
* Get the parameters type
@@ -258,13 +263,7 @@ plpgsql_compile(Oid fn_oid, int functype)
258263
* For tuple type parameters, we set up a record of
259264
* that type
260265
*/
261-
sprintf(buf,"%s%%rowtype",NameStr(typeStruct->typname));
262-
if (plpgsql_parse_wordrowtype(buf)!=T_ROW)
263-
elog(ERROR,"cannot get tuple struct of argument %d",
264-
i+1);
265-
266-
row=plpgsql_yylval.row;
267-
sprintf(buf,"$%d",i+1);
266+
row=build_rowtype(typeStruct->typrelid);
268267

269268
row->refname=strdup(buf);
270269

@@ -284,7 +283,6 @@ plpgsql_compile(Oid fn_oid, int functype)
284283
var->datatype=malloc(sizeof(PLpgSQL_type));
285284
memset(var->datatype,0,sizeof(PLpgSQL_type));
286285

287-
sprintf(buf,"$%d",i+1);
288286
var->dtype=PLPGSQL_DTYPE_VAR;
289287
var->refname=strdup(buf);
290288
var->lineno=0;
@@ -1097,15 +1095,6 @@ int
10971095
plpgsql_parse_wordrowtype(char*word)
10981096
{
10991097
OidclassOid;
1100-
HeapTupleclasstup;
1101-
Form_pg_classclassStruct;
1102-
HeapTupletypetup;
1103-
Form_pg_typetypeStruct;
1104-
HeapTupleattrtup;
1105-
Form_pg_attributeattrStruct;
1106-
PLpgSQL_row*row;
1107-
PLpgSQL_var*var;
1108-
char*attname;
11091098
char*cp[2];
11101099
inti;
11111100

@@ -1116,25 +1105,51 @@ plpgsql_parse_wordrowtype(char *word)
11161105
word[i]='.';
11171106
plpgsql_convert_ident(word,cp,2);
11181107
word[i]='%';
1108+
1109+
/* Lookup the relation */
1110+
classOid=RelnameGetRelid(cp[0]);
1111+
if (!OidIsValid(classOid))
1112+
elog(ERROR,"%s: no such class",cp[0]);
1113+
1114+
/*
1115+
* Build and return the complete row definition
1116+
*/
1117+
plpgsql_yylval.row=build_rowtype(classOid);
1118+
1119+
pfree(cp[0]);
11191120
pfree(cp[1]);
11201121

1122+
returnT_ROW;
1123+
}
1124+
1125+
/*
1126+
* Build a rowtype data structure given the pg_class OID.
1127+
*/
1128+
staticPLpgSQL_row*
1129+
build_rowtype(OidclassOid)
1130+
{
1131+
PLpgSQL_row*row;
1132+
HeapTupleclasstup;
1133+
Form_pg_classclassStruct;
1134+
constchar*relname;
1135+
inti;
1136+
11211137
/*
11221138
* Fetch the pg_class tuple.
11231139
*/
1124-
classOid=RelnameGetRelid(cp[0]);
1125-
if (!OidIsValid(classOid))
1126-
elog(ERROR,"%s: no such class",cp[0]);
11271140
classtup=SearchSysCache(RELOID,
11281141
ObjectIdGetDatum(classOid),
11291142
0,0,0);
11301143
if (!HeapTupleIsValid(classtup))
1131-
elog(ERROR,"%s: no such class",cp[0]);
1144+
elog(ERROR,"cache lookup failed for relation %u",classOid);
11321145
classStruct= (Form_pg_class)GETSTRUCT(classtup);
1146+
relname=NameStr(classStruct->relname);
1147+
11331148
/* accept relation, sequence, or view pg_class entries */
11341149
if (classStruct->relkind!=RELKIND_RELATION&&
11351150
classStruct->relkind!=RELKIND_SEQUENCE&&
11361151
classStruct->relkind!=RELKIND_VIEW)
1137-
elog(ERROR,"%s isn't a table",cp[0]);
1152+
elog(ERROR,"%s isn't a table",relname);
11381153

11391154
/*
11401155
* Create a row datum entry and all the required variables that it
@@ -1151,6 +1166,13 @@ plpgsql_parse_wordrowtype(char *word)
11511166

11521167
for (i=0;i<row->nfields;i++)
11531168
{
1169+
HeapTupleattrtup;
1170+
Form_pg_attributeattrStruct;
1171+
HeapTupletypetup;
1172+
Form_pg_typetypeStruct;
1173+
constchar*attname;
1174+
PLpgSQL_var*var;
1175+
11541176
/*
11551177
* Get the attribute and it's type
11561178
*/
@@ -1160,17 +1182,17 @@ plpgsql_parse_wordrowtype(char *word)
11601182
0,0);
11611183
if (!HeapTupleIsValid(attrtup))
11621184
elog(ERROR,"cache lookup for attribute %d of class %s failed",
1163-
i+1,cp[0]);
1185+
i+1,relname);
11641186
attrStruct= (Form_pg_attribute)GETSTRUCT(attrtup);
11651187

1166-
attname=pstrdup(NameStr(attrStruct->attname));
1188+
attname=NameStr(attrStruct->attname);
11671189

11681190
typetup=SearchSysCache(TYPEOID,
11691191
ObjectIdGetDatum(attrStruct->atttypid),
11701192
0,0,0);
11711193
if (!HeapTupleIsValid(typetup))
11721194
elog(ERROR,"cache lookup for type %u of %s.%s failed",
1173-
attrStruct->atttypid,cp[0],attname);
1195+
attrStruct->atttypid,relname,attname);
11741196
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
11751197

11761198
/*
@@ -1186,8 +1208,8 @@ plpgsql_parse_wordrowtype(char *word)
11861208
var=malloc(sizeof(PLpgSQL_var));
11871209
memset(var,0,sizeof(PLpgSQL_var));
11881210
var->dtype=PLPGSQL_DTYPE_VAR;
1189-
var->refname=malloc(strlen(cp[0])+strlen(attname)+2);
1190-
strcpy(var->refname,cp[0]);
1211+
var->refname=malloc(strlen(relname)+strlen(attname)+2);
1212+
strcpy(var->refname,relname);
11911213
strcat(var->refname,".");
11921214
strcat(var->refname,attname);
11931215
var->datatype=malloc(sizeof(PLpgSQL_type));
@@ -1205,26 +1227,21 @@ plpgsql_parse_wordrowtype(char *word)
12051227
var->isnull= true;
12061228
var->freeval= false;
12071229

1208-
ReleaseSysCache(typetup);
1209-
ReleaseSysCache(attrtup);
1210-
12111230
plpgsql_adddatum((PLpgSQL_datum*)var);
12121231

12131232
/*
12141233
* Add the variable to the row.
12151234
*/
12161235
row->fieldnames[i]=strdup(attname);
12171236
row->varnos[i]=var->varno;
1237+
1238+
ReleaseSysCache(typetup);
1239+
ReleaseSysCache(attrtup);
12181240
}
12191241

12201242
ReleaseSysCache(classtup);
12211243

1222-
/*
1223-
* Return the complete row definition
1224-
*/
1225-
plpgsql_yylval.row=row;
1226-
1227-
returnT_ROW;
1244+
returnrow;
12281245
}
12291246

12301247

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp