From 7b583b20b1c95acb621c71251150beef958bb603 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 17 Oct 2012 18:31:42 -0300 Subject: [PATCH] pg_dump: Output functions deterministically sorted Implementation idea from Tom Lane Author: Joel Jacobson Reviewed by Joachim Wieland --- src/bin/pg_dump/pg_dump.c | 47 ++++++++++++++++++++++++++++++++-- src/bin/pg_dump/pg_dump.h | 1 + src/bin/pg_dump/pg_dump_sort.c | 3 +++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index dd2019a1fb..4223b41536 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -3534,6 +3534,7 @@ getAggregates(Archive *fout, int *numAggs) int i_proargtypes; int i_rolname; int i_aggacl; + int i_proiargs; /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); @@ -3543,11 +3544,12 @@ getAggregates(Archive *fout, int *numAggs) * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 80200) + if (fout->remoteVersion >= 80400) { appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, " "pronamespace AS aggnamespace, " "pronargs, proargtypes, " + "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs," "(%s proowner) AS rolname, " "proacl AS aggacl " "FROM pg_proc p " @@ -3565,12 +3567,28 @@ getAggregates(Archive *fout, int *numAggs) "deptype = 'e')"); appendPQExpBuffer(query, ")"); } + else if (fout->remoteVersion >= 80200) + { + appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, " + "pronamespace AS aggnamespace, " + "pronargs, proargtypes, " + "NULL::text AS proiargs," + "(%s proowner) AS rolname, " + "proacl AS aggacl " + "FROM pg_proc p " + "WHERE proisagg AND (" + "pronamespace != " + "(SELECT oid FROM pg_namespace " + "WHERE nspname = 'pg_catalog'))", + username_subquery); + } else if (fout->remoteVersion >= 70300) { appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, " "pronamespace AS aggnamespace, " "CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, " "proargtypes, " + "NULL::text AS proiargs, " "(%s proowner) AS rolname, " "proacl AS aggacl " "FROM pg_proc " @@ -3585,6 +3603,7 @@ getAggregates(Archive *fout, int *numAggs) "0::oid AS aggnamespace, " "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "aggbasetype AS proargtypes, " + "NULL::text AS proiargs, " "(%s aggowner) AS rolname, " "'{=X}' AS aggacl " "FROM pg_aggregate " @@ -3600,6 +3619,7 @@ getAggregates(Archive *fout, int *numAggs) "0::oid AS aggnamespace, " "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "aggbasetype AS proargtypes, " + "NULL::text AS proiargs, " "(%s aggowner) AS rolname, " "'{=X}' AS aggacl " "FROM pg_aggregate " @@ -3623,6 +3643,7 @@ getAggregates(Archive *fout, int *numAggs) i_proargtypes = PQfnumber(res, "proargtypes"); i_rolname = PQfnumber(res, "rolname"); i_aggacl = PQfnumber(res, "aggacl"); + i_proiargs = PQfnumber(res, "proiargs"); for (i = 0; i < ntups; i++) { @@ -3642,6 +3663,7 @@ getAggregates(Archive *fout, int *numAggs) agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */ agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */ agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl)); + agginfo[i].aggfn.proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs)); agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs)); if (agginfo[i].aggfn.nargs == 0) agginfo[i].aggfn.argtypes = NULL; @@ -3693,6 +3715,7 @@ getFuncs(Archive *fout, int *numFuncs) int i_proargtypes; int i_prorettype; int i_proacl; + int i_proiargs; /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); @@ -3713,12 +3736,13 @@ getFuncs(Archive *fout, int *numFuncs) * doesn't have; otherwise we might not get creation ordering correct. */ - if (fout->remoteVersion >= 70300) + if (fout->remoteVersion >= 80400) { appendPQExpBuffer(query, "SELECT tableoid, oid, proname, prolang, " "pronargs, proargtypes, prorettype, proacl, " "pronamespace, " + "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs," "(%s proowner) AS rolname " "FROM pg_proc p " "WHERE NOT proisagg AND (" @@ -3740,6 +3764,21 @@ getFuncs(Archive *fout, int *numFuncs) "deptype = 'e')"); appendPQExpBuffer(query, ")"); } + else if (fout->remoteVersion >= 70300) + { + appendPQExpBuffer(query, + "SELECT tableoid, oid, proname, prolang, " + "pronargs, proargtypes, prorettype, proacl, " + "pronamespace, " + "NULL::text AS proiargs," + "(%s proowner) AS rolname " + "FROM pg_proc p " + "WHERE NOT proisagg AND (" + "pronamespace != " + "(SELECT oid FROM pg_namespace " + "WHERE nspname = 'pg_catalog'))", + username_subquery); + } else if (fout->remoteVersion >= 70100) { appendPQExpBuffer(query, @@ -3747,6 +3786,7 @@ getFuncs(Archive *fout, int *numFuncs) "pronargs, proargtypes, prorettype, " "'{=X}' AS proacl, " "0::oid AS pronamespace, " + "NULL::text AS proiargs," "(%s proowner) AS rolname " "FROM pg_proc " "WHERE pg_proc.oid > '%u'::oid", @@ -3763,6 +3803,7 @@ getFuncs(Archive *fout, int *numFuncs) "pronargs, proargtypes, prorettype, " "'{=X}' AS proacl, " "0::oid AS pronamespace, " + "NULL::text AS proiargs," "(%s proowner) AS rolname " "FROM pg_proc " "where pg_proc.oid > '%u'::oid", @@ -3788,6 +3829,7 @@ getFuncs(Archive *fout, int *numFuncs) i_proargtypes = PQfnumber(res, "proargtypes"); i_prorettype = PQfnumber(res, "prorettype"); i_proacl = PQfnumber(res, "proacl"); + i_proiargs = PQfnumber(res, "proiargs"); for (i = 0; i < ntups; i++) { @@ -3803,6 +3845,7 @@ getFuncs(Archive *fout, int *numFuncs) finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname)); finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang)); finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype)); + finfo[i].proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs)); finfo[i].proacl = pg_strdup(PQgetvalue(res, i, i_proacl)); finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs)); if (finfo[i].nargs == 0) diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 2aa206038d..2100d432e9 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -193,6 +193,7 @@ typedef struct _funcInfo Oid *argtypes; Oid prorettype; char *proacl; + char *proiargs; } FuncInfo; /* AggInfo is a superset of FuncInfo */ diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index f0dc14592a..7aeb52f9e8 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -198,6 +198,9 @@ DOTypeNameCompare(const void *p1, const void *p2) cmpval = fobj1->nargs - fobj2->nargs; if (cmpval != 0) return cmpval; + cmpval = strcmp(fobj1->proiargs, fobj2->proiargs); + if (cmpval != 0) + return cmpval; } else if (obj1->objType == DO_OPERATOR) { -- 2.40.0