查詢透過 TCP/IP 或 Unix Domain sockets 傳送的資料封包到達後端。 它被載入到字串中,並傳遞給剖析器,詞法掃描器 scan.l 將查詢分解為 tokens(單字)。 剖析器使用 gram.y 和 tokens 來識別查詢類型,並載入適當的查詢特定結構,例如 CreateStmt 或 SelectStmt。
然後,該語句被識別為複雜語句 (SELECT / INSERT / UPDATE / DELETE) 或簡單語句,例如 CREATE ROLE, ANALYZE 等。 不需要執行器的簡單實用命令由 commands 模組中的語句特定函數處理。 複雜語句需要更多處理。
剖析器採用複雜查詢,並創建一個 Query 結構,其中包含複雜查詢使用的所有元素。 Query.jointree 保存 FROM 和 WHERE 子句,這些子句由 transformFromClause() 和 transformWhereClause() 填寫。 查詢中引用的每個表都由 RangeTblEntry 表示,並且它們鏈接在一起以形成查詢的範圍表,該範圍表由 transformFromClause() 產生。 Query.rtable 保存查詢的範圍表。
某些查詢,如 SELECT,會傳回資料欄。 其他查詢,如 INSERT 和 UPDATE,指定由查詢修改的欄位。 這些欄位參考會轉換為 TargetEntry 條目,這些條目鏈接在一起以構成查詢的目標列表。 目標列表儲存在 Query.targetList 中,該目標列表由 transformTargetList() 產生。
其他查詢元素,如彙總 (SUM())、GROUP BY 和 ORDER BY 也儲存在它們自己的 Query 欄位中。
下一步是由可能適用於查詢的任何 VIEWS 或 RULES 修改 Query。 這由 rewrite 系統執行。
最佳化器使用 Query 結構來確定 RangeTable 中每個表的最佳表連接順序和連接類型,使用 Query.jointree(FROM 和 WHERE 子句)來考慮最佳索引使用。
path 模組然後產生一個最佳的 Plan,其中包含執行查詢要執行的操作。然後,Plan 被傳遞給 executor 執行,結果傳回給客戶端。 Plan 實際上是一個節點集合,排列成樹狀結構,其中包含一個頂層節點和作為子節點的各種子節點。
還有許多其他模組支援這個基本功能。 點擊流程圖可以訪問它們。