Skip to content

Commit 473b932

Browse files
committed
Support CREATE ACCESS METHOD
This enables external code to create access methods. This is useful so that extensions can add their own access methods which can be formally tracked for dependencies, so that DROP operates correctly. Also, having explicit support makes pg_dump work correctly. Currently only index AMs are supported, but we expect different types to be added in the future. Authors: Alexander Korotkov, Petr Jelínek Reviewed-By: Teodor Sigaev, Petr Jelínek, Jim Nasby Commitfest-URL: https://commitfest.postgresql.org/9/353/ Discussion: https://www.postgresql.org/message-id/CAPpHfdsXwZmojm6Dx+TJnpYk27kT4o7Ri6X_4OSWcByu1Rm+VA@mail.gmail.com
1 parent 2c6af4f commit 473b932

37 files changed

+1150
-101
lines changed

doc/src/sgml/indexam.sgml

+6
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
to insert an appropriate row for themselves.
5858
</para>
5959

60+
<para>
61+
Index access access methods can be defined and dropped using
62+
<xref linkend="sql-create-access-method"> and
63+
<xref linkend="sql-drop-access-method"> SQL commands respectively.
64+
</para>
65+
6066
<para>
6167
An index access method handler function must be declared to accept a
6268
single argument of type <type>internal</> and to return the

