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

Commit6400d69

Browse files
committed
pg_dump support for function parameter names.
1 parenta77e32d commit6400d69

File tree

3 files changed

+144
-98
lines changed

3 files changed

+144
-98
lines changed

‎src/bin/pg_dump/dumputils.c

Lines changed: 87 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.10 2003/11/29 19:52:05 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.11 2004/01/07 00:44:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,7 +21,6 @@
2121

2222
#definesupports_grant_options(version) ((version) >= 70400)
2323

24-
staticboolparseAclArray(constchar*acls,char***itemarray,int*nitems);
2524
staticboolparseAclItem(constchar*item,constchar*type,constchar*name,
2625
intremoteVersion,
2726
PQExpBuffergrantee,PQExpBuffergrantor,
@@ -166,6 +165,91 @@ parse_version(const char *versionString)
166165
}
167166

168167

168+
/*
169+
* Deconstruct the text representation of a 1-dimensional Postgres array
170+
* into individual items.
171+
*
172+
* On success, returns true and sets *itemarray and *nitems to describe
173+
* an array of individual strings.On parse failure, returns false;
174+
* *itemarray may exist or be NULL.
175+
*
176+
* NOTE: free'ing itemarray is sufficient to deallocate the working storage.
177+
*/
178+
bool
179+
parsePGArray(constchar*atext,char***itemarray,int*nitems)
180+
{
181+
intinputlen;
182+
char**items;
183+
char*strings;
184+
intcuritem;
185+
186+
/*
187+
* We expect input in the form of "{item,item,item}" where any item is
188+
* either raw data, or surrounded by double quotes (in which case
189+
* embedded characters including backslashes and quotes are
190+
* backslashed).
191+
*
192+
* We build the result as an array of pointers followed by the actual
193+
* string data, all in one malloc block for convenience of
194+
* deallocation. The worst-case storage need is not more than one
195+
* pointer and one character for each input character (consider
196+
* "{,,,,,,,,,,}").
197+
*/
198+
*itemarray=NULL;
199+
*nitems=0;
200+
inputlen=strlen(atext);
201+
if (inputlen<2||atext[0]!='{'||atext[inputlen-1]!='}')
202+
return false;/* bad input */
203+
items= (char**)malloc(inputlen* (sizeof(char*)+sizeof(char)));
204+
if (items==NULL)
205+
return false;/* out of memory */
206+
*itemarray=items;
207+
strings= (char*) (items+inputlen);
208+
209+
atext++;/* advance over initial '{' */
210+
curitem=0;
211+
while (*atext!='}')
212+
{
213+
if (*atext=='\0')
214+
return false;/* premature end of string */
215+
items[curitem]=strings;
216+
while (*atext!='}'&&*atext!=',')
217+
{
218+
if (*atext=='\0')
219+
return false;/* premature end of string */
220+
if (*atext!='"')
221+
*strings++=*atext++;/* copy unquoted data */
222+
else
223+
{
224+
/* process quoted substring */
225+
atext++;
226+
while (*atext!='"')
227+
{
228+
if (*atext=='\0')
229+
return false;/* premature end of string */
230+
if (*atext=='\\')
231+
{
232+
atext++;
233+
if (*atext=='\0')
234+
return false;/* premature end of string */
235+
}
236+
*strings++=*atext++;/* copy quoted data */
237+
}
238+
atext++;
239+
}
240+
}
241+
*strings++='\0';
242+
if (*atext==',')
243+
atext++;
244+
curitem++;
245+
}
246+
if (atext[1]!='\0')
247+
return false;/* bogus syntax (embedded '}') */
248+
*nitems=curitem;
249+
return true;
250+
}
251+
252+
169253
/*
170254
* Build GRANT/REVOKE command(s) for an object.
171255
*
@@ -202,7 +286,7 @@ buildACLCommands(const char *name, const char *type,
202286
if (strlen(acls)==0)
203287
return true;/* object has default permissions */
204288

