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

Commitb3f5232

Browse files
committed
> Sean Chittenden <sean@chittenden.org> writes:
>>>::sigh:: Is it me or does it look like all>>of pl/pgsql is schema un-aware (ie, all of the declarations). -sc>>> Yeah. The group of routines parse_word, parse_dblword, etc that are> called by the lexer certainly all need work. There are some> definitional issues to think about, too --- plpgsql presently relies on> the number of names to give it some idea of what to look for, and those> rules are probably all toast now. Please come up with a sketch of what> you think the behavior should be before you start hacking code.Attached is a diff -c format proposal to fix this. I've also attached a shorttest script. Seems to work OK and passes all regression tests.Here's a breakdown of how I understand plpgsql's "Special word rules" -- Ithink it illustrates the behavior reasonably well. New functions added by thispatch are plpgsql_parse_tripwordtype and plpgsql_parse_dblwordrowtype:Joe Conway
1 parent8118686 commitb3f5232

File tree

4 files changed

+216
-3
lines changed

4 files changed

+216
-3
lines changed

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

Lines changed: 161 additions & 1 deletion
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.51 2002/09/04 20:31:47 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.52 2002/09/12 00:24:09 momjian Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1092,6 +1092,126 @@ plpgsql_parse_dblwordtype(char *word)
10921092
returnT_DTYPE;
10931093
}
10941094

1095+
/* ----------
1096+
* plpgsql_parse_tripwordtypeSame lookup for word.word.word%TYPE
1097+
* ----------
1098+
*/
1099+
#defineTYPE_JUNK_LEN5
1100+
1101+
int
1102+
plpgsql_parse_tripwordtype(char*word)
1103+
{
1104+
OidclassOid;
1105+
HeapTupleclasstup;
1106+
Form_pg_classclassStruct;
1107+
HeapTupleattrtup;
1108+
Form_pg_attributeattrStruct;
1109+
HeapTupletypetup;
1110+
Form_pg_typetypeStruct;
1111+
PLpgSQL_type*typ;
1112+
char*cp[2];
1113+
intqualified_att_len;
1114+
intnumdots=0;
1115+
inti;
1116+
RangeVar*relvar;
1117+
1118+
/* Do case conversion and word separation */
1119+
qualified_att_len=strlen(word)-TYPE_JUNK_LEN;
1120+
Assert(word[qualified_att_len]=='%');
1121+
1122+
for (i=0;i<qualified_att_len;i++)
1123+
{
1124+
if (word[i]=='.'&&++numdots==2)
1125+
{
1126+
cp[0]= (char*)palloc((i+1)*sizeof(char));
1127+
memset(cp[0],0, (i+1)*sizeof(char));
1128+
memcpy(cp[0],word,i*sizeof(char));
1129+
1130+
/* qualified_att_len - one based position + 1 (null terminator) */
1131+
cp[1]= (char*)palloc((qualified_att_len-i)*sizeof(char));
1132+
memset(cp[1],0, (qualified_att_len-i)*sizeof(char));
1133+
memcpy(cp[1],&word[i+1], (qualified_att_len-i-1)*sizeof(char));
1134+
1135+
break;
1136+
}
1137+
}
1138+
1139+
relvar=makeRangeVarFromNameList(stringToQualifiedNameList(cp[0],"plpgsql_parse_dblwordtype"));
1140+
classOid=RangeVarGetRelid(relvar, true);
1141+
if (!OidIsValid(classOid))
1142+
{
1143+
pfree(cp[0]);
1144+
pfree(cp[1]);
1145+
returnT_ERROR;
1146+
}
1147+
classtup=SearchSysCache(RELOID,
1148+
ObjectIdGetDatum(classOid),
1149+
0,0,0);
1150+
if (!HeapTupleIsValid(classtup))
1151+
{
1152+
pfree(cp[0]);
1153+
pfree(cp[1]);
1154+
returnT_ERROR;
1155+
}
1156+
1157+
/*
1158+
* It must be a relation, sequence, view, or type
1159+
*/
1160+
classStruct= (Form_pg_class)GETSTRUCT(classtup);
1161+
if (classStruct->relkind!=RELKIND_RELATION&&
1162+
classStruct->relkind!=RELKIND_SEQUENCE&&
1163+
classStruct->relkind!=RELKIND_VIEW&&
1164+
classStruct->relkind!=RELKIND_COMPOSITE_TYPE)
1165+
{
1166+
ReleaseSysCache(classtup);
1167+
pfree(cp[0]);
1168+
pfree(cp[1]);
1169+
returnT_ERROR;
1170+
}
1171+
1172+
/*
1173+
* Fetch the named table field and it's type
1174+
*/
1175+
attrtup=SearchSysCacheAttName(classOid,cp[1]);
1176+
if (!HeapTupleIsValid(attrtup))
1177+
{
1178+
ReleaseSysCache(classtup);
1179+
pfree(cp[0]);
1180+
pfree(cp[1]);
1181+
returnT_ERROR;
1182+
}
1183+
attrStruct= (Form_pg_attribute)GETSTRUCT(attrtup);
1184+
1185+
typetup=SearchSysCache(TYPEOID,
1186+
ObjectIdGetDatum(attrStruct->atttypid),
1187+
0,0,0);
1188+
if (!HeapTupleIsValid(typetup))
1189+
elog(ERROR,"cache lookup for type %u of %s.%s failed",
1190+
attrStruct->atttypid,cp[0],cp[1]);
1191+
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
1192+
1193+
/*
1194+
* Found that - build a compiler type struct and return it
1195+
*/
1196+
typ= (PLpgSQL_type*)malloc(sizeof(PLpgSQL_type));
1197+
1198+
typ->typname=strdup(NameStr(typeStruct->typname));
1199+
typ->typoid=attrStruct->atttypid;
1200+
perm_fmgr_info(typeStruct->typinput,&(typ->typinput));
1201+
typ->typelem=typeStruct->typelem;
1202+
typ->typbyval=typeStruct->typbyval;
1203+
typ->typlen=typeStruct->typlen;
1204+
typ->atttypmod=attrStruct->atttypmod;
1205+
1206+
plpgsql_yylval.dtype=typ;
1207+
1208+
ReleaseSysCache(classtup);
1209+
ReleaseSysCache(attrtup);
1210+
ReleaseSysCache(typetup);
1211+
pfree(cp[0]);
1212+
pfree(cp[1]);
1213+
returnT_DTYPE;
1214+
}
10951215

