SQL是一種強型別語言。也就是說,每個資料項都有一個關聯的資料型別,該資料型別決定了其行為和允許的使用方式。PostgreSQL 擁有一個可擴充套件的型別系統,該系統比其他SQL實現更為通用和靈活。因此,PostgreSQL 中的大多數型別轉換行為都遵循通用規則,而不是臨時的特殊處理。這使得即使使用使用者定義的型別,也可以在混合型別表示式中使用。
PostgreSQL 的詞法分析器/解析器將詞法元素分為五個基本類別:整數、非整數數字、字串、識別符號和關鍵字。大多數非數字型別的常量首先被歸類為字串。PostgreSQL 的SQL語言定義允許使用字串指定型別名稱,並且可以在 PostgreSQL 中使用此機制來引導解析器進入正確的路徑。例如,查詢
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
有兩個字面量常量,型別分別為 text
和 point
。如果字串字面量未指定型別,則最初會分配佔位符型別 unknown
,然後在後續階段進行解析,如下所述。
有四個基本SQLPostgreSQL 解析器中需要不同型別轉換規則的構造:
PostgreSQL 的型別系統很大程度上圍繞著一套豐富的函式構建。函式可以有一個或多個引數。由於 PostgreSQL 允許函式過載,僅函式名稱不能唯一標識要呼叫的函式;解析器必須根據所提供引數的資料型別來選擇正確的函式。
PostgreSQL 允許使用字首(單引數)運算子以及中綴(雙引數)運算子的表示式。與函式一樣,運算子也可以過載,因此存在選擇正確運算子的相同問題。
SQL INSERT
和 UPDATE
語句將表示式的結果存入表中。語句中的表示式必須與目標列的型別匹配,並可能轉換為目標列的型別。
UNION
、CASE
及相關構造由於聯合 SELECT
語句的所有查詢結果都必須出現在同一組列中,因此每個 SELECT
子句的結果型別必須匹配並轉換為統一的集合。類似地,CASE
構造的結果表示式必須轉換為公共型別,以便 CASE
表示式整體具有已知的輸出型別。其他一些構造,如 ARRAY[]
以及 GREATEST
和 LEAST
函式,同樣需要確定多個子表示式的公共型別。
系統目錄儲存有關哪些轉換(或稱 cast)存在於哪些資料型別之間以及如何執行這些轉換的資訊。使用者可以使用 CREATE CAST 命令新增額外的 cast。(這通常與定義新資料型別結合進行。內建型別之間的 cast 集經過精心設計,最好不要更改。)
解析器提供了一個額外的啟發式方法,可以改進對具有隱式 cast 的型別組之間正確 cast 行為的確定。資料型別被劃分為幾個基本 型別類別,包括 boolean
、numeric
、string
、bitstring
、datetime
、timespan
、geometric
、network
和使用者定義的。(有關列表,請參閱 Table 52.65;但請注意,也可以建立自定義型別類別。)在每個類別中,可以有一個或多個 首選型別,在有多種可能型別可供選擇時會偏向使用這些首選型別。透過仔細選擇首選型別和可用的隱式 cast,可以確保歧義表示式(具有多個候選解析解決方案的表示式)能夠以有用的方式得到解決。
所有型別轉換規則的設計都考慮了幾個原則:
隱式轉換絕不應產生令人驚訝或不可預測的結果。
如果查詢不需要隱式型別轉換,則解析器或執行器不應有任何額外的開銷。也就是說,如果查詢格式正確且型別已經匹配,則查詢應執行,而不會在解析器中花費額外時間,也不會在查詢中引入不必要的隱式轉換呼叫。
此外,如果一個查詢通常需要為函式進行隱式轉換,然後使用者定義了一個具有正確引數型別的新函式,則解析器應使用這個新函式,而不再進行隱式轉換來使用舊函式。
如果您在文件中發現任何不正確之處,與您對特定功能的實際體驗不符,或需要進一步的說明,請使用 此表單 報告文件問題。