PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
policy.h File Reference
Include dependency graph for policy.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void RelationBuildRowSecurity (Relation relation)
 
void RemovePolicyById (Oid policy_id)
 
bool RemoveRoleFromObjectPolicy (Oid roleid, Oid classid, Oid objid)
 
ObjectAddress CreatePolicy (CreatePolicyStmt *stmt)
 
ObjectAddress AlterPolicy (AlterPolicyStmt *stmt)
 
Oid get_relation_policy_oid (Oid relid, const char *policy_name, bool missing_ok)
 
ObjectAddress rename_policy (RenameStmt *stmt)
 
bool relation_has_policies (Relation rel)
 

Function Documentation

ObjectAddress AlterPolicy ( AlterPolicyStmt stmt)

Definition at line 878 of file policy.c.

References AccessExclusiveLock, ACL_DELETE_CHR, ACL_ID_PUBLIC, ACL_INSERT_CHR, ACL_SELECT_CHR, addRangeTableEntryForRelation(), addRTEtoQuery(), Anum_pg_policy_polcmd, Anum_pg_policy_polname, Anum_pg_policy_polqual, Anum_pg_policy_polrelid, Anum_pg_policy_polroles, Anum_pg_policy_polwithcheck, ARR_DATA_PTR, ARR_DIMS, Assert, assign_expr_collations(), AuthIdRelationId, BTEqualStrategyNumber, CacheInvalidateRelcache(), CatalogTupleUpdate(), ObjectAddress::classId, construct_array(), copyObject, CStringGetDatum, CStringGetTextDatum, DatumGetArrayTypePCopy, DatumGetChar, DatumGetObjectId, deleteDependencyRecordsFor(), deleteSharedDependencyRecordsFor(), DEPENDENCY_AUTO, DEPENDENCY_NORMAL, ereport, errcode(), errmsg(), ERROR, EXPR_KIND_POLICY, free_parsestate(), heap_close, heap_freetuple(), heap_getattr, heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, InvokeObjectPostAlterHook, make_parsestate(), Natts_pg_policy, NIL, nodeToString(), NoLock, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OIDOID, ParseState::p_rtable, palloc(), PointerGetDatum, AlterPolicyStmt::policy_name, policy_role_list_to_array(), PolicyPolrelidPolnameIndexId, PolicyRelationId, AlterPolicyStmt::qual, RangeVarCallbackForPolicy(), RangeVarGetRelidExtended(), recordDependencyOn(), recordDependencyOnExpr(), recordSharedDependencyOn(), relation_close(), relation_open(), RelationGetDescr, RelationGetRelationName, RelationRelationId, AlterPolicyStmt::roles, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_POLICY, stringToNode(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, AlterPolicyStmt::table, TextDatumGetCString, transformWhereClause(), values, and AlterPolicyStmt::with_check.

Referenced by ProcessUtilitySlow().

879 {
880  Relation pg_policy_rel;
881  Oid policy_id;
882  Relation target_table;
883  Oid table_id;
884  Datum *role_oids = NULL;
885  int nitems = 0;
886  ArrayType *role_ids = NULL;
887  List *qual_parse_rtable = NIL;
888  List *with_check_parse_rtable = NIL;
889  Node *qual = NULL;
890  Node *with_check_qual = NULL;
891  ScanKeyData skey[2];
892  SysScanDesc sscan;
893  HeapTuple policy_tuple;
894  HeapTuple new_tuple;
896  bool isnull[Natts_pg_policy];
897  bool replaces[Natts_pg_policy];
898  ObjectAddress target;
899  ObjectAddress myself;
900  Datum polcmd_datum;
901  char polcmd;
902  bool polcmd_isnull;
903  int i;
904 
905  /* Parse role_ids */
906  if (stmt->roles != NULL)
907  {
908  role_oids = policy_role_list_to_array(stmt->roles, &nitems);
909  role_ids = construct_array(role_oids, nitems, OIDOID,
910  sizeof(Oid), true, 'i');
911  }
912 
913  /* Get id of table. Also handles permissions checks. */
915  false, false,
917  (void *) stmt);
918 
919  target_table = relation_open(table_id, NoLock);
920 
921  /* Parse the using policy clause */
922  if (stmt->qual)
923  {
924  RangeTblEntry *rte;
925  ParseState *qual_pstate = make_parsestate(NULL);
926 
927  rte = addRangeTableEntryForRelation(qual_pstate, target_table,
928  NULL, false, false);
929 
930  addRTEtoQuery(qual_pstate, rte, false, true, true);
931 
932  qual = transformWhereClause(qual_pstate, copyObject(stmt->qual),
934  "POLICY");
935 
936  /* Fix up collation information */
937  assign_expr_collations(qual_pstate, qual);
938 
939  qual_parse_rtable = qual_pstate->p_rtable;
940  free_parsestate(qual_pstate);
941  }
942 
943  /* Parse the with-check policy clause */
944  if (stmt->with_check)
945  {
946  RangeTblEntry *rte;
947  ParseState *with_check_pstate = make_parsestate(NULL);
948 
949  rte = addRangeTableEntryForRelation(with_check_pstate, target_table,
950  NULL, false, false);
951 
952  addRTEtoQuery(with_check_pstate, rte, false, true, true);
953 
954  with_check_qual = transformWhereClause(with_check_pstate,
955  copyObject(stmt->with_check),
957  "POLICY");
958 
959  /* Fix up collation information */
960  assign_expr_collations(with_check_pstate, with_check_qual);
961 
962  with_check_parse_rtable = with_check_pstate->p_rtable;
963  free_parsestate(with_check_pstate);
964  }
965 
966  /* zero-clear */
967  memset(values, 0, sizeof(values));
968  memset(replaces, 0, sizeof(replaces));
969  memset(isnull, 0, sizeof(isnull));
970 
971  /* Find policy to update. */
972  pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
973 
974  /* Set key - policy's relation id. */
975  ScanKeyInit(&skey[0],
977  BTEqualStrategyNumber, F_OIDEQ,
978  ObjectIdGetDatum(table_id));
979 
980  /* Set key - policy's name. */
981  ScanKeyInit(&skey[1],
983  BTEqualStrategyNumber, F_NAMEEQ,
985 
986  sscan = systable_beginscan(pg_policy_rel,
988  skey);
989 
990  policy_tuple = systable_getnext(sscan);
991 
992  /* Check that the policy is found, raise an error if not. */
993  if (!HeapTupleIsValid(policy_tuple))
994  ereport(ERROR,
995  (errcode(ERRCODE_UNDEFINED_OBJECT),
996  errmsg("policy \"%s\" for table \"%s\" does not exist",
997  stmt->policy_name,
998  RelationGetRelationName(target_table))));
999 
1000  /* Get policy command */
1001  polcmd_datum = heap_getattr(policy_tuple, Anum_pg_policy_polcmd,
1002  RelationGetDescr(pg_policy_rel),
1003  &polcmd_isnull);
1004  Assert(!polcmd_isnull);
1005  polcmd = DatumGetChar(polcmd_datum);
1006 
1007  /*
1008  * If the command is SELECT or DELETE then WITH CHECK should be NULL.
1009  */
1010  if ((polcmd == ACL_SELECT_CHR || polcmd == ACL_DELETE_CHR)
1011  && stmt->with_check != NULL)
1012  ereport(ERROR,
1013  (errcode(ERRCODE_SYNTAX_ERROR),
1014  errmsg("only USING expression allowed for SELECT, DELETE")));
1015 
1016  /*
1017  * If the command is INSERT then WITH CHECK should be the only expression
1018  * provided.
1019  */
1020  if ((polcmd == ACL_INSERT_CHR)
1021  && stmt->qual != NULL)
1022  ereport(ERROR,
1023  (errcode(ERRCODE_SYNTAX_ERROR),
1024  errmsg("only WITH CHECK expression allowed for INSERT")));
1025 
1026  policy_id = HeapTupleGetOid(policy_tuple);
1027 
1028  if (role_ids != NULL)
1029  {
1030  replaces[Anum_pg_policy_polroles - 1] = true;
1031  values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
1032  }
1033  else
1034  {
1035  Oid *roles;
1036  Datum roles_datum;
1037  bool attr_isnull;
1038  ArrayType *policy_roles;
1039 
1040  /*
1041  * We need to pull the set of roles this policy applies to from what's
1042  * in the catalog, so that we can recreate the dependencies correctly
1043  * for the policy.
1044  */
1045 
1046  roles_datum = heap_getattr(policy_tuple, Anum_pg_policy_polroles,
1047  RelationGetDescr(pg_policy_rel),
1048  &attr_isnull);
1049  Assert(!attr_isnull);
1050 
1051  policy_roles = DatumGetArrayTypePCopy(roles_datum);
1052 
1053  roles = (Oid *) ARR_DATA_PTR(policy_roles);
1054 
1055  nitems = ARR_DIMS(policy_roles)[0];
1056 
1057  role_oids = (Datum *) palloc(nitems * sizeof(Datum));
1058 
1059  for (i = 0; i < nitems; i++)
1060  role_oids[i] = ObjectIdGetDatum(roles[i]);
1061  }
1062 
1063  if (qual != NULL)
1064  {
1065  replaces[Anum_pg_policy_polqual - 1] = true;
1066  values[Anum_pg_policy_polqual - 1]
1068  }
1069  else
1070  {
1071  Datum value_datum;
1072  bool attr_isnull;
1073 
1074  /*
1075  * We need to pull the USING expression and build the range table for
1076  * the policy from what's in the catalog, so that we can recreate the
1077  * dependencies correctly for the policy.
1078  */
1079 
1080  /* Check if the policy has a USING expr */
1081  value_datum = heap_getattr(policy_tuple, Anum_pg_policy_polqual,
1082  RelationGetDescr(pg_policy_rel),
1083  &attr_isnull);
1084  if (!attr_isnull)
1085  {
1086  char *qual_value;
1087  ParseState *qual_pstate;
1088 
1089  /* parsestate is built just to build the range table */
1090  qual_pstate = make_parsestate(NULL);
1091 
1092  qual_value = TextDatumGetCString(value_datum);
1093  qual = stringToNode(qual_value);
1094 
1095  /* Add this rel to the parsestate's rangetable, for dependencies */
1096  addRangeTableEntryForRelation(qual_pstate, target_table, NULL,
1097  false, false);
1098 
1099  qual_parse_rtable = qual_pstate->p_rtable;
1100  free_parsestate(qual_pstate);
1101  }
1102  }
1103 
1104  if (with_check_qual != NULL)
1105  {
1106  replaces[Anum_pg_policy_polwithcheck - 1] = true;
1107  values[Anum_pg_policy_polwithcheck - 1]
1108  = CStringGetTextDatum(nodeToString(with_check_qual));
1109  }
1110  else
1111  {
1112  Datum value_datum;
1113  bool attr_isnull;
1114 
1115  /*
1116  * We need to pull the WITH CHECK expression and build the range table
1117  * for the policy from what's in the catalog, so that we can recreate
1118  * the dependencies correctly for the policy.
1119  */
1120 
1121  /* Check if the policy has a WITH CHECK expr */
1122  value_datum = heap_getattr(policy_tuple, Anum_pg_policy_polwithcheck,
1123  RelationGetDescr(pg_policy_rel),
1124  &attr_isnull);
1125  if (!attr_isnull)
1126  {
1127  char *with_check_value;
1128  ParseState *with_check_pstate;
1129 
1130  /* parsestate is built just to build the range table */
1131  with_check_pstate = make_parsestate(NULL);
1132 
1133  with_check_value = TextDatumGetCString(value_datum);
1134  with_check_qual = stringToNode(with_check_value);
1135 
1136  /* Add this rel to the parsestate's rangetable, for dependencies */
1137  addRangeTableEntryForRelation(with_check_pstate, target_table, NULL,
1138  false, false);
1139 
1140  with_check_parse_rtable = with_check_pstate->p_rtable;
1141  free_parsestate(with_check_pstate);
1142  }
1143  }
1144 
1145  new_tuple = heap_modify_tuple(policy_tuple,
1146  RelationGetDescr(pg_policy_rel),
1147  values, isnull, replaces);
1148  CatalogTupleUpdate(pg_policy_rel, &new_tuple->t_self, new_tuple);
1149 
1150  /* Update Dependencies. */
1151  deleteDependencyRecordsFor(PolicyRelationId, policy_id, false);
1152 
1153  /* Record Dependencies */
1154  target.classId = RelationRelationId;
1155  target.objectId = table_id;
1156  target.objectSubId = 0;
1157 
1158  myself.classId = PolicyRelationId;
1159  myself.objectId = policy_id;
1160  myself.objectSubId = 0;
1161 
1162  recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
1163 
1164  recordDependencyOnExpr(&myself, qual, qual_parse_rtable, DEPENDENCY_NORMAL);
1165 
1166  recordDependencyOnExpr(&myself, with_check_qual, with_check_parse_rtable,
1168 
1169  /* Register role dependencies */
1171  target.classId = AuthIdRelationId;
1172  target.objectSubId = 0;
1173  for (i = 0; i < nitems; i++)
1174  {
1175  target.objectId = DatumGetObjectId(role_oids[i]);
1176  /* no dependency if public */
1177  if (target.objectId != ACL_ID_PUBLIC)
1178  recordSharedDependencyOn(&myself, &target,
1180  }
1181 
1183 
1184  heap_freetuple(new_tuple);
1185 
1186  /* Invalidate Relation Cache */
1187  CacheInvalidateRelcache(target_table);
1188 
1189  /* Clean up. */
1190  systable_endscan(sscan);
1191  relation_close(target_table, NoLock);
1192  heap_close(pg_policy_rel, RowExclusiveLock);
1193 
1194  return myself;
1195 }
#define NIL
Definition: pg_list.h:69
#define ACL_INSERT_CHR
Definition: acl.h:130
void * stringToNode(char *str)
Definition: read.c:38
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:115
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok, bool nowait, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:218
#define OIDOID
Definition: pg_type.h:328
#define PointerGetDatum(X)
Definition: postgres.h:562
#define DatumGetObjectId(X)
Definition: postgres.h:506
#define RelationRelationId
Definition: pg_class.h:29
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
#define ACL_DELETE_CHR
Definition: acl.h:133
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_policy_polroles
Definition: pg_policy.h:51
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polqual
Definition: pg_policy.h:52
RangeVar * table
Definition: parsenodes.h:2313
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
#define AuthIdRelationId
Definition: pg_authid.h:42
void assign_expr_collations(ParseState *pstate, Node *expr)
#define Anum_pg_policy_polcmd
Definition: pg_policy.h:49
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
char * policy_name
Definition: parsenodes.h:2312
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:275
ItemPointerData t_self
Definition: htup.h:65
#define ARR_DATA_PTR(a)
Definition: array.h:303
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Natts_pg_policy
Definition: pg_policy.h:46
#define CStringGetDatum(X)
Definition: postgres.h:584
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1351
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define Anum_pg_policy_polwithcheck
Definition: pg_policy.h:53
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
Definition: pg_shdepend.c:823
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define Anum_pg_policy_polname
Definition: pg_policy.h:47
#define ACL_SELECT_CHR
Definition: acl.h:131
#define TextDatumGetCString(d)
Definition: builtins.h:92
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetChar(X)
Definition: postgres.h:415
#define DatumGetArrayTypePCopy(X)
Definition: array.h:243
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
static Datum * policy_role_list_to_array(List *roles, int *num_roles)
Definition: policy.c:138
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, Alias *alias, bool inh, bool inFromCl)
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg)
Definition: policy.c:65
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4222
#define ACL_ID_PUBLIC
Definition: acl.h:39
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define copyObject(obj)
Definition: nodes.h:622
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
List * p_rtable
Definition: parse_node.h:172
ObjectAddress CreatePolicy ( CreatePolicyStmt stmt)

Definition at line 683 of file policy.c.

References AccessExclusiveLock, ACL_DELETE_CHR, ACL_ID_PUBLIC, ACL_INSERT_CHR, ACL_SELECT_CHR, addRangeTableEntryForRelation(), addRTEtoQuery(), Anum_pg_policy_polcmd, Anum_pg_policy_polname, Anum_pg_policy_polpermissive, Anum_pg_policy_polqual, Anum_pg_policy_polrelid, Anum_pg_policy_polroles, Anum_pg_policy_polwithcheck, assign_expr_collations(), AuthIdRelationId, BoolGetDatum, BTEqualStrategyNumber, CacheInvalidateRelcache(), CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CreatePolicyStmt::cmd_name, construct_array(), copyObject, CStringGetDatum, CStringGetTextDatum, DatumGetObjectId, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, EXPR_KIND_POLICY, free_parsestate(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), HeapTupleIsValid, i, InvokeObjectPostCreateHook, make_parsestate(), namein(), Natts_pg_policy, nodeToString(), NoLock, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OIDOID, ParseState::p_rtable, parse_policy_command(), CreatePolicyStmt::permissive, PointerGetDatum, CreatePolicyStmt::policy_name, policy_role_list_to_array(), PolicyPolrelidPolnameIndexId, PolicyRelationId, CreatePolicyStmt::qual, RangeVarCallbackForPolicy(), RangeVarGetRelidExtended(), recordDependencyOn(), recordDependencyOnExpr(), recordSharedDependencyOn(), relation_close(), relation_open(), RelationGetDescr, RelationGetRelationName, RelationRelationId, CreatePolicyStmt::roles, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_POLICY, systable_beginscan(), systable_endscan(), systable_getnext(), CreatePolicyStmt::table, transformWhereClause(), values, and CreatePolicyStmt::with_check.

Referenced by ProcessUtilitySlow().

684 {
685  Relation pg_policy_rel;
686  Oid policy_id;
687  Relation target_table;
688  Oid table_id;
689  char polcmd;
690  Datum *role_oids;
691  int nitems = 0;
692  ArrayType *role_ids;
693  ParseState *qual_pstate;
694  ParseState *with_check_pstate;
695  RangeTblEntry *rte;
696  Node *qual;
697  Node *with_check_qual;
698  ScanKeyData skey[2];
699  SysScanDesc sscan;
700  HeapTuple policy_tuple;
702  bool isnull[Natts_pg_policy];
703  ObjectAddress target;
704  ObjectAddress myself;
705  int i;
706 
707  /* Parse command */
708  polcmd = parse_policy_command(stmt->cmd_name);
709 
710  /*
711  * If the command is SELECT or DELETE then WITH CHECK should be NULL.
712  */
713  if ((polcmd == ACL_SELECT_CHR || polcmd == ACL_DELETE_CHR)
714  && stmt->with_check != NULL)
715  ereport(ERROR,
716  (errcode(ERRCODE_SYNTAX_ERROR),
717  errmsg("WITH CHECK cannot be applied to SELECT or DELETE")));
718 
719  /*
720  * If the command is INSERT then WITH CHECK should be the only expression
721  * provided.
722  */
723  if (polcmd == ACL_INSERT_CHR && stmt->qual != NULL)
724  ereport(ERROR,
725  (errcode(ERRCODE_SYNTAX_ERROR),
726  errmsg("only WITH CHECK expression allowed for INSERT")));
727 
728  /* Collect role ids */
729  role_oids = policy_role_list_to_array(stmt->roles, &nitems);
730  role_ids = construct_array(role_oids, nitems, OIDOID,
731  sizeof(Oid), true, 'i');
732 
733  /* Parse the supplied clause */
734  qual_pstate = make_parsestate(NULL);
735  with_check_pstate = make_parsestate(NULL);
736 
737  /* zero-clear */
738  memset(values, 0, sizeof(values));
739  memset(isnull, 0, sizeof(isnull));
740 
741  /* Get id of table. Also handles permissions checks. */
743  false, false,
745  (void *) stmt);
746 
747  /* Open target_table to build quals. No additional lock is necessary. */
748  target_table = relation_open(table_id, NoLock);
749 
750  /* Add for the regular security quals */
751  rte = addRangeTableEntryForRelation(qual_pstate, target_table,
752  NULL, false, false);
753  addRTEtoQuery(qual_pstate, rte, false, true, true);
754 
755  /* Add for the with-check quals */
756  rte = addRangeTableEntryForRelation(with_check_pstate, target_table,
757  NULL, false, false);
758  addRTEtoQuery(with_check_pstate, rte, false, true, true);
759 
760  qual = transformWhereClause(qual_pstate,
761  copyObject(stmt->qual),
763  "POLICY");
764 
765  with_check_qual = transformWhereClause(with_check_pstate,
766  copyObject(stmt->with_check),
768  "POLICY");
769 
770  /* Fix up collation information */
771  assign_expr_collations(qual_pstate, qual);
772  assign_expr_collations(with_check_pstate, with_check_qual);
773 
774  /* Open pg_policy catalog */
775  pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
776 
777  /* Set key - policy's relation id. */
778  ScanKeyInit(&skey[0],
780  BTEqualStrategyNumber, F_OIDEQ,
781  ObjectIdGetDatum(table_id));
782 
783  /* Set key - policy's name. */
784  ScanKeyInit(&skey[1],
786  BTEqualStrategyNumber, F_NAMEEQ,
788 
789  sscan = systable_beginscan(pg_policy_rel,
791  skey);
792 
793  policy_tuple = systable_getnext(sscan);
794 
795  /* Complain if the policy name already exists for the table */
796  if (HeapTupleIsValid(policy_tuple))
797  ereport(ERROR,
799  errmsg("policy \"%s\" for table \"%s\" already exists",
800  stmt->policy_name, RelationGetRelationName(target_table))));
801 
802  values[Anum_pg_policy_polrelid - 1] = ObjectIdGetDatum(table_id);
805  values[Anum_pg_policy_polcmd - 1] = CharGetDatum(polcmd);
807  values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
808 
809  /* Add qual if present. */
810  if (qual)
812  else
813  isnull[Anum_pg_policy_polqual - 1] = true;
814 
815  /* Add WITH CHECK qual if present */
816  if (with_check_qual)
817  values[Anum_pg_policy_polwithcheck - 1] = CStringGetTextDatum(nodeToString(with_check_qual));
818  else
819  isnull[Anum_pg_policy_polwithcheck - 1] = true;
820 
821  policy_tuple = heap_form_tuple(RelationGetDescr(pg_policy_rel), values,
822  isnull);
823 
824  policy_id = CatalogTupleInsert(pg_policy_rel, policy_tuple);
825 
826  /* Record Dependencies */
827  target.classId = RelationRelationId;
828  target.objectId = table_id;
829  target.objectSubId = 0;
830 
831  myself.classId = PolicyRelationId;
832  myself.objectId = policy_id;
833  myself.objectSubId = 0;
834 
835  recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
836 
837  recordDependencyOnExpr(&myself, qual, qual_pstate->p_rtable,
839 
840  recordDependencyOnExpr(&myself, with_check_qual,
841  with_check_pstate->p_rtable, DEPENDENCY_NORMAL);
842 
843  /* Register role dependencies */
844  target.classId = AuthIdRelationId;
845  target.objectSubId = 0;
846  for (i = 0; i < nitems; i++)
847  {
848  target.objectId = DatumGetObjectId(role_oids[i]);
849  /* no dependency if public */
850  if (target.objectId != ACL_ID_PUBLIC)
851  recordSharedDependencyOn(&myself, &target,
853  }
854 
856 
857  /* Invalidate Relation Cache */
858  CacheInvalidateRelcache(target_table);
859 
860  /* Clean up. */
861  heap_freetuple(policy_tuple);
862  free_parsestate(qual_pstate);
863  free_parsestate(with_check_pstate);
864  systable_endscan(sscan);
865  relation_close(target_table, NoLock);
866  heap_close(pg_policy_rel, RowExclusiveLock);
867 
868  return myself;
869 }
#define ACL_INSERT_CHR
Definition: acl.h:130
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:115
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok, bool nowait, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:218
#define OIDOID
Definition: pg_type.h:328
#define PointerGetDatum(X)
Definition: postgres.h:562
#define DatumGetObjectId(X)
Definition: postgres.h:506
#define RelationRelationId
Definition: pg_class.h:29
#define ACL_DELETE_CHR
Definition: acl.h:133
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
static char parse_policy_command(const char *cmd_name)
Definition: policy.c:109
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
#define Anum_pg_policy_polroles
Definition: pg_policy.h:51
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polqual
Definition: pg_policy.h:52
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
#define AuthIdRelationId
Definition: pg_authid.h:42
void assign_expr_collations(ParseState *pstate, Node *expr)
#define Anum_pg_policy_polcmd
Definition: pg_policy.h:49
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Natts_pg_policy
Definition: pg_policy.h:46
#define CStringGetDatum(X)
Definition: postgres.h:584
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1351
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define Anum_pg_policy_polwithcheck
Definition: pg_policy.h:53
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
#define ereport(elevel, rest)
Definition: elog.h:122
void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
#define Anum_pg_policy_polpermissive
Definition: pg_policy.h:50
#define Anum_pg_policy_polname
Definition: pg_policy.h:47
#define ACL_SELECT_CHR
Definition: acl.h:131
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define BoolGetDatum(X)
Definition: postgres.h:408
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
static Datum * policy_role_list_to_array(List *roles, int *num_roles)
Definition: policy.c:138
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, Alias *alias, bool inh, bool inFromCl)
#define CharGetDatum(X)
Definition: postgres.h:422
RangeVar * table
Definition: parsenodes.h:2297
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg)
Definition: policy.c:65
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4222
#define ACL_ID_PUBLIC
Definition: acl.h:39
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define copyObject(obj)
Definition: nodes.h:622
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define BTEqualStrategyNumber
Definition: stratnum.h:31
List * p_rtable
Definition: parse_node.h:172
Oid get_relation_policy_oid ( Oid  relid,
const char *  policy_name,
bool  missing_ok 
)

