如何在Postgres中实现包含运算符

时间:2014-07-20 15:03:56

标签: postgresql operators plpgsql contains

如何实现包含字符串的运算符,如果左侧字符串包含在右侧字符串中,则返回true。

运营商名称可以是任意名称。我试过@@和代码,但是

select 'A' @@ 'SAS'

返回false。

如何解决?

CREATE OR REPLACE FUNCTION public.contains(searchFor text, searchIn text)
RETURNS bool

AS $BODY$ BEGIN

RETURN position( searchFor in searchIn)<>0;

END; $BODY$ language plpgsql immutable  RETURNS NULL ON NULL INPUT;

CREATE OPERATOR public.@@ (
    leftarg = text,
    rightarg = text,
    procedure = public.contains
);

在Windows和Linux中使用Postgres 9.1及以上版本。

select contains('A' , 'SAS' )

按预期返回true。

更新

我在回答中尝试了9.1代码:

CREATE OR REPLACE FUNCTION public.contains(searchFor text, searchIn text)
RETURNS bool
LANGUAGE sql IMMUTABLE
AS $BODY$
SELECT position( searchFor in searchIn )<>0;
$BODY$;


CREATE OPERATOR public.<@ (
    leftarg = text,
    rightarg = text,
    procedure = public.contains
);

但收到错误

ERROR:  column "searchin" does not exist
LINE 5: SELECT position( searchFor in searchIn )<>0;

如何让它在9.1中运行?在9.3中它起作用。

使用

“x86_64-unknown-linux-gnu上的PostgreSQL 9.1.2,由gcc-4.4 .real编译(Debian 4.4.5-8)4.4.5,64位”

1 个答案:

答案 0 :(得分:2)

PostgreSQL已经在@@架构的(text,text)上定义了pg_catalog运算符,其定义为:

regress=> \do @@
                                  List of operators
   Schema   | Name | Left arg type | Right arg type | Result type |    Description    
------------+------+---------------+----------------+-------------+-------------------
 pg_catalog | @@   | text          | text           | boolean     | text search match

这优先于您在@@架构中定义的public

我建议<@使用contains运算符,因为that's consistent with the array contains and contained-by operatorspg_catalog text中没有对pg_catalog使用它...但不保证在将来的版本或扩展中不会添加。

如果您希望保证您的运算符优先于pg_catalog中的运算符,则需要将它们放在不同的模式中,并在CREATE SCHEMA my_operators; CREATE OR REPLACE FUNCTION my_operators.contains(searchFor text, searchIn text) RETURNS bool LANGUAGE sql IMMUTABLE AS $BODY$ SELECT position( searchFor in searchIn)<>0; $BODY$; CREATE OPERATOR my_operators.<@ ( leftarg = text, rightarg = text, procedure = public.contains ); 之前明确地将其放在搜索路径上。如下所示:

SET search_path = 'my_operators, pg_catalog, public';

然后

ALTER USER

您可以使用ALTER DATABASE和/或{{1}}将其设为默认值。