PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
defrem.h File Reference
#include "catalog/objectaddress.h"
#include "nodes/parsenodes.h"
#include "utils/array.h"
Include dependency graph for defrem.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void RemoveObjects (DropStmt *stmt)
 
ObjectAddress DefineIndex (Oid relationId, IndexStmt *stmt, Oid indexRelationId, bool is_alter_table, bool check_rights, bool skip_build, bool quiet)
 
Oid ReindexIndex (RangeVar *indexRelation, int options)
 
Oid ReindexTable (RangeVar *relation, int options)
 
void ReindexMultipleTables (const char *objectName, ReindexObjectType objectKind, int options)
 
char * makeObjectName (const char *name1, const char *name2, const char *label)
 
char * ChooseRelationName (const char *name1, const char *name2, const char *label, Oid namespaceid)
 
bool CheckIndexCompatible (Oid oldId, char *accessMethodName, List *attributeList, List *exclusionOpNames)
 
Oid GetDefaultOpClass (Oid type_id, Oid am_id)
 
Oid ResolveOpClass (List *opclass, Oid attrType, char *accessMethodName, Oid accessMethodId)
 
ObjectAddress CreateFunction (ParseState *pstate, CreateFunctionStmt *stmt)
 
void RemoveFunctionById (Oid funcOid)
 
void SetFunctionReturnType (Oid funcOid, Oid newRetType)
 
void SetFunctionArgType (Oid funcOid, int argIndex, Oid newArgType)
 
ObjectAddress AlterFunction (ParseState *pstate, AlterFunctionStmt *stmt)
 
ObjectAddress CreateCast (CreateCastStmt *stmt)
 
void DropCastById (Oid castOid)
 
ObjectAddress CreateTransform (CreateTransformStmt *stmt)
 
void DropTransformById (Oid transformOid)
 
void IsThereFunctionInNamespace (const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
 
void ExecuteDoStmt (DoStmt *stmt)
 
Oid get_cast_oid (Oid sourcetypeid, Oid targettypeid, bool missing_ok)
 
Oid get_transform_oid (Oid type_id, Oid lang_id, bool missing_ok)
 
void interpret_function_parameter_list (ParseState *pstate, List *parameters, Oid languageOid, bool is_aggregate, oidvector **parameterTypes, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType)
 
ObjectAddress DefineOperator (List *names, List *parameters)
 
void RemoveOperatorById (Oid operOid)
 
ObjectAddress AlterOperator (AlterOperatorStmt *stmt)
 
ObjectAddress DefineAggregate (ParseState *pstate, List *name, List *args, bool oldstyle, List *parameters)
 
ObjectAddress DefineOpClass (CreateOpClassStmt *stmt)
 
ObjectAddress DefineOpFamily (CreateOpFamilyStmt *stmt)
 
Oid AlterOpFamily (AlterOpFamilyStmt *stmt)
 
void RemoveOpClassById (Oid opclassOid)
 
void RemoveOpFamilyById (Oid opfamilyOid)
 
void RemoveAmOpEntryById (Oid entryOid)
 
void RemoveAmProcEntryById (Oid entryOid)
 
void IsThereOpClassInNamespace (const char *opcname, Oid opcmethod, Oid opcnamespace)
 
void IsThereOpFamilyInNamespace (const char *opfname, Oid opfmethod, Oid opfnamespace)
 
Oid get_opclass_oid (Oid amID, List *opclassname, bool missing_ok)
 
Oid get_opfamily_oid (Oid amID, List *opfamilyname, bool missing_ok)
 
ObjectAddress DefineTSParser (List *names, List *parameters)
 
void RemoveTSParserById (Oid prsId)
 
ObjectAddress DefineTSDictionary (List *names, List *parameters)
 
void RemoveTSDictionaryById (Oid dictId)
 
ObjectAddress AlterTSDictionary (AlterTSDictionaryStmt *stmt)
 
ObjectAddress DefineTSTemplate (List *names, List *parameters)
 
void RemoveTSTemplateById (Oid tmplId)
 
ObjectAddress DefineTSConfiguration (List *names, List *parameters, ObjectAddress *copied)
 
void RemoveTSConfigurationById (Oid cfgId)
 
ObjectAddress AlterTSConfiguration (AlterTSConfigurationStmt *stmt)
 
textserialize_deflist (List *deflist)
 
Listdeserialize_deflist (Datum txt)
 
ObjectAddress AlterForeignServerOwner (const char *name, Oid newOwnerId)
 
void AlterForeignServerOwner_oid (Oid, Oid newOwnerId)
 
ObjectAddress AlterForeignDataWrapperOwner (const char *name, Oid newOwnerId)
 
void AlterForeignDataWrapperOwner_oid (Oid fwdId, Oid newOwnerId)
 
ObjectAddress CreateForeignDataWrapper (CreateFdwStmt *stmt)
 
ObjectAddress AlterForeignDataWrapper (AlterFdwStmt *stmt)
 
void RemoveForeignDataWrapperById (Oid fdwId)
 
ObjectAddress CreateForeignServer (CreateForeignServerStmt *stmt)
 
ObjectAddress AlterForeignServer (AlterForeignServerStmt *stmt)
 
void RemoveForeignServerById (Oid srvId)
 
ObjectAddress CreateUserMapping (CreateUserMappingStmt *stmt)
 
ObjectAddress AlterUserMapping (AlterUserMappingStmt *stmt)
 
Oid RemoveUserMapping (DropUserMappingStmt *stmt)
 
void RemoveUserMappingById (Oid umId)
 
void CreateForeignTable (CreateForeignTableStmt *stmt, Oid relid)
 
void ImportForeignSchema (ImportForeignSchemaStmt *stmt)
 
Datum transformGenericOptions (Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
 
ObjectAddress CreateAccessMethod (CreateAmStmt *stmt)
 
void RemoveAccessMethodById (Oid amOid)
 
Oid get_index_am_oid (const char *amname, bool missing_ok)
 
Oid get_am_oid (const char *amname, bool missing_ok)
 
char * get_am_name (Oid amOid)
 
char * defGetString (DefElem *def)
 
double defGetNumeric (DefElem *def)
 
bool defGetBoolean (DefElem *def)
 
int32 defGetInt32 (DefElem *def)
 
int64 defGetInt64 (DefElem *def)
 
ListdefGetQualifiedName (DefElem *def)
 
TypeNamedefGetTypeName (DefElem *def)
 
int defGetTypeLength (DefElem *def)
 
ListdefGetStringList (DefElem *def)
 

Function Documentation

ObjectAddress AlterForeignDataWrapper ( AlterFdwStmt stmt)

Definition at line 673 of file foreigncmds.c.

References Anum_pg_foreign_data_wrapper_fdwhandler, Anum_pg_foreign_data_wrapper_fdwoptions, Anum_pg_foreign_data_wrapper_fdwvalidator, CatalogTupleUpdate(), ObjectAddress::classId, CStringGetDatum, DatumGetPointer, deleteDependencyRecordsForClass(), DEPENDENCY_NORMAL, ereport, errcode(), errhint(), errmsg(), ERROR, AlterFdwStmt::fdwname, FOREIGNDATAWRAPPERNAME, FOREIGNDATAWRAPPEROID, ForeignDataWrapperRelationId, AlterFdwStmt::func_options, GETSTRUCT, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, Natts_pg_foreign_data_wrapper, NULL, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, AlterFdwStmt::options, parse_func_options(), PointerGetDatum, PointerIsValid, ProcedureRelationId, recordDependencyOn(), RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), and WARNING.

Referenced by ProcessUtilitySlow().

674 {
675  Relation rel;
676  HeapTuple tp;
679  bool repl_null[Natts_pg_foreign_data_wrapper];
680  bool repl_repl[Natts_pg_foreign_data_wrapper];
681  Oid fdwId;
682  bool isnull;
683  Datum datum;
684  bool handler_given;
685  bool validator_given;
686  Oid fdwhandler;
687  Oid fdwvalidator;
688  ObjectAddress myself;
689 
691 
692  /* Must be super user */
693  if (!superuser())
694  ereport(ERROR,
695  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
696  errmsg("permission denied to alter foreign-data wrapper \"%s\"",
697  stmt->fdwname),
698  errhint("Must be superuser to alter a foreign-data wrapper.")));
699 
701  CStringGetDatum(stmt->fdwname));
702 
703  if (!HeapTupleIsValid(tp))
704  ereport(ERROR,
705  (errcode(ERRCODE_UNDEFINED_OBJECT),
706  errmsg("foreign-data wrapper \"%s\" does not exist", stmt->fdwname)));
707 
708  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
709  fdwId = HeapTupleGetOid(tp);
710 
711  memset(repl_val, 0, sizeof(repl_val));
712  memset(repl_null, false, sizeof(repl_null));
713  memset(repl_repl, false, sizeof(repl_repl));
714 
716  &handler_given, &fdwhandler,
717  &validator_given, &fdwvalidator);
718 
719  if (handler_given)
720  {
721  repl_val[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = ObjectIdGetDatum(fdwhandler);
722  repl_repl[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = true;
723 
724  /*
725  * It could be that the behavior of accessing foreign table changes
726  * with the new handler. Warn about this.
727  */
729  (errmsg("changing the foreign-data wrapper handler can change behavior of existing foreign tables")));
730  }
731 
732  if (validator_given)
733  {
734  repl_val[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
735  repl_repl[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = true;
736 
737  /*
738  * It could be that existing options for the FDW or dependent SERVER,
739  * USER MAPPING or FOREIGN TABLE objects are no longer valid according
740  * to the new validator. Warn about this.
741  */
742  if (OidIsValid(fdwvalidator))
744  (errmsg("changing the foreign-data wrapper validator can cause "
745  "the options for dependent objects to become invalid")));
746  }
747  else
748  {
749  /*
750  * Validator is not changed, but we need it for validating options.
751  */
752  fdwvalidator = fdwForm->fdwvalidator;
753  }
754 
755  /*
756  * If options specified, validate and update.
757  */
758  if (stmt->options)
759  {
760  /* Extract the current options */
762  tp,
764  &isnull);
765  if (isnull)
766  datum = PointerGetDatum(NULL);
767 
768  /* Transform the options */
770  datum,
771  stmt->options,
772  fdwvalidator);
773 
774  if (PointerIsValid(DatumGetPointer(datum)))
775  repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
776  else
777  repl_null[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
778 
779  repl_repl[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
780  }
781 
782  /* Everything looks good - update the tuple */
783  tp = heap_modify_tuple(tp, RelationGetDescr(rel),
784  repl_val, repl_null, repl_repl);
785 
786  CatalogTupleUpdate(rel, &tp->t_self, tp);
787 
788  heap_freetuple(tp);
789 
791 
792  /* Update function dependencies if we changed them */
793  if (handler_given || validator_given)
794  {
795  ObjectAddress referenced;
796 
797  /*
798  * Flush all existing dependency records of this FDW on functions; we
799  * assume there can be none other than the ones we are fixing.
800  */
802  fdwId,
805 
806  /* And build new ones. */
807 
808  if (OidIsValid(fdwhandler))
809  {
810  referenced.classId = ProcedureRelationId;
811  referenced.objectId = fdwhandler;
812  referenced.objectSubId = 0;
813  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
814  }
815 
816  if (OidIsValid(fdwvalidator))
817  {
818  referenced.classId = ProcedureRelationId;
819  referenced.objectId = fdwvalidator;
820  referenced.objectSubId = 0;
821  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
822  }
823  }
824 
826 
828 
829  return myself;
830 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static void parse_func_options(List *func_options, bool *handler_given, Oid *fdwhandler, bool *validator_given, Oid *fdwvalidator)
Definition: foreigncmds.c:516
#define RelationGetDescr(relation)
Definition: rel.h:425
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define PointerGetDatum(X)
Definition: postgres.h:564
#define ProcedureRelationId
Definition: pg_proc.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define Anum_pg_foreign_data_wrapper_fdwhandler
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
char * fdwname
Definition: parsenodes.h:2099
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
List * func_options
Definition: parsenodes.h:2100
#define WARNING
Definition: elog.h:40
uintptr_t Datum
Definition: postgres.h:374
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:241
#define Anum_pg_foreign_data_wrapper_fdwvalidator
#define Natts_pg_foreign_data_wrapper
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ForeignDataWrapperRelationId
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define DatumGetPointer(X)
Definition: postgres.h:557
List * options
Definition: parsenodes.h:2101
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define PointerIsValid(pointer)
Definition: c.h:522
#define Anum_pg_foreign_data_wrapper_fdwoptions
ObjectAddress AlterForeignDataWrapperOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 277 of file foreigncmds.c.

References AlterForeignDataWrapperOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPERNAME, ForeignDataWrapperRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, ObjectAddressSet, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by ExecAlterOwnerStmt().

278 {
279  Oid fdwId;
280  HeapTuple tup;
281  Relation rel;
282  ObjectAddress address;
283 
285 
287 
288  if (!HeapTupleIsValid(tup))
289  ereport(ERROR,
290  (errcode(ERRCODE_UNDEFINED_OBJECT),
291  errmsg("foreign-data wrapper \"%s\" does not exist", name)));
292 
293  fdwId = HeapTupleGetOid(tup);
294 
295  AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
296 
298 
299  heap_freetuple(tup);
300 
302 
303  return address;
304 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define ForeignDataWrapperRelationId
const char * name
Definition: encode.c:521
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
Definition: foreigncmds.c:207
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void AlterForeignDataWrapperOwner_oid ( Oid  fwdId,
Oid  newOwnerId 
)

Definition at line 312 of file foreigncmds.c.

References AlterForeignDataWrapperOwner_internal(), ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, ForeignDataWrapperRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by shdepReassignOwned().

313 {
314  HeapTuple tup;
315  Relation rel;
316 
318 
320 
321  if (!HeapTupleIsValid(tup))
322  ereport(ERROR,
323  (errcode(ERRCODE_UNDEFINED_OBJECT),
324  errmsg("foreign-data wrapper with OID %u does not exist", fwdId)));
325 
326  AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
327 
328  heap_freetuple(tup);
329 
331 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define ForeignDataWrapperRelationId
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
Definition: foreigncmds.c:207
ObjectAddress AlterForeignServer ( AlterForeignServerStmt stmt)

Definition at line 972 of file foreigncmds.c.

References ACL_KIND_FOREIGN_SERVER, aclcheck_error(), ACLCHECK_NOT_OWNER, Anum_pg_foreign_server_srvoptions, Anum_pg_foreign_server_srvversion, CatalogTupleUpdate(), CStringGetDatum, CStringGetTextDatum, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, ForeignDataWrapper::fdwvalidator, FOREIGNSERVERNAME, FOREIGNSERVEROID, ForeignServerRelationId, GetForeignDataWrapper(), GETSTRUCT, GetUserId(), AlterForeignServerStmt::has_version, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, Natts_pg_foreign_server, NULL, ObjectAddressSet, AlterForeignServerStmt::options, pg_foreign_server_ownercheck(), PointerGetDatum, PointerIsValid, RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, AlterForeignServerStmt::servername, SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), and AlterForeignServerStmt::version.

Referenced by ProcessUtilitySlow().

973 {
974  Relation rel;
975  HeapTuple tp;
976  Datum repl_val[Natts_pg_foreign_server];
977  bool repl_null[Natts_pg_foreign_server];
978  bool repl_repl[Natts_pg_foreign_server];
979  Oid srvId;
980  Form_pg_foreign_server srvForm;
981  ObjectAddress address;
982 
984 
986  CStringGetDatum(stmt->servername));
987 
988  if (!HeapTupleIsValid(tp))
989  ereport(ERROR,
990  (errcode(ERRCODE_UNDEFINED_OBJECT),
991  errmsg("server \"%s\" does not exist", stmt->servername)));
992 
993  srvId = HeapTupleGetOid(tp);
994  srvForm = (Form_pg_foreign_server) GETSTRUCT(tp);
995 
996  /*
997  * Only owner or a superuser can ALTER a SERVER.
998  */
1001  stmt->servername);
1002 
1003  memset(repl_val, 0, sizeof(repl_val));
1004  memset(repl_null, false, sizeof(repl_null));
1005  memset(repl_repl, false, sizeof(repl_repl));
1006 
1007  if (stmt->has_version)
1008  {
1009  /*
1010  * Change the server VERSION string.
1011  */
1012  if (stmt->version)
1013  repl_val[Anum_pg_foreign_server_srvversion - 1] =
1015  else
1016  repl_null[Anum_pg_foreign_server_srvversion - 1] = true;
1017 
1018  repl_repl[Anum_pg_foreign_server_srvversion - 1] = true;
1019  }
1020 
1021  if (stmt->options)
1022  {
1023  ForeignDataWrapper *fdw = GetForeignDataWrapper(srvForm->srvfdw);
1024  Datum datum;
1025  bool isnull;
1026 
1027  /* Extract the current srvoptions */
1029  tp,
1031  &isnull);
1032  if (isnull)
1033  datum = PointerGetDatum(NULL);
1034 
1035  /* Prepare the options array */
1037  datum,
1038  stmt->options,
1039  fdw->fdwvalidator);
1040 
1041  if (PointerIsValid(DatumGetPointer(datum)))
1042  repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
1043  else
1044  repl_null[Anum_pg_foreign_server_srvoptions - 1] = true;
1045 
1046  repl_repl[Anum_pg_foreign_server_srvoptions - 1] = true;
1047  }
1048 
1049  /* Everything looks good - update the tuple */
1050  tp = heap_modify_tuple(tp, RelationGetDescr(rel),
1051  repl_val, repl_null, repl_repl);
1052 
1053  CatalogTupleUpdate(rel, &tp->t_self, tp);
1054 
1056 
1057  ObjectAddressSet(address, ForeignServerRelationId, srvId);
1058 
1059  heap_freetuple(tp);
1060 
1062 
1063  return address;
1064 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define Anum_pg_foreign_server_srvversion
#define PointerGetDatum(X)
Definition: postgres.h:564
bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid)
Definition: aclchk.c:4885
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define Natts_pg_foreign_server
uintptr_t Datum
Definition: postgres.h:374
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
FormData_pg_foreign_server * Form_pg_foreign_server
#define ForeignServerRelationId
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define DatumGetPointer(X)
Definition: postgres.h:557
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CStringGetTextDatum(s)
Definition: builtins.h:90
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define Anum_pg_foreign_server_srvoptions
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define PointerIsValid(pointer)
Definition: c.h:522
ObjectAddress AlterForeignServerOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 414 of file foreigncmds.c.

References AlterForeignServerOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNSERVERNAME, ForeignServerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, ObjectAddressSet, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by ExecAlterOwnerStmt().

415 {
416  Oid servOid;
417  HeapTuple tup;
418  Relation rel;
419  ObjectAddress address;
420 
422 
424 
425  if (!HeapTupleIsValid(tup))
426  ereport(ERROR,
427  (errcode(ERRCODE_UNDEFINED_OBJECT),
428  errmsg("server \"%s\" does not exist", name)));
429 
430  servOid = HeapTupleGetOid(tup);
431 
432  AlterForeignServerOwner_internal(rel, tup, newOwnerId);
433 
434  ObjectAddressSet(address, ForeignServerRelationId, servOid);
435 
436  heap_freetuple(tup);
437 
439 
440  return address;
441 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define ForeignServerRelationId
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
Definition: foreigncmds.c:337
const char * name
Definition: encode.c:521
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void AlterForeignServerOwner_oid ( Oid  ,
Oid  newOwnerId 
)

Definition at line 447 of file foreigncmds.c.

References AlterForeignServerOwner_internal(), ereport, errcode(), errmsg(), ERROR, FOREIGNSERVEROID, ForeignServerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, and SearchSysCacheCopy1.

Referenced by shdepReassignOwned().

448 {
449  HeapTuple tup;
450  Relation rel;
451 
453 
455 
456  if (!HeapTupleIsValid(tup))
457  ereport(ERROR,
458  (errcode(ERRCODE_UNDEFINED_OBJECT),
459  errmsg("foreign server with OID %u does not exist", srvId)));
460 
461  AlterForeignServerOwner_internal(rel, tup, newOwnerId);
462 
463  heap_freetuple(tup);
464 
466 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define ForeignServerRelationId
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
Definition: foreigncmds.c:337
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
ObjectAddress AlterFunction ( ParseState pstate,
AlterFunctionStmt stmt 
)

Definition at line 1165 of file functioncmds.c.

References ACL_KIND_PROC, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterFunctionStmt::actions, Anum_pg_proc_proconfig, DefElem::arg, CatalogTupleUpdate(), compute_common_attribute(), DatumGetArrayTypeP, defGetNumeric(), DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, AlterFunctionStmt::func, FuncWithArgs::funcargs, FuncWithArgs::funcname, GETSTRUCT, GetUserId(), heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, interpret_func_parallel(), interpret_func_volatility(), intVal, InvokeObjectPostAlterHook, lfirst, LookupFuncNameTypeNames(), NameListToString(), Natts_pg_proc, NIL, NoLock, NULL, ObjectAddressSet, ObjectIdGetDatum, pg_proc_ownercheck(), PointerGetDatum, ProcedureRelationId, PROCOID, RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, and update_proconfig_value().

Referenced by ProcessUtilitySlow().

1166 {
1167  HeapTuple tup;
1168  Oid funcOid;
1169  Form_pg_proc procForm;
1170  Relation rel;
1171  ListCell *l;
1172  DefElem *volatility_item = NULL;
1173  DefElem *strict_item = NULL;
1174  DefElem *security_def_item = NULL;
1175  DefElem *leakproof_item = NULL;
1176  List *set_items = NIL;
1177  DefElem *cost_item = NULL;
1178  DefElem *rows_item = NULL;
1179  DefElem *parallel_item = NULL;
1180  ObjectAddress address;
1181 
1183 
1184  funcOid = LookupFuncNameTypeNames(stmt->func->funcname,
1185  stmt->func->funcargs,
1186  false);
1187 
1188  tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid));
1189  if (!HeapTupleIsValid(tup)) /* should not happen */
1190  elog(ERROR, "cache lookup failed for function %u", funcOid);
1191 
1192  procForm = (Form_pg_proc) GETSTRUCT(tup);
1193 
1194  /* Permission check: must own function */
1195  if (!pg_proc_ownercheck(funcOid, GetUserId()))
1197  NameListToString(stmt->func->funcname));
1198 
1199  if (procForm->proisagg)
1200  ereport(ERROR,
1201  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1202  errmsg("\"%s\" is an aggregate function",
1203  NameListToString(stmt->func->funcname))));
1204 
1205  /* Examine requested actions. */
1206  foreach(l, stmt->actions)
1207  {
1208  DefElem *defel = (DefElem *) lfirst(l);
1209 
1210  if (compute_common_attribute(pstate,
1211  defel,
1212  &volatility_item,
1213  &strict_item,
1214  &security_def_item,
1215  &leakproof_item,
1216  &set_items,
1217  &cost_item,
1218  &rows_item,
1219  &parallel_item) == false)
1220  elog(ERROR, "option \"%s\" not recognized", defel->defname);
1221  }
1222 
1223  if (volatility_item)
1224  procForm->provolatile = interpret_func_volatility(volatility_item);
1225  if (strict_item)
1226  procForm->proisstrict = intVal(strict_item->arg);
1227  if (security_def_item)
1228  procForm->prosecdef = intVal(security_def_item->arg);
1229  if (leakproof_item)
1230  {
1231  procForm->proleakproof = intVal(leakproof_item->arg);
1232  if (procForm->proleakproof && !superuser())
1233  ereport(ERROR,
1234  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1235  errmsg("only superuser can define a leakproof function")));
1236  }
1237  if (cost_item)
1238  {
1239  procForm->procost = defGetNumeric(cost_item);
1240  if (procForm->procost <= 0)
1241  ereport(ERROR,
1242  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1243  errmsg("COST must be positive")));
1244  }
1245  if (rows_item)
1246  {
1247  procForm->prorows = defGetNumeric(rows_item);
1248  if (procForm->prorows <= 0)
1249  ereport(ERROR,
1250  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1251  errmsg("ROWS must be positive")));
1252  if (!procForm->proretset)
1253  ereport(ERROR,
1254  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1255  errmsg("ROWS is not applicable when function does not return a set")));
1256  }
1257  if (set_items)
1258  {
1259  Datum datum;
1260  bool isnull;
1261  ArrayType *a;
1262  Datum repl_val[Natts_pg_proc];
1263  bool repl_null[Natts_pg_proc];
1264  bool repl_repl[Natts_pg_proc];
1265 
1266  /* extract existing proconfig setting */
1267  datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull);
1268  a = isnull ? NULL : DatumGetArrayTypeP(datum);
1269 
1270  /* update according to each SET or RESET item, left to right */
1271  a = update_proconfig_value(a, set_items);
1272 
1273  /* update the tuple */
1274  memset(repl_repl, false, sizeof(repl_repl));
1275  repl_repl[Anum_pg_proc_proconfig - 1] = true;
1276 
1277  if (a == NULL)
1278  {
1279  repl_val[Anum_pg_proc_proconfig - 1] = (Datum) 0;
1280  repl_null[Anum_pg_proc_proconfig - 1] = true;
1281  }
1282  else
1283  {
1284  repl_val[Anum_pg_proc_proconfig - 1] = PointerGetDatum(a);
1285  repl_null[Anum_pg_proc_proconfig - 1] = false;
1286  }
1287 
1288  tup = heap_modify_tuple(tup, RelationGetDescr(rel),
1289  repl_val, repl_null, repl_repl);
1290  }
1291  if (parallel_item)
1292  procForm->proparallel = interpret_func_parallel(parallel_item);
1293 
1294  /* Do the update */
1295  CatalogTupleUpdate(rel, &tup->t_self, tup);
1296 
1298 
1299  ObjectAddressSet(address, ProcedureRelationId, funcOid);
1300 
1301  heap_close(rel, NoLock);
1302  heap_freetuple(tup);
1303 
1304  return address;
1305 }
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
List * funcargs
Definition: parsenodes.h:1774
#define PointerGetDatum(X)
Definition: postgres.h:564
#define ProcedureRelationId
Definition: pg_proc.h:33
double defGetNumeric(DefElem *def)
Definition: define.c:85
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
FuncWithArgs * func
Definition: parsenodes.h:2646
#define Anum_pg_proc_proconfig
Definition: pg_proc.h:117
#define Natts_pg_proc
Definition: pg_proc.h:89
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
Definition: parse_func.c:1940
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
static char interpret_func_volatility(DefElem *defel)
Definition: functioncmds.c:532
Node * arg
Definition: parsenodes.h:676
char * NameListToString(List *names)
Definition: namespace.c:2897
uintptr_t Datum
Definition: postgres.h:374
static ArrayType * update_proconfig_value(ArrayType *a, List *set_items)
Definition: functioncmds.c:575
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
List * funcname
Definition: parsenodes.h:1773
#define elog
Definition: elog.h:219
static bool compute_common_attribute(ParseState *pstate, DefElem *defel, DefElem **volatility_item, DefElem **strict_item, DefElem **security_item, DefElem **leakproof_item, List **set_items, DefElem **cost_item, DefElem **rows_item, DefElem **parallel_item)
Definition: functioncmds.c:453
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
Definition: pg_list.h:45
bool pg_proc_ownercheck(Oid proc_oid, Oid roleid)
Definition: aclchk.c:4599
static char interpret_func_parallel(DefElem *defel)
Definition: functioncmds.c:550
#define DatumGetArrayTypeP(X)
Definition: array.h:242
ObjectAddress AlterOperator ( AlterOperatorStmt stmt)

Definition at line 385 of file operatorcmds.c.

References ACL_KIND_OPER, aclcheck_error(), ACLCHECK_NOT_OWNER, Anum_pg_operator_oprjoin, Anum_pg_operator_oprrest, DefElem::arg, BOOLOID, CatalogTupleUpdate(), defGetQualifiedName(), DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, GetUserId(), heap_close, heap_modify_tuple(), heap_open(), i, InvalidOid, InvokeObjectPostAlterHook, lfirst, linitial, LookupOperNameTypeNames(), lsecond, makeOperatorDependencies(), NameStr, Natts_pg_operator, NIL, NoLock, NULL, ObjectIdGetDatum, OidIsValid, AlterOperatorStmt::operargs, OperatorRelationId, AlterOperatorStmt::opername, OPEROID, AlterOperatorStmt::options, pg_oper_ownercheck(), pg_strcasecmp(), RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, ValidateJoinEstimator(), ValidateRestrictionEstimator(), and values.

Referenced by ProcessUtilitySlow().

386 {
387  ObjectAddress address;
388  Oid oprId;
389  Relation catalog;
390  HeapTuple tup;
391  Form_pg_operator oprForm;
392  int i;
393  ListCell *pl;
395  bool nulls[Natts_pg_operator];
396  bool replaces[Natts_pg_operator];
397  List *restrictionName = NIL; /* optional restrict. sel. procedure */
398  bool updateRestriction = false;
399  Oid restrictionOid;
400  List *joinName = NIL; /* optional join sel. procedure */
401  bool updateJoin = false;
402  Oid joinOid;
403 
404  /* Look up the operator */
405  oprId = LookupOperNameTypeNames(NULL, stmt->opername,
406  (TypeName *) linitial(stmt->operargs),
407  (TypeName *) lsecond(stmt->operargs),
408  false, -1);
411  if (tup == NULL)
412  elog(ERROR, "cache lookup failed for operator %u", oprId);
413  oprForm = (Form_pg_operator) GETSTRUCT(tup);
414 
415  /* Process options */
416  foreach(pl, stmt->options)
417  {
418  DefElem *defel = (DefElem *) lfirst(pl);
419  List *param;
420 
421  if (defel->arg == NULL)
422  param = NIL; /* NONE, removes the function */
423  else
424  param = defGetQualifiedName(defel);
425 
426  if (pg_strcasecmp(defel->defname, "restrict") == 0)
427  {
428  restrictionName = param;
429  updateRestriction = true;
430  }
431  else if (pg_strcasecmp(defel->defname, "join") == 0)
432  {
433  joinName = param;
434  updateJoin = true;
435  }
436 
437  /*
438  * The rest of the options that CREATE accepts cannot be changed.
439  * Check for them so that we can give a meaningful error message.
440  */
441  else if (pg_strcasecmp(defel->defname, "leftarg") == 0 ||
442  pg_strcasecmp(defel->defname, "rightarg") == 0 ||
443  pg_strcasecmp(defel->defname, "procedure") == 0 ||
444  pg_strcasecmp(defel->defname, "commutator") == 0 ||
445  pg_strcasecmp(defel->defname, "negator") == 0 ||
446  pg_strcasecmp(defel->defname, "hashes") == 0 ||
447  pg_strcasecmp(defel->defname, "merges") == 0)
448  {
449  ereport(ERROR,
450  (errcode(ERRCODE_SYNTAX_ERROR),
451  errmsg("operator attribute \"%s\" cannot be changed",
452  defel->defname)));
453  }
454  else
455  ereport(ERROR,
456  (errcode(ERRCODE_SYNTAX_ERROR),
457  errmsg("operator attribute \"%s\" not recognized",
458  defel->defname)));
459  }
460 
461  /* Check permissions. Must be owner. */
462  if (!pg_oper_ownercheck(oprId, GetUserId()))
464  NameStr(oprForm->oprname));
465 
466  /*
467  * Look up restriction and join estimators if specified
468  */
469  if (restrictionName)
470  restrictionOid = ValidateRestrictionEstimator(restrictionName);
471  else
472  restrictionOid = InvalidOid;
473  if (joinName)
474  joinOid = ValidateJoinEstimator(joinName);
475  else
476  joinOid = InvalidOid;
477 
478  /* Perform additional checks, like OperatorCreate does */
479  if (!(OidIsValid(oprForm->oprleft) && OidIsValid(oprForm->oprright)))
480  {
481  /* If it's not a binary op, these things mustn't be set: */
482  if (OidIsValid(joinOid))
483  ereport(ERROR,
484  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
485  errmsg("only binary operators can have join selectivity")));
486  }
487 
488  if (oprForm->oprresult != BOOLOID)
489  {
490  if (OidIsValid(restrictionOid))
491  ereport(ERROR,
492  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
493  errmsg("only boolean operators can have restriction selectivity")));
494  if (OidIsValid(joinOid))
495  ereport(ERROR,
496  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
497  errmsg("only boolean operators can have join selectivity")));
498  }
499 
500  /* Update the tuple */
501  for (i = 0; i < Natts_pg_operator; ++i)
502  {
503  values[i] = (Datum) 0;
504  replaces[i] = false;
505  nulls[i] = false;
506  }
507  if (updateRestriction)
508  {
509  replaces[Anum_pg_operator_oprrest - 1] = true;
510  values[Anum_pg_operator_oprrest - 1] = restrictionOid;
511  }
512  if (updateJoin)
513  {
514  replaces[Anum_pg_operator_oprjoin - 1] = true;
515  values[Anum_pg_operator_oprjoin - 1] = joinOid;
516  }
517 
518  tup = heap_modify_tuple(tup, RelationGetDescr(catalog),
519  values, nulls, replaces);
520 
521  CatalogTupleUpdate(catalog, &tup->t_self, tup);
522 
523  address = makeOperatorDependencies(tup, true);
524 
526 
527  heap_close(catalog, NoLock);
528 
529  return address;
530 }
Oid LookupOperNameTypeNames(ParseState *pstate, List *opername, TypeName *oprleft, TypeName *oprright, bool noError, int location)
Definition: parse_oper.c:142
#define NIL
Definition: pg_list.h:69
#define OperatorRelationId
Definition: pg_operator.h:32
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate)
Definition: pg_operator.c:764
static Oid ValidateJoinEstimator(List *joinName)
Definition: operatorcmds.c:296
bool pg_oper_ownercheck(Oid oper_oid, Oid roleid)
Definition: aclchk.c:4573
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define lsecond(l)
Definition: pg_list.h:114
#define Anum_pg_operator_oprjoin
Definition: pg_operator.h:78
#define linitial(l)
Definition: pg_list.h:110
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
static Oid ValidateRestrictionEstimator(List *restrictionName)
Definition: operatorcmds.c:261
Node * arg
Definition: parsenodes.h:676
#define Anum_pg_operator_oprrest
Definition: pg_operator.h:77
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define BOOLOID
Definition: pg_type.h:288
FormData_pg_operator* Form_pg_operator
Definition: pg_operator.h:57
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
#define Natts_pg_operator
Definition: pg_operator.h:64
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:495
char * defname
Definition: parsenodes.h:675
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
Definition: pg_list.h:45
Oid AlterOpFamily ( AlterOpFamilyStmt stmt)

Definition at line 771 of file opclasscmds.c.

References AlterOpFamilyAdd(), AlterOpFamilyDrop(), AMNAME, AlterOpFamilyStmt::amname, IndexAmRoutine::amstrategies, IndexAmRoutine::amsupport, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, get_opfamily_oid(), GetIndexAmRoutineByAmId(), HeapTupleGetOid, HeapTupleIsValid, AlterOpFamilyStmt::isDrop, AlterOpFamilyStmt::items, AlterOpFamilyStmt::opfamilyname, ReleaseSysCache(), SearchSysCache1, and superuser().

Referenced by ProcessUtilitySlow().

772 {
773  Oid amoid, /* our AM's oid */
774  opfamilyoid; /* oid of opfamily */
775  int maxOpNumber, /* amstrategies value */
776  maxProcNumber; /* amsupport value */
777  HeapTuple tup;
778  IndexAmRoutine *amroutine;
779 
780  /* Get necessary info about access method */
782  if (!HeapTupleIsValid(tup))
783  ereport(ERROR,
784  (errcode(ERRCODE_UNDEFINED_OBJECT),
785  errmsg("access method \"%s\" does not exist",
786  stmt->amname)));
787 
788  amoid = HeapTupleGetOid(tup);
789  amroutine = GetIndexAmRoutineByAmId(amoid, false);
790  ReleaseSysCache(tup);
791 
792  maxOpNumber = amroutine->amstrategies;
793  /* if amstrategies is zero, just enforce that op numbers fit in int16 */
794  if (maxOpNumber <= 0)
795  maxOpNumber = SHRT_MAX;
796  maxProcNumber = amroutine->amsupport;
797 
798  /* XXX Should we make any privilege check against the AM? */
799 
800  /* Look up the opfamily */
801  opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
802 
803  /*
804  * Currently, we require superuser privileges to alter an opfamily.
805  *
806  * XXX re-enable NOT_USED code sections below if you remove this test.
807  */
808  if (!superuser())
809  ereport(ERROR,
810  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
811  errmsg("must be superuser to alter an operator family")));
812 
813  /*
814  * ADD and DROP cases need separate code from here on down.
815  */
816  if (stmt->isDrop)
817  AlterOpFamilyDrop(stmt, amoid, opfamilyoid,
818  maxOpNumber, maxProcNumber, stmt->items);
819  else
820  AlterOpFamilyAdd(stmt, amoid, opfamilyoid,
821  maxOpNumber, maxProcNumber, stmt->items);
822 
823  return opfamilyoid;
824 }
uint16 amsupport
Definition: amapi.h:169
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, int maxOpNumber, int maxProcNumber, List *items)
Definition: opclasscmds.c:963
#define ERROR
Definition: elog.h:43
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, int maxOpNumber, int maxProcNumber, List *items)
Definition: opclasscmds.c:830
Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
Definition: opclasscmds.c:141
uint16 amstrategies
Definition: amapi.h:167
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
ObjectAddress AlterTSConfiguration ( AlterTSConfigurationStmt stmt)

Definition at line 1173 of file tsearchcmds.c.

References ACL_KIND_TSCONFIGURATION, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterTSConfigurationStmt::cfgname, AlterTSConfigurationStmt::dicts, DropConfigurationMapping(), ereport, errcode(), errmsg(), ERROR, GetTSConfigTuple(), GetUserId(), heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, makeConfigurationDependencies(), MakeConfigurationMapping(), NameListToString(), ObjectAddressSet, pg_ts_config_ownercheck(), ReleaseSysCache(), RowExclusiveLock, AlterTSConfigurationStmt::tokentype, TSConfigMapRelationId, and TSConfigRelationId.

Referenced by ProcessUtilitySlow().

1174 {
1175  HeapTuple tup;
1176  Oid cfgId;
1177  Relation relMap;
1178  ObjectAddress address;
1179 
1180  /* Find the configuration */
1181  tup = GetTSConfigTuple(stmt->cfgname);
1182  if (!HeapTupleIsValid(tup))
1183  ereport(ERROR,
1184  (errcode(ERRCODE_UNDEFINED_OBJECT),
1185  errmsg("text search configuration \"%s\" does not exist",
1186  NameListToString(stmt->cfgname))));
1187 
1188  cfgId = HeapTupleGetOid(tup);
1189 
1190  /* must be owner */
1193  NameListToString(stmt->cfgname));
1194 
1196 
1197  /* Add or drop mappings */
1198  if (stmt->dicts)
1199  MakeConfigurationMapping(stmt, tup, relMap);
1200  else if (stmt->tokentype)
1201  DropConfigurationMapping(stmt, tup, relMap);
1202 
1203  /* Update dependencies */
1204  makeConfigurationDependencies(tup, true, relMap);
1205 
1207  HeapTupleGetOid(tup), 0);
1208 
1209  ObjectAddressSet(address, TSConfigRelationId, cfgId);
1210 
1211  heap_close(relMap, RowExclusiveLock);
1212 
1213  ReleaseSysCache(tup);
1214 
1215  return address;
1216 }
Oid GetUserId(void)
Definition: miscinit.c:283
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:4831
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
Definition: tsearchcmds.c:873
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
static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1439
#define TSConfigRelationId
Definition: pg_ts_config.h:31
#define TSConfigMapRelationId
#define ERROR
Definition: elog.h:43
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
static HeapTuple GetTSConfigTuple(List *names)
Definition: tsearchcmds.c:848
char * NameListToString(List *names)
Definition: namespace.c:2897
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1278
ObjectAddress AlterTSDictionary ( AlterTSDictionaryStmt stmt)

Definition at line 525 of file tsearchcmds.c.

References ACL_KIND_TSDICTIONARY, aclcheck_error(), ACLCHECK_NOT_OWNER, Anum_pg_ts_dict_dictinitoption, DefElem::arg, CatalogTupleUpdate(), DefElem::defname, deserialize_deflist(), AlterTSDictionaryStmt::dictname, elog, ERROR, get_ts_dict_oid(), GETSTRUCT, GetUserId(), heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, InvokeObjectPostAlterHook, lappend(), lfirst, list_delete_cell(), list_head(), lnext, NameListToString(), Natts_pg_ts_dict, next, NIL, NULL, ObjectAddressSet, ObjectIdGetDatum, AlterTSDictionaryStmt::options, pg_strcasecmp(), pg_ts_dict_ownercheck(), PointerGetDatum, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, serialize_deflist(), SysCacheGetAttr(), HeapTupleData::t_self, TSDictionaryRelationId, TSDICTOID, and verify_dictoptions().

Referenced by ProcessUtilitySlow().

526 {
527  HeapTuple tup,
528  newtup;
529  Relation rel;
530  Oid dictId;
531  ListCell *pl;
532  List *dictoptions;
533  Datum opt;
534  bool isnull;
535  Datum repl_val[Natts_pg_ts_dict];
536  bool repl_null[Natts_pg_ts_dict];
537  bool repl_repl[Natts_pg_ts_dict];
538  ObjectAddress address;
539 
540  dictId = get_ts_dict_oid(stmt->dictname, false);
541 
543 
545 
546  if (!HeapTupleIsValid(tup))
547  elog(ERROR, "cache lookup failed for text search dictionary %u",
548  dictId);
549 
550  /* must be owner */
551  if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
553  NameListToString(stmt->dictname));
554 
555  /* deserialize the existing set of options */
556  opt = SysCacheGetAttr(TSDICTOID, tup,
558  &isnull);
559  if (isnull)
560  dictoptions = NIL;
561  else
562  dictoptions = deserialize_deflist(opt);
563 
564  /*
565  * Modify the options list as per specified changes
566  */
567  foreach(pl, stmt->options)
568  {
569  DefElem *defel = (DefElem *) lfirst(pl);
570  ListCell *cell;
571  ListCell *prev;
572  ListCell *next;
573 
574  /*
575  * Remove any matches ...
576  */
577  prev = NULL;
578  for (cell = list_head(dictoptions); cell; cell = next)
579  {
580  DefElem *oldel = (DefElem *) lfirst(cell);
581 
582  next = lnext(cell);
583  if (pg_strcasecmp(oldel->defname, defel->defname) == 0)
584  dictoptions = list_delete_cell(dictoptions, cell, prev);
585  else
586  prev = cell;
587  }
588 
589  /*
590  * and add new value if it's got one
591  */
592  if (defel->arg)
593  dictoptions = lappend(dictoptions, defel);
594  }
595 
596  /*
597  * Validate
598  */
599  verify_dictoptions(((Form_pg_ts_dict) GETSTRUCT(tup))->dicttemplate,
600  dictoptions);
601 
602  /*
603  * Looks good, update
604  */
605  memset(repl_val, 0, sizeof(repl_val));
606  memset(repl_null, false, sizeof(repl_null));
607  memset(repl_repl, false, sizeof(repl_repl));
608 
609  if (dictoptions)
610  repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
611  PointerGetDatum(serialize_deflist(dictoptions));
612  else
613  repl_null[Anum_pg_ts_dict_dictinitoption - 1] = true;
614  repl_repl[Anum_pg_ts_dict_dictinitoption - 1] = true;
615 
616  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
617  repl_val, repl_null, repl_repl);
618 
619  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
620 
622 
623  ObjectAddressSet(address, TSDictionaryRelationId, dictId);
624 
625  /*
626  * NOTE: because we only support altering the options, not the template,
627  * there is no need to update dependencies. This might have to change if
628  * the options ever reference inside-the-database objects.
629  */
630 
631  heap_freetuple(newtup);
632  ReleaseSysCache(tup);
633 
635 
636  return address;
637 }
#define NIL
Definition: pg_list.h:69
#define Natts_pg_ts_dict
Definition: pg_ts_dict.h:51
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static int32 next
Definition: blutils.c:210
bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid)
Definition: aclchk.c:4804
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
#define PointerGetDatum(X)
Definition: postgres.h:564
List * deserialize_deflist(Datum txt)
Definition: tsearchcmds.c:1562
#define heap_close(r, l)
Definition: heapam.h:97
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2220
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define TSDictionaryRelationId
Definition: pg_ts_dict.h:31
ItemPointerData t_self
Definition: htup.h:65
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:45
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
Node * arg
Definition: parsenodes.h:676
List * lappend(List *list, void *datum)
Definition: list.c:128
char * NameListToString(List *names)
Definition: namespace.c:2897
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
text * serialize_deflist(List *deflist)
Definition: tsearchcmds.c:1517
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
static void verify_dictoptions(Oid tmplId, List *dictoptions)
Definition: tsearchcmds.c:354
#define Anum_pg_ts_dict_dictinitoption
Definition: pg_ts_dict.h:56
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
char * defname
Definition: parsenodes.h:675
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
Definition: pg_list.h:45
ObjectAddress AlterUserMapping ( AlterUserMappingStmt stmt)

Definition at line 1222 of file foreigncmds.c.

References ACL_ID_PUBLIC, Anum_pg_user_mapping_umoptions, CatalogTupleUpdate(), DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, get_rolespec_oid(), GetForeignDataWrapper(), GetForeignServerByName(), GetSysCacheOid2, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, MappingUserName, Natts_pg_user_mapping, NULL, ObjectAddressSet, ObjectIdGetDatum, OidIsValid, AlterUserMappingStmt::options, PointerGetDatum, PointerIsValid, RelationGetDescr, ROLESPEC_PUBLIC, RoleSpec::roletype, RowExclusiveLock, SearchSysCacheCopy1, ForeignServer::serverid, AlterUserMappingStmt::servername, SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), AlterUserMappingStmt::user, user_mapping_ddl_aclcheck(), USERMAPPINGOID, UserMappingRelationId, and USERMAPPINGUSERSERVER.

Referenced by ProcessUtilitySlow().

1223 {
1224  Relation rel;
1225  HeapTuple tp;
1226  Datum repl_val[Natts_pg_user_mapping];
1227  bool repl_null[Natts_pg_user_mapping];
1228  bool repl_repl[Natts_pg_user_mapping];
1229  Oid useId;
1230  Oid umId;
1231  ForeignServer *srv;
1232  ObjectAddress address;
1233  RoleSpec *role = (RoleSpec *) stmt->user;
1234 
1236 
1237  if (role->roletype == ROLESPEC_PUBLIC)
1238  useId = ACL_ID_PUBLIC;
1239  else
1240  useId = get_rolespec_oid(stmt->user, false);
1241 
1242  srv = GetForeignServerByName(stmt->servername, false);
1243 
1245  ObjectIdGetDatum(useId),
1246  ObjectIdGetDatum(srv->serverid));
1247  if (!OidIsValid(umId))
1248  ereport(ERROR,
1249  (errcode(ERRCODE_UNDEFINED_OBJECT),
1250  errmsg("user mapping \"%s\" does not exist for the server",
1251  MappingUserName(useId))));
1252 
1253  user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
1254 
1256 
1257  if (!HeapTupleIsValid(tp))
1258  elog(ERROR, "cache lookup failed for user mapping %u", umId);
1259 
1260  memset(repl_val, 0, sizeof(repl_val));
1261  memset(repl_null, false, sizeof(repl_null));
1262  memset(repl_repl, false, sizeof(repl_repl));
1263 
1264  if (stmt->options)
1265  {
1266  ForeignDataWrapper *fdw;
1267  Datum datum;
1268  bool isnull;
1269 
1270  /*
1271  * Process the options.
1272  */
1273 
1274  fdw = GetForeignDataWrapper(srv->fdwid);
1275 
1277  tp,
1279  &isnull);
1280  if (isnull)
1281  datum = PointerGetDatum(NULL);
1282 
1283  /* Prepare the options array */
1285  datum,
1286  stmt->options,
1287  fdw->fdwvalidator);
1288 
1289  if (PointerIsValid(DatumGetPointer(datum)))
1290  repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
1291  else
1292  repl_null[Anum_pg_user_mapping_umoptions - 1] = true;
1293 
1294  repl_repl[Anum_pg_user_mapping_umoptions - 1] = true;
1295  }
1296 
1297  /* Everything looks good - update the tuple */
1298  tp = heap_modify_tuple(tp, RelationGetDescr(rel),
1299  repl_val, repl_null, repl_repl);
1300 
1301  CatalogTupleUpdate(rel, &tp->t_self, tp);
1302 
1303  ObjectAddressSet(address, UserMappingRelationId, umId);
1304 
1305  heap_freetuple(tp);
1306 
1308 
1309  return address;
1310 }
#define RelationGetDescr(relation)
Definition: rel.h:425
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define PointerGetDatum(X)
Definition: postgres.h:564
int errcode(int sqlerrcode)
Definition: elog.c:575
static void user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
Definition: foreigncmds.c:1097
#define heap_close(r, l)
Definition: heapam.h:97
#define Natts_pg_user_mapping
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define Anum_pg_user_mapping_umoptions
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition: foreign.c:148
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
RoleSpecType roletype
Definition: parsenodes.h:319
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5147
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define DatumGetPointer(X)
Definition: postgres.h:557
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define UserMappingRelationId
#define ACL_ID_PUBLIC
Definition: acl.h:39
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define PointerIsValid(pointer)
Definition: c.h:522
Oid serverid
Definition: foreign.h:47
#define MappingUserName(userid)
Definition: foreign.h:20
bool CheckIndexCompatible ( Oid  oldId,
char *  accessMethodName,
List attributeList,
List exclusionOpNames 
)

Definition at line 117 of file indexcmds.c.

References AccessShareLock, IndexAmRoutine::amcanorder, AMNAME, Anum_pg_index_indclass, Anum_pg_index_indcollation, Anum_pg_index_indexprs, Anum_pg_index_indpred, Assert, tupleDesc::attrs, ComputeIndexAttrs(), CurrentMemoryContext, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, get_opclass_input_type(), GetIndexAmRoutine(), GETSTRUCT, heap_attisnull(), HeapTupleGetOid, HeapTupleIsValid, i, IndexInfo::ii_AmCache, IndexInfo::ii_Context, IndexInfo::ii_ExclusionOps, IndexInfo::ii_ExclusionProcs, IndexInfo::ii_ExclusionStrats, IndexInfo::ii_Expressions, IndexInfo::ii_ExpressionsState, IndexInfo::ii_PredicateState, index_close(), INDEX_MAX_KEYS, index_open(), IndexGetRelation(), IndexIsValid, INDEXRELID, IsPolymorphicType, list_length(), makeNode, NIL, NoLock, NULL, ObjectIdGetDatum, op_input_types(), palloc(), PointerGetDatum, RelationData::rd_att, RelationGetExclusionInfo(), ReleaseSysCache(), SearchSysCache1, SysCacheGetAttr(), and oidvector::values.

Referenced by TryReuseIndex().

121 {
122  bool isconstraint;
123  Oid *typeObjectId;
124  Oid *collationObjectId;
125  Oid *classObjectId;
126  Oid accessMethodId;
127  Oid relationId;
128  HeapTuple tuple;
129  Form_pg_index indexForm;
130  Form_pg_am accessMethodForm;
131  IndexAmRoutine *amRoutine;
132  bool amcanorder;
133  int16 *coloptions;
134  IndexInfo *indexInfo;
135  int numberOfAttributes;
136  int old_natts;
137  bool isnull;
138  bool ret = true;
139  oidvector *old_indclass;
140  oidvector *old_indcollation;
141  Relation irel;
142  int i;
143  Datum d;
144 
145  /* Caller should already have the relation locked in some way. */
146  relationId = IndexGetRelation(oldId, false);
147 
148  /*
149  * We can pretend isconstraint = false unconditionally. It only serves to
150  * decide the text of an error message that should never happen for us.
151  */
152  isconstraint = false;
153 
154  numberOfAttributes = list_length(attributeList);
155  Assert(numberOfAttributes > 0);
156  Assert(numberOfAttributes <= INDEX_MAX_KEYS);
157 
158  /* look up the access method */
159  tuple = SearchSysCache1(AMNAME, PointerGetDatum(accessMethodName));
160  if (!HeapTupleIsValid(tuple))
161  ereport(ERROR,
162  (errcode(ERRCODE_UNDEFINED_OBJECT),
163  errmsg("access method \"%s\" does not exist",
164  accessMethodName)));
165  accessMethodId = HeapTupleGetOid(tuple);
166  accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
167  amRoutine = GetIndexAmRoutine(accessMethodForm->amhandler);
168  ReleaseSysCache(tuple);
169 
170  amcanorder = amRoutine->amcanorder;
171 
172  /*
173  * Compute the operator classes, collations, and exclusion operators for
174  * the new index, so we can test whether it's compatible with the existing
175  * one. Note that ComputeIndexAttrs might fail here, but that's OK:
176  * DefineIndex would have called this function with the same arguments
177  * later on, and it would have failed then anyway.
178  */
179  indexInfo = makeNode(IndexInfo);
180  indexInfo->ii_Expressions = NIL;
181  indexInfo->ii_ExpressionsState = NIL;
182  indexInfo->ii_PredicateState = NIL;
183  indexInfo->ii_ExclusionOps = NULL;
184  indexInfo->ii_ExclusionProcs = NULL;
185  indexInfo->ii_ExclusionStrats = NULL;
186  indexInfo->ii_AmCache = NULL;
187  indexInfo->ii_Context = CurrentMemoryContext;
188  typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
189  collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
190  classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
191  coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
192  ComputeIndexAttrs(indexInfo,
193  typeObjectId, collationObjectId, classObjectId,
194  coloptions, attributeList,
195  exclusionOpNames, relationId,
196  accessMethodName, accessMethodId,
197  amcanorder, isconstraint);
198 
199 
200  /* Get the soon-obsolete pg_index tuple. */
202  if (!HeapTupleIsValid(tuple))
203  elog(ERROR, "cache lookup failed for index %u", oldId);
204  indexForm = (Form_pg_index) GETSTRUCT(tuple);
205 
206  /*
207  * We don't assess expressions or predicates; assume incompatibility.
208  * Also, if the index is invalid for any reason, treat it as incompatible.
209  */
210  if (!(heap_attisnull(tuple, Anum_pg_index_indpred) &&
212  IndexIsValid(indexForm)))
213  {
214  ReleaseSysCache(tuple);
215  return false;
216  }
217 
218  /* Any change in operator class or collation breaks compatibility. */
219  old_natts = indexForm->indnatts;
220  Assert(old_natts == numberOfAttributes);
221 
223  Assert(!isnull);
224  old_indcollation = (oidvector *) DatumGetPointer(d);
225 
226  d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indclass, &isnull);
227  Assert(!isnull);
228  old_indclass = (oidvector *) DatumGetPointer(d);
229 
230  ret = (memcmp(old_indclass->values, classObjectId,
231  old_natts * sizeof(Oid)) == 0 &&
232  memcmp(old_indcollation->values, collationObjectId,
233  old_natts * sizeof(Oid)) == 0);
234 
235  ReleaseSysCache(tuple);
236 
237  if (!ret)
238  return false;
239 
240  /* For polymorphic opcintype, column type changes break compatibility. */
241  irel = index_open(oldId, AccessShareLock); /* caller probably has a lock */
242  for (i = 0; i < old_natts; i++)
243  {
244  if (IsPolymorphicType(get_opclass_input_type(classObjectId[i])) &&
245  irel->rd_att->attrs[i]->atttypid != typeObjectId[i])
246  {
247  ret = false;
248  break;
249  }
250  }
251 
252  /* Any change in exclusion operator selections breaks compatibility. */
253  if (ret && indexInfo->ii_ExclusionOps != NULL)
254  {
255  Oid *old_operators,
256  *old_procs;
257  uint16 *old_strats;
258 
259  RelationGetExclusionInfo(irel, &old_operators, &old_procs, &old_strats);
260  ret = memcmp(old_operators, indexInfo->ii_ExclusionOps,
261  old_natts * sizeof(Oid)) == 0;
262 
263  /* Require an exact input type match for polymorphic operators. */
264  if (ret)
265  {
266  for (i = 0; i < old_natts && ret; i++)
267  {
268  Oid left,
269  right;
270 
271  op_input_types(indexInfo->ii_ExclusionOps[i], &left, &right);
272  if ((IsPolymorphicType(left) || IsPolymorphicType(right)) &&
273  irel->rd_att->attrs[i]->atttypid != typeObjectId[i])
274  {
275  ret = false;
276  break;
277  }
278  }
279  }
280  }
281 
282  index_close(irel, NoLock);
283  return ret;
284 }
signed short int16
Definition: c.h:252
#define NIL
Definition: pg_list.h:69
Definition: c.h:474
MemoryContext ii_Context
Definition: execnodes.h:82
Oid IndexGetRelation(Oid indexId, bool missing_ok)
Definition: index.c:3281
void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, uint16 **strategies)
Definition: relcache.c:4966
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define IndexIsValid(indexForm)
Definition: pg_index.h:107
#define PointerGetDatum(X)
Definition: postgres.h:564
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define Anum_pg_index_indclass
Definition: pg_index.h:89
#define AccessShareLock
Definition: lockdefs.h:36
Oid * ii_ExclusionProcs
Definition: execnodes.h:72
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
List * ii_ExpressionsState
Definition: execnodes.h:68
unsigned short uint16
Definition: c.h:264
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define IsPolymorphicType(typid)
Definition: pg_type.h:733
static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *typeOidP, Oid *collationOidP, Oid *classOidP, int16 *colOptionP, List *attList, List *exclusionOpNames, Oid relId, char *accessMethodName, Oid accessMethodId, bool amcanorder, bool isconstraint)
Definition: indexcmds.c:999
IndexAmRoutine * GetIndexAmRoutine(Oid amhandler)
Definition: amapi.c:33
List * ii_PredicateState
Definition: execnodes.h:70
#define NoLock
Definition: lockdefs.h:34
Oid values[FLEXIBLE_ARRAY_MEMBER]
Definition: c.h:482
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
Definition: lsyscache.c:1135
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define ereport(elevel, rest)
Definition: elog.h:122
void * ii_AmCache
Definition: execnodes.h:81
FormData_pg_index * Form_pg_index
Definition: pg_index.h:67
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
TupleDesc rd_att
Definition: rel.h:114
#define Anum_pg_index_indpred
Definition: pg_index.h:92
#define makeNode(_type_)
Definition: nodes.h:556
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
List * ii_Expressions
Definition: execnodes.h:67
#define Assert(condition)
Definition: c.h:671
#define INDEX_MAX_KEYS
static int list_length(const List *l)
Definition: pg_list.h:89
bool amcanorder
Definition: amapi.h:171
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
#define DatumGetPointer(X)
Definition: postgres.h:557
#define Anum_pg_index_indcollation
Definition: pg_index.h:88
Oid * ii_ExclusionOps
Definition: execnodes.h:71
FormData_pg_am * Form_pg_am
Definition: pg_am.h:46
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
uint16 * ii_ExclusionStrats
Definition: execnodes.h:73
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define Anum_pg_index_indexprs
Definition: pg_index.h:91
Oid get_opclass_input_type(Oid opclass)
Definition: lsyscache.c:1037
char* ChooseRelationName ( const char *  name1,
const char *  name2,
const char *  label,
Oid  namespaceid 
)

Definition at line 1571 of file indexcmds.c.

References get_relname_relid(), makeObjectName(), NAMEDATALEN, NULL, OidIsValid, pfree(), snprintf(), and StrNCpy.

Referenced by ChooseIndexName(), and transformColumnDefinition().

1573 {
1574  int pass = 0;
1575  char *relname = NULL;
1576  char modlabel[NAMEDATALEN];
1577 
1578  /* try the unmodified label first */
1579  StrNCpy(modlabel, label, sizeof(modlabel));
1580 
1581  for (;;)
1582  {
1583  relname = makeObjectName(name1, name2, modlabel);
1584 
1585  if (!OidIsValid(get_relname_relid(relname, namespaceid)))
1586  break;
1587 
1588  /* found a conflict, so try a new name component */
1589  pfree(relname);
1590  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
1591  }
1592 
1593  return relname;
1594 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define OidIsValid(objectId)
Definition: c.h:534
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:1491
#define NAMEDATALEN
void pfree(void *pointer)
Definition: mcxt.c:992
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1651
static char * label
Definition: pg_basebackup.c:84
#define NULL
Definition: c.h:226
#define StrNCpy(dst, src, len)
Definition: c.h:826
ObjectAddress CreateAccessMethod ( CreateAmStmt stmt)

Definition at line 41 of file amcmds.c.

References AccessMethodRelationId, AMNAME, CreateAmStmt::amname, CreateAmStmt::amtype, Anum_pg_am_amhandler, Anum_pg_am_amname, Anum_pg_am_amtype, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CStringGetDatum, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, GetSysCacheOid1, CreateAmStmt::handler_name, heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), lookup_index_am_handler_func(), namein(), Natts_pg_am, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, ProcedureRelationId, recordDependencyOn(), recordDependencyOnCurrentExtension(), RelationGetDescr, RowExclusiveLock, superuser(), and values.

Referenced by ProcessUtilitySlow().

42 {
43  Relation rel;
44  ObjectAddress myself;
45  ObjectAddress referenced;
46  Oid amoid;
47  Oid amhandler;
48  bool nulls[Natts_pg_am];
50  HeapTuple tup;
51 
53 
54  /* Must be super user */
55  if (!superuser())
56  ereport(ERROR,
57  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
58  errmsg("permission denied to create access method \"%s\"",
59  stmt->amname),
60  errhint("Must be superuser to create an access method.")));
61 
62  /* Check if name is used */
64  if (OidIsValid(amoid))
65  {
66  ereport(ERROR,
68  errmsg("access method \"%s\" already exists",
69  stmt->amname)));
70  }
71 
72  /*
73  * Get the handler function oid, verifying the AM type while at it.
74  */
75  amhandler = lookup_index_am_handler_func(stmt->handler_name, stmt->amtype);
76 
77  /*
78  * Insert tuple into pg_am.
79  */
80  memset(values, 0, sizeof(values));
81  memset(nulls, false, sizeof(nulls));
82 
83  values[Anum_pg_am_amname - 1] =
85  values[Anum_pg_am_amhandler - 1] = ObjectIdGetDatum(amhandler);
86  values[Anum_pg_am_amtype - 1] = CharGetDatum(stmt->amtype);
87 
88  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
89 
90  amoid = CatalogTupleInsert(rel, tup);
91  heap_freetuple(tup);
92 
94  myself.objectId = amoid;
95  myself.objectSubId = 0;
96 
97  /* Record dependency on handler function */
98  referenced.classId = ProcedureRelationId;
99  referenced.objectId = amhandler;
100  referenced.objectSubId = 0;
101 
102  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
103 
104  recordDependencyOnCurrentExtension(&myself, false);
105 
107 
108  return myself;
109 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
int errhint(const char *fmt,...)
Definition: elog.c:987
#define RelationGetDescr(relation)
Definition: rel.h:425
#define ProcedureRelationId
Definition: pg_proc.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
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:555
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:176
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
char * amname
Definition: parsenodes.h:2229
#define AccessMethodRelationId
Definition: pg_am.h:32
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
static Oid lookup_index_am_handler_func(List *handler_name, char amtype)
Definition: amcmds.c:242
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_am_amtype
Definition: pg_am.h:55
uintptr_t Datum
Definition: postgres.h:374
List * handler_name
Definition: parsenodes.h:2230
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Anum_pg_am_amhandler
Definition: pg_am.h:54
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define Natts_pg_am
Definition: pg_am.h:52
#define CharGetDatum(X)
Definition: postgres.h:424
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Anum_pg_am_amname
Definition: pg_am.h:53
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
ObjectAddress CreateCast ( CreateCastStmt stmt)

Definition at line 1379 of file functioncmds.c.

