インデックススキャンでは、スキャンキーに一致するものと示したすべてのタプルのTIDを吐き戻すことに関する責任をインデックスアクセスメソッドが持ちます。 アクセスメソッドには、実際のインデックスの親テーブルからのタプルの取り出しやタプルがスキャンの時間制限試験や他の条件を通過したかどうかの決定は含まれません。
スキャンキーは、index_key operator constantという形式のWHERE句の内部的表現です。 ここで、index_keyは、インデックス列の1つで、operatorはインデックス列に関連した演算子族の中の1つです。 インデックススキャンは、暗黙的にAND演算される0個以上のスキャンキーを持ちます。 返されるタプルは指定された条件を満たすものと想定されます。
アクセスメソッドはインデックスがある特定の問い合わせに対し非可逆、または再チェックを要求するか報告することができます。 これは、インデックススキャンがスキャンキーを渡す全ての項目と、そして加えるに、渡さない可能性のある追加項目を返します。中核システムのインデックススキャン機構はヒープタプルに対し、本当に選択されるべきかどうかを検証するためにその演算子をインデックス条件に再度適用します。 再検査オプションが指定されない場合、インデックススキャンは一致する項目の集合を返さなければなりません。
確実に、指定されたスキャンキーすべてに一致する項目を正確に、すべてかつ一致するもののみを見つけ出すことが、完全にアクセスメソッドの責任であることに注意してください。
また、中核システムは、冗長かどうかや矛盾するかどうかを決定するための意味的な解析を行わず、単にインデックスキーと演算子族に一致するWHERE句をすべて渡します。
例えば、
WHERE x > 4 AND x > 14があり、xがB-treeインデックス列であったとすると、
これは、B-tree amrescan
関数に渡され、最初のスキャンキーが冗長であると認知され、無視されることになります。
amrescan
における前処理の必要性は、
インデックスアクセスメソッドがスキャンキーを"正規化"形式にする必要があるかどうかに依存します。
一部のアクセスメソッドは、他のメソッドでは行いませんが、十分に定義された順序でインデックス項目を返します。 ソートされた順序で項目が返される場合、アクセスメソッドは順序付きスキャンをサポートすることを示すpg_am.amcanorderを真に設定しなければなりません。 こうしたアクセスメソッドはすべて、その等価性演算子と順序付け演算子に関してB-Tree互換の戦略番号を使用しなければなりません。
amgettuple
関数はdirection引数を持ちます。
ForwardScanDirection(通常の場合)またはBackwardScanDirectionのいずれかを取ることができます。
amrescan
後の最初の呼び出しがBackwardScanDirectionを指定していた場合、
一致したインデックス項目は通常の前から後ろという方向ではなく、後ろから前という方向でスキャンされます。
そのため、amgettuple
は
通常ならばインデックス内の最初に一致したタプルを返すところですが、最後に一致したタプルを返さなければなりません。
(これは順序付きスキャンをサポートするものと広告されたアクセスメソッドでのみ発生します。)
最初の呼び出しの後、amgettuple
は、最も最近に返された項目からどちらの方向にスキャンを進めるかを準備しなければなりません。(しかしpg_am.amcanbackwardが偽であれば、引き続く全ての呼び出しは最初のものと同じ道順を持ちます。
順序付けされたスキャンを提供するアクセスメソッドはスキャン内位置の"記録"をサポートしなければならず、また、後でその記録された位置に戻ることをサポートしなければなりません。
同じ位置が複数回記録されるかもしれません。
しかし、スキャン内の1つの位置のみを記録する必要があります。
新しいammarkpos
呼び出しにより前回記録された位置は上書きされます。順序付けされたスキャンを提供しないアクセスメソッドは、pg_am内で印付けとリストア関数を依然として提供しますが、呼ばれた場合、それらがエラーを投げるのに間に合います。
スキャン位置と記録された位置(もしあれば)の両方は、インデックス内の同時挿入や削除という観点における一貫性を保持しなければなりません。 スキャンが始まった時に存在していた場合、項目を見つけ出したスキャンが新しく挿入された項目を返さなかったとしても問題ありません。 このような場合のスキャンでは、再スキャンやバックアップによって、あたかも最初の時点で返されたものとして項目が返されます。 同様に、同時実行削除によってスキャンの結果に影響が出るかもしれません。 重要なことは、挿入や削除によってスキャンが返す項目において、その項目自体が挿入・削除されていない項目が失われたり二重になったりすることが起こらないという点です。
amgettuple
を使用する代わりに、amgetbitmap
を使用して、一回の呼出しで全てのタプルを取り出してインデックススキャンを行うことができます。
これはアクセスメソッド内でのロック・ロック解除という過程を防ぐことができますので、amgettuple
よりもかなり効率的です。
実際には、amgetbitmap
はamgettuple
呼び出しを繰り返すことと同じ効果を持つはずですが、物事を単純化するために複数の制限を加えています。
まず第一に、amgetbitmap
は一回で全てのタプルを返し、提供されていないスキャン位置を印付けまたはリストアします。第二に、なんら特定の順序付けを持たないビットマップの中にタプルが返されます。これは何でamgetbitmap
がdirection引数を取らないかという理由です。
最後に、amgetbitmap
は返されたタプルに関し、項50.4に記載した意味でのロックを保証しません。
アクセスメソッドがamgettuple
ではなくamgetbitmap
のみの実装を認められていて、逆もまた同様にその内部実装が1つのAPIかもう一方のいずれかに目的がそぐわない場合のみの実装が認められます。