要了解規則系統如何運作,必須知道它何時被調用,以及它的輸入和結果是什麼。
規則系統位於剖析器和計畫器之間。它採用剖析器的輸出,即一個查詢樹,以及使用者定義的重寫規則,這些規則也是帶有一些額外資訊的查詢樹,並建立零或多個查詢樹作為結果。因此,它的輸入和輸出始終是剖析器本身可以產生的東西,因此,它所看到的任何東西基本上都可以表示為一個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
的特殊情況在很大程度上與 CREATE TABLE
接著 INSERT ... SELECT
相同,這裡不單獨討論。)
對於 INSERT
、UPDATE
和 DELETE
命令,結果關聯式資料庫是要生效的資料表(或檢視表!)。
目標列表是定義查詢結果的表達式清單。在 SELECT
的情況下,這些表達式是建立查詢最終輸出的表達式。它們對應於 SELECT
和 FROM
關鍵字之間的表達式。(*
只是關聯式資料庫所有欄位名稱的縮寫。它被剖析器展開為單個欄位,因此規則系統永遠不會看到它。)
DELETE
命令不需要正常的目標列表,因為它們不產生任何結果。相反,計畫器會將一個特殊的CTID條目新增到空的目標列表中,以允許執行器找到要刪除的列。(CTID當結果關聯式資料庫是一個普通資料表時新增。如果它是一個檢視表,則由規則系統新增一個整列變數,如第 39.2.4 節中所述。)
對於 INSERT
命令,目標列表描述了應該進入結果關聯式資料庫的新列。它由 VALUES
子句中的表達式或 INSERT ... SELECT
中的 SELECT
子句中的表達式組成。重寫過程的第一步是為原始命令未分配但具有預設值的任何欄位新增目標列表條目。任何剩餘的欄位(既沒有給定值也沒有預設值)將由計畫器用常數空表達式填寫。
對於 UPDATE
命令,目標列表描述了應該替換舊列的新列。在規則系統中,它僅包含來自命令的 SET column = expression
部分的表達式。計畫器將透過插入將舊列中的值複製到新列中的表達式來處理遺失的欄位。就像 DELETE
一樣,一個CTID或加入整列變數,以便執行器可以識別要更新的舊列。
目標列表中的每個條目都包含一個表達式,該表達式可以是常數值、指向範圍表中某個關係的欄位的變數、參數,或由函數呼叫、常數、變數、運算符等組成的表達式樹。
查詢的限定條件是一個表達式,非常類似於目標列表條目中包含的那些表達式。此表達式的結果值是一個布林值,用於指示是否應執行最終結果列的操作(INSERT
、UPDATE
、DELETE
或 SELECT
)。它對應於SQL語句。
查詢的連接樹顯示了 FROM
子句的結構。 對於像 SELECT ... FROM a, b, c
這樣的簡單查詢,連接樹只是一個 FROM
項目列表,因為我們允許以任何順序連接它們。 但是當使用 JOIN
表達式,特別是外部連接時,我們必須按照連接中顯示的順序連接。 在這種情況下,連接樹顯示了 JOIN
表達式的結構。 與特定 JOIN
子句相關聯的限制(來自 ON
或 USING
表達式)儲存為附加到這些連接樹節點的限定條件表達式。 事實證明,將頂層 WHERE
表達式儲存為附加到頂層連接樹項目的限定條件也很方便。 因此,連接樹實際上代表了 SELECT
的 FROM
和 WHERE
子句。
查詢樹的其他部分,例如 ORDER BY
子句,在這裡並不重要。 規則系統在應用規則時會替換其中的一些條目,但這與規則系統的基本原理關係不大。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用此表單來報告文件問題。