From 7c4bcfa472fd96c5c8a39309fc1394e94831e395 Mon Sep 17 00:00:00 2001 From: Hari Babu Date: Tue, 29 Aug 2017 19:45:30 +1000 Subject: [PATCH 1/8] Change Create Access method to include storage handler Add the support of storage handler as an access method --- src/backend/commands/amcmds.c | 17 ++++++++++++++--- src/backend/parser/gram.y | 11 +++++++++-- src/backend/utils/adt/pseudotypes.c | 1 + src/include/catalog/pg_am.h | 4 ++++ src/include/catalog/pg_proc.h | 4 ++++ src/include/catalog/pg_type.h | 2 ++ src/test/regress/expected/opr_sanity.out | 19 ++++++++++++++++--- src/test/regress/sql/opr_sanity.sql | 16 +++++++++++++--- 8 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c index 7e0a9aa..33079c1 100644 --- a/src/backend/commands/amcmds.c +++ b/src/backend/commands/amcmds.c @@ -29,7 +29,7 @@ #include "utils/syscache.h" -static Oid lookup_index_am_handler_func(List *handler_name, char amtype); +static Oid lookup_am_handler_func(List *handler_name, char amtype); static const char *get_am_type_string(char amtype); @@ -72,7 +72,7 @@ CreateAccessMethod(CreateAmStmt *stmt) /* * Get the handler function oid, verifying the AM type while at it. */ - amhandler = lookup_index_am_handler_func(stmt->handler_name, stmt->amtype); + amhandler = lookup_am_handler_func(stmt->handler_name, stmt->amtype); /* * Insert tuple into pg_am. @@ -225,6 +225,8 @@ get_am_type_string(char amtype) { case AMTYPE_INDEX: return "INDEX"; + case AMTYPE_STORAGE: + return "STORAGE"; default: /* shouldn't happen */ elog(ERROR, "invalid access method type '%c'", amtype); @@ -239,7 +241,7 @@ get_am_type_string(char amtype) * This function either return valid function Oid or throw an error. */ static Oid -lookup_index_am_handler_func(List *handler_name, char amtype) +lookup_am_handler_func(List *handler_name, char amtype) { Oid handlerOid; static const Oid funcargtypes[1] = {INTERNALOID}; @@ -263,6 +265,15 @@ lookup_index_am_handler_func(List *handler_name, char amtype) NameListToString(handler_name), "index_am_handler"))); break; + /* XXX refactor duplicate error */ + case AMTYPE_STORAGE: + if (get_func_rettype(handlerOid) != STORAGE_AM_HANDLEROID) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("function %s must return type %s", + NameListToString(handler_name), + "storage_am_handler"))); + break; default: elog(ERROR, "unrecognized access method type \"%c\"", amtype); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index c303818..d4ac340 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -321,6 +321,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type OptSchemaName %type OptSchemaEltList +%type am_type + %type TriggerForSpec TriggerForType %type TriggerActionTime %type TriggerEvents TriggerOneEvent @@ -5172,16 +5174,21 @@ row_security_cmd: * *****************************************************************************/ -CreateAmStmt: CREATE ACCESS METHOD name TYPE_P INDEX HANDLER handler_name +CreateAmStmt: CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name { CreateAmStmt *n = makeNode(CreateAmStmt); n->amname = $4; n->handler_name = $8; - n->amtype = AMTYPE_INDEX; + n->amtype = $6; $$ = (Node *) n; } ; +am_type: + INDEX { $$ = AMTYPE_INDEX; } + | STORAGE { $$ = AMTYPE_STORAGE; } + ; + /***************************************************************************** * * QUERIES : diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index be79353..0a7e0a3 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -418,3 +418,4 @@ PSEUDOTYPE_DUMMY_IO_FUNCS(internal); PSEUDOTYPE_DUMMY_IO_FUNCS(opaque); PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement); PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray); +PSEUDOTYPE_DUMMY_IO_FUNCS(storage_am_handler); diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index e021f5b..2c3e33c 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -59,6 +59,7 @@ typedef FormData_pg_am *Form_pg_am; * ---------------- */ #define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_STORAGE 's' /* storage access method */ /* ---------------- * initial contents of pg_am @@ -83,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 f73c6c6..6b675b0 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3879,6 +3879,10 @@ DATA(insert OID = 326 ( index_am_handler_in PGNSP PGUID 12 1 0 0 0 f f f f f f DESCR("I/O"); DATA(insert OID = 327 ( index_am_handler_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "325" _null_ _null_ _null_ _null_ _null_ index_am_handler_out _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3425 ( storage_am_handler_in PGNSP PGUID 12 1 0 0 0 f f f f f f i s 1 0 3998 "2275" _null_ _null_ _null_ _null_ _null_ storage_am_handler_in _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3426 ( storage_am_handler_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "3998" _null_ _null_ _null_ _null_ _null_ storage_am_handler_out _null_ _null_ _null_ )); +DESCR("I/O"); DATA(insert OID = 3311 ( tsm_handler_in PGNSP PGUID 12 1 0 0 0 f f f f f f i s 1 0 3310 "2275" _null_ _null_ _null_ _null_ _null_ tsm_handler_in _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 3312 ( tsm_handler_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "3310" _null_ _null_ _null_ _null_ _null_ tsm_handler_out _null_ _null_ _null_ )); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index ffdb452..ea352fa 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -708,6 +708,8 @@ DATA(insert OID = 3115 ( fdw_handler PGNSP PGUID 4 t p P f t \054 0 0 0 fdw_han #define FDW_HANDLEROID 3115 DATA(insert OID = 325 ( index_am_handler PGNSP PGUID 4 t p P f t \054 0 0 0 index_am_handler_in index_am_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define INDEX_AM_HANDLEROID 325 +DATA(insert OID = 3998 ( storage_am_handler PGNSP PGUID 4 t p P f t \054 0 0 0 storage_am_handler_in storage_am_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); +#define STORAGE_AM_HANDLEROID 3998 DATA(insert OID = 3310 ( tsm_handler PGNSP PGUID 4 t p P f t \054 0 0 0 tsm_handler_in tsm_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define TSM_HANDLEROID 3310 DATA(insert OID = 3831 ( anyrange PGNSP PGUID -1 f p P f t \054 0 0 0 anyrange_in anyrange_out - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index fcf8bd7..3bc9607 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -1711,11 +1711,24 @@ WHERE p1.amhandler = 0; -----+-------- (0 rows) --- Check for amhandler functions with the wrong signature +-- Check for index amhandler functions with the wrong signature SELECT p1.oid, p1.amname, p2.oid, p2.proname FROM pg_am AS p1, pg_proc AS p2 -WHERE p2.oid = p1.amhandler AND - (p2.prorettype != 'index_am_handler'::regtype OR p2.proretset +WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND + (p2.prorettype != 'index_am_handler'::regtype + OR p2.proretset + OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype); + oid | amname | oid | proname +-----+--------+-----+--------- +(0 rows) + +-- Check for storage amhandler functions with the wrong signature +SELECT p1.oid, p1.amname, p2.oid, p2.proname +FROM pg_am AS p1, pg_proc AS p2 +WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND + (p2.prorettype != 'storage_am_handler'::regtype + OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); oid | amname | oid | proname diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index 2945966..f1f58a3 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -1153,15 +1153,25 @@ SELECT p1.oid, p1.amname FROM pg_am AS p1 WHERE p1.amhandler = 0; --- Check for amhandler functions with the wrong signature +-- Check for index amhandler functions with the wrong signature SELECT p1.oid, p1.amname, p2.oid, p2.proname FROM pg_am AS p1, pg_proc AS p2 -WHERE p2.oid = p1.amhandler AND - (p2.prorettype != 'index_am_handler'::regtype OR p2.proretset +WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND + (p2.prorettype != 'index_am_handler'::regtype + OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); +-- Check for storage amhandler functions with the wrong signature + +SELECT p1.oid, p1.amname, p2.oid, p2.proname +FROM pg_am AS p1, pg_proc AS p2 +WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND + (p2.prorettype != 'storage_am_handler'::regtype + OR p2.proretset + OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype); -- **************** pg_amop **************** -- 2.7.4.windows.1