int是否可以多載 PostgreSQL 中現有的相等運算子以給出兩個型別或值之間相等的新定義real?我認為這違反了多載規則,但我想知道是否有辦法做到這一點。我試過這個:
CREATE OPERATOR = ( LEFTARG = real ,
RIGHTARG = real,
PROCEDURE = new_equality,
COMMUTATOR = = ,
NEGATOR = !=
);
CREATE OR REPLACE FUNCTION new_equality (real, real) RETURNS BOOLEAN AS
$$
SELECT abs ($1 - $2) < 0,2 ;
$$ LANGUAGE PL/PGSQL
但是當我在查詢中使用相等運算子時,我沒有得到任何結果。
我還嘗試將new_equality()函式引數定義為我的屬性型別,如下所示:
CREATE OR REPLACE FUNCTION new_equality (Student.age%TYPE, Student.age%TYPE) RETURNS BOOLEAN
AS
$$
SELECT abs ($1 - $2) < 0,2;
$$ lANGUAGE PL/PGSQL
但是我收到一條通知,說 Postgres 將它們轉換為real,當我在查詢中使用相等運算子時,我仍然沒有得到任何結果。
uj5u.com熱心網友回復:
Laurenz 指出了眼前的問題search_path。還有更多。
假設Postgres 14,這將作業:
CREATE OR REPLACE FUNCTION public.new_equality (real, real) -- be explicit about the schema!
RETURNS bool
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE COST 10
BEGIN ATOMIC
SELECT abs($1 - $2) < 0.2;
END;
CREATE OR REPLACE FUNCTION public.new_inequality (real, real) -- be explicit about the schema!
RETURNS bool
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE COST 10
BEGIN ATOMIC
SELECT abs($1 - $2) >= 0.2;
END;
CREATE OPERATOR public.= ( -- be explicit about the schema!
LEFTARG = real
, RIGHTARG = real
, FUNCTION = public.new_equality
, COMMUTATOR = OPERATOR(public.=) -- be explicit about the schema!
, NEGATOR = OPERATOR(public.!=) -- must also exist
);
CREATE OPERATOR public.!= (
LEFTARG = real
, RIGHTARG = real
, FUNCTION = public.new_inequality
, COMMUTATOR = OPERATOR(public.!=)
, NEGATOR = OPERATOR(public.=)
);
使用OPERATOR()構造來呼叫它:
SELECT id, real '0.1' OPERATOR(public.=) real '0.2';
SELECT id, real '0.1' OPERATOR(public.!=) real '0.2';
SELECT id, real '0.1' OPERATOR(public.<>) real '0.2';
db<>fiddle here - 更多示例
請注意更高的運算子優先級,可能會在普通運算子不會強制使用括號!
您還必須定義您在宣告中NEGATOR提到的內容。使用內置!=將是矛盾的廢話。創建一個匹配的運算子,您必須使用模式限定的語法來參考它。手冊:
要在
com_op或其他可選引數中提供模式限定的運算子名稱,請使用OPERATOR()語法 [...]
有關的:
- 如何使用擴展 pg_trgm 中的 % 運算子?
- smallint[] 列上的 GIN 索引未使用或錯誤“操作員不是唯一的”
請注意,它<>是 , 的自動別名!=,并且<>是 SQL 中的默認不等式運算子。
不合格的=將是標準的相等運算子 ( OPERATOR(pg_catalog.=)),而您不會弄亂search_path降級pg_catalog- 這是您不應該的!降級pg_catalog為各種嚴重問題打開了大門,因為系統物件現在隱藏在一個或多個其他模式之后。除非您確切知道自己在做什么,否則不要這樣做。關于search_path:
- search_path 如何影響識別符號決議和“當前模式”
這假設至少 Postgres 14。關于BEGIN ATOMIC:
- 如何在 PostgreSQL 中實作“BEGIN ATOMIC”
使用關鍵字FUNCTION而不是誤導性的PROCEDURE,這對于向后兼容仍然有效。看:
- 觸發器使用程序還是函式?
與建議的 a_horse_with_no_name一樣,使用與現有運算子不同的運算子符號以避免沖突可能更方便。與默認比較運算子相比,仍具有標準(= 更高)運算子優先級,并且不能輕易更改。
uj5u.com熱心網友回復:
您的代碼無效(應該是LANGUAGE sql),但您的運算子不會被使用,因為pg_catalog它隱式地首先在search_path.
您可以更改search_path為放在pg_catalog其他地方:
SET search_path = public, pg_catalog;
或者您可以明確參考運算子:
SELECT 1::real OPERATOR(public.=) 1.1::real;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/432603.html
標籤:sql PostgreSQL 运算符重载
