Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a78fcfb

Browse files
committed
Restructure operator classes to allow improved handling of cross-data-type
cases. Operator classes now exist within "operator families". While most families are equivalent to a single class, related classes can be grouped into one family to represent the fact that they are semantically compatible. Cross-type operators are now naturally adjunct parts of a family, without having to wedge them into a particular opclass as we had done originally. This commit restructures the catalogs and cleans up enough of the fallout so that everything still works at least as well as before, but most of the work needed to actually improve the planner's behavior will come later. Also, there are not yet CREATE/DROP/ALTER OPERATOR FAMILY commands; the only way to create a new family right now is to allow CREATE OPERATOR CLASS to make one by default. I owe some more documentation work, too. But that can all be done in smaller pieces once this infrastructure is in place.
1 parent d31ccb6 commit a78fcfb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+4794
-4141
lines changed

contrib/intarray/_int.sql.in

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,9 @@ AS
459459

460460
--GIN
461461
--mark built-in gin's _int4_ops as non default
462-
update pg_opclass set opcdefault = 'f' where
463-
pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and
464-
opcname = '_int4_ops';
462+
update pg_catalog.pg_opclass set opcdefault = 'f'
463+
where opcmethod = (select oid from pg_catalog.pg_am where amname='gin') and
464+
opcname = '_int4_ops';
465465

466466
CREATE FUNCTION ginint4_queryextract(internal, internal, int2)
467467
RETURNS internal

contrib/intarray/uninstall__int.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ DROP FUNCTION querytree(query_int);
124124

125125
DROP TYPE query_int CASCADE;
126126

127-
update pg_opclass set opcdefault = 't' where
128-
pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and
129-
opcname = '_int4_ops';
130-
127+
--mark built-in gin's _int4_ops as default again
128+
update pg_catalog.pg_opclass set opcdefault = 't'
129+
where opcmethod = (select oid from pg_catalog.pg_am where amname='gin') and
130+
opcname = '_int4_ops';

doc/src/sgml/catalogs.sgml

Lines changed: 173 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.138 2006/12/18 18:56:28 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.139 2006/12/23 00:43:08 tgl Exp $ -->
22
<!--
33
Documentation of the system catalogs, directed toward PostgreSQL developers
44
-->
@@ -160,14 +160,19 @@
160160

161161
<row>
162162
<entry><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link></entry>
163-
<entry>index access method operator classes</entry>
163+
<entry>access method operator classes</entry>
164164
</row>
165165

166166
<row>
167167
<entry><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link></entry>
168168
<entry>operators</entry>
169169
</row>
170170

171+
<row>
172+
<entry><link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link></entry>
173+
<entry>access method operator families</entry>
174+
</row>
175+
171176
<row>
172177
<entry><link linkend="catalog-pg-pltemplate"><structname>pg_pltemplate</structname></link></entry>
173178
<entry>template data for procedural languages</entry>
@@ -516,9 +521,11 @@
516521
</indexterm>
517522

518523
<para>
519-
The catalog <structname>pg_amop</structname> stores information about operators
520-
associated with index access method operator classes. There is one
521-
row for each operator that is a member of an operator class.
524+
The catalog <structname>pg_amop</structname> stores information about
525+
operators associated with access method operator families. There is one
526+
row for each operator that is a member of an operator family. An operator
527+
can appear in more than one family, but may not appear in more than one
528+
position within a family.
522529
</para>
523530

524531
<table>
@@ -536,18 +543,24 @@
536543
<tbody>
537544

538545
<row>
539-
<entry><structfield>amopclaid</structfield></entry>
546+
<entry><structfield>amopfamily</structfield></entry>
540547
<entry><type>oid</type></entry>
541-
<entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
542-
<entry>The index operator class this entry is for</entry>
548+
<entry><literal><link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.oid</literal></entry>
549+
<entry>The operator family this entry is for</entry>
543550
</row>
544551

