| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 42. PostgreSQL 內部概貌 | Fast Forward | Next |
分析器階段含兩個部分:
在 gram.y 和 scan.l 裡定義的分析器是使用 Unix 工具 yacc 和 lex制作的。
轉換處理對分析器返回的數據結構進行修改和增補。
分析器必須檢查(以純 ASCII 文本方式到來的)查詢字串的語法。 如果語法正確,則創建一個分析樹並將之傳回, 否則,返回一個錯誤。實現分析器和詞法器我們使用了著名的 Unix 工具 lex 和 yacc。
詞法器在文件 scan.l裡定義,負責識別標識符,SQL 關鍵字等。 對于發現的每個關鍵字或者標識符都會生成一個記號並且傳遞給分析器。
分析器在文件 gram.y 裡定義並且包含一套 語法規則和觸發規則時執行的 動作。 動作代碼(實際上是 C 代碼)用于建立分析樹。
文件 scan.l 用 lex 轉換成 C 源文件 scan.c 而 gram.y 用 yacc 轉換成 gram.c。 在完成這些轉換後,一個通用的 C 編譯器就可以用于創建分析器。 千萬不要對生成的 C 源文件做修改,因為下一次調用 lex 或 yacc 時會把它們覆蓋。
注意: 上面提到的轉換和編譯是使用跟隨 PostgreSQL 發布的 makefiles 自動完成的。
對 yacc 或者 gram.y 裡的語法規則的詳細描述超出本文的範圍。 有很多關于 lex 和 yacc的書籍和文檔。你在開始研究 gram.y 裡給出的語法之前,你應該對 yacc 很熟悉,否則你是看不懂那裡面的內容,理解不了發生了什麼事情的。
分析器截斷只使用和 SQL 語法結構相關的固定規則創建一個分析樹。 它不會查找任何系統表,因此就不可能理解請求查詢裡面的詳細的語意。 在分析器技術之後,轉換處理接受分析器傳過來的分析樹然後做進一步處理, 解析那些理解查詢中引用了哪個表,哪個函數以及哪個操作符的語意。所生成的表示這個信息的數據結構叫做查詢樹。
把裸分析和語意分析分成兩個過程的原因是系統表查找只能在一個事務中進行, 而我們不想在一接收到查詢字串就發起一個事務。 裸分析階段已經足夠可以標識事務控制命令(BEGIN,ROLLBACK,等), 並且這些東西不用任何進一步的分析就可以執行。一旦我們知道我們正在處理一個真正 的查詢(比如SELECT 或者 UPDATE), 我們就可以發起一個事務了(如果我們還沒開始這麼一個)。只有這個時候可以調用轉換處理。
轉換處理生成的查詢樹結構上在很大程度上類似于裸分析樹,但是在細節上有很多區別。 比如,在分析樹裡的 FuncCall 節點代表那些看上去像函數調用的東西。 根據引用的名字是一個普通函數還是一個聚集函數, 這個可能被轉換成一個 FuncExpr 或者一個 Aggref 節點。 同樣,有關字段和表達式結果的具體數據類型也添加到查詢樹中。