1/*-------------------------------------------------------------------------
4 * Routines for SQL commands that manipulate access methods.
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/commands/amcmds.c
12 *-------------------------------------------------------------------------
40 * Registers a new access method.
50 bool nulls[Natts_pg_am];
56 /* Must be superuser */
59 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
60 errmsg(
"permission denied to create access method \"%s\"",
62 errhint(
"Must be superuser to create an access method.")));
64 /* Check if name is used */
71 errmsg(
"access method \"%s\" already exists",
76 * Get the handler function oid, verifying the AM type while at it.
81 * Insert tuple into pg_am.
84 memset(nulls,
false,
sizeof(nulls));
88 values[Anum_pg_am_amname - 1] =
98 myself.
classId = AccessMethodRelationId;
102 /* Record dependency on handler function */
103 referenced.
classId = ProcedureRelationId;
120 * Worker for various get_am_*_oid variants
122 * If missing_ok is false, throw an error if access method not found. If
123 * true, just return InvalidOid.
125 * If amtype is not '0円', an error is raised if the AM found is not of the
139 if (amtype !=
'0円' &&
140 amform->amtype != amtype)
142 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
143 errmsg(
"access method \"%s\" is not of type %s",
153 (
errcode(ERRCODE_UNDEFINED_OBJECT),
154 errmsg(
"access method \"%s\" does not exist", amname)));
159 * get_index_am_oid - given an access method name, look up its OID
160 * and verify it corresponds to an index AM.
169 * get_table_am_oid - given an access method name, look up its OID
170 * and verify it corresponds to a table AM.
179 * get_am_oid - given an access method name, look up its OID.
180 * The type is not checked.
189 * get_am_name - given an access method OID, look up its name.
209 * Convert single-character access method type into string for error reporting.
221 /* shouldn't happen */
222 elog(
ERROR,
"invalid access method type '%c'", amtype);
223 return NULL;
/* keep compiler quiet */
228 * Convert a handler function name to an Oid. If the return type of the
229 * function doesn't match the given AM type, an error is raised.
231 * This function either return valid function Oid or throw an error.
237 Oid funcargtypes[1] = {INTERNALOID};
240 if (handler_name ==
NIL)
242 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
243 errmsg(
"handler function is not specified")));
245 /* handlers have one argument of type internal */
246 handlerOid =
LookupFuncName(handler_name, 1, funcargtypes,
false);
248 /* check that handler has the correct return type */
252 expectedType = INDEX_AM_HANDLEROID;
255 expectedType = TABLE_AM_HANDLEROID;
258 elog(
ERROR,
"unrecognized access method type \"%c\"", amtype);
263 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
264 errmsg(
"function %s must return type %s",
ObjectAddress CreateAccessMethod(CreateAmStmt *stmt)
Oid get_table_am_oid(const char *amname, bool missing_ok)
Oid get_index_am_oid(const char *amname, bool missing_ok)
static const char * get_am_type_string(char amtype)
char * get_am_name(Oid amOid)
static Oid get_am_type_oid(const char *amname, char amtype, bool missing_ok)
Oid get_am_oid(const char *amname, bool missing_ok)
static Oid lookup_am_handler_func(List *handler_name, char amtype)
static Datum values[MAXATTR]
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define DirectFunctionCall1(func, arg1)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
char * get_func_name(Oid funcid)
Oid get_func_rettype(Oid funcid)
char * pstrdup(const char *in)
Datum namein(PG_FUNCTION_ARGS)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
FormData_pg_am * Form_pg_am
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum CharGetDatum(char X)
#define RelationGetDescr(relation)
#define ERRCODE_DUPLICATE_OBJECT
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define GetSysCacheOid1(cacheId, oidcol, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)