545552
<row>
546-
<entry><structfield>amopsubtype</structfield></entry>
553+
<entry><structfield>amoplefttype</structfield></entry>
547554
<entry><type>oid</type></entry>
548555
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
549-
<entry>Subtype to distinguish multiple entries for one strategy;
550-
zero for default</entry>
556+
<entry>Left-hand input data type of operator</entry>
557+
</row>
558+
559+
<row>
560+
<entry><structfield>amoprighttype</structfield></entry>
561+
<entry><type>oid</type></entry>
562+
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
563+
<entry>Right-hand input data type of operator</entry>
551564
</row>
552565

553566
<row>
@@ -571,10 +584,27 @@
571584
<entry>OID of the operator</entry>
572585
</row>
573586

587+
<row>
588+
<entry><structfield>amopmethod</structfield></entry>
589+
<entry><type>oid</type></entry>
590+
<entry><literal><link linkend="catalog-pg-am"><structname>pg_am</structname></link>.oid</literal></entry>
591+
<entry>Index access method operator family is for</entry>
592+
</row>
593+
574594
</tbody>
575595
</tgroup>
576596
</table>
577597

598+
<para>
599+
An entry's <structfield>amopmethod</> must match the
600+
<structname>opfmethod</> of its containing operator family (including
601+
<structfield>amopmethod</> here is an intentional denormalization of the
602+
catalog structure for performance reasons). Also,
603+
<structfield>amoplefttype</> and <structfield>amoprighttype</> must match
604+
the <structfield>oprleft</> and <structfield>oprright</> fields of the
605+
referenced <structname>pg_operator</> entry.
606+
</para>
607+
578608
</sect1>
579609

580610

@@ -586,10 +616,9 @@
586616
</indexterm>
587617

588618
<para>
589-
The catalog <structname>pg_amproc</structname> stores information about support
590-
procedures
591-
associated with index access method operator classes. There is one
592-
row for each support procedure belonging to an operator class.
619+
The catalog <structname>pg_amproc</structname> stores information about
620+
support procedures associated with access method operator families. There
621+
is one row for each support procedure belonging to an operator family.
593622
</para>
594623

595624
<table>
@@ -607,17 +636,24 @@
607636
<tbody>
608637

609638
<row>
610-
<entry><structfield>amopclaid</structfield></entry>
639+
<entry><structfield>amprocfamily</structfield></entry>
611640
<entry><type>oid</type></entry>
612-
<entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
613-
<entry>The index operator class this entry is for</entry>
641+
<entry><literal><link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.oid</literal></entry>
642+
<entry>The operator family this entry is for</entry>
643+
</row>
644+
645+
<row>
646+
<entry><structfield>amproclefttype</structfield></entry>
647+
<entry><type>oid</type></entry>
648+
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
649+
<entry>Left-hand input data type of associated operator</entry>
614650
</row>
615651

616652
<row>
617-
<entry><structfield>amprocsubtype</structfield></entry>
653+
<entry><structfield>amprocrighttype</structfield></entry>
618654
<entry><type>oid</type></entry>
619655
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
620-
<entry>Subtype, if cross-type routine, else zero</entry>
656+
<entry>Right-hand input data type of associated operator</entry>
621657
</row>
622658

623659
<row>
@@ -638,6 +674,18 @@
638674
</tgroup>
639675
</table>
640676

677+
<para>
678+
The usual interpretation of the
679+
<structfield>amproclefttype</> and <structfield>amprocrighttype</> fields
680+
is that they identify the left and right input types of the operator(s)
681+
that a particular support procedure supports. For some access methods
682+
these match the input data type(s) of the support procedure itself, for
683+
others not. There is a notion of <quote>default</> support procedures for
684+
an index, which are those with <structfield>amproclefttype</> and
685+
<structfield>amprocrighttype</> both equal to the index opclass's
686+
<structfield>opcintype</>.
687+
</para>
688+
641689
</sect1>
642690

643691

