Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
pg_dump: Output functions deterministically sorted
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 17 Oct 2012 21:31:42 +0000 (18:31 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 18 Oct 2012 15:23:27 +0000 (12:23 -0300)
Implementation idea from Tom Lane

Author: Joel Jacobson
Reviewed by Joachim Wieland

src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dump_sort.c

index dd2019a1fb70f0d7ac6a27bb854a4d71e6de05f4..4223b415362f4673097b6950c1c1f8b8349ca7d7 100644 (file)
@@ -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)
index 2aa206038dee4d090772bd087f7b0c47affc6afd..2100d432e99cd0b0eb86e21da4987a11f1e6eaa3 100644 (file)
@@ -193,6 +193,7 @@ typedef struct _funcInfo
    Oid        *argtypes;
    Oid         prorettype;
    char       *proacl;
+   char       *proiargs;
 } FuncInfo;
 
 /* AggInfo is a superset of FuncInfo */
index f0dc14592adbd73da55556a0053876fee0faf1f7..7aeb52f9e87a8bedf5762e625ecea397b7ab2688 100644 (file)
@@ -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)
    {