=== Applying patches on top of PostgreSQL commit ID 53a49365052026907afff7613929710d1e7f0da0 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Fri Jan 31 20:51:24 UTC 2025 On branch cf/4688 nothing to commit, working tree clean === applying patch ./v9-0001-New-options-engine.patch Applied patch to 'contrib/bloom/bloom.h' cleanly. Applied patch to 'contrib/bloom/blutils.c' with conflicts. Applied patch to 'contrib/dblink/dblink.c' cleanly. Applied patch to 'contrib/file_fdw/file_fdw.c' cleanly. Applied patch to 'contrib/postgres_fdw/option.c' cleanly. Applied patch to 'contrib/test_decoding/expected/twophase.out' cleanly. Applied patch to 'doc/src/sgml/indexam.sgml' with conflicts. Applied patch to 'src/backend/access/brin/brin.c' with conflicts. Applied patch to 'src/backend/access/common/Makefile' cleanly. Applied patch to 'src/backend/access/common/meson.build' cleanly. Falling back to direct application... Applied patch to 'src/backend/access/common/reloptions.c' with conflicts. Applied patch to 'src/backend/access/gin/ginutil.c' with conflicts. Applied patch to 'src/backend/access/gist/gist.c' with conflicts. Applied patch to 'src/backend/access/gist/gistutil.c' with conflicts. Applied patch to 'src/backend/access/hash/hash.c' with conflicts. Applied patch to 'src/backend/access/hash/hashutil.c' cleanly. Applied patch to 'src/backend/access/nbtree/nbtree.c' with conflicts. Applied patch to 'src/backend/access/nbtree/nbtutils.c' with conflicts. Applied patch to 'src/backend/access/spgist/spgutils.c' with conflicts. Applied patch to 'src/backend/commands/createas.c' cleanly. Applied patch to 'src/backend/commands/foreigncmds.c' cleanly. Applied patch to 'src/backend/commands/indexcmds.c' with conflicts. Applied patch to 'src/backend/commands/tablecmds.c' with conflicts. Applied patch to 'src/backend/commands/tablespace.c' cleanly. Applied patch to 'src/backend/foreign/foreign.c' cleanly. Applied patch to 'src/backend/parser/parse_utilcmd.c' cleanly. Applied patch to 'src/backend/tcop/utility.c' with conflicts. Applied patch to 'src/backend/utils/cache/attoptcache.c' cleanly. Applied patch to 'src/backend/utils/cache/relcache.c' cleanly. Applied patch to 'src/backend/utils/cache/spccache.c' cleanly. Applied patch to 'src/bin/pg_basebackup/streamutil.c' cleanly. Applied patch to 'src/include/access/amapi.h' with conflicts. Applied patch to 'src/include/access/brin.h' cleanly. Applied patch to 'src/include/access/brin_internal.h' cleanly. Applied patch to 'src/include/access/gin_private.h' cleanly. Applied patch to 'src/include/access/gist_private.h' cleanly. Applied patch to 'src/include/access/hash.h' cleanly. Applied patch to 'src/include/access/nbtree.h' cleanly. Falling back to direct application... Applied patch to 'src/include/access/reloptions.h' with conflicts. Applied patch to 'src/include/access/spgist.h' cleanly. Applied patch to 'src/include/access/spgist_private.h' cleanly. Applied patch to 'src/include/commands/tablecmds.h' cleanly. Applied patch to 'src/test/modules/dummy_index_am/dummy_index_am.c' with conflicts. Applied patch to 'src/test/modules/test_oat_hooks/expected/alter_table.out' cleanly. Applied patch to 'src/test/regress/expected/reloptions.out' cleanly. Applied patch to 'src/test/regress/sql/reloptions.sql' cleanly. U contrib/bloom/blutils.c U doc/src/sgml/indexam.sgml U src/backend/access/brin/brin.c U src/backend/access/common/reloptions.c U src/backend/access/gin/ginutil.c U src/backend/access/gist/gist.c U src/backend/access/gist/gistutil.c U src/backend/access/hash/hash.c U src/backend/access/nbtree/nbtree.c U src/backend/access/nbtree/nbtutils.c U src/backend/access/spgist/spgutils.c U src/backend/commands/indexcmds.c U src/backend/commands/tablecmds.c U src/backend/tcop/utility.c U src/include/access/amapi.h U src/include/access/reloptions.h U src/test/modules/dummy_index_am/dummy_index_am.c diff --cc contrib/bloom/blutils.c index 3796bea786,670c8b67d8..0000000000 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@@ -15,13 -15,16 +15,13 @@@ #include "access/amapi.h" #include "access/generic_xlog.h" - #include "access/reloptions.h" + #include "access/options.h" #include "bloom.h" -#include "catalog/index.h" #include "commands/vacuum.h" -#include "miscadmin.h" #include "storage/bufmgr.h" -#include "storage/freespace.h" #include "storage/indexfsm.h" -#include "storage/lmgr.h" #include "utils/memutils.h" +#include "varatt.h" /* Signature dealing macros - note i is assumed to be of type int */ #define GETWORD(x,i) ( *( (BloomSignatureWord *)(x) + ( (i) / SIGNWORDBITS ) ) ) @@@ -134,8 -97,7 +94,12 @@@ blhandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = blvacuumcleanup; amroutine->amcanreturn = NULL; amroutine->amcostestimate = blcostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = bloptions; ++======= + amroutine->amreloptspecset = blrelopt_specset; ++>>>>>>> theirs amroutine->amproperty = NULL; amroutine->ambuildphasename = NULL; amroutine->amvalidate = blvalidate; diff --cc doc/src/sgml/indexam.sgml index dc7d14b60d,31b7d940e7..0000000000 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@@ -481,42 -480,12 +481,33 @@@ amcostestimate (PlannerInfo *root ++<<<<<<< ours +int +amgettreeheight (Relation rel); + + Compute the height of a tree-shaped index. This information is supplied to + the amcostestimate function in + path->indexinfo->tree_height and can be used to support + the cost estimation. The result is not used anywhere else, so this + function can actually be used to compute any kind of data (that fits into + an integer) about the index that the cost estimation function might want to + know. If the computation is expensive, it could be useful to cache the + result as part of RelationData.rd_amcache. + + + + +bytea * +amoptions (ArrayType *reloptions, + bool validate); ++======= + void * + amreloptspecset(void); ++>>>>>>> theirs - Parse and validate the reloptions array for an index. This is called only - when a non-null reloptions array exists for the index. - reloptions is a text array containing entries of the - form name=value. - The function should construct a bytea value, which will be copied - into the rd_options field of the index's relcache entry. - The data contents of the bytea value are open for the access - method to define; most of the standard access methods use struct - StdRdOptions. - When validate is true, the function should report a suitable - error message if any of the options are unrecognized or have invalid - values; when validate is false, invalid entries should be - silently ignored. (validate is false when loading options - already stored in pg_catalog; an invalid entry could only - be found if the access method has changed its rules for options, and in - that case ignoring obsolete entries is appropriate.) - It is OK to return NULL if default behavior is wanted. + Returns pointer to Options Spec Set that defines options available for an + index relation. This Spec Set will be used for parsing and validating index + relation options. diff --cc src/backend/access/brin/brin.c index 4289142e20,5eb7e04458..0000000000 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@@ -282,8 -278,6 +281,11 @@@ brinhandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = brinvacuumcleanup; amroutine->amcanreturn = NULL; amroutine->amcostestimate = brincostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = brinoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = NULL; amroutine->ambuildphasename = NULL; amroutine->amvalidate = brinvalidate; diff --cc src/backend/access/common/reloptions.c index e587abd999,7ec05df7b9..0000000000 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@@ -1,9 -1,9 +1,9 @@@ /*------------------------------------------------------------------------- * * reloptions.c - * Core support for relation options (pg_class.reloptions) + * Support for relation options (pg_class.reloptions) * - * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@@ -1120,247 -213,8 +213,252 @@@ add_local_string_reloption(local_relopt validate_string_relopt validator, fill_string_relopt filler, int offset) { ++<<<<<<< ours + relopt_string *newoption = init_string_reloption(RELOPT_KIND_LOCAL, + name, desc, + default_val, + validator, filler, + 0); + + add_local_reloption(relopts, (relopt_gen *) newoption, offset); +} + +/* + * Transform a relation options list (list of DefElem) into the text array + * format that is kept in pg_class.reloptions, including only those options + * that are in the passed namespace. The output values do not include the + * namespace. + * + * This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and + * ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing + * reloptions value (possibly NULL), and we replace or remove entries + * as needed. + * + * If acceptOidsOff is true, then we allow oids = false, but throw error when + * on. This is solely needed for backwards compatibility. + * + * Note that this is not responsible for determining whether the options + * are valid, but it does check that namespaces for all the options given are + * listed in validnsps. The NULL namespace is always valid and need not be + * explicitly listed. Passing a NULL pointer means that only the NULL + * namespace is valid. + * + * Both oldOptions and the result are text arrays (or NULL for "default"), + * but we declare them as Datums to avoid including array.h in reloptions.h. + */ +Datum +transformRelOptions(Datum oldOptions, List *defList, const char *namspace, + const char *const validnsps[], bool acceptOidsOff, bool isReset) +{ + Datum result; + ArrayBuildState *astate; + ListCell *cell; + + /* no change if empty list */ + if (defList == NIL) + return oldOptions; + + /* We build new array using accumArrayResult */ + astate = NULL; + + /* Copy any oldOptions that aren't to be replaced */ + if (PointerIsValid(DatumGetPointer(oldOptions))) + { + ArrayType *array = DatumGetArrayTypeP(oldOptions); + Datum *oldoptions; + int noldoptions; + int i; + + deconstruct_array_builtin(array, TEXTOID, &oldoptions, NULL, &noldoptions); + + for (i = 0; i < noldoptions; i++) + { + char *text_str = VARDATA(oldoptions[i]); + int text_len = VARSIZE(oldoptions[i]) - VARHDRSZ; + + /* Search for a match in defList */ + foreach(cell, defList) + { + DefElem *def = (DefElem *) lfirst(cell); + int kw_len; + + /* ignore if not in the same namespace */ + if (namspace == NULL) + { + if (def->defnamespace != NULL) + continue; + } + else if (def->defnamespace == NULL) + continue; + else if (strcmp(def->defnamespace, namspace) != 0) + continue; + + kw_len = strlen(def->defname); + if (text_len > kw_len && text_str[kw_len] == '=' && + strncmp(text_str, def->defname, kw_len) == 0) + break; + } + if (!cell) + { + /* No match, so keep old option */ + astate = accumArrayResult(astate, oldoptions[i], + false, TEXTOID, + CurrentMemoryContext); + } + } + } + + /* + * If CREATE/SET, add new options to array; if RESET, just check that the + * user didn't say RESET (option=val). (Must do this because the grammar + * doesn't enforce it.) + */ + foreach(cell, defList) + { + DefElem *def = (DefElem *) lfirst(cell); + + if (isReset) + { + if (def->arg != NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("RESET must not include values for parameters"))); + } + else + { + text *t; + const char *value; + Size len; + + /* + * Error out if the namespace is not valid. A NULL namespace is + * always valid. + */ + if (def->defnamespace != NULL) + { + bool valid = false; + int i; + + if (validnsps) + { + for (i = 0; validnsps[i]; i++) + { + if (strcmp(def->defnamespace, validnsps[i]) == 0) + { + valid = true; + break; + } + } + } + + if (!valid) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized parameter namespace \"%s\"", + def->defnamespace))); + } + + /* ignore if not in the same namespace */ + if (namspace == NULL) + { + if (def->defnamespace != NULL) + continue; + } + else if (def->defnamespace == NULL) + continue; + else if (strcmp(def->defnamespace, namspace) != 0) + continue; + + /* + * Flatten the DefElem into a text string like "name=arg". If we + * have just "name", assume "name=true" is meant. Note: the + * namespace is not output. + */ + if (def->arg != NULL) + value = defGetString(def); + else + value = "true"; + + /* + * This is not a great place for this test, but there's no other + * convenient place to filter the option out. As WITH (oids = + * false) will be removed someday, this seems like an acceptable + * amount of ugly. + */ + if (acceptOidsOff && def->defnamespace == NULL && + strcmp(def->defname, "oids") == 0) + { + if (defGetBoolean(def)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("tables declared WITH OIDS are not supported"))); + /* skip over option, reloptions machinery doesn't know it */ + continue; + } + + len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value); + /* +1 leaves room for sprintf's trailing null */ + t = (text *) palloc(len + 1); + SET_VARSIZE(t, len); + sprintf(VARDATA(t), "%s=%s", def->defname, value); + + astate = accumArrayResult(astate, PointerGetDatum(t), + false, TEXTOID, + CurrentMemoryContext); + } + } + + if (astate) + result = makeArrayResult(astate, CurrentMemoryContext); + else + result = (Datum) 0; + + return result; +} + + +/* + * Convert the text-array format of reloptions into a List of DefElem. + * This is the inverse of transformRelOptions(). + */ +List * +untransformRelOptions(Datum options) +{ + List *result = NIL; + ArrayType *array; + Datum *optiondatums; + int noptions; + int i; + + /* Nothing to do if no options */ + if (!PointerIsValid(DatumGetPointer(options))) + return result; + + array = DatumGetArrayTypeP(options); + + deconstruct_array_builtin(array, TEXTOID, &optiondatums, NULL, &noptions); + + for (i = 0; i < noptions; i++) + { + char *s; + char *p; + Node *val = NULL; + + s = TextDatumGetCString(optiondatums[i]); + p = strchr(s, '='); + if (p) + { + *p++ = '\0'; + val = (Node *) makeString(p); + } + result = lappend(result, makeDefElem(s, val, -1)); + } + + return result; ++======= + optionsSpecSetAddString(relopts->spec_set, name, desc, NoLock, offset, + NULL, default_val, validator, filler); ++>>>>>>> theirs } /* diff --cc src/backend/access/gin/ginutil.c index 2500d16b7b,6b637a81bf..0000000000 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@@ -69,8 -70,6 +70,11 @@@ ginhandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = ginvacuumcleanup; amroutine->amcanreturn = NULL; amroutine->amcostestimate = gincostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = ginoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = NULL; amroutine->ambuildphasename = NULL; amroutine->amvalidate = ginvalidate; diff --cc src/backend/access/gist/gist.c index b6bc75b44e,b5a1521a83..0000000000 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@@ -91,8 -91,6 +91,11 @@@ gisthandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = gistvacuumcleanup; amroutine->amcanreturn = gistcanreturn; amroutine->amcostestimate = gistcostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = gistoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = gistproperty; amroutine->ambuildphasename = NULL; amroutine->amvalidate = gistvalidate; diff --cc src/backend/access/gist/gistutil.c index 48db718b90,ed43b1bbda..0000000000 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@@ -1057,61 -1042,38 +1043,98 @@@ gistGetFakeLSN(Relation rel } } ++<<<<<<< ours +/* + * This is a stratnum support function for GiST opclasses that use the + * RT*StrategyNumber constants. + */ +Datum +gist_stratnum_common(PG_FUNCTION_ARGS) +{ + CompareType cmptype = PG_GETARG_INT32(0); + + switch (cmptype) + { + case COMPARE_EQ: + PG_RETURN_UINT16(RTEqualStrategyNumber); + case COMPARE_LT: + PG_RETURN_UINT16(RTLessStrategyNumber); + case COMPARE_LE: + PG_RETURN_UINT16(RTLessEqualStrategyNumber); + case COMPARE_GT: + PG_RETURN_UINT16(RTGreaterStrategyNumber); + case COMPARE_GE: + PG_RETURN_UINT16(RTGreaterEqualStrategyNumber); + case COMPARE_OVERLAP: + PG_RETURN_UINT16(RTOverlapStrategyNumber); + case COMPARE_CONTAINED_BY: + PG_RETURN_UINT16(RTContainedByStrategyNumber); + default: + PG_RETURN_UINT16(InvalidStrategy); + } +} + +/* + * Returns the opclass's private stratnum used for the given compare type. + * + * Calls the opclass's GIST_STRATNUM_PROC support function, if any, + * and returns the result. + * Returns InvalidStrategy if the function is not defined. + */ +StrategyNumber +GistTranslateStratnum(Oid opclass, CompareType cmptype) +{ + Oid opfamily; + Oid opcintype; + Oid funcid; + Datum result; + + /* Look up the opclass family and input datatype. */ + if (!get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype)) + return InvalidStrategy; + + /* Check whether the function is provided. */ + funcid = get_opfamily_proc(opfamily, opcintype, opcintype, GIST_STRATNUM_PROC); + if (!OidIsValid(funcid)) + return InvalidStrategy; + + /* Ask the translation function */ + result = OidFunctionCall1Coll(funcid, InvalidOid, Int32GetDatum(cmptype)); + return DatumGetUInt16(result); ++======= + /* values from GistOptBufferingMode */ + static opt_enum_elt_def gistBufferingOptValues[] = + { + {"auto", GIST_OPTION_BUFFERING_AUTO}, + {"on", GIST_OPTION_BUFFERING_ON}, + {"off", GIST_OPTION_BUFFERING_OFF}, + {(const char *) NULL} /* list terminator */ + }; + + static options_spec_set *gist_relopt_specset = NULL; + + options_spec_set * + gistgetreloptspecset(void) + { + if (gist_relopt_specset) + return gist_relopt_specset; + + gist_relopt_specset = allocateOptionsSpecSet(NULL, + sizeof(GiSTOptions), false, 2); + + optionsSpecSetAddInt(gist_relopt_specset, "fillfactor", + "Packs gist index pages only to this percentage", + NoLock, /* No ALTER, no lock */ + offsetof(GiSTOptions, fillfactor), NULL, + GIST_DEFAULT_FILLFACTOR, GIST_MIN_FILLFACTOR, 100); + + optionsSpecSetAddEnum(gist_relopt_specset, "buffering", + "Enables buffering build for this GiST index", + NoLock, /* No ALTER, no lock */ + offsetof(GiSTOptions, buffering_mode), NULL, + gistBufferingOptValues, + GIST_OPTION_BUFFERING_AUTO, + gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")); + return gist_relopt_specset; ++>>>>>>> theirs } diff --cc src/backend/access/hash/hash.c index df8409ab23,aae9541762..0000000000 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@@ -89,8 -89,6 +89,11 @@@ hashhandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = hashvacuumcleanup; amroutine->amcanreturn = NULL; amroutine->amcostestimate = hashcostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = hashoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = NULL; amroutine->ambuildphasename = NULL; amroutine->amvalidate = hashvalidate; diff --cc src/backend/access/nbtree/nbtree.c index 3d617f168f,cbcd5b8976..0000000000 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@@ -20,8 -20,11 +20,13 @@@ #include "access/nbtree.h" #include "access/relscan.h" ++<<<<<<< ours ++======= + #include "access/xloginsert.h" + #include "access/options.h" ++>>>>>>> theirs #include "commands/progress.h" #include "commands/vacuum.h" -#include "miscadmin.h" #include "nodes/execnodes.h" #include "pgstat.h" #include "storage/bulk_write.h" @@@ -132,8 -134,6 +137,11 @@@ bthandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = btvacuumcleanup; amroutine->amcanreturn = btcanreturn; amroutine->amcostestimate = btcostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = btgettreeheight; + amroutine->amoptions = btoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = btproperty; amroutine->ambuildphasename = btbuildphasename; amroutine->amvalidate = btvalidate; @@@ -1500,11 -1447,34 +1509,44 @@@ btcanreturn(Relation index, int attno return true; } ++<<<<<<< ours +/* + * btgettreeheight() -- Compute tree height for use by btcostestimate(). + */ +int +btgettreeheight(Relation rel) +{ + return _bt_getrootheight(rel); ++======= + static options_spec_set *bt_relopt_specset = NULL; + + options_spec_set * + btgetreloptspecset(void) + { + if (bt_relopt_specset) + return bt_relopt_specset; + + bt_relopt_specset = allocateOptionsSpecSet(NULL, + sizeof(BTOptions), false, 3); + + optionsSpecSetAddInt(bt_relopt_specset, "fillfactor", + "Packs btree index pages only to this percentage", + ShareUpdateExclusiveLock, /* affects inserts only */ + offsetof(BTOptions, fillfactor), NULL, + BTREE_DEFAULT_FILLFACTOR, BTREE_MIN_FILLFACTOR, 100); + + optionsSpecSetAddReal(bt_relopt_specset, "vacuum_cleanup_index_scale_factor", + "Number of tuple inserts prior to index cleanup as a fraction of reltuples", + ShareUpdateExclusiveLock, + offsetof(BTOptions, vacuum_cleanup_index_scale_factor), + NULL, -1, 0.0, 1e10); + + optionsSpecSetAddBool(bt_relopt_specset, "deduplicate_items", + "Enables \"deduplicate items\" feature for this btree index", + ShareUpdateExclusiveLock, /* affects inserts only */ + offsetof(BTOptions, deduplicate_items), NULL, + true); + + return bt_relopt_specset; ++>>>>>>> theirs } diff --cc src/backend/access/nbtree/nbtutils.c index 693e43c674,65658a5023..0000000000 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@@ -18,11 -18,16 +18,16 @@@ #include #include "access/nbtree.h" ++<<<<<<< ours +#include "access/reloptions.h" ++======= + #include "storage/lock.h" + #include "access/relscan.h" ++>>>>>>> theirs #include "commands/progress.h" -#include "lib/qunique.h" #include "miscadmin.h" -#include "utils/array.h" #include "utils/datum.h" #include "utils/lsyscache.h" -#include "utils/memutils.h" -#include "utils/rel.h" #define LOOK_AHEAD_REQUIRED_RECHECKS 3 #define LOOK_AHEAD_DEFAULT_DISTANCE 5 diff --cc src/backend/access/spgist/spgutils.c index 6e96804891,7ab983b036..0000000000 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@@ -76,8 -76,6 +76,11 @@@ spghandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = spgvacuumcleanup; amroutine->amcanreturn = spgcanreturn; amroutine->amcostestimate = spgcostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = spgoptions; ++======= ++>>>>>>> theirs amroutine->amproperty = spgproperty; amroutine->ambuildphasename = NULL; amroutine->amvalidate = spgvalidate; diff --cc src/backend/commands/indexcmds.c index 59c836fc24,649aa915b6..0000000000 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@@ -571,8 -560,7 +572,12 @@@ DefineIndex(Oid tableId IndexAmRoutine *amRoutine; bool amcanorder; bool amissummarizing; ++<<<<<<< ours + amoptions_function amoptions; + bool exclusion; ++======= + amreloptspecset_function amreloptspecsetfn; ++>>>>>>> theirs bool partitioned; bool safe_index; Datum reloptions; @@@ -887,14 -869,9 +892,14 @@@ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support exclusion constraints", accessMethodName))); + if (stmt->iswithoutoverlaps && strcmp(accessMethodName, "gist") != 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("access method \"%s\" does not support WITHOUT OVERLAPS constraints", + accessMethodName))); amcanorder = amRoutine->amcanorder; - amoptions = amRoutine->amoptions; + amreloptspecsetfn = amRoutine->amreloptspecset; amissummarizing = amRoutine->amsummarizing; pfree(amRoutine); diff --cc src/backend/commands/tablecmds.c index d617c4bc63,e145bf7957..0000000000 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@@ -741,7 -700,6 +742,10 @@@ DefineRelation(CreateStmt *stmt, char r ListCell *listptr; AttrNumber attnum; bool partitioned; ++<<<<<<< ours + const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ++======= ++>>>>>>> theirs Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@@ -15643,7 -14884,9 +15669,13 @@@ ATExecSetRelOptions(Relation rel, List Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; ++<<<<<<< ours + const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ++======= + List *optionsDefList; + options_spec_set *optionsSpecSet; + char *heap_namespaces[] = HEAP_RELOPT_NAMESPACES; ++>>>>>>> theirs if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ diff --cc src/backend/tcop/utility.c index 25fe3d5801,bafa48199b..0000000000 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@@ -1158,7 -1155,8 +1158,12 @@@ ProcessUtilitySlow(ParseState *pstate { CreateStmt *cstmt = (CreateStmt *) stmt; Datum toast_options; ++<<<<<<< ours + const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ++======= + static char *validnsps[] = HEAP_RELOPT_NAMESPACES; + List *toastDefList; ++>>>>>>> theirs /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; diff --cc src/include/access/amapi.h index fb94b3d1ac,97ecede1d7..0000000000 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@@ -144,16 -141,8 +145,21 @@@ typedef void (*amcostestimate_function double *indexCorrelation, double *indexPages); ++<<<<<<< ours +/* estimate height of a tree-structured index + * + * XXX This just computes a value that is later used by amcostestimate. This + * API could be expanded to support passing more values if the need arises. + */ +typedef int (*amgettreeheight_function) (Relation rel); + +/* parse index reloptions */ +typedef bytea *(*amoptions_function) (Datum reloptions, + bool validate); ++======= + /* get Spec Set for relation options */ + typedef options_spec_set *(*amreloptspecset_function) (); ++>>>>>>> theirs /* report AM, index, or index column property */ typedef bool (*amproperty_function) (Oid index_oid, int attno, @@@ -283,8 -272,7 +289,12 @@@ typedef struct IndexAmRoutin amvacuumcleanup_function amvacuumcleanup; amcanreturn_function amcanreturn; /* can be NULL */ amcostestimate_function amcostestimate; ++<<<<<<< ours + amgettreeheight_function amgettreeheight; /* can be NULL */ + amoptions_function amoptions; ++======= + amreloptspecset_function amreloptspecset; /* can be NULL */ ++>>>>>>> theirs amproperty_function amproperty; /* can be NULL */ ambuildphasename_function ambuildphasename; /* can be NULL */ amvalidate_function amvalidate; diff --cc src/include/access/reloptions.h index 43445cdcc6,3572345102..0000000000 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@@ -1,15 -1,10 +1,19 @@@ /*------------------------------------------------------------------------- * * reloptions.h - * Core support for relation and tablespace options (pg_class.reloptions + + * Support for relation view and tablespace options (pg_class.reloptions * and pg_tablespace.spcoptions) * ++<<<<<<< ours + * Note: the functions dealing with text-array reloptions values declare + * them as Datum, not ArrayType *, to avoid needing to include array.h + * into a lot of low-level code. + * + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group ++======= + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group ++>>>>>>> theirs * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/reloptions.h @@@ -219,17 -75,8 +84,15 @@@ extern void add_local_string_reloption( validate_string_relopt validator, fill_string_relopt filler, int offset); ++<<<<<<< ours +extern Datum transformRelOptions(Datum oldOptions, List *defList, + const char *namspace, const char *const validnsps[], + bool acceptOidsOff, bool isReset); +extern List *untransformRelOptions(Datum options); ++======= ++>>>>>>> theirs extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, - amoptions_function amoptions); - extern void *build_reloptions(Datum reloptions, bool validate, - relopt_kind kind, - Size relopt_struct_size, - const relopt_parse_elt *relopt_elems, - int num_relopt_elems); + amreloptspecset_function amoptions_def_set); extern void *build_local_reloptions(local_relopts *relopts, Datum options, bool validate); diff --cc src/test/modules/dummy_index_am/dummy_index_am.c index 7586f8ae5e,8d4150cd86..0000000000 --- a/src/test/modules/dummy_index_am/dummy_index_am.c +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@@ -21,11 -21,9 +21,15 @@@ PG_MODULE_MAGIC; ++<<<<<<< ours +/* parse table for fillRelOptions */ +static relopt_parse_elt di_relopt_tab[6]; + +/* Kind of relation options for dummy index */ +static relopt_kind di_relopt_kind; ++======= + void _PG_init(void); ++>>>>>>> theirs typedef enum DummyAmEnum { @@@ -45,7 -43,7 +49,11 @@@ typedef struct DummyIndexOption int option_string_null_offset; } DummyIndexOptions; ++<<<<<<< ours +static relopt_enum_elt_def dummyAmEnumValues[] = ++======= + static opt_enum_elt_def dummyAmEnumValues[] = ++>>>>>>> theirs { {"one", DUMMY_AM_ENUM_ONE}, {"two", DUMMY_AM_ENUM_TWO}, @@@ -306,8 -296,6 +306,11 @@@ dihandler(PG_FUNCTION_ARGS amroutine->amvacuumcleanup = divacuumcleanup; amroutine->amcanreturn = NULL; amroutine->amcostestimate = dicostestimate; ++<<<<<<< ours + amroutine->amgettreeheight = NULL; + amroutine->amoptions = dioptions; ++======= ++>>>>>>> theirs amroutine->amproperty = NULL; amroutine->ambuildphasename = NULL; amroutine->amvalidate = divalidate;