如 表 38.9 所示,btree 定義了一個必要的支援函數和四個選用的支援函數。這五個使用者定義的方法為
order
對於 btree 算子系列提供比較算子的每種資料類型組合,它必須提供一個比較支援函數,在 pg_amproc
中註冊,支援函數編號為 1,且 amproclefttype
/amprocrighttype
等於比較運算的左資料類型和右資料類型(也就是與匹配運算子在 pg_amop
中註冊相同的資料類型)。比較函數必須採用兩個非空值 A
和 B
,並傳回一個 int32
值,當 A
<
B
、A
=
B
或 A
>
B
時,分別為 <
0
、0
或 >
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
PRECEDING
和 RANGE
offset
FOLLOWING
範圍邊界類型的視窗子句(請參閱 第 4.2.8 節)。基本上,提供的額外資訊是,如何以與系列資料排序相容的方式,新增或減去 offset
值。
一個 in_range
函數必須具有簽名
in_range(val
type1,base
type1,offset
type2,sub
bool,less
bool) returns bool
val
和 base
必須是同類型,這是運算子系列支援的類型之一(即提供排序的類型)。不過,offset
可以是不同類型,這可能是系列原本不支援的類型。一個範例是內建 time_ops
系列提供一個 in_range
函數,其 offset
為 interval
類型。一個系列可以為其支援的任何類型提供 in_range
函數,以及一個或多個 offset
類型。每個 in_range
函數都應該輸入 pg_amproc
,其中 amproclefttype
等於 type1
,amprocrighttype
等於 type2
。
一個 in_range
函數的基本語意取決於兩個布林旗標參數。它應該加上或減去 base
和 offset
,然後將 val
與結果進行比較,如下所示
如果 !
sub
和 !
less
,傳回 val
>=
(base
+
offset
)
如果 !
sub
和 less
,傳回 val
<=
(base
+
offset
)
如果 sub
和 !
less
,傳回 val
>=
(base
-
offset
)
如果 sub
和 less
,傳回 val
<=
(base
-
offset
)
在這樣做之前,函數應該檢查 offset
的符號:如果小於零,則引發錯誤 ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE
(22013),錯誤文字類似於 “視窗函數中無效的前置或後置大小”。(這是 SQL 標準所要求的,儘管非標準運算子系列可能會選擇忽略此限制,因為這似乎沒有什麼語意上的必要性。)此要求委派給 in_range
函數,以便核心程式碼不必了解 “小於零” 對特定資料類型來說是什麼意思。
另一個期望是 in_range
函數應該在實務上避免在 base
+
offset
或 base
-
offset
會溢位時引發錯誤。即使該值超出資料類型的範圍,也可以確定正確的比較結果。請注意,如果資料類型包含 “無限大” 或 “NaN” 等概念,可能需要特別小心以確保 in_range
的結果與運算子系列的正常排序順序一致。
in_range
函數的結果必須與運算子系列施加的排序順序一致。準確來說,給定 offset
和 sub
的任何固定值,則
如果 in_range
對於某些 val1
和 base
,且 less
= true 為 true,則對於每個 val2
<=
val1
且具有相同 base
,它都必須為 true。
如果 in_range
對於某些 val1
和 base
,且 less
= true 為 false,則對於每個 val2
>=
val1
且具有相同 base
,它都必須為 false。
如果 in_range
對於某些 val
和 base1
,且 less
= true 為 true,則對於每個 base2
>=
base1
且具有相同 val
,它都必須為 true。
如果 in_range
對於某些 val
和 base1
,且 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
函數保證只會在 A
和 B
參數在語意資訊沒有任何損失的情況下也可以互換時,才會回傳 0
(“參數相等”)。未註冊 equalimage
函數或回傳 false
表示無法假設此條件成立。
opcintype
參數是算子類別索引的資料類型的
。這是一種便利性,允許在算子類別間重複使用相同的基礎 pg_type
.oidequalimage
函數。如果 opcintype
是可整理的資料類型,則適當的整理 OID 將使用標準 PG_GET_COLLATION()
機制傳遞給 equalimage
函數。
就運算子類別而言,傳回 true
表示重複資料刪除是安全的(或對其 equalimage
函式傳遞 OID 的校對是安全的)。然而,核心程式碼只會在 每個 編製索引的欄位使用註冊 equalimage
函式的運算子類別,且每個函式在呼叫時實際傳回 true
時,才將重複資料刪除視為對索引而言是安全的。
影像相等與單純的按位元相等條件 幾乎 相同。有一個細微的差異:在編製變長資料類型的索引時,兩個影像相等資料的磁碟表示法可能因為輸入上 TOAST 壓縮應用不一致而無法按位元相等。正式來說,當運算子類別的 equalimage
函式傳回 true
時,可以安全地假設 datum_image_eq()
C 函式將永遠與運算子類別的 order
函式一致(前提是相同的校對 OID 傳遞給 equalimage
和 order
函式)。
核心程式碼基本上無法推論出多資料類型系列中運算子類別的 “相等表示影像相等” 狀態,這是根據同系列中其他運算子類別的詳細資料。此外,運算子系列註冊跨類型的 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 樹進一步演進時找到用途。
如果您在文件檔中看到任何不正確、與您對特定功能的體驗不符或需要進一步說明的地方,請使用 此表單 回報文件檔問題。