@@ -3549,6 +3549,7 @@ void
3549
3549
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3550
3550
{
3551
3551
PQExpBuffer query;
3552
+ PQExpBuffer tbloids;
3552
3553
PGresult *res;
3553
3554
PolicyInfo *polinfo;
3554
3555
inti_oid;
@@ -3564,15 +3565,17 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3564
3565
j,
3565
3566
ntups;
3566
3567
3568
+ /* No policies before 9.5 */
3567
3569
if (fout->remoteVersion < 90500)
3568
3570
return;
3569
3571
3570
3572
query = createPQExpBuffer();
3573
+ tbloids = createPQExpBuffer();
3571
3574
3572
3575
/*
3573
- * First, check which tables have RLS enabled. We represent RLS being
3574
- * enabled on a table by creating a PolicyInfo object with null polname.
3576
+ * Identify tables of interest, and check which ones have RLS enabled.
3575
3577
*/
3578
+ appendPQExpBufferChar(tbloids, '{');
3576
3579
for (i = 0; i < numTables; i++)
3577
3580
{
3578
3581
TableInfo *tbinfo = &tblinfo[i];
@@ -3581,9 +3584,23 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3581
3584
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3582
3585
continue;
3583
3586
3587
+ /* It can't have RLS or policies if it's not a table */
3588
+ if (tbinfo->relkind != RELKIND_RELATION &&
3589
+ tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3590
+ continue;
3591
+
3592
+ /* Add it to the list of table OIDs to be probed below */
3593
+ if (tbloids->len > 1)/* do we have more than the '{'? */
3594
+ appendPQExpBufferChar(tbloids, ',');
3595
+ appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3596
+
3597
+ /* Is RLS enabled? (That's separate from whether it has policies) */
3584
3598
if (tbinfo->rowsec)
3585
3599
{
3586
3600
/*
3601
+ * We represent RLS being enabled on a table by creating a
3602
+ * PolicyInfo object with null polname.
3603
+ *
3587
3604
* Note: use tableoid 0 so that this object won't be mistaken for
3588
3605
* something that pg_depend entries apply to.
3589
3606
*/
@@ -3603,15 +3620,18 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3603
3620
polinfo->polwithcheck = NULL;
3604
3621
}
3605
3622
}
3623
+ appendPQExpBufferChar(tbloids, '}');
3606
3624
3607
3625
/*
3608
- * Now, read all RLS policies, and create PolicyInfo objects for all those
3609
- * that are of interest.
3626
+ * Now, read all RLS policies belonging to the tables of interest, and
3627
+ * create PolicyInfo objects for them. (Note that we must filter the
3628
+ * results server-side not locally, because we dare not apply pg_get_expr
3629
+ * to tables we don't have lock on.)
3610
3630
*/
3611
3631
pg_log_info("reading row-level security policies");
3612
3632
3613
3633
printfPQExpBuffer(query,
3614
- "SELECT oid, tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3634
+ "SELECTpol. oid,pol. tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3615
3635
if (fout->remoteVersion >= 100000)
3616
3636
appendPQExpBuffer(query, "pol.polpermissive, ");
3617
3637
else
@@ -3621,7 +3641,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3621
3641
" 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, "
3622
3642
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3623
3643
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3624
- "FROM pg_catalog.pg_policy pol");
3644
+ "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3645
+ "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3646
+ tbloids->data);
3625
3647
3626
3648
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3627
3649
@@ -3645,13 +3667,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3645
3667
Oidpolrelid = atooid(PQgetvalue(res, j, i_polrelid));
3646
3668
TableInfo *tbinfo = findTableByOid(polrelid);
3647
3669
3648
- /*
3649
- * Ignore row security on tables not to be dumped. (This will
3650
- * result in some harmless wasted slots in polinfo[].)
3651
- */
3652
- if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3653
- continue;
3654
-
3655
3670
polinfo[j].dobj.objType = DO_POLICY;
3656
3671
polinfo[j].dobj.catId.tableoid =
3657
3672
atooid(PQgetvalue(res, j, i_tableoid));
@@ -3686,6 +3701,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3686
3701
PQclear(res);
3687
3702
3688
3703
destroyPQExpBuffer(query);
3704
+ destroyPQExpBuffer(tbloids);
3689
3705
}
3690
3706
3691
3707
/*