1
0
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 commit
65c5fcd35).  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 commit 473b93287.

Andrew Gierth, with kibitzing by me and others

Discussion: <87mvl5on7n.fsf@news-spur.riddles.org.uk>
This commit is contained in:
Tom Lane
2016-08-13 18:31:14 -04:00
parent 4997878193
commit ed0097e4f9
28 changed files with 1146 additions and 18 deletions

View File

@ -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>

View File

@ -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 &lt;-&gt; 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

View File

@ -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