| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Fast Forward | Next | |
SQL 語句可能(有意無意地)要求在同一表達式裡混合不同的數據類型。 PostgreSQL 在計算混合類型表達式方面有許多擴展性很強的功能。
在大多數情況下,用戶不需要明白類型轉換機制的細節。 但是,由 PostgreSQL 所進行的隱含的類型轉換會對查詢的結果產生影響,必要時這些影響又可以由用或程序員通過明確的類型轉換進行剪裁利用。
本章介紹 PostgreSQL類型轉換的傳統和機制。 關于特定的類型和函數及操作符的進一步信息, 請參考Chapter 8 和 Chapter 9裡的相關章節。
SQL 是強類型語言。 也就是說,每一數據都與一個決定其行為和可行用法的數據類型相聯。 PostgreSQL 有一個可擴展的數據類型系統, 該系統比其他 SQL 實現實現更具通用性和靈活性。 因而,PostgreSQL中大多數類型轉換的特性應該是由通用規則來管理的, 而不是由專門搜索方法來分析,以此令混合類型表達式有實際意義,即便是用戶定義的類型也如此。
PostgreSQL 掃描/分析器只將詞法元素分解成五個基本種類: 整數(integers),浮點數(floating-point numbers), 字符串(strings),名字(names)和關鍵字(keywords)。 大多數擴展的類型首先表征為字符串(strings)。 SQL 語言的定義允許將類型名聲明為字符串,這個機制被 PostgreSQL 用于令分析器沿著正確的方向運行。例如,下面查詢
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
有兩個文本常量,類型分別為 text 和 point。 如果沒有為字串文本聲明類型, (該文本)先被初始化成一個擁有存儲空間的 unknown(未知)類型, 該類型將在後面描述的晚期階段分析。
在 PostgreSQL 分析器裡, 有四種基本的 SQL 元素需要獨立的類型轉換規則:
PostgreSQL 也允許使用左目或右目操作符(單目操作符,一個參數), 允許表達式裡使用雙目操作符(兩個參數)。
多數 PostgreSQL 類型系統是建築在一套豐富的函數上的。 函數調用可以有一個或多個參數。 因為 PostgreSQL 允許函數重載, 所以函數名自身並不唯一地標識將要調用的函數 --- 分析器必須以函數提供的參數的類型為基礎選擇正確的函數。
SQL INSERT和UPDATE 語句將表達式結果放入表中。 語句中的表達式類型必須和的目標列的類型一致或者是(可能需要)轉換成一致的。
因為聯合SELECT語句中的所有查詢結果必須在一列裡顯示出來, 所以每個SELECT 子句中的元素類型必須相互匹配並轉換成一套統一類型。 類似,一個CASE構造的結果表達式必須轉換成統一的類型, 這樣CASE表達式自身作為整體有一種已知輸出類型。 同樣的要求也存在于 ARRAY 構造中。
系統表存儲有關哪種數據類型之間的轉換(叫 casts )是合法的, 以及如何執行這些轉換的信息。額外的轉換可以由用戶通過 CREATE CAST 命令增加。(通常和定義一種新的數據類型一起完成。 內置類型的類型轉換集已經經過仔細的雕琢了,因此最好不要去更改它們。)
分析器中還有一個搜索器用于更好地猜測 SQL 標準類型的確切特性。 分析器裡定義了幾種類型範疇: boolean,numeric,string, bitstring,datetime,timespan, geometric,network,和用戶定義(user-defined)。 除用戶定義類型外, 每種類型都有一種首選類型用于解決類型定義歧義的問題。 對于用戶定義的類型,其自身就是自己的首選類型,所以那些含混不清的表達式(在分析結果中有多種可能的表達式) 如果有多個內置類型的時候大多可以正確分析,但如果有多個用戶定義類型可選,則會拋出錯。
所有類型轉換規則都是建立在下面幾個基本原則上的:
隱含轉換決不能有奇怪的或不可預見的輸出。
用戶定義類型,因為分析器對其沒有預先的認識, 在類型級別中應該級別較"高"。 在混合類型的表達式裡,內部類型總是應該轉換成用戶定義類型。 (當然只是在必須轉換的時候)。
用戶定義類型是不相關的。目前,PostgreSQL 除了用于內部數據類型的硬代碼搜索器和以現有函數為基礎的隱含類型關系外,沒有任何可用于處理類型間關系的信息。
如果一個查詢不需要隱含的類型轉換, 分析器或執行器不應該進行更多的額外操作。 這就是說,任何一個類型匹配,格式清晰的查詢不應該在分析器裡耗費更多的時間, 也不應該向查詢中引入任何不必要的隱含類型轉換調用。
另外,如果一個查詢通常使用某個函數進行隱含類型轉換, 而用戶定義了一個有正確參數的函數,解釋器應該使用新函數取代原先舊函數的隱含操作。