@@ -3619,6 +3619,7 @@ void
3619
3619
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3620
3620
{
3621
3621
PQExpBuffer query;
3622
+ PQExpBuffer tbloids;
3622
3623
PGresult *res;
3623
3624
PolicyInfo *polinfo;
3624
3625
inti_oid;
@@ -3634,15 +3635,17 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3634
3635
j,
3635
3636
ntups;
3636
3637
3638
+ /* No policies before 9.5 */
3637
3639
if (fout->remoteVersion < 90500)
3638
3640
return;
3639
3641
3640
3642
query = createPQExpBuffer();
3643
+ tbloids = createPQExpBuffer();
3641
3644
3642
3645
/*
3643
- * First, check which tables have RLS enabled. We represent RLS being
3644
- * enabled on a table by creating a PolicyInfo object with null polname.
3646
+ * Identify tables of interest, and check which ones have RLS enabled.
3645
3647
*/
3648
+ appendPQExpBufferChar(tbloids, '{');
3646
3649
for (i = 0; i < numTables; i++)
3647
3650
{
3648
3651
TableInfo *tbinfo = &tblinfo[i];
@@ -3651,9 +3654,23 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3651
3654
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3652
3655
continue;
3653
3656
3657
+ /* It can't have RLS or policies if it's not a table */
3658
+ if (tbinfo->relkind != RELKIND_RELATION &&
3659
+ tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3660
+ continue;
3661
+
3662
+ /* Add it to the list of table OIDs to be probed below */
3663
+ if (tbloids->len > 1)/* do we have more than the '{'? */
3664
+ appendPQExpBufferChar(tbloids, ',');
3665
+ appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3666
+
3667
+ /* Is RLS enabled? (That's separate from whether it has policies) */
3654
3668
if (tbinfo->rowsec)
3655
3669
{
3656
3670
/*
3671
+ * We represent RLS being enabled on a table by creating a
3672
+ * PolicyInfo object with null polname.
3673
+ *
3657
3674
* Note: use tableoid 0 so that this object won't be mistaken for
3658
3675
* something that pg_depend entries apply to.
3659
3676
*/
@@ -3673,15 +3690,18 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3673
3690
polinfo->polwithcheck = NULL;
3674
3691
}
3675
3692
}
3693
+ appendPQExpBufferChar(tbloids, '}');
3676
3694
3677
3695
/*
3678
- * Now, read all RLS policies, and create PolicyInfo objects for all those
3679
- * that are of interest.
3696
+ * Now, read all RLS policies belonging to the tables of interest, and
3697
+ * create PolicyInfo objects for them. (Note that we must filter the
3698
+ * results server-side not locally, because we dare not apply pg_get_expr
3699
+ * to tables we don't have lock on.)
3680
3700
*/
3681
3701
pg_log_info("reading row-level security policies");
3682
3702
3683
3703
printfPQExpBuffer(query,
3684
- "SELECT oid, tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3704
+ "SELECTpol. oid,pol. tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3685
3705
if (fout->remoteVersion >= 100000)
3686
3706
appendPQExpBuffer(query, "pol.polpermissive, ");
3687
3707
else
@@ -3691,7 +3711,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3691
3711
" pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
3692
3712
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3693
3713
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3694
- "FROM pg_catalog.pg_policy pol");
3714
+ "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3715
+ "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3716
+ tbloids->data);
3695
3717
3696
3718
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3697
3719
@@ -3715,13 +3737,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3715
3737
Oidpolrelid = atooid(PQgetvalue(res, j, i_polrelid));
3716
3738
TableInfo *tbinfo = findTableByOid(polrelid);
3717
3739
3718
- /*
3719
- * Ignore row security on tables not to be dumped. (This will
3720
- * result in some harmless wasted slots in polinfo[].)
3721
- */
3722
- if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3723
- continue;
3724
-
3725
3740
polinfo[j].dobj.objType = DO_POLICY;
3726
3741
polinfo[j].dobj.catId.tableoid =
3727
3742
atooid(PQgetvalue(res, j, i_tableoid));
@@ -3756,6 +3771,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3756
3771
PQclear(res);
3757
3772
3758
3773
destroyPQExpBuffer(query);
3774
+ destroyPQExpBuffer(tbloids);
3759
3775
}
3760
3776
3761
3777
/*