10961216
/* ----------
10971217
* plpgsql_parse_wordrowtypeScanner found word%ROWTYPE.
@@ -1129,6 +1249,46 @@ plpgsql_parse_wordrowtype(char *word)
11291249
returnT_ROW;
11301250
}
11311251

1252+
/* ----------
1253+
* plpgsql_parse_dblwordrowtypeScanner found word.word%ROWTYPE.
1254+
*So word must be namespace qualified a table name.
1255+
* ----------
1256+
*/
1257+
#defineROWTYPE_JUNK_LEN8
1258+
1259+
int
1260+
plpgsql_parse_dblwordrowtype(char*word)
1261+
{
1262+
OidclassOid;
1263+
char*cp;
1264+
inti;
1265+
RangeVar*relvar;
1266+
1267+
/* Do case conversion and word separation */
1268+
/* We convert %rowtype to .rowtype momentarily to keep converter happy */
1269+
i=strlen(word)-ROWTYPE_JUNK_LEN;
1270+
Assert(word[i]=='%');
1271+
1272+
cp= (char*)palloc((i+1)*sizeof(char));
1273+
memset(cp,0, (i+1)*sizeof(char));
1274+
memcpy(cp,word,i*sizeof(char));
1275+
1276+
/* Lookup the relation */
1277+
relvar=makeRangeVarFromNameList(stringToQualifiedNameList(cp,"plpgsql_parse_dblwordtype"));
1278+
classOid=RangeVarGetRelid(relvar, true);
1279+
if (!OidIsValid(classOid))
1280+
elog(ERROR,"%s: no such class",cp);
1281+
1282+
/*
1283+
* Build and return the complete row definition
1284+
*/
1285+
plpgsql_yylval.row=build_rowtype(classOid);
1286+
1287+
pfree(cp);
1288+
1289+
returnT_ROW;
1290+
}
1291+
11321292
/*
11331293
* Build a rowtype data structure given the pg_class OID.
11341294
*/

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

Lines changed: 3 additions & 1 deletion
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.27 2002/09/04 20:31:47 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.28 2002/09/12 00:24:09 momjian Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -568,7 +568,9 @@ extern intplpgsql_parse_dblword(char *word);
568568
externintplpgsql_parse_tripword(char*word);
569569
externintplpgsql_parse_wordtype(char*word);
570570
externintplpgsql_parse_dblwordtype(char*word);
571+
externintplpgsql_parse_tripwordtype(char*word);
571572
externintplpgsql_parse_wordrowtype(char*word);
573+
externintplpgsql_parse_dblwordrowtype(char*word);
572574
externPLpgSQL_type*plpgsql_parse_datatype(char*string);
573575
externvoidplpgsql_adddatum(PLpgSQL_datum*new);
574576
externintplpgsql_add_initdatums(int**varnos);

