diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index bf26488c510..96fbfc96e8e 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1841,10 +1841,21 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) if (node->withCheckOptionLists != NIL && mtstate->mt_num_partitions > 0) { List *wcoList; + PlanState *plan; - Assert(operation == CMD_INSERT); - resultRelInfo = mtstate->mt_partitions; + /* + * In case of INSERT on partitioned tables, there is only one plan. + * Likewise, there is only one WITH CHECK OPTIONS list, not one per + * partition. We make a copy of the WCO qual for each partition; note + * that, if there are SubPlans in there, they all end up attached to + * the one parent Plan node. + */ + Assert(operation == CMD_INSERT && + list_length(node->withCheckOptionLists) == 1 && + mtstate->mt_nplans == 1); wcoList = linitial(node->withCheckOptionLists); + plan = mtstate->mt_plans[0]; + resultRelInfo = mtstate->mt_partitions; for (i = 0; i < mtstate->mt_num_partitions; i++) { Relation partrel = resultRelInfo->ri_RelationDesc; @@ -1858,9 +1869,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) partrel, rel); foreach(ll, mapped_wcoList) { - WithCheckOption *wco = (WithCheckOption *) lfirst(ll); - ExprState *wcoExpr = ExecInitQual((List *) wco->qual, - mtstate->mt_plans[i]); + WithCheckOption *wco = castNode(WithCheckOption, lfirst(ll)); + ExprState *wcoExpr = ExecInitQual(castNode(List, wco->qual), + plan); wcoExprs = lappend(wcoExprs, wcoExpr); } diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out index d382a9f4cc1..e2ec961ad9c 100644 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -1327,6 +1327,14 @@ SELECT * FROM part_document ORDER by did; ERROR: query would be affected by row-level security policy for table "part_document" SELECT * FROM part_document_satire ORDER by did; ERROR: query would be affected by row-level security policy for table "part_document_satire" +-- Check behavior with a policy that uses a SubPlan not an InitPlan. +SET SESSION AUTHORIZATION regress_rls_alice; +SET row_security TO ON; +CREATE POLICY pp3 ON part_document AS RESTRICTIVE + USING ((SELECT dlevel <= seclv FROM uaccount WHERE pguser = current_user)); +SET SESSION AUTHORIZATION regress_rls_carol; +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3'); -- fail +ERROR: new row violates row-level security policy "pp3" for table "part_document" ----- Dependencies ----- SET SESSION AUTHORIZATION regress_rls_alice; SET row_security TO ON; diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index 80537ffcac7..3ce929320a2 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -450,6 +450,15 @@ SET row_security TO OFF; SELECT * FROM part_document ORDER by did; SELECT * FROM part_document_satire ORDER by did; +-- Check behavior with a policy that uses a SubPlan not an InitPlan. +SET SESSION AUTHORIZATION regress_rls_alice; +SET row_security TO ON; +CREATE POLICY pp3 ON part_document AS RESTRICTIVE + USING ((SELECT dlevel <= seclv FROM uaccount WHERE pguser = current_user)); + +SET SESSION AUTHORIZATION regress_rls_carol; +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3'); -- fail + ----- Dependencies ----- SET SESSION AUTHORIZATION regress_rls_alice; SET row_security TO ON;