Commit 7b583b20 authored by Alvaro Herrera's avatar Alvaro Herrera

pg_dump: Output functions deterministically sorted

Implementation idea from Tom Lane

Author: Joel Jacobson
Reviewed by Joachim Wieland
parent 5ad72cee
...@@ -3534,6 +3534,7 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3534,6 +3534,7 @@ getAggregates(Archive *fout, int *numAggs)
int i_proargtypes; int i_proargtypes;
int i_rolname; int i_rolname;
int i_aggacl; int i_aggacl;
int i_proiargs;
/* Make sure we are in proper schema */ /* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog"); selectSourceSchema(fout, "pg_catalog");
...@@ -3543,11 +3544,12 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3543,11 +3544,12 @@ getAggregates(Archive *fout, int *numAggs)
* rationale behind the filtering logic. * rationale behind the filtering logic.
*/ */
if (fout->remoteVersion >= 80200) if (fout->remoteVersion >= 80400)
{ {
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, " appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
"pronamespace AS aggnamespace, " "pronamespace AS aggnamespace, "
"pronargs, proargtypes, " "pronargs, proargtypes, "
"pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
"(%s proowner) AS rolname, " "(%s proowner) AS rolname, "
"proacl AS aggacl " "proacl AS aggacl "
"FROM pg_proc p " "FROM pg_proc p "
...@@ -3565,12 +3567,28 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3565,12 +3567,28 @@ getAggregates(Archive *fout, int *numAggs)
"deptype = 'e')"); "deptype = 'e')");
appendPQExpBuffer(query, ")"); 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) else if (fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, " appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
"pronamespace AS aggnamespace, " "pronamespace AS aggnamespace, "
"CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, " "CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, "
"proargtypes, " "proargtypes, "
"NULL::text AS proiargs, "
"(%s proowner) AS rolname, " "(%s proowner) AS rolname, "
"proacl AS aggacl " "proacl AS aggacl "
"FROM pg_proc " "FROM pg_proc "
...@@ -3585,6 +3603,7 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3585,6 +3603,7 @@ getAggregates(Archive *fout, int *numAggs)
"0::oid AS aggnamespace, " "0::oid AS aggnamespace, "
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
"aggbasetype AS proargtypes, " "aggbasetype AS proargtypes, "
"NULL::text AS proiargs, "
"(%s aggowner) AS rolname, " "(%s aggowner) AS rolname, "
"'{=X}' AS aggacl " "'{=X}' AS aggacl "
"FROM pg_aggregate " "FROM pg_aggregate "
...@@ -3600,6 +3619,7 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3600,6 +3619,7 @@ getAggregates(Archive *fout, int *numAggs)
"0::oid AS aggnamespace, " "0::oid AS aggnamespace, "
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
"aggbasetype AS proargtypes, " "aggbasetype AS proargtypes, "
"NULL::text AS proiargs, "
"(%s aggowner) AS rolname, " "(%s aggowner) AS rolname, "
"'{=X}' AS aggacl " "'{=X}' AS aggacl "
"FROM pg_aggregate " "FROM pg_aggregate "
...@@ -3623,6 +3643,7 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3623,6 +3643,7 @@ getAggregates(Archive *fout, int *numAggs)
i_proargtypes = PQfnumber(res, "proargtypes"); i_proargtypes = PQfnumber(res, "proargtypes");
i_rolname = PQfnumber(res, "rolname"); i_rolname = PQfnumber(res, "rolname");
i_aggacl = PQfnumber(res, "aggacl"); i_aggacl = PQfnumber(res, "aggacl");
i_proiargs = PQfnumber(res, "proiargs");
for (i = 0; i < ntups; i++) for (i = 0; i < ntups; i++)
{ {
...@@ -3642,6 +3663,7 @@ getAggregates(Archive *fout, int *numAggs) ...@@ -3642,6 +3663,7 @@ getAggregates(Archive *fout, int *numAggs)
agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */ agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */ agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */
agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl)); 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)); agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
if (agginfo[i].aggfn.nargs == 0) if (agginfo[i].aggfn.nargs == 0)
agginfo[i].aggfn.argtypes = NULL; agginfo[i].aggfn.argtypes = NULL;
...@@ -3693,6 +3715,7 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3693,6 +3715,7 @@ getFuncs(Archive *fout, int *numFuncs)
int i_proargtypes; int i_proargtypes;
int i_prorettype; int i_prorettype;
int i_proacl; int i_proacl;
int i_proiargs;
/* Make sure we are in proper schema */ /* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog"); selectSourceSchema(fout, "pg_catalog");
...@@ -3713,12 +3736,13 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3713,12 +3736,13 @@ getFuncs(Archive *fout, int *numFuncs)
* doesn't have; otherwise we might not get creation ordering correct. * doesn't have; otherwise we might not get creation ordering correct.
*/ */
if (fout->remoteVersion >= 70300) if (fout->remoteVersion >= 80400)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT tableoid, oid, proname, prolang, " "SELECT tableoid, oid, proname, prolang, "
"pronargs, proargtypes, prorettype, proacl, " "pronargs, proargtypes, prorettype, proacl, "
"pronamespace, " "pronamespace, "
"pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
"(%s proowner) AS rolname " "(%s proowner) AS rolname "
"FROM pg_proc p " "FROM pg_proc p "
"WHERE NOT proisagg AND (" "WHERE NOT proisagg AND ("
...@@ -3740,6 +3764,21 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3740,6 +3764,21 @@ getFuncs(Archive *fout, int *numFuncs)
"deptype = 'e')"); "deptype = 'e')");
appendPQExpBuffer(query, ")"); 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) else if (fout->remoteVersion >= 70100)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
...@@ -3747,6 +3786,7 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3747,6 +3786,7 @@ getFuncs(Archive *fout, int *numFuncs)
"pronargs, proargtypes, prorettype, " "pronargs, proargtypes, prorettype, "
"'{=X}' AS proacl, " "'{=X}' AS proacl, "
"0::oid AS pronamespace, " "0::oid AS pronamespace, "
"NULL::text AS proiargs,"
"(%s proowner) AS rolname " "(%s proowner) AS rolname "
"FROM pg_proc " "FROM pg_proc "
"WHERE pg_proc.oid > '%u'::oid", "WHERE pg_proc.oid > '%u'::oid",
...@@ -3763,6 +3803,7 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3763,6 +3803,7 @@ getFuncs(Archive *fout, int *numFuncs)
"pronargs, proargtypes, prorettype, " "pronargs, proargtypes, prorettype, "
"'{=X}' AS proacl, " "'{=X}' AS proacl, "
"0::oid AS pronamespace, " "0::oid AS pronamespace, "
"NULL::text AS proiargs,"
"(%s proowner) AS rolname " "(%s proowner) AS rolname "
"FROM pg_proc " "FROM pg_proc "
"where pg_proc.oid > '%u'::oid", "where pg_proc.oid > '%u'::oid",
...@@ -3788,6 +3829,7 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3788,6 +3829,7 @@ getFuncs(Archive *fout, int *numFuncs)
i_proargtypes = PQfnumber(res, "proargtypes"); i_proargtypes = PQfnumber(res, "proargtypes");
i_prorettype = PQfnumber(res, "prorettype"); i_prorettype = PQfnumber(res, "prorettype");
i_proacl = PQfnumber(res, "proacl"); i_proacl = PQfnumber(res, "proacl");
i_proiargs = PQfnumber(res, "proiargs");
for (i = 0; i < ntups; i++) for (i = 0; i < ntups; i++)
{ {
...@@ -3803,6 +3845,7 @@ getFuncs(Archive *fout, int *numFuncs) ...@@ -3803,6 +3845,7 @@ getFuncs(Archive *fout, int *numFuncs)
finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname)); finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang)); finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype)); 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].proacl = pg_strdup(PQgetvalue(res, i, i_proacl));
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs)); finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
if (finfo[i].nargs == 0) if (finfo[i].nargs == 0)
......
...@@ -193,6 +193,7 @@ typedef struct _funcInfo ...@@ -193,6 +193,7 @@ typedef struct _funcInfo
Oid *argtypes; Oid *argtypes;
Oid prorettype; Oid prorettype;
char *proacl; char *proacl;
char *proiargs;
} FuncInfo; } FuncInfo;
/* AggInfo is a superset of FuncInfo */ /* AggInfo is a superset of FuncInfo */
......
...@@ -198,6 +198,9 @@ DOTypeNameCompare(const void *p1, const void *p2) ...@@ -198,6 +198,9 @@ DOTypeNameCompare(const void *p1, const void *p2)
cmpval = fobj1->nargs - fobj2->nargs; cmpval = fobj1->nargs - fobj2->nargs;
if (cmpval != 0) if (cmpval != 0)
return cmpval; return cmpval;
cmpval = strcmp(fobj1->proiargs, fobj2->proiargs);
if (cmpval != 0)
return cmpval;
} }
else if (obj1->objType == DO_OPERATOR) else if (obj1->objType == DO_OPERATOR)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment