PostgreSQL Source Code  git master
amcmds.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_am.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for amcmds.c:

Go to the source code of this file.

Functions

static Oid lookup_am_handler_func (List *handler_name, char amtype)
 
static const char * get_am_type_string (char amtype)
 
ObjectAddress CreateAccessMethod (CreateAmStmt *stmt)
 
void RemoveAccessMethodById (Oid amOid)
 
static Oid get_am_type_oid (const char *amname, char amtype, bool missing_ok)
 
Oid get_index_am_oid (const char *amname, bool missing_ok)
 
Oid get_table_am_oid (const char *amname, bool missing_ok)
 
Oid get_am_oid (const char *amname, bool missing_ok)
 
char * get_am_name (Oid amOid)
 

Function Documentation

◆ CreateAccessMethod()

ObjectAddress CreateAccessMethod ( CreateAmStmt stmt)

Definition at line 42 of file amcmds.c.

References AMNAME, CreateAmStmt::amname, AmOidIndexId, CreateAmStmt::amtype, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CStringGetDatum, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, GetNewOidWithIndex(), GetSysCacheOid1, CreateAmStmt::handler_name, heap_form_tuple(), heap_freetuple(), lookup_am_handler_func(), namein(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, recordDependencyOn(), recordDependencyOnCurrentExtension(), RelationGetDescr, RowExclusiveLock, superuser(), table_close(), table_open(), and values.

Referenced by ProcessUtilitySlow().

43 {
44  Relation rel;
45  ObjectAddress myself;
46  ObjectAddress referenced;
47  Oid amoid;
48  Oid amhandler;
49  bool nulls[Natts_pg_am];
50  Datum values[Natts_pg_am];
51  HeapTuple tup;
52 
53  rel = table_open(AccessMethodRelationId, RowExclusiveLock);
54 
55  /* Must be super user */
56  if (!superuser())
57  ereport(ERROR,
58  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
59  errmsg("permission denied to create access method \"%s\"",
60  stmt->amname),
61  errhint("Must be superuser to create an access method.")));
62 
63  /* Check if name is used */
64  amoid = GetSysCacheOid1(AMNAME, Anum_pg_am_oid,
65  CStringGetDatum(stmt->amname));
66  if (OidIsValid(amoid))
67  {
68  ereport(ERROR,
70  errmsg("access method \"%s\" already exists",
71  stmt->amname)));
72  }
73 
74  /*
75  * Get the handler function oid, verifying the AM type while at it.
76  */
77  amhandler = lookup_am_handler_func(stmt->handler_name, stmt->amtype);
78 
79  /*
80  * Insert tuple into pg_am.
81  */
82  memset(values, 0, sizeof(values));
83  memset(nulls, false, sizeof(nulls));
84 
85  amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
86  values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
87  values[Anum_pg_am_amname - 1] =
89  values[Anum_pg_am_amhandler - 1] = ObjectIdGetDatum(amhandler);
90  values[Anum_pg_am_amtype - 1] = CharGetDatum(stmt->amtype);
91 
92  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
93 
94  CatalogTupleInsert(rel, tup);
95  heap_freetuple(tup);
96 
97  myself.classId = AccessMethodRelationId;
98  myself.objectId = amoid;
99  myself.objectSubId = 0;
100 
101  /* Record dependency on handler function */
102  referenced.classId = ProcedureRelationId;
103  referenced.objectId = amhandler;
104  referenced.objectSubId = 0;
105 
106  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
107 
108  recordDependencyOnCurrentExtension(&myself, false);
109 
111 
112  return myself;
113 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:323
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
int errhint(const char *fmt,...)
Definition: elog.c:974
static Oid lookup_am_handler_func(List *handler_name, char amtype)
Definition: amcmds.c:258
#define RelationGetDescr(relation)
Definition: rel.h:445
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * amname
Definition: parsenodes.h:2395
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
List * handler_name
Definition: parsenodes.h:2396
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138
#define CharGetDatum(X)
Definition: postgres.h:416
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define AmOidIndexId
Definition: indexing.h:74
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:33
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:183

◆ get_am_name()

char* get_am_name ( Oid  amOid)

Definition at line 216 of file amcmds.c.

References AMOID, GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, pstrdup(), ReleaseSysCache(), and SearchSysCache1().

Referenced by assignOperTypes(), getObjectIdentityParts(), IsThereOpClassInNamespace(), and IsThereOpFamilyInNamespace().

