Skip to content

Commit 7b583b2

Browse files
committed
pg_dump: Output functions deterministically sorted
Implementation idea from Tom Lane Author: Joel Jacobson Reviewed by Joachim Wieland
1 parent 5ad72ce commit 7b583b2

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3534,6 +3534,7 @@ getAggregates(Archive *fout, int *numAggs)
35343534
int i_proargtypes;
35353535
int i_rolname;
35363536
int i_aggacl;
3537+
int i_proiargs;
35373538

35383539
/* Make sure we are in proper schema */
35393540
selectSourceSchema(fout, "pg_catalog");
@@ -3543,11 +3544,12 @@ getAggregates(Archive *fout, int *numAggs)
35433544
* rationale behind the filtering logic.
35443545
*/
35453546

3546-
if (fout->remoteVersion >= 80200)
3547+
if (fout->remoteVersion >= 80400)
35473548
{
35483549
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
35493550
"pronamespace AS aggnamespace, "
35503551
"pronargs, proargtypes, "
3552+
"pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
35513553
"(%s proowner) AS rolname, "
35523554
"proacl AS aggacl "
35533555
"FROM pg_proc p "
@@ -3565,12 +3567,28 @@ getAggregates(Archive *fout, int *numAggs)
35653567
"deptype = 'e')");
35663568
appendPQExpBuffer(query, ")");
35673569
}
3570+
else if (fout->remoteVersion >= 80200)
3571+
{
3572+
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
3573+
"pronamespace AS aggnamespace, "
3574+
"pronargs, proargtypes, "
3575+
"NULL::text AS proiargs,"
3576+
"(%s proowner) AS rolname, "
3577+
"proacl AS aggacl "
3578+
"FROM pg_proc p "
3579+
"WHERE proisagg AND ("
3580+
"pronamespace != "
3581+
"(SELECT oid FROM pg_namespace "
3582+
"WHERE nspname = 'pg_catalog'))",
3583+
username_subquery);
3584+
}
35683585
else if (fout->remoteVersion >= 70300)
35693586
{
35703587
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
35713588
"pronamespace AS aggnamespace, "
35723589
"CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, "
35733590
"proargtypes, "
3591+
"NULL::text AS proiargs, "
35743592
"(%s proowner) AS rolname, "
35753593
"proacl AS aggacl "
35763594
"FROM pg_proc "
@@ -3585,6 +3603,7 @@ getAggregates(Archive *fout, int *numAggs)
35853603
"0::oid AS aggnamespace, "
35863604
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
35873605
"aggbasetype AS proargtypes, "
3606+
"NULL::text AS proiargs, "
35883607
"(%s aggowner) AS rolname, "
35893608
"'{=X}' AS aggacl "
35903609
"FROM pg_aggregate "
@@ -3600,6 +3619,7 @@ getAggregates(Archive *fout, int *numAggs)
36003619
"0::oid AS aggnamespace, "
36013620
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
36023621
"aggbasetype AS proargtypes, "
3622+
"NULL::text AS proiargs, "
36033623
"(%s aggowner) AS rolname, "
36043624
"'{=X}' AS aggacl "
36053625
"FROM pg_aggregate "
@@ -3623,6 +3643,7 @@ getAggregates(Archive *fout, int *numAggs)
36233643
i_proargtypes = PQfnumber(res, "proargtypes");
36243644
i_rolname = PQfnumber(res, "rolname");
36253645
i_aggacl = PQfnumber(res, "aggacl");
3646+
i_proiargs = PQfnumber(res, "proiargs");
36263647

36273648
for (i = 0; i < ntups; i++)
36283649
{
@@ -3642,6 +3663,7 @@ getAggregates(Archive *fout, int *numAggs)
36423663
agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
36433664
agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
36443665
agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl));
3666+
agginfo[i].aggfn.proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
36453667
agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
36463668
if (agginfo[i].aggfn.nargs == 0)
36473669
agginfo[i].aggfn.argtypes = NULL;
@@ -3693,6 +3715,7 @@ getFuncs(Archive *fout, int *numFuncs)
36933715
int i_proargtypes;
36943716
int i_prorettype;
36953717
int i_proacl;
3718+
int i_proiargs;
36963719

