@@ -3761,6 +3761,7 @@ void
3761
3761
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3762
3762
{
3763
3763
PQExpBuffer query;
3764
+ PQExpBuffer tbloids;
3764
3765
PGresult *res;
3765
3766
PolicyInfo *polinfo;
3766
3767
inti_oid;
@@ -3776,15 +3777,17 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3776
3777
j,
3777
3778
ntups;
3778
3779
3780
+ /* No policies before 9.5 */
3779
3781
if (fout->remoteVersion < 90500)
3780
3782
return;
3781
3783
3782
3784
query = createPQExpBuffer();
3785
+ tbloids = createPQExpBuffer();
3783
3786
3784
3787
/*
3785
- * First, check which tables have RLS enabled. We represent RLS being
3786
- * enabled on a table by creating a PolicyInfo object with null polname.
3788
+ * Identify tables of interest, and check which ones have RLS enabled.
3787
3789
*/
3790
+ appendPQExpBufferChar(tbloids, '{');
3788
3791
for (i = 0; i < numTables; i++)
3789
3792
{
3790
3793
TableInfo *tbinfo = &tblinfo[i];
@@ -3793,9 +3796,23 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3793
3796
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3794
3797
continue;
3795
3798
3799
+ /* It can't have RLS or policies if it's not a table */
3800
+ if (tbinfo->relkind != RELKIND_RELATION &&
3801
+ tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3802
+ continue;
3803
+
3804
+ /* Add it to the list of table OIDs to be probed below */
3805
+ if (tbloids->len > 1)/* do we have more than the '{'? */
3806
+ appendPQExpBufferChar(tbloids, ',');
3807
+ appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3808
+
3809
+ /* Is RLS enabled? (That's separate from whether it has policies) */
3796
3810
if (tbinfo->rowsec)
3797
3811
{
3798
3812
/*
3813
+ * We represent RLS being enabled on a table by creating a
3814
+ * PolicyInfo object with null polname.
3815
+ *
3799
3816
* Note: use tableoid 0 so that this object won't be mistaken for
3800
3817
* something that pg_depend entries apply to.
3801
3818
*/
@@ -3815,15 +3832,18 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3815
3832
polinfo->polwithcheck = NULL;
3816
3833
}
3817
3834
}
3835
+ appendPQExpBufferChar(tbloids, '}');
3818
3836
3819
3837
/*
3820
- * Now, read all RLS policies, and create PolicyInfo objects for all those
3821
- * that are of interest.
3838
+ * Now, read all RLS policies belonging to the tables of interest, and
3839
+ * create PolicyInfo objects for them. (Note that we must filter the
3840
+ * results server-side not locally, because we dare not apply pg_get_expr
3841
+ * to tables we don't have lock on.)
3822
3842
*/
3823
3843
pg_log_info("reading row-level security policies");
3824
3844
3825
3845
printfPQExpBuffer(query,
3826
- "SELECT oid, tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3846
+ "SELECTpol. oid,pol. tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3827
3847
if (fout->remoteVersion >= 100000)
3828
3848
appendPQExpBuffer(query, "pol.polpermissive, ");
3829
3849
else
@@ -3833,7 +3853,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3833
3853
" 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, "
3834
3854
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3835
3855
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3836
- "FROM pg_catalog.pg_policy pol");
3856
+ "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3857
+ "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3858
+ tbloids->data);
3837
3859
3838
3860
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3839
3861
@@ -3857,13 +3879,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3857
3879
Oidpolrelid = atooid(PQgetvalue(res, j, i_polrelid));
3858
3880
TableInfo *tbinfo = findTableByOid(polrelid);
3859
3881
3860
- /*
3861
- * Ignore row security on tables not to be dumped. (This will
3862
- * result in some harmless wasted slots in polinfo[].)
3863
- */
3864
- if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3865
- continue;
3866
-
3867
3882
polinfo[j].dobj.objType = DO_POLICY;
3868
3883
polinfo[j].dobj.catId.tableoid =
3869
3884
atooid(PQgetvalue(res, j, i_tableoid));
@@ -3898,6 +3913,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3898
3913
PQclear(res);
3899
3914
3900
3915
destroyPQExpBuffer(query);
3916
+ destroyPQExpBuffer(tbloids);
3901
3917
}
3902
3918
3903
3919
/*