PostgreSQL B-樹支持函數(shù)

2021-09-15 11:07 更新

表 37.9中所示,btree定義了一種必需的和四種可選的支持函數(shù)。這五種用戶定義的方法為:

order

對于btree操作符族為其提供了比較操作符的每一種數(shù)據(jù)類型組合,操作符族必須提供一個比較支持函數(shù),在pg_amproc中注冊:支持函數(shù)編號為1,amproclefttype/amprocrighttype等于比較的左右數(shù)據(jù)類型(即匹配的操作符注冊在pg_amop中的數(shù)據(jù)類型)。 比較函數(shù)必須接收兩個非空值AB并且返回一個int32值,返回值在A < B、 A = B以及A > B時分別為< 0、 0> 0。 不允許空值結果:該數(shù)據(jù)類型的所有值必須是可比較的。 例子請見src/backend/access/nbtree/nbtcompare.c。

如果被比較的值是一種可排序的數(shù)據(jù)類型,合適的排序規(guī)則OID將使用標準的PG_GET_COLLATION()機制被傳遞給比較支持函數(shù)。

sortsupport

可選地,btree操作符族可以提供排序支持函數(shù),它們以支持函數(shù)編號2注冊。 這些函數(shù)允許以一種比單純調(diào)用比較支持函數(shù)更加高效的方式實現(xiàn)排序比較。 涉及的API在src/include/utils/sortsupport.h中定義。

in_range

可選地,btree操作符族可以提供in_range支持函數(shù),它們以支持函數(shù)編號3注冊。 在btree索引操作期間不會用到這些函數(shù),它們擴展了操作符族的語義,這樣就能支持包含RANGE offset PRECEDING以及RANGE offset FOLLOWING窗口幀界類型(見第 4.2.8 節(jié))的窗口子句。 歸根到底,這些函數(shù)所提供的額外信息是如何以一種與該操作符族的數(shù)據(jù)排序相兼容的方式加上或者減去一個offset值。

An in_range 函數(shù)必須有簽名

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

valbase必須是同一種類型,該類型也是操作符族所支持的類型之一(即它提供排序的一種類型)。 不過,offset可以是一種不同的類型,該類型有可能不被該操作符族所支持。例如內(nèi)建的time_ops族提供了一個 in_range函數(shù),其offset是類型interval。 一個操作符族可以為其所支持的任意類型提供in_range函數(shù)以及一個或者更多種offset類型。 每一個in_range函數(shù)在進入到 pg_amproc時,需要有amproclefttype等于type1以及amprocrighttype等于type2

in_range函數(shù)的本質語義取決于兩個布爾標志參數(shù)。 它應該將baseoffset相加或者相減,然后用val與其結果比較:

  • 如果!sub并且!less,則返回val >= (base + offset)

  • 如果!sub并且less,則返回val <= (base + offset)

  • 如果sub并且!less,則返回val >= (base - offset)

  • 如果sub并且less,則返回val <= (base - offset )

在這樣做之前,該函數(shù)應該檢查offset的符號:如果它小于零,則拋出錯誤ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE (22013)外加invalid preceding or following size in window function這樣的錯誤文本(這是SQL標準所要求的,不過非標準操作符族可能會選擇忽視這一限制,因為似乎其語義必要性很?。? 這種要求被委托給了in_range函數(shù),這樣核心代碼不需要理解對一種特定數(shù)據(jù)類型less than zero表示什么。

一個額外的期望是,如果可行,in_range函數(shù)應當在base + offset或者base - offset 溢出時避免拋出錯誤。 即便值超過了該數(shù)據(jù)類型的范圍,也可以確定正確的比較結果。 注意,如果數(shù)據(jù)類型包括諸如infinity或者NaN之類的概念,就需要額外的注意確保in_range的結果符合該操作符族的正常排序順序。

in_range函數(shù)的結果必須與操作符族施加的排序順序保持一致。 準確的來說,給定任意固定的offset值以及sub值,那么:

  • 如果帶有less = true的in_range對某個val1base為真,則它必須對每一個有相同baseval2 <= val1為真。

  • 如果帶有less = true的in_range對某個val1base為假,則它必須對每一個有相同baseval2 >= val1為假。

  • 如果帶有less = true的in_range對于某些valbase1為真,那么它對于每一個有相同valbase2 >= base1也必須為真。

  • 如果帶有less = true的in_range對于某些valbase1為假, name它對于每一個有相同valbase2 <= base1也必須為假。

less = false時,類似的具有相逆條件的語句成立。

如果被排序的類型(type1)是可排序的,合適的排序規(guī)則OID將使用標準的PG_GET_COLLATION()機制被傳遞給in_range函數(shù)。

in_range函數(shù)不需要處理NULL輸入,并且通常將被標記為strict。

equalimage

可選地,btree 操作符系列可以提供equalimageequality implies image equality)支持功能,注冊在支持函數(shù) 4 下面。 這些函數(shù)允許核心代碼確定何時可以安全地應用 btree 重復數(shù)據(jù)消除進行優(yōu)化。 目前,equalimage函數(shù)僅在生成或重建索引時調(diào)用。

