Hi! This patch introduce a dummy_index access method module, that does not do any indexing at all, but allow to test reloptions from inside of access method extension.
This patch is part of my bigger work on reloptions refactoring. It came from https://www.postgresql.org/message-id/20190220060832.GI15532%40paquier.xyz thread where I suggested to add a "enum" reloption type, and we came to conclusion that we need to test how this new option works for access method created from extension (it does not work in the same way as in-core access methods) . But we can't add this option to bloom index, so we need an index extension that can be freely used for tests. So I created src/test/modules/dummy_index, it does no real indexing, but it has all types of reloptions that can be set (reloption_int, reloption_real, reloption_bool, reloption_string and reloption_string2). It also has set of boolean GUC variables that enables test output concerning certain reloption: (do_test_reloption_int, do_test_reloption_real, do_test_reloption_bool and do_test_reloption_string and do_test_reloption_string2) also set do_test_reloptions to true to get any output at all. Dummy index will print this output when index is created, and when record is inserted (this needed to check if your ALTER TABLE did well) Then you just use normal regression tests: turns on test output, sets some reloption and check test output, that it properly reaches the access method internals. While writing this module I kept in mind the idea that this module can be also used for other am-related tests, so I separated the code into two parts: dummy_index.c has only code related to implementation of an empty access method, and all code related to reloptions tests were stored into direloptions.c. So in future somebody can add di[what_ever_he_wants].c whith his own tests code, add necessary calls to dummy_index.c, create some GUC variables, and has his own feature tested. So I kindly ask you to review and commit this module, so I would be able to continue my work on reloptions refactoring... Thanks!
diff --git a/.gitignore b/.gitignore index 794e35b..37331c2 100644 diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 19d60a5..aa34320 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -7,6 +7,7 @@ include $(top_builddir)/src/Makefile.global SUBDIRS = \ brin \ commit_ts \ + dummy_index \ dummy_seclabel \ snapshot_too_old \ test_bloomfilter \ diff --git a/src/test/modules/dummy_index/.gitignore b/src/test/modules/dummy_index/.gitignore new file mode 100644 index 0000000..5dcb3ff --- /dev/null +++ b/src/test/modules/dummy_index/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/dummy_index/Makefile b/src/test/modules/dummy_index/Makefile new file mode 100644 index 0000000..95c1fcc --- /dev/null +++ b/src/test/modules/dummy_index/Makefile @@ -0,0 +1,21 @@ +# contrib/bloom/Makefile + +MODULE_big = dummy_index +OBJS = dummy_index.o direloptions.o $(WIN32RES) + +EXTENSION = dummy_index +DATA = dummy_index--1.0.sql +PGFILEDESC = "dummy index access method - needed for all kinds of tests" + +REGRESS = reloptions + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/dummy_index +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/dummy_index/README b/src/test/modules/dummy_index/README new file mode 100644 index 0000000..b704112 --- /dev/null +++ b/src/test/modules/dummy_index/README @@ -0,0 +1,34 @@ +DUMMY INDEX + +Dummy index, an index module for testing am-related internal calls that can't be +properly tested inside production indexes, but better to be tested inside actual +access method module. + +Guidelines: +1. Keep this index as simple as as possible. It should not do any real indexing +(unless you need it for your tests), if you need it make it as simple as +possible; +2. Keep all code related to feature you test inside id[name_of_a_feature].c +file. dummy_index.c file should contain code that is needed for everyone, and +make calls to feature-related code; +3. Code related to your feature tests should be enabled and disabled by GUC +variables. Create as many boolean GUC variables as you need and set them on so +your test will know when it is time to do test output. Thus output from +different features tests are not interfered; +4. Add section to this README file that describes the general idea of what your +tests do. + +RELOPTIONS TESTS + +Here we check that values of reloptions properly reaches am-internals, and that +all reloption-related code works as expected. Several GUC variables are defined +to control test's output. do_test_reloptions turns on and off any +reloptions-related output. You will also get some test output in the case when +no relation options is set at all. do_test_reloption_int, +do_test_reloption_real, do_test_reloption_bool and do_test_reloption_string +allows to enable test output for int, real, boolean and string options. +do_test_reloption_string2 enables test output for another string option. We need +second string option, because a) string reloption implementation is a bit +tricky, and it is better to check that second value works as well; b) better to +check both cases: string option with validation function and without one, so we +need to string options. diff --git a/src/test/modules/dummy_index/direloptions.c b/src/test/modules/dummy_index/direloptions.c new file mode 100644 index 0000000..174a61d --- /dev/null +++ b/src/test/modules/dummy_index/direloptions.c @@ -0,0 +1,214 @@ +/*------------------------------------------------------------------------- + * + * direloptions.c + * Functions and variables needed for reloptions tests. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/dummy_index/direloptions.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "utils/rel.h" +#include "access/reloptions.h" +#include "utils/guc.h" + +#include "dummy_index.h" + + +/* parse table for fillRelOptions */ +relopt_parse_elt di_relopt_tab[5]; + + +/* Kind of relation options for dummy index */ +relopt_kind di_relopt_kind; + +/* GUC variables */ +static bool do_test_reloptions = false; +static bool do_test_reloption_int = false; +static bool do_test_reloption_real = false; +static bool do_test_reloption_bool = false; +static bool do_test_reloption_string = false; +static bool do_test_reloption_string2 = false; + +/* + * This function creates reloptions that would be used in reloptions tests + */ +void +create_reloptions_table() +{ + di_relopt_kind = add_reloption_kind(); + + add_int_reloption(di_relopt_kind, "int_option", + "Int option used for relotions test purposes", + 10, -10, 100); + di_relopt_tab[0].optname = "int_option"; + di_relopt_tab[0].opttype = RELOPT_TYPE_INT; + di_relopt_tab[0].offset = offsetof(DummyIndexOptions, int_option); + + add_real_reloption(di_relopt_kind, "real_option", + "Real option used for relotions test purposes", + 3.1415, -10, 100); + di_relopt_tab[1].optname = "real_option"; + di_relopt_tab[1].opttype = RELOPT_TYPE_REAL; + di_relopt_tab[1].offset = offsetof(DummyIndexOptions, real_option); + + + add_bool_reloption(di_relopt_kind, "bool_option", + "Boolean option used for relotions test purposes", + true); + di_relopt_tab[2].optname = "bool_option"; + di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL; + di_relopt_tab[2].offset = offsetof(DummyIndexOptions, bool_option); + + add_string_reloption(di_relopt_kind, "string_option", + "String option used for relotions test purposes", + "DefaultValue", &validate_string_option); + di_relopt_tab[3].optname = "string_option"; + di_relopt_tab[3].opttype = RELOPT_TYPE_STRING; + di_relopt_tab[3].offset = offsetof(DummyIndexOptions, string_option_offset); + + add_string_reloption(di_relopt_kind, "string_option2", + "Seconf string option used for relotions test purposes", + "SecondDefaultValue", &validate_string_option); + di_relopt_tab[4].optname = "string_option2"; + di_relopt_tab[4].opttype = RELOPT_TYPE_STRING; + di_relopt_tab[4].offset = offsetof(DummyIndexOptions, string_option2_offset); + +} + +/* + * This function creates GUC variables that allows to turn on and off test + * output for different relopntions + */ +void +create_reloptions_test_GUC() +{ + DefineCustomBoolVariable("dummy_index.do_test_reloptions", + "Set to true if you are going to test reloptions.", + NULL, + &do_test_reloptions, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + + DefineCustomBoolVariable("dummy_index.do_test_reloption_int", + "Set to true if you are going to test int reloption.", + NULL, + &do_test_reloption_int, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + + DefineCustomBoolVariable("dummy_index.do_test_reloption_real", + "Set to true if you are going to test real reloption.", + NULL, + &do_test_reloption_real, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + + DefineCustomBoolVariable("dummy_index.do_test_reloption_bool", + "Set to true if you are going to test boolean reloption.", + NULL, + &do_test_reloption_bool, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + + DefineCustomBoolVariable("dummy_index.do_test_reloption_string", + "Set to true if you are going to test string reloption.", + NULL, + &do_test_reloption_string, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + DefineCustomBoolVariable("dummy_index.do_test_reloption_string2", + "Set to true if you are going to test second string reloption.", + NULL, + &do_test_reloption_string2, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); +} +/* + * Function prints output for reloptions tests if GUC variables switches are + * properly set on. + */ +void +print_reloptions_test_output(Relation index) +{ + if (do_test_reloptions) + { + if(!index->rd_options) + { + elog(WARNING, "No reloptions is set, default values will be chosen in module runtime"); + } else + { + DummyIndexOptions * opt; + opt = (DummyIndexOptions *) index->rd_options; + if (do_test_reloption_int) + { + elog(WARNING, "int_option = %d", opt->int_option); + } + if (do_test_reloption_real) + { + elog(WARNING, "real_option = %f", opt->real_option); + } + if (do_test_reloption_bool) + { + elog(WARNING, "bool_option = %d", opt->bool_option); + } + if (do_test_reloption_string) + { + char * str; + str = (char *) opt + opt->string_option_offset; + elog(WARNING, "string_option = '%s'", str); + } + if (do_test_reloption_string2) + { + char * str; + str = (char *) opt + opt->string_option2_offset; + elog(WARNING, "string_option2 = '%s'", str); + } + } + } +} + +/* + * Validation function for string_option reloption + */ +void +validate_string_option(const char *value) +{ + if (do_test_reloptions && do_test_reloption_string) + { + if (value) + elog(WARNING,"Validating string option '%s'", value); + else + elog(WARNING,"Validating string option with NULL value"); + } + if (! value || *value == 'I') + elog(ERROR, "This seems to be invalid value. Please set valid value"); +} diff --git a/src/test/modules/dummy_index/dummy_index--1.0.sql b/src/test/modules/dummy_index/dummy_index--1.0.sql new file mode 100644 index 0000000..27bee5e --- /dev/null +++ b/src/test/modules/dummy_index/dummy_index--1.0.sql @@ -0,0 +1,20 @@ +/* src/test/modules/dummy_index/dummy_index--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION dummy_index" to load this file. \quit + +CREATE FUNCTION dihandler(internal) +RETURNS index_am_handler +AS 'MODULE_PATHNAME' +LANGUAGE C; + +-- Access method +CREATE ACCESS METHOD dummy_index TYPE INDEX HANDLER dihandler; +COMMENT ON ACCESS METHOD dummy_index IS 'dummy index is access method for test purposes'; + +-- Opclasses + +CREATE OPERATOR CLASS int4_ops +DEFAULT FOR TYPE int4 USING dummy_index AS + OPERATOR 1 =(int4, int4), + FUNCTION 1 hashint4(int4); diff --git a/src/test/modules/dummy_index/dummy_index.c b/src/test/modules/dummy_index/dummy_index.c new file mode 100644 index 0000000..a0ab84d --- /dev/null +++ b/src/test/modules/dummy_index/dummy_index.c @@ -0,0 +1,194 @@ +/*------------------------------------------------------------------------- + * + * dummy_index.c + * Dummy index main file. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/dummy_index/dummy_index.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/amapi.h" +#include "catalog/index.h" +#include "access/reloptions.h" +#include "utils/guc.h" +#include "dummy_index.h" + + +PG_FUNCTION_INFO_V1(dihandler); +PG_MODULE_MAGIC; + +void +_PG_init(void) + +{ + create_reloptions_table(); + create_reloptions_test_GUC(); +} +/* + * Dummy index handler function: return IndexAmRoutine with access method + * parameters and callbacks. + */ +Datum +dihandler(PG_FUNCTION_ARGS) +{ + IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); + + amroutine->amstrategies = 0; + amroutine->amsupport = 1; + amroutine->amcanorder = false; + amroutine->amcanorderbyop = false; + amroutine->amcanbackward = false; + amroutine->amcanunique = false; + amroutine->amcanmulticol = false; + amroutine->amoptionalkey = false; + amroutine->amsearcharray = false; + amroutine->amsearchnulls = false; + amroutine->amstorage = false; + amroutine->amclusterable = false; + amroutine->ampredlocks = false; + amroutine->amcanparallel = false; + amroutine->amcaninclude = false; + amroutine->amkeytype = InvalidOid; + + amroutine->ambuild = dibuild; + amroutine->ambuildempty = dibuildempty; + amroutine->aminsert = diinsert; + amroutine->ambulkdelete = dibulkdelete; + amroutine->amvacuumcleanup = divacuumcleanup; + amroutine->amcanreturn = NULL; + amroutine->amcostestimate = dicostestimate; + amroutine->amoptions = dioptions; + amroutine->amproperty = NULL; + amroutine->amvalidate = divalidate; + amroutine->ambeginscan = dibeginscan; + amroutine->amrescan = direscan; + amroutine->amgettuple = NULL; + amroutine->amgetbitmap = NULL; + amroutine->amendscan = diendscan; + amroutine->ammarkpos = NULL; + amroutine->amrestrpos = NULL; + amroutine->amestimateparallelscan = NULL; + amroutine->aminitparallelscan = NULL; + amroutine->amparallelrescan = NULL; + + PG_RETURN_POINTER(amroutine); +} + +IndexBuildResult * +dibuild(Relation heap, Relation index, IndexInfo *indexInfo) +{ + IndexBuildResult *result; + + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + + /* let's pretend that no tuples were scanned */ + result->heap_tuples = 0; + /* and no index tuples were created (that is true) */ + result->index_tuples = 0; + + print_reloptions_test_output(index); + + return result; +} + +void +dibuildempty(Relation index) +{ + /* Let's see what will happen if nothing is done here */ + /* Add tests for reloptions here */ +} + +bool +diinsert(Relation index, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + IndexInfo *indexInfo) +{ + /* This is Dummy Index we do nothing on insert :-) */ + print_reloptions_test_output(index); + return false; + +} + +IndexBulkDeleteResult * +dibulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + /* Do not delete anything; Return NULL as we have nothing to pass to + * amvacuumcleanup */ + return NULL; +} + +IndexBulkDeleteResult * +divacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +{ + /* Index have not been modified, so it is absolutely right to return NULL */ + return NULL; +} + +void +dicostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation, + double *indexPages) +{ + /* Tell planner to never use this index! */ + *indexStartupCost = 1.0e10; /* AKA disable_cost */ + *indexTotalCost = 1.0e10; /* AKA disable_cost */ + + /* Do not care about the rest */ + *indexSelectivity = 1; + *indexCorrelation = 0; + *indexPages = 1; +} + +bytea * +dioptions(Datum reloptions, bool validate) +{ + relopt_value *options; + int numoptions; + DummyIndexOptions *rdopts; + + /* Parse the user-given reloptions */ + options = parseRelOptions(reloptions, validate, di_relopt_kind, &numoptions); + rdopts = allocateReloptStruct(sizeof(DummyIndexOptions), options, numoptions); + fillRelOptions((void *) rdopts, sizeof(DummyIndexOptions), options, numoptions, + validate, di_relopt_tab, lengthof(di_relopt_tab)); + + return (bytea *) rdopts; +} + +bool +divalidate(Oid opclassoid) +{ + /* Index does not really work so we are happy with any opclass */ + return true; +} + +IndexScanDesc +dibeginscan(Relation r, int nkeys, int norderbys) +{ + IndexScanDesc scan; + + /* Let's pretend we are doing something, just in case */ + scan = RelationGetIndexScan(r, nkeys, norderbys); + return scan; +} + +void +direscan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys) +{ + /* Just do nothing */ +} + +void +diendscan(IndexScanDesc scan) +{ + /* Do nothing */ +} diff --git a/src/test/modules/dummy_index/dummy_index.control b/src/test/modules/dummy_index/dummy_index.control new file mode 100644 index 0000000..9eac994 --- /dev/null +++ b/src/test/modules/dummy_index/dummy_index.control @@ -0,0 +1,5 @@ +# dummy_index extension +comment = 'dummmy_index access method that does nothin and is used for test purposes' +default_version = '1.0' +module_pathname = '$libdir/dummy_index' +relocatable = true diff --git a/src/test/modules/dummy_index/dummy_index.h b/src/test/modules/dummy_index/dummy_index.h new file mode 100644 index 0000000..ddab4e3 --- /dev/null +++ b/src/test/modules/dummy_index/dummy_index.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------- + * + * dummy_index.h + * Header for dummy_index index. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/dummy_index/dummy_index.h + * + *------------------------------------------------------------------------- + */ +#ifndef _DUMMY_INDEX_H_ +#define _DUMMY_INDEX_H_ + +#include "nodes/relation.h" + +/* Dummy index options */ +typedef struct DummyIndexOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int int_option; /* for reloptions test purposes */ + double real_option; /* for reloptions test purposes */ + bool bool_option; /* for reloptions test purposes */ + int string_option_offset; /* for reloptions test purposes */ + int string_option2_offset; /* for reloptions test purposes */ +} DummyIndexOptions; + +extern void _PG_init(void); + +/* index access method interface functions */ +extern bool divalidate(Oid opclassoid); +extern bool diinsert(Relation index, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); +extern IndexScanDesc dibeginscan(Relation r, int nkeys, int norderbys); +extern void direscan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern void diendscan(IndexScanDesc scan); +extern IndexBuildResult *dibuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void dibuildempty(Relation index); +extern IndexBulkDeleteResult *dibulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *divacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); +extern bytea *dioptions(Datum reloptions, bool validate); +extern void dicostestimate(PlannerInfo *root, IndexPath *path, + double loop_count, Cost *indexStartupCost, + Cost *indexTotalCost, Selectivity *indexSelectivity, + double *indexCorrelation, double *indexPages); + +/* direoptions.c */ +/* Functions and variables needed for reloptions tests*/ + +extern relopt_parse_elt di_relopt_tab[5]; +extern relopt_kind di_relopt_kind; + +extern void create_reloptions_table(void); +extern void create_reloptions_test_GUC(void); +extern void print_reloptions_test_output(Relation index); +extern void validate_string_option(const char *value); + +#endif diff --git a/src/test/modules/dummy_index/expected/reloptions.out b/src/test/modules/dummy_index/expected/reloptions.out new file mode 100644 index 0000000..33bccba --- /dev/null +++ b/src/test/modules/dummy_index/expected/reloptions.out @@ -0,0 +1,97 @@ +CREATE EXTENSION dummy_index; +SET dummy_index.do_test_reloptions to true; +CREATE TABLE tst (i int4); +-- Test reloptions behavior when no reloption is set +CREATE INDEX test_idx ON tst USING dummy_index (i); +WARNING: No reloptions is set, default values will be chosen in module runtime +DROP INDEX test_idx; +-- Test behavior of int option (default and non default values) +SET dummy_index.do_test_reloption_int to true; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); +WARNING: int_option = 10 +DROP INDEX test_idx; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); +WARNING: int_option = 5 +ALTER INDEX test_idx SET (int_option = 3); +INSERT INTO tst VALUES(1); +WARNING: int_option = 3 +ALTER INDEX test_idx SET (bool_option = false); +ALTER INDEX test_idx RESET (int_option); +INSERT INTO tst VALUES(1); +WARNING: int_option = 10 +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_int to false; +-- Test behavior of real option (default and non default values) +SET dummy_index.do_test_reloption_real to true; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); +WARNING: real_option = 3.141500 +DROP INDEX test_idx; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (real_option = 5); +WARNING: real_option = 5.000000 +ALTER INDEX test_idx SET (real_option = 3); +INSERT INTO tst VALUES(1); +WARNING: real_option = 3.000000 +ALTER INDEX test_idx SET (bool_option = false); +ALTER INDEX test_idx RESET (real_option); +INSERT INTO tst VALUES(1); +WARNING: real_option = 3.141500 +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_real to false; +-- Test behavior of bool option (default and non default values) +SET dummy_index.do_test_reloption_bool to true; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); +WARNING: bool_option = 1 +DROP INDEX test_idx; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); +WARNING: bool_option = 0 +ALTER INDEX test_idx SET (bool_option = true); +INSERT INTO tst VALUES(1); +WARNING: bool_option = 1 +ALTER INDEX test_idx SET (int_option = 5, bool_option = false); +ALTER INDEX test_idx RESET (bool_option); +INSERT INTO tst VALUES(1); +WARNING: bool_option = 1 +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_bool to false; +-- Test behavior of string option (default and non default values + valudate +-- function) +SET dummy_index.do_test_reloption_string to true; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); +WARNING: string_option = 'DefaultValue' +DROP INDEX test_idx; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Invalid_value"); +WARNING: Validating string option 'Invalid_value' +ERROR: This seems to be invalid value. Please set valid value +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Valid_value"); +WARNING: Validating string option 'Valid_value' +WARNING: string_option = 'Valid_value' +ALTER INDEX test_idx SET (string_option = "Valid_value_2", int_option = 5); +WARNING: Validating string option 'Valid_value_2' +INSERT INTO tst VALUES(1); +WARNING: string_option = 'Valid_value_2' +ALTER INDEX test_idx RESET (string_option); +INSERT INTO tst VALUES(1); +WARNING: string_option = 'DefaultValue' +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_string to false; +-- Test behavior of second string option (there can be issues with second one) +-- Testing default and non default values + _no_ valudate function) +SET dummy_index.do_test_reloption_string2 to true; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Something"); +WARNING: string_option2 = 'SecondDefaultValue' +DROP INDEX test_idx; +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option2 = +"Some_value"); +WARNING: string_option2 = 'Some_value' +ALTER INDEX test_idx SET (string_option2 = "Valid_value_2", int_option = 5); +INSERT INTO tst VALUES(1); +WARNING: string_option2 = 'Valid_value_2' +ALTER INDEX test_idx RESET (string_option2); +INSERT INTO tst VALUES(1); +WARNING: string_option2 = 'SecondDefaultValue' +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_string2 to false; +SET dummy_index.do_test_reloptions to false; diff --git a/src/test/modules/dummy_index/sql/reloptions.sql b/src/test/modules/dummy_index/sql/reloptions.sql new file mode 100644 index 0000000..3b33ee7 --- /dev/null +++ b/src/test/modules/dummy_index/sql/reloptions.sql @@ -0,0 +1,101 @@ +CREATE EXTENSION dummy_index; + +SET dummy_index.do_test_reloptions to true; + +CREATE TABLE tst (i int4); + +-- Test reloptions behavior when no reloption is set +CREATE INDEX test_idx ON tst USING dummy_index (i); +DROP INDEX test_idx; + +-- Test behavior of int option (default and non default values) +SET dummy_index.do_test_reloption_int to true; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); +DROP INDEX test_idx; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); + +ALTER INDEX test_idx SET (int_option = 3); +INSERT INTO tst VALUES(1); +ALTER INDEX test_idx SET (bool_option = false); +ALTER INDEX test_idx RESET (int_option); +INSERT INTO tst VALUES(1); + +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_int to false; + +-- Test behavior of real option (default and non default values) +SET dummy_index.do_test_reloption_real to true; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); +DROP INDEX test_idx; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (real_option = 5); + +ALTER INDEX test_idx SET (real_option = 3); +INSERT INTO tst VALUES(1); +ALTER INDEX test_idx SET (bool_option = false); +ALTER INDEX test_idx RESET (real_option); +INSERT INTO tst VALUES(1); + +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_real to false; + +-- Test behavior of bool option (default and non default values) +SET dummy_index.do_test_reloption_bool to true; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); +DROP INDEX test_idx; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (bool_option = false); + +ALTER INDEX test_idx SET (bool_option = true); +INSERT INTO tst VALUES(1); +ALTER INDEX test_idx SET (int_option = 5, bool_option = false); +ALTER INDEX test_idx RESET (bool_option); +INSERT INTO tst VALUES(1); + +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_bool to false; + +-- Test behavior of string option (default and non default values + valudate +-- function) +SET dummy_index.do_test_reloption_string to true; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (int_option = 5); +DROP INDEX test_idx; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Invalid_value"); + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Valid_value"); + +ALTER INDEX test_idx SET (string_option = "Valid_value_2", int_option = 5); +INSERT INTO tst VALUES(1); +ALTER INDEX test_idx RESET (string_option); +INSERT INTO tst VALUES(1); + +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_string to false; + +-- Test behavior of second string option (there can be issues with second one) +-- Testing default and non default values + _no_ valudate function) +SET dummy_index.do_test_reloption_string2 to true; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option = +"Something"); +DROP INDEX test_idx; + +CREATE INDEX test_idx ON tst USING dummy_index (i) WITH (string_option2 = +"Some_value"); + +ALTER INDEX test_idx SET (string_option2 = "Valid_value_2", int_option = 5); +INSERT INTO tst VALUES(1); +ALTER INDEX test_idx RESET (string_option2); +INSERT INTO tst VALUES(1); + +DROP INDEX test_idx; +SET dummy_index.do_test_reloption_string2 to false; +SET dummy_index.do_test_reloptions to false;