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/objectaccess.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)
 
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 43 of file amcmds.c.

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

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

Referenced by ProcessUtilitySlow().

◆ get_am_name()

char* get_am_name ( Oid  amOid)

Definition at line 192 of file amcmds.c.

193 {
194  HeapTuple tup;
195  char *result = NULL;
196 
197  tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
198  if (HeapTupleIsValid(tup))
199  {
200  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
201 
202  result = pstrdup(NameStr(amform->amname));
203  ReleaseSysCache(tup);
204  }
205  return result;
206 }
#define NameStr(name)
Definition: c.h:746
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1695
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

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

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

◆ get_am_oid()

Oid get_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 183 of file amcmds.c.

184 {
185  return get_am_type_oid(amname, '\0', missing_ok);
186 }
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Definition: amcmds.c:129

References get_am_type_oid().

Referenced by get_object_address_unqualified().

◆ get_am_type_oid()

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

Definition at line 129 of file amcmds.c.

130 {
131  HeapTuple tup;
132  Oid oid = InvalidOid;
133 
134  tup = SearchSysCache1(AMNAME, CStringGetDatum(amname));
135  if (HeapTupleIsValid(tup))
136  {
137  Form_pg_am amform = (Form_pg_am) GETSTRUCT(tup);
138 
139  if (amtype != '\0' &&
140  amform->amtype != amtype)
141  ereport(ERROR,
142  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
143  errmsg("access method \"%s\" is not of type %s",
144  NameStr(amform->amname),
145  get_am_type_string(amtype))));
146 
147  oid = amform->oid;
148  ReleaseSysCache(tup);
149  }
150 
151  if (!OidIsValid(oid) && !missing_ok)
152  ereport(ERROR,
153  (errcode(ERRCODE_UNDEFINED_OBJECT),
154  errmsg("access method \"%s\" does not exist", amname)));
155  return oid;
156 }
static const char * get_am_type_string(char amtype)
Definition: amcmds.c:212
#define InvalidOid
Definition: postgres_ext.h:36

References 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().

◆ get_am_type_string()

static const char * get_am_type_string ( char  amtype)
static

Definition at line 212 of file amcmds.c.

213 {
214  switch (amtype)
215  {
216  case AMTYPE_INDEX:
217  return "INDEX";
218  case AMTYPE_TABLE:
219  return "TABLE";
220  default:
221  /* shouldn't happen */
222  elog(ERROR, "invalid access method type '%c'", amtype);
223  return NULL; /* keep compiler quiet */
224  }
225 }
#define elog(elevel,...)
Definition: elog.h:224

References elog, and ERROR.

Referenced by get_am_type_oid().

◆ get_index_am_oid()

Oid get_index_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 163 of file amcmds.c.

164 {
165  return get_am_type_oid(amname, AMTYPE_INDEX, missing_ok);
166 }

References get_am_type_oid().

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

◆ get_table_am_oid()

Oid get_table_am_oid ( const char *  amname,
bool  missing_ok 
)

Definition at line 173 of file amcmds.c.

174 {
175  return get_am_type_oid(amname, AMTYPE_TABLE, missing_ok);
176 }

References get_am_type_oid().

Referenced by ATPrepSetAccessMethod(), check_default_table_access_method(), and DefineRelation().

◆ lookup_am_handler_func()

static Oid lookup_am_handler_func ( List handler_name,
char  amtype 
)
static

Definition at line 234 of file amcmds.c.

235 {
236  Oid handlerOid;
237  Oid funcargtypes[1] = {INTERNALOID};
238  Oid expectedType = InvalidOid;
239 
240  if (handler_name == NIL)
241  ereport(ERROR,
242  (errcode(ERRCODE_UNDEFINED_FUNCTION),
243  errmsg("handler function is not specified")));
244 
245  /* handlers have one argument of type internal */
246  handlerOid = LookupFuncName(handler_name, 1, funcargtypes, false);
247 
248  /* check that handler has the correct return type */
249  switch (amtype)
250  {
251  case AMTYPE_INDEX:
252  expectedType = INDEX_AM_HANDLEROID;
253  break;
254  case AMTYPE_TABLE:
255  expectedType = TABLE_AM_HANDLEROID;
256  break;
257  default:
258  elog(ERROR, "unrecognized access method type \"%c\"", amtype);
259  }
260 
261  if (get_func_rettype(handlerOid) != expectedType)
262  ereport(ERROR,
263  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
264  errmsg("function %s must return type %s",
265  get_func_name(handlerOid),
266  format_type_extended(expectedType, -1, 0))));
267 
268  return handlerOid;
269 }
char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
Definition: format_type.c:112
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1608
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1655
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2143
#define NIL
Definition: pg_list.h:68

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

Referenced by CreateAccessMethod().