一個 equalimage 函數(shù)必須包含簽名

equalimage(opcintype oid) returns bool

返回值是有關運算符類和排序規(guī)則的靜態(tài)信息。 返回true表示運算符類的 order 函數(shù)保證僅返回0 (arguments are equal) 時,AB 參數(shù)也可以互換,而不會丟失任何語義信息。 不注冊equalimage函數(shù)或返回false表示不能假定此條件成立。

opcintype參數(shù)是操作符類索引的數(shù)據(jù)類型的pg_type.oid。 這提供一種便利,允許在操作符類之間重用相同的底層equalimage函數(shù)。 如果opcintype是可排序數(shù)據(jù)類型,則相應的排序規(guī)則 OID 將傳遞給 equalimage 函數(shù),使用標準的 PG_GET_COLLATION() 機制。

就操作符類而言,返回true意味著重復數(shù)據(jù)刪除是安全的(或安全排序規(guī)則,其OID傳遞給它的equalimage函數(shù))。 但是,核心代碼只有在every 索引列使用注冊了 equalimage 函數(shù)的操作符類時,并且每個函數(shù)在調(diào)用時實際返回 true時,才會認為重復數(shù)據(jù)刪除是安全的。

圖像相等幾乎與簡單位元(simple bitwise)相等的條件相同。 有一個細微的區(qū)別:在索引 varlena 數(shù)據(jù)類型時,由于輸入上TOAST壓縮應用不一致,兩個圖像相等基準的磁盤表示可能不是位相等的。 從形式上看,當操作符類的 equalimage函數(shù)返回 true 時,可以安全的地假定 datum_image_eq()C 函數(shù)將始終與操作符類的 order 函數(shù)一致(前提是將同一個排序規(guī)則 OID 傳遞給 equalimageorder 函數(shù))。

核心代碼從根本上無法推斷出任何關于基于同一系列中其他運算符類的詳細信息的具有多數(shù)據(jù)類型系列中的操作符類的equality implies image equality狀態(tài)。 此外,操作符系列注冊跨類型 equalimage函數(shù)是不明智的,嘗試這樣做將導致錯誤。 這是因為equality implies image equality狀態(tài)不僅僅取決于排序/相等語義,這些語義或多或少在操作符系列級別定義。 通常,特定數(shù)據(jù)類型實現(xiàn)的語義必須單獨考慮。

核心 PostgreSQL 分發(fā)中包含的操作符類所遵循的約定是注冊股票(register a stock),通用equalimage函數(shù)。 大多數(shù)操作符類注冊btequalimage(),這表明重復數(shù)據(jù)刪除是安全的。 可排序數(shù)據(jù)類型的操作符類(如 text注冊 btvarstrequalimage(),這表明在確定性排序規(guī)則下應用重復數(shù)據(jù)刪除是安全的。 第三方擴展的最佳實踐是注冊自己的自定義函數(shù)以保持控制。

options

可選地,B 樹操作符系列可以提供options操作符類指定選項)支持功能,注冊在支持函數(shù) 5 下面。 這些函數(shù)定義一組用戶可見的參數(shù),用于控制操作符類行為。

options 支持函數(shù)必須具有簽名

options(relopts local_relopts *) returns void

函數(shù)傳遞一個指向local_relopts結構的指針,需要用一組操作符類特定的選項來填充。 這些選項可以通過PG_HAS_OPCLASS_OPTIONS()PG_GET_OPCLASS_OPTIONS() 宏,從其他支持的函數(shù)進行訪問。

目前,沒有 B-Tree 操作符類具有 options支持功能。 B-tree不允許靈活表示鍵, 例如 GiST, SP-GiST, GIN 和 BRIN。 因此,options在當前的B-tree索引訪問方法中可能沒有太多的應用。 不過,此支持函數(shù)已添加到 B-tree中以保持一致性,并且可能會在PostgreSQL中B-tree的進一步演進中找到更多應用。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號