References ACL_USAGE, aclcheck_error_type(), ACLCHECK_OK, Anum_pg_cast_castcontext, Anum_pg_cast_castfunc, Anum_pg_cast_castmethod, Anum_pg_cast_castsource, Anum_pg_cast_casttarget, BOOLOID, CastRelationId, CASTSOURCETARGET, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, COERCION_ASSIGNMENT, COERCION_CODE_ASSIGNMENT, COERCION_CODE_EXPLICIT, COERCION_CODE_IMPLICIT, COERCION_EXPLICIT, COERCION_IMPLICIT, COERCION_METHOD_BINARY, COERCION_METHOD_FUNCTION, COERCION_METHOD_INOUT, CreateCastStmt::context, DEPENDENCY_NORMAL, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, format_type_be(), CreateCastStmt::func, FuncWithArgs::funcargs, FuncWithArgs::funcname, get_element_type(), get_typlenbyvalalign(), get_typtype(), GETSTRUCT, GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), HeapTupleIsValid, CreateCastStmt::inout, INT4OID, InvalidOid, InvokeObjectPostCreateHook, IsBinaryCoercible(), LookupFuncNameTypeNames(), MemSet, Natts_pg_cast, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, pg_type_aclcheck(), pg_type_ownercheck(), ProcedureRelationId, PROCOID, PROVOLATILE_VOLATILE, recordDependencyOn(), recordDependencyOnCurrentExtension(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, SearchSysCache2, CreateCastStmt::sourcetype, superuser(), CreateCastStmt::targettype, TypeNameToString(), typenameTypeId(), TypeRelationId, TYPTYPE_COMPOSITE, TYPTYPE_DOMAIN, TYPTYPE_ENUM, TYPTYPE_PSEUDO, values, and WARNING.

Referenced by ProcessUtilitySlow().

1380 {
1381  Oid sourcetypeid;
1382  Oid targettypeid;
1383  char sourcetyptype;
1384  char targettyptype;
1385  Oid funcid;
1386  Oid castid;
1387  int nargs;
1388  char castcontext;
1389  char castmethod;
1390  Relation relation;
1391  HeapTuple tuple;
1393  bool nulls[Natts_pg_cast];
1394  ObjectAddress myself,
1395  referenced;
1396  AclResult aclresult;
1397 
1398  sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
1399  targettypeid = typenameTypeId(NULL, stmt->targettype);
1400  sourcetyptype = get_typtype(sourcetypeid);
1401  targettyptype = get_typtype(targettypeid);
1402 
1403  /* No pseudo-types allowed */
1404  if (sourcetyptype == TYPTYPE_PSEUDO)
1405  ereport(ERROR,
1406  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1407  errmsg("source data type %s is a pseudo-type",
1408  TypeNameToString(stmt->sourcetype))));
1409 
1410  if (targettyptype == TYPTYPE_PSEUDO)
1411  ereport(ERROR,
1412  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1413  errmsg("target data type %s is a pseudo-type",
1414  TypeNameToString(stmt->targettype))));
1415 
1416  /* Permission check */
1417  if (!pg_type_ownercheck(sourcetypeid, GetUserId())
1418  && !pg_type_ownercheck(targettypeid, GetUserId()))
1419  ereport(ERROR,
1420  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1421  errmsg("must be owner of type %s or type %s",
1422  format_type_be(sourcetypeid),
1423  format_type_be(targettypeid))));
1424 
1425  aclresult = pg_type_aclcheck(sourcetypeid, GetUserId(), ACL_USAGE);
1426  if (aclresult != ACLCHECK_OK)
1427  aclcheck_error_type(aclresult, sourcetypeid);
1428 
1429  aclresult = pg_type_aclcheck(targettypeid, GetUserId(), ACL_USAGE);
1430  if (aclresult != ACLCHECK_OK)
1431  aclcheck_error_type(aclresult, targettypeid);
1432 
1433  /* Domains are allowed for historical reasons, but we warn */
1434  if (sourcetyptype == TYPTYPE_DOMAIN)
1435  ereport(WARNING,
1436  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1437  errmsg("cast will be ignored because the source data type is a domain")));
1438 
1439  else if (targettyptype == TYPTYPE_DOMAIN)
1440  ereport(WARNING,
1441  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1442  errmsg("cast will be ignored because the target data type is a domain")));
1443 
1444  /* Determine the cast method */
1445  if (stmt->func != NULL)
1446  castmethod = COERCION_METHOD_FUNCTION;
1447  else if (stmt->inout)
1448  castmethod = COERCION_METHOD_INOUT;
1449  else
1450  castmethod = COERCION_METHOD_BINARY;
1451 
1452  if (castmethod == COERCION_METHOD_FUNCTION)
1453  {
1454  Form_pg_proc procstruct;
1455 
1456  funcid = LookupFuncNameTypeNames(stmt->func->funcname,
1457  stmt->func->funcargs,
1458  false);
1459 
1460  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1461  if (!HeapTupleIsValid(tuple))
1462  elog(ERROR, "cache lookup failed for function %u", funcid);
1463 
1464  procstruct = (Form_pg_proc) GETSTRUCT(tuple);
1465  nargs = procstruct->pronargs;
1466  if (nargs < 1 || nargs > 3)
1467  ereport(ERROR,
1468  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1469  errmsg("cast function must take one to three arguments")));
1470  if (!IsBinaryCoercible(sourcetypeid, procstruct->proargtypes.values[0]))
1471  ereport(ERROR,
1472  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1473  errmsg("argument of cast function must match or be binary-coercible from source data type")));
1474  if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)
1475  ereport(ERROR,
1476  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1477  errmsg("second argument of cast function must be type %s",
1478  "integer")));
1479  if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)
1480  ereport(ERROR,
1481  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1482  errmsg("third argument of cast function must be type %s",
1483  "boolean")));
1484  if (!IsBinaryCoercible(procstruct->prorettype, targettypeid))
1485  ereport(ERROR,
1486  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1487  errmsg("return data type of cast function must match or be binary-coercible to target data type")));
1488 
1489  /*
1490  * Restricting the volatility of a cast function may or may not be a
1491  * good idea in the abstract, but it definitely breaks many old
1492  * user-defined types. Disable this check --- tgl 2/1/03
1493  */
1494 #ifdef NOT_USED
1495  if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1496  ereport(ERROR,
1497  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1498  errmsg("cast function must not be volatile")));
1499 #endif
1500  if (procstruct->proisagg)
1501  ereport(ERROR,
1502  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1503  errmsg("cast function must not be an aggregate function")));
1504  if (procstruct->proiswindow)
1505  ereport(ERROR,
1506  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1507  errmsg("cast function must not be a window function")));
1508  if (procstruct->proretset)
1509  ereport(ERROR,
1510  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1511  errmsg("cast function must not return a set")));
1512 
1513  ReleaseSysCache(tuple);
1514  }
1515  else
1516  {
1517  funcid = InvalidOid;
1518  nargs = 0;
1519  }
1520 
1521  if (castmethod == COERCION_METHOD_BINARY)
1522  {
1523  int16 typ1len;
1524  int16 typ2len;
1525  bool typ1byval;
1526  bool typ2byval;
1527  char typ1align;
1528  char typ2align;
1529 
1530  /*
1531  * Must be superuser to create binary-compatible casts, since
1532  * erroneous casts can easily crash the backend.
1533  */
1534  if (!superuser())
1535  ereport(ERROR,
1536  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1537  errmsg("must be superuser to create a cast WITHOUT FUNCTION")));
1538 
1539  /*
1540  * Also, insist that the types match as to size, alignment, and
1541  * pass-by-value attributes; this provides at least a crude check that
1542  * they have similar representations. A pair of types that fail this
1543  * test should certainly not be equated.
1544  */
1545  get_typlenbyvalalign(sourcetypeid, &typ1len, &typ1byval, &typ1align);
1546  get_typlenbyvalalign(targettypeid, &typ2len, &typ2byval, &typ2align);
1547  if (typ1len != typ2len ||
1548  typ1byval != typ2byval ||
1549  typ1align != typ2align)
1550  ereport(ERROR,
1551  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1552  errmsg("source and target data types are not physically compatible")));
1553 
1554  /*
1555  * We know that composite, enum and array types are never binary-
1556  * compatible with each other. They all have OIDs embedded in them.
1557  *
1558  * Theoretically you could build a user-defined base type that is
1559  * binary-compatible with a composite, enum, or array type. But we
1560  * disallow that too, as in practice such a cast is surely a mistake.
1561  * You can always work around that by writing a cast function.
1562  */
1563  if (sourcetyptype == TYPTYPE_COMPOSITE ||
1564  targettyptype == TYPTYPE_COMPOSITE)
1565  ereport(ERROR,
1566  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1567  errmsg("composite data types are not binary-compatible")));
1568 
1569  if (sourcetyptype == TYPTYPE_ENUM ||
1570  targettyptype == TYPTYPE_ENUM)
1571  ereport(ERROR,
1572  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1573  errmsg("enum data types are not binary-compatible")));
1574 
1575  if (OidIsValid(get_element_type(sourcetypeid)) ||
1576  OidIsValid(get_element_type(targettypeid)))
1577  ereport(ERROR,
1578  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1579  errmsg("array data types are not binary-compatible")));
1580 
1581  /*
1582  * We also disallow creating binary-compatibility casts involving
1583  * domains. Casting from a domain to its base type is already
1584  * allowed, and casting the other way ought to go through domain
1585  * coercion to permit constraint checking. Again, if you're intent on
1586  * having your own semantics for that, create a no-op cast function.
1587  *
1588  * NOTE: if we were to relax this, the above checks for composites
1589  * etc. would have to be modified to look through domains to their
1590  * base types.
1591  */
1592  if (sourcetyptype == TYPTYPE_DOMAIN ||
1593  targettyptype == TYPTYPE_DOMAIN)
1594  ereport(ERROR,
1595  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1596  errmsg("domain data types must not be marked binary-compatible")));
1597  }
1598 
1599  /*
1600  * Allow source and target types to be same only for length coercion
1601  * functions. We assume a multi-arg function does length coercion.
1602  */
1603  if (sourcetypeid == targettypeid && nargs < 2)
1604  ereport(ERROR,
1605  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1606  errmsg("source data type and target data type are the same")));
1607 
1608  /* convert CoercionContext enum to char value for castcontext */
1609  switch (stmt->context)
1610  {
1611  case COERCION_IMPLICIT:
1612  castcontext = COERCION_CODE_IMPLICIT;
1613  break;
1614  case COERCION_ASSIGNMENT:
1615  castcontext = COERCION_CODE_ASSIGNMENT;
1616  break;
1617  case COERCION_EXPLICIT:
1618  castcontext = COERCION_CODE_EXPLICIT;
1619  break;
1620  default:
1621  elog(ERROR, "unrecognized CoercionContext: %d", stmt->context);
1622  castcontext = 0; /* keep compiler quiet */
1623  break;
1624  }
1625 
1627 
1628  /*
1629  * Check for duplicate. This is just to give a friendly error message,
1630  * the unique index would catch it anyway (so no need to sweat about race
1631  * conditions).
1632  */
1634  ObjectIdGetDatum(sourcetypeid),
1635  ObjectIdGetDatum(targettypeid));
1636  if (HeapTupleIsValid(tuple))
1637  ereport(ERROR,
1639  errmsg("cast from type %s to type %s already exists",
1640  format_type_be(sourcetypeid),
1641  format_type_be(targettypeid))));
1642 
1643  /* ready to go */
1644  values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
1645  values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
1646  values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
1647  values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
1648  values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
1649 
1650  MemSet(nulls, false, sizeof(nulls));
1651 
1652  tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
1653 
1654  castid = CatalogTupleInsert(relation, tuple);
1655 
1656  /* make dependency entries */
1657  myself.classId = CastRelationId;
1658  myself.objectId = castid;
1659  myself.objectSubId = 0;
1660 
1661  /* dependency on source type */
1662  referenced.classId = TypeRelationId;
1663  referenced.objectId = sourcetypeid;
1664  referenced.objectSubId = 0;
1665  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1666 
1667  /* dependency on target type */
1668  referenced.classId = TypeRelationId;
1669  referenced.objectId = targettypeid;
1670  referenced.objectSubId = 0;
1671  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1672 
1673  /* dependency on function */
1674  if (OidIsValid(funcid))
1675  {
1676  referenced.classId = ProcedureRelationId;
1677  referenced.objectId = funcid;
1678  referenced.objectSubId = 0;
1679  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1680  }
1681 
1682  /* dependency on extension */
1683  recordDependencyOnCurrentExtension(&myself, false);
1684 
1685  /* Post creation hook for new cast */
1687 
1688  heap_freetuple(tuple);
1689 
1690  heap_close(relation, RowExclusiveLock);
1691 
1692  return myself;
1693 }
signed short int16
Definition: c.h:252
#define TYPTYPE_DOMAIN
Definition: pg_type.h:710
TypeName * sourcetype
Definition: parsenodes.h:3138
#define Anum_pg_cast_castfunc
Definition: pg_cast.h:80
#define Anum_pg_cast_casttarget
Definition: pg_cast.h:79
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
#define TYPTYPE_COMPOSITE
Definition: pg_type.h:709
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2452
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:1989
List * funcargs
Definition: parsenodes.h:1774
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
#define ProcedureRelationId
Definition: pg_proc.h:33
#define INT4OID
Definition: pg_type.h:316
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
char get_typtype(Oid typid)
Definition: lsyscache.c:2347
#define MemSet(start, val, len)
Definition: c.h:853
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
FuncWithArgs * func
Definition: parsenodes.h:3140
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
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
bool pg_type_ownercheck(Oid type_oid, Oid roleid)
Definition: aclchk.c:4547
#define TypeRelationId
Definition: pg_type.h:34
#define OidIsValid(objectId)
Definition: c.h:534
#define Anum_pg_cast_castmethod
Definition: pg_cast.h:82
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3436
#define Natts_pg_cast
Definition: pg_cast.h:77
#define Anum_pg_cast_castsource
Definition: pg_cast.h:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
CoercionContext context
Definition: parsenodes.h:3141
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
Definition: parse_func.c:1940
#define ACL_USAGE
Definition: parsenodes.h:73
#define ereport(elevel, rest)
Definition: elog.h:122
bool IsBinaryCoercible(Oid srctype, Oid targettype)
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5374
#define WARNING
Definition: elog.h:40
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define CastRelationId
Definition: pg_cast.h:31
#define BOOLOID
Definition: pg_type.h:288
#define CharGetDatum(X)
Definition: postgres.h:424
#define TYPTYPE_PSEUDO
Definition: pg_type.h:712
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
TypeName * targettype
Definition: parsenodes.h:3139
#define TYPTYPE_ENUM
Definition: pg_type.h:711
#define Anum_pg_cast_castcontext
Definition: pg_cast.h:81
List * funcname
Definition: parsenodes.h:1773
#define elog
Definition: elog.h:219
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4509
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151
ObjectAddress CreateForeignDataWrapper ( CreateFdwStmt stmt)

Definition at line 560 of file foreigncmds.c.

References Anum_pg_foreign_data_wrapper_fdwacl, Anum_pg_foreign_data_wrapper_fdwhandler, Anum_pg_foreign_data_wrapper_fdwname, Anum_pg_foreign_data_wrapper_fdwoptions, Anum_pg_foreign_data_wrapper_fdwowner, Anum_pg_foreign_data_wrapper_fdwvalidator, CatalogTupleInsert(), ObjectAddress::classId, CStringGetDatum, DatumGetPointer, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, CreateFdwStmt::fdwname, ForeignDataWrapperRelationId, CreateFdwStmt::func_options, GetForeignDataWrapperByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, namein(), Natts_pg_foreign_data_wrapper, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, CreateFdwStmt::options, parse_func_options(), PointerGetDatum, PointerIsValid, ProcedureRelationId, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, superuser(), transformGenericOptions(), and values.

Referenced by ProcessUtilitySlow().

