1
- <!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.30 2009/03/24 20:17:08 tgl Exp $ -->
1
+ <!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.31 2009/07/29 20:56:17 tgl Exp $ -->
2
2
3
3
<chapter id="indexam">
4
4
<title>Index Access Method Interface Definition</title>
@@ -172,20 +172,32 @@ aminsert (Relation indexRelation,
172
172
bool *isnull,
173
173
ItemPointer heap_tid,
174
174
Relation heapRelation,
175
- bool check_uniqueness );
175
+ IndexUniqueCheck checkUnique );
176
176
</programlisting>
177
177
Insert a new tuple into an existing index. The <literal>values</> and
178
178
<literal>isnull</> arrays give the key values to be indexed, and
179
179
<literal>heap_tid</> is the TID to be indexed.
180
180
If the access method supports unique indexes (its
181
181
<structname>pg_am</>.<structfield>amcanunique</> flag is true) then
182
- <literal>check_uniqueness</> might be true, in which case the access method
183
- must verify that there is no conflicting row; this is the only situation in
184
- which the access method normally needs the <literal>heapRelation</>
185
- parameter. See <xref linkend="index-unique-checks"> for details.
186
- The result is TRUE if an index entry was inserted, FALSE if not. (A FALSE
187
- result does not denote an error condition, but is used for cases such
188
- as an index method refusing to index a NULL.)
182
+ <literal>checkUnique</> indicates the type of uniqueness check to
183
+ perform. This varies depending on whether the unique constraint is
184
+ deferrable; see <xref linkend="index-unique-checks"> for details.
185
+ Normally the access method only needs the <literal>heapRelation</>
186
+ parameter when performing uniqueness checking (since then it will have to
187
+ look into the heap to verify tuple liveness).
188
+ </para>
189
+
190
+ <para>
191
+ The function's boolean result value is significant only when
192
+ <literal>checkUnique</> is <literal>UNIQUE_CHECK_PARTIAL</>.
193
+ In this case a TRUE result means the new entry is known unique, whereas
194
+ FALSE means it might be non-unique (and a deferred uniqueness check must
195
+ be scheduled). For other cases a constant FALSE result is recommended.
196
+ </para>
197
+
198
+ <para>
199
+ Some indexes might not index all tuples. If the tuple is not to be
200
+ indexed, <function>aminsert</> should just return without doing anything.
189
201
</para>
190
202
191
203
<para>
@@ -706,10 +718,10 @@ amrestrpos (IndexScanDesc scan);
706
718
</para>
707
719
708
720
<para>
709
- Furthermore, immediately before raising a uniqueness violation
721
+ Furthermore, immediately before reporting a uniqueness violation
710
722
according to the above rules, the access method must recheck the
711
723
liveness of the row being inserted. If it is committed dead then
712
- no error should be raised . (This case cannot occur during the
724
+ no violation should be reported . (This case cannot occur during the
713
725
ordinary scenario of inserting a row that's just been created by
714
726
the current transaction. It can happen during
715
727
<command>CREATE UNIQUE INDEX CONCURRENTLY</>, however.)
@@ -728,8 +740,78 @@ amrestrpos (IndexScanDesc scan);
728
740
</para>
729
741
730
742
<para>
731
- The main limitation of this scheme is that it has no convenient way
732
- to support deferred uniqueness checks.
743
+ If the unique constraint is deferrable, there is additional complexity:
744
+ we need to be able to insert an index entry for a new row, but defer any
745
+ uniqueness-violation error until end of statement or even later. To
746
+ avoid unnecessary repeat searches of the index, the index access method
747
+ should do a preliminary uniqueness check during the initial insertion.
748
+ If this shows that there is definitely no conflicting live tuple, we
749
+ are done. Otherwise, we schedule a recheck to occur when it is time to
750
+ enforce the constraint. If, at the time of the recheck, both the inserted
751
+ tuple and some other tuple with the same key are live, then the error
752
+ must be reported. (Note that for this purpose, <quote>live</> actually
753
+ means <quote>any tuple in the index entry's HOT chain is live</>.)
754
+ To implement this, the <function>aminsert</> function is passed a
755
+ <literal>checkUnique</> parameter having one of the following values:
756
+
757
+ <itemizedlist>
758
+ <listitem>
759
+ <para>
760
+ <literal>UNIQUE_CHECK_NO</> indicates that no uniqueness checking
761
+ should be done (this is not a unique index).
762
+ </para>
763
+ </listitem>
764
+ <listitem>
765
+ <para>
766
+ <literal>UNIQUE_CHECK_YES</> indicates that this is a non-deferrable
767
+ unique index, and the uniqueness check must be done immediately, as
768
+ described above.
769
+ </para>
770
+ </listitem>
771
+ <listitem>
772
+ <para>
773
+ <literal>UNIQUE_CHECK_PARTIAL</> indicates that the unique
774
+ constraint is deferrable. <productname>PostgreSQL</productname>
775
+ will use this mode to insert each row's index entry. The access
776
+ method must allow duplicate entries into the index, and report any
777
+ potential duplicates by returning FALSE from <function>aminsert</>.
778
+ For each row for which FALSE is returned, a deferred recheck will
779
+ be scheduled.
780
+ </para>
781
+
782
+ <para>
783
+ The access method must identify any rows which might violate the
784
+ unique constraint, but it is not an error for it to report false
785
+ positives. This allows the check to be done without waiting for other
786
+ transactions to finish; conflicts reported here are not treated as
787
+ errors and will be rechecked later, by which time they may no longer
788
+ be conflicts.
789
+ </para>
790
+ </listitem>
791
+ <listitem>
792
+ <para>
793
+ <literal>UNIQUE_CHECK_EXISTING</> indicates that this is a deferred
794
+ recheck of a row that was reported as a potential uniqueness violation.
795
+ Although this is implemented by calling <function>aminsert</>, the
796
+ access method must <emphasis>not</> insert a new index entry in this
797
+ case. The index entry is already present. Rather, the access method
798
+ must check to see if there is another live index entry. If so, and
799
+ if the target row is also still live, report error.
800
+ </para>
801
+
802
+ <para>
803
+ It is recommended that in a <literal>UNIQUE_CHECK_EXISTING</> call,
804
+ the access method further verify that the target row actually does
805
+ have an existing entry in the index, and report error if not. This
806
+ is a good idea because the index tuple values passed to
807
+ <function>aminsert</> will have been recomputed. If the index
808
+ definition involves functions that are not really immutable, we
809
+ might be checking the wrong area of the index. Checking that the
810
+ target row is found in the recheck verifies that we are scanning
811
+ for the same tuple values as were used in the original insertion.
812
+ </para>
813
+ </listitem>
814
+ </itemizedlist>
733
815
</para>
734
816
735
817
</sect1>
0 commit comments