@@ -2843,9 +2891,11 @@
28432891
The catalog <structname>pg_opclass</structname> defines
28442892
index access method operator classes. Each operator class defines
28452893
semantics for index columns of a particular data type and a particular
2846-
index access method. Note that there can be multiple operator classes
2847-
for a given data type/access method combination, thus supporting multiple
2848-
behaviors.
2894+
index access method. An operator class essentially specifies that a
2895+
particular operator family is applicable to a particular indexable column
2896+
data type. The set of operators from the family that are actually usable
2897+
with the indexed column are whichever ones accept the column's data type
2898+
as their lefthand input.
28492899
</para>
28502900

28512901
<para>
@@ -2867,7 +2917,7 @@
28672917
<tbody>
28682918

28692919
<row>
2870-
<entry><structfield>opcamid</structfield></entry>
2920+
<entry><structfield>opcmethod</structfield></entry>
28712921
<entry><type>oid</type></entry>
28722922
<entry><literal><link linkend="catalog-pg-am"><structname>pg_am</structname></link>.oid</literal></entry>
28732923
<entry>Index access method operator class is for</entry>
@@ -2894,6 +2944,13 @@
28942944
<entry>Owner of the operator class</entry>
28952945
</row>
28962946

2947+
<row>
2948+
<entry><structfield>opcfamily</structfield></entry>
2949+
<entry><type>oid</type></entry>
2950+
<entry><literal><link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.oid</literal></entry>
2951+
<entry>Operator family containing the operator class</entry>
2952+
</row>
2953+
28972954
<row>
28982955
<entry><structfield>opcintype</structfield></entry>
28992956
<entry><type>oid</type></entry>
@@ -2920,14 +2977,11 @@
29202977
</table>
29212978

29222979
<para>
2923-
The majority of the information defining an operator class is actually
2924-
not in its <structname>pg_opclass</structname> row, but in the associated
2925-
rows in <structname>pg_amop</structname> and
2926-
<structname>pg_amproc</structname>. Those rows are considered to be
2927-
part of the operator class definition &mdash; this is not unlike the way
2928-
that a relation is defined by a single <structname>pg_class</structname>
2929-
row plus associated rows in <structname>pg_attribute</structname> and
2930-
other tables.
2980+
An operator class's <structfield>opcmethod</> must match the
2981+
<structname>opfmethod</> of its containing operator family.
2982+
Also, there must be no more than one <structname>pg_opclass</structname>
2983+
row having <structname>opcdefault</> true for any given combination of
2984+
<structname>opcmethod</> and <structname>opcintype</>.
29312985
</para>
29322986

29332987
</sect1>
@@ -2993,6 +3047,13 @@
29933047
</entry>
29943048
</row>
29953049

3050+
<row>
3051+
<entry><structfield>oprcanmerge</structfield></entry>
3052+
<entry><type>bool</type></entry>
3053+
<entry></entry>
3054+
<entry>This operator supports merge joins</entry>
3055+
</row>
3056+
29963057
<row>
29973058
<entry><structfield>oprcanhash</structfield></entry>
29983059
<entry><type>bool</type></entry>
@@ -3035,46 +3096,6 @@
30353096
<entry>Negator of this operator, if any</entry>
30363097
</row>
30373098

3038-
<row>
3039-
<entry><structfield>oprlsortop</structfield></entry>
3040-
<entry><type>oid</type></entry>
3041-
<entry><literal><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.oid</literal></entry>
3042-
<entry>
3043-
If this operator supports merge joins, the operator that sorts
3044-
the type of the left-hand operand (<literal>L&lt;L</>)
3045-
</entry>
3046-
</row>
3047-
3048-
<row>
3049-
<entry><structfield>oprrsortop</structfield></entry>
3050-
<entry><type>oid</type></entry>
3051-
<entry><literal><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.oid</literal></entry>
3052-
<entry>
3053-
If this operator supports merge joins, the operator that sorts
3054-
the type of the right-hand operand (<literal>R&lt;R</>)
3055-
</entry>
3056-
</row>
3057-
3058-
<row>
3059-
<entry><structfield>oprltcmpop</structfield></entry>
3060-
<entry><type>oid</type></entry>
3061-
<entry><literal><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.oid</literal></entry>
3062-
<entry>
3063-
If this operator supports merge joins, the less-than operator that
3064-
compares the left and right operand types (<literal>L&lt;R</>)
3065-
</entry>
3066-
</row>
3067-
3068-
<row>
3069-
<entry><structfield>oprgtcmpop</structfield></entry>
3070-
<entry><type>oid</type></entry>
3071-
<entry><literal><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.oid</literal></entry>
3072-
<entry>
3073-
If this operator supports merge joins, the greater-than operator that
3074-
compares the left and right operand types (<literal>L&gt;R</>)
3075-
</entry>
3076-
</row>
3077-
30783099
<row>
30793100
<entry><structfield>oprcode</structfield></entry>
30803101
<entry><type>regproc</type></entry>
@@ -3107,6 +3128,86 @@
31073128
</sect1>
31083129

