From 81c7a600ed62818e7c81e000d0876e959c6001d6 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 1 Dec 2023 12:56:52 +0900 Subject: [PATCH v1 9/9] dummy_sequence_am: Example of sequence AM --- src/test/modules/Makefile | 1 + src/test/modules/dummy_sequence_am/.gitignore | 3 + src/test/modules/dummy_sequence_am/Makefile | 19 +++ .../dummy_sequence_am--1.0.sql | 13 +++ .../dummy_sequence_am/dummy_sequence_am.c | 110 ++++++++++++++++++ .../dummy_sequence_am.control | 5 + .../expected/dummy_sequence.out | 35 ++++++ .../modules/dummy_sequence_am/meson.build | 33 ++++++ .../dummy_sequence_am/sql/dummy_sequence.sql | 17 +++ src/test/modules/meson.build | 1 + 10 files changed, 237 insertions(+) create mode 100644 src/test/modules/dummy_sequence_am/.gitignore create mode 100644 src/test/modules/dummy_sequence_am/Makefile create mode 100644 src/test/modules/dummy_sequence_am/dummy_sequence_am--1.0.sql create mode 100644 src/test/modules/dummy_sequence_am/dummy_sequence_am.c create mode 100644 src/test/modules/dummy_sequence_am/dummy_sequence_am.control create mode 100644 src/test/modules/dummy_sequence_am/expected/dummy_sequence.out create mode 100644 src/test/modules/dummy_sequence_am/meson.build create mode 100644 src/test/modules/dummy_sequence_am/sql/dummy_sequence.sql diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 5d33fa6a9a..81f857599e 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -10,6 +10,7 @@ SUBDIRS = \ delay_execution \ dummy_index_am \ dummy_seclabel \ + dummy_sequence_am \ libpq_pipeline \ plsample \ spgist_name_ops \ diff --git a/src/test/modules/dummy_sequence_am/.gitignore b/src/test/modules/dummy_sequence_am/.gitignore new file mode 100644 index 0000000000..44d119cfcc --- /dev/null +++ b/src/test/modules/dummy_sequence_am/.gitignore @@ -0,0 +1,3 @@ +# Generated subdirectories +/log/ +/results/ diff --git a/src/test/modules/dummy_sequence_am/Makefile b/src/test/modules/dummy_sequence_am/Makefile new file mode 100644 index 0000000000..391f7ac946 --- /dev/null +++ b/src/test/modules/dummy_sequence_am/Makefile @@ -0,0 +1,19 @@ +# src/test/modules/dummy_sequence_am/Makefile + +MODULES = dummy_sequence_am + +EXTENSION = dummy_sequence_am +DATA = dummy_sequence_am--1.0.sql + +REGRESS = dummy_sequence + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/dummy_sequence_am +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/dummy_sequence_am/dummy_sequence_am--1.0.sql b/src/test/modules/dummy_sequence_am/dummy_sequence_am--1.0.sql new file mode 100644 index 0000000000..e12b1f9d87 --- /dev/null +++ b/src/test/modules/dummy_sequence_am/dummy_sequence_am--1.0.sql @@ -0,0 +1,13 @@ +/* src/test/modules/dummy_sequence_am/dummy_sequence_am--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION dummy_sequence_am" to load this file. \quit + +CREATE FUNCTION dummy_sequenceam_handler(internal) + RETURNS sequence_am_handler + AS 'MODULE_PATHNAME' + LANGUAGE C; + +CREATE ACCESS METHOD dummy_sequence_am + TYPE SEQUENCE HANDLER dummy_sequenceam_handler; +COMMENT ON ACCESS METHOD dummy_sequence_am IS 'dummy sequence access method'; diff --git a/src/test/modules/dummy_sequence_am/dummy_sequence_am.c b/src/test/modules/dummy_sequence_am/dummy_sequence_am.c new file mode 100644 index 0000000000..b5ee5d89da --- /dev/null +++ b/src/test/modules/dummy_sequence_am/dummy_sequence_am.c @@ -0,0 +1,110 @@ +/*------------------------------------------------------------------------- + * + * dummy_sequence_am.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/test/modules/dummy_sequence_am/dummy_sequence_am.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/sequenceam.h" +#include "fmgr.h" + +PG_MODULE_MAGIC; + +/* this sequence is fully on-memory */ +static int dummy_seqam_last_value = 1; +static bool dummy_seqam_is_called = false; + +PG_FUNCTION_INFO_V1(dummy_sequenceam_handler); + + +/* ------------------------------------------------------------------------ + * Callbacks for the dummy sequence access method. + * ------------------------------------------------------------------------ + */ + +/* + * Return the table access method used by this sequence. + * + * This is just an on-memory sequence, so anything is fine. + */ +static const char * +dummy_sequenceam_get_table_am(void) +{ + return "heap"; +} + +static void +dummy_sequenceam_init(Relation rel, int64 last_value, bool is_called) +{ + dummy_seqam_last_value = last_value; + dummy_seqam_is_called = is_called; +} + +static int64 +dummy_sequenceam_nextval(Relation rel, int64 incby, int64 maxv, + int64 minv, int64 cache, bool cycle, + int64 *last) +{ + dummy_seqam_last_value += incby; + dummy_seqam_is_called = true; + + return dummy_seqam_last_value; +} + +static void +dummy_sequenceam_setval(Relation rel, int64 next, bool iscalled) +{ + dummy_seqam_last_value = next; + dummy_seqam_is_called = iscalled; +} + +static void +dummy_sequenceam_get_state(Relation rel, int64 *last_value, bool *is_called) +{ + *last_value = dummy_seqam_last_value; + *is_called = dummy_seqam_is_called; +} + +static void +dummy_sequenceam_reset(Relation rel, int64 startv, bool is_called, + bool reset_state) +{ + dummy_seqam_last_value = startv; + dummy_seqam_is_called = is_called; +} + +static void +dummy_sequenceam_change_persistence(Relation rel, char newrelpersistence) +{ + /* nothing to do, really */ +} + +/* ------------------------------------------------------------------------ + * Definition of the dummy sequence access method. + * ------------------------------------------------------------------------ + */ + +static const SequenceAmRoutine dummy_sequenceam_methods = { + .type = T_SequenceAmRoutine, + .get_table_am = dummy_sequenceam_get_table_am, + .init = dummy_sequenceam_init, + .nextval = dummy_sequenceam_nextval, + .setval = dummy_sequenceam_setval, + .get_state = dummy_sequenceam_get_state, + .reset = dummy_sequenceam_reset, + .change_persistence = dummy_sequenceam_change_persistence +}; + +Datum +dummy_sequenceam_handler(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(&dummy_sequenceam_methods); +} diff --git a/src/test/modules/dummy_sequence_am/dummy_sequence_am.control b/src/test/modules/dummy_sequence_am/dummy_sequence_am.control new file mode 100644 index 0000000000..9f10622f2f --- /dev/null +++ b/src/test/modules/dummy_sequence_am/dummy_sequence_am.control @@ -0,0 +1,5 @@ +# dummy_sequence_am extension +comment = 'dummy_sequence_am - sequence access method template' +default_version = '1.0' +module_pathname = '$libdir/dummy_sequence_am' +relocatable = true diff --git a/src/test/modules/dummy_sequence_am/expected/dummy_sequence.out b/src/test/modules/dummy_sequence_am/expected/dummy_sequence.out new file mode 100644 index 0000000000..57588cea5b --- /dev/null +++ b/src/test/modules/dummy_sequence_am/expected/dummy_sequence.out @@ -0,0 +1,35 @@ +CREATE EXTENSION dummy_sequence_am; +CREATE SEQUENCE dummyseq USING dummy_sequence_am; +SELECT nextval('dummyseq'::regclass); + nextval +--------- + 2 +(1 row) + +SELECT setval('dummyseq'::regclass, 14); + setval +-------- + 14 +(1 row) + +SELECT nextval('dummyseq'::regclass); + nextval +--------- + 15 +(1 row) + +-- Sequence relation exists, but it has no attributes. +SELECT * FROM dummyseq; +-- +(0 rows) + +-- Reset connection, which will reset the sequence +\c +SELECT nextval('dummyseq'::regclass); + nextval +--------- + 2 +(1 row) + +DROP SEQUENCE dummyseq; +DROP EXTENSION dummy_sequence_am; diff --git a/src/test/modules/dummy_sequence_am/meson.build b/src/test/modules/dummy_sequence_am/meson.build new file mode 100644 index 0000000000..84460070e4 --- /dev/null +++ b/src/test/modules/dummy_sequence_am/meson.build @@ -0,0 +1,33 @@ +# Copyright (c) 2022-2023, PostgreSQL Global Development Group + +dummy_sequence_am_sources = files( + 'dummy_sequence_am.c', +) + +if host_system == 'windows' + dummy_sequence_am_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ + '--NAME', 'dummy_sequence_am', + '--FILEDESC', 'dummy_sequence_am - sequence access method template',]) +endif + +dummy_sequence_am = shared_module('dummy_sequence_am', + dummy_sequence_am_sources, + kwargs: pg_test_mod_args, +) +test_install_libs += dummy_sequence_am + +test_install_data += files( + 'dummy_sequence_am.control', + 'dummy_sequence_am--1.0.sql', +) + +tests += { + 'name': 'dummy_sequence_am', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'regress': { + 'sql': [ + 'dummy_sequence', + ], + }, +} diff --git a/src/test/modules/dummy_sequence_am/sql/dummy_sequence.sql b/src/test/modules/dummy_sequence_am/sql/dummy_sequence.sql new file mode 100644 index 0000000000..c739b29a46 --- /dev/null +++ b/src/test/modules/dummy_sequence_am/sql/dummy_sequence.sql @@ -0,0 +1,17 @@ +CREATE EXTENSION dummy_sequence_am; + +CREATE SEQUENCE dummyseq USING dummy_sequence_am; + +SELECT nextval('dummyseq'::regclass); +SELECT setval('dummyseq'::regclass, 14); +SELECT nextval('dummyseq'::regclass); + +-- Sequence relation exists, but it has no attributes. +SELECT * FROM dummyseq; + +-- Reset connection, which will reset the sequence +\c +SELECT nextval('dummyseq'::regclass); + +DROP SEQUENCE dummyseq; +DROP EXTENSION dummy_sequence_am; diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build index b76f588559..9a4c4ac506 100644 --- a/src/test/modules/meson.build +++ b/src/test/modules/meson.build @@ -5,6 +5,7 @@ subdir('commit_ts') subdir('delay_execution') subdir('dummy_index_am') subdir('dummy_seclabel') +subdir('dummy_sequence_am') subdir('ldap_password_func') subdir('libpq_pipeline') subdir('plsample') -- 2.43.0