mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Add SQL-accessible functions for inspecting index AM properties.
Per discussion, we should provide such functions to replace the lost ability to discover AM properties by inspecting pg_am (cf commit65c5fcd35
). The added functionality is also meant to displace any code that was looking directly at pg_index.indoption, since we'd rather not believe that the bit meanings in that field are part of any client API contract. As future-proofing, define the SQL API to not assume that properties that are currently AM-wide or index-wide will remain so unless they logically must be; instead, expose them only when inquiring about a specific index or even specific index column. Also provide the ability for an index AM to override the behavior. In passing, document pg_am.amtype, overlooked in commit473b93287
. Andrew Gierth, with kibitzing by me and others Discussion: <87mvl5on7n.fsf@news-spur.riddles.org.uk>
This commit is contained in:
@ -529,10 +529,11 @@
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The catalog <structname>pg_am</structname> stores information about index
|
||||
access methods. There is one row for each index access method supported by
|
||||
the system. The requirements for index access methods are discussed in
|
||||
detail in <xref linkend="indexam">.
|
||||
The catalog <structname>pg_am</structname> stores information about
|
||||
relation access methods. There is one row for each access method supported
|
||||
by the system.
|
||||
Currently, only indexes have access methods. The requirements for index
|
||||
access methods are discussed in detail in <xref linkend="indexam">.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
@ -573,10 +574,30 @@
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>amtype</structfield></entry>
|
||||
<entry><type>char</type></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
Currently always <literal>i</literal> to indicate an index access
|
||||
method; other values may be allowed in future
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Before <productname>PostgreSQL</> 9.6, <structname>pg_am</structname>
|
||||
contained many additional columns representing properties of index access
|
||||
methods. That data is now only directly visible at the C code level.
|
||||
However, <function>pg_index_column_has_property()</function> and related
|
||||
functions have been added to allow SQL queries to inspect index access
|
||||
method properties; see <xref linkend="functions-info-catalog-table">.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
|
@ -16289,6 +16289,18 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
||||
<primary>pg_get_viewdef</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>pg_index_column_has_property</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>pg_index_has_property</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>pg_indexam_has_property</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>pg_options_to_table</primary>
|
||||
</indexterm>
|
||||
@ -16476,6 +16488,21 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
||||
materialized view; lines with fields are wrapped to specified
|
||||
number of columns, pretty-printing is implied</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>pg_index_column_has_property(<parameter>index_oid</parameter>, <parameter>column_no</>, <parameter>prop_name</>)</function></literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>test whether an index column has a specified property</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>pg_index_has_property(<parameter>index_oid</parameter>, <parameter>prop_name</>)</function></literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>test whether an index has a specified property</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>pg_indexam_has_property(<parameter>am_oid</parameter>, <parameter>prop_name</>)</function></literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>test whether an index access method has a specified property</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>pg_options_to_table(<parameter>reloptions</parameter>)</function></literal></entry>
|
||||
<entry><type>setof record</type></entry>
|
||||
@ -16619,6 +16646,144 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
||||
its OID.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>pg_index_column_has_property</function>,
|
||||
<function>pg_index_has_property</function>, and
|
||||
<function>pg_indexam_has_property</function> return whether the
|
||||
specified index column, index, or index access method possesses the named
|
||||
property. <literal>NULL</literal> is returned if the property name is not
|
||||
known or does not apply to the particular object, or if the OID or column
|
||||
number does not identify a valid object. Refer to
|
||||
<xref linkend="functions-info-index-column-props"> for column properties,
|
||||
<xref linkend="functions-info-index-props"> for index properties, and
|
||||
<xref linkend="functions-info-indexam-props"> for access method properties.
|
||||
(Note that extension access methods can define additional property names
|
||||
for their indexes.)
|
||||
</para>
|
||||
|
||||
<table id="functions-info-index-column-props">
|
||||
<title>Index Column Properties</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row><entry>Name</entry><entry>Description</entry></row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>asc</literal></entry>
|
||||
<entry>Does the column sort in ascending order on a forward scan?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>desc</literal></entry>
|
||||
<entry>Does the column sort in descending order on a forward scan?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>nulls_first</literal></entry>
|
||||
<entry>Does the column sort with nulls first on a forward scan?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>nulls_last</literal></entry>
|
||||
<entry>Does the column sort with nulls last on a forward scan?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>orderable</literal></entry>
|
||||
<entry>Does the column possess any defined sort ordering?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>distance_orderable</literal></entry>
|
||||
<entry>Can the column be scanned in order by a <quote>distance</>
|
||||
operator, for example <literal>ORDER BY col <-> constant</> ?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>returnable</literal></entry>
|
||||
<entry>Can the column value be returned by an index-only scan?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>search_array</literal></entry>
|
||||
<entry>Does the column natively support <literal>col = ANY(array)</>
|
||||
searches?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>search_nulls</literal></entry>
|
||||
<entry>Does the column support <literal>IS NULL</> and
|
||||
<literal>IS NOT NULL</> searches?
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table id="functions-info-index-props">
|
||||
<title>Index Properties</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row><entry>Name</entry><entry>Description</entry></row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>clusterable</literal></entry>
|
||||
<entry>Can the index be used in a <literal>CLUSTER</> command?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>index_scan</literal></entry>
|
||||
<entry>Does the index support plain (non-bitmap) scans?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>bitmap_scan</literal></entry>
|
||||
<entry>Does the index support bitmap scans?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>backward_scan</literal></entry>
|
||||
<entry>Can the index be scanned backwards?
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table id="functions-info-indexam-props">
|
||||
<title>Index Access Method Properties</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row><entry>Name</entry><entry>Description</entry></row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>can_order</literal></entry>
|
||||
<entry>Does the access method support <literal>ASC</>,
|
||||
<literal>DESC</> and related keywords in
|
||||
<literal>CREATE INDEX</>?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>can_unique</literal></entry>
|
||||
<entry>Does the access method support unique indexes?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>can_multi_col</literal></entry>
|
||||
<entry>Does the access method support indexes with multiple columns?
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>can_exclude</literal></entry>
|
||||
<entry>Does the access method support exclusion constraints?
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
<function>pg_options_to_table</function> returns the set of storage
|
||||
option name/value pairs
|
||||
|
@ -129,6 +129,7 @@ typedef struct IndexAmRoutine
|
||||
amcanreturn_function amcanreturn; /* can be NULL */
|
||||
amcostestimate_function amcostestimate;
|
||||
amoptions_function amoptions;
|
||||
amproperty_function amproperty; /* can be NULL */
|
||||
amvalidate_function amvalidate;
|
||||
ambeginscan_function ambeginscan;
|
||||
amrescan_function amrescan;
|
||||
@ -407,6 +408,55 @@ amoptions (ArrayType *reloptions,
|
||||
<para>
|
||||
<programlisting>
|
||||
bool
|
||||
amproperty (Oid index_oid, int attno,
|
||||
IndexAMProperty prop, const char *propname,
|
||||
bool *res, bool *isnull);
|
||||
</programlisting>
|
||||
The <function>amproperty</> method allows index access methods to override
|
||||
the default behavior of <function>pg_index_column_has_property</function>
|
||||
and related functions.
|
||||
If the access method does not have any special behavior for index property
|
||||
inquiries, the <structfield>amproperty</> field in
|
||||
its <structname>IndexAmRoutine</> struct can be set to NULL.
|
||||
Otherwise, the <function>amproperty</> method will be called with
|
||||
<parameter>index_oid</> and <parameter>attno</> both zero for
|
||||
<function>pg_indexam_has_property</function> calls,
|
||||
or with <parameter>index_oid</> valid and <parameter>attno</> zero for
|
||||
<function>pg_index_has_property</function> calls,
|
||||
or with <parameter>index_oid</> valid and <parameter>attno</> greater than
|
||||
zero for <function>pg_index_column_has_property</function> calls.
|
||||
<parameter>prop</> is an enum value identifying the property being tested,
|
||||
while <parameter>propname</> is the original property name string.
|
||||
If the core code does not recognize the property name
|
||||
then <parameter>prop</> is <literal>AMPROP_UNKNOWN</>.
|
||||
Access methods can define custom property names by
|
||||
checking <parameter>propname</> for a match (use <function>pg_strcasecmp</>
|
||||
to match, for consistency with the core code); for names known to the core
|
||||
code, it's better to inspect <parameter>prop</>.
|
||||
If the <structfield>amproperty</> method returns <literal>true</> then
|
||||
it has determined the property test result: it must set <literal>*res</>
|
||||
to the boolean value to return, or set <literal>*isnull</>
|
||||
to <literal>true</> to return a NULL. (Both of the referenced variables
|
||||
are initialized to <literal>false</> before the call.)
|
||||
If the <structfield>amproperty</> method returns <literal>false</> then
|
||||
the core code will proceed with its normal logic for determining the
|
||||
property test result.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Access methods that support ordering operators should
|
||||
implement <literal>AMPROP_DISTANCE_ORDERABLE</> property testing, as the
|
||||
core code does not know how to do that and will return NULL. It may
|
||||
also be advantageous to implement <literal>AMPROP_RETURNABLE</> testing,
|
||||
if that can be done more cheaply than by opening the index and calling
|
||||
<structfield>amcanreturn</>, which is the core code's default behavior.
|
||||
The default behavior should be satisfactory for all other standard
|
||||
properties.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
bool
|
||||
amvalidate (Oid opclassoid);
|
||||
</programlisting>
|
||||
Validate the catalog entries for the specified operator class, so far as
|
||||
|
Reference in New Issue
Block a user