Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
gin-extensibility.html237 linesDownload Raw Back to html
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.3. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes" /><link rel="next" href="gin-implementation.html" title="70.4. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.3. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 16.3 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-implementation.html" title="70.4. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.3. Extensibility <a href="#GIN-EXTENSIBILITY" class="id_link">#</a></h2></div></div></div><p>3   The <acronym class="acronym">GIN</acronym> interface has a high level of abstraction,4   requiring the access method implementer only to implement the semantics of5   the data type being accessed.  The <acronym class="acronym">GIN</acronym> layer itself6   takes care of concurrency, logging and searching the tree structure.7 </p><p>8   All it takes to get a <acronym class="acronym">GIN</acronym> access method working is to9   implement a few user-defined methods, which define the behavior of10   keys in the tree and the relationships between keys, indexed items,11   and indexable queries. In short, <acronym class="acronym">GIN</acronym> combines12   extensibility with generality, code reuse, and a clean interface.13 </p><p>14   There are two methods that an operator class for15   <acronym class="acronym">GIN</acronym> must provide:16 17  </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">Datum *extractValue(Datum itemValue, int32 *nkeys,18        bool **nullFlags)</code></span></dt><dd><p>19       Returns a palloc'd array of keys given an item to be indexed.  The20       number of returned keys must be stored into <code class="literal">*nkeys</code>.21       If any of the keys can be null, also palloc an array of22       <code class="literal">*nkeys</code> <code class="type">bool</code> fields, store its address at23       <code class="literal">*nullFlags</code>, and set these null flags as needed.24       <code class="literal">*nullFlags</code> can be left <code class="symbol">NULL</code> (its initial value)25       if all keys are non-null.26       The return value can be <code class="symbol">NULL</code> if the item contains no keys.27      </p></dd><dt><span class="term"><code class="function">Datum *extractQuery(Datum query, int32 *nkeys,28        StrategyNumber n, bool **pmatch, Pointer **extra_data,29        bool **nullFlags, int32 *searchMode)</code></span></dt><dd><p>30       Returns a palloc'd array of keys given a value to be queried; that is,31       <code class="literal">query</code> is the value on the right-hand side of an32       indexable operator whose left-hand side is the indexed column.33       <code class="literal">n</code> is the strategy number of the operator within the34       operator class (see <a class="xref" href="xindex.html#XINDEX-STRATEGIES" title="38.16.2. Index Method Strategies">Section 38.16.2</a>).35       Often, <code class="function">extractQuery</code> will need36       to consult <code class="literal">n</code> to determine the data type of37       <code class="literal">query</code> and the method it should use to extract key values.38       The number of returned keys must be stored into <code class="literal">*nkeys</code>.39       If any of the keys can be null, also palloc an array of40       <code class="literal">*nkeys</code> <code class="type">bool</code> fields, store its address at41       <code class="literal">*nullFlags</code>, and set these null flags as needed.42       <code class="literal">*nullFlags</code> can be left <code class="symbol">NULL</code> (its initial value)43       if all keys are non-null.44       The return value can be <code class="symbol">NULL</code> if the <code class="literal">query</code> contains no keys.45      </p><p>46       <code class="literal">searchMode</code> is an output argument that allows47       <code class="function">extractQuery</code> to specify details about how the search48       will be done.49       If <code class="literal">*searchMode</code> is set to50       <code class="literal">GIN_SEARCH_MODE_DEFAULT</code> (which is the value it is51       initialized to before call), only items that match at least one of52       the returned keys are considered candidate matches.53       If <code class="literal">*searchMode</code> is set to54       <code class="literal">GIN_SEARCH_MODE_INCLUDE_EMPTY</code>, then in addition to items55       containing at least one matching key, items that contain no keys at56       all are considered candidate matches.  (This mode is useful for57       implementing is-subset-of operators, for example.)58       If <code class="literal">*searchMode</code> is set to <code class="literal">GIN_SEARCH_MODE_ALL</code>,59       then all non-null items in the index are considered candidate60       matches, whether they match any of the returned keys or not.  (This61       mode is much slower than the other two choices, since it requires62       scanning essentially the entire index, but it may be necessary to63       implement corner cases correctly.  An operator that needs this mode64       in most cases is probably not a good candidate for a GIN operator65       class.)66       The symbols to use for setting this mode are defined in67       <code class="filename">access/gin.h</code>.68      </p><p>69       <code class="literal">pmatch</code> is an output argument for use when partial match70       is supported.  To use it, <code class="function">extractQuery</code> must allocate71       an array of <code class="literal">*nkeys</code> <code class="type">bool</code>s and store its address at72       <code class="literal">*pmatch</code>.  Each element of the array should be set to true73       if the corresponding key requires partial match, false if not.74       If <code class="literal">*pmatch</code> is set to <code class="symbol">NULL</code> then GIN assumes partial match75       is not required.  The variable is initialized to <code class="symbol">NULL</code> before call,76       so this argument can simply be ignored by operator classes that do77       not support partial match.78      </p><p>79       <code class="literal">extra_data</code> is an output argument that allows80       <code class="function">extractQuery</code> to pass additional data to the81       <code class="function">consistent</code> and <code class="function">comparePartial</code> methods.82       To use it, <code class="function">extractQuery</code> must allocate83       an array of <code class="literal">*nkeys</code> pointers and store its address at84       <code class="literal">*extra_data</code>, then store whatever it wants to into the85       individual pointers.  The variable is initialized to <code class="symbol">NULL</code> before86       call, so this argument can simply be ignored by operator classes that87       do not require extra data.  If <code class="literal">*extra_data</code> is set, the88       whole array is passed to the <code class="function">consistent</code> method, and89       the appropriate element to the <code class="function">comparePartial</code> method.90      </p></dd></dl></div><p>91 92  An operator class must also provide a function to check if an indexed item93  matches the query. It comes in two flavors, a Boolean <code class="function">consistent</code>94  function, and a ternary <code class="function">triConsistent</code> function.95  <code class="function">triConsistent</code> covers the functionality of both, so providing96  <code class="function">triConsistent</code> alone is sufficient. However, if the Boolean97  variant is significantly cheaper to calculate, it can be advantageous to98  provide both.  If only the Boolean variant is provided, some optimizations99  that depend on refuting index items before fetching all the keys are100  disabled.101 102  </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">bool consistent(bool check[], StrategyNumber n, Datum query,103        int32 nkeys, Pointer extra_data[], bool *recheck,104        Datum queryKeys[], bool nullFlags[])</code></span></dt><dd><p>105       Returns true if an indexed item satisfies the query operator with106       strategy number <code class="literal">n</code> (or might satisfy it, if the recheck107       indication is returned).  This function does not have direct access108       to the indexed item's value, since <acronym class="acronym">GIN</acronym> does not109       store items explicitly.  Rather, what is available is knowledge110       about which key values extracted from the query appear in a given111       indexed item.  The <code class="literal">check</code> array has length112       <code class="literal">nkeys</code>, which is the same as the number of keys previously113       returned by <code class="function">extractQuery</code> for this <code class="literal">query</code> datum.114       Each element of the115       <code class="literal">check</code> array is true if the indexed item contains the116       corresponding query key, i.e., if (check[i] == true) the i-th key of the117       <code class="function">extractQuery</code> result array is present in the indexed item.118       The original <code class="literal">query</code> datum is119       passed in case the <code class="function">consistent</code> method needs to consult it,120       and so are the <code class="literal">queryKeys[]</code> and <code class="literal">nullFlags[]</code>121       arrays previously returned by <code class="function">extractQuery</code>.122       <code class="literal">extra_data</code> is the extra-data array returned by123       <code class="function">extractQuery</code>, or <code class="symbol">NULL</code> if none.124      </p><p>125       When <code class="function">extractQuery</code> returns a null key in126       <code class="literal">queryKeys[]</code>, the corresponding <code class="literal">check[]</code> element127       is true if the indexed item contains a null key; that is, the128       semantics of <code class="literal">check[]</code> are like <code class="literal">IS NOT DISTINCT129       FROM</code>.  The <code class="function">consistent</code> function can examine the130       corresponding <code class="literal">nullFlags[]</code> element if it needs to tell131       the difference between a regular value match and a null match.132      </p><p>133       On success, <code class="literal">*recheck</code> should be set to true if the heap134       tuple needs to be rechecked against the query operator, or false if135       the index test is exact.  That is, a false return value guarantees136       that the heap tuple does not match the query; a true return value with137       <code class="literal">*recheck</code> set to false guarantees that the heap tuple does138       match the query; and a true return value with139       <code class="literal">*recheck</code> set to true means that the heap tuple might match140       the query, so it needs to be fetched and rechecked by evaluating the141       query operator directly against the originally indexed item.142      </p></dd><dt><span class="term"><code class="function">GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,143        int32 nkeys, Pointer extra_data[],144        Datum queryKeys[], bool nullFlags[])</code></span></dt><dd><p>145       <code class="function">triConsistent</code> is similar to <code class="function">consistent</code>,146       but instead of Booleans in the <code class="literal">check</code> vector, there are147       three possible values for each148       key: <code class="literal">GIN_TRUE</code>, <code class="literal">GIN_FALSE</code> and149       <code class="literal">GIN_MAYBE</code>. <code class="literal">GIN_FALSE</code> and <code class="literal">GIN_TRUE</code>150       have the same meaning as regular Boolean values, while151       <code class="literal">GIN_MAYBE</code> means that the presence of that key is not known.152       When <code class="literal">GIN_MAYBE</code> values are present, the function should only153       return <code class="literal">GIN_TRUE</code> if the item certainly matches whether or154       not the index item contains the corresponding query keys. Likewise, the155       function must return <code class="literal">GIN_FALSE</code> only if the item certainly156       does not match, whether or not it contains the <code class="literal">GIN_MAYBE</code>157       keys. If the result depends on the <code class="literal">GIN_MAYBE</code> entries, i.e.,158       the match cannot be confirmed or refuted based on the known query keys,159       the function must return <code class="literal">GIN_MAYBE</code>.160      </p><p>161       When there are no <code class="literal">GIN_MAYBE</code> values in the <code class="literal">check</code>162       vector, a <code class="literal">GIN_MAYBE</code> return value is the equivalent of163       setting the <code class="literal">recheck</code> flag in the164       Boolean <code class="function">consistent</code> function.165      </p></dd></dl></div><p>166 </p><p>167  In addition, GIN must have a way to sort the key values stored in the index.168  The operator class can define the sort ordering by specifying a comparison169  method:170 171  </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">int compare(Datum a, Datum b)</code></span></dt><dd><p>172       Compares two keys (not indexed items!) and returns an integer less than173       zero, zero, or greater than zero, indicating whether the first key is174       less than, equal to, or greater than the second.  Null keys are never175       passed to this function.176      </p></dd></dl></div><p>177 178  Alternatively, if the operator class does not provide a <code class="function">compare</code>179  method, GIN will look up the default btree operator class for the index180  key data type, and use its comparison function.  It is recommended to181  specify the comparison function in a GIN operator class that is meant for182  just one data type, as looking up the btree operator class costs a few183  cycles.  However, polymorphic GIN operator classes (such184  as <code class="literal">array_ops</code>) typically cannot specify a single comparison185  function.186 </p><p>187  An operator class for <acronym class="acronym">GIN</acronym> can optionally supply the188  following methods:189 190  </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">int comparePartial(Datum partial_key, Datum key, StrategyNumber n,191                              Pointer extra_data)</code></span></dt><dd><p>192       Compare a partial-match query key to an index key.  Returns an integer193       whose sign indicates the result: less than zero means the index key194       does not match the query, but the index scan should continue; zero195       means that the index key does match the query; greater than zero196       indicates that the index scan should stop because no more matches197       are possible.  The strategy number <code class="literal">n</code> of the operator198       that generated the partial match query is provided, in case its199       semantics are needed to determine when to end the scan.  Also,200       <code class="literal">extra_data</code> is the corresponding element of the extra-data201       array made by <code class="function">extractQuery</code>, or <code class="symbol">NULL</code> if none.202       Null keys are never passed to this function.203      </p></dd><dt><span class="term"><code class="function">void options(local_relopts *relopts)</code></span></dt><dd><p>204       Defines a set of user-visible parameters that control operator class205       behavior.206      </p><p>207       The <code class="function">options</code> function is passed a pointer to a208       <code class="structname">local_relopts</code> struct, which needs to be209       filled with a set of operator class specific options.  The options210       can be accessed from other support functions using the211       <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and212       <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.213      </p><p>214       Since both key extraction of indexed values and representation of the215       key in <acronym class="acronym">GIN</acronym> are flexible, they may depend on216       user-specified parameters.217      </p></dd></dl></div><p>218 </p><p>219  To support <span class="quote">“<span class="quote">partial match</span>”</span> queries, an operator class must220  provide the <code class="function">comparePartial</code> method, and its221  <code class="function">extractQuery</code> method must set the <code class="literal">pmatch</code>222  parameter when a partial-match query is encountered.  See223  <a class="xref" href="gin-implementation.html#GIN-PARTIAL-MATCH" title="70.4.2. Partial Match Algorithm">Section 70.4.2</a> for details.224 </p><p>225  The actual data types of the various <code class="literal">Datum</code> values mentioned226  above vary depending on the operator class.  The item values passed to227  <code class="function">extractValue</code> are always of the operator class's input type, and228  all key values must be of the class's <code class="literal">STORAGE</code> type.  The type of229  the <code class="literal">query</code> argument passed to <code class="function">extractQuery</code>,230  <code class="function">consistent</code> and <code class="function">triConsistent</code> is whatever is the231  right-hand input type of the class member operator identified by the232  strategy number.  This need not be the same as the indexed type, so long as233  key values of the correct type can be extracted from it.  However, it is234  recommended that the SQL declarations of these three support functions use235  the opclass's indexed data type for the <code class="literal">query</code> argument, even236  though the actual type might be something else depending on the operator.237 </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-implementation.html" title="70.4. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.2. Built-in Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 16.3 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.4. Implementation</td></tr></table></div></body></html>
codekingpro/portable-devtools · Team Ai