無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

38.1. 問い合わせツリーとは

どのようにルールシステムが機能するかを理解するためには、ルールがどのように起動され、その入力と結果は何かを理解しなければなりません。

ルールシステムは問い合わせパーサとプランナの中間に位置します。 ルールシステムは、入力としてパーサの出力、単一の問い合わせツリー、および何らかの特別な情報を持つ問い合わせツリーでもあるユーザ定義の書き換えルールを取り、結果として0個以上の問い合わせツリーを生成します。 ルールシステムの入力と出力は常にパーサ自体でも生成することができるもので、参照する対象は基本的に SQL 文として表現できるものです。

では問い合わせツリーとは何でしょうか。 それは、 SQL 文を構成する個々の部品を別々に記憶した、 SQL 文の内部表現です。 debug_print_parse debug_print_rewritten 、もしくは debug_print_plan 設定パラメータを設定していれば、サーバログ内で問い合わせツリーを見ることができます。 ルールアクションも pg_rewrite システムカタログ内に問い合わせツリーとして格納されています。 これはログ出力のように整形されていませんが、まったく同じ情報を持っています。

問い合わせツリーそのものを読むためにはある程度の経験が必要です。 ルールシステムを理解するためには問い合わせツリーの SQL 表現で十分ですので、ここではその読み方までは教えません。

本章の問い合わせツリーの SQL 表現形式を読む時に必要なのは、問い合わせツリー構造の中に分解された、ある文の部品を識別できることです。 問い合わせツリーには以下の部品があります。

コマンド種類

これはどのコマンド( SELECT INSERT UPDATE DELETE )が構文解析ツリーを作ったかを示す単純な値です。

範囲テーブル

範囲テーブルは問い合わせで使われるリレーションのリストです。 SELECT 文ではこれは FROM キーワードの後で与えられるリレーションになります。

範囲テーブルのそれぞれの項目はテーブルもしくはビューを識別し、問い合わせの別の部品ではどんな名前で呼び出されるかを示します。 問い合わせツリーでは範囲テーブルの項目は名前よりも番号で参照されることが多いため、ここでは SQL 文とは違い、重複する名前があるかということは問題になりません。 これはルールの範囲テーブルがマージされた後に起こる可能性があります。 本章の例ではその状況を含んでいません。

結果リレーション

問い合わせの結果が格納されるリレーションを識別する範囲テーブルへのインデックスです。

SELECT 問い合わせは結果リレーションを持ちません。 ( SELECT INTO の場合は特別ですが、 INSERT ... SELECT が付いた CREATE TABLE とほぼ同じですので、ここでは個別には説明しません。)

INSERT UPDATE DELETE コマンドでは、結果リレーションは変更が有効になるテーブル(もしくはビュー)です。

目的リスト

目的リストは問い合わせの結果を定義する式のリストです。 SELECT の場合、この式は問い合わせの最終結果を構築するものです。 これらは SELECT FROM キーワードの間にある式に対応します ( * は単にリレーションの全ての列名の省略です。 これはパーサによって個別の列に展開されますので、ルールシステムが見ることはありません)。

DELETE コマンドは結果を返しませんので、通常の目的リストは必要ありません。 その代わり、ルールシステムは空の目的リストに特別な CTID 項目を追加し、エクゼキュータが削除すべき行を見つけられるようにします。 ( CTID は結果リレーションが通常のテーブルの場合に追加されます。 もしビューであれば 項38.2.4 で述べるように、代わりに行全体の変数が追加されます。)

INSERT 問い合わせでは、目的リストは結果リレーションへ入る新規の行を示します。 これは VALUES 句か INSERT ... SELECT の中の SELECT 句の式です。 書き換え処理の最初のステップでは、元の問い合わせでは割り当てられず、デフォルト値となっている列の目的リストの項目を追加します。 残った列(値が与えられていない列、かつデフォルト値を持たない列)は全て、プランナによって定数NULL式で埋められます。

UPDATE コマンドでは、目的リストは古いものを置き換えるべき新しい行を示します。 ルールシステムではコマンド内の SET column = expression 部分にある式だけを持っています。 プランナは、古い行から新しい行へ値をコピーする式を挿入することにより、抜けている列を処理します。 DELETE の場合と同様、エクゼキュータが更新すべき行を見つけられるように、ルールシステムは CTID もしくは行全体の変数を追加します。

目的リストの各項目は、定数値、範囲テーブル内のリレーション中の1つの列を指し示す変数、パラメータ、または、関数呼び出し、定数、変数、演算子などにより作られた式のツリーを保持します。

条件

問い合わせの条件は目的リストの項目に含まれている式によく似た式です。 この式の結果は、最終的な結果の行を得るための( INSERT UPDATE DELETE または SELECT )演算を実行すべきかどうかを示すブール値です。 それは SQL 文の中の WHERE 句です。

結合ツリー

問い合わせの結合ツリーは FROM 句の構造を表します。 SELECT ... FROM a, b, c のような単純な問い合わせでは、結合ツリーは単なる FROM 項目のリストです。 なぜならこれらはどんな順番で結合しても構わないためです。 しかし JOIN 式、特に外部結合が使われた場合は、その結合が示す順番通りに結合しなければいけません。 この場合結合ツリーは JOIN 式の構造を表します。 特定の JOIN 句と関連付けられた制約( ON もしくは USING 式からのもの)はこれらの結合ツリーノードに付加された条件として格納されます。 頂点レベルの WHERE 式を頂点レベルの結合ツリー項目に付加された条件として格納することも便利です。 ですから、結合ツリーは SELECT FROM 句と WHERE 句の両方を表しているわけです。

その他

ORDER BY 句のような、問い合わせツリーのその他の部品は、ここでは取り上げません。 ルールシステムはルールを適用している時にそこで項目を入れ替えることもありますが、これはルールシステムの基本とはあまり関係しません。


powered by SEO.CUG.NET