支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

CREATE OPERATOR

CREATE OPERATOR — 定義一個新的運算子

概要

CREATE OPERATOR name (
    {FUNCTION|PROCEDURE} = function_name
    [, LEFTARG = left_type ] [, RIGHTARG = right_type ]
    [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
    [, RESTRICT = res_proc ] [, JOIN = join_proc ]
    [, HASHES ] [, MERGES ]
)

描述

CREATE OPERATOR 定義一個新的運算子,name。定義運算子的使用者成為其擁有者。如果給定了綱要名稱,則會在指定的綱要中建立運算子。否則,它會在目前的綱要中建立。

運算子名稱是最多 NAMEDATALEN-1 (預設為 63) 個字元的序列,來自以下清單


+ - * / < > = ~ ! @ # % ^ & | ` ?

對您選擇的名稱有一些限制

  • --/* 不能出現在運算子名稱的任何地方,因為它們會被視為註解的開始。

  • 多字元運算子名稱不能以 +- 結尾,除非該名稱也包含至少一個以下字元


    ~ ! @ # % ^ & | ` ?

    例如,@- 是一個允許的運算子名稱,但 *- 不是。此限制允許 PostgreSQL 解析符合 SQL 標準的命令,而不需要符號之間的空格。

  • 符號 => 由 SQL 語法保留,因此不能用作運算子名稱。

運算子 != 在輸入時會被對應到 <>,因此這兩個名稱始終等效。

對於二元運算子,必須定義 LEFTARGRIGHTARG。對於前綴運算子,僅應定義 RIGHTARGfunction_name 函式必須先前已使用 CREATE FUNCTION 定義,並且必須定義為接受指示類型的正確數量的引數(一個或兩個)。

CREATE OPERATOR 的語法中,關鍵字 FUNCTIONPROCEDURE 是等效的,但無論如何,引用的函式必須是一個函式,而不是一個程序。此處使用關鍵字 PROCEDURE 是歷史遺留問題,不建議使用。

其他子句指定了可選的運算子最佳化屬性。它們的含義在 第 36.15 節 中有詳細說明。

要能夠建立運算子,您必須對引數類型和傳回類型具有 USAGE 權限,以及對底層函式具有 EXECUTE 權限。如果指定了交換器或否定器運算子,您必須擁有這些運算子。

參數

name

要定義的運算子的名稱。有關允許的字元,請參閱上文。該名稱可以是綱要限定的,例如 CREATE OPERATOR myschema.+ (...)。如果不是,則會在目前的綱要中建立運算子。如果同一綱要中的兩個運算子作用於不同的資料類型,則它們可以具有相同的名稱。這稱為多載

function_name

用於實作此運算子的函式。

left_type

運算子左運算元的資料類型(如果有的話)。對於前綴運算子,此選項將被省略。

right_type

運算子右運算元的資料類型。

com_op

此運算子的交換器。

neg_op

此運算子的否定器。

res_proc

此運算子的限制選擇性估計器函式。

join_proc

此運算子的連接選擇性估計器函式。

HASHES

表示此運算子可以支援雜湊連接。

MERGES

表示此運算子可以支援合併連接。

要在 com_op 或其他可選引數中給定綱要限定的運算子名稱,請使用 OPERATOR() 語法,例如

COMMUTATOR = OPERATOR(myschema.===) ,

注釋

有關更多資訊,請參閱 第 36.14 節第 36.15 節

當您定義一個自交換運算子時,您只需執行它即可。當您定義一對可交換的運算子時,事情會稍微棘手:第一個要定義的運算子如何引用另一個尚未定義的運算子?解決這個問題有三種方法

  • 一種方法是在您定義的第一個運算子中省略 COMMUTATOR 子句,然後在第二個運算子的定義中提供一個。由於 PostgreSQL 知道可交換運算子成對出現,因此當它看到第二個定義時,它會自動返回並在第一個定義中填寫遺失的 COMMUTATOR 子句。

  • 另一個更直接的方法是在兩個定義中都包含 COMMUTATOR 子句。當 PostgreSQL 處理第一個定義並發現 COMMUTATOR 引用了一個不存在的運算子時,系統將在系統目錄中為該運算子建立一個虛擬條目。這個虛擬條目將僅包含運算子名稱、左側和右側運算元類型以及所有者的有效資料,因為這是 PostgreSQL 在此時可以推斷出的所有資訊。第一個運算子的目錄條目將連結到這個虛擬條目。稍後,當您定義第二個運算子時,系統會使用第二個定義中的其他資訊更新虛擬條目。如果您嘗試在使用虛擬運算子之前使用它,您將只會收到錯誤訊息。

  • 或者,可以在沒有 COMMUTATOR 子句的情況下定義這兩個運算子,然後使用 ALTER OPERATOR 來設定它們的可交換運算子連結。對任一對運算子執行 ALTER 操作就足夠了。

在這三種情況下,您必須擁有這兩個運算子才能將它們標記為可交換運算子。

可以使用與可交換運算子對相同的方法來定義否定運算子對。

無法在 CREATE OPERATOR 中指定運算子的詞彙優先順序,因為剖析器的優先順序行為是硬式編碼的。有關優先順序的詳細資訊,請參閱第 4.1.6 節

過時的選項 SORT1SORT2LTCMPGTCMP 以前用於指定與可合併聯結運算子相關聯的排序運算子的名稱。這不再必要,因為現在可以透過查看 B-tree 運算子族來找到有關關聯運算子的資訊。如果給出其中一個選項,則會忽略它,除了隱式設定 MERGES 為 true 之外。

使用 DROP OPERATOR 從資料庫中刪除使用者定義的運算子。使用 ALTER OPERATOR 修改資料庫中的運算子。

範例

以下命令為資料類型 box 定義一個新的運算子,面積相等性。

CREATE OPERATOR === (
    LEFTARG = box,
    RIGHTARG = box,
    FUNCTION = area_equal_function,
    COMMUTATOR = ===,
    NEGATOR = !==,
    RESTRICT = area_restriction_function,
    JOIN = area_join_function,
    HASHES, MERGES
);

相容性

CREATE OPERATOR 是一個 PostgreSQL 擴充功能。SQL 標準中沒有針對使用者定義運算子的規定。

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用此表單報告文件問題。