1212 * by PostgreSQL
1313 *
1414 * IDENTIFICATION
15- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.404 2005/03/14 18:57:33 tgl Exp $
15+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.405 2005/04/01 18:35:41 tgl Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -150,8 +150,11 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
150150static void getDependencies (void );
151151static void getDomainConstraints (TypeInfo * tinfo );
152152static void getTableData (TableInfo * tblinfo , int numTables , bool oids );
153- static char * format_function_signature (FuncInfo * finfo , char * * argnames ,
154- bool honor_quotes );
153+ static char * format_function_arguments (FuncInfo * finfo , int nallargs ,
154+ char * * allargtypes ,
155+ char * * argmodes ,
156+ char * * argnames );
157+ static char * format_function_signature (FuncInfo * finfo , bool honor_quotes );
155158static const char * convertRegProcReference (const char * proc );
156159static const char * convertOperatorReference (const char * opr );
157160static Oid findLastBuiltinOid_V71 (const char * );
@@ -5060,38 +5063,63 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
50605063}
50615064
50625065/*
5063- * format_function_signature : generate function name and argument list
5066+ * format_function_arguments : generate function name and argument list
50645067 *
50655068 * The argument type names are qualified if needed. The function name
50665069 * is never qualified.
50675070 *
5068- * argnames may be NULL if no names are available .
5071+ * Any or all of allargtypes, argmodes, argnames may be NULL .
50695072 */
50705073static char *
5071- format_function_signature (FuncInfo * finfo , char * * argnames ,
5072- bool honor_quotes )
5074+ format_function_arguments (FuncInfo * finfo , int nallargs ,
5075+ char * * allargtypes ,
5076+ char * * argmodes ,
5077+ char * * argnames )
50735078{
50745079 PQExpBufferData fn ;
50755080 int j ;
50765081
50775082 initPQExpBuffer (& fn );
5078- if (honor_quotes )
5079- appendPQExpBuffer (& fn , "%s(" , fmtId (finfo -> dobj .name ));
5080- else
5081- appendPQExpBuffer (& fn , "%s(" , finfo -> dobj .name );
5082- for (j = 0 ; j < finfo -> nargs ; j ++ )
5083+ appendPQExpBuffer (& fn , "%s(" , fmtId (finfo -> dobj .name ));
5084+ for (j = 0 ; j < nallargs ; j ++ )
50835085 {
5086+ Oid typid ;
50845087 char * typname ;
5085- char * argname ;
5088+ const char * argmode ;
5089+ const char * argname ;
50865090
5087- typname = getFormattedTypeName (finfo -> argtypes [j ], zeroAsOpaque );
5091+ typid = allargtypes ? atooid (allargtypes [j ]) : finfo -> argtypes [j ];
5092+ typname = getFormattedTypeName (typid , zeroAsOpaque );
5093+
5094+ if (argmodes )
5095+ {
5096+ switch (argmodes [j ][0 ])
5097+ {
5098+ case 'i' :
5099+ argmode = "" ;
5100+ break ;
5101+ case 'o' :
5102+ argmode = "OUT " ;
5103+ break ;
5104+ case 'b' :
5105+ argmode = "INOUT " ;
5106+ break ;
5107+ default :
5108+ write_msg (NULL , "WARNING: bogus value in proargmodes array\n" );
5109+ argmode = "" ;
5110+ break ;
5111+ }
5112+ }
5113+ else
5114+ argmode = "" ;
50885115
50895116 argname = argnames ? argnames [j ] : (char * ) NULL ;
50905117 if (argname && argname [0 ] == '\0' )
50915118 argname = NULL ;
50925119
5093- appendPQExpBuffer (& fn , "%s%s%s%s" ,
5120+ appendPQExpBuffer (& fn , "%s%s%s%s%s " ,
50945121 (j > 0 ) ? ", " : "" ,
5122+ argmode ,
50955123 argname ? fmtId (argname ) : "" ,
50965124 argname ? " " : "" ,
50975125 typname );
@@ -5101,6 +5129,42 @@ format_function_signature(FuncInfo *finfo, char **argnames,
51015129 return fn .data ;
51025130}
51035131
5132+ /*
5133+ * format_function_signature: generate function name and argument list
5134+ *
5135+ * This is like format_function_arguments except that only a minimal
5136+ * list of input argument types is generated; this is sufficient to
5137+ * reference the function, but not to define it.
5138+ *
5139+ * If honor_quotes is false then the function name is never quoted.
5140+ * This is appropriate for use in TOC tags, but not in SQL commands.
5141+ */
5142+ static char *
5143+ format_function_signature (FuncInfo * finfo , bool honor_quotes )
5144+ {
5145+ PQExpBufferData fn ;
5146+ int j ;
5147+
5148+ initPQExpBuffer (& fn );
5149+ if (honor_quotes )
5150+ appendPQExpBuffer (& fn , "%s(" , fmtId (finfo -> dobj .name ));
5151+ else
5152+ appendPQExpBuffer (& fn , "%s(" , finfo -> dobj .name );
5153+ for (j = 0 ; j < finfo -> nargs ; j ++ )
5154+ {
5155+ char * typname ;
5156+
5157+ typname = getFormattedTypeName (finfo -> argtypes [j ], zeroAsOpaque );
5158+
5159+ appendPQExpBuffer (& fn , "%s%s" ,
5160+ (j > 0 ) ? ", " : "" ,
5161+ typname );
5162+ free (typname );
5163+ }
5164+ appendPQExpBuffer (& fn , ")" );
5165+ return fn .data ;
5166+ }
5167+
51045168
51055169/*
51065170 * dumpFunc:
@@ -5120,13 +5184,18 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51205184 char * proretset ;
51215185 char * prosrc ;
51225186 char * probin ;
5187+ char * proallargtypes ;
5188+ char * proargmodes ;
51235189 char * proargnames ;
51245190 char * provolatile ;
51255191 char * proisstrict ;
51265192 char * prosecdef ;
51275193 char * lanname ;
51285194 char * rettypename ;
5129- char * * argnamearray = NULL ;
5195+ int nallargs ;
5196+ char * * allargtypes = NULL ;
5197+ char * * argmodes = NULL ;
5198+ char * * argnames = NULL ;
51305199
51315200 /* Dump only funcs in dumpable namespaces */
51325201 if (!finfo -> dobj .namespace -> dump || dataOnly )
@@ -5141,10 +5210,23 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51415210 selectSourceSchema (finfo -> dobj .namespace -> dobj .name );
51425211
51435212 /* Fetch function-specific details */
5144- if (g_fout -> remoteVersion >= 80000 )
5213+ if (g_fout -> remoteVersion >= 80100 )
5214+ {
5215+ appendPQExpBuffer (query ,
5216+ "SELECT proretset, prosrc, probin, "
5217+ "proallargtypes, proargmodes, proargnames, "
5218+ "provolatile, proisstrict, prosecdef, "
5219+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
5220+ "FROM pg_catalog.pg_proc "
5221+ "WHERE oid = '%u'::pg_catalog.oid" ,
5222+ finfo -> dobj .catId .oid );
5223+ }
5224+ else if (g_fout -> remoteVersion >= 80000 )
51455225 {
51465226 appendPQExpBuffer (query ,
51475227 "SELECT proretset, prosrc, probin, "
5228+ "null::text as proallargtypes, "
5229+ "null::text as proargmodes, "
51485230 "proargnames, "
51495231 "provolatile, proisstrict, prosecdef, "
51505232 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
@@ -5156,6 +5238,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51565238 {
51575239 appendPQExpBuffer (query ,
51585240 "SELECT proretset, prosrc, probin, "
5241+ "null::text as proallargtypes, "
5242+ "null::text as proargmodes, "
51595243 "null::text as proargnames, "
51605244 "provolatile, proisstrict, prosecdef, "
51615245 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
@@ -5167,6 +5251,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51675251 {
51685252 appendPQExpBuffer (query ,
51695253 "SELECT proretset, prosrc, probin, "
5254+ "null::text as proallargtypes, "
5255+ "null::text as proargmodes, "
51705256 "null::text as proargnames, "
51715257 "case when proiscachable then 'i' else 'v' end as provolatile, "
51725258 "proisstrict, "
@@ -5180,6 +5266,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51805266 {
51815267 appendPQExpBuffer (query ,
51825268 "SELECT proretset, prosrc, probin, "
5269+ "null::text as proallargtypes, "
5270+ "null::text as proargmodes, "
51835271 "null::text as proargnames, "
51845272 "case when proiscachable then 'i' else 'v' end as provolatile, "
51855273 "'f'::boolean as proisstrict, "
@@ -5205,6 +5293,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
52055293 proretset = PQgetvalue (res , 0 , PQfnumber (res , "proretset" ));
52065294 prosrc = PQgetvalue (res , 0 , PQfnumber (res , "prosrc" ));
52075295 probin = PQgetvalue (res , 0 , PQfnumber (res , "probin" ));
5296+ proallargtypes = PQgetvalue (res , 0 , PQfnumber (res , "proallargtypes" ));
5297+ proargmodes = PQgetvalue (res , 0 , PQfnumber (res , "proargmodes" ));
52085298 proargnames = PQgetvalue (res , 0 , PQfnumber (res , "proargnames" ));
52095299 provolatile = PQgetvalue (res , 0 , PQfnumber (res , "provolatile" ));
52105300 proisstrict = PQgetvalue (res , 0 , PQfnumber (res , "proisstrict" ));
@@ -5246,22 +5336,55 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
52465336 }
52475337 }
52485338
5339+ nallargs = finfo -> nargs ; /* unless we learn different from allargs */
5340+
5341+ if (proallargtypes && * proallargtypes )
5342+ {
5343+ int nitems = 0 ;
5344+
5345+ if (!parsePGArray (proallargtypes , & allargtypes , & nitems ) ||
5346+ nitems < finfo -> nargs )
5347+ {
5348+ write_msg (NULL , "WARNING: could not parse proallargtypes array\n" );
5349+ if (allargtypes )
5350+ free (allargtypes );
5351+ allargtypes = NULL ;
5352+ }
5353+ else
5354+ nallargs = nitems ;
5355+ }
5356+
5357+ if (proargmodes && * proargmodes )
5358+ {
5359+ int nitems = 0 ;
5360+
5361+ if (!parsePGArray (proargmodes , & argmodes , & nitems ) ||
5362+ nitems != nallargs )
5363+ {
5364+ write_msg (NULL , "WARNING: could not parse proargmodes array\n" );
5365+ if (argmodes )
5366+ free (argmodes );
5367+ argmodes = NULL ;
5368+ }
5369+ }
5370+
52495371 if (proargnames && * proargnames )
52505372 {
52515373 int nitems = 0 ;
52525374
5253- if (!parsePGArray (proargnames , & argnamearray , & nitems ) ||
5254- nitems != finfo -> nargs )
5375+ if (!parsePGArray (proargnames , & argnames , & nitems ) ||
5376+ nitems != nallargs )
52555377 {
52565378 write_msg (NULL , "WARNING: could not parse proargnames array\n" );
5257- if (argnamearray )
5258- free (argnamearray );
5259- argnamearray = NULL ;
5379+ if (argnames )
5380+ free (argnames );
5381+ argnames = NULL ;
52605382 }
52615383 }
52625384
5263- funcsig = format_function_signature (finfo , argnamearray , true);
5264- funcsig_tag = format_function_signature (finfo , NULL , false);
5385+ funcsig = format_function_arguments (finfo , nallargs , allargtypes ,
5386+ argmodes , argnames );
5387+ funcsig_tag = format_function_signature (finfo , false);
52655388
52665389 /*
52675390 * DROP must be fully qualified in case same name appears in
@@ -5333,8 +5456,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
53335456 destroyPQExpBuffer (asPart );
53345457 free (funcsig );
53355458 free (funcsig_tag );
5336- if (argnamearray )
5337- free (argnamearray );
5459+ if (allargtypes )
5460+ free (allargtypes );
5461+ if (argmodes )
5462+ free (argmodes );
5463+ if (argnames )
5464+ free (argnames );
53385465}
53395466
53405467
@@ -5432,7 +5559,7 @@ dumpCast(Archive *fout, CastInfo *cast)
54325559 appendPQExpBuffer (defqry , "WITH FUNCTION %s." ,
54335560 fmtId (funcInfo -> dobj .namespace -> dobj .name ));
54345561 appendPQExpBuffer (defqry , "%s" ,
5435- format_function_signature (funcInfo , NULL , true));
5562+ format_function_signature (funcInfo , true));
54365563 }
54375564
54385565 if (cast -> castcontext == 'a' )
@@ -6380,8 +6507,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
63806507 free (aggsig );
63816508 free (aggsig_tag );
63826509
6383- aggsig = format_function_signature (& agginfo -> aggfn , NULL , true);
6384- aggsig_tag = format_function_signature (& agginfo -> aggfn , NULL , false);
6510+ aggsig = format_function_signature (& agginfo -> aggfn , true);
6511+ aggsig_tag = format_function_signature (& agginfo -> aggfn , false);
63856512
63866513 dumpACL (fout , agginfo -> aggfn .dobj .catId , agginfo -> aggfn .dobj .dumpId ,
63876514 "FUNCTION" ,
0 commit comments