Definition at line 1311 of file policy.c.

References AccessShareLock, Anum_pg_policy_polname, Anum_pg_policy_polrelid, BTEqualStrategyNumber, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, get_rel_name(), heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvalidOid, NULL, ObjectIdGetDatum, PolicyPolrelidPolnameIndexId, PolicyRelationId, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address_relobject().

1312 {
1313  Relation pg_policy_rel;
1314  ScanKeyData skey[2];
1315  SysScanDesc sscan;
1316  HeapTuple policy_tuple;
1317  Oid policy_oid;
1318 
1319  pg_policy_rel = heap_open(PolicyRelationId, AccessShareLock);
1320 
1321  /* Add key - policy's relation id. */
1322  ScanKeyInit(&skey[0],
1324  BTEqualStrategyNumber, F_OIDEQ,
1325  ObjectIdGetDatum(relid));
1326 
1327  /* Add key - policy's name. */
1328  ScanKeyInit(&skey[1],
1330  BTEqualStrategyNumber, F_NAMEEQ,
1331  CStringGetDatum(policy_name));
1332 
1333  sscan = systable_beginscan(pg_policy_rel,
1335  skey);
1336 
1337  policy_tuple = systable_getnext(sscan);
1338 
1339  if (!HeapTupleIsValid(policy_tuple))
1340  {
1341  if (!missing_ok)
1342  ereport(ERROR,
1343  (errcode(ERRCODE_UNDEFINED_OBJECT),
1344  errmsg("policy \"%s\" for table \"%s\" does not exist",
1345  policy_name, get_rel_name(relid))));
1346 
1347  policy_oid = InvalidOid;
1348  }
1349  else
1350  policy_oid = HeapTupleGetOid(policy_tuple);
1351 
1352  /* Clean up. */
1353  systable_endscan(sscan);
1354  heap_close(pg_policy_rel, AccessShareLock);
1355 
1356  return policy_oid;
1357 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_policy_polname
Definition: pg_policy.h:47
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvalidOid
Definition: postgres_ext.h:36
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
#define BTEqualStrategyNumber
Definition: stratnum.h:31
bool relation_has_policies ( Relation  rel)

Definition at line 1363 of file policy.c.

References AccessShareLock, Anum_pg_policy_polrelid, BTEqualStrategyNumber, heap_close, heap_open(), HeapTupleIsValid, NULL, ObjectIdGetDatum, PolicyPolrelidPolnameIndexId, PolicyRelationId, RelationGetRelid, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by DefineQueryRewrite().

1364 {
1365  Relation catalog;
1366  ScanKeyData skey;
1367  SysScanDesc sscan;
1368  HeapTuple policy_tuple;
1369  bool ret = false;
1370 
1372  ScanKeyInit(&skey,
1374  BTEqualStrategyNumber, F_OIDEQ,
1376  sscan = systable_beginscan(catalog, PolicyPolrelidPolnameIndexId, true,
1377  NULL, 1, &skey);
1378  policy_tuple = systable_getnext(sscan);
1379  if (HeapTupleIsValid(policy_tuple))
1380  ret = true;
1381 
1382  systable_endscan(sscan);
1383  heap_close(catalog, AccessShareLock);
1384 
1385  return ret;
1386 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define RelationGetRelid(relation)
Definition: rel.h:416
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void RelationBuildRowSecurity ( Relation  relation)

Definition at line 191 of file policy.c.

References AccessShareLock, ALLOCSET_SMALL_SIZES, AllocSetContextCreate(), Anum_pg_policy_polcmd, Anum_pg_policy_polname, Anum_pg_policy_polpermissive, Anum_pg_policy_polqual, Anum_pg_policy_polrelid, Anum_pg_policy_polroles, Anum_pg_policy_polwithcheck, Assert, BTEqualStrategyNumber, CacheMemoryContext, checkExprHasSubLink(), copyObject, CurrentMemoryContext, DatumGetArrayTypePCopy, DatumGetBool, DatumGetChar, DatumGetName, elog, ERROR, RowSecurityPolicy::hassublinks, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, lcons(), MemoryContextAllocZero(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, NULL, ObjectIdGetDatum, palloc0(), RowSecurityPolicy::permissive, pfree(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, RowSecurityPolicy::polcmd, RowSecurityDesc::policies, RowSecurityPolicy::policy_name, PolicyPolrelidPolnameIndexId, PolicyRelationId, pstrdup(), RowSecurityPolicy::qual, RelationData::rd_rsdesc, RelationGetDescr, RelationGetRelid, RowSecurityPolicy::roles, RowSecurityDesc::rscxt, ScanKeyInit(), stringToNode(), systable_beginscan(), systable_endscan(), systable_getnext(), TextDatumGetCString, and RowSecurityPolicy::with_check_qual.

Referenced by RelationBuildDesc(), and RelationCacheInitializePhase3().

192 {
193  MemoryContext rscxt;
195  RowSecurityDesc *volatile rsdesc = NULL;
196 
197  /*
198  * Create a memory context to hold everything associated with this
199  * relation's row security policy. This makes it easy to clean up during
200  * a relcache flush.
201  */
203  "row security descriptor",
205 
206  /*
207  * Since rscxt lives under CacheMemoryContext, it is long-lived. Use a
208  * PG_TRY block to ensure it'll get freed if we fail partway through.
209  */
210  PG_TRY();
211  {
212  Relation catalog;
213  ScanKeyData skey;
214  SysScanDesc sscan;
215  HeapTuple tuple;
216 
217  rsdesc = MemoryContextAllocZero(rscxt, sizeof(RowSecurityDesc));
218  rsdesc->rscxt = rscxt;
219 
221 
222  ScanKeyInit(&skey,
224  BTEqualStrategyNumber, F_OIDEQ,
226 
227  sscan = systable_beginscan(catalog, PolicyPolrelidPolnameIndexId, true,
228  NULL, 1, &skey);
229 
230  /*
231  * Loop through the row level security policies for this relation, if
232  * any.
233  */
234  while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
235  {
236  Datum value_datum;
237  char cmd_value;
238  bool permissive_value;
239  Datum roles_datum;
240  char *qual_value;
241  Expr *qual_expr;
242  char *with_check_value;
243  Expr *with_check_qual;
244  char *policy_name_value;
245  bool isnull;
246  RowSecurityPolicy *policy;
247 
248  /*
249  * Note: all the pass-by-reference data we collect here is either
250  * still stored in the tuple, or constructed in the caller's
251  * short-lived memory context. We must copy it into rscxt
252  * explicitly below.
253  */
254 
255  /* Get policy command */
256  value_datum = heap_getattr(tuple, Anum_pg_policy_polcmd,
257  RelationGetDescr(catalog), &isnull);
258  Assert(!isnull);
259  cmd_value = DatumGetChar(value_datum);
260 
261  /* Get policy permissive or restrictive */
262  value_datum = heap_getattr(tuple, Anum_pg_policy_polpermissive,
263  RelationGetDescr(catalog), &isnull);
264  Assert(!isnull);
265  permissive_value = DatumGetBool(value_datum);
266 
267  /* Get policy name */
268  value_datum = heap_getattr(tuple, Anum_pg_policy_polname,
269  RelationGetDescr(catalog), &isnull);
270  Assert(!isnull);
271  policy_name_value = NameStr(*(DatumGetName(value_datum)));
272 
273  /* Get policy roles */
274  roles_datum = heap_getattr(tuple, Anum_pg_policy_polroles,
275  RelationGetDescr(catalog), &isnull);
276  /* shouldn't be null, but initdb doesn't mark it so, so check */
277  if (isnull)
278  elog(ERROR, "unexpected null value in pg_policy.polroles");
279 
280  /* Get policy qual */
281  value_datum = heap_getattr(tuple, Anum_pg_policy_polqual,
282  RelationGetDescr(catalog), &isnull);
283  if (!isnull)
284  {
285  qual_value = TextDatumGetCString(value_datum);
286  qual_expr = (Expr *) stringToNode(qual_value);
287  }
288  else
289  qual_expr = NULL;
290 
291  /* Get WITH CHECK qual */
292  value_datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck,
293  RelationGetDescr(catalog), &isnull);
294  if (!isnull)
295  {
296  with_check_value = TextDatumGetCString(value_datum);
297  with_check_qual = (Expr *) stringToNode(with_check_value);
298  }
299  else
300  with_check_qual = NULL;
301 
302  /* Now copy everything into the cache context */
303  MemoryContextSwitchTo(rscxt);
304 
305  policy = palloc0(sizeof(RowSecurityPolicy));
306  policy->policy_name = pstrdup(policy_name_value);
307  policy->polcmd = cmd_value;
308  policy->permissive = permissive_value;
309  policy->roles = DatumGetArrayTypePCopy(roles_datum);
310  policy->qual = copyObject(qual_expr);
311  policy->with_check_qual = copyObject(with_check_qual);
312  policy->hassublinks = checkExprHasSubLink((Node *) qual_expr) ||
313  checkExprHasSubLink((Node *) with_check_qual);
314 
315  rsdesc->policies = lcons(policy, rsdesc->policies);
316 
317  MemoryContextSwitchTo(oldcxt);
318 
319  /* clean up some (not all) of the junk ... */
320  if (qual_expr != NULL)
321  pfree(qual_expr);
322  if (with_check_qual != NULL)
323  pfree(with_check_qual);
324  }
325 
326  systable_endscan(sscan);
327  heap_close(catalog, AccessShareLock);
328  }
329  PG_CATCH();
330  {
331  /* Delete rscxt, first making sure it isn't active */
332  MemoryContextSwitchTo(oldcxt);
333  MemoryContextDelete(rscxt);
334  PG_RE_THROW();
335  }
336  PG_END_TRY();
337 
338  /* Success --- attach the policy descriptor to the relcache entry */
339  relation->rd_rsdesc = rsdesc;
340 }
void * stringToNode(char *str)
Definition: read.c:38
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
bool checkExprHasSubLink(Node *node)
Definition: rewriteManip.c:277
#define RelationGetDescr(relation)
Definition: rel.h:428
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:175
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
Definition: nodes.h:509
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_policy_polroles
Definition: pg_policy.h:51
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polqual
Definition: pg_policy.h:52
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
#define DatumGetName(X)
Definition: postgres.h:591
#define Anum_pg_policy_polcmd
Definition: pg_policy.h:49
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Expr * with_check_qual
Definition: rowsecurity.h:27
#define DatumGetBool(X)
Definition: postgres.h:399
ArrayType * roles
Definition: rowsecurity.h:24
#define Anum_pg_policy_polwithcheck
Definition: pg_policy.h:53
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
struct RowSecurityDesc * rd_rsdesc
Definition: rel.h:122
MemoryContext rscxt
Definition: rowsecurity.h:33
#define Anum_pg_policy_polpermissive
Definition: pg_policy.h:50
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define Anum_pg_policy_polname
Definition: pg_policy.h:47
#define TextDatumGetCString(d)
Definition: builtins.h:92
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
void * palloc0(Size size)
Definition: mcxt.c:878
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetChar(X)
Definition: postgres.h:415
#define DatumGetArrayTypePCopy(X)
Definition: array.h:243
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:742
#define PolicyRelationId
Definition: pg_policy.h:19
List * lcons(void *datum, List *list)
Definition: list.c:259
#define PG_CATCH()
Definition: elog.h:293
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define PG_RE_THROW()
Definition: elog.h:314
#define NameStr(name)
Definition: c.h:499
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define copyObject(obj)
Definition: nodes.h:622
#define PG_TRY()
Definition: elog.h:284
#define RelationGetRelid(relation)
Definition: rel.h:416
#define PG_END_TRY()
Definition: elog.h:300
#define BTEqualStrategyNumber
Definition: stratnum.h:31
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
void RemovePolicyById ( Oid  policy_id)

Definition at line 350 of file policy.c.

References AccessExclusiveLock, allowSystemTableMods, BTEqualStrategyNumber, CacheInvalidateRelcache(), CatalogTupleDelete(), elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, IsSystemRelation(), NoLock, NULL, ObjectIdAttributeNumber, ObjectIdGetDatum, PolicyOidIndexId, PolicyRelationId, RelationData::rd_rel, RelationGetRelationName, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by doDeletion().

351 {
352  Relation pg_policy_rel;
353  SysScanDesc sscan;
354  ScanKeyData skey[1];
355  HeapTuple tuple;
356  Oid relid;
357  Relation rel;
358 
359  pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
360 
361  /*
362  * Find the policy to delete.
363  */
364  ScanKeyInit(&skey[0],
366  BTEqualStrategyNumber, F_OIDEQ,
367  ObjectIdGetDatum(policy_id));
368 
369  sscan = systable_beginscan(pg_policy_rel, PolicyOidIndexId, true,
370  NULL, 1, skey);
371 
372  tuple = systable_getnext(sscan);
373 
374  /* If the policy exists, then remove it, otherwise raise an error. */
375  if (!HeapTupleIsValid(tuple))
376  elog(ERROR, "could not find tuple for policy %u", policy_id);
377 
378  /*
379  * Open and exclusive-lock the relation the policy belongs to. (We need
380  * exclusive lock to lock out queries that might otherwise depend on the
381  * set of policies the rel has; furthermore we've got to hold the lock
382  * till commit.)
383  */
384  relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
385 
386  rel = heap_open(relid, AccessExclusiveLock);
387  if (rel->rd_rel->relkind != RELKIND_RELATION &&
388  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
389  ereport(ERROR,
390  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
391  errmsg("\"%s\" is not a table",
392  RelationGetRelationName(rel))));
393 
395  ereport(ERROR,
396  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
397  errmsg("permission denied: \"%s\" is a system catalog",
398  RelationGetRelationName(rel))));
399 
400  CatalogTupleDelete(pg_policy_rel, &tuple->t_self);
401 
402  systable_endscan(sscan);
403 
404  /*
405  * Note that, unlike some of the other flags in pg_class, relrowsecurity
406  * is not just an indication of if policies exist. When relrowsecurity is
407  * set by a user, then all access to the relation must be through a
408  * policy. If no policy is defined for the relation then a default-deny
409  * policy is created and all records are filtered (except for queries from
410  * the owner).
411  */
413 
414  heap_close(rel, NoLock);
415 
416  /* Clean up */
417  heap_close(pg_policy_rel, RowExclusiveLock);
418 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool IsSystemRelation(Relation relation)
Definition: catalog.c:63
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define PolicyOidIndexId
Definition: indexing.h:327
int errcode(int sqlerrcode)
Definition: elog.c:575
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
bool allowSystemTableMods
Definition: globals.c:112
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:40
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define BTEqualStrategyNumber
Definition: stratnum.h:31
bool RemoveRoleFromObjectPolicy ( Oid  roleid,
Oid  classid,
Oid  objid 
)

Definition at line 435 of file policy.c.

References AccessExclusiveLock, ACL_ID_PUBLIC, addRangeTableEntryForRelation(), allowSystemTableMods, Anum_pg_policy_polqual, Anum_pg_policy_polroles, Anum_pg_policy_polwithcheck, ARR_DATA_PTR, ARR_DIMS, Assert, AuthIdRelationId, BTEqualStrategyNumber, CacheInvalidateRelcache(), CatalogTupleUpdate(), ObjectAddress::classId, construct_array(), DatumGetArrayTypePCopy, DatumGetObjectId, deleteDependencyRecordsFor(), deleteSharedDependencyRecordsFor(), DEPENDENCY_AUTO, DEPENDENCY_NORMAL, elog, ereport, errcode(), errmsg(), ERROR, free_parsestate(), GETSTRUCT, GetUserId(), GetUserNameFromId(), heap_close, heap_freetuple(), heap_getattr, heap_modify_tuple(), heap_open(), HeapTupleIsValid, i, InvokeObjectPostAlterHook, IsSystemRelation(), make_parsestate(), NameStr, Natts_pg_policy, NIL, NoLock, NULL, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectIdGetDatum, ObjectAddress::objectSubId, OIDOID, ParseState::p_rtable, palloc(), pg_class_ownercheck(), PointerGetDatum, PolicyOidIndexId, PolicyRelationId, RelationData::rd_rel, recordDependencyOn(), recordDependencyOnExpr(), recordSharedDependencyOn(), relation_close(), relation_open(), RelationGetDescr, RelationGetRelationName, RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_POLICY, stringToNode(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, TextDatumGetCString, values, and WARNING.

Referenced by shdepDropOwned().

436 {
437  Relation pg_policy_rel;
438  SysScanDesc sscan;
439  ScanKeyData skey[1];
440  HeapTuple tuple;
441  Oid relid;
442  Relation rel;
443  ArrayType *policy_roles;
444  int num_roles;
445  Datum roles_datum;
446  bool attr_isnull;
447  bool noperm = true;
448 
449  Assert(classid == PolicyRelationId);
450 
451  pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
452 
453  /*
454  * Find the policy to update.
455  */
456  ScanKeyInit(&skey[0],
458  BTEqualStrategyNumber, F_OIDEQ,
459  ObjectIdGetDatum(policy_id));
460 
461  sscan = systable_beginscan(pg_policy_rel, PolicyOidIndexId, true,
462  NULL, 1, skey);
463 
464  tuple = systable_getnext(sscan);
465 
466  /* Raise an error if we don't find the policy. */
467  if (!HeapTupleIsValid(tuple))
468  elog(ERROR, "could not find tuple for policy %u", policy_id);
469 
470  /*
471  * Open and exclusive-lock the relation the policy belongs to.
472  */
473  relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
474 
475  rel = relation_open(relid, AccessExclusiveLock);
476 
477  if (rel->rd_rel->relkind != RELKIND_RELATION &&
478  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
479  ereport(ERROR,
480  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
481  errmsg("\"%s\" is not a table",
482  RelationGetRelationName(rel))));
483 
485  ereport(ERROR,
486  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
487  errmsg("permission denied: \"%s\" is a system catalog",
488  RelationGetRelationName(rel))));
489 
490  /* Get the current set of roles */
491  roles_datum = heap_getattr(tuple,
493  RelationGetDescr(pg_policy_rel),
494  &attr_isnull);
495 
496  Assert(!attr_isnull);
497 
498  policy_roles = DatumGetArrayTypePCopy(roles_datum);
499 
500  /* We should be removing exactly one entry from the roles array */
501  num_roles = ARR_DIMS(policy_roles)[0] - 1;
502 
503  Assert(num_roles >= 0);
504 
505  /* Must own relation. */
506  if (pg_class_ownercheck(relid, GetUserId()))
507  noperm = false; /* user is allowed to modify this policy */
508  else
510  (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
511  errmsg("role \"%s\" could not be removed from policy \"%s\" on \"%s\"",
512  GetUserNameFromId(roleid, false),
513  NameStr(((Form_pg_policy) GETSTRUCT(tuple))->polname),
514  RelationGetRelationName(rel))));
515 
516  /*
517  * If multiple roles exist on this policy, then remove the one we were
518  * asked to and leave the rest.
519  */
520  if (!noperm && num_roles > 0)
521  {
522  int i,
523  j;
524  Oid *roles = (Oid *) ARR_DATA_PTR(policy_roles);
525  Datum *role_oids;
526  char *qual_value;
527  Node *qual_expr;
528  List *qual_parse_rtable = NIL;
529  char *with_check_value;
530  Node *with_check_qual;
531  List *with_check_parse_rtable = NIL;
533  bool isnull[Natts_pg_policy];
534  bool replaces[Natts_pg_policy];
535  Datum value_datum;
536  ArrayType *role_ids;
537  HeapTuple new_tuple;
538  ObjectAddress target;
539  ObjectAddress myself;
540 
541  /* zero-clear */
542  memset(values, 0, sizeof(values));
543  memset(replaces, 0, sizeof(replaces));
544  memset(isnull, 0, sizeof(isnull));
545 
546  /*
547  * All of the dependencies will be removed from the policy and then
548  * re-added. In order to get them correct, we need to extract out the
549  * expressions in the policy and construct a parsestate just enough to
550  * build the range table(s) to then pass to recordDependencyOnExpr().
551  */
552 
553  /* Get policy qual, to update dependencies */
554  value_datum = heap_getattr(tuple, Anum_pg_policy_polqual,
555  RelationGetDescr(pg_policy_rel), &attr_isnull);
556  if (!attr_isnull)
557  {
558  ParseState *qual_pstate;
559 
560  /* parsestate is built just to build the range table */
561  qual_pstate = make_parsestate(NULL);
562 
563  qual_value = TextDatumGetCString(value_datum);
564  qual_expr = stringToNode(qual_value);
565 
566  /* Add this rel to the parsestate's rangetable, for dependencies */
567  addRangeTableEntryForRelation(qual_pstate, rel, NULL, false, false);
568 
569  qual_parse_rtable = qual_pstate->p_rtable;
570  free_parsestate(qual_pstate);
571  }
572  else
573  qual_expr = NULL;
574 
575  /* Get WITH CHECK qual, to update dependencies */
576  value_datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck,
577  RelationGetDescr(pg_policy_rel), &attr_isnull);
578  if (!attr_isnull)
579  {
580  ParseState *with_check_pstate;
581 
582  /* parsestate is built just to build the range table */
583  with_check_pstate = make_parsestate(NULL);
584 
585  with_check_value = TextDatumGetCString(value_datum);
586  with_check_qual = stringToNode(with_check_value);
587 
588  /* Add this rel to the parsestate's rangetable, for dependencies */
589  addRangeTableEntryForRelation(with_check_pstate, rel, NULL, false,
590  false);
591 
592  with_check_parse_rtable = with_check_pstate->p_rtable;
593  free_parsestate(with_check_pstate);
594  }
595  else
596  with_check_qual = NULL;
597 
598  /* Rebuild the roles array to then update the pg_policy tuple with */
599  role_oids = (Datum *) palloc(num_roles * sizeof(Datum));
600  for (i = 0, j = 0; i < ARR_DIMS(policy_roles)[0]; i++)
601  /* Copy over all of the roles which are not the one being removed */
602  if (roles[i] != roleid)
603  role_oids[j++] = ObjectIdGetDatum(roles[i]);
604 
605  /* We should have only removed the one role */
606  Assert(j == num_roles);
607 
608  /* This is the array for the new tuple */
609  role_ids = construct_array(role_oids, num_roles, OIDOID,
610  sizeof(Oid), true, 'i');
611 
612  replaces[Anum_pg_policy_polroles - 1] = true;
613  values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
614 
615  new_tuple = heap_modify_tuple(tuple,
616  RelationGetDescr(pg_policy_rel),
617  values, isnull, replaces);
618  CatalogTupleUpdate(pg_policy_rel, &new_tuple->t_self, new_tuple);
619 
620  /* Remove all old dependencies. */
621  deleteDependencyRecordsFor(PolicyRelationId, policy_id, false);
622 
623  /* Record the new set of dependencies */
624  target.classId = RelationRelationId;
625  target.objectId = relid;
626  target.objectSubId = 0;
627 
628  myself.classId = PolicyRelationId;
629  myself.objectId = policy_id;
630  myself.objectSubId = 0;
631 
632  recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
633 
634  if (qual_expr)
635  recordDependencyOnExpr(&myself, qual_expr, qual_parse_rtable,
637 
638  if (with_check_qual)
639  recordDependencyOnExpr(&myself, with_check_qual,
640  with_check_parse_rtable,
642 
643  /* Remove all the old shared dependencies (roles) */
645 
646  /* Record the new shared dependencies (roles) */
647  target.classId = AuthIdRelationId;
648  target.objectSubId = 0;
649  for (i = 0; i < num_roles; i++)
650  {
651  target.objectId = DatumGetObjectId(role_oids[i]);
652  /* no need for dependency on the public role */
653  if (target.objectId != ACL_ID_PUBLIC)
654  recordSharedDependencyOn(&myself, &target,
656  }
657 
659 
660  heap_freetuple(new_tuple);
661 
662  /* Invalidate Relation Cache */
664  }
665 
666  /* Clean up. */
667  systable_endscan(sscan);
668 
669  relation_close(rel, NoLock);
670 
671  heap_close(pg_policy_rel, RowExclusiveLock);
672 
673  return (noperm || num_roles > 0);
674 }
#define NIL
Definition: pg_list.h:69
void * stringToNode(char *str)
Definition: read.c:38
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:115
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool IsSystemRelation(Relation relation)
Definition: catalog.c:63
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:283
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define OIDOID
Definition: pg_type.h:328
#define PolicyOidIndexId
Definition: indexing.h:327
#define PointerGetDatum(X)
Definition: postgres.h:562
#define DatumGetObjectId(X)
Definition: postgres.h:506
#define RelationRelationId
Definition: pg_class.h:29
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_policy_polroles
Definition: pg_policy.h:51
Form_pg_class rd_rel
Definition: rel.h:114
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polqual
Definition: pg_policy.h:52
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
#define AuthIdRelationId
Definition: pg_authid.h:42
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:275
ItemPointerData t_self
Definition: htup.h:65
#define ARR_DATA_PTR(a)
Definition: array.h:303
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Natts_pg_policy
Definition: pg_policy.h:46
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1351
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define Anum_pg_policy_polwithcheck
Definition: pg_policy.h:53
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
Definition: pg_shdepend.c:823
#define WARNING
Definition: elog.h:40
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define TextDatumGetCString(d)
Definition: builtins.h:92
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetArrayTypePCopy(X)
Definition: array.h:243
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
bool allowSystemTableMods
Definition: globals.c:112
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:40
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:691
#define Assert(condition)
Definition: c.h:675
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4546
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, Alias *alias, bool inh, bool inFromCl)
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:499
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ACL_ID_PUBLIC
Definition: acl.h:39
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define elog
Definition: elog.h:219
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
#define RELKIND_RELATION
Definition: pg_class.h:160
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
List * p_rtable
Definition: parse_node.h:172
ObjectAddress rename_policy ( RenameStmt stmt)

Definition at line 1202 of file policy.c.

References AccessExclusiveLock, Anum_pg_policy_polname, Anum_pg_policy_polrelid, BTEqualStrategyNumber, CacheInvalidateRelcache(), CatalogTupleUpdate(), CStringGetDatum, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, GETSTRUCT, heap_close, heap_copytuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcpy(), RenameStmt::newname, NoLock, NULL, ObjectAddressSet, ObjectIdGetDatum, PolicyPolrelidPolnameIndexId, PolicyRelationId, RangeVarCallbackForPolicy(), RangeVarGetRelidExtended(), RenameStmt::relation, relation_close(), relation_open(), RelationGetRelationName, RowExclusiveLock, ScanKeyInit(), RenameStmt::subname, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by ExecRenameStmt().

1203 {
1204  Relation pg_policy_rel;
1205  Relation target_table;
1206  Oid table_id;
1207  Oid opoloid;
1208  ScanKeyData skey[2];
1209  SysScanDesc sscan;
1210  HeapTuple policy_tuple;
1211  ObjectAddress address;
1212 
1213  /* Get id of table. Also handles permissions checks. */
1215  false, false,
1217  (void *) stmt);
1218 
1219  target_table = relation_open(table_id, NoLock);
1220 
1221  pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
1222 
1223  /* First pass -- check for conflict */
1224 
1225  /* Add key - policy's relation id. */
1226  ScanKeyInit(&skey[0],
1228  BTEqualStrategyNumber, F_OIDEQ,
1229  ObjectIdGetDatum(table_id));
1230 
1231  /* Add key - policy's name. */
1232  ScanKeyInit(&skey[1],
1234  BTEqualStrategyNumber, F_NAMEEQ,
1235  CStringGetDatum(stmt->newname));
1236 
1237  sscan = systable_beginscan(pg_policy_rel,
1239  skey);
1240 
1241  if (HeapTupleIsValid(systable_getnext(sscan)))
1242  ereport(ERROR,
1244  errmsg("policy \"%s\" for table \"%s\" already exists",
1245  stmt->newname, RelationGetRelationName(target_table))));
1246 
1247  systable_endscan(sscan);
1248 
1249  /* Second pass -- find existing policy and update */
1250  /* Add key - policy's relation id. */
1251  ScanKeyInit(&skey[0],
1253  BTEqualStrategyNumber, F_OIDEQ,
1254  ObjectIdGetDatum(table_id));
1255 
1256  /* Add key - policy's name. */
1257  ScanKeyInit(&skey[1],
1259  BTEqualStrategyNumber, F_NAMEEQ,
1260  CStringGetDatum(stmt->subname));
1261 
1262  sscan = systable_beginscan(pg_policy_rel,
1264  skey);
1265 
1266  policy_tuple = systable_getnext(sscan);
1267 
1268  /* Complain if we did not find the policy */
1269  if (!HeapTupleIsValid(policy_tuple))
1270  ereport(ERROR,
1271  (errcode(ERRCODE_UNDEFINED_OBJECT),
1272  errmsg("policy \"%s\" for table \"%s\" does not exist",
1273  stmt->subname, RelationGetRelationName(target_table))));
1274 
1275  opoloid = HeapTupleGetOid(policy_tuple);
1276 
1277  policy_tuple = heap_copytuple(policy_tuple);
1278 
1279  namestrcpy(&((Form_pg_policy) GETSTRUCT(policy_tuple))->polname,
1280  stmt->newname);
1281 
1282  CatalogTupleUpdate(pg_policy_rel, &policy_tuple->t_self, policy_tuple);
1283 
1285  HeapTupleGetOid(policy_tuple), 0);
1286 
1287  ObjectAddressSet(address, PolicyRelationId, opoloid);
1288 
1289  /*
1290  * Invalidate relation's relcache entry so that other backends (and this
1291  * one too!) are sent SI message to make them rebuild relcache entries.
1292  * (Ideally this should happen automatically...)
1293  */
1294  CacheInvalidateRelcache(target_table);
1295 
1296  /* Clean up. */
1297  systable_endscan(sscan);
1298  heap_close(pg_policy_rel, RowExclusiveLock);
1299  relation_close(target_table, NoLock);
1300 
1301  return address;
1302 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * subname
Definition: parsenodes.h:2790
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok, bool nowait, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:218
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
#define heap_close(r, l)
Definition: heapam.h:97
char * newname
Definition: parsenodes.h:2792
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:216
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_policy_polrelid
Definition: pg_policy.h:48
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:584
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define PolicyPolrelidPolnameIndexId
Definition: indexing.h:330
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define Anum_pg_policy_polname
Definition: pg_policy.h:47
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
RangeVar * relation
Definition: parsenodes.h:2788
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:40
#define PolicyRelationId
Definition: pg_policy.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg)
Definition: policy.c:65
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define BTEqualStrategyNumber
Definition: stratnum.h:31