@@ -3473,6 +3473,7 @@ void
3473
3473
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3474
3474
{
3475
3475
PQExpBuffer query;
3476
+ PQExpBuffer tbloids;
3476
3477
PGresult *res;
3477
3478
PolicyInfo *polinfo;
3478
3479
inti_oid;
@@ -3488,15 +3489,17 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3488
3489
j,
3489
3490
ntups;
3490
3491
3492
+ /* No policies before 9.5 */
3491
3493
if (fout->remoteVersion < 90500)
3492
3494
return;
3493
3495
3494
3496
query = createPQExpBuffer();
3497
+ tbloids = createPQExpBuffer();
3495
3498
3496
3499
/*
3497
- * First, check which tables have RLS enabled. We represent RLS being
3498
- * enabled on a table by creating a PolicyInfo object with null polname.
3500
+ * Identify tables of interest, and check which ones have RLS enabled.
3499
3501
*/
3502
+ appendPQExpBufferChar(tbloids, '{');
3500
3503
for (i = 0; i < numTables; i++)
3501
3504
{
3502
3505
TableInfo *tbinfo = &tblinfo[i];
@@ -3505,11 +3508,25 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3505
3508
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3506
3509
continue;
3507
3510
3511
+ /* It can't have RLS or policies if it's not a table */
3512
+ if (tbinfo->relkind != RELKIND_RELATION &&
3513
+ tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
3514
+ continue;
3515
+
3516
+ /* Add it to the list of table OIDs to be probed below */
3517
+ if (tbloids->len > 1)/* do we have more than the '{'? */
3518
+ appendPQExpBufferChar(tbloids, ',');
3519
+ appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
3520
+
3521
+ /* Is RLS enabled? (That's separate from whether it has policies) */
3508
3522
if (tbinfo->rowsec)
3509
3523
{
3510
3524
tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
3511
3525
3512
3526
/*
3527
+ * We represent RLS being enabled on a table by creating a
3528
+ * PolicyInfo object with null polname.
3529
+ *
3513
3530
* Note: use tableoid 0 so that this object won't be mistaken for
3514
3531
* something that pg_depend entries apply to.
3515
3532
*/
@@ -3529,15 +3546,18 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3529
3546
polinfo->polwithcheck = NULL;
3530
3547
}
3531
3548
}
3549
+ appendPQExpBufferChar(tbloids, '}');
3532
3550
3533
3551
/*
3534
- * Now, read all RLS policies, and create PolicyInfo objects for all those
3535
- * that are of interest.
3552
+ * Now, read all RLS policies belonging to the tables of interest, and
3553
+ * create PolicyInfo objects for them. (Note that we must filter the
3554
+ * results server-side not locally, because we dare not apply pg_get_expr
3555
+ * to tables we don't have lock on.)
3536
3556
*/
3537
3557
pg_log_info("reading row-level security policies");
3538
3558
3539
3559
printfPQExpBuffer(query,
3540
- "SELECT oid, tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3560
+ "SELECTpol. oid,pol. tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
3541
3561
if (fout->remoteVersion >= 100000)
3542
3562
appendPQExpBuffer(query, "pol.polpermissive, ");
3543
3563
else
@@ -3547,7 +3567,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3547
3567
" 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, "
3548
3568
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
3549
3569
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
3550
- "FROM pg_catalog.pg_policy pol");
3570
+ "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
3571
+ "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
3572
+ tbloids->data);
3551
3573
3552
3574
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
3553
3575
@@ -3571,13 +3593,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3571
3593
Oidpolrelid = atooid(PQgetvalue(res, j, i_polrelid));
3572
3594
TableInfo *tbinfo = findTableByOid(polrelid);
3573
3595
3574
- /*
3575
- * Ignore row security on tables not to be dumped. (This will
3576
- * result in some harmless wasted slots in polinfo[].)
3577
- */
3578
- if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
3579
- continue;
3580
-
3581
3596
tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
3582
3597
3583
3598
polinfo[j].dobj.objType = DO_POLICY;
@@ -3614,6 +3629,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
3614
3629
PQclear(res);
3615
3630
3616
3631
destroyPQExpBuffer(query);
3632
+ destroyPQExpBuffer(tbloids);
3617
3633
}
3618
3634
3619
3635
/*