31093130

3131+
<sect1 id="catalog-pg-opfamily">
3132+
<title><structname>pg_opfamily</structname></title>
3133+
3134+
<indexterm zone="catalog-pg-opfamily">
3135+
<primary>pg_opfamily</primary>
3136+
</indexterm>
3137+
3138+
<para>
3139+
The catalog <structname>pg_opfamily</structname> defines operator families.
3140+
Each operator family is a collection of operators and associated
3141+
support routines that implement the semantics specified for a particular
3142+
index access method. Furthermore, the operators in a family are all
3143+
<quote>compatible</>, in a way that depends on the access method.
3144+
The operator family concept allows cross-data-type operators to be used
3145+
with indexes and to be reasoned about using knowledge of access method
3146+
semantics.
3147+
</para>
3148+
3149+
<para>
3150+
Operator families are described at length in <xref linkend="xindex">.
3151+
</para>
3152+
3153+
<table>
3154+
<title><structname>pg_opfamily</> Columns</title>
3155+
3156+
<tgroup cols=4>
3157+
<thead>
3158+
<row>
3159+
<entry>Name</entry>
3160+
<entry>Type</entry>
3161+
<entry>References</entry>
3162+
<entry>Description</entry>
3163+
</row>
3164+
</thead>
3165+
<tbody>
3166+
3167+
<row>
3168+
<entry><structfield>opfmethod</structfield></entry>
3169+
<entry><type>oid</type></entry>
3170+
<entry><literal><link linkend="catalog-pg-am"><structname>pg_am</structname></link>.oid</literal></entry>
3171+
<entry>Index access method operator family is for</entry>
3172+
</row>
3173+
3174+
<row>
3175+
<entry><structfield>opfname</structfield></entry>
3176+
<entry><type>name</type></entry>
3177+
<entry></entry>
3178+
<entry>Name of this operator family</entry>
3179+
</row>
3180+
3181+
<row>
3182+
<entry><structfield>opfnamespace</structfield></entry>
3183+
<entry><type>oid</type></entry>
3184+
<entry><literal><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.oid</literal></entry>
3185+
<entry>Namespace of this operator family</entry>
3186+
</row>
3187+
3188+
<row>
3189+
<entry><structfield>opfowner</structfield></entry>
3190+
<entry><type>oid</type></entry>
3191+
<entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
3192+
<entry>Owner of the operator family</entry>
3193+
</row>
3194+
3195+
</tbody>
3196+
</tgroup>
3197+
</table>
3198+
3199+
<para>
3200+
The majority of the information defining an operator family is not in its
3201+
<structname>pg_opfamily</structname> row, but in the associated rows in
3202+
<link linkend="catalog-pg-amop"><structname>pg_amop</structname></link>,
3203+
<link linkend="catalog-pg-amproc"><structname>pg_amproc</structname></link>,
3204+
and
3205+
<link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.
3206+
</para>
3207+
3208+
</sect1>
3209+
3210+
31103211
<sect1 id="catalog-pg-pltemplate">
31113212
<title><structname>pg_pltemplate</structname></title>
31123213

0 commit comments

Comments
 (0)