PostgreSQL Source Code  git master
alter.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * alter.c
4  * Drivers for generic alter commands
5  *
6  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/commands/alter.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/htup_details.h"
18 #include "access/relation.h"
19 #include "access/sysattr.h"
20 #include "access/table.h"
21 #include "catalog/dependency.h"
22 #include "catalog/indexing.h"
23 #include "catalog/namespace.h"
24 #include "catalog/objectaccess.h"
25 #include "catalog/pg_collation.h"
26 #include "catalog/pg_conversion.h"
30 #include "catalog/pg_language.h"
31 #include "catalog/pg_largeobject.h"
33 #include "catalog/pg_namespace.h"
34 #include "catalog/pg_opclass.h"
35 #include "catalog/pg_opfamily.h"
36 #include "catalog/pg_proc.h"
39 #include "catalog/pg_ts_config.h"
40 #include "catalog/pg_ts_dict.h"
41 #include "catalog/pg_ts_parser.h"
42 #include "catalog/pg_ts_template.h"
43 #include "commands/alter.h"
44 #include "commands/collationcmds.h"
46 #include "commands/dbcommands.h"
47 #include "commands/defrem.h"
48 #include "commands/event_trigger.h"
49 #include "commands/extension.h"
50 #include "commands/policy.h"
51 #include "commands/proclang.h"
53 #include "commands/schemacmds.h"
55 #include "commands/tablecmds.h"
56 #include "commands/tablespace.h"
57 #include "commands/trigger.h"
58 #include "commands/typecmds.h"
59 #include "commands/user.h"
60 #include "miscadmin.h"
61 #include "parser/parse_func.h"
62 #include "rewrite/rewriteDefine.h"
63 #include "tcop/utility.h"
64 #include "utils/builtins.h"
65 #include "utils/fmgroids.h"
66 #include "utils/lsyscache.h"
67 #include "utils/rel.h"
68 #include "utils/syscache.h"
69 
70 static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid);
71 
72 /*
73  * Raise an error to the effect that an object of the given name is already
74  * present in the given namespace.
75  */
76 static void
77 report_name_conflict(Oid classId, const char *name)
78 {
79  char *msgfmt;
80 
81  switch (classId)
82  {
83  case EventTriggerRelationId:
84  msgfmt = gettext_noop("event trigger \"%s\" already exists");
85  break;
86  case ForeignDataWrapperRelationId:
87  msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
88  break;
89  case ForeignServerRelationId:
90  msgfmt = gettext_noop("server \"%s\" already exists");
91  break;
92  case LanguageRelationId:
93  msgfmt = gettext_noop("language \"%s\" already exists");
94  break;
95  case PublicationRelationId:
96  msgfmt = gettext_noop("publication \"%s\" already exists");
97  break;
98  case SubscriptionRelationId:
99  msgfmt = gettext_noop("subscription \"%s\" already exists");
100  break;
101  default:
102  elog(ERROR, "unsupported object class: %u", classId);
103  break;
104  }
105 
106  ereport(ERROR,
108  errmsg(msgfmt, name)));
109 }
110 
111 static void
112 report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
113 {
114  char *msgfmt;
115 
116  Assert(OidIsValid(nspOid));
117 
118  switch (classId)
119  {
120  case ConversionRelationId:
121  Assert(OidIsValid(nspOid));
122  msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
123  break;
124  case StatisticExtRelationId:
125  Assert(OidIsValid(nspOid));
126  msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
127  break;
128  case TSParserRelationId:
129  Assert(OidIsValid(nspOid));
130  msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
131  break;
132  case TSDictionaryRelationId:
133  Assert(OidIsValid(nspOid));
134  msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
135  break;
136  case TSTemplateRelationId:
137  Assert(OidIsValid(nspOid));
138  msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
139  break;
140  case TSConfigRelationId:
141  Assert(OidIsValid(nspOid));
142  msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
143  break;
144  default:
145  elog(ERROR, "unsupported object class: %u", classId);
146  break;
147  }
148 
149  ereport(ERROR,
151  errmsg(msgfmt, name, get_namespace_name(nspOid))));
152 }
153 
154 /*
155  * AlterObjectRename_internal
156  *
157  * Generic function to rename the given object, for simple cases (won't
158  * work for tables, nor other cases where we need to do more than change
159  * the name column of a single catalog entry).
160  *
161  * rel: catalog relation containing object (RowExclusiveLock'd by caller)
162  * objectId: OID of object to be renamed
163  * new_name: CString representation of new name
164  */
165 static void
166 AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
167 {
168  Oid classId = RelationGetRelid(rel);
169  int oidCacheId = get_object_catcache_oid(classId);
170  int nameCacheId = get_object_catcache_name(classId);
171  AttrNumber Anum_name = get_object_attnum_name(classId);
172  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
173  AttrNumber Anum_owner = get_object_attnum_owner(classId);
174  HeapTuple oldtup;
175  HeapTuple newtup;
176  Datum datum;
177  bool isnull;
178  Oid namespaceId;
179  Oid ownerId;
180  char *old_name;
181  AclResult aclresult;
182  Datum *values;
183  bool *nulls;
184  bool *replaces;
185  NameData nameattrdata;
186 
187  oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
188  if (!HeapTupleIsValid(oldtup))
189  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
190  objectId, RelationGetRelationName(rel));
191 
192  datum = heap_getattr(oldtup, Anum_name,
193  RelationGetDescr(rel), &isnull);
194  Assert(!isnull);
195  old_name = NameStr(*(DatumGetName(datum)));
196 
197  /* Get OID of namespace */
198  if (Anum_namespace > 0)
199  {
200  datum = heap_getattr(oldtup, Anum_namespace,
201  RelationGetDescr(rel), &isnull);
202  Assert(!isnull);
203  namespaceId = DatumGetObjectId(datum);
204  }
205  else
206  namespaceId = InvalidOid;
207 
208  /* Permission checks ... superusers can always do it */
209  if (!superuser())
210  {
211  /* Fail if object does not have an explicit owner */
212  if (Anum_owner <= 0)
213  ereport(ERROR,
214  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
215  errmsg("must be superuser to rename %s",
216  getObjectDescriptionOids(classId, objectId))));
217 
218  /* Otherwise, must be owner of the existing object */
219  datum = heap_getattr(oldtup, Anum_owner,
220  RelationGetDescr(rel), &isnull);
221  Assert(!isnull);
222  ownerId = DatumGetObjectId(datum);
223 
224  if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId)))
226  old_name);
227 
228  /* User must have CREATE privilege on the namespace */
229  if (OidIsValid(namespaceId))
230  {
231  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
232  ACL_CREATE);
233  if (aclresult != ACLCHECK_OK)
234  aclcheck_error(aclresult, OBJECT_SCHEMA,
235  get_namespace_name(namespaceId));
236  }
237  }
238 
239  /*
240  * Check for duplicate name (more friendly than unique-index failure).
241  * Since this is just a friendliness check, we can just skip it in cases
242  * where there isn't suitable support.
243  */
244  if (classId == ProcedureRelationId)
245  {
246  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
247 
248  IsThereFunctionInNamespace(new_name, proc->pronargs,
249  &proc->proargtypes, proc->pronamespace);
250  }
251  else if (classId == CollationRelationId)
252  {
254 
255  IsThereCollationInNamespace(new_name, coll->collnamespace);
256  }
257  else if (classId == OperatorClassRelationId)
258  {
259  Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
260 
261  IsThereOpClassInNamespace(new_name, opc->opcmethod,
262  opc->opcnamespace);
263  }
264  else if (classId == OperatorFamilyRelationId)
265  {
267 
268  IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
269  opf->opfnamespace);
270  }
271  else if (classId == SubscriptionRelationId)
272  {
274  CStringGetDatum(new_name)))
275  report_name_conflict(classId, new_name);
276 
277  /* Also enforce regression testing naming rules, if enabled */
278 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
279  if (strncmp(new_name, "regress_", 8) != 0)
280  elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
281 #endif
282  }
283  else if (nameCacheId >= 0)
284  {
285  if (OidIsValid(namespaceId))
286  {
287  if (SearchSysCacheExists2(nameCacheId,
288  CStringGetDatum(new_name),
289  ObjectIdGetDatum(namespaceId)))
290  report_namespace_conflict(classId, new_name, namespaceId);
291  }
292  else
293  {
294  if (SearchSysCacheExists1(nameCacheId,
295  CStringGetDatum(new_name)))
296  report_name_conflict(classId, new_name);
297  }
298  }
299 
300  /* Build modified tuple */
302  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
303  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
304  namestrcpy(&nameattrdata, new_name);
305  values[Anum_name - 1] = NameGetDatum(&nameattrdata);
306  replaces[Anum_name - 1] = true;
307  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
308  values, nulls, replaces);
309 
310  /* Perform actual update */
311  CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
312 
313  InvokeObjectPostAlterHook(classId, objectId, 0);
314 
315  /* Release memory */
316  pfree(values);
317  pfree(nulls);
318  pfree(replaces);
319  heap_freetuple(newtup);
320 
321  ReleaseSysCache(oldtup);
322 }
323 
324 /*
325  * Executes an ALTER OBJECT / RENAME TO statement. Based on the object
326  * type, the function appropriate to that type is executed.
327  *
328  * Return value is the address of the renamed object.
329  */
332 {
333  switch (stmt->renameType)
334  {
337  return RenameConstraint(stmt);
338 
339  case OBJECT_DATABASE:
340  return RenameDatabase(stmt->subname, stmt->newname);
341 
342  case OBJECT_ROLE:
343  return RenameRole(stmt->subname, stmt->newname);
344 
345  case OBJECT_SCHEMA:
346  return RenameSchema(stmt->subname, stmt->newname);
347 
348  case OBJECT_TABLESPACE:
349  return RenameTableSpace(stmt->subname, stmt->newname);
350 
351  case OBJECT_TABLE:
352  case OBJECT_SEQUENCE:
353  case OBJECT_VIEW:
354  case OBJECT_MATVIEW:
355  case OBJECT_INDEX:
357  return RenameRelation(stmt);
358 
359  case OBJECT_COLUMN:
360  case OBJECT_ATTRIBUTE:
361  return renameatt(stmt);
362 
363  case OBJECT_RULE:
364  return RenameRewriteRule(stmt->relation, stmt->subname,
365  stmt->newname);
366 
367  case OBJECT_TRIGGER:
368  return renametrig(stmt);
369 
370  case OBJECT_POLICY:
371  return rename_policy(stmt);
372 
373  case OBJECT_DOMAIN:
374  case OBJECT_TYPE:
375  return RenameType(stmt);
376 
377  case OBJECT_AGGREGATE:
378  case OBJECT_COLLATION:
379  case OBJECT_CONVERSION:
381  case OBJECT_FDW:
383  case OBJECT_FUNCTION:
384  case OBJECT_OPCLASS:
385  case OBJECT_OPFAMILY:
386  case OBJECT_LANGUAGE:
387  case OBJECT_PROCEDURE:
388  case OBJECT_ROUTINE:
391  case OBJECT_TSDICTIONARY:
392  case OBJECT_TSPARSER:
393  case OBJECT_TSTEMPLATE:
394  case OBJECT_PUBLICATION:
395  case OBJECT_SUBSCRIPTION:
396  {
397  ObjectAddress address;
398  Relation catalog;
399  Relation relation;
400 
401  address = get_object_address(stmt->renameType,
402  stmt->object,
403  &relation,
404  AccessExclusiveLock, false);
405  Assert(relation == NULL);
406 
407  catalog = table_open(address.classId, RowExclusiveLock);
409  address.objectId,
410  stmt->newname);
411  table_close(catalog, RowExclusiveLock);
412 
413  return address;
414  }
415 
416  default:
417  elog(ERROR, "unrecognized rename stmt type: %d",
418  (int) stmt->renameType);
419  return InvalidObjectAddress; /* keep compiler happy */
420  }
421 }
422 
423 /*
424  * Executes an ALTER OBJECT / [NO] DEPENDS ON EXTENSION statement.
425  *
426  * Return value is the address of the altered object. refAddress is an output
427  * argument which, if not null, receives the address of the object that the
428  * altered object now depends on.
429  */
432 {
433  ObjectAddress address;
434  ObjectAddress refAddr;
435  Relation rel;
436 
437  address =
438  get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
439  &rel, AccessExclusiveLock, false);
440 
441  /*
442  * Verify that the user is entitled to run the command.
443  *
444  * We don't check any privileges on the extension, because that's not
445  * needed. The object owner is stipulating, by running this command, that
446  * the extension owner can drop the object whenever they feel like it,
447  * which is not considered a problem.
448  */
450  stmt->objectType, address, stmt->object, rel);
451 
452  /*
453  * If a relation was involved, it would have been opened and locked. We
454  * don't need the relation here, but we'll retain the lock until commit.
455  */
456  if (rel)
457  table_close(rel, NoLock);
458 
459  refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
460  &rel, AccessExclusiveLock, false);
461  Assert(rel == NULL);
462  if (refAddress)
463  *refAddress = refAddr;
464 
465  if (stmt->remove)
466  {
469  refAddr.classId, refAddr.objectId);
470  }
471  else
472  {
473  List *currexts;
474 
475  /* Avoid duplicates */
476  currexts = getAutoExtensionsOfObject(address.classId,
477  address.objectId);
478  if (!list_member_oid(currexts, refAddr.objectId))
479  recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
480  }
481 
482  return address;
483 }
484 
485 /*
486  * Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object
487  * type, the function appropriate to that type is executed.
488  *
489  * Return value is that of the altered object.
490  *
491  * oldSchemaAddr is an output argument which, if not NULL, is set to the object
492  * address of the original schema.
493  */
496  ObjectAddress *oldSchemaAddr)
497 {
498  ObjectAddress address;
499  Oid oldNspOid;
500 
501  switch (stmt->objectType)
502  {
503  case OBJECT_EXTENSION:
504  address = AlterExtensionNamespace(strVal(stmt->object), stmt->newschema,
505  oldSchemaAddr ? &oldNspOid : NULL);
506  break;
507 
509  case OBJECT_SEQUENCE:
510  case OBJECT_TABLE:
511  case OBJECT_VIEW:
512  case OBJECT_MATVIEW:
513  address = AlterTableNamespace(stmt,
514  oldSchemaAddr ? &oldNspOid : NULL);
515  break;
516 
517  case OBJECT_DOMAIN:
518  case OBJECT_TYPE:
519  address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
520  stmt->objectType,
521  oldSchemaAddr ? &oldNspOid : NULL);
522  break;
523 
524  /* generic code path */
525  case OBJECT_AGGREGATE:
526  case OBJECT_COLLATION:
527  case OBJECT_CONVERSION:
528  case OBJECT_FUNCTION:
529  case OBJECT_OPERATOR:
530  case OBJECT_OPCLASS:
531  case OBJECT_OPFAMILY:
532  case OBJECT_PROCEDURE:
533  case OBJECT_ROUTINE:
536  case OBJECT_TSDICTIONARY:
537  case OBJECT_TSPARSER:
538  case OBJECT_TSTEMPLATE:
539  {
540  Relation catalog;
541  Relation relation;
542  Oid classId;
543  Oid nspOid;
544 
545  address = get_object_address(stmt->objectType,
546  stmt->object,
547  &relation,
549  false);
550  Assert(relation == NULL);
551  classId = address.classId;
552  catalog = table_open(classId, RowExclusiveLock);
553  nspOid = LookupCreationNamespace(stmt->newschema);
554 
555  oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
556  nspOid);
557  table_close(catalog, RowExclusiveLock);
558  }
559  break;
560 
561  default:
562  elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
563  (int) stmt->objectType);
564  return InvalidObjectAddress; /* keep compiler happy */
565  }
566 
567  if (oldSchemaAddr)
568  ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
569 
570  return address;
571 }
572 
573 /*
574  * Change an object's namespace given its classOid and object Oid.
575  *
576  * Objects that don't have a namespace should be ignored.
577  *
578  * This function is currently used only by ALTER EXTENSION SET SCHEMA,
579  * so it only needs to cover object types that can be members of an
580  * extension, and it doesn't have to deal with certain special cases
581  * such as not wanting to process array types --- those should never
582  * be direct members of an extension anyway. Nonetheless, we insist
583  * on listing all OCLASS types in the switch.
584  *
585  * Returns the OID of the object's previous namespace, or InvalidOid if
586  * object doesn't have a schema.
587  */
588 Oid
589 AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
590  ObjectAddresses *objsMoved)
591 {
592  Oid oldNspOid = InvalidOid;
593  ObjectAddress dep;
594 
595  dep.classId = classId;
596  dep.objectId = objid;
597  dep.objectSubId = 0;
598 
599  switch (getObjectClass(&dep))
600  {
601  case OCLASS_CLASS:
602  {
603  Relation rel;
604 
605  rel = relation_open(objid, AccessExclusiveLock);
606  oldNspOid = RelationGetNamespace(rel);
607 
608  AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
609 
610  relation_close(rel, NoLock);
611  break;
612  }
613 
614  case OCLASS_TYPE:
615  oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
616  break;
617 
618  case OCLASS_PROC:
619  case OCLASS_COLLATION:
620  case OCLASS_CONVERSION:
621  case OCLASS_OPERATOR:
622  case OCLASS_OPCLASS:
623  case OCLASS_OPFAMILY:
625  case OCLASS_TSPARSER:
626  case OCLASS_TSDICT:
627  case OCLASS_TSTEMPLATE:
628  case OCLASS_TSCONFIG:
629  {
630  Relation catalog;
631 
632  catalog = table_open(classId, RowExclusiveLock);
633 
634  oldNspOid = AlterObjectNamespace_internal(catalog, objid,
635  nspOid);
636 
637  table_close(catalog, RowExclusiveLock);
638  }
639  break;
640 
641  case OCLASS_CAST:
642  case OCLASS_CONSTRAINT:
643  case OCLASS_DEFAULT:
644  case OCLASS_LANGUAGE:
645  case OCLASS_LARGEOBJECT:
646  case OCLASS_AM:
647  case OCLASS_AMOP:
648  case OCLASS_AMPROC:
649  case OCLASS_REWRITE:
650  case OCLASS_TRIGGER:
651  case OCLASS_SCHEMA:
652  case OCLASS_ROLE:
654  case OCLASS_DATABASE:
655  case OCLASS_TBLSPACE:
656  case OCLASS_FDW:
658  case OCLASS_USER_MAPPING:
659  case OCLASS_DEFACL:
660  case OCLASS_EXTENSION:
663  case OCLASS_POLICY:
664  case OCLASS_PUBLICATION:
667  case OCLASS_SUBSCRIPTION:
668  case OCLASS_TRANSFORM:
669  /* ignore object types that don't have schema-qualified names */
670  break;
671 
672  /*
673  * There's intentionally no default: case here; we want the
674  * compiler to warn if a new OCLASS hasn't been handled above.
675  */
676  }
677 
678  return oldNspOid;
679 }
680 
681 /*
682  * Generic function to change the namespace of a given object, for simple
683  * cases (won't work for tables, nor other cases where we need to do more
684  * than change the namespace column of a single catalog entry).
685  *
686  * rel: catalog relation containing object (RowExclusiveLock'd by caller)
687  * objid: OID of object to change the namespace of
688  * nspOid: OID of new namespace
689  *
690  * Returns the OID of the object's previous namespace.
691  */
692 static Oid
694 {
695  Oid classId = RelationGetRelid(rel);
696  int oidCacheId = get_object_catcache_oid(classId);
697  int nameCacheId = get_object_catcache_name(classId);
698  AttrNumber Anum_name = get_object_attnum_name(classId);
699  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
700  AttrNumber Anum_owner = get_object_attnum_owner(classId);
701  Oid oldNspOid;
702  Datum name,
703  namespace;
704  bool isnull;
705  HeapTuple tup,
706  newtup;
707  Datum *values;
708  bool *nulls;
709  bool *replaces;
710 
711  tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
712  if (!HeapTupleIsValid(tup)) /* should not happen */
713  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
714  objid, RelationGetRelationName(rel));
715 
716  name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
717  Assert(!isnull);
718  namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
719  &isnull);
720  Assert(!isnull);
721  oldNspOid = DatumGetObjectId(namespace);
722 
723  /*
724  * If the object is already in the correct namespace, we don't need to do
725  * anything except fire the object access hook.
726  */
727  if (oldNspOid == nspOid)
728  {
729  InvokeObjectPostAlterHook(classId, objid, 0);
730  return oldNspOid;
731  }
732 
733  /* Check basic namespace related issues */
734  CheckSetNamespace(oldNspOid, nspOid);
735 
736  /* Permission checks ... superusers can always do it */
737  if (!superuser())
738  {
739  Datum owner;
740  Oid ownerId;
741  AclResult aclresult;
742 
743  /* Fail if object does not have an explicit owner */
744  if (Anum_owner <= 0)
745  ereport(ERROR,
746  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
747  errmsg("must be superuser to set schema of %s",
748  getObjectDescriptionOids(classId, objid))));
749 
750  /* Otherwise, must be owner of the existing object */
751  owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
752  Assert(!isnull);
753  ownerId = DatumGetObjectId(owner);
754 
755  if (!has_privs_of_role(GetUserId(), ownerId))
757  NameStr(*(DatumGetName(name))));
758 
759  /* User must have CREATE privilege on new namespace */
760  aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
761  if (aclresult != ACLCHECK_OK)
762  aclcheck_error(aclresult, OBJECT_SCHEMA,
763  get_namespace_name(nspOid));
764  }
765 
766  /*
767  * Check for duplicate name (more friendly than unique-index failure).
768  * Since this is just a friendliness check, we can just skip it in cases
769  * where there isn't suitable support.
770  */
771  if (classId == ProcedureRelationId)
772  {
773  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
774 
775  IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
776  &proc->proargtypes, nspOid);
777  }
778  else if (classId == CollationRelationId)
779  {
781 
782  IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
783  }
784  else if (classId == OperatorClassRelationId)
785  {
787 
788  IsThereOpClassInNamespace(NameStr(opc->opcname),
789  opc->opcmethod, nspOid);
790  }
791  else if (classId == OperatorFamilyRelationId)
792  {
794 
795  IsThereOpFamilyInNamespace(NameStr(opf->opfname),
796  opf->opfmethod, nspOid);
797  }
798  else if (nameCacheId >= 0 &&
799  SearchSysCacheExists2(nameCacheId, name,
800  ObjectIdGetDatum(nspOid)))
803  nspOid);
804 
805  /* Build modified tuple */
807  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
808  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
809  values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
810  replaces[Anum_namespace - 1] = true;
811  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
812  values, nulls, replaces);
813 
814  /* Perform actual update */
815  CatalogTupleUpdate(rel, &tup->t_self, newtup);
816 
817  /* Release memory */
818  pfree(values);
819  pfree(nulls);
820  pfree(replaces);
821 
822  /* update dependencies to point to the new schema */
823  changeDependencyFor(classId, objid,
824  NamespaceRelationId, oldNspOid, nspOid);
825 
826  InvokeObjectPostAlterHook(classId, objid, 0);
827 
828  return oldNspOid;
829 }
830 
831 /*
832  * Executes an ALTER OBJECT / OWNER TO statement. Based on the object
833  * type, the function appropriate to that type is executed.
834  */
837 {
838  Oid newowner = get_rolespec_oid(stmt->newowner, false);
839 
840  switch (stmt->objectType)
841  {
842  case OBJECT_DATABASE:
843  return AlterDatabaseOwner(strVal(stmt->object), newowner);
844 
845  case OBJECT_SCHEMA:
846  return AlterSchemaOwner(strVal(stmt->object), newowner);
847 
848  case OBJECT_TYPE:
849  case OBJECT_DOMAIN: /* same as TYPE */
850  return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
851  break;
852 
853  case OBJECT_FDW:
855  newowner);
856 
858  return AlterForeignServerOwner(strVal(stmt->object),
859  newowner);
860 
862  return AlterEventTriggerOwner(strVal(stmt->object),
863  newowner);
864 
865  case OBJECT_PUBLICATION:
866  return AlterPublicationOwner(strVal(stmt->object),
867  newowner);
868 
869  case OBJECT_SUBSCRIPTION:
870  return AlterSubscriptionOwner(strVal(stmt->object),
871  newowner);
872 
873  /* Generic cases */
874  case OBJECT_AGGREGATE:
875  case OBJECT_COLLATION:
876  case OBJECT_CONVERSION:
877  case OBJECT_FUNCTION:
878  case OBJECT_LANGUAGE:
879  case OBJECT_LARGEOBJECT:
880  case OBJECT_OPERATOR:
881  case OBJECT_OPCLASS:
882  case OBJECT_OPFAMILY:
883  case OBJECT_PROCEDURE:
884  case OBJECT_ROUTINE:
886  case OBJECT_TABLESPACE:
887  case OBJECT_TSDICTIONARY:
889  {
890  Relation catalog;
891  Relation relation;
892  Oid classId;
893  ObjectAddress address;
894 
895  address = get_object_address(stmt->objectType,
896  stmt->object,
897  &relation,
899  false);
900  Assert(relation == NULL);
901  classId = address.classId;
902 
903  /*
904  * XXX - get_object_address returns Oid of pg_largeobject
905  * catalog for OBJECT_LARGEOBJECT because of historical
906  * reasons. Fix up it here.
907  */
908  if (classId == LargeObjectRelationId)
909  classId = LargeObjectMetadataRelationId;
910 
911  catalog = table_open(classId, RowExclusiveLock);
912 
913  AlterObjectOwner_internal(catalog, address.objectId, newowner);
914  table_close(catalog, RowExclusiveLock);
915 
916  return address;
917  }
918  break;
919 
920  default:
921  elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
922  (int) stmt->objectType);
923  return InvalidObjectAddress; /* keep compiler happy */
924  }
925 }
926 
927 /*
928  * Generic function to change the ownership of a given object, for simple
929  * cases (won't work for tables, nor other cases where we need to do more than
930  * change the ownership column of a single catalog entry).
931  *
932  * rel: catalog relation containing object (RowExclusiveLock'd by caller)
933  * objectId: OID of object to change the ownership of
934  * new_ownerId: OID of new object owner
935  */
936 void
937 AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
938 {
939  Oid classId = RelationGetRelid(rel);
940  AttrNumber Anum_oid = get_object_attnum_oid(classId);
941  AttrNumber Anum_owner = get_object_attnum_owner(classId);
942  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
943  AttrNumber Anum_acl = get_object_attnum_acl(classId);
944  AttrNumber Anum_name = get_object_attnum_name(classId);
945  HeapTuple oldtup;
946  Datum datum;
947  bool isnull;
948  Oid old_ownerId;
949  Oid namespaceId = InvalidOid;
950 
951  oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
952  if (oldtup == NULL)
953  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
954  objectId, RelationGetRelationName(rel));
955 
956  datum = heap_getattr(oldtup, Anum_owner,
957  RelationGetDescr(rel), &isnull);
958  Assert(!isnull);
959  old_ownerId = DatumGetObjectId(datum);
960 
961  if (Anum_namespace != InvalidAttrNumber)
962  {
963  datum = heap_getattr(oldtup, Anum_namespace,
964  RelationGetDescr(rel), &isnull);
965  Assert(!isnull);
966  namespaceId = DatumGetObjectId(datum);
967  }
968 
969  if (old_ownerId != new_ownerId)
970  {
971  AttrNumber nattrs;
972  HeapTuple newtup;
973  Datum *values;
974  bool *nulls;
975  bool *replaces;
976 
977  /* Superusers can bypass permission checks */
978  if (!superuser())
979  {
980  /* must be owner */
981  if (!has_privs_of_role(GetUserId(), old_ownerId))
982  {
983  char *objname;
984  char namebuf[NAMEDATALEN];
985 
986  if (Anum_name != InvalidAttrNumber)
987  {
988  datum = heap_getattr(oldtup, Anum_name,
989  RelationGetDescr(rel), &isnull);
990  Assert(!isnull);
991  objname = NameStr(*DatumGetName(datum));
992  }
993  else
994  {
995  snprintf(namebuf, sizeof(namebuf), "%u", objectId);
996  objname = namebuf;
997  }
999  objname);
1000  }
1001  /* Must be able to become new owner */
1002  check_can_set_role(GetUserId(), new_ownerId);
1003 
1004  /* New owner must have CREATE privilege on namespace */
1005  if (OidIsValid(namespaceId))
1006  {
1007  AclResult aclresult;
1008 
1009  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
1010  ACL_CREATE);
1011  if (aclresult != ACLCHECK_OK)
1012  aclcheck_error(aclresult, OBJECT_SCHEMA,
1013  get_namespace_name(namespaceId));
1014  }
1015  }
1016 
1017  /* Build a modified tuple */
1018  nattrs = RelationGetNumberOfAttributes(rel);
1019  values = palloc0(nattrs * sizeof(Datum));
1020  nulls = palloc0(nattrs * sizeof(bool));
1021  replaces = palloc0(nattrs * sizeof(bool));
1022  values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
1023  replaces[Anum_owner - 1] = true;
1024 
1025  /*
1026  * Determine the modified ACL for the new owner. This is only
1027  * necessary when the ACL is non-null.
1028  */
1029  if (Anum_acl != InvalidAttrNumber)
1030  {
1031  datum = heap_getattr(oldtup,
1032  Anum_acl, RelationGetDescr(rel), &isnull);
1033  if (!isnull)
1034  {
1035  Acl *newAcl;
1036 
1037  newAcl = aclnewowner(DatumGetAclP(datum),
1038  old_ownerId, new_ownerId);
1039  values[Anum_acl - 1] = PointerGetDatum(newAcl);
1040  replaces[Anum_acl - 1] = true;
1041  }
1042  }
1043 
1044  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
1045  values, nulls, replaces);
1046 
1047  /* Perform actual update */
1048  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1049 
1050  /* Update owner dependency reference */
1051  if (classId == LargeObjectMetadataRelationId)
1052  classId = LargeObjectRelationId;
1053  changeDependencyOnOwner(classId, objectId, new_ownerId);
1054 
1055  /* Release memory */
1056  pfree(values);
1057  pfree(nulls);
1058  pfree(replaces);
1059  }
1060 
1061  InvokeObjectPostAlterHook(classId, objectId, 0);
1062 }
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4949
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1065
void check_can_set_role(Oid member, Oid role)
Definition: acl.c:5006
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5269
AclResult
Definition: acl.h:183
@ ACLCHECK_OK
Definition: acl.h:184
@ ACLCHECK_NOT_OWNER
Definition: acl.h:186
#define DatumGetAclP(X)
Definition: acl.h:120
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3485
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:4598
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:693
static void report_name_conflict(Oid classId, const char *name)
Definition: alter.c:77
ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
Definition: alter.c:836
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:112
ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddress)
Definition: alter.c:431
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:937
static void AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
Definition: alter.c:166
ObjectAddress ExecRenameStmt(RenameStmt *stmt)
Definition: alter.c:331
ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, ObjectAddress *oldSchemaAddr)
Definition: alter.c:495
Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: alter.c:589
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition: tablespace.c:936
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define NameStr(name)
Definition: c.h:682
#define gettext_noop(x)
Definition: c.h:1135
#define OidIsValid(objectId)
Definition: c.h:711
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
Definition: dbcommands.c:1714
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
Definition: dbcommands.c:2446
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2836
@ DEPENDENCY_AUTO_EXTENSION
Definition: dependency.h:39
@ OCLASS_OPERATOR
Definition: dependency.h:100
@ OCLASS_PARAMETER_ACL
Definition: dependency.h:124
@ OCLASS_LARGEOBJECT
Definition: dependency.h:99
@ OCLASS_FDW
Definition: dependency.h:118
@ OCLASS_OPFAMILY
Definition: dependency.h:102
@ OCLASS_DEFACL
Definition: dependency.h:121
@ OCLASS_TSPARSER
Definition: dependency.h:110
@ OCLASS_TRIGGER
Definition: dependency.h:107
@ OCLASS_DEFAULT
Definition: dependency.h:97
@ OCLASS_TSTEMPLATE
Definition: dependency.h:112
@ OCLASS_AMPROC
Definition: dependency.h:105
@ OCLASS_TBLSPACE
Definition: dependency.h:117
@ OCLASS_TSCONFIG
Definition: dependency.h:113
@ OCLASS_TYPE
Definition: dependency.h:92
@ OCLASS_LANGUAGE
Definition: dependency.h:98
@ OCLASS_CAST
Definition: dependency.h:93
@ OCLASS_SUBSCRIPTION
Definition: dependency.h:129
@ OCLASS_PUBLICATION_NAMESPACE
Definition: dependency.h:127
@ OCLASS_EXTENSION
Definition: dependency.h:122
@ OCLASS_COLLATION
Definition: dependency.h:94
@ OCLASS_FOREIGN_SERVER
Definition: dependency.h:119
@ OCLASS_REWRITE
Definition: dependency.h:106
@ OCLASS_STATISTIC_EXT
Definition: dependency.h:109
@ OCLASS_PROC
Definition: dependency.h:91
@ OCLASS_OPCLASS
Definition: dependency.h:101
@ OCLASS_CONVERSION
Definition: dependency.h:96
@ OCLASS_DATABASE
Definition: dependency.h:116
@ OCLASS_ROLE_MEMBERSHIP
Definition: dependency.h:115
@ OCLASS_SCHEMA
Definition: dependency.h:108
@ OCLASS_EVENT_TRIGGER
Definition: dependency.h:123
@ OCLASS_CLASS
Definition: dependency.h:90
@ OCLASS_TRANSFORM
Definition: dependency.h:130
@ OCLASS_ROLE
Definition: dependency.h:114
@ OCLASS_CONSTRAINT
Definition: dependency.h:95
@ OCLASS_POLICY
Definition: dependency.h:125
@ OCLASS_USER_MAPPING
Definition: dependency.h:120
@ OCLASS_PUBLICATION_REL
Definition: dependency.h:128
@ OCLASS_AM
Definition: dependency.h:103
@ OCLASS_TSDICT
Definition: dependency.h:111
@ OCLASS_PUBLICATION
Definition: dependency.h:126
@ OCLASS_AMOP
Definition: dependency.h:104
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define WARNING
Definition: elog.h:36
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
const char * name
Definition: encode.c:561
ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition: extension.c:2708
ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:415
ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:275
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
Oid MyDatabaseId
Definition: globals.c:89
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:788
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
Assert(fmt[strlen(fmt) - 1] !='\n')
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3331
void pfree(void *pointer)
Definition: mcxt.c:1306
void * palloc0(Size size)
Definition: mcxt.c:1230
Oid GetUserId(void)
Definition: miscinit.c:497
void namestrcpy(Name name, const char *str)
Definition: name.c:233
Oid LookupCreationNamespace(const char *nspname)
Definition: namespace.c:2979
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition: namespace.c:3010
#define castNode(_type_, nodeptr)
Definition: nodes.h:186
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
int get_object_catcache_name(Oid class_id)
ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
AttrNumber get_object_attnum_owner(Oid class_id)
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
AttrNumber get_object_attnum_oid(Oid class_id)
char * getObjectDescriptionOids(Oid classid, Oid objid)
AttrNumber get_object_attnum_namespace(Oid class_id)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
AttrNumber get_object_attnum_name(Oid class_id)
AttrNumber get_object_attnum_acl(Oid class_id)
int get_object_catcache_oid(Oid class_id)
const ObjectAddress InvalidObjectAddress
ObjectType get_object_type(Oid class_id, Oid object_id)
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace)
Definition: opclasscmds.c:1731
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1708
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:1902
@ OBJECT_FDW
Definition: parsenodes.h:1904
@ OBJECT_TSPARSER
Definition: parsenodes.h:1935
@ OBJECT_COLLATION
Definition: parsenodes.h:1895
@ OBJECT_OPCLASS
Definition: parsenodes.h:1912
@ OBJECT_AGGREGATE
Definition: parsenodes.h:1889
@ OBJECT_MATVIEW
Definition: parsenodes.h:1911
@ OBJECT_SCHEMA
Definition: parsenodes.h:1924
@ OBJECT_POLICY
Definition: parsenodes.h:1916
@ OBJECT_OPERATOR
Definition: parsenodes.h:1913
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:1906
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:1933
@ OBJECT_OPFAMILY
Definition: parsenodes.h:1914
@ OBJECT_DOMAIN
Definition: parsenodes.h:1900
@ OBJECT_COLUMN
Definition: parsenodes.h:1894
@ OBJECT_TABLESPACE
Definition: parsenodes.h:1930
@ OBJECT_ROLE
Definition: parsenodes.h:1921
@ OBJECT_ROUTINE
Definition: parsenodes.h:1922
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:1910
@ OBJECT_PROCEDURE
Definition: parsenodes.h:1917
@ OBJECT_EXTENSION
Definition: parsenodes.h:1903
@ OBJECT_INDEX
Definition: parsenodes.h:1908
@ OBJECT_DATABASE
Definition: parsenodes.h:1897
@ OBJECT_SEQUENCE
Definition: parsenodes.h:1925
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:1936
@ OBJECT_LANGUAGE
Definition: parsenodes.h:1909
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:1905
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:1934
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:1892
@ OBJECT_PUBLICATION
Definition: parsenodes.h:1918
@ OBJECT_RULE
Definition: parsenodes.h:1923
@ OBJECT_CONVERSION
Definition: parsenodes.h:1896
@ OBJECT_TABLE
Definition: parsenodes.h:1929
@ OBJECT_VIEW
Definition: parsenodes.h:1939
@ OBJECT_TYPE
Definition: parsenodes.h:1937
@ OBJECT_FUNCTION
Definition: parsenodes.h:1907
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:1928
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:1901
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:1926
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:1927
@ OBJECT_TRIGGER
Definition: parsenodes.h:1932
#define ACL_CREATE
Definition: parsenodes.h:92
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:57
#define NAMEDATALEN
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition: pg_depend.c:456
List * getAutoExtensionsOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:777
long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype, Oid refclassId, Oid refobjectId)
Definition: pg_depend.c:397
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:313
ObjectAddress rename_policy(RenameStmt *stmt)
Definition: policy.c:1099
#define snprintf
Definition: port.h:238
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:670
static Name DatumGetName(Datum X)
Definition: postgres.h:708
uintptr_t Datum
Definition: postgres.h:412
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:590
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:721
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:698
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId)
#define RelationGetRelid(relation)
Definition: rel.h:501
#define RelationGetDescr(relation)
Definition: rel.h:527
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:507
#define RelationGetRelationName(relation)
Definition: rel.h:535
#define RelationGetNamespace(relation)
Definition: rel.h:542
ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName)
ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId)
Definition: schemacmds.c:312
ObjectAddress RenameSchema(const char *oldname, const char *newname)
Definition: schemacmds.c:231
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
RoleSpec * newowner
Definition: parsenodes.h:3216
ObjectType objectType
Definition: parsenodes.h:3213
ItemPointerData t_self
Definition: htup.h:65
Definition: pg_list.h:52
Definition: nodes.h:118
RangeVar * relation
Definition: parsenodes.h:3169
ObjectType renameType
Definition: parsenodes.h:3167
char * newname
Definition: parsenodes.h:3173
char * subname
Definition: parsenodes.h:3171
Node * object
Definition: parsenodes.h:3170
Definition: c.h:677
ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId)
bool superuser(void)
Definition: superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:179
@ SUBSCRIPTIONNAME
Definition: syscache.h:98
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:190
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:188
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
ObjectAddress RenameRelation(RenameStmt *stmt)
Definition: tablecmds.c:3797
ObjectAddress renameatt(RenameStmt *stmt)
Definition: tablecmds.c:3603
void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: tablecmds.c:16474
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
Definition: tablecmds.c:16403
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition: tablecmds.c:3747
ObjectAddress renametrig(RenameStmt *stmt)
Definition: trigger.c:1473
ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
Definition: typecmds.c:3674
ObjectAddress RenameType(RenameStmt *stmt)
Definition: typecmds.c:3597
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: typecmds.c:3914
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition: typecmds.c:3877
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition: user.c:1227
#define strVal(v)
Definition: value.h:82