バージョンごとのドキュメント一覧

39.1. 問い合わせツリーとは #

<title>The Query Tree</title>

To understand how the rule system works it is necessary to know when it is invoked and what its input and results are. どのようにルールシステムが機能するかを理解するためには、ルールがどのように起動され、その入力と結果は何かを理解しなければなりません。

The rule system is located between the parser and the planner. It takes the output of the parser, one query tree, and the user-defined rewrite rules, which are also query trees with some extra information, and creates zero or more query trees as result. So its input and output are always things the parser itself could have produced and thus, anything it sees is basically representable as an <acronym>SQL</acronym> statement. ルールシステムは問い合わせパーサとプランナの中間に位置します。 ルールシステムは、入力としてパーサの出力、単一の問い合わせツリー、および何らかの特別な情報を持つ問い合わせツリーでもあるユーザ定義の書き換えルールを取り、結果として0個以上の問い合わせツリーを生成します。 ルールシステムの入力と出力は常にパーサ自体でも生成することができるもので、参照する対象は基本的にSQL文として表現できるものです。

Now what is a query tree? It is an internal representation of an <acronym>SQL</acronym> statement where the single parts that it is built from are stored separately. These query trees can be shown in the server log if you set the configuration parameters <varname>debug_print_parse</varname>, <varname>debug_print_rewritten</varname>, or <varname>debug_print_plan</varname>. The rule actions are also stored as query trees, in the system catalog <structname>pg_rewrite</structname>. They are not formatted like the log output, but they contain exactly the same information. では問い合わせツリーとは何でしょうか。 それは、SQL文を構成する個々の部品を別々に記憶した、SQL文の内部表現です。 debug_print_parsedebug_print_rewritten、もしくはdebug_print_plan設定パラメータを設定していれば、サーバログ内で問い合わせツリーを見ることができます。 ルールアクションもpg_rewriteシステムカタログ内に問い合わせツリーとして格納されています。 これはログ出力のように整形されていませんが、まったく同じ情報を持っています。

Reading a raw query tree requires some experience. But since <acronym>SQL</acronym> representations of query trees are sufficient to understand the rule system, this chapter will not teach how to read them. 問い合わせツリーそのものを読むためにはある程度の経験が必要です。 ルールシステムを理解するためには問い合わせツリーのSQL表現で十分ですので、本章ではその読み方については説明しません。

When reading the <acronym>SQL</acronym> representations of the query trees in this chapter it is necessary to be able to identify the parts the statement is broken into when it is in the query tree structure. The parts of a query tree are 本章の問い合わせツリーのSQL表現形式を読む時に必要なのは、問い合わせツリー構造の中に分解された、ある文の部品を識別できることです。 問い合わせツリーには以下の部品があります。

the command type コマンド種類

This is a simple value telling which command (<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>, <command>DELETE</command>) produced the query tree. これはどのコマンド(SELECTINSERTUPDATEDELETE)が構文解析ツリーを作ったかを示す単純な値です。

the range table <indexterm><primary>range table</primary></indexterm> 範囲テーブル

The range table is a list of relations that are used in the query. In a <command>SELECT</command> statement these are the relations given after the <literal>FROM</literal> key word. 範囲テーブルは問い合わせで使われるリレーションのリストです。 SELECT文ではこれはFROMキーワードの後で与えられるリレーションになります。

Every range table entry identifies a table or view and tells by which name it is called in the other parts of the query. In the query tree, the range table entries are referenced by number rather than by name, so here it doesn't matter if there are duplicate names as it would in an <acronym>SQL</acronym> statement. This can happen after the range tables of rules have been merged in. The examples in this chapter will not have this situation. 範囲テーブルのそれぞれの項目はテーブルもしくはビューを識別し、問い合わせの別の部品ではどんな名前で呼び出されるかを示します。 問い合わせツリーでは範囲テーブルの項目は名前よりも番号で参照されることが多いため、ここではSQL文とは違い、重複する名前があるかということは問題になりません。 これはルールの範囲テーブルがマージされた後に起こる可能性があります。 本章の例ではその状況を含んでいません。

the result relation 結果リレーション

This is an index into the range table that identifies the relation where the results of the query go. 問い合わせの結果が格納されるリレーションを識別する範囲テーブルへのインデックスです。

<command>SELECT</command> queries don't have a result relation. (The special case of <command>SELECT INTO</command> is mostly identical to <command>CREATE TABLE</command> followed by <literal>INSERT ... SELECT</literal>, and is not discussed separately here.) SELECT問い合わせは結果リレーションを持ちません。 (SELECT INTOの場合は特別ですが、INSERT ... SELECTが付いたCREATE TABLEとほぼ同じですので、ここでは個別には説明しません。)

For <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command> commands, the result relation is the table (or view!) where the changes are to take effect. INSERTUPDATEDELETEコマンドでは、結果リレーションは変更が有効になるテーブル(もしくはビュー)です。

the target list <indexterm><primary>target list</primary></indexterm> 目的リスト

The target list is a list of expressions that define the result of the query. In the case of a <command>SELECT</command>, these expressions are the ones that build the final output of the query. They correspond to the expressions between the key words <command>SELECT</command> and <command>FROM</command>. (<literal>*</literal> is just an abbreviation for all the column names of a relation. It is expanded by the parser into the individual columns, so the rule system never sees it.) 目的リストは問い合わせの結果を定義する式のリストです。 SELECTの場合、この式は問い合わせの最終結果を構築するものです。 これらはSELECTFROMキーワードの間にある式に対応します (*は単にリレーションの全ての列名の省略です。 これはパーサによって個別の列に展開されますので、ルールシステムが見ることはありません)。

