From 1ca8f8f2f92a3d7b4605e4b47e50e245d3f10265 Mon Sep 17 00:00:00 2001 From: Hari Babu Date: Wed, 30 Aug 2017 12:41:15 +1000 Subject: [PATCH 02/12] Storage AM folder and init functions --- src/backend/access/Makefile | 2 +- src/backend/access/heap/Makefile | 3 +- src/backend/access/heap/heapam_storage.c | 33 ++++++++++ src/backend/access/storage/Makefile | 17 +++++ src/backend/access/storage/storageam.c | 15 +++++ src/backend/access/storage/storageamapi.c | 103 ++++++++++++++++++++++++++++++ src/include/access/storageamapi.h | 39 +++++++++++ src/include/catalog/pg_am.h | 3 + src/include/catalog/pg_proc.h | 5 ++ src/include/nodes/nodes.h | 1 + 10 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 src/backend/access/heap/heapam_storage.c create mode 100644 src/backend/access/storage/Makefile create mode 100644 src/backend/access/storage/storageam.c create mode 100644 src/backend/access/storage/storageamapi.c create mode 100644 src/include/access/storageamapi.h diff --git a/src/backend/access/Makefile b/src/backend/access/Makefile index bd93a6a8d1..e72ad6c86c 100644 --- a/src/backend/access/Makefile +++ b/src/backend/access/Makefile @@ -9,6 +9,6 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global SUBDIRS = brin common gin gist hash heap index nbtree rmgrdesc spgist \ - tablesample transam + storage tablesample transam include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile index b83d496bcd..816f03a86f 100644 --- a/src/backend/access/heap/Makefile +++ b/src/backend/access/heap/Makefile @@ -12,6 +12,7 @@ subdir = src/backend/access/heap top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o visibilitymap.o +OBJS = heapam.o hio.o heapam_storage.o pruneheap.o rewriteheap.o \ + syncscan.o tuptoaster.o visibilitymap.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/heap/heapam_storage.c b/src/backend/access/heap/heapam_storage.c new file mode 100644 index 0000000000..792e9cb436 --- /dev/null +++ b/src/backend/access/heap/heapam_storage.c @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * heapam_storage.c + * heap storage access method code + * + * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/heap/heapam_storage.c + * + * + * NOTES + * This file contains the heap_ routines which implement + * the POSTGRES heap access method used for all POSTGRES + * relations. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/storageamapi.h" +#include "utils/builtins.h" + + +Datum +heapam_storage_handler(PG_FUNCTION_ARGS) +{ + StorageAmRoutine *amroutine = makeNode(StorageAmRoutine); + + PG_RETURN_POINTER(amroutine); +} diff --git a/src/backend/access/storage/Makefile b/src/backend/access/storage/Makefile new file mode 100644 index 0000000000..2a05c7ce66 --- /dev/null +++ b/src/backend/access/storage/Makefile @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for access/storage +# +# IDENTIFICATION +# src/backend/access/storage/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/access/storage +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = storageam.o storageamapi.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/storage/storageam.c b/src/backend/access/storage/storageam.c new file mode 100644 index 0000000000..8541c75782 --- /dev/null +++ b/src/backend/access/storage/storageam.c @@ -0,0 +1,15 @@ +/*------------------------------------------------------------------------- + * + * storageam.c + * storage access method code + * + * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/storage/storageam.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" diff --git a/src/backend/access/storage/storageamapi.c b/src/backend/access/storage/storageamapi.c new file mode 100644 index 0000000000..bcbe14588b --- /dev/null +++ b/src/backend/access/storage/storageamapi.c @@ -0,0 +1,103 @@ +/*---------------------------------------------------------------------- + * + * storageamapi.c + * Support routines for API for Postgres storage access methods + * + * FIXME: looks like this should be in amapi.c. + * + * Copyright (c) 2016, PostgreSQL Global Development Group + * + * src/backend/access/heap/storageamapi.c + *---------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/htup_details.h" +#include "access/storageamapi.h" +#include "catalog/pg_am.h" +#include "catalog/pg_proc.h" +#include "utils/syscache.h" +#include "utils/memutils.h" + + +/* + * GetStorageAmRoutine + * Call the specified access method handler routine to get its + * StorageAmRoutine struct, which will be palloc'd in the caller's + * memory context. + */ +StorageAmRoutine * +GetStorageAmRoutine(Oid amhandler) +{ + Datum datum; + StorageAmRoutine *routine; + + datum = OidFunctionCall0(amhandler); + routine = (StorageAmRoutine *) DatumGetPointer(datum); + + if (routine == NULL || !IsA(routine, StorageAmRoutine)) + elog(ERROR, "storage access method handler %u did not return a StorageAmRoutine struct", + amhandler); + + return routine; +} + +/* A crock */ +StorageAmRoutine * +GetHeapamStorageAmRoutine(void) +{ + Datum datum; + static StorageAmRoutine * HeapamStorageAmRoutine = NULL; + + if (HeapamStorageAmRoutine == NULL) + { + MemoryContext oldcxt; + + oldcxt = MemoryContextSwitchTo(TopMemoryContext); + datum = OidFunctionCall0(HEAPAM_STORAGE_AM_HANDLER_OID); + HeapamStorageAmRoutine = (StorageAmRoutine *) DatumGetPointer(datum); + MemoryContextSwitchTo(oldcxt); + } + + return HeapamStorageAmRoutine; +} + +/* + * GetStorageAmRoutineByAmId - look up the handler of the storage access + * method with the given OID, and get its StorageAmRoutine struct. + */ +StorageAmRoutine * +GetStorageAmRoutineByAmId(Oid amoid) +{ + regproc amhandler; + HeapTuple tuple; + Form_pg_am amform; + + /* Get handler function OID for the access method */ + tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for access method %u", + amoid); + amform = (Form_pg_am) GETSTRUCT(tuple); + + /* Check that it is a storage access method */ + if (amform->amtype != AMTYPE_STORAGE) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("access method \"%s\" is not of type %s", + NameStr(amform->amname), "STORAGE"))); + + amhandler = amform->amhandler; + + /* Complain if handler OID is invalid */ + if (!RegProcedureIsValid(amhandler)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("storage access method \"%s\" does not have a handler", + NameStr(amform->amname)))); + + ReleaseSysCache(tuple); + + /* And finally, call the handler function to get the API struct. */ + return GetStorageAmRoutine(amhandler); +} diff --git a/src/include/access/storageamapi.h b/src/include/access/storageamapi.h new file mode 100644 index 0000000000..6fae4eea5c --- /dev/null +++ b/src/include/access/storageamapi.h @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------- + * + * storageamapi.h + * API for Postgres storage access methods + * + * Copyright (c) 2017, PostgreSQL Global Development Group + * + * src/include/access/storageamapi.h + *--------------------------------------------------------------------- + */ +#ifndef STORAGEAMAPI_H +#define STORAGEAMAPI_H + +#include "nodes/nodes.h" +#include "fmgr.h" + +/* A physical tuple coming from a storage AM scan */ +typedef void *StorageTuple; + +/* + * API struct for a storage AM. Note this must be stored in a single palloc'd + * chunk of memory. + * + * XXX currently all functions are together in a single struct. Would it be + * worthwhile to split the slot-accessor functions to a different struct? + * That way, MinimalTuple could be handled without a complete StorageAmRoutine + * for them -- it'd only have a few functions in TupleTableSlotAmRoutine or so. + */ +typedef struct StorageAmRoutine +{ + NodeTag type; + +} StorageAmRoutine; + +extern StorageAmRoutine * GetStorageAmRoutine(Oid amhandler); +extern StorageAmRoutine * GetStorageAmRoutineByAmId(Oid amoid); +extern StorageAmRoutine * GetHeapamStorageAmRoutine(void); + +#endif /* STORAGEAMAPI_H */ diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index b3532e4058..e946f6ad3b 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -84,5 +84,8 @@ DESCR("SP-GiST index access method"); DATA(insert OID = 3580 ( brin brinhandler i )); DESCR("block range index (BRIN) access method"); #define BRIN_AM_OID 3580 +DATA(insert OID = 4001 ( heapam heapam_storage_handler s )); +DESCR("heapam storage access method"); +#define HEAPAM_STORAGE_AM_OID 4001 #endif /* PG_AM_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index f3b471a0b6..f0d1b9311a 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -558,6 +558,11 @@ DESCR("convert int4 to float4"); DATA(insert OID = 319 ( int4 PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "700" _null_ _null_ _null_ _null_ _null_ ftoi4 _null_ _null_ _null_ )); DESCR("convert float4 to int4"); +/* Storage access method handlers */ +DATA(insert OID = 4002 ( heapam_storage_handler PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 3998 "2281" _null_ _null_ _null_ _null_ _null_ heapam_storage_handler _null_ _null_ _null_ )); +DESCR("row-oriented storage access method handler"); +#define HEAPAM_STORAGE_AM_HANDLER_OID 4002 + /* Index access method handlers */ DATA(insert OID = 330 ( bthandler PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 325 "2281" _null_ _null_ _null_ _null_ _null_ bthandler _null_ _null_ _null_ )); DESCR("btree index access method handler"); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 2eb3d6d371..6477664b30 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -499,6 +499,7 @@ typedef enum NodeTag T_InlineCodeBlock, /* in nodes/parsenodes.h */ T_FdwRoutine, /* in foreign/fdwapi.h */ T_IndexAmRoutine, /* in access/amapi.h */ + T_StorageAmRoutine, /* in access/storageamapi.h */ T_TsmRoutine, /* in access/tsmapi.h */ T_ForeignKeyCacheInfo /* in utils/rel.h */ } NodeTag; -- 2.15.0.windows.1