2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 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 資料型別定義了一個新的運算子,area-equality

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

相容性

CREATE OPERATORPostgreSQL 的擴充套件。SQL 標準中沒有為使用者定義的運算子提供任何規定。

提交更正

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