2626#include "catalog/pg_authid.h"
2727#include "catalog/pg_policy.h"
2828#include "catalog/pg_type.h"
29+ #include "commands/comment.h"
2930#include "commands/policy.h"
3031#include "miscadmin.h"
3132#include "nodes/pg_list.h"
3233#include "parser/parse_clause.h"
3334#include "parser/parse_collate.h"
3435#include "parser/parse_node.h"
3536#include "parser/parse_relation.h"
37+ #include "parser/parse_utilcmd.h"
3638#include "rewrite/rewriteManip.h"
3739#include "rewrite/rowsecurity.h"
3840#include "utils/acl.h"
@@ -566,7 +568,7 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
566568 * stmt - the CreatePolicyStmt that describes the policy to create.
567569 */
568570ObjectAddress
569- CreatePolicy (CreatePolicyStmt * stmt )
571+ CreatePolicy (CreatePolicyStmt * stmt , const char * queryString )
570572{
571573 Relation pg_policy_rel ;
572574 Oid policy_id ;
@@ -576,8 +578,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
576578 Datum * role_oids ;
577579 int nitems = 0 ;
578580 ArrayType * role_ids ;
579- ParseState * qual_pstate ;
580- ParseState * with_check_pstate ;
581+ ParseState * pstate ;
581582 ParseNamespaceItem * nsitem ;
582583 Node * qual ;
583584 Node * with_check_qual ;
@@ -612,12 +613,22 @@ CreatePolicy(CreatePolicyStmt *stmt)
612613 errmsg ("only WITH CHECK expression allowed for INSERT" )));
613614
614615 /* Collect role ids */
615- role_oids = policy_role_list_to_array (stmt -> roles , & nitems );
616- role_ids = construct_array_builtin (role_oids , nitems , OIDOID );
616+ if (stmt -> roles != NIL )
617+ {
618+ role_oids = policy_role_list_to_array (stmt -> roles , & nitems );
619+ role_ids = construct_array_builtin (role_oids , nitems , OIDOID );
620+ }
621+ else
622+ {
623+ Assert (stmt -> rolesId != NIL );
624+ nitems = list_length (stmt -> rolesId );
625+
626+ role_oids = (Datum * ) palloc (nitems * sizeof (Datum ));
627+ foreach_oid (roleoid , stmt -> rolesId )
628+ role_oids [foreach_current_index (roleoid )] = ObjectIdGetDatum (roleoid );
617629
618- /* Parse the supplied clause */
619- qual_pstate = make_parsestate (NULL );
620- with_check_pstate = make_parsestate (NULL );
630+ role_ids = construct_array_builtin (role_oids , nitems , OIDOID );
631+ }
621632
622633 /* zero-clear */
623634 memset (values , 0 , sizeof (values ));
@@ -628,35 +639,23 @@ CreatePolicy(CreatePolicyStmt *stmt)
628639 0 ,
629640 RangeVarCallbackForPolicy ,
630641 stmt );
642+ if (!stmt -> transformed )
643+ stmt = transformPolicyStmt (table_id , stmt , queryString );
631644
632- /* Open target_table to build quals. No additional lock is necessary. */
633- target_table = relation_open ( table_id , NoLock ) ;
645+ qual = stmt -> qual ;
646+ with_check_qual = stmt -> with_check ;
634647
635- /* Add for the regular security quals */
636- nsitem = addRangeTableEntryForRelation (qual_pstate , target_table ,
637- AccessShareLock ,
638- NULL , false, false);
639- addNSItemToQuery (qual_pstate , nsitem , false, true, true);
648+ /* we'll need the pstate->rtable for recordDependencyOnExpr */
649+ pstate = make_parsestate (NULL );
650+ pstate -> p_sourcetext = queryString ;
651+
652+ /* No additional lock is necessary. */
653+ target_table = relation_open (table_id , NoLock );
640654
641- /* Add for the with-check quals */
642- nsitem = addRangeTableEntryForRelation (with_check_pstate , target_table ,
655+ nsitem = addRangeTableEntryForRelation (pstate , target_table ,
643656 AccessShareLock ,
644657 NULL , false, false);
645- addNSItemToQuery (with_check_pstate , nsitem , false, true, true);
646-
647- qual = transformWhereClause (qual_pstate ,
648- stmt -> qual ,
649- EXPR_KIND_POLICY ,
650- "POLICY" );
651-
652- with_check_qual = transformWhereClause (with_check_pstate ,
653- stmt -> with_check ,
654- EXPR_KIND_POLICY ,
655- "POLICY" );
656-
657- /* Fix up collation information */
658- assign_expr_collations (qual_pstate , qual );
659- assign_expr_collations (with_check_pstate , with_check_qual );
658+ addNSItemToQuery (pstate , nsitem , false, true, true);
660659
661660 /* Open pg_policy catalog */
662661 pg_policy_rel = table_open (PolicyRelationId , RowExclusiveLock );
@@ -724,11 +723,11 @@ CreatePolicy(CreatePolicyStmt *stmt)
724723
725724 recordDependencyOn (& myself , & target , DEPENDENCY_AUTO );
726725
727- recordDependencyOnExpr (& myself , qual , qual_pstate -> p_rtable ,
726+ recordDependencyOnExpr (& myself , qual , pstate -> p_rtable ,
728727 DEPENDENCY_NORMAL );
729728
730729 recordDependencyOnExpr (& myself , with_check_qual ,
731- with_check_pstate -> p_rtable , DEPENDENCY_NORMAL );
730+ pstate -> p_rtable , DEPENDENCY_NORMAL );
732731
733732 /* Register role dependencies */
734733 target .classId = AuthIdRelationId ;
@@ -749,12 +748,16 @@ CreatePolicy(CreatePolicyStmt *stmt)
749748
750749 /* Clean up. */
751750 heap_freetuple (policy_tuple );
752- free_parsestate (qual_pstate );
753- free_parsestate (with_check_pstate );
751+ free_parsestate (pstate );
754752 systable_endscan (sscan );
755753 relation_close (target_table , NoLock );
756754 table_close (pg_policy_rel , RowExclusiveLock );
757755
756+ /* Add any requested comment */
757+ if (stmt -> policycomment != NULL )
758+ CreateComments (policy_id , PolicyRelationId , 0 ,
759+ stmt -> policycomment );
760+
758761 return myself ;
759762}
760763
0 commit comments