codekingpro/portable-devtools
115k
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>