支援版本:目前 (16) / 15 / 14 / 13 / 12
開發版本:devel
不支援版本:11

67.3. B 樹支援函數 #

表 38.9 所示,btree 定義了一個必要的支援函數和四個選用的支援函數。這五個使用者定義的方法為

order

對於 btree 算子系列提供比較算子的每種資料類型組合,它必須提供一個比較支援函數,在 pg_amproc 中註冊,支援函數編號為 1,且 amproclefttype/amprocrighttype 等於比較運算的左資料類型和右資料類型(也就是與匹配運算子在 pg_amop 中註冊相同的資料類型)。比較函數必須採用兩個非空值 AB,並傳回一個 int32 值,當 A < BA = BA > B 時,分別為 < 00> 0。不允許空值結果:資料類型的所有值都必須可比較。請參閱 src/backend/access/nbtree/nbtcompare.c 以取得範例。

如果比較值屬於可整理資料類型,適當的整理 OID 會使用標準 PG_GET_COLLATION() 機制傳遞給比較支援函數。

sortsupport

btree 算子系列可以選擇提供在支援函數編號 2 下註冊的 排序支援 函數。這些函數允許以比天真地呼叫比較支援函數更有效率的方式,針對排序目的實作比較。相關的 API 定義在 src/include/utils/sortsupport.h 中。

in_range

btree 算子系列可以選擇提供在支援函數編號 3 下註冊的 in_range 支援函數。這些函數不會在 btree 索引操作期間使用;相反地,它們會擴充算子系列的語意,以支援包含 RANGE offset PRECEDINGRANGE offset FOLLOWING 範圍邊界類型的視窗子句(請參閱 第 4.2.8 節)。基本上,提供的額外資訊是,如何以與系列資料排序相容的方式,新增或減去 offset 值。

一個 in_range 函數必須具有簽名

in_range(val type1, base type1, offset type2, sub bool, less bool)
returns bool

valbase 必須是同類型,這是運算子系列支援的類型之一(即提供排序的類型)。不過,offset 可以是不同類型,這可能是系列原本不支援的類型。一個範例是內建 time_ops 系列提供一個 in_range 函數,其 offsetinterval 類型。一個系列可以為其支援的任何類型提供 in_range 函數,以及一個或多個 offset 類型。每個 in_range 函數都應該輸入 pg_amproc,其中 amproclefttype 等於 type1amprocrighttype 等於 type2

一個 in_range 函數的基本語意取決於兩個布林旗標參數。它應該加上或減去 baseoffset,然後將 val 與結果進行比較,如下所示

  • 如果 !sub!less,傳回 val >= (base + offset)

  • 如果 !subless,傳回 val <= (base + offset)

  • 如果 sub!less,傳回 val >= (base - offset)

  • 如果 subless,傳回 val <= (base - offset)

在這樣做之前,函數應該檢查 offset 的符號:如果小於零,則引發錯誤 ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE (22013),錯誤文字類似於 視窗函數中無效的前置或後置大小。(這是 SQL 標準所要求的,儘管非標準運算子系列可能會選擇忽略此限制,因為這似乎沒有什麼語意上的必要性。)此要求委派給 in_range 函數,以便核心程式碼不必了解 小於零 對特定資料類型來說是什麼意思。

另一個期望是 in_range 函數應該在實務上避免在 base + offsetbase - offset 會溢位時引發錯誤。即使該值超出資料類型的範圍,也可以確定正確的比較結果。請注意,如果資料類型包含 無限大NaN 等概念,可能需要特別小心以確保 in_range 的結果與運算子系列的正常排序順序一致。

in_range 函數的結果必須與運算子系列施加的排序順序一致。準確來說,給定 offsetsub 的任何固定值,則

  • 如果 in_range 對於某些 val1base,且 less = true 為 true,則對於每個 val2 <= val1 且具有相同 base,它都必須為 true。

  • 如果 in_range 對於某些 val1base,且 less = true 為 false,則對於每個 val2 >= val1 且具有相同 base,它都必須為 false。

  • 如果 in_range 對於某些 valbase1,且 less = true 為 true,則對於每個 base2 >= base1 且具有相同 val,它都必須為 true。

  • 如果 in_range 對於某些 valbase1,且 less = true 為 false,則對於每個 base2 <= base1 且具有相同 val,它都必須為 false。

