[PATCH] pg_dump: Sort overloaded functions in deterministic order
Started by Joel Jacobsonover 13 years ago1 messages
Makes pg_dump sort overloaded functions in deterministic order.
The field "proiargs" has been added to FuncInfo and is set by getFuncs()
and getAggregates() for all functions and aggregates.
DOTypeNameCompare uses this field to break ties if the name and number of
arguments are the same. This avoid having to default to OID sorting.
This patch is independent from the ongoing discussion of the pg_dump --split
option. Even if we can't agree on how to do the splitting of objects into
files, it still makes sense to fix the sort order of overloaded functions.
Attachments:
pg_dump_deterministic_order_v4.patchapplication/octet-stream; name=pg_dump_deterministic_order_v4.patchDownload
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
***************
*** 3532,3537 **** getAggregates(Archive *fout, int *numAggs)
--- 3532,3538 ----
int i_proargtypes;
int i_rolname;
int i_aggacl;
+ int i_proiargs;
/* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog");
***************
*** 3546,3551 **** getAggregates(Archive *fout, int *numAggs)
--- 3547,3553 ----
appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
"pronamespace AS aggnamespace, "
"pronargs, proargtypes, "
+ "%s AS proiargs,"
"(%s proowner) AS rolname, "
"proacl AS aggacl "
"FROM pg_proc p "
***************
*** 3553,3558 **** getAggregates(Archive *fout, int *numAggs)
--- 3555,3561 ----
"pronamespace != "
"(SELECT oid FROM pg_namespace "
"WHERE nspname = 'pg_catalog')",
+ (fout->remoteVersion >= 80400) ? "pg_catalog.pg_get_function_identity_arguments(oid)" : "NULL::text",
username_subquery);
if (binary_upgrade && fout->remoteVersion >= 90100)
appendPQExpBuffer(query,
***************
*** 3569,3574 **** getAggregates(Archive *fout, int *numAggs)
--- 3572,3578 ----
"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 "
***************
*** 3583,3588 **** getAggregates(Archive *fout, int *numAggs)
--- 3587,3593 ----
"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 "
***************
*** 3598,3603 **** getAggregates(Archive *fout, int *numAggs)
--- 3603,3609 ----
"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 "
***************
*** 3621,3626 **** getAggregates(Archive *fout, int *numAggs)
--- 3627,3633 ----
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++)
{
***************
*** 3640,3645 **** getAggregates(Archive *fout, int *numAggs)
--- 3647,3653 ----
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;
***************
*** 3691,3696 **** getFuncs(Archive *fout, int *numFuncs)
--- 3699,3705 ----
int i_proargtypes;
int i_prorettype;
int i_proacl;
+ int i_proiargs;
/* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog");
***************
*** 3717,3728 **** getFuncs(Archive *fout, int *numFuncs)
--- 3726,3739 ----
"SELECT tableoid, oid, proname, prolang, "
"pronargs, proargtypes, prorettype, proacl, "
"pronamespace, "
+ "%s AS proiargs,"
"(%s proowner) AS rolname "
"FROM pg_proc p "
"WHERE NOT proisagg AND ("
"pronamespace != "
"(SELECT oid FROM pg_namespace "
"WHERE nspname = 'pg_catalog')",
+ (fout->remoteVersion >= 80400) ? "pg_catalog.pg_get_function_identity_arguments(oid)" : "NULL::text",
username_subquery);
if (fout->remoteVersion >= 90200)
appendPQExpBuffer(query,
***************
*** 3745,3750 **** getFuncs(Archive *fout, int *numFuncs)
--- 3756,3762 ----
"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",
***************
*** 3761,3766 **** getFuncs(Archive *fout, int *numFuncs)
--- 3773,3779 ----
"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",
***************
*** 3786,3791 **** getFuncs(Archive *fout, int *numFuncs)
--- 3799,3805 ----
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++)
{
***************
*** 3801,3806 **** getFuncs(Archive *fout, int *numFuncs)
--- 3815,3821 ----
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)
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
***************
*** 192,197 **** typedef struct _funcInfo
--- 192,198 ----
Oid *argtypes;
Oid prorettype;
char *proacl;
+ char *proiargs;
} FuncInfo;
/* AggInfo is a superset of FuncInfo */
*** a/src/bin/pg_dump/pg_dump_sort.c
--- b/src/bin/pg_dump/pg_dump_sort.c
***************
*** 194,199 **** DOTypeNameCompare(const void *p1, const void *p2)
--- 194,202 ----
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)
{