561 {
562  Relation rel;
564  bool nulls[Natts_pg_foreign_data_wrapper];
565  HeapTuple tuple;
566  Oid fdwId;
567  bool handler_given;
568  bool validator_given;
569  Oid fdwhandler;
570  Oid fdwvalidator;
571  Datum fdwoptions;
572  Oid ownerId;
573  ObjectAddress myself;
574  ObjectAddress referenced;
575 
577 
578  /* Must be super user */
579  if (!superuser())
580  ereport(ERROR,
581  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
582  errmsg("permission denied to create foreign-data wrapper \"%s\"",
583  stmt->fdwname),
584  errhint("Must be superuser to create a foreign-data wrapper.")));
585 
586  /* For now the owner cannot be specified on create. Use effective user ID. */
587  ownerId = GetUserId();
588 
589  /*
590  * Check that there is no other foreign-data wrapper by this name.
591  */
592  if (GetForeignDataWrapperByName(stmt->fdwname, true) != NULL)
593  ereport(ERROR,
595  errmsg("foreign-data wrapper \"%s\" already exists",
596  stmt->fdwname)));
597 
598  /*
599  * Insert tuple into pg_foreign_data_wrapper.
600  */
601  memset(values, 0, sizeof(values));
602  memset(nulls, false, sizeof(nulls));
603 
607 
608  /* Lookup handler and validator functions, if given */
610  &handler_given, &fdwhandler,
611  &validator_given, &fdwvalidator);
612 
615 
616  nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
617 
620  stmt->options,
621  fdwvalidator);
622 
623  if (PointerIsValid(DatumGetPointer(fdwoptions)))
624  values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions;
625  else
626  nulls[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
627 
628  tuple = heap_form_tuple(rel->rd_att, values, nulls);
629 
630  fdwId = CatalogTupleInsert(rel, tuple);
631 
632  heap_freetuple(tuple);
633 
634  /* record dependencies */
636  myself.objectId = fdwId;
637  myself.objectSubId = 0;
638 
639  if (OidIsValid(fdwhandler))
640  {
641  referenced.classId = ProcedureRelationId;
642  referenced.objectId = fdwhandler;
643  referenced.objectSubId = 0;
644  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
645  }
646 
647  if (OidIsValid(fdwvalidator))
648  {
649  referenced.classId = ProcedureRelationId;
650  referenced.objectId = fdwvalidator;
651  referenced.objectSubId = 0;
652  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
653  }
654 
656 
657  /* dependency on extension */
658  recordDependencyOnCurrentExtension(&myself, false);
659 
660  /* Post creation hook for new foreign data wrapper */
662 
664 
665  return myself;
666 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
int errhint(const char *fmt,...)
Definition: elog.c:987
static void parse_func_options(List *func_options, bool *handler_given, Oid *fdwhandler, bool *validator_given, Oid *fdwvalidator)
Definition: foreigncmds.c:516
#define Anum_pg_foreign_data_wrapper_fdwowner
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
Oid GetUserId(void)
Definition: miscinit.c:283
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define PointerGetDatum(X)
Definition: postgres.h:564
#define ProcedureRelationId
Definition: pg_proc.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define Anum_pg_foreign_data_wrapper_fdwhandler
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:555
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:158
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define Anum_pg_foreign_data_wrapper_fdwacl
List * options
Definition: parsenodes.h:2093
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define RowExclusiveLock
Definition: lockdefs.h:38
char * fdwname
Definition: parsenodes.h:2091
#define CStringGetDatum(X)
Definition: postgres.h:586
#define Anum_pg_foreign_data_wrapper_fdwname
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:114
#define Anum_pg_foreign_data_wrapper_fdwvalidator
#define Natts_pg_foreign_data_wrapper
#define NULL
Definition: c.h:226
ForeignDataWrapper * GetForeignDataWrapperByName(const char *fdwname, bool missing_ok)
Definition: foreign.c:78
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define ForeignDataWrapperRelationId
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
#define PointerIsValid(pointer)
Definition: c.h:522
#define Anum_pg_foreign_data_wrapper_fdwoptions
List * func_options
Definition: parsenodes.h:2092
ObjectAddress CreateForeignServer ( CreateForeignServerStmt stmt)

Definition at line 861 of file foreigncmds.c.

References ACL_KIND_FDW, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, Anum_pg_foreign_server_srvacl, Anum_pg_foreign_server_srvfdw, Anum_pg_foreign_server_srvname, Anum_pg_foreign_server_srvoptions, Anum_pg_foreign_server_srvowner, Anum_pg_foreign_server_srvtype, Anum_pg_foreign_server_srvversion, CatalogTupleInsert(), ObjectAddress::classId, CStringGetDatum, CStringGetTextDatum, DatumGetPointer, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, ForeignDataWrapper::fdwid, ForeignDataWrapper::fdwname, CreateForeignServerStmt::fdwname, ForeignDataWrapper::fdwvalidator, ForeignDataWrapperRelationId, ForeignServerRelationId, GetForeignDataWrapperByName(), GetForeignServerByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, namein(), Natts_pg_foreign_server, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, CreateForeignServerStmt::options, pg_foreign_data_wrapper_aclcheck(), PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, CreateForeignServerStmt::servername, CreateForeignServerStmt::servertype, transformGenericOptions(), values, and CreateForeignServerStmt::version.

Referenced by ProcessUtilitySlow().

862 {
863  Relation rel;
864  Datum srvoptions;
866  bool nulls[Natts_pg_foreign_server];
867  HeapTuple tuple;
868  Oid srvId;
869  Oid ownerId;
870  AclResult aclresult;
871  ObjectAddress myself;
872  ObjectAddress referenced;
873  ForeignDataWrapper *fdw;
874 
876 
877  /* For now the owner cannot be specified on create. Use effective user ID. */
878  ownerId = GetUserId();
879 
880  /*
881  * Check that there is no other foreign server by this name.
882  */
883  if (GetForeignServerByName(stmt->servername, true) != NULL)
884  ereport(ERROR,
886  errmsg("server \"%s\" already exists",
887  stmt->servername)));
888 
889  /*
890  * Check that the FDW exists and that we have USAGE on it. Also get the
891  * actual FDW for option validation etc.
892  */
893  fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
894 
895  aclresult = pg_foreign_data_wrapper_aclcheck(fdw->fdwid, ownerId, ACL_USAGE);
896  if (aclresult != ACLCHECK_OK)
897  aclcheck_error(aclresult, ACL_KIND_FDW, fdw->fdwname);
898 
899  /*
900  * Insert tuple into pg_foreign_server.
901  */
902  memset(values, 0, sizeof(values));
903  memset(nulls, false, sizeof(nulls));
904 
905  values[Anum_pg_foreign_server_srvname - 1] =
907  values[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(ownerId);
909 
910  /* Add server type if supplied */
911  if (stmt->servertype)
912  values[Anum_pg_foreign_server_srvtype - 1] =
914  else
915  nulls[Anum_pg_foreign_server_srvtype - 1] = true;
916 
917  /* Add server version if supplied */
918  if (stmt->version)
921  else
922  nulls[Anum_pg_foreign_server_srvversion - 1] = true;
923 
924  /* Start with a blank acl */
925  nulls[Anum_pg_foreign_server_srvacl - 1] = true;
926 
927  /* Add server options */
930  stmt->options,
931  fdw->fdwvalidator);
932 
933  if (PointerIsValid(DatumGetPointer(srvoptions)))
934  values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions;
935  else
936  nulls[Anum_pg_foreign_server_srvoptions - 1] = true;
937 
938  tuple = heap_form_tuple(rel->rd_att, values, nulls);
939 
940  srvId = CatalogTupleInsert(rel, tuple);
941 
942  heap_freetuple(tuple);
943 
944  /* record dependencies */
946  myself.objectId = srvId;
947  myself.objectSubId = 0;
948 
950  referenced.objectId = fdw->fdwid;
951  referenced.objectSubId = 0;
952  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
953 
955 
956  /* dependency on extension */
957  recordDependencyOnCurrentExtension(&myself, false);
958 
959  /* Post creation hook for new foreign server */
961 
963 
964  return myself;
965 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
Oid GetUserId(void)
Definition: miscinit.c:283
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define Anum_pg_foreign_server_srvversion
char * fdwname
Definition: foreign.h:39
#define PointerGetDatum(X)
Definition: postgres.h:564
AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4484
int errcode(int sqlerrcode)
Definition: elog.c:575
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:555
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:158
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define Anum_pg_foreign_server_srvname
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ACL_USAGE
Definition: parsenodes.h:73
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition: foreign.c:148
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_foreign_server_srvacl
#define Natts_pg_foreign_server
#define Anum_pg_foreign_server_srvowner
#define Anum_pg_foreign_server_srvfdw
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:114
#define ForeignServerRelationId
#define NULL
Definition: c.h:226
ForeignDataWrapper * GetForeignDataWrapperByName(const char *fdwname, bool missing_ok)
Definition: foreign.c:78
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define ForeignDataWrapperRelationId
#define Anum_pg_foreign_server_srvtype
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CStringGetTextDatum(s)
Definition: builtins.h:90
#define Anum_pg_foreign_server_srvoptions
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
#define PointerIsValid(pointer)
Definition: c.h:522
void CreateForeignTable ( CreateForeignTableStmt stmt,
Oid  relid 
)

Definition at line 1418 of file foreigncmds.c.

References ACL_KIND_FOREIGN_SERVER, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, Anum_pg_foreign_table_ftoptions, Anum_pg_foreign_table_ftrelid, Anum_pg_foreign_table_ftserver, CatalogTupleInsert(), ObjectAddress::classId, CommandCounterIncrement(), DatumGetPointer, DEPENDENCY_NORMAL, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, ForeignServerRelationId, ForeignTableRelationId, GetForeignDataWrapper(), GetForeignServerByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), Natts_pg_foreign_table, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, CreateForeignTableStmt::options, pg_foreign_server_aclcheck(), PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), RelationRelationId, RowExclusiveLock, ForeignServer::serverid, ForeignServer::servername, CreateForeignTableStmt::servername, transformGenericOptions(), and values.

Referenced by ProcessUtilitySlow().

1419 {
1420  Relation ftrel;
1421  Datum ftoptions;
1423  bool nulls[Natts_pg_foreign_table];
1424  HeapTuple tuple;
1425  AclResult aclresult;
1426  ObjectAddress myself;
1427  ObjectAddress referenced;
1428  Oid ownerId;
1429  ForeignDataWrapper *fdw;
1430  ForeignServer *server;
1431 
1432  /*
1433  * Advance command counter to ensure the pg_attribute tuple is visible;
1434  * the tuple might be updated to add constraints in previous step.
1435  */
1437 
1439 
1440  /*
1441  * For now the owner cannot be specified on create. Use effective user ID.
1442  */
1443  ownerId = GetUserId();
1444 
1445  /*
1446  * Check that the foreign server exists and that we have USAGE on it. Also
1447  * get the actual FDW for option validation etc.
1448  */
1449  server = GetForeignServerByName(stmt->servername, false);
1450  aclresult = pg_foreign_server_aclcheck(server->serverid, ownerId, ACL_USAGE);
1451  if (aclresult != ACLCHECK_OK)
1452  aclcheck_error(aclresult, ACL_KIND_FOREIGN_SERVER, server->servername);
1453 
1454  fdw = GetForeignDataWrapper(server->fdwid);
1455 
1456  /*
1457  * Insert tuple into pg_foreign_table.
1458  */
1459  memset(values, 0, sizeof(values));
1460  memset(nulls, false, sizeof(nulls));
1461 
1462  values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
1464  /* Add table generic options */
1467  stmt->options,
1468  fdw->fdwvalidator);
1469 
1470  if (PointerIsValid(DatumGetPointer(ftoptions)))
1471  values[Anum_pg_foreign_table_ftoptions - 1] = ftoptions;
1472  else
1473  nulls[Anum_pg_foreign_table_ftoptions - 1] = true;
1474 
1475  tuple = heap_form_tuple(ftrel->rd_att, values, nulls);
1476 
1477  CatalogTupleInsert(ftrel, tuple);
1478 
1479  heap_freetuple(tuple);
1480 
1481  /* Add pg_class dependency on the server */
1482  myself.classId = RelationRelationId;
1483  myself.objectId = relid;
1484  myself.objectSubId = 0;
1485 
1486  referenced.classId = ForeignServerRelationId;
1487  referenced.objectId = server->serverid;
1488  referenced.objectSubId = 0;
1489  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1490 
1491  heap_close(ftrel, RowExclusiveLock);
1492 }
Oid GetUserId(void)
Definition: miscinit.c:283
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define PointerGetDatum(X)
Definition: postgres.h:564
#define RelationRelationId
Definition: pg_class.h:29
#define Natts_pg_foreign_table
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
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define Anum_pg_foreign_table_ftserver
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4497
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ACL_USAGE
Definition: parsenodes.h:73
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition: foreign.c:148
#define Anum_pg_foreign_table_ftrelid
#define Anum_pg_foreign_table_ftoptions
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
void CommandCounterIncrement(void)
Definition: xact.c:921
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:114
#define ForeignServerRelationId
#define NULL
Definition: c.h:226
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
char * servername
Definition: foreign.h:50
#define ForeignTableRelationId
#define PointerIsValid(pointer)
Definition: c.h:522
Oid serverid
Definition: foreign.h:47
ObjectAddress CreateFunction ( ParseState pstate,
CreateFunctionStmt stmt 
)

Definition at line 861 of file functioncmds.c.

References ACL_CREATE, ACL_KIND_LANGUAGE, ACL_KIND_NAMESPACE, ACL_USAGE, aclcheck_error(), ACLCHECK_NO_PRIV, ACLCHECK_OK, castNode, ClanguageId, compute_attributes_sql_style(), compute_attributes_with_style(), compute_return_type(), construct_array(), ereport, errcode(), errhint(), errmsg(), ERROR, format_type_be(), CreateFunctionStmt::funcname, get_base_element_type(), get_namespace_name(), get_transform_oid(), GETSTRUCT, GetUserId(), HeapTupleGetOid, HeapTupleIsValid, i, INTERNALlanguageId, interpret_AS_clause(), interpret_function_parameter_list(), LANGNAME, lappend_oid(), lfirst, lfirst_oid, list_length(), NameStr, NIL, NULL, ObjectIdGetDatum, OidIsValid, OIDOID, CreateFunctionStmt::options, palloc(), CreateFunctionStmt::parameters, pg_language_aclcheck(), pg_namespace_aclcheck(), PLTemplateExists(), PointerGetDatum, ProcedureCreate(), PROPARALLEL_UNSAFE, PROVOLATILE_VOLATILE, QualifiedNameGetCreationNamespace(), ReleaseSysCache(), CreateFunctionStmt::replace, CreateFunctionStmt::returnType, SearchSysCache1, superuser(), typenameTypeId(), VOIDOID, and CreateFunctionStmt::withClause.

Referenced by ProcessUtilitySlow().

