PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
amcmds.c File Reference
#include "postgres.h"
#include "access/heapam.h"
#include "access/htup_details.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_index_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_am_oid (const char *amname, bool missing_ok)
 
char * get_am_name (Oid amOid)
 

Function Documentation

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:576
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:177
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
char * amname
Definition: parsenodes.h:2272
#define AccessMethodRelationId
Definition: pg_am.h:32
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:584
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:372
List * handler_name
Definition: parsenodes.h:2273
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:422
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:31
char* get_am_name ( Oid  amOid)

Definition at line 202 of file amcmds.c.

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

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

203 {
204  HeapTuple tup;
205  char *result = NULL;
206 
207  tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
208  if (HeapTupleIsValid(tup))
209  {
210  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
211 
212  result = pstrdup(NameStr(amform->amname));
213  ReleaseSysCache(tup);
214  }
215  return result;
216 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Definition: syscache.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:150
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
FormData_pg_am * Form_pg_am
Definition: pg_am.h:46
#define NameStr(name)
Definition: c.h:499
Oid get_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 193 of file amcmds.c.

References get_am_type_oid().

Referenced by get_object_address_unqualified().

194 {
195  return get_am_type_oid(amname, '\0', missing_ok);
196 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:149
static Oid get_am_type_oid ( const char *  amname,
char  amtype,
bool  missing_ok 
)
static

Definition at line 149 of file amcmds.c.

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

Referenced by get_am_oid(), and get_index_am_oid().

150 {
151  HeapTuple tup;
152  Oid oid = InvalidOid;
153 
154  tup = SearchSysCache1(AMNAME, CStringGetDatum(amname));
155  if (HeapTupleIsValid(tup))
156  {
157  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
158 
159  if (amtype != '\0' &&
160  amform->amtype != amtype)
161  ereport(ERROR,
162  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
163  errmsg("access method \"%s\" is not of type %s",
164  NameStr(amform->amname),
165  get_am_type_string(amtype))));
166 
167  oid = HeapTupleGetOid(tup);
168  ReleaseSysCache(tup);
169  }
170 
171  if (!OidIsValid(oid) && !missing_ok)
172  ereport(ERROR,
173  (errcode(ERRCODE_UNDEFINED_OBJECT),
174  errmsg("access method \"%s\" does not exist", amname)));
175  return oid;
176 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static const char * get_am_type_string(char amtype)
Definition: amcmds.c:222
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:150
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_am * Form_pg_am
Definition: pg_am.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static const char * get_am_type_string ( char  amtype)
static

Definition at line 222 of file amcmds.c.

References AMTYPE_INDEX, elog, ERROR, and NULL.

Referenced by get_am_type_oid().

223 {
224  switch (amtype)
225  {
226  case AMTYPE_INDEX:
227  return "INDEX";
228  default:
229  /* shouldn't happen */
230  elog(ERROR, "invalid access method type '%c'", amtype);
231  return NULL; /* keep compiler quiet */
232  }
233 }
#define ERROR
Definition: elog.h:43
#define AMTYPE_INDEX
Definition: pg_am.h:61
#define NULL
Definition: c.h:229
#define elog
Definition: elog.h:219
Oid get_index_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 183 of file amcmds.c.

References AMTYPE_INDEX, and get_am_type_oid().

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

184 {
185  return get_am_type_oid(amname, AMTYPE_INDEX, missing_ok);
186 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:149
#define AMTYPE_INDEX
Definition: pg_am.h:61
static Oid lookup_index_am_handler_func ( List handler_name,
char  amtype 
)
static

Definition at line 242 of file amcmds.c.

References AMTYPE_INDEX, elog, ereport, errcode(), errmsg(), ERROR, get_func_rettype(), INDEX_AM_HANDLEROID, INTERNALOID, LookupFuncName(), NameListToString(), and NIL.

Referenced by CreateAccessMethod().

243 {
244  Oid handlerOid;
245  static const Oid funcargtypes[1] = {INTERNALOID};
246 
247  if (handler_name == NIL)
248  ereport(ERROR,
249  (errcode(ERRCODE_UNDEFINED_FUNCTION),
250  errmsg("handler function is not specified")));
251 
252  /* handlers have one argument of type internal */
253  handlerOid = LookupFuncName(handler_name, 1, funcargtypes, false);
254 
255  /* check that handler has the correct return type */
256  switch (amtype)
257  {
258  case AMTYPE_INDEX:
259  if (get_func_rettype(handlerOid) != INDEX_AM_HANDLEROID)
260  ereport(ERROR,
261  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
262  errmsg("function %s must return type %s",
263  NameListToString(handler_name),
264  "index_am_handler")));
265  break;
266  default:
267  elog(ERROR, "unrecognized access method type \"%c\"", amtype);
268  }
269 
270  return handlerOid;
271 }
#define NIL
Definition: pg_list.h:69
int errcode(int sqlerrcode)
Definition: elog.c:575
#define INDEX_AM_HANDLEROID
Definition: pg_type.h:702
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1427
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define AMTYPE_INDEX
Definition: pg_am.h:61
char * NameListToString(List *names)
Definition: namespace.c:2897
#define INTERNALOID
Definition: pg_type.h:690
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
Definition: parse_func.c:1910
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void RemoveAccessMethodById ( Oid  amOid)

Definition at line 115 of file amcmds.c.

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

Referenced by doDeletion().

116 {
117  Relation relation;
118  HeapTuple tup;
119 
120  if (!superuser())
121  ereport(ERROR,
122  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
123  errmsg("must be superuser to drop access methods")));
124 
126 
127  tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
128  if (!HeapTupleIsValid(tup))
129  elog(ERROR, "cache lookup failed for access method %u", amOid);
130 
131  CatalogTupleDelete(relation, &tup->t_self);
132 
133  ReleaseSysCache(tup);
134 
135  heap_close(relation, RowExclusiveLock);
136 }
Definition: syscache.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:150
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define AccessMethodRelationId
Definition: pg_am.h:32
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219