205-
if (!parseAclArray(acls,&aclitems,&naclitems))
289+
if (!parsePGArray(acls,&aclitems,&naclitems))
206290
{
207291
if (aclitems)
208292
free(aclitems);
@@ -341,90 +425,6 @@ buildACLCommands(const char *name, const char *type,
341425
return true;
342426
}
343427

344-
/*
345-
* Deconstruct an ACL array (or actually any 1-dimensional Postgres array)
346-
* into individual items.
347-
*
348-
* On success, returns true and sets *itemarray and *nitems to describe
349-
* an array of individual strings.On parse failure, returns false;
350-
* *itemarray may exist or be NULL.
351-
*
352-
* NOTE: free'ing itemarray is sufficient to deallocate the working storage.
353-
*/
354-
staticbool
355-
parseAclArray(constchar*acls,char***itemarray,int*nitems)
356-
{
357-
intinputlen;
358-
char**items;
359-
char*strings;
360-
intcuritem;
361-
362-
/*
363-
* We expect input in the form of "{item,item,item}" where any item is
364-
* either raw data, or surrounded by double quotes (in which case
365-
* embedded characters including backslashes and quotes are
366-
* backslashed).
367-
*
368-
* We build the result as an array of pointers followed by the actual
369-
* string data, all in one malloc block for convenience of
370-
* deallocation. The worst-case storage need is not more than one
371-
* pointer and one character for each input character (consider
372-
* "{,,,,,,,,,,}").
373-
*/
374-
*itemarray=NULL;
375-
*nitems=0;
376-
inputlen=strlen(acls);
377-
if (inputlen<2||acls[0]!='{'||acls[inputlen-1]!='}')
378-
return false;/* bad input */
379-
items= (char**)malloc(inputlen* (sizeof(char*)+sizeof(char)));
380-
if (items==NULL)
381-
return false;/* out of memory */
382-
*itemarray=items;
383-
strings= (char*) (items+inputlen);
384-
385-
acls++;/* advance over initial '{' */
386-
curitem=0;
387-
while (*acls!='}')
388-
{
389-
if (*acls=='\0')
390-
return false;/* premature end of string */
391-
items[curitem]=strings;
392-
while (*acls!='}'&&*acls!=',')
393-
{
394-
if (*acls=='\0')
395-
return false;/* premature end of string */
396-
if (*acls!='"')
397-
*strings++=*acls++;/* copy unquoted data */
398-
else
399-
{
400-
/* process quoted substring */
401-
acls++;
402-
while (*acls!='"')
403-
{
404-
if (*acls=='\0')
405-
return false;/* premature end of string */
406-
if (*acls=='\\')
407-
{
408-
acls++;
409-
if (*acls=='\0')
410-
return false;/* premature end of string */
411-
}
412-
*strings++=*acls++;/* copy quoted data */
413-
}
414-
acls++;
415-
}
416-
}
417-
*strings++='\0';
418-
if (*acls==',')
419-
acls++;
420-
curitem++;
421-
}
422-
if (acls[1]!='\0')
423-
return false;/* bogus syntax (embedded '}') */
424-
*nitems=curitem;
425-
return true;
426-
}
427-
428428
/*
429429
* This will parse an aclitem string, having the general form
430430
*username=privilegecodes/grantor

‎src/bin/pg_dump/dumputils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.9 2003/11/29 22:40:46 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.10 2004/01/07 00:44:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -22,6 +22,7 @@ extern const char *fmtId(const char *identifier);
2222
externvoidappendStringLiteral(PQExpBufferbuf,constchar*str,
2323
boolescapeAll);
2424
externintparse_version(constchar*versionString);
25+
externboolparsePGArray(constchar*atext,char***itemarray,int*nitems);
2526
externboolbuildACLCommands(constchar*name,constchar*type,
2627
constchar*acls,constchar*owner,
2728
intremoteVersion,

‎src/bin/pg_dump/pg_dump.c

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.361 2003/12/19 14:21:56 petere Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.362 2004/01/07 00:44:21 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -135,7 +135,8 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
135135
staticvoidgetDependencies(void);
136136
staticvoidgetDomainConstraints(TypeInfo*tinfo);
137137
staticvoidgetTableData(TableInfo*tblinfo,intnumTables,booloids);
138-
staticchar*format_function_signature(FuncInfo*finfo,boolhonor_quotes);
138+
staticchar*format_function_signature(FuncInfo*finfo,char**argnames,
139+
boolhonor_quotes);
139140
staticconstchar*convertRegProcReference(constchar*proc);
140141
staticconstchar*convertOperatorReference(constchar*opr);
141142
staticOidfindLastBuiltinOid_V71(constchar*);
@@ -4650,9 +4651,12 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
46504651
*
46514652
* The argument type names are qualified if needed. The function name
46524653
* is never qualified.
4654+
*
4655+
* argnames may be NULL if no names are available.
46534656
*/
46544657
staticchar*
4655-
format_function_signature(FuncInfo*finfo,boolhonor_quotes)
4658+
format_function_signature(FuncInfo*finfo,char**argnames,
4659+
boolhonor_quotes)
46564660
{
46574661
PQExpBufferDatafn;
46584662
intj;
@@ -4665,10 +4669,18 @@ format_function_signature(FuncInfo *finfo, bool honor_quotes)
46654669
for (j=0;j<finfo->nargs;j++)
46664670
{
46674671
char*typname;
4672+
char*argname;
46684673

46694674
typname=getFormattedTypeName(finfo->argtypes[j],zeroAsOpaque);
4670-
appendPQExpBuffer(&fn,"%s%s",
4675+
4676+
argname=argnames ?argnames[j] : (char*)NULL;
4677+
if (argname&&argname[0]=='\0')
4678+
argname=NULL;
4679+
4680+
appendPQExpBuffer(&fn,"%s%s%s%s",
46714681
(j>0) ?", " :"",
4682+
argname ?fmtId(argname) :"",
4683+
argname ?" " :"",
46724684
typname);
46734685
free(typname);
46744686
}
@@ -4695,11 +4707,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
46954707
char*proretset;
46964708
char*prosrc;
46974709
char*probin;
4710+
char*proargnames;
46984711
char*provolatile;
46994712
char*proisstrict;
47004713
char*prosecdef;
47014714
char*lanname;
47024715
char*rettypename;
4716+
char**argnamearray=NULL;
47034717

47044718
/* Dump only funcs in dumpable namespaces */
47054719
if (!finfo->pronamespace->dump||dataOnly)
@@ -4714,10 +4728,22 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
47144728
selectSourceSchema(finfo->pronamespace->nspname);
47154729

47164730
/* Fetch function-specific details */
4717-
if (g_fout->remoteVersion >=70300)
4731+
if (g_fout->remoteVersion >=70500)
47184732
{
47194733
appendPQExpBuffer(query,
47204734
"SELECT proretset, prosrc, probin, "
4735+
"proargnames, "
4736+
"provolatile, proisstrict, prosecdef, "
4737+
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
4738+
"FROM pg_catalog.pg_proc "
4739+
"WHERE oid = '%u'::pg_catalog.oid",
4740+
finfo->dobj.catId.oid);
4741+
}
4742+
elseif (g_fout->remoteVersion >=70300)
4743+
{
4744+
appendPQExpBuffer(query,
4745+
"SELECT proretset, prosrc, probin, "
4746+
"null::text as proargnames, "
47214747
"provolatile, proisstrict, prosecdef, "
47224748
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
47234749
"FROM pg_catalog.pg_proc "
@@ -4728,6 +4754,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
47284754
{
47294755
appendPQExpBuffer(query,
47304756
"SELECT proretset, prosrc, probin, "
4757+
"null::text as proargnames, "
47314758
"case when proiscachable then 'i' else 'v' end as provolatile, "
47324759
"proisstrict, "
47334760
"'f'::boolean as prosecdef, "
@@ -4740,6 +4767,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
47404767
{
47414768
appendPQExpBuffer(query,
47424769
"SELECT proretset, prosrc, probin, "
4770+
"null::text as proargnames, "
47434771
"case when proiscachable then 'i' else 'v' end as provolatile, "
47444772
"'f'::boolean as proisstrict, "
47454773
"'f'::boolean as prosecdef, "
@@ -4764,6 +4792,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
47644792
proretset=PQgetvalue(res,0,PQfnumber(res,"proretset"));
47654793
prosrc=PQgetvalue(res,0,PQfnumber(res,"prosrc"));
47664794
probin=PQgetvalue(res,0,PQfnumber(res,"probin"));
4795+
proargnames=PQgetvalue(res,0,PQfnumber(res,"proargnames"));
47674796
provolatile=PQgetvalue(res,0,PQfnumber(res,"provolatile"));
47684797
proisstrict=PQgetvalue(res,0,PQfnumber(res,"proisstrict"));
47694798
prosecdef=PQgetvalue(res,0,PQfnumber(res,"prosecdef"));
@@ -4792,8 +4821,22 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
47924821
}
47934822
}
47944823

4795-
funcsig=format_function_signature(finfo, true);
4796-
funcsig_tag=format_function_signature(finfo, false);
4824+
if (proargnames&&*proargnames)
4825+
{
4826+
intnitems=0;
4827+
4828+
if (!parsePGArray(proargnames,&argnamearray,&nitems)||
4829+
nitems!=finfo->nargs)
4830+
{
4831+
write_msg(NULL,"WARNING: could not parse proargnames array\n");
4832+
if (argnamearray)
4833+
free(argnamearray);
4834+
argnamearray=NULL;
4835+
}
4836+
}
4837+
4838+
funcsig=format_function_signature(finfo,argnamearray, true);
4839+
funcsig_tag=format_function_signature(finfo,NULL, false);
47974840

47984841
/*
47994842
* DROP must be fully qualified in case same name appears in
@@ -4864,6 +4907,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
48644907
destroyPQExpBuffer(asPart);
48654908
free(funcsig);
48664909
free(funcsig_tag);
4910+
if (argnamearray)
4911+
free(argnamearray);
48674912
}
48684913

48694914

@@ -4953,7 +4998,7 @@ dumpCast(Archive *fout, CastInfo *cast)
49534998
appendPQExpBuffer(defqry,"WITHOUT FUNCTION");
49544999
else
49555000
appendPQExpBuffer(defqry,"WITH FUNCTION %s",
4956-
format_function_signature(funcInfo, true));
5001+
format_function_signature(funcInfo,NULL,true));
49575002

49585003
if (cast->castcontext=='a')
49595004
appendPQExpBuffer(defqry," AS ASSIGNMENT");
@@ -5892,8 +5937,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
58925937
free(aggsig);
58935938
free(aggsig_tag);
58945939

5895-
aggsig=format_function_signature(&agginfo->aggfn, true);
5896-
aggsig_tag=format_function_signature(&agginfo->aggfn, false);
5940+
aggsig=format_function_signature(&agginfo->aggfn,NULL,true);
5941+
aggsig_tag=format_function_signature(&agginfo->aggfn,NULL,false);
58975942

58985943
dumpACL(fout,agginfo->aggfn.dobj.catId,agginfo->aggfn.dobj.dumpId,
58995944
"FUNCTION",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp