=== 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;