Skip to content

Commit 860204a

Browse files
author
Commitfest Bot
committed
[CF 6054] v2 - let ALTER COLUMN SET DATA TYPE cope with POLICY dependency
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/6054 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/CACJufxGPcBzdL9T6Qh=OFecN8zqxuU0QXfYF8F3WYV=uzwYCdA@mail.gmail.com Author(s): Jian He
2 parents 454c046 + 5098277 commit 860204a

File tree

13 files changed

+546
-55
lines changed

13 files changed

+546
-55
lines changed

src/backend/commands/policy.c

Lines changed: 77 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@
2424
#include "catalog/namespace.h"
2525
#include "catalog/objectaccess.h"
2626
#include "catalog/pg_authid.h"
27+
#include "catalog/pg_depend.h"
2728
#include "catalog/pg_policy.h"
2829
#include "catalog/pg_type.h"
30+
#include "commands/comment.h"
2931
#include "commands/policy.h"
3032
#include "miscadmin.h"
3133
#include "nodes/pg_list.h"
3234
#include "parser/parse_clause.h"
3335
#include "parser/parse_collate.h"
3436
#include "parser/parse_node.h"
3537
#include "parser/parse_relation.h"
38+
#include "parser/parse_utilcmd.h"
3639
#include "rewrite/rewriteManip.h"
3740
#include "rewrite/rowsecurity.h"
3841
#include "utils/acl.h"
@@ -566,7 +569,7 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
566569
* stmt - the CreatePolicyStmt that describes the policy to create.
567570
*/
568571
ObjectAddress
569-
CreatePolicy(CreatePolicyStmt *stmt)
572+
CreatePolicy(CreatePolicyStmt *stmt, const char *queryString)
570573
{
571574
Relation pg_policy_rel;
572575
Oid policy_id;
@@ -576,8 +579,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
576579
Datum *role_oids;
577580
int nitems = 0;
578581
ArrayType *role_ids;
579-
ParseState *qual_pstate;
580-
ParseState *with_check_pstate;
582+
ParseState *pstate;
581583
ParseNamespaceItem *nsitem;
582584
Node *qual;
583585
Node *with_check_qual;
@@ -615,10 +617,6 @@ CreatePolicy(CreatePolicyStmt *stmt)
615617
role_oids = policy_role_list_to_array(stmt->roles, &nitems);
616618
role_ids = construct_array_builtin(role_oids, nitems, OIDOID);
617619

618-
/* Parse the supplied clause */
619-
qual_pstate = make_parsestate(NULL);
620-
with_check_pstate = make_parsestate(NULL);
621-
622620
/* zero-clear */
623621
memset(values, 0, sizeof(values));
624622
memset(isnull, 0, sizeof(isnull));
@@ -628,35 +626,23 @@ CreatePolicy(CreatePolicyStmt *stmt)
628626
0,
629627
RangeVarCallbackForPolicy,
630628
stmt);
629+
if (!stmt->transformed)
630+
stmt = transformPolicyStmt(table_id, stmt, queryString);
631631

632-
/* Open target_table to build quals. No additional lock is necessary. */
633-
target_table = relation_open(table_id, NoLock);
632+
qual = stmt->qual;
633+
with_check_qual = stmt->with_check;
634634

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);
635+
/* we'll need the pstate->rtable for recordDependencyOnExpr */
636+
pstate = make_parsestate(NULL);
637+
pstate->p_sourcetext = queryString;
640638

641-
/* Add for the with-check quals */
642-
nsitem = addRangeTableEntryForRelation(with_check_pstate, target_table,
639+
/* No additional lock is necessary. */
640+
target_table = relation_open(table_id, NoLock);
641+
642+
nsitem = addRangeTableEntryForRelation(pstate, target_table,
643643
AccessShareLock,
644644
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);
645+
addNSItemToQuery(pstate, nsitem, false, true, true);
660646

661647
/* Open pg_policy catalog */
662648
pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock);
@@ -724,11 +710,11 @@ CreatePolicy(CreatePolicyStmt *stmt)
724710

725711
recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
726712

727-
recordDependencyOnExpr(&myself, qual, qual_pstate->p_rtable,
713+
recordDependencyOnExpr(&myself, qual, pstate->p_rtable,
728714
DEPENDENCY_NORMAL);
729715

730716
recordDependencyOnExpr(&myself, with_check_qual,
731-
with_check_pstate->p_rtable, DEPENDENCY_NORMAL);
717+
pstate->p_rtable, DEPENDENCY_NORMAL);
732718

733719
/* Register role dependencies */
734720
target.classId = AuthIdRelationId;
@@ -749,12 +735,16 @@ CreatePolicy(CreatePolicyStmt *stmt)
749735

750736
/* Clean up. */
751737
heap_freetuple(policy_tuple);
752-
free_parsestate(qual_pstate);
753-
free_parsestate(with_check_pstate);
738+
free_parsestate(pstate);
754739
systable_endscan(sscan);
755740
relation_close(target_table, NoLock);
756741
table_close(pg_policy_rel, RowExclusiveLock);
757742

743+
/* Add any requested comment */
744+
if (stmt->polcomment != NULL)
745+
CreateComments(policy_id, PolicyRelationId, 0,
746+
stmt->polcomment);
747+
758748
return myself;
759749
}
760750

@@ -1277,3 +1267,55 @@ relation_has_policies(Relation rel)
12771267

12781268
return ret;
12791269
}
1270+
1271+
/*
1272+
* PoliciesGetRelations -
1273+
* Collect all relations this policy depends on.
1274+
* The policy's check qual or qual may reference other relations, we include
1275+
* those as well.
1276+
*/
1277+
List *
1278+
PoliciesGetRelations(Oid policyId)
1279+
{
1280+
List *result = NIL;
1281+
Relation depRel;
1282+
ScanKeyData key[2];
1283+
SysScanDesc depScan;
1284+
HeapTuple depTup;
1285+
1286+
/*
1287+
* We scan pg_depend to find those things that policy being depended on.
1288+
*/
1289+
depRel = table_open(DependRelationId, AccessShareLock);
1290+
1291+
ScanKeyInit(&key[0],
1292+
Anum_pg_depend_classid,
1293+
BTEqualStrategyNumber, F_OIDEQ,
1294+
ObjectIdGetDatum(PolicyRelationId));
1295+
ScanKeyInit(&key[1],
1296+
Anum_pg_depend_objid,
1297+
BTEqualStrategyNumber, F_OIDEQ,
1298+
ObjectIdGetDatum(policyId));
1299+
1300+
depScan = systable_beginscan(depRel, DependDependerIndexId, true,
1301+
NULL, 2, key);
1302+
while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
1303+
{
1304+
Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
1305+
1306+
/* Prepend oid of the relation with this policy. */
1307+
if (pg_depend->refclassid == RelationRelationId)
1308+
{
1309+
if (pg_depend->deptype == DEPENDENCY_AUTO)
1310+
result = lcons_oid(pg_depend->refobjid, result);
1311+
else
1312+
result = lappend_oid(result, pg_depend->refobjid);
1313+
}
1314+
}
1315+
systable_endscan(depScan);
1316+
1317+
relation_close(depRel, AccessShareLock);
1318+
1319+
Assert(result != NIL);
1320+
return result;
1321+
}

0 commit comments

Comments
 (0)