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