Qualify table usage in dumpTable() and use regclass
authorStephen Frost <sfrost@snowman.net>
Wed, 25 May 2016 00:10:16 +0000 (20:10 -0400)
committerStephen Frost <sfrost@snowman.net>
Wed, 25 May 2016 00:10:16 +0000 (20:10 -0400)
All of the other tables used in the query in dumpTable(), which is
collecting column-level ACLs, are qualified, so we should be qualifying
the pg_init_privs, the related sub-select against pg_class and the
other queries added by the pg_dump catalog ACLs work.

Also, use ::regclass (or ::pg_catalog.regclass, where appropriate)
instead of using a poorly constructed query to get the OID for various
catalog tables.

Issues identified by Noah and Alvaro, patch by me.

src/bin/pg_dump/dumputils.c
src/bin/pg_dump/pg_dump.c
src/test/modules/test_pg_dump/t/001_base.pl

index c55a2fa14ecbc7386ecf569be2634abf70621dff..0acdf54fa5eb85eb42e436a8e60a1863a32acc16 100644 (file)
@@ -715,20 +715,20 @@ buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery,
     * these are run the initial privileges will be in place, even in a
     * binary upgrade situation (see below).
     */
-   printfPQExpBuffer(acl_subquery, "(SELECT array_agg(acl) FROM "
-                     "(SELECT unnest(coalesce(%s,acldefault(%s,%s))) AS acl "
+   printfPQExpBuffer(acl_subquery, "(SELECT pg_catalog.array_agg(acl) FROM "
+                     "(SELECT pg_catalog.unnest(coalesce(%s,pg_catalog.acldefault(%s,%s))) AS acl "
                      "EXCEPT "
-        "SELECT unnest(coalesce(pip.initprivs,acldefault(%s,%s)))) as foo)",
+        "SELECT pg_catalog.unnest(coalesce(pip.initprivs,pg_catalog.acldefault(%s,%s)))) as foo)",
                      acl_column,
                      obj_kind,
                      acl_owner,
                      obj_kind,
                      acl_owner);
 
-   printfPQExpBuffer(racl_subquery, "(SELECT array_agg(acl) FROM "
-         "(SELECT unnest(coalesce(pip.initprivs,acldefault(%s,%s))) AS acl "
+   printfPQExpBuffer(racl_subquery, "(SELECT pg_catalog.array_agg(acl) FROM "
+         "(SELECT pg_catalog.unnest(coalesce(pip.initprivs,pg_catalog.acldefault(%s,%s))) AS acl "
                      "EXCEPT "
-                   "SELECT unnest(coalesce(%s,acldefault(%s,%s)))) as foo)",
+                   "SELECT pg_catalog.unnest(coalesce(%s,pg_catalog.acldefault(%s,%s)))) as foo)",
                      obj_kind,
                      acl_owner,
                      acl_column,
@@ -753,19 +753,19 @@ buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery,
    {
        printfPQExpBuffer(init_acl_subquery,
                          "CASE WHEN privtype = 'e' THEN "
-                         "(SELECT array_agg(acl) FROM "
-                         "(SELECT unnest(pip.initprivs) AS acl "
+                         "(SELECT pg_catalog.array_agg(acl) FROM "
+                         "(SELECT pg_catalog.unnest(pip.initprivs) AS acl "
                          "EXCEPT "
-                         "SELECT unnest(acldefault(%s,%s))) as foo) END",
+                         "SELECT pg_catalog.unnest(pg_catalog.acldefault(%s,%s))) as foo) END",
                          obj_kind,
                          acl_owner);
 
        printfPQExpBuffer(init_racl_subquery,
                          "CASE WHEN privtype = 'e' THEN "
-                         "(SELECT array_agg(acl) FROM "
-                         "(SELECT unnest(acldefault(%s,%s)) AS acl "
+                         "(SELECT pg_catalog.array_agg(acl) FROM "
+                         "(SELECT pg_catalog.unnest(pg_catalog.acldefault(%s,%s)) AS acl "
                          "EXCEPT "
-                         "SELECT unnest(pip.initprivs)) as foo) END",
+                         "SELECT pg_catalog.unnest(pip.initprivs)) as foo) END",
                          obj_kind,
                          acl_owner);
    }
index 1267afbce9a7c62488ab28b231b600e1952ccfd6..2848fa995f15d1356910c3a80f3c6cc711aac7c3 100644 (file)
@@ -2825,8 +2825,8 @@ getBlobs(Archive *fout)
                          "%s AS initrlomacl "
                          "FROM pg_largeobject_metadata l "
                          "LEFT JOIN pg_init_privs pip ON "
-                         "(l.oid = pip.objoid AND pip.classoid = "
-               "(SELECT oid FROM pg_class WHERE relname = 'pg_largeobject')"
+                         "(l.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_largeobject'::regclass "
                          "AND pip.objsubid = 0) ",
                          username_subquery,
                          acl_subquery->data,
@@ -3569,8 +3569,8 @@ getNamespaces(Archive *fout, int *numNamespaces)
                          "%s as initrnspacl "
                          "FROM pg_namespace n "
                          "LEFT JOIN pg_init_privs pip "
-                         "ON (n.oid = pip.objoid AND pip.classoid = "
-                "(SELECT oid FROM pg_class WHERE relname = 'pg_namespace') "
+                         "ON (n.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_namespace'::regclass "
                          "AND pip.objsubid = 0) ",
                          username_subquery,
                          acl_subquery->data,
@@ -3851,9 +3851,9 @@ getTypes(Archive *fout, int *numTypes)
                          "t.typname[0] = '_' AND t.typelem != 0 AND "
                          "(SELECT typarray FROM pg_type te WHERE oid = t.typelem) = t.oid AS isarray "
                          "FROM pg_type t "
-                         "LEFT JOIN pg_init_privs pip "
-                         "ON (t.oid = pip.objoid AND pip.classoid = "
-                     "(SELECT oid FROM pg_class WHERE relname = 'pg_type') "
+                         "LEFT JOIN pg_init_privs pip ON "
+                         "(t.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_type'::regclass "
                          "AND pip.objsubid = 0) ",
                          acl_subquery->data,
                          racl_subquery->data,
@@ -4713,8 +4713,8 @@ getAggregates(Archive *fout, int *numAggs)
                          "%s AS initraggacl "
                          "FROM pg_proc p "
                          "LEFT JOIN pg_init_privs pip ON "
-                         "(p.oid = pip.objoid AND pip.classoid = "
-                     "(SELECT oid FROM pg_class WHERE relname = 'pg_proc') "
+                         "(p.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_proc'::regclass "
                          "AND pip.objsubid = 0) "
                          "WHERE p.proisagg AND ("
                          "p.pronamespace != "
@@ -4956,8 +4956,8 @@ getFuncs(Archive *fout, int *numFuncs)
                          "(%s p.proowner) AS rolname "
                          "FROM pg_proc p "
                          "LEFT JOIN pg_init_privs pip ON "
-                         "(p.oid = pip.objoid AND pip.classoid = "
-                     "(SELECT oid FROM pg_class WHERE relname = 'pg_proc') "
+                         "(p.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_proc'::regclass "
                          "AND pip.objsubid = 0) "
                          "WHERE NOT proisagg "
                          "AND NOT EXISTS (SELECT 1 FROM pg_depend "
@@ -5246,9 +5246,10 @@ getTables(Archive *fout, int *numTables)
                          "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
                          "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
                          "tc.reloptions AS toast_reloptions, "
-                         "EXISTS (SELECT 1 FROM pg_attribute at LEFT JOIN pg_init_privs pip ON"
-                         "(c.oid = pip.objoid AND pip.classoid = "
-                         "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AND pip.objsubid = at.attnum)"
+                         "EXISTS (SELECT 1 FROM pg_attribute at LEFT JOIN pg_init_privs pip ON "
+                         "(c.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_class'::regclass "
+                         "AND pip.objsubid = at.attnum)"
                          "WHERE at.attrelid = c.oid AND ("
                          "%s IS NOT NULL "
                          "OR %s IS NOT NULL "
@@ -5264,9 +5265,9 @@ getTables(Archive *fout, int *numTables)
                          "d.refclassid = c.tableoid AND d.deptype = 'a') "
                       "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
                          "LEFT JOIN pg_init_privs pip ON "
-                         "(c.oid = pip.objoid AND pip.classoid = "
-                         "(SELECT oid FROM pg_class "
-                         "WHERE relname = 'pg_class') AND pip.objsubid = 0) "
+                         "(c.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_class'::regclass "
+                         "AND pip.objsubid = 0) "
                   "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
                          "ORDER BY c.oid",
                          acl_subquery->data,
@@ -7163,9 +7164,9 @@ getProcLangs(Archive *fout, int *numProcLangs)
                          "%s AS initrlanacl, "
                          "(%s l.lanowner) AS lanowner "
                          "FROM pg_language l "
-                         "LEFT JOIN pg_init_privs pip "
-                         "ON (l.oid = pip.objoid AND pip.classoid = "
-                     "(SELECT oid FROM pg_class WHERE relname = 'pg_type') "
+                         "LEFT JOIN pg_init_privs pip ON "
+                         "(l.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_type'::regclass "
                          "AND pip.objsubid = 0) "
                          "WHERE l.lanispl "
                          "ORDER BY l.oid",
@@ -8583,9 +8584,9 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
                          "ORDER BY option_name"
                          "), E',\n    ') AS fdwoptions "
                          "FROM pg_foreign_data_wrapper f "
-                         "LEFT JOIN pg_init_privs pip "
-                         "ON (f.oid = pip.objoid AND pip.classoid = "
-                         "(SELECT oid FROM pg_class WHERE relname = 'pg_foreign_data_wrapper') "
+                         "LEFT JOIN pg_init_privs pip ON "
+                         "(f.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_foreign_data_wrapper'::regclass "
                          "AND pip.objsubid = 0) ",
                          username_subquery,
                          acl_subquery->data,
@@ -8753,8 +8754,8 @@ getForeignServers(Archive *fout, int *numForeignServers)
                          "), E',\n    ') AS srvoptions "
                          "FROM pg_foreign_server f "
                          "LEFT JOIN pg_init_privs pip "
-                         "ON (f.oid = pip.objoid AND pip.classoid = "
-           "(SELECT oid FROM pg_class WHERE relname = 'pg_foreign_server') "
+                         "ON (f.oid = pip.objoid "
+                         "AND pip.classoid = 'pg_foreign_server'::regclass "
                          "AND pip.objsubid = 0) ",
                          username_subquery,
                          acl_subquery->data,
@@ -14600,13 +14601,13 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
     */
    if (strlen(initacls) != 0 || strlen(initracls) != 0)
    {
-       appendPQExpBuffer(sql, "SELECT binary_upgrade_set_record_init_privs(true);\n");
+       appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
        if (!buildACLCommands(name, subname, type, initacls, initracls, owner,
                              "", fout->remoteVersion, sql))
            exit_horribly(NULL,
                          "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n",
                          initacls, initracls, name, type);
-       appendPQExpBuffer(sql, "SELECT binary_upgrade_set_record_init_privs(false);\n");
+       appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
    }
 
    if (!buildACLCommands(name, subname, type, acls, racls, owner,
@@ -14992,11 +14993,11 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                              "%s AS initrattacl "
                              "FROM pg_catalog.pg_attribute at "
                       "JOIN pg_catalog.pg_class c ON (at.attrelid = c.oid) "
-                             "LEFT JOIN pg_init_privs pip ON "
-                             "(pip.classoid = "
-                "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AND "
-                  " at.attrelid = pip.objoid AND at.attnum = pip.objsubid) "
-                             "WHERE at.attrelid = '%u' AND "
+                             "LEFT JOIN pg_catalog.pg_init_privs pip ON "
+                             "(at.attrelid = pip.objoid "
+             "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
+                             "AND at.attnum = pip.objsubid) "
+                             "WHERE at.attrelid = '%u'::pg_catalog.oid AND "
                              "NOT at.attisdropped "
                              "AND ("
                              "%s IS NOT NULL OR "
@@ -15025,7 +15026,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                              "SELECT attname, attacl, NULL as rattacl, "
                              "NULL AS initattacl, NULL AS initrattacl "
                              "FROM pg_catalog.pg_attribute "
-                             "WHERE attrelid = '%u' AND NOT attisdropped "
+                             "WHERE attrelid = '%u'::pg_catalog.oid AND NOT attisdropped "
                              "AND attacl IS NOT NULL "
                              "ORDER BY attnum",
                              tbinfo->dobj.catId.oid);
index 9a65da1d6aeb0b4ecdab68be61fe4835bb22db1c..2177df8bba443c1355dfde2546cf9f8a367e63f9 100644 (file)
@@ -340,9 +340,9 @@ my %tests = (
    },
    'GRANT SELECT ON TABLE regress_pg_dump_table' => {
        regexp => qr/^
-           \QSELECT binary_upgrade_set_record_init_privs(true);\E\n
+           \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
            \QGRANT SELECT ON TABLE regress_pg_dump_table TO dump_test;\E\n
-           \QSELECT binary_upgrade_set_record_init_privs(false);\E
+           \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
            $/xms,
        like => {
            binary_upgrade => 1,
@@ -362,9 +362,9 @@ my %tests = (
    },
    'GRANT SELECT(col1) ON regress_pg_dump_table' => {
        regexp => qr/^
-           \QSELECT binary_upgrade_set_record_init_privs(true);\E\n
+           \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
            \QGRANT SELECT(col1) ON TABLE regress_pg_dump_table TO PUBLIC;\E\n
-           \QSELECT binary_upgrade_set_record_init_privs(false);\E
+           \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
            $/xms,
        like => {
            binary_upgrade => 1,