Add documentation for opclass options
authorAlexander Korotkov <akorotkov@postgresql.org>
Sat, 20 Jun 2020 10:34:54 +0000 (13:34 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Sat, 20 Jun 2020 10:34:54 +0000 (13:34 +0300)
911e7020770 added opclass options and adjusted documentation for each
particular affected opclass.  However, documentation for extendability was
not adjusted.  This commit adjusts documentation for interfaces of index AMs
and opclasses.

Discussion: https://postgr.es/m/CAH2-WzmQnW6%2Bz5F9AW%2BSz%2BzEcEvXofTwh_A9J3%3D_WA-FBP0wYg%40mail.gmail.com
Author: Alexander Korotkov
Reported-by: Peter Geoghegan
Reviewed-by: Peter Geoghegan
doc/src/sgml/brin.sgml
doc/src/sgml/btree.sgml
doc/src/sgml/gin.sgml
doc/src/sgml/gist.sgml
doc/src/sgml/indexam.sgml
doc/src/sgml/spgist.sgml
doc/src/sgml/xindex.sgml

index 46a7d07bf8b670d77692a796ad1adb1db0c0e3bc..d7f1af7819a49a77aa1221b452654f993cd90f63 100644 (file)
@@ -562,6 +562,36 @@ typedef struct BrinOpcInfo
    </varlistentry>
   </variablelist>
 
+  Optionally, an operator class for <acronym>BRIN</acronym> can supply the
+  following method:
+
+  <variablelist>
+    <varlistentry>
+     <term><function>void options(local_relopts *relopts)</function></term>
+     <listitem>
+      <para>
+       Defines set of user-visible parameters that control operator class
+       behavior.
+      </para>
+
+      <para>
+       The <function>options</function> 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>
+       Since both key extraction for indexed value and representation of the
+       key in <acronym>GIN</acronym> are flexible, it may depends on
+       user-specified parameters.
+      </para>
+     </listitem>
+    </varlistentry>
+  </variablelist>
+
   The core distribution includes support for two types of operator classes:
   minmax and inclusion.  Operator class definitions using them are shipped for
   in-core data types as appropriate.  Additional operator classes can be
index 73947db55cb44a41d3e201d1845c347c792dfc71..2c4dd48ea35f576e421067efd4260c3fa3c02e89 100644 (file)
@@ -550,6 +550,39 @@ equalimage(<replaceable>opcintype</replaceable> <type>oid</type>) returns bool
     </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>
index 0182b445855ca7d59ec57a4b07b9c781dfd9fb51..d85e7c8796bc39b1d5a8ce909da5afacd8b007fc 100644 (file)
 
  <para>
   Optionally, an operator class for <acronym>GIN</acronym> can supply the
-  following method:
+  following methods:
 
   <variablelist>
     <varlistentry>
       </para>
      </listitem>
     </varlistentry>
+    <varlistentry>
+     <term><function>void options(local_relopts *relopts)</function></term>
+     <listitem>
+      <para>
+       Defines set of user-visible parameters that control operator class
+       behavior.
+      </para>
+
+      <para>
+       The <function>options</function> function has given pointer to
+       <replaceable>local_relopts</replaceable> struct, which needs to be
+       filled with s 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>
+       Since both key extraction for indexed value and representation of the
+       key in <acronym>GIN</acronym> are flexible, it may depends on
+       user-specified parameters.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
  </para>
 
index a7eec1e94970fc5baee92f0576480b3fa7cbe3a4..31c28fdb61c7bb77624322989efaf4463d9ef45e 100644 (file)
@@ -269,7 +269,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
 
  <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
@@ -287,7 +287,9 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
    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>
@@ -939,6 +941,161 @@ my_fetch(PG_FUNCTION_ARGS)
 
      </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,
+                               &amp;validate_my_string_relopt,
+                               &amp;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>
index 37f8d8760a380fac2277178e9acf53e76215a23e..af87f172a7cd06a69b25be96bbdb63ac68b8689e 100644 (file)
@@ -96,6 +96,8 @@ typedef struct IndexAmRoutine
     uint16      amstrategies;
     /* total number of support functions that this AM uses */
     uint16      amsupport;
+    /* opclass options support function number or 0 */
+    uint16      amoptsprocnum;
     /* does AM support ORDER BY indexed column's value? */
     bool        amcanorder;
     /* does AM support ORDER BY result of an operator on indexed column? */
index 0e04a0867932ecbb16cda8c3749ca76051736f40..03f914735bdb7f9961f09cbad4658c8d4ba96a48 100644 (file)
@@ -858,7 +858,7 @@ typedef struct spgLeafConsistentOut
    </variablelist>
 
  <para>
-  The optional user-defined method is:
+  The optional user-defined method are:
  </para>
 
  <variablelist>
@@ -875,6 +875,39 @@ typedef struct spgLeafConsistentOut
       </para>
      </listitem>
     </varlistentry>
+    <varlistentry>
+     <term><function>options</function></term>
+     <listitem>
+      <para>
+       Defines set 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>
+       Since the representation of the key in <acronym>SP-GiST</acronym> is
+       flexible, it may depends on user-specified parameters.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
 
   <para>
index 14c1701c9b572b3cabfb320167f0fbfb1c94736d..0e4587a81b98dc372fde841b41693de5cae9b047 100644 (file)
    <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>