36973720
/* Make sure we are in proper schema */
36983721
selectSourceSchema(fout, "pg_catalog");
@@ -3713,12 +3736,13 @@ getFuncs(Archive *fout, int *numFuncs)
37133736
* doesn't have; otherwise we might not get creation ordering correct.
37143737
*/
37153738

3716-
if (fout->remoteVersion >= 70300)
3739+
if (fout->remoteVersion >= 80400)
37173740
{
37183741
appendPQExpBuffer(query,
37193742
"SELECT tableoid, oid, proname, prolang, "
37203743
"pronargs, proargtypes, prorettype, proacl, "
37213744
"pronamespace, "
3745+
"pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
37223746
"(%s proowner) AS rolname "
37233747
"FROM pg_proc p "
37243748
"WHERE NOT proisagg AND ("
@@ -3740,13 +3764,29 @@ getFuncs(Archive *fout, int *numFuncs)
37403764
"deptype = 'e')");
37413765
appendPQExpBuffer(query, ")");
37423766
}
3767+
else if (fout->remoteVersion >= 70300)
3768+
{
3769+
appendPQExpBuffer(query,
3770+
"SELECT tableoid, oid, proname, prolang, "
3771+
"pronargs, proargtypes, prorettype, proacl, "
3772+
"pronamespace, "
3773+
"NULL::text AS proiargs,"
3774+
"(%s proowner) AS rolname "
3775+
"FROM pg_proc p "
3776+
"WHERE NOT proisagg AND ("
3777+
"pronamespace != "
3778+
"(SELECT oid FROM pg_namespace "
3779+
"WHERE nspname = 'pg_catalog'))",
3780+
username_subquery);
3781+
}
37433782
else if (fout->remoteVersion >= 70100)
37443783
{
37453784
appendPQExpBuffer(query,
37463785
"SELECT tableoid, oid, proname, prolang, "
37473786
"pronargs, proargtypes, prorettype, "
37483787
"'{=X}' AS proacl, "
37493788
"0::oid AS pronamespace, "
3789+
"NULL::text AS proiargs,"
37503790
"(%s proowner) AS rolname "
37513791
"FROM pg_proc "
37523792
"WHERE pg_proc.oid > '%u'::oid",
@@ -3763,6 +3803,7 @@ getFuncs(Archive *fout, int *numFuncs)
37633803
"pronargs, proargtypes, prorettype, "
37643804
"'{=X}' AS proacl, "
37653805
"0::oid AS pronamespace, "
3806+
"NULL::text AS proiargs,"
37663807
"(%s proowner) AS rolname "
37673808
"FROM pg_proc "
37683809
"where pg_proc.oid > '%u'::oid",
@@ -3788,6 +3829,7 @@ getFuncs(Archive *fout, int *numFuncs)
37883829
i_proargtypes = PQfnumber(res, "proargtypes");
37893830
i_prorettype = PQfnumber(res, "prorettype");
37903831
i_proacl = PQfnumber(res, "proacl");
3832+
i_proiargs = PQfnumber(res, "proiargs");
37913833

37923834
for (i = 0; i < ntups; i++)
37933835
{
@@ -3803,6 +3845,7 @@ getFuncs(Archive *fout, int *numFuncs)
38033845
finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
38043846
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
38053847
finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
3848+
finfo[i].proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
38063849
finfo[i].proacl = pg_strdup(PQgetvalue(res, i, i_proacl));
38073850
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
38083851
if (finfo[i].nargs == 0)

src/bin/pg_dump/pg_dump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ typedef struct _funcInfo
193193
Oid *argtypes;
194194
Oid prorettype;
195195
char *proacl;
196+
char *proiargs;
196197
} FuncInfo;
197198

198199
/* AggInfo is a superset of FuncInfo */

src/bin/pg_dump/pg_dump_sort.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ DOTypeNameCompare(const void *p1, const void *p2)
198198
cmpval = fobj1->nargs - fobj2->nargs;
199199
if (cmpval != 0)
200200
return cmpval;
201+
cmpval = strcmp(fobj1->proiargs, fobj2->proiargs);
202+
if (cmpval != 0)
203+
return cmpval;
201204
}
202205
else if (obj1->objType == DO_OPERATOR)
203206
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy