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,