less = false 時,具有反向條件的類比陳述成立。

如果正在排序的類型 (type1) 可整理,則適當的整理 OID 將使用標準 PG_GET_COLLATION() 機制傳遞給 in_range 函數。

in_range 函數不需要處理 NULL 輸入,而且通常會標記為嚴格。

equalimage

btree 算子系列可以選擇性地提供 equalimage (相等意味著影像相等) 支援函數,在支援函數編號 4 下註冊。這些函數允許核心程式碼確定何時可以安全地套用 btree 重複資料刪除最佳化。目前,equalimage 函數只會在建立或重建索引時呼叫。

equalimage 函數必須具有簽章

equalimage(opcintype oid) returns bool

回傳值是關於算子類別和整理的靜態資訊。回傳 true 表示算子類別的 order 函數保證只會在 AB 參數在語意資訊沒有任何損失的情況下也可以互換時,才會回傳 0 (參數相等)。未註冊 equalimage 函數或回傳 false 表示無法假設此條件成立。

opcintype 參數是算子類別索引的資料類型的 pg_type.oid。這是一種便利性,允許在算子類別間重複使用相同的基礎 equalimage 函數。如果 opcintype 是可整理的資料類型,則適當的整理 OID 將使用標準 PG_GET_COLLATION() 機制傳遞給 equalimage 函數。

就運算子類別而言,傳回 true 表示重複資料刪除是安全的(或對其 equalimage 函式傳遞 OID 的校對是安全的)。然而,核心程式碼只會在 每個 編製索引的欄位使用註冊 equalimage 函式的運算子類別,且每個函式在呼叫時實際傳回 true 時,才將重複資料刪除視為對索引而言是安全的。

影像相等與單純的按位元相等條件 幾乎 相同。有一個細微的差異:在編製變長資料類型的索引時,兩個影像相等資料的磁碟表示法可能因為輸入上 TOAST 壓縮應用不一致而無法按位元相等。正式來說,當運算子類別的 equalimage 函式傳回 true 時,可以安全地假設 datum_image_eq() C 函式將永遠與運算子類別的 order 函式一致(前提是相同的校對 OID 傳遞給 equalimageorder 函式)。

核心程式碼基本上無法推論出多資料類型系列中運算子類別的 相等表示影像相等 狀態,這是根據同系列中其他運算子類別的詳細資料。此外,運算子系列註冊跨類型的 equalimage 函式並非明智之舉,而且嘗試這麼做會導致錯誤。這是因為 相等表示影像相等 狀態不只取決於排序/相等語意,這些語意或多或少定義在運算子系列層級。一般來說,一個特定資料類型實作的語意必須個別考量。

核心 PostgreSQL 發行版附帶的運算子類別遵循的慣例是註冊一個庫存的、通用的 equalimage 函式。大多數運算子類別註冊 btequalimage(),表示重複資料刪除無條件安全。可校對資料類型(例如 text)的運算子類別註冊 btvarstrequalimage(),表示重複資料刪除在確定性校對下是安全的。第三方擴充套件的最佳作法是註冊自己的自訂函式以保留控制權。

選項

B 樹運算子系列可以選擇提供 options (運算子類別特定選項) 支援函式,在支援函式編號 5 下註冊。這些函式定義一組使用者可見的參數,用於控制運算子類別行為。

一個 options 支援函數必須具有簽章

options(relopts local_relopts *) returns void

函數傳遞一個指向 local_relopts 結構的指標,需要填入一組運算子類別特定選項。可以使用 PG_HAS_OPCLASS_OPTIONS()PG_GET_OPCLASS_OPTIONS() 巨集從其他支援函數存取選項。

目前,沒有 B 樹運算子類別具有 options 支援函數。B 樹不允許彈性表示像 GiST、SP-GiST、GIN 和 BRIN 那樣的鍵。因此,options 可能在目前的 B 樹索引存取方法中沒有太多應用。不過,這個支援函數已新增到 B 樹以求一致性,而且可能在 PostgreSQL 中 B 樹進一步演進時找到用途。

提交修正

如果您在文件檔中看到任何不正確、與您對特定功能的體驗不符或需要進一步說明的地方,請使用 此表單 回報文件檔問題。