From d5c4e514bb77471e896796dd2c228b92ed0ce081 Mon Sep 17 00:00:00 2001 From: Hari Babu Date: Thu, 29 Mar 2018 16:17:54 +1100 Subject: [PATCH 02/16] Table AM API init functions --- src/backend/access/Makefile | 2 +- src/backend/access/heap/Makefile | 3 +- src/backend/access/heap/heapam_handler.c | 33 ++++++++++ src/backend/access/table/Makefile | 17 +++++ src/backend/access/table/tableamapi.c | 103 +++++++++++++++++++++++++++++++ src/include/access/tableamapi.h | 39 ++++++++++++ src/include/catalog/pg_am.dat | 3 + src/include/catalog/pg_proc.dat | 6 ++ src/include/nodes/nodes.h | 1 + 9 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 src/backend/access/heap/heapam_handler.c create mode 100644 src/backend/access/table/Makefile create mode 100644 src/backend/access/table/tableamapi.c create mode 100644 src/include/access/tableamapi.h diff --git a/src/backend/access/Makefile b/src/backend/access/Makefile index bd93a6a8d1..0880e0a8bb 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 + table 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..87bea410f9 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 heapam_handler.o hio.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_handler.c b/src/backend/access/heap/heapam_handler.c new file mode 100644 index 0000000000..6d4323152e --- /dev/null +++ b/src/backend/access/heap/heapam_handler.c @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * heapam_handler.c + * heap table 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_handler.c + * + * + * NOTES + * This file contains the heap_ routines which implement + * the POSTGRES heap table access method used for all POSTGRES + * relations. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/tableamapi.h" +#include "utils/builtins.h" + + +Datum +heap_tableam_handler(PG_FUNCTION_ARGS) +{ + TableAmRoutine *amroutine = makeNode(TableAmRoutine); + + PG_RETURN_POINTER(amroutine); +} diff --git a/src/backend/access/table/Makefile b/src/backend/access/table/Makefile new file mode 100644 index 0000000000..496b7387c6 --- /dev/null +++ b/src/backend/access/table/Makefile @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for access/table +# +# IDENTIFICATION +# src/backend/access/table/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/access/table +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = tableamapi.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c new file mode 100644 index 0000000000..f94660e306 --- /dev/null +++ b/src/backend/access/table/tableamapi.c @@ -0,0 +1,103 @@ +/*---------------------------------------------------------------------- + * + * tableamapi.c + * Support routines for API for Postgres table access methods + * + * FIXME: looks like this should be in amapi.c. + * + * Copyright (c) 2016, PostgreSQL Global Development Group + * + * src/backend/access/table/tableamapi.c + *---------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/htup_details.h" +#include "access/tableamapi.h" +#include "catalog/pg_am.h" +#include "catalog/pg_proc.h" +#include "utils/syscache.h" +#include "utils/memutils.h" + + +/* + * GetTableAmRoutine + * Call the specified access method handler routine to get its + * TableAmRoutine struct, which will be palloc'd in the caller's + * memory context. + */ +TableAmRoutine * +GetTableAmRoutine(Oid amhandler) +{ + Datum datum; + TableAmRoutine *routine; + + datum = OidFunctionCall0(amhandler); + routine = (TableAmRoutine *) DatumGetPointer(datum); + + if (routine == NULL || !IsA(routine, TableAmRoutine)) + elog(ERROR, "Table access method handler %u did not return a TableAmRoutine struct", + amhandler); + + return routine; +} + +/* A crock */ +TableAmRoutine * +GetHeapamTableAmRoutine(void) +{ + Datum datum; + static TableAmRoutine * HeapTableAmRoutine = NULL; + + if (HeapTableAmRoutine == NULL) + { + MemoryContext oldcxt; + + oldcxt = MemoryContextSwitchTo(TopMemoryContext); + datum = OidFunctionCall0(HEAP_TABLE_AM_HANDLER_OID); + HeapTableAmRoutine = (TableAmRoutine *) DatumGetPointer(datum); + MemoryContextSwitchTo(oldcxt); + } + + return HeapTableAmRoutine; +} + +/* + * GetTableAmRoutineByAmId - look up the handler of the table access + * method with the given OID, and get its TableAmRoutine struct. + */ +TableAmRoutine * +GetTableAmRoutineByAmId(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 table access method */ + if (amform->amtype != AMTYPE_TABLE) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("access method \"%s\" is not of type %s", + NameStr(amform->amname), "TABLE"))); + + amhandler = amform->amhandler; + + /* Complain if handler OID is invalid */ + if (!RegProcedureIsValid(amhandler)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("table 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 GetTableAmRoutine(amhandler); +} diff --git a/src/include/access/tableamapi.h b/src/include/access/tableamapi.h new file mode 100644 index 0000000000..55ddad68fb --- /dev/null +++ b/src/include/access/tableamapi.h @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------- + * + * tableamapi.h + * API for Postgres table access methods + * + * Copyright (c) 2017, PostgreSQL Global Development Group + * + * src/include/access/tableamapi.h + *--------------------------------------------------------------------- + */ +#ifndef TABLEEAMAPI_H +#define TABLEEAMAPI_H + +#include "nodes/nodes.h" +#include "fmgr.h" + +/* A physical tuple coming from a table AM scan */ +typedef void *TableTuple; + +/* + * API struct for a table 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 TableAmRoutine + * for them -- it'd only have a few functions in TupleTableSlotAmRoutine or so. + */ +typedef struct TableAmRoutine +{ + NodeTag type; + +} TableAmRoutine; + +extern TableAmRoutine * GetTableAmRoutine(Oid amhandler); +extern TableAmRoutine * GetTableAmRoutineByAmId(Oid amoid); +extern TableAmRoutine * GetHeapamTableAmRoutine(void); + +#endif /* TABLEEAMAPI_H */ diff --git a/src/include/catalog/pg_am.dat b/src/include/catalog/pg_am.dat index bef53a319a..aa3293d736 100644 --- a/src/include/catalog/pg_am.dat +++ b/src/include/catalog/pg_am.dat @@ -30,5 +30,8 @@ { oid => '3580', oid_symbol => 'BRIN_AM_OID', descr => 'block range index (BRIN) access method', amname => 'brin', amhandler => 'brinhandler', amtype => 'i' }, +{ oid => '4001', oid_symbol => 'HEAP_TABLE_AM_OID', + descr => 'heap table access method', + amname => 'heap_tableam', amhandler => 'heap_tableam_handler', amtype => 't' }, ] diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 1dbc1ddcc8..4a047c0e08 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -921,6 +921,12 @@ proname => 'int4', prorettype => 'int4', proargtypes => 'float4', prosrc => 'ftoi4' }, +# Table access method handlers +{ oid => '4002', oid_symbol => 'HEAP_TABLE_AM_HANDLER_OID', + descr => 'row-oriented heap table access method handler', + proname => 'heap_tableam_handler', provolatile => 'v', prorettype => 'table_am_handler', + proargtypes => 'internal', prosrc => 'heap_tableam_handler' }, + # Index access method handlers { oid => '330', descr => 'btree index access method handler', proname => 'bthandler', provolatile => 'v', prorettype => 'index_am_handler', diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 43f1552241..945bbc3ddf 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -502,6 +502,7 @@ typedef enum NodeTag T_InlineCodeBlock, /* in nodes/parsenodes.h */ T_FdwRoutine, /* in foreign/fdwapi.h */ T_IndexAmRoutine, /* in access/amapi.h */ + T_TableAmRoutine, /* in access/tableamapi.h */ T_TsmRoutine, /* in access/tsmapi.h */ T_ForeignKeyCacheInfo, /* in utils/rel.h */ T_CallContext /* in nodes/parsenodes.h */ -- 2.16.1.windows.4