217 {
218  HeapTuple tup;
219  char *result = NULL;
220 
221  tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
222  if (HeapTupleIsValid(tup))
223  {
224  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
225 
226  result = pstrdup(NameStr(amform->amname));
227  ReleaseSysCache(tup);
228  }
229  return result;
230 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Definition: syscache.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
#define NameStr(name)
Definition: c.h:609

◆ get_am_oid()

Oid get_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 207 of file amcmds.c.

References get_am_type_oid().

Referenced by get_object_address_unqualified().

208 {
209  return get_am_type_oid(amname, '\0', missing_ok);
210 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:153

◆ get_am_type_oid()

static Oid get_am_type_oid ( const char *  amname,
char  amtype,
bool  missing_ok 
)
static

Definition at line 153 of file amcmds.c.

References AMNAME, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, get_am_type_string(), GETSTRUCT, HeapTupleIsValid, InvalidOid, NameStr, OidIsValid, ReleaseSysCache(), and SearchSysCache1().

Referenced by get_am_oid(), get_index_am_oid(), and get_table_am_oid().

154 {
155  HeapTuple tup;
156  Oid oid = InvalidOid;
157 
158  tup = SearchSysCache1(AMNAME, CStringGetDatum(amname));
159  if (HeapTupleIsValid(tup))
160  {
161  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
162 
163  if (amtype != '\0' &&
164  amform->amtype != amtype)
165  ereport(ERROR,
166  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
167  errmsg("access method \"%s\" is not of type %s",
168  NameStr(amform->amname),
169  get_am_type_string(amtype))));
170 
171  oid = amform->oid;
172  ReleaseSysCache(tup);
173  }
174 
175  if (!OidIsValid(oid) && !missing_ok)
176  ereport(ERROR,
177  (errcode(ERRCODE_UNDEFINED_OBJECT),
178  errmsg("access method \"%s\" does not exist", amname)));
179  return oid;
180 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static const char * get_am_type_string(char amtype)
Definition: amcmds.c:236
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define NameStr(name)
Definition: c.h:609

◆ get_am_type_string()

static const char * get_am_type_string ( char  amtype)
static

Definition at line 236 of file amcmds.c.

References elog, and ERROR.

Referenced by get_am_type_oid().

237 {
238  switch (amtype)
239  {
240  case AMTYPE_INDEX:
241  return "INDEX";
242  case AMTYPE_TABLE:
243  return "TABLE";
244  default:
245  /* shouldn't happen */
246  elog(ERROR, "invalid access method type '%c'", amtype);
247  return NULL; /* keep compiler quiet */
248  }
249 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:226

◆ get_index_am_oid()

Oid get_index_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 187 of file amcmds.c.

References get_am_type_oid().

Referenced by DefineOpFamily(), get_object_address_opcf(), and transformIndexConstraint().

188 {
189  return get_am_type_oid(amname, AMTYPE_INDEX, missing_ok);
190 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:153

◆ get_table_am_oid()

Oid get_table_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 197 of file amcmds.c.

References get_am_type_oid().

Referenced by check_default_table_access_method(), and DefineRelation().

198 {
199  return get_am_type_oid(amname, AMTYPE_TABLE, missing_ok);
200 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:153

◆ lookup_am_handler_func()

static Oid lookup_am_handler_func ( List handler_name,
char  amtype 
)
static

Definition at line 258 of file amcmds.c.

References elog, ereport, errcode(), errmsg(), ERROR, format_type_extended(), get_func_name(), get_func_rettype(), InvalidOid, LookupFuncName(), and NIL.

Referenced by CreateAccessMethod().

259 {
260  Oid handlerOid;
261  Oid funcargtypes[1] = {INTERNALOID};
262  Oid expectedType = InvalidOid;
263 
264  if (handler_name == NIL)
265  ereport(ERROR,
266  (errcode(ERRCODE_UNDEFINED_FUNCTION),
267  errmsg("handler function is not specified")));
268 
269  /* handlers have one argument of type internal */
270  handlerOid = LookupFuncName(handler_name, 1, funcargtypes, false);
271 
272  /* check that handler has the correct return type */
273  switch (amtype)
274  {
275  case AMTYPE_INDEX:
276  expectedType = INDEX_AM_HANDLEROID;
277  break;
278  case AMTYPE_TABLE:
279  expectedType = TABLE_AM_HANDLEROID;
280  break;
281  default:
282  elog(ERROR, "unrecognized access method type \"%c\"", amtype);
283  }
284 
285  if (get_func_rettype(handlerOid) != expectedType)
286  ereport(ERROR,
287  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
288  errmsg("function %s must return type %s",
289  get_func_name(handlerOid),
290  format_type_extended(expectedType, -1, 0))));
291 
292  return handlerOid;
293 }
#define NIL
Definition: pg_list.h:65
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1457
#define ERROR
Definition: elog.h:43
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1410
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2100
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvalidOid
Definition: postgres_ext.h:36
char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
Definition: format_type.c:108
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ RemoveAccessMethodById()

void RemoveAccessMethodById ( Oid  amOid)

Definition at line 119 of file amcmds.c.

References AMOID, CatalogTupleDelete(), elog, ereport, errcode(), errmsg(), ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), superuser(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

120 {
121  Relation relation;
122  HeapTuple tup;
123 
124  if (!superuser())
125  ereport(ERROR,
126  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
127  errmsg("must be superuser to drop access methods")));
128 
129  relation = table_open(AccessMethodRelationId, RowExclusiveLock);
130 
131  tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
132  if (!HeapTupleIsValid(tup))
133  elog(ERROR, "cache lookup failed for access method %u", amOid);
134 
135  CatalogTupleDelete(relation, &tup->t_self);
136 
137  ReleaseSysCache(tup);
138 
139  table_close(relation, RowExclusiveLock);
140 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Definition: syscache.h:36
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:141
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39