‎src/pl/plpgsql/src/scan.l

Lines changed: 5 additions & 1 deletion
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/Attic/scan.l,v 1.22 2002/08/30 00:28:41 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.23 2002/09/12 00:24:09 momjian Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -170,14 +170,18 @@ dump{ return O_DUMP;}
170170
{identifier}{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{returnplpgsql_parse_tripword(yytext); }
171171
{identifier}{space}*%TYPE{returnplpgsql_parse_wordtype(yytext);}
172172
{identifier}{space}*\.{space}*{identifier}{space}*%TYPE{returnplpgsql_parse_dblwordtype(yytext); }
173+
{identifier}{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{space}*%TYPE{returnplpgsql_parse_tripwordtype(yytext); }
173174
{identifier}{space}*%ROWTYPE{returnplpgsql_parse_wordrowtype(yytext);}
175+
{identifier}{space}*\.{space}*{identifier}{space}*%ROWTYPE{returnplpgsql_parse_dblwordrowtype(yytext);}
174176

175177
\${digit}+{returnplpgsql_parse_word(yytext);}
176178
\${digit}+{space}*\.{space}*{identifier}{returnplpgsql_parse_dblword(yytext);}
177179
\${digit}+{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{returnplpgsql_parse_tripword(yytext); }
178180
\${digit}+{space}*%TYPE{returnplpgsql_parse_wordtype(yytext);}
179181
\${digit}+{space}*\.{space}*{identifier}{space}*%TYPE{returnplpgsql_parse_dblwordtype(yytext); }
182+
\${digit}+{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{space}*%TYPE{returnplpgsql_parse_tripwordtype(yytext); }
180183
\${digit}+{space}*%ROWTYPE{returnplpgsql_parse_wordrowtype(yytext);}
184+
\${digit}+{space}*\.{space}*{identifier}{space}*%ROWTYPE{returnplpgsql_parse_dblwordrowtype(yytext);}
181185

182186
{digit}+{return T_NUMBER;}
183187

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
-- nspname.relname.attname%TYPE
2+
DROPFUNCTION t();
3+
CREATE OR REPLACEFUNCTIONt() RETURNSTEXTAS'
4+
DECLARE
5+
col_name pg_catalog.pg_attribute.attname%TYPE;
6+
BEGIN
7+
col_name :=''uga'';
8+
RETURN col_name;
9+
END;
10+
' LANGUAGE'plpgsql';
11+
SELECT t();
12+
13+
-- nspname.relname%ROWTYPE
14+
DROPFUNCTION t();
15+
CREATE OR REPLACEFUNCTIONt() RETURNSpg_catalog.pg_attributeAS'
16+
DECLARE
17+
rec pg_catalog.pg_attribute%ROWTYPE;
18+
BEGIN
19+
SELECT INTO rec * FROM pg_catalog.pg_attribute WHERE attrelid = 1247 AND attname =''typname'';
20+
RETURN rec;
21+
END;
22+
' LANGUAGE'plpgsql';
23+
SELECT*FROM t();
24+
25+
-- nspname.relname.attname%TYPE
26+
DROPFUNCTION t();
27+
CREATE OR REPLACEFUNCTIONt() RETURNSpg_catalog.pg_attribute.attname%TYPEAS'
28+
DECLARE
29+
rec pg_catalog.pg_attribute.attname%TYPE;
30+
BEGIN
31+
SELECT INTO rec pg_catalog.pg_attribute.attname FROM pg_catalog.pg_attribute WHERE attrelid = 1247 AND attname =''typname'';
32+
RETURN rec;
33+
END;
34+
' LANGUAGE'plpgsql';
35+
SELECT t();
36+
37+
-- nspname.relname%ROWTYPE
38+
DROPFUNCTION t();
39+
CREATE OR REPLACEFUNCTIONt() RETURNSpg_catalog.pg_attributeAS'
40+
DECLARE
41+
rec pg_catalog.pg_attribute%ROWTYPE;
42+
BEGIN
43+
SELECT INTO rec * FROM pg_catalog.pg_attribute WHERE attrelid = 1247 AND attname =''typname'';
44+
RETURN rec;
45+
END;
46+
' LANGUAGE'plpgsql';
47+
SELECT*FROM t();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp