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{
50745079PQExpBufferData fn ;
50755080int j ;
50765081
50775082initPQExpBuffer (& 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 ;
50845087char * 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
50895116argname = argnames ?argnames [j ] : (char * )NULL ;
50905117if (argname && argname [0 ]== '\0' )
50915118argname = NULL ;
50925119
5093- appendPQExpBuffer (& fn ,"%s%s%s%s" ,
5120+ appendPQExpBuffer (& fn ,"%s%s%s%s%s " ,
50945121 (j > 0 ) ?", " :"" ,
5122+ argmode ,
50955123argname ?fmtId (argname ) :"" ,
50965124argname ?" " :"" ,
50975125typname );
@@ -5101,6 +5129,42 @@ format_function_signature(FuncInfo *finfo, char **argnames,
51015129return 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)
51205184char * proretset ;
51215185char * prosrc ;
51225186char * probin ;
5187+ char * proallargtypes ;
5188+ char * proargmodes ;
51235189char * proargnames ;
51245190char * provolatile ;
51255191char * proisstrict ;
51265192char * prosecdef ;
51275193char * lanname ;
51285194char * 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 */
51325201if (!finfo -> dobj .namespace -> dump || dataOnly )
@@ -5141,10 +5210,23 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
51415210selectSourceSchema (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{
51465226appendPQExpBuffer (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{
51575239appendPQExpBuffer (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{
51685252appendPQExpBuffer (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{
51815267appendPQExpBuffer (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)
52055293proretset = PQgetvalue (res ,0 ,PQfnumber (res ,"proretset" ));
52065294prosrc = PQgetvalue (res ,0 ,PQfnumber (res ,"prosrc" ));
52075295probin = PQgetvalue (res ,0 ,PQfnumber (res ,"probin" ));
5296+ proallargtypes = PQgetvalue (res ,0 ,PQfnumber (res ,"proallargtypes" ));
5297+ proargmodes = PQgetvalue (res ,0 ,PQfnumber (res ,"proargmodes" ));
52085298proargnames = PQgetvalue (res ,0 ,PQfnumber (res ,"proargnames" ));
52095299provolatile = PQgetvalue (res ,0 ,PQfnumber (res ,"provolatile" ));
52105300proisstrict = 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+
52495371if (proargnames && * proargnames )
52505372{
52515373int nitems = 0 ;
52525374
5253- if (!parsePGArray (proargnames ,& argnamearray ,& nitems )||
5254- nitems != finfo -> nargs )
5375+ if (!parsePGArray (proargnames ,& argnames ,& nitems )||
5376+ nitems != nallargs )
52555377{
52565378write_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)
53335456destroyPQExpBuffer (asPart );
53345457free (funcsig );
53355458free (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)
54325559appendPQExpBuffer (defqry ,"WITH FUNCTION %s." ,
54335560fmtId (funcInfo -> dobj .namespace -> dobj .name ));
54345561appendPQExpBuffer (defqry ,"%s" ,
5435- format_function_signature (funcInfo , NULL , true));
5562+ format_function_signature (funcInfo , true));
54365563}
54375564
54385565if (cast -> castcontext == 'a' )
@@ -6380,8 +6507,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
63806507free (aggsig );
63816508free (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
63866513dumpACL (fout ,agginfo -> aggfn .dobj .catId ,agginfo -> aggfn .dobj .dumpId ,
63876514"FUNCTION" ,