[PATCH] pg_dump: Sort overloaded functions in deterministic order

Started by Joel Jacobsonover 13 years ago1 messages
#1Joel Jacobson
joel@trustly.com
2 attachment(s)

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)
  	{
pg_dump_deterministic_order.tapplication/x-troff; name=pg_dump_deterministic_order.tDownload