doc/src/sgml/ref/allfiles.sgml

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Complete list of usable sgml source files in this directory.
5252
<!ENTITY commit SYSTEM "commit.sgml">
5353
<!ENTITY commitPrepared SYSTEM "commit_prepared.sgml">
5454
<!ENTITY copyTable SYSTEM "copy.sgml">
55+
<!ENTITY createAccessMethod SYSTEM "create_access_method.sgml">
5556
<!ENTITY createAggregate SYSTEM "create_aggregate.sgml">
5657
<!ENTITY createCast SYSTEM "create_cast.sgml">
5758
<!ENTITY createCollation SYSTEM "create_collation.sgml">
@@ -94,6 +95,7 @@ Complete list of usable sgml source files in this directory.
9495
<!ENTITY delete SYSTEM "delete.sgml">
9596
<!ENTITY discard SYSTEM "discard.sgml">
9697
<!ENTITY do SYSTEM "do.sgml">
98+
<!ENTITY dropAccessMethod SYSTEM "drop_access_method.sgml">
9799
<!ENTITY dropAggregate SYSTEM "drop_aggregate.sgml">
98100
<!ENTITY dropCast SYSTEM "drop_cast.sgml">
99101
<!ENTITY dropCollation SYSTEM "drop_collation.sgml">
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<!--
2+
doc/src/sgml/ref/create_access_method.sgml
3+
PostgreSQL documentation
4+
-->
5+
6+
<refentry id="sql-create-access-method">
7+
<indexterm zone="sql-create-access-method">
8+
<primary>CREATE ACCESS METHOD</primary>
9+
</indexterm>
10+
11+
<refmeta>
12+
<refentrytitle>CREATE ACCESS METHOD</refentrytitle>
13+
<manvolnum>7</manvolnum>
14+
<refmiscinfo>SQL - Language Statements</refmiscinfo>
15+
</refmeta>
16+
17+
<refnamediv>
18+
<refname>CREATE ACCESS METHOD</refname>
19+
<refpurpose>define a new access method</refpurpose>
20+
</refnamediv>
21+
22+
<refsynopsisdiv>
23+
<synopsis>
24+
CREATE ACCESS METHOD <replaceable class="parameter">name</replaceable>
25+
TYPE <replaceable class="parameter">access_method_type</replaceable>
26+
HANDLER <replaceable class="parameter">handler_function</replaceable>
27+
</synopsis>
28+
</refsynopsisdiv>
29+
30+
<refsect1>
31+
<title>Description</title>
32+
33+
<para>
34+
<command>CREATE ACCESS METHOD</command> creates a new access method.
35+
</para>
36+
37+
<para>
38+
The access method name must be unique within the database.
39+
</para>
40+
41+
<para>
42+
Only superusers can define new access methods.
43+
</para>
44+
</refsect1>
45+
46+
<refsect1>
47+
<title>Parameters</title>
48+
49+
<variablelist>
50+
<varlistentry>
51+
<term><replaceable class="parameter">name</replaceable></term>
52+
<listitem>
53+
<para>
54+
The name of the access method to be created.
55+
</para>
56+
</listitem>
57+
</varlistentry>
58+
59+
<varlistentry>
60+
<term><literal>access_method_type</literal></term>
61+
<listitem>
62+
<para>
63+
This clause specifies type of access method to define.
64+
Only <literal>INDEX</literal> is supported at present.
65+
</para>
66+
</listitem>
67+
</varlistentry>
68+
69+
<varlistentry>
70+
<term><literal>HANDLER <replaceable class="parameter">handler_function</replaceable></literal></term>
71+
<listitem>
72+
<para><replaceable class="parameter">handler_function</replaceable> is the
73+
name of a previously registered function that will be called to
74+
retrieve the struct which contains required parameters and functions
75+
of access method to the core. The handler function must take single
76+
argument of type <type>internal</>, and its return type depends on the
77+
type of access method; for <literal>INDEX</literal> access methods, it
78+
must be <type>index_am_handler</type>.
79+
</para>
80+
81+
<para>
82+
See <xref linkend="index-api"> for index access methods API.
83+
</para>
84+
</listitem>
85+
</varlistentry>
86+
</variablelist>
87+
</refsect1>
88+
89+
<refsect1>
90+
<title>Examples</title>
91+
92+
<para>
93+
Create an access method <literal>heptree</> with
94+
handler function <literal>heptree_handler</>:
95+
<programlisting>
96+
CREATE ACCESS METHOD heptree TYPE INDEX HANDLER heptree_handler;
97+
</programlisting>
98+
</para>
99+
</refsect1>
100+
101+
<refsect1>
102+
<title>Compatibility</title>
103+
104+
<para>
105+
<command>CREATE ACCESS METHOD</command> is a
106+
<productname>PostgreSQL</> extension.
107+
</para>
108+
</refsect1>
109+
110+
<refsect1>
111+
<title>See Also</title>
112+
113+
<simplelist type="inline">
114+
<member><xref linkend="sql-drop-access-method"></member>
115+
<member><xref linkend="sql-createopclass"></member>
116+
<member><xref linkend="sql-createopfamily"></member>
117+
</simplelist>
118+
</refsect1>
119+
120+
</refentry>
+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!--
2+
doc/src/sgml/ref/drop_access_method.sgml
3+
PostgreSQL documentation
4+
-->
5+
6+
<refentry id="sql-drop-access-method">
7+
<indexterm zone="sql-drop-access-method">
8+
<primary>DROP ACCESS METHOD</primary>
9+
</indexterm>
10+
11+
<refmeta>
12+
<refentrytitle>DROP ACCESS METHOD</refentrytitle>
13+
<manvolnum>7</manvolnum>
14+
<refmiscinfo>SQL - Language Statements</refmiscinfo>
15+
</refmeta>
16+
17+
<refnamediv>
18+
<refname>DROP ACCESS METHOD</refname>
19+
<refpurpose>remove an access method</refpurpose>
20+
</refnamediv>
21+
22+
<refsynopsisdiv>
23+
<synopsis>
24+
DROP ACCESS METHOD [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
25+
</synopsis>
26+
</refsynopsisdiv>
27+
28+
<refsect1>
29+
<title>Description</title>
30+
31+
<para>
32+
<command>DROP ACCESS METHOD</command> removes an existing access method.
33+
Only superusers can drop access methods.
34+
</para>
35+
36+
<para>
37+
</para>
38+
</refsect1>
39+
40+
<refsect1>
41+
<title>Parameters</title>
42+
43+
<variablelist>
44+
<varlistentry>
45+
<term><literal>IF EXISTS</literal></term>
46+
<listitem>
47+
<para>
48+
Do not throw an error if the access method does not exist.
49+
A notice is issued in this case.
50+
</para>
51+
</listitem>
52+
</varlistentry>
53+
54+
<varlistentry>
55+
<term><replaceable class="parameter">name</replaceable></term>
56+
<listitem>
57+
<para>
58+
The name of an existing access method.
59+
</para>
60+
</listitem>
61+
</varlistentry>
62+
63+
<varlistentry>
64+
<term><literal>CASCADE</literal></term>
65+
<listitem>
66+
<para>
67+
Automatically drop objects that depend on the access method
68+
(such as operator classes, operator families, indexes).
69+
</para>
70+
</listitem>
71+
</varlistentry>
72+
73+
<varlistentry>
74+
<term><literal>RESTRICT</literal></term>
75+
<listitem>
76+
<para>
77+
Refuse to drop the access method if any objects depend on it.
78+
This is the default.
79+
</para>
80+
</listitem>
81+
</varlistentry>
82+
</variablelist>
83+
</refsect1>
84+
85+
<refsect1>
86+
<title>Examples</title>
87+
88+
<para>
89+
Drop the access method <literal>heptree</>:
90+
<programlisting>
91+
DROP ACCESS METHOD heptree;
92+
</programlisting></para>
93+
</refsect1>
94+
95+
<refsect1>
96+
<title>Compatibility</title>
97+
98+
<para>
99+
<command>DROP ACCESS METHOD</command> is a
100+
<productname>PostgreSQL</> extension.
101+
</para>
102+
</refsect1>
103+
104+
<refsect1>
105+
<title>See Also</title>
106+
107+
<simplelist type="inline">
108+
<member><xref linkend="sql-create-access-method"></member>
109+
</simplelist>
110+
</refsect1>
111+
112+
</refentry>

doc/src/sgml/reference.sgml

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
&commit;
8181
&commitPrepared;
8282
&copyTable;
83+
&createAccessMethod;
8384
&createAggregate;
8485
&createCast;
8586
&createCollation;
@@ -122,6 +123,7 @@
122123
&delete;
123124
&discard;
124125
&do;
126+
&dropAccessMethod;
125127
&dropAggregate;
126128
&dropCast;
127129
&dropCollation;

src/backend/access/index/amapi.c

+7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ GetIndexAmRoutineByAmId(Oid amoid)
6262
amoid);
6363
amform = (Form_pg_am) GETSTRUCT(tuple);
6464

