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)