</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><function>options</function></term>
+ <listitem>
+ <para>
+ Optionally, a B-tree operator family may provide
+ <function>options</function> (<quote>operator class specific
+ options</quote>) support functions, registered under support
+ function number 5. These functions define set of user-visible
+ parameters that control operator class behavior.
+ </para>
+ <para>
+ An <function>options</function> support function must have the
+ signature
+<synopsis>
+options(<replaceable>relopts</replaceable> <type>local_relopts *</type>) returns void
+</synopsis>
+ The function has given pointer to <replaceable>local_relopts</replaceable>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+ <para>
+ Currently, no B-Tree operator class has <function>options</function>
+ support function. B-tree doesn't allow flexible representation of keys
+ like GiST, SP-GiST, GIN and BRIN do. So, <function>options</function>
+ probably doesn't have much usage in current shape of B-tree index
+ access method. Nevertheless, this support function was added to B-tree
+ for uniformity, and probably it will found its usage during further
+ evolution of B-tree in <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</sect1>
<para>
There are five methods that an index operator class for
- <acronym>GiST</acronym> must provide, and four that are optional.
+ <acronym>GiST</acronym> must provide, and five that are optional.
Correctness of the index is ensured
by proper implementation of the <function>same</function>, <function>consistent</function>
and <function>union</function> methods, while efficiency (size and speed) of the
if the operator class wishes to support ordered scans (nearest-neighbor
searches). The optional ninth method <function>fetch</function> is needed if the
operator class wishes to support index-only scans, except when the
- <function>compress</function> method is omitted.
+ <function>compress</function> method is omitted. The optional tenth method
+ <function>options</function> is needed if the operator class provides
+ the user-specified parameters.
</para>
<variablelist>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><function>options</function></term>
+ <listitem>
+ <para>
+ Allows defintion of user-visible parameters that control operator
+ class behavior.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_options(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ The function has given pointer to <replaceable>local_relopts</replaceable>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+
+ <para>
+ The sample implementation of my_option() and parameters usage
+ in the another support function are given below:
+
+<programlisting>
+typedef enum MyEnumType
+{
+ MY_ENUM_ON,
+ MY_ENUM_OFF,
+ MY_ENUM_AUTO
+} MyEnumType;
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int int_param; /* integer parameter */
+ double real_param; /* real parameter */
+ MyEnumType enum_param; /* enum parameter */
+ int str_param; /* string parameter */
+} MyOptionsStruct;
+
+/* String representations for enum values */
+static relopt_enum_elt_def myEnumValues[] =
+{
+ {"on", MY_ENUM_ON},
+ {"off", MY_ENUM_OFF},
+ {"auto", MY_ENUM_AUTO},
+ {(const char *) NULL} /* list terminator */
+};
+
+static char *str_param_default = "default";
+
+/*
+ * Sample validatior: checks that string is not longer than 8 bytes.
+ */
+static void
+validate_my_string_relopt(const char *value)
+{
+ if (strlen(value) > 8)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("str_param must be at most 8 bytes")));
+}
+
+/*
+ * Sample filler: switches characters to lower case.
+ */
+static Size
+fill_my_string_relopt(const char *value, void *ptr)
+{
+ char *tmp = str_tolower(value, strlen(value), DEFAULT_COLLATION_OID);
+ int len = strlen(tmp);
+
+ if (ptr)
+ strcpy((char *) ptr, tmp);
+
+ pfree(tmp);
+ return len + 1;
+}
+
+PG_FUNCTION_INFO_V1(my_options);
+
+Datum
+my_options(PG_FUNCTION_ARGS)
+{
+ local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
+
+ init_local_reloptions(relopts, sizeof(MyOptionsStruct));
+ add_local_int_reloption(relopts, "int_param", "integer parameter",
+ 100, 0, 1000000,
+ offsetof(MyOptionsStruct, int_param));
+ add_local_real_reloption(relopts, "real_param", "real parameter",
+ 1.0, 0.0, 1000000.0,
+ offsetof(MyOptionsStruct, real_param));
+ add_local_enum_reloption(relopts, "enum_param", "enum parameter",
+ myEnumValues, MY_ENUM_ON,
+ "Valid values are: \"on\", \"off\" and \"auto\".",
+ offsetof(MyOptionsStruct, enum_param));
+ add_local_string_reloption(relopts, "str_param", "string parameter",
+ str_param_default,
+ &validate_my_string_relopt,
+ &fill_my_string_relopt,
+ offsetof(MyOptionsStruct, str_param));
+
+ PG_RETURN_VOID();
+}
+
+PG_FUNCTION_INFO_V1(my_compress);
+
+Datum
+my_compress(PG_FUNCTION_ARGS)
+{
+ int int_param = 100;
+ double real_param = 1.0;
+ MyEnumType enum_param = MY_ENUM_ON;
+ char *str_param = str_param_default;
+
+ /*
+ * Normally, when opclass contains 'options' method, then options are always
+ * passed to support functions. However, if you add 'options' method to
+ * existing opclass, previously defined indexes have no options, so the
+ * check is required.
+ */
+ if (PG_HAS_OPCLASS_OPTIONS())
+ {
+ MyOptionsStruct *options = (MyOptionsStruct *) PG_GET_OPCLASS_OPTIONS();
+
+ int_param = options->int_param;
+ real_param = options->real_param;
+ enum_param = options->enum_param;
+ str_param = GET_STRING_RELOPTION(options, str_param);
+ }
+
+ /* the rest implementation of support function */
+}
+
+</programlisting>
+ </para>
+
+ <para>
+ Since the representation of the key in <acronym>GiST</acronym> is
+ flexible, it may depends on user-specified parameters. For instace,
+ the length of key signature may be such parameter. See
+ <literal>gtsvector_options()</literal> for example.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>
<xref linkend="btree-support-funcs"/>.
</para>
+ <para>
+ Additionally, some opclasses allow user to set specific parameters, which
+ controls its behavior. Each builtin index access method have optional
+ <function>options</function> support function, which defines set of
+ opclass-specific parameters.
+ </para>
+
<table tocentry="1" id="xindex-btree-support-table">
<title>B-Tree Support Functions</title>
<tgroup cols="2">
</entry>
<entry>4</entry>
</row>
+ <row>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>5</entry>
+ </row>
</tbody>
</tgroup>
</table>
</entry>
<entry>2</entry>
</row>
+ <row>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>3</entry>
+ </row>
</tbody>
</tgroup>
</table>
index-only scans (optional)</entry>
<entry>9</entry>
</row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>10</entry>
+ </row>
</tbody>
</tgroup>
</table>
query qualifier</entry>
<entry>5</entry>
</row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>6</entry>
+ </row>
</tbody>
</tgroup>
</table>
</entry>
<entry>6</entry>
</row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>7</entry>
+ </row>
</tbody>
</tgroup>
</table>
</entry>
<entry>4</entry>
</row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ Defines set of options that are specific for this operator class
+ (optional)
+ </entry>
+ <entry>5</entry>
+ </row>
</tbody>
</tgroup>
</table>