CREATE OPERATOR
名稱
CREATE OPERATOR ― 定義一個(gè)新的用戶操作符
語(yǔ)法
CREATE OPERATOR name ( PROCEDURE = func_name
[, LEFTARG = type1 ] [, RIGHTARG = type2 ]
[, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
[, RESTRICT = res_proc ] [, JOIN = join_proc ]
[, HASHES ] [, SORT1 = left_sort_op ] [, SORT2 = right_sort_op ] )
輸入
name
定義的操作符名.可用的字符見下文?!?
func_name
用于實(shí)現(xiàn)該操作符的函數(shù)?!?
type1
如果存在的話,操作符左手邊的參數(shù)類型.如果是右目操作符,這個(gè)參數(shù)可以省略。
type2
如果存在的話,操作符右手邊的參數(shù)類型.如果是左目操作符,這個(gè)參數(shù)可以省略?!?
com_op
對(duì)應(yīng)的換向(commutative)操作符。
neg_op
對(duì)應(yīng)的負(fù)操作符。
res_proc
此操作符約束選擇性評(píng)估函數(shù)?!?
join_proc
此操作符的聯(lián)合選擇性評(píng)估函數(shù)。
HASHES
表明此操作符支持哈希(散列)聯(lián)合算法。
left_sort_op
如果此操作符支持融合聯(lián)合(join),此操作符的左邊數(shù)據(jù)的排序操作符?!?
right_sort_op
如果此操作符支持融合聯(lián)合(join),此操作符的右邊數(shù)據(jù)的排序操作符?!?
輸出
CREATE
成功創(chuàng)建操作符后的返回信息.
描述
CREATE OPERATOR 定義一個(gè)新的操作符, name?。x該操作符的用戶成為其所有者.
操作符 name 是一個(gè)最多 NAMEDATALEN-1 長(zhǎng)的(缺省委 31 個(gè))下列字符組成的字串.
+ - * / < > = ~ ! @ # % ^ & | ` ? $ :
你選擇名字的時(shí)候有幾個(gè)限制:
"$" 和 ":" 不能定義為單字符操作符,盡管它們可以是一個(gè)多字符操作符的名稱的一部分.
"--" 和 "/*" 不能在操作符名字的任何地方出現(xiàn),因?yàn)樗鼈儠?huì)被認(rèn)為是一個(gè)注釋的開始.
一個(gè)多字符的操作符名字不能以 "+" 或 "-" 結(jié)尾,除非該名字還包含至少下面字符之一:
~ ! @ # % ^ & | ` ? $ :
例如,@- 是一個(gè)允許的操作符名,但 *- 不是.這個(gè)限制允許 Postgres 分析 SQL-有問(wèn)題的查詢而不要求在符號(hào)之間有空白.
請(qǐng)注意:當(dāng)使用非 SQL-標(biāo)準(zhǔn)操作符名時(shí),你通常將需要用空白把聯(lián)接的操作符分離開以避免含混.例如,如果你定義了一個(gè)左目操作符,名為 "@",你不能寫 X*@Y;你必須些成 X* @Y 以保證 Postgres 把它讀做兩個(gè)操作符而不是一個(gè).
操作符 "!=" 在輸入時(shí)映射成 "<>" , 因?yàn)檫@兩個(gè)名稱總是相等的.
至少需要定義一個(gè) LEFTARG 或 RIGHTARG .對(duì)于雙目操作符來(lái)說(shuō),兩者都需要定義.對(duì)右目操作符來(lái)說(shuō),只需要定義 LEFTARG,而對(duì)于左目操作符來(lái)說(shuō),只需要定義 RIGHTARG.
同樣, func_name 過(guò)程必須已經(jīng)用 CREATE FUNCTION 定義過(guò),而且必須定義為接受正確數(shù)量的參數(shù)(一個(gè)或是兩個(gè)).
換向操作符用于令 Postgres 可以按它的意愿轉(zhuǎn)換操作符的方向.例如,操作符面積小于,<<<,就有一個(gè)轉(zhuǎn)換操作符:面積大于操作符, >>>.因此,查詢優(yōu)化器可以自由的將下面查詢從:
box '((0,0),(1,1))' >>> MYBOXES.description
轉(zhuǎn)換到
MYBOXES.description <<< box '((0,0),(1,1))'
這就允許執(zhí)行代碼總是使用后面的形式而某種程度上簡(jiǎn)化了查詢優(yōu)化器.
類似地,如果存在負(fù)號(hào)操作符則應(yīng)該聲明。假設(shè)一個(gè)操作符,面積相等, ===,存在,同樣有一個(gè)面積不等操作符,!==.負(fù)號(hào)操作符允許查詢優(yōu)化器將
NOT MYBOXES.description === box '((0,0),(1,1))'
簡(jiǎn)化成
MYBOXES.description !== box '((0,0),(1,1))'
如果提供了一個(gè)轉(zhuǎn)換器操作符名稱,Postgres 將在目錄中查找它.如果找到,而且其本身沒(méi)有一個(gè)轉(zhuǎn)換器,那么轉(zhuǎn)換器表將被更新,以當(dāng)前(最新)操作符作為它的轉(zhuǎn)換器.這一點(diǎn)一樣適用于負(fù)號(hào)操作符.這就允許定義兩個(gè)互為轉(zhuǎn)換器或負(fù)號(hào)符的操作符.第一個(gè)操作符應(yīng)該定義為沒(méi)有轉(zhuǎn)換器或負(fù)號(hào)符(as appropriate).當(dāng)定義第二個(gè)操作符時(shí),將第一個(gè)符號(hào)作為轉(zhuǎn)換器或負(fù)號(hào)符.第一個(gè)將因上述的副作用一樣被更新(而獲得轉(zhuǎn)換器或負(fù)號(hào)符).(對(duì)于 Postgres 6.5,把兩個(gè)操作符指向?qū)Ψ酵瑯右残?。)?
HASHES,SORT1 和 SORT2 選項(xiàng)將為查詢優(yōu)化器進(jìn)行聯(lián)合查詢時(shí)提供支持.Postgres 能夠總是用語(yǔ)義替換 [WONG76] 來(lái)計(jì)算一個(gè)聯(lián)合(也就是說(shuō),處理這樣的子句,該子句有兩個(gè)記錄變量,這兩個(gè)變量被一個(gè)操作符分開,最后這個(gè)子句返回一個(gè)布爾量).另外, Postgres 準(zhǔn)備在行[SHAP86](?)實(shí)現(xiàn)一個(gè)哈希-聯(lián)合算法(hash-join algorithm);但是,我們必須知道這個(gè)策略是否可行.目前的哈希-聯(lián)合算法只是對(duì)代表相等測(cè)試的操作符有效;而且,數(shù)據(jù)類型的相等必須意味著類型的表現(xiàn)是按位相等的。(例如,一個(gè)包含未用的位的數(shù)據(jù)類型,這些位對(duì)相等測(cè)試沒(méi)有影響,但卻不能用于哈希聯(lián)合。)HASHES 標(biāo)記告訴優(yōu)化器,對(duì)這個(gè)操作符可以安全地使用哈希聯(lián)合?!?
類似的,兩目排序操作符告訴查詢優(yōu)化器一個(gè)融合-排序(merge-sort)是否是一個(gè)可用的聯(lián)合策略,并且告訴優(yōu)化器使用哪個(gè)操作符來(lái)對(duì)這兩個(gè)操作數(shù)表排序.排序操作符應(yīng)該只提供給相等操作符,并且它們應(yīng)該對(duì)應(yīng)用于對(duì)應(yīng)的左邊和右邊數(shù)據(jù)類型的小于操作符?!?
如果發(fā)現(xiàn)其他聯(lián)合策略可用, Postgres 將更改優(yōu)化器和運(yùn)行時(shí)系統(tǒng)以利用這些策略,并且在定義一個(gè)操作符時(shí)將需要更多的聲明.幸運(yùn)的是,研究團(tuán)隊(duì)不經(jīng)常發(fā)明新的聯(lián)合策略,而且增加用戶定義聯(lián)合策略的方法看來(lái)與其實(shí)現(xiàn)的復(fù)雜性相比是不值得的?!?
RESTRICT 和 JOIN 選項(xiàng)幫助優(yōu)化器計(jì)算結(jié)果的尺寸大小.如果像下面的語(yǔ)句:
MYBOXES.description <<< box '((0,0),(1,1))'
在判斷條件中出現(xiàn),那么 Postgres 將不得不估計(jì) MYBOXES 中滿足該子句的記錄數(shù)量的范圍的大?。瘮?shù) res_proc 必需是一個(gè)注冊(cè)過(guò)的函數(shù)(也就是說(shuō)它已經(jīng)用 CREATE FUNCTION 定義過(guò)了),它接受一個(gè)正確數(shù)據(jù)的數(shù)據(jù)類型作為參數(shù),返回一個(gè)浮點(diǎn)數(shù).查詢優(yōu)化器只是簡(jiǎn)單的調(diào)用這個(gè)函數(shù),將參數(shù) ((0,0),(1,1)) 傳入并且把結(jié)果乘以關(guān)系(表)尺寸以獲得所需要的記錄的數(shù)值?!?
類似的,當(dāng)操作符的操作數(shù)都包含記錄變量時(shí),優(yōu)化器必須計(jì)算聯(lián)合結(jié)果的尺寸.函數(shù) join_proc 將返回另一個(gè)浮點(diǎn)數(shù),這個(gè)數(shù)就是將兩個(gè)表相關(guān)的記錄相乘,計(jì)算出預(yù)期結(jié)果的尺寸.
函數(shù)
my_procedure_1 (MYBOXES.description, box '((0,0),(1,1))')
和操作符
MYBOXES.description === box '((0,0),(1,1))'
之間的區(qū)別是 Postgres 試圖優(yōu)化操作符并且可以決定使用索引來(lái)縮小相關(guān)操作符的搜索區(qū)間.但是,對(duì)函數(shù)將不會(huì)有任何優(yōu)化的動(dòng)作,而且是強(qiáng)制執(zhí)行.最后,函數(shù)可有任意個(gè)參數(shù),而操作符限于一個(gè)或兩個(gè).
注意
請(qǐng)參閱PostgreSQL 用戶手冊(cè) 中操作符章節(jié)獲取更多信息.請(qǐng)使用 DROP OPERATOR 從數(shù)據(jù)庫(kù)中刪除用戶定義操作符.
用法
下面命令定義一個(gè)新操作符,面積相等,用于 BOX 數(shù)據(jù)類型.
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
PROCEDURE = area_equal_procedure,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = area_restriction_procedure,
JOIN = area_join_procedure,
HASHES,
SORT1 = <<<,
SORT2 = <<<
);
兼容性
SQL92
CREATE OPERATOR 是 Postgres 擴(kuò)展.在 SQL92 中沒(méi)有 CREATE OPERATOR 語(yǔ)句.