<command>DELETE</command> commands don't need a normal target list because they don't produce any result. Instead, the planner adds a special <acronym>CTID</acronym> entry to the empty target list, to allow the executor to find the row to be deleted. (<acronym>CTID</acronym> is added when the result relation is an ordinary table. If it is a view, a whole-row variable is added instead, by the rule system, as described in <xref linkend="rules-views-update"/>.) DELETEコマンドは結果を返しませんので、通常の目的リストは必要ありません。 その代わり、プランナは空の目的リストに特別なCTID項目を追加し、エグゼキュータが削除すべき行を見つけられるようにします。 (CTIDは結果リレーションが通常のテーブルの場合に追加されます。 もしビューであれば39.2.4で述べるように、代わりに行全体の変数がルールシステムによって追加されます。)

For <command>INSERT</command> commands, the target list describes the new rows that should go into the result relation. It consists of the expressions in the <literal>VALUES</literal> clause or the ones from the <command>SELECT</command> clause in <literal>INSERT ... SELECT</literal>. The first step of the rewrite process adds target list entries for any columns that were not assigned to by the original command but have defaults. Any remaining columns (with neither a given value nor a default) will be filled in by the planner with a constant null expression. INSERT問い合わせでは、目的リストは結果リレーションへ入る新規の行を示します。 これはVALUES句かINSERT ... SELECTの中のSELECT句の式です。 書き換え処理の最初のステップでは、元の問い合わせでは割り当てられず、デフォルト値となっている列の目的リストの項目を追加します。 残った列(値が与えられていない列、かつデフォルト値を持たない列)は全て、プランナによって定数NULL式で埋められます。

For <command>UPDATE</command> commands, the target list describes the new rows that should replace the old ones. In the rule system, it contains just the expressions from the <literal>SET column = expression</literal> part of the command. The planner will handle missing columns by inserting expressions that copy the values from the old row into the new one. Just as for <command>DELETE</command>, a <acronym>CTID</acronym> or whole-row variable is added so that the executor can identify the old row to be updated. UPDATEコマンドでは、目的リストは古いものを置き換えるべき新しい行を示します。 ルールシステムではコマンド内のSET column = expression部分にある式だけを持っています。 プランナは、古い行から新しい行へ値をコピーする式を挿入することにより、抜けている列を処理します。 DELETEの場合と同様、エグゼキュータが更新すべき行を見つけられるように、CTIDもしくは行全体の変数が追加されます。

Every entry in the target list contains an expression that can be a constant value, a variable pointing to a column of one of the relations in the range table, a parameter, or an expression tree made of function calls, constants, variables, operators, etc. 目的リストの各項目は、定数値、範囲テーブル内のリレーション中の1つの列を指し示す変数、パラメータ等の式を保持するか、または、関数呼び出し、定数、変数、演算子などにより作られた式のツリーを保持します。

the qualification 条件

The query's qualification is an expression much like one of those contained in the target list entries. The result value of this expression is a Boolean that tells whether the operation (<command>INSERT</command>, <command>UPDATE</command>, <command>DELETE</command>, or <command>SELECT</command>) for the final result row should be executed or not. It corresponds to the <literal>WHERE</literal> clause of an <acronym>SQL</acronym> statement. 問い合わせの条件は目的リストの項目に含まれている式によく似た式です。 この式の結果は、最終的な結果の行を得るための(INSERTUPDATEDELETEまたはSELECT)演算を実行すべきかどうかを示すブール値です。 それはSQL文の中のWHERE句に対応します。

the join tree 結合ツリー

The query's join tree shows the structure of the <literal>FROM</literal> clause. For a simple query like <literal>SELECT ... FROM a, b, c</literal>, the join tree is just a list of the <literal>FROM</literal> items, because we are allowed to join them in any order. But when <literal>JOIN</literal> expressions, particularly outer joins, are used, we have to join in the order shown by the joins. In that case, the join tree shows the structure of the <literal>JOIN</literal> expressions. The restrictions associated with particular <literal>JOIN</literal> clauses (from <literal>ON</literal> or <literal>USING</literal> expressions) are stored as qualification expressions attached to those join-tree nodes. It turns out to be convenient to store the top-level <literal>WHERE</literal> expression as a qualification attached to the top-level join-tree item, too. So really the join tree represents both the <literal>FROM</literal> and <literal>WHERE</literal> clauses of a <command>SELECT</command>. 問い合わせの結合ツリーはFROM句の構造を表します。 SELECT ... FROM a, b, cのような単純な問い合わせでは、結合ツリーは単なるFROM項目のリストです。 なぜならこれらはどんな順番で結合しても構わないためです。 しかしJOIN式、特に外部結合が使われた場合は、その結合が示す順番通りに結合しなければいけません。 この場合結合ツリーはJOIN式の構造を表します。 特定のJOIN句と関連付けられた制約(ONもしくはUSING式からのもの)はこれらの結合ツリーノードに付加された条件として格納されます。 頂点レベルのWHERE式を頂点レベルの結合ツリー項目に付加された条件として格納することも便利です。 ですから、結合ツリーはSELECTFROM句とWHERE句の両方を表しているわけです。

the others その他

The other parts of the query tree like the <literal>ORDER BY</literal> clause aren't of interest here. The rule system substitutes some entries there while applying rules, but that doesn't have much to do with the fundamentals of the rule system. ORDER BY句のような、問い合わせツリーのその他の部品は、ここでは取り上げません。 ルールシステムはルールを適用している時にそこで項目を入れ替えることもありますが、これはルールシステムの基本とはあまり関係しません。