Skip to content

Commit 6b41381

Browse files
author
Commitfest Bot
committed
[CF 6064] v1 - CREATE TABLE LIKE INCLUDING POLICIES
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/6064 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CACJufxFuEOB-i2z2qhyCG=dGwDf7g6Fs_o8cz=BUi76UuUFSOA@mail.gmail.com Author(s): Jian He
2 parents aaf0357 + 28b7d51 commit 6b41381

File tree

11 files changed

+475
-46
lines changed

11 files changed

+475
-46
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable cl
8888

8989
<phrase>and <replaceable class="parameter">like_option</replaceable> is:</phrase>
9090

91-
{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
91+
{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | POLICIES | STATISTICS | STORAGE | ALL }
9292

9393
<phrase>and <replaceable class="parameter">partition_bound_spec</replaceable> is:</phrase>
9494

@@ -672,9 +672,9 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
672672
<term><literal>INCLUDING COMMENTS</literal></term>
673673
<listitem>
674674
<para>
675-
Comments for the copied columns, constraints, and indexes will be
675+
Comments for the copied columns, constraints, policies, and indexes will be
676676
copied. The default behavior is to exclude comments, resulting in
677-
the copied columns and constraints in the new table having no
677+
the copied columns, policies, and constraints in the new table having no
678678
comments.
679679
</para>
680680
</listitem>
@@ -753,6 +753,18 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
753753
</listitem>
754754
</varlistentry>
755755

756+
<varlistentry id="sql-createtable-parms-like-opt-policies">
757+
<term><literal>INCLUDING POLICIES</literal></term>
758+
<listitem>
759+
<para>
760+
Any row-level security policies are copied to the new table.
761+
Note that row-level security is not enabled to the new table,
762+
using <command>ALTER TABLE ... ENABLE ROW LEVEL SECURITY</command>
763+
in order for created policies to be applied to the new table.
764+
</para>
765+
</listitem>
766+
</varlistentry>
767+
756768
<varlistentry id="sql-createtable-parms-like-opt-statistics">
757769
<term><literal>INCLUDING STATISTICS</literal></term>
758770
<listitem>

src/backend/commands/policy.c

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
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
*/
568570
ObjectAddress
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

src/backend/parser/gram.y

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
763763
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
764764

765765
PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH
766-
PERIOD PLACING PLAN PLANS POLICY
766+
PERIOD PLACING PLAN PLANS POLICIES POLICY
767767
POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
768768
PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
769769

@@ -4242,6 +4242,7 @@ TableLikeOption:
42424242
| IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; }
42434243
| GENERATED { $$ = CREATE_TABLE_LIKE_GENERATED; }
42444244
| INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }
4245+
| POLICIES { $$ = CREATE_TABLE_LIKE_POLICIES; }
42454246
| STATISTICS { $$ = CREATE_TABLE_LIKE_STATISTICS; }
42464247
| STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }
42474248
| ALL { $$ = CREATE_TABLE_LIKE_ALL; }
@@ -5976,6 +5977,9 @@ CreatePolicyStmt:
59765977
n->roles = $8;
59775978
n->qual = $9;
59785979
n->with_check = $10;
5980+
n->transformed = false;
5981+
n->policycomment = NULL;
5982+
n->rolesId = NIL;
59795983
$$ = (Node *) n;
59805984
}
59815985
;
@@ -18044,6 +18048,7 @@ unreserved_keyword:
1804418048
| PERIOD
1804518049
| PLAN
1804618050
| PLANS
18051+
| POLICIES
1804718052
| POLICY
1804818053
| PRECEDING
1804918054
| PREPARE
@@ -18675,6 +18680,7 @@ bare_label_keyword:
1867518680
| PLACING
1867618681
| PLAN
1867718682
| PLANS
18683+
| POLICIES
1867818684
| POLICY
1867918685
| POSITION
1868018686
| PRECEDING

0 commit comments

Comments
 (0)