862 {
863  char *probin_str;
864  char *prosrc_str;
865  Oid prorettype;
866  bool returnsSet;
867  char *language;
868  Oid languageOid;
869  Oid languageValidator;
870  Node *transformDefElem = NULL;
871  char *funcname;
872  Oid namespaceId;
873  AclResult aclresult;
874  oidvector *parameterTypes;
875  ArrayType *allParameterTypes;
876  ArrayType *parameterModes;
877  ArrayType *parameterNames;
878  List *parameterDefaults;
879  Oid variadicArgType;
880  List *trftypes_list = NIL;
881  ArrayType *trftypes;
882  Oid requiredResultType;
883  bool isWindowFunc,
884  isStrict,
885  security,
886  isLeakProof;
887  char volatility;
888  ArrayType *proconfig;
889  float4 procost;
890  float4 prorows;
891  HeapTuple languageTuple;
892  Form_pg_language languageStruct;
893  List *as_clause;
894  char parallel;
895 
896  /* Convert list of names to a name and namespace */
897  namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
898  &funcname);
899 
900  /* Check we have creation rights in target namespace */
901  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
902  if (aclresult != ACLCHECK_OK)
904  get_namespace_name(namespaceId));
905 
906  /* default attributes */
907  isWindowFunc = false;
908  isStrict = false;
909  security = false;
910  isLeakProof = false;
911  volatility = PROVOLATILE_VOLATILE;
912  proconfig = NULL;
913  procost = -1; /* indicates not set */
914  prorows = -1; /* indicates not set */
915  parallel = PROPARALLEL_UNSAFE;
916 
917  /* override attributes from explicit list */
919  stmt->options,
920  &as_clause, &language, &transformDefElem,
921  &isWindowFunc, &volatility,
922  &isStrict, &security, &isLeakProof,
923  &proconfig, &procost, &prorows, &parallel);
924 
925  /* Look up the language and validate permissions */
926  languageTuple = SearchSysCache1(LANGNAME, PointerGetDatum(language));
927  if (!HeapTupleIsValid(languageTuple))
928  ereport(ERROR,
929  (errcode(ERRCODE_UNDEFINED_OBJECT),
930  errmsg("language \"%s\" does not exist", language),
931  (PLTemplateExists(language) ?
932  errhint("Use CREATE LANGUAGE to load the language into the database.") : 0)));
933 
934  languageOid = HeapTupleGetOid(languageTuple);
935  languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
936 
937  if (languageStruct->lanpltrusted)
938  {
939  /* if trusted language, need USAGE privilege */
940  AclResult aclresult;
941 
942  aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE);
943  if (aclresult != ACLCHECK_OK)
945  NameStr(languageStruct->lanname));
946  }
947  else
948  {
949  /* if untrusted language, must be superuser */
950  if (!superuser())
952  NameStr(languageStruct->lanname));
953  }
954 
955  languageValidator = languageStruct->lanvalidator;
956 
957  ReleaseSysCache(languageTuple);
958 
959  /*
960  * Only superuser is allowed to create leakproof functions because
961  * leakproof functions can see tuples which have not yet been filtered out
962  * by security barrier views or row level security policies.
963  */
964  if (isLeakProof && !superuser())
965  ereport(ERROR,
966  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
967  errmsg("only superuser can define a leakproof function")));
968 
969  if (transformDefElem)
970  {
971  ListCell *lc;
972 
973  foreach(lc, castNode(List, transformDefElem))
974  {
975  Oid typeid = typenameTypeId(NULL, lfirst(lc));
976  Oid elt = get_base_element_type(typeid);
977 
978  typeid = elt ? elt : typeid;
979 
980  get_transform_oid(typeid, languageOid, false);
981  trftypes_list = lappend_oid(trftypes_list, typeid);
982  }
983  }
984 
985  /*
986  * Convert remaining parameters of CREATE to form wanted by
987  * ProcedureCreate.
988  */
990  stmt->parameters,
991  languageOid,
992  false, /* not an aggregate */
993  &parameterTypes,
994  &allParameterTypes,
995  &parameterModes,
996  &parameterNames,
997  &parameterDefaults,
998  &variadicArgType,
999  &requiredResultType);
1000 
1001  if (stmt->returnType)
1002  {
1003  /* explicit RETURNS clause */
1004  compute_return_type(stmt->returnType, languageOid,
1005  &prorettype, &returnsSet);
1006  if (OidIsValid(requiredResultType) && prorettype != requiredResultType)
1007  ereport(ERROR,
1008  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1009  errmsg("function result type must be %s because of OUT parameters",
1010  format_type_be(requiredResultType))));
1011  }
1012  else if (OidIsValid(requiredResultType))
1013  {
1014  /* default RETURNS clause from OUT parameters */
1015  prorettype = requiredResultType;
1016  returnsSet = false;
1017  }
1018  else
1019  {
1020  ereport(ERROR,
1021  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1022  errmsg("function result type must be specified")));
1023  /* Alternative possibility: default to RETURNS VOID */
1024  prorettype = VOIDOID;
1025  returnsSet = false;
1026  }
1027 
1028  if (list_length(trftypes_list) > 0)
1029  {
1030  ListCell *lc;
1031  Datum *arr;
1032  int i;
1033 
1034  arr = palloc(list_length(trftypes_list) * sizeof(Datum));
1035  i = 0;
1036  foreach(lc, trftypes_list)
1037  arr[i++] = ObjectIdGetDatum(lfirst_oid(lc));
1038  trftypes = construct_array(arr, list_length(trftypes_list),
1039  OIDOID, sizeof(Oid), true, 'i');
1040  }
1041  else
1042  {
1043  /* store SQL NULL instead of empty array */
1044  trftypes = NULL;
1045  }
1046 
1047  compute_attributes_with_style(pstate, stmt->withClause, &isStrict, &volatility);
1048 
1049  interpret_AS_clause(languageOid, language, funcname, as_clause,
1050  &prosrc_str, &probin_str);
1051 
1052  /*
1053  * Set default values for COST and ROWS depending on other parameters;
1054  * reject ROWS if it's not returnsSet. NB: pg_dump knows these default
1055  * values, keep it in sync if you change them.
1056  */
1057  if (procost < 0)
1058  {
1059  /* SQL and PL-language functions are assumed more expensive */
1060  if (languageOid == INTERNALlanguageId ||
1061  languageOid == ClanguageId)
1062  procost = 1;
1063  else
1064  procost = 100;
1065  }
1066  if (prorows < 0)
1067  {
1068  if (returnsSet)
1069  prorows = 1000;
1070  else
1071  prorows = 0; /* dummy value if not returnsSet */
1072  }
1073  else if (!returnsSet)
1074  ereport(ERROR,
1075  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1076  errmsg("ROWS is not applicable when function does not return a set")));
1077 
1078  /*
1079  * And now that we have all the parameters, and know we're permitted to do
1080  * so, go ahead and create the function.
1081  */
1082  return ProcedureCreate(funcname,
1083  namespaceId,
1084  stmt->replace,
1085  returnsSet,
1086  prorettype,
1087  GetUserId(),
1088  languageOid,
1089  languageValidator,
1090  prosrc_str, /* converted to text later */
1091  probin_str, /* converted to text later */
1092  false, /* not an aggregate */
1093  isWindowFunc,
1094  security,
1095  isLeakProof,
1096  isStrict,
1097  volatility,
1098  parallel,
1099  parameterTypes,
1100  PointerGetDatum(allParameterTypes),
1101  PointerGetDatum(parameterModes),
1102  PointerGetDatum(parameterNames),
1103  parameterDefaults,
1104  PointerGetDatum(trftypes),
1105  PointerGetDatum(proconfig),
1106  procost,
1107  prorows);
1108 }
#define NIL
Definition: pg_list.h:69
Definition: c.h:474
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static void compute_attributes_sql_style(ParseState *pstate, List *options, List **as, char **language, Node **transform, bool *windowfunc_p, char *volatility_p, bool *strict_p, bool *security_definer, bool *leakproof_p, ArrayType **proconfig, float4 *procost, float4 *prorows, char *parallel_p)
Definition: functioncmds.c:605
#define INTERNALlanguageId
Definition: pg_language.h:74
Oid GetUserId(void)
Definition: miscinit.c:283
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
#define OIDOID
Definition: pg_type.h:328
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2790
#define PointerGetDatum(X)
Definition: postgres.h:564
static void compute_return_type(TypeName *returnType, Oid languageOid, Oid *prorettype_p, bool *returnsSet_p)
Definition: functioncmds.c:83
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
Definition: nodes.h:508
#define ClanguageId
Definition: pg_language.h:77
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
static void interpret_AS_clause(Oid languageOid, const char *languageName, char *funcname, List *as, char **prosrc_str_p, char **probin_str_p)
Definition: functioncmds.c:801
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:534
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4459
AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4433
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void interpret_function_parameter_list(ParseState *pstate, List *parameters, Oid languageOid, bool is_aggregate, oidvector **parameterTypes, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType)
Definition: functioncmds.c:179
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
#define VOIDOID
Definition: pg_type.h:678
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:75
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define ACL_USAGE
Definition: parsenodes.h:73
#define ereport(elevel, rest)
Definition: elog.h:122
#define PROPARALLEL_UNSAFE
Definition: pg_proc.h:5383
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5374
float float4
Definition: c.h:377
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
bool PLTemplateExists(const char *languageName)
Definition: proclang.c:519
ObjectAddress ProcedureCreate(const char *procedureName, Oid procNamespace, bool replace, bool returnsSet, Oid returnType, Oid proowner, Oid languageObjectId, Oid languageValidator, const char *prosrc, const char *probin, bool isAgg, bool isWindowFunc, bool security_definer, bool isLeakProof, bool isStrict, char volatility, char parallel, oidvector *parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List *parameterDefaults, Datum trftypes, Datum proconfig, float4 procost, float4 prorows)
Definition: pg_proc.c:67
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
TypeName * returnType
Definition: parsenodes.h:2619
static int list_length(const List *l)
Definition: pg_list.h:89
static void compute_attributes_with_style(ParseState *pstate, List *parameters, bool *isStrict_p, char *volatility_p)
Definition: functioncmds.c:765
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2525
FormData_pg_language * Form_pg_language
Definition: pg_language.h:51
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:495
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
ObjectAddress CreateTransform ( CreateTransformStmt stmt)

Definition at line 1780 of file functioncmds.c.

References ACL_EXECUTE, ACL_KIND_LANGUAGE, ACL_KIND_PROC, ACL_USAGE, aclcheck_error(), aclcheck_error_type(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Anum_pg_transform_trffromsql, Anum_pg_transform_trflang, Anum_pg_transform_trftosql, Anum_pg_transform_trftype, CatalogTupleInsert(), CatalogTupleUpdate(), check_transform_function(), ObjectAddress::classId, deleteDependencyRecordsFor(), DEPENDENCY_NORMAL, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, format_type_be(), CreateTransformStmt::fromsql, FuncWithArgs::funcargs, FuncWithArgs::funcname, get_language_oid(), get_typtype(), GETSTRUCT, GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, INTERNALOID, InvalidOid, InvokeObjectPostCreateHook, CreateTransformStmt::lang, LanguageRelationId, LookupFuncNameTypeNames(), MemSet, NameListToString(), Natts_pg_transform, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, pg_language_aclcheck(), pg_proc_aclcheck(), pg_proc_ownercheck(), pg_type_aclcheck(), pg_type_ownercheck(), ProcedureRelationId, PROCOID, recordDependencyOn(), recordDependencyOnCurrentExtension(), RelationGetDescr, ReleaseSysCache(), CreateTransformStmt::replace, RowExclusiveLock, SearchSysCache1, SearchSysCache2, HeapTupleData::t_self, CreateTransformStmt::tosql, TransformRelationId, TRFTYPELANG, CreateTransformStmt::type_name, TypeNameToString(), typenameTypeId(), TypeRelationId, TYPTYPE_DOMAIN, TYPTYPE_PSEUDO, and values.

Referenced by ProcessUtilitySlow().

1781 {
1782  Oid typeid;
1783  char typtype;
1784  Oid langid;
1785  Oid fromsqlfuncid;
1786  Oid tosqlfuncid;
1787  AclResult aclresult;
1788  Form_pg_proc procstruct;
1790  bool nulls[Natts_pg_transform];
1791  bool replaces[Natts_pg_transform];
1792  Oid transformid;
1793  HeapTuple tuple;
1794  HeapTuple newtuple;
1795  Relation relation;
1796  ObjectAddress myself,
1797  referenced;
1798  bool is_replace;
1799 
1800  /*
1801  * Get the type
1802  */
1803  typeid = typenameTypeId(NULL, stmt->type_name);
1804  typtype = get_typtype(typeid);
1805 
1806  if (typtype == TYPTYPE_PSEUDO)
1807  ereport(ERROR,
1808  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1809  errmsg("data type %s is a pseudo-type",
1810  TypeNameToString(stmt->type_name))));
1811 
1812  if (typtype == TYPTYPE_DOMAIN)
1813  ereport(ERROR,
1814  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1815  errmsg("data type %s is a domain",
1816  TypeNameToString(stmt->type_name))));
1817 
1818  if (!pg_type_ownercheck(typeid, GetUserId()))
1820 
1821  aclresult = pg_type_aclcheck(typeid, GetUserId(), ACL_USAGE);
1822  if (aclresult != ACLCHECK_OK)
1823  aclcheck_error_type(aclresult, typeid);
1824 
1825  /*
1826  * Get the language
1827  */
1828  langid = get_language_oid(stmt->lang, false);
1829 
1830  aclresult = pg_language_aclcheck(langid, GetUserId(), ACL_USAGE);
1831  if (aclresult != ACLCHECK_OK)
1832  aclcheck_error(aclresult, ACL_KIND_LANGUAGE, stmt->lang);
1833 
1834  /*
1835  * Get the functions
1836  */
1837  if (stmt->fromsql)
1838  {
1839  fromsqlfuncid = LookupFuncNameTypeNames(stmt->fromsql->funcname, stmt->fromsql->funcargs, false);
1840 
1841  if (!pg_proc_ownercheck(fromsqlfuncid, GetUserId()))
1843 
1844  aclresult = pg_proc_aclcheck(fromsqlfuncid, GetUserId(), ACL_EXECUTE);
1845  if (aclresult != ACLCHECK_OK)
1847 
1848  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(fromsqlfuncid));
1849  if (!HeapTupleIsValid(tuple))
1850  elog(ERROR, "cache lookup failed for function %u", fromsqlfuncid);
1851  procstruct = (Form_pg_proc) GETSTRUCT(tuple);
1852  if (procstruct->prorettype != INTERNALOID)
1853  ereport(ERROR,
1854  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1855  errmsg("return data type of FROM SQL function must be %s",
1856  "internal")));
1857  check_transform_function(procstruct);
1858  ReleaseSysCache(tuple);
1859  }
1860  else
1861  fromsqlfuncid = InvalidOid;
1862 
1863  if (stmt->tosql)
1864  {
1865  tosqlfuncid = LookupFuncNameTypeNames(stmt->tosql->funcname, stmt->tosql->funcargs, false);
1866 
1867  if (!pg_proc_ownercheck(tosqlfuncid, GetUserId()))
1869 
1870  aclresult = pg_proc_aclcheck(tosqlfuncid, GetUserId(), ACL_EXECUTE);
1871  if (aclresult != ACLCHECK_OK)
1873 
1874  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(tosqlfuncid));
1875  if (!HeapTupleIsValid(tuple))
1876  elog(ERROR, "cache lookup failed for function %u", tosqlfuncid);
1877  procstruct = (Form_pg_proc) GETSTRUCT(tuple);
1878  if (procstruct->prorettype != typeid)
1879  ereport(ERROR,
1880  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1881  errmsg("return data type of TO SQL function must be the transform data type")));
1882  check_transform_function(procstruct);
1883  ReleaseSysCache(tuple);
1884  }
1885  else
1886  tosqlfuncid = InvalidOid;
1887 
1888  /*
1889  * Ready to go
1890  */
1891  values[Anum_pg_transform_trftype - 1] = ObjectIdGetDatum(typeid);
1892  values[Anum_pg_transform_trflang - 1] = ObjectIdGetDatum(langid);
1893  values[Anum_pg_transform_trffromsql - 1] = ObjectIdGetDatum(fromsqlfuncid);
1894  values[Anum_pg_transform_trftosql - 1] = ObjectIdGetDatum(tosqlfuncid);
1895 
1896  MemSet(nulls, false, sizeof(nulls));
1897 
1899 
1900  tuple = SearchSysCache2(TRFTYPELANG,
1901  ObjectIdGetDatum(typeid),
1902  ObjectIdGetDatum(langid));
1903  if (HeapTupleIsValid(tuple))
1904  {
1905  if (!stmt->replace)
1906  ereport(ERROR,
1908  errmsg("transform for type %s language \"%s\" already exists",
1909  format_type_be(typeid),
1910  stmt->lang)));
1911 
1912  MemSet(replaces, false, sizeof(replaces));
1913  replaces[Anum_pg_transform_trffromsql - 1] = true;
1914  replaces[Anum_pg_transform_trftosql - 1] = true;
1915 
1916  newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
1917  CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
1918 
1919  transformid = HeapTupleGetOid(tuple);
1920  ReleaseSysCache(tuple);
1921  is_replace = true;
1922  }
1923  else
1924  {
1925  newtuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
1926  transformid = CatalogTupleInsert(relation, newtuple);
1927  is_replace = false;
1928  }
1929 
1930  if (is_replace)
1931  deleteDependencyRecordsFor(TransformRelationId, transformid, true);
1932 
1933  /* make dependency entries */
1934  myself.classId = TransformRelationId;
1935  myself.objectId = transformid;
1936  myself.objectSubId = 0;
1937 
1938  /* dependency on language */
1939  referenced.classId = LanguageRelationId;
1940  referenced.objectId = langid;
1941  referenced.objectSubId = 0;
1942  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1943 
1944  /* dependency on type */
1945  referenced.classId = TypeRelationId;
1946  referenced.objectId = typeid;
1947  referenced.objectSubId = 0;
1948  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1949 
1950  /* dependencies on functions */
1951  if (OidIsValid(fromsqlfuncid))
1952  {
1953  referenced.classId = ProcedureRelationId;
1954  referenced.objectId = fromsqlfuncid;
1955  referenced.objectSubId = 0;
1956  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1957  }
1958  if (OidIsValid(tosqlfuncid))
1959  {
1960  referenced.classId = ProcedureRelationId;
1961  referenced.objectId = tosqlfuncid;
1962  referenced.objectSubId = 0;
1963  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1964  }
1965 
1966  /* dependency on extension */
1967  recordDependencyOnCurrentExtension(&myself, is_replace);
1968 
1969  /* Post creation hook for new transform */
1971 
1972  heap_freetuple(newtuple);
1973 
1974  heap_close(relation, RowExclusiveLock);
1975 
1976  return myself;
1977 }
#define TYPTYPE_DOMAIN
Definition: pg_type.h:710
static void check_transform_function(Form_pg_proc procstruct)
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define TransformRelationId
Definition: pg_transform.h:25
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
List * funcargs
Definition: parsenodes.h:1774
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
#define ProcedureRelationId
Definition: pg_proc.h:33
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
Oid get_language_oid(const char *langname, bool missing_ok)
Definition: proclang.c:553
int errcode(int sqlerrcode)
Definition: elog.c:575
char get_typtype(Oid typid)
Definition: lsyscache.c:2347
#define MemSet(start, val, len)
Definition: c.h:853
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
FuncWithArgs * tosql
Definition: parsenodes.h:3156
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
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
bool pg_type_ownercheck(Oid type_oid, Oid roleid)
Definition: aclchk.c:4547
#define TypeRelationId
Definition: pg_type.h:34
#define OidIsValid(objectId)
Definition: c.h:534
#define Anum_pg_transform_trftosql
Definition: pg_transform.h:45
AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4433
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3436
FuncWithArgs * fromsql
Definition: parsenodes.h:3155
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Natts_pg_transform
Definition: pg_transform.h:41
#define Anum_pg_transform_trflang
Definition: pg_transform.h:43
ItemPointerData t_self
Definition: htup.h:65
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
Definition: parse_func.c:1940
#define ACL_USAGE
Definition: parsenodes.h:73
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define InvalidOid
Definition: postgres_ext.h:36
#define Anum_pg_transform_trffromsql
Definition: pg_transform.h:44
#define INTERNALOID
Definition: pg_type.h:686
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define TYPTYPE_PSEUDO
Definition: pg_type.h:712
#define Anum_pg_transform_trftype
Definition: pg_transform.h:42
TypeName * type_name
Definition: parsenodes.h:3153
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_EXECUTE
Definition: parsenodes.h:72
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4421
#define LanguageRelationId
Definition: pg_language.h:29
List * funcname
Definition: parsenodes.h:1773
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4509
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
bool pg_proc_ownercheck(Oid proc_oid, Oid roleid)
Definition: aclchk.c:4599
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151
ObjectAddress CreateUserMapping ( CreateUserMappingStmt stmt)