65+
/* Check if it's index access method */
66+
if (amform->amtype != AMTYPE_INDEX)
67+
ereport(ERROR,
68+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
69+
errmsg("access method \"%s\" is not of type %s",
70+
NameStr(amform->amname), "INDEX")));
71+
6572
amhandler = amform->amhandler;
6673

6774
/* Complain if handler OID is invalid */

src/backend/catalog/dependency.c

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "catalog/heap.h"
2121
#include "catalog/index.h"
2222
#include "catalog/objectaccess.h"
23+
#include "catalog/pg_am.h"
2324
#include "catalog/pg_amop.h"
2425
#include "catalog/pg_amproc.h"
2526
#include "catalog/pg_attrdef.h"
@@ -141,6 +142,7 @@ static const Oid object_classes[] = {
141142
OperatorRelationId, /* OCLASS_OPERATOR */
142143
OperatorClassRelationId, /* OCLASS_OPCLASS */
143144
OperatorFamilyRelationId, /* OCLASS_OPFAMILY */
145+
AccessMethodRelationId, /* OCLASS_AM */
144146
AccessMethodOperatorRelationId, /* OCLASS_AMOP */
145147
AccessMethodProcedureRelationId, /* OCLASS_AMPROC */
146148
RewriteRelationId, /* OCLASS_REWRITE */
@@ -1199,6 +1201,10 @@ doDeletion(const ObjectAddress *object, int flags)
11991201
RemoveOpFamilyById(object->objectId);
12001202
break;
12011203

1204+
case OCLASS_AM:
1205+
RemoveAccessMethodById(object->objectId);
1206+
break;
1207+
12021208
case OCLASS_AMOP:
12031209
RemoveAmOpEntryById(object->objectId);
12041210
break;
@@ -2356,6 +2362,9 @@ getObjectClass(const ObjectAddress *object)
23562362
case OperatorFamilyRelationId:
23572363
return OCLASS_OPFAMILY;
23582364

2365+
case AccessMethodRelationId:
2366+
return OCLASS_AM;
2367+
23592368
case AccessMethodOperatorRelationId:
23602369
return OCLASS_AMOP;
23612370

0 commit comments

Comments
 (0)