33 * procedural language
44 *
55 * IDENTIFICATION
6- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.56 2003/04/24 21: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
8383static void plpgsql_compile_error_callback (void * arg );
84- static PLpgSQL_row * build_rowtype ( Oid classOid );
84+ static PLpgSQL_type * build_datatype ( HeapTuple typeTup , int32 typmod );
8585
8686
8787/*
@@ -275,19 +275,11 @@ plpgsql_compile(Oid fn_oid, int functype)
275275 */
276276var = malloc (sizeof (PLpgSQL_var ));
277277memset (var ,0 ,sizeof (PLpgSQL_var ));
278- var -> datatype = malloc (sizeof (PLpgSQL_type ));
279- memset (var -> datatype ,0 ,sizeof (PLpgSQL_type ));
280278
281279var -> dtype = PLPGSQL_DTYPE_VAR ;
282280var -> refname = strdup (buf );
283281var -> 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 );
291283var -> isconst = true;
292284var -> notnull = false;
293285var -> default_val = NULL ;
@@ -908,7 +900,6 @@ plpgsql_parse_wordtype(char *word)
908900if (HeapTupleIsValid (typeTup ))
909901{
910902Form_pg_type typeStruct = (Form_pg_type )GETSTRUCT (typeTup );
911- PLpgSQL_type * typ ;
912903
913904if (!typeStruct -> typisdefined ||
914905typeStruct -> typrelid != InvalidOid )
@@ -918,17 +909,7 @@ plpgsql_parse_wordtype(char *word)
918909return T_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
933914ReleaseSysCache (typeTup );
934915pfree (cp [0 ]);
@@ -960,8 +941,6 @@ plpgsql_parse_dblwordtype(char *word)
960941HeapTuple attrtup ;
961942Form_pg_attribute attrStruct ;
962943HeapTuple typetup ;
963- Form_pg_type typeStruct ;
964- PLpgSQL_type * typ ;
965944char * cp [3 ];
966945int i ;
967946
@@ -1067,22 +1046,11 @@ plpgsql_parse_dblwordtype(char *word)
10671046if (!HeapTupleIsValid (typetup ))
10681047elog (ERROR ,"cache lookup for type %u of %s.%s failed" ,
10691048attrStruct -> 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
10871055ReleaseSysCache (classtup );
10881056ReleaseSysCache (attrtup );
@@ -1107,8 +1075,6 @@ plpgsql_parse_tripwordtype(char *word)
11071075HeapTuple attrtup ;
11081076Form_pg_attribute attrStruct ;
11091077HeapTuple typetup ;
1110- Form_pg_type typeStruct ;
1111- PLpgSQL_type * typ ;
11121078char * cp [2 ];
11131079char * colname [1 ];
11141080int qualified_att_len ;
@@ -1192,22 +1158,11 @@ plpgsql_parse_tripwordtype(char *word)
11921158if (!HeapTupleIsValid (typetup ))
11931159elog (ERROR ,"cache lookup for type %u of %s.%s failed" ,
11941160attrStruct -> 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
12121167ReleaseSysCache (classtup );
12131168ReleaseSysCache (attrtup );
@@ -1296,7 +1251,7 @@ plpgsql_parse_dblwordrowtype(char *word)
12961251/*
12971252 * Build a rowtype data structure given the pg_class OID.
12981253 */
1299- static PLpgSQL_row *
1254+ PLpgSQL_row *
13001255build_rowtype (Oid classOid )
13011256{
13021257PLpgSQL_row * row ;
@@ -1341,7 +1296,6 @@ build_rowtype(Oid classOid)
13411296HeapTuple attrtup ;
13421297Form_pg_attribute attrStruct ;
13431298HeapTuple typetup ;
1344- Form_pg_type typeStruct ;
13451299const char * attname ;
13461300PLpgSQL_var * var ;
13471301
@@ -1365,7 +1319,6 @@ build_rowtype(Oid classOid)
13651319if (!HeapTupleIsValid (typetup ))
13661320elog (ERROR ,"cache lookup for type %u of %s.%s failed" ,
13671321attrStruct -> 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)
13841337strcpy (var -> refname ,relname );
13851338strcat (var -> refname ,"." );
13861339strcat (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 );
13951341var -> isconst = false;
13961342var -> notnull = false;
13971343var -> default_val = NULL ;
@@ -1428,7 +1374,6 @@ plpgsql_parse_datatype(char *string)
14281374Oid type_id ;
14291375int32 typmod ;
14301376HeapTuple typeTup ;
1431- Form_pg_type typeStruct ;
14321377PLpgSQL_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)
144013850 ,0 ,0 );
14411386if (!HeapTupleIsValid (typeTup ))
14421387elog (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+ return typ ;
1394+ }
1395+
1396+ /*
1397+ * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1398+ */
1399+ static PLpgSQL_type *
1400+ build_datatype (HeapTuple typeTup ,int32 typmod )
1401+ {
1402+ Form_pg_type typeStruct = (Form_pg_type )GETSTRUCT (typeTup );
1403+ PLpgSQL_type * typ ;
14441404
14451405typ = (PLpgSQL_type * )malloc (sizeof (PLpgSQL_type ));
14461406
14471407typ -> 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 );
14521409typ -> 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 ));
14531414typ -> atttypmod = typmod ;
14541415
1455- ReleaseSysCache (typeTup );
1456-
14571416return typ ;
14581417}
14591418