Definition at line 1122 of file foreigncmds.c.

References ACL_ID_PUBLIC, Anum_pg_user_mapping_umoptions, Anum_pg_user_mapping_umserver, Anum_pg_user_mapping_umuser, CatalogTupleInsert(), ObjectAddress::classId, DatumGetPointer, DEPENDENCY_NORMAL, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, ForeignServerRelationId, get_rolespec_oid(), GetForeignDataWrapper(), GetForeignServerByName(), GetSysCacheOid2, heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, MappingUserName, Natts_pg_user_mapping, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, CreateUserMappingStmt::options, PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), ROLESPEC_PUBLIC, RoleSpec::roletype, RowExclusiveLock, ForeignServer::serverid, CreateUserMappingStmt::servername, transformGenericOptions(), CreateUserMappingStmt::user, user_mapping_ddl_aclcheck(), UserMappingRelationId, USERMAPPINGUSERSERVER, and values.

Referenced by ProcessUtilitySlow().

1123 {
1124  Relation rel;
1125  Datum useoptions;
1127  bool nulls[Natts_pg_user_mapping];
1128  HeapTuple tuple;
1129  Oid useId;
1130  Oid umId;
1131  ObjectAddress myself;
1132  ObjectAddress referenced;
1133  ForeignServer *srv;
1134  ForeignDataWrapper *fdw;
1135  RoleSpec *role = (RoleSpec *) stmt->user;
1136 
1138 
1139  if (role->roletype == ROLESPEC_PUBLIC)
1140  useId = ACL_ID_PUBLIC;
1141  else
1142  useId = get_rolespec_oid(stmt->user, false);
1143 
1144  /* Check that the server exists. */
1145  srv = GetForeignServerByName(stmt->servername, false);
1146 
1147  user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
1148 
1149  /*
1150  * Check that the user mapping is unique within server.
1151  */
1153  ObjectIdGetDatum(useId),
1154  ObjectIdGetDatum(srv->serverid));
1155  if (OidIsValid(umId))
1156  ereport(ERROR,
1158  errmsg("user mapping \"%s\" already exists for server %s",
1159  MappingUserName(useId),
1160  stmt->servername)));
1161 
1162  fdw = GetForeignDataWrapper(srv->fdwid);
1163 
1164  /*
1165  * Insert tuple into pg_user_mapping.
1166  */
1167  memset(values, 0, sizeof(values));
1168  memset(nulls, false, sizeof(nulls));
1169 
1170  values[Anum_pg_user_mapping_umuser - 1] = ObjectIdGetDatum(useId);
1172 
1173  /* Add user options */
1176  stmt->options,
1177  fdw->fdwvalidator);
1178 
1179  if (PointerIsValid(DatumGetPointer(useoptions)))
1180  values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
1181  else
1182  nulls[Anum_pg_user_mapping_umoptions - 1] = true;
1183 
1184  tuple = heap_form_tuple(rel->rd_att, values, nulls);
1185 
1186  umId = CatalogTupleInsert(rel, tuple);
1187 
1188  heap_freetuple(tuple);
1189 
1190  /* Add dependency on the server */
1191  myself.classId = UserMappingRelationId;
1192  myself.objectId = umId;
1193  myself.objectSubId = 0;
1194 
1195  referenced.classId = ForeignServerRelationId;
1196  referenced.objectId = srv->serverid;
1197  referenced.objectSubId = 0;
1198  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1199 
1200  if (OidIsValid(useId))
1201  {
1202  /* Record the mapped user dependency */
1204  }
1205 
1206  /* dependency on extension */
1207  recordDependencyOnCurrentExtension(&myself, false);
1208 
1209  /* Post creation hook for new user mapping */
1211 
1213 
1214  return myself;
1215 }
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define Anum_pg_user_mapping_umuser
Datum transformGenericOptions(Oid catalogId, Datum oldOptions, List *options, Oid fdwvalidator)
Definition: foreigncmds.c:109
#define Anum_pg_user_mapping_umserver
#define PointerGetDatum(X)
Definition: postgres.h:564
int errcode(int sqlerrcode)
Definition: elog.c:575
static void user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
Definition: foreigncmds.c:1097
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 Natts_pg_user_mapping
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:158
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_user_mapping_umoptions
#define RowExclusiveLock
Definition: lockdefs.h:38
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition: foreign.c:148
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
RoleSpecType roletype
Definition: parsenodes.h:319
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5147
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:114
#define ForeignServerRelationId
#define NULL
Definition: c.h:226
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define UserMappingRelationId
#define ACL_ID_PUBLIC
Definition: acl.h:39
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
#define PointerIsValid(pointer)
Definition: c.h:522
Oid serverid
Definition: foreign.h:47
#define MappingUserName(userid)
Definition: foreign.h:20
bool defGetBoolean ( DefElem def)

Definition at line 111 of file define.c.

References DefElem::arg, defGetString(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, intVal, nodeTag, NULL, pg_strcasecmp(), and T_Integer.

Referenced by AlterDatabase(), compute_attributes_with_style(), createdb(), CreateExtension(), DefineAggregate(), DefineOperator(), DefineType(), dintdict_init(), dsimple_init(), dsynonym_init(), dxsyn_init(), ExplainQuery(), file_fdw_validator(), get_file_fdw_attribute_options(), GetCommandLogLevel(), interpretOidsOption(), parse_publication_options(), parse_subscription_options(), postgres_fdw_validator(), postgresGetForeignRelSize(), postgresImportForeignSchema(), postgresIsForeignRelUpdatable(), and ProcessCopyOptions().

112 {
113  /*
114  * If no parameter given, assume "true" is meant.
115  */
116  if (def->arg == NULL)
117  return true;
118 
119  /*
120  * Allow 0, 1, "true", "false", "on", "off"
121  */
122  switch (nodeTag(def->arg))
123  {
124  case T_Integer:
125  switch (intVal(def->arg))
126  {
127  case 0:
128  return false;
129  case 1:
130  return true;
131  default:
132  /* otherwise, error out below */
133  break;
134  }
135  break;
136  default:
137  {
138  char *sval = defGetString(def);
139 
140  /*
141  * The set of strings accepted here should match up with the
142  * grammar's opt_boolean production.
143  */
144  if (pg_strcasecmp(sval, "true") == 0)
145  return true;
146  if (pg_strcasecmp(sval, "false") == 0)
147  return false;
148  if (pg_strcasecmp(sval, "on") == 0)
149  return true;
150  if (pg_strcasecmp(sval, "off") == 0)
151  return false;
152  }
153  break;
154  }
155  ereport(ERROR,
156  (errcode(ERRCODE_SYNTAX_ERROR),
157  errmsg("%s requires a Boolean value",
158  def->defname)));
159  return false; /* keep compiler quiet */
160 }
int errcode(int sqlerrcode)
Definition: elog.c:575
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define ERROR
Definition: elog.h:43
char * defGetString(DefElem *def)
Definition: define.c:49
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
#define nodeTag(nodeptr)
Definition: nodes.h:513
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
int32 defGetInt32 ( DefElem def)

Definition at line 166 of file define.c.

References DefElem::arg, DefElem::defname, ereport, errcode(), errmsg(), ERROR, intVal, nodeTag, NULL, and T_Integer.

Referenced by AlterDatabase(), createdb(), and DefineAggregate().

167 {
168  if (def->arg == NULL)
169  ereport(ERROR,
170  (errcode(ERRCODE_SYNTAX_ERROR),
171  errmsg("%s requires an integer value",
172  def->defname)));
173  switch (nodeTag(def->arg))
174  {
175  case T_Integer:
176  return (int32) intVal(def->arg);
177  default:
178  ereport(ERROR,
179  (errcode(ERRCODE_SYNTAX_ERROR),
180  errmsg("%s requires an integer value",
181  def->defname)));
182  }
183  return 0; /* keep compiler quiet */
184 }
int errcode(int sqlerrcode)
Definition: elog.c:575
signed int int32
Definition: c.h:253
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
#define nodeTag(nodeptr)
Definition: nodes.h:513
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
int64 defGetInt64 ( DefElem def)

Definition at line 190 of file define.c.

References DefElem::arg, CStringGetDatum, DatumGetInt64, DefElem::defname, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, int8in(), intVal, nodeTag, NULL, strVal, T_Float, and T_Integer.

Referenced by init_params().

191 {
192  if (def->arg == NULL)
193  ereport(ERROR,
194  (errcode(ERRCODE_SYNTAX_ERROR),
195  errmsg("%s requires a numeric value",
196  def->defname)));
197  switch (nodeTag(def->arg))
198  {
199  case T_Integer:
200  return (int64) intVal(def->arg);
201  case T_Float:
202 
203  /*
204  * Values too large for int4 will be represented as Float
205  * constants by the lexer. Accept these if they are valid int8
206  * strings.
207  */
209  CStringGetDatum(strVal(def->arg))));
210  default:
211  ereport(ERROR,
212  (errcode(ERRCODE_SYNTAX_ERROR),
213  errmsg("%s requires a numeric value",
214  def->defname)));
215  }
216  return 0; /* keep compiler quiet */
217 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:555
#define ERROR
Definition: elog.h:43
#define DatumGetInt64(X)
Definition: postgres.h:615
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
Datum int8in(PG_FUNCTION_ARGS)
Definition: int8.c:145
#define nodeTag(nodeptr)
Definition: nodes.h:513
Definition: nodes.h:287
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
double defGetNumeric ( DefElem def)

Definition at line 85 of file define.c.

References DefElem::arg, DefElem::defname, ereport, errcode(), errmsg(), ERROR, floatVal, intVal, nodeTag, NULL, T_Float, and T_Integer.

Referenced by AlterFunction().

86 {
87  if (def->arg == NULL)
88  ereport(ERROR,
89  (errcode(ERRCODE_SYNTAX_ERROR),
90  errmsg("%s requires a numeric value",
91  def->defname)));
92  switch (nodeTag(def->arg))
93  {
94  case T_Integer:
95  return (double) intVal(def->arg);
96  case T_Float:
97  return floatVal(def->arg);
98  default:
99  ereport(ERROR,
100  (errcode(ERRCODE_SYNTAX_ERROR),
101  errmsg("%s requires a numeric value",
102  def->defname)));
103  }
104  return 0; /* keep compiler quiet */
105 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define floatVal(v)
Definition: value.h:53
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
#define nodeTag(nodeptr)
Definition: nodes.h:513
Definition: nodes.h:287
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
List* defGetQualifiedName ( DefElem def)

Definition at line 223 of file define.c.

References DefElem::arg, DefElem::defname, ereport, errcode(), errmsg(), ERROR, list_make1, NIL, nodeTag, NULL, T_List, T_String, and T_TypeName.

Referenced by AlterOperator(), DefineAggregate(), DefineCollation(), DefineOperator(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), get_ts_parser_func(), get_ts_template_func(), and init_params().

224 {
225  if (def->arg == NULL)
226  ereport(ERROR,
227  (errcode(ERRCODE_SYNTAX_ERROR),
228  errmsg("%s requires a parameter",
229  def->defname)));
230  switch (nodeTag(def->arg))
231  {
232  case T_TypeName:
233  return ((TypeName *) def->arg)->names;
234  case T_List:
235  return (List *) def->arg;
236  case T_String:
237  /* Allow quoted name for backwards compatibility */
238  return list_make1(def->arg);
239  default:
240  ereport(ERROR,
241  (errcode(ERRCODE_SYNTAX_ERROR),
242  errmsg("argument of %s must be a name",
243  def->defname)));
244  }
245  return NIL; /* keep compiler quiet */
246 }
#define NIL
Definition: pg_list.h:69
int errcode(int sqlerrcode)
Definition: elog.c:575
#define list_make1(x1)
Definition: pg_list.h:133
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:295
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
#define nodeTag(nodeptr)
Definition: nodes.h:513
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
Definition: pg_list.h:45
char* defGetString ( DefElem def)

Definition at line 49 of file define.c.

References DefElem::arg, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, intVal, NameListToString(), nodeTag, NULL, psprintf(), pstrdup(), strVal, T_A_Star, T_Float, T_Integer, T_List, T_String, T_TypeName, and TypeNameToString().

Referenced by AlterDatabase(), check_selective_binary_conversion(), createdb(), CreateExtension(), defGetBoolean(), defGetTypeLength(), DefineAggregate(), DefineCollation(), DefineType(), deparseAnalyzeSql(), deparseColumnRef(), deparseRelation(), dintdict_init(), dispell_init(), dsimple_init(), dsnowball_init(), dsynonym_init(), dxsyn_init(), ExplainQuery(), ExplainResultDesc(), ExtractConnectionOptions(), file_fdw_validator(), fileGetOptions(), optionListToArray(), parse_subscription_options(), postgres_fdw_validator(), postgresAcquireSampleRowsFunc(), postgresGetForeignRelSize(), ProcessCopyOptions(), prsd_headline(), serialize_deflist(), thesaurus_init(), transformRelOptions(), and unaccent_init().

50 {
51  if (def->arg == NULL)
52  ereport(ERROR,
53  (errcode(ERRCODE_SYNTAX_ERROR),
54  errmsg("%s requires a parameter",
55  def->defname)));
56  switch (nodeTag(def->arg))
57  {
58  case T_Integer:
59  return psprintf("%ld", (long) intVal(def->arg));
60  case T_Float:
61 
62  /*
63  * T_Float values are kept in string form, so this type cheat
64  * works (and doesn't risk losing precision)
65  */
66  return strVal(def->arg);
67  case T_String:
68  return strVal(def->arg);
69  case T_TypeName:
70  return TypeNameToString((TypeName *) def->arg);
71  case T_List:
72  return NameListToString((List *) def->arg);
73  case T_A_Star:
74  return pstrdup("*");
75  default:
76  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
77  }
78  return NULL; /* keep compiler quiet */
79 }
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
char * pstrdup(const char *in)
Definition: mcxt.c:1165
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:295
Node * arg
Definition: parsenodes.h:676
char * NameListToString(List *names)
Definition: namespace.c:2897
#define NULL
Definition: c.h:226
#define nodeTag(nodeptr)
Definition: nodes.h:513
Definition: nodes.h:287
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:675
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
List* defGetStringList ( DefElem def)

Definition at line 327 of file define.c.

References DefElem::arg, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, IsA, lfirst, nodeTag, NULL, and T_List.

Referenced by parse_subscription_options().

328 {
329  ListCell *cell;
330 
331  if (def->arg == NULL)
332  ereport(ERROR,
333  (errcode(ERRCODE_SYNTAX_ERROR),
334  errmsg("%s requires a parameter",
335  def->defname)));
336  if (nodeTag(def->arg) != T_List)
337  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
338 
339  foreach(cell, (List *)def->arg)
340  {
341  Node *str = (Node *) lfirst(cell);
342 
343  if (!IsA(str, String))
344  elog(ERROR, "unexpected node type in name list: %d",
345  (int) nodeTag(str));
346  }
347 
348  return (List *) def->arg;
349 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:295
Node * arg
Definition: parsenodes.h:676
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define nodeTag(nodeptr)
Definition: nodes.h:513
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: pa