Commit 484a0fa4 authored by Bruce Momjian's avatar Bruce Momjian

please apply attached patch to current CVS.

Changes:

 1. Added support for boolean queries (indexable operator @@, looks like
       a @@ '1|(2&3)'
 2. Some code cleanup and optimization

        Regards,
                Oleg
parent 296011d8
...@@ -12,6 +12,10 @@ for additional information. ...@@ -12,6 +12,10 @@ for additional information.
CHANGES: CHANGES:
September 21, 2001
1. Added support for boolean query (indexable operator @@, looks like
a @@ '1|(2&3)', perfomance is better in any case )
2. Done some small optimizations
March 19, 2001 March 19, 2001
1. Added support for toastable keys 1. Added support for toastable keys
2. Improved split algorithm for intbig (selection speedup is about 30%) 2. Improved split algorithm for intbig (selection speedup is about 30%)
......
This diff is collapsed.
...@@ -2,6 +2,51 @@ ...@@ -2,6 +2,51 @@
-- --
BEGIN TRANSACTION; BEGIN TRANSACTION;
-- Query type
CREATE FUNCTION bqarr_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE FUNCTION bqarr_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE TYPE query_int (
internallength = -1,
input = bqarr_in,
output = bqarr_out
);
--only for debug
CREATE FUNCTION querytree(query_int)
RETURNS text
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE FUNCTION boolop(_int4, query_int) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION boolop(_int4, query_int) IS 'boolean operation with array';
CREATE FUNCTION rboolop(query_int, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION rboolop(query_int, _int4) IS 'boolean operation with array';
CREATE OPERATOR @@ (
LEFTARG = _int4, RIGHTARG = query_int, PROCEDURE = boolop,
COMMUTATOR = '~~', RESTRICT = contsel, JOIN = contjoinsel
);
CREATE OPERATOR ~~ (
LEFTARG = query_int, RIGHTARG = _int4, PROCEDURE = rboolop,
COMMUTATOR = '@@', RESTRICT = contsel, JOIN = contjoinsel
);
-- --
-- External C-functions for R-tree methods -- External C-functions for R-tree methods
-- --
...@@ -111,9 +156,10 @@ INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) ...@@ -111,9 +156,10 @@ INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
-- get the comparators for _intments and store them in a tmp table -- get the comparators for _intments and store them in a tmp table
SELECT o.oid AS opoid, o.oprname SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE _int_ops_tmp INTO TEMP TABLE _int_ops_tmp
FROM pg_operator o, pg_type t FROM pg_operator o, pg_type t, pg_type tq
WHERE o.oprleft = t.oid and o.oprright = t.oid WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid )
and t.typname = '_int4'; and t.typname = '_int4'
and tq.typname='query_int';
-- make sure we have the right operators -- make sure we have the right operators
-- SELECT * from _int_ops_tmp; -- SELECT * from _int_ops_tmp;
...@@ -157,6 +203,23 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) ...@@ -157,6 +203,23 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
and opcname = 'gist__int_ops' and opcname = 'gist__int_ops'
and c.oprname = '~'; and c.oprname = '~';
--boolean search
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 20, true, c.opoid
FROM pg_opclass opcl, _int_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist__int_ops'
and c.oprname = '@@';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 20, true, c.opoid
FROM pg_opclass opcl, _int_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist__int_ops'
and c.oprname = '~~';
DROP TABLE _int_ops_tmp; DROP TABLE _int_ops_tmp;
...@@ -258,9 +321,10 @@ INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) ...@@ -258,9 +321,10 @@ INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
-- get the comparators for _intments and store them in a tmp table -- get the comparators for _intments and store them in a tmp table
SELECT o.oid AS opoid, o.oprname SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE _int_ops_tmp INTO TEMP TABLE _int_ops_tmp
FROM pg_operator o, pg_type t FROM pg_operator o, pg_type t, pg_type tq
WHERE o.oprleft = t.oid and o.oprright = t.oid WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid )
and t.typname = '_int4'; and t.typname = '_int4'
and tq.typname='query_int';
-- make sure we have the right operators -- make sure we have the right operators
-- SELECT * from _int_ops_tmp; -- SELECT * from _int_ops_tmp;
...@@ -295,6 +359,22 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) ...@@ -295,6 +359,22 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
and opcname = 'gist__intbig_ops' and opcname = 'gist__intbig_ops'
and c.oprname = '~'; and c.oprname = '~';
--boolean search
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 20, true, c.opoid
FROM pg_opclass opcl, _int_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist__intbig_ops'
and c.oprname = '@@';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 20, true, c.opoid
FROM pg_opclass opcl, _int_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist__intbig_ops'
and c.oprname = '~~';
DROP TABLE _int_ops_tmp; DROP TABLE _int_ops_tmp;
......
...@@ -3,6 +3,229 @@ ...@@ -3,6 +3,229 @@
-- does not depend on contents of seg.sql. -- does not depend on contents of seg.sql.
-- --
\set ECHO none \set ECHO none
--test query_int
select '1'::query_int;
?column?
----------
1
(1 row)
select ' 1'::query_int;
?column?
----------
1
(1 row)
select '1 '::query_int;
?column?
----------
1
(1 row)
select ' 1 '::query_int;
?column?
----------
1
(1 row)
select ' ! 1 '::query_int;
?column?
----------
!1
(1 row)
select '!1'::query_int;
?column?
----------
!1
(1 row)
select '1|2'::query_int;
?column?
----------
1 | 2
(1 row)
select '1|!2'::query_int;
?column?
----------
1 | !2
(1 row)
select '!1|2'::query_int;
?column?
----------
!1 | 2
(1 row)
select '!1|!2'::query_int;
?column?
----------
!1 | !2
(1 row)
select '!(!1|!2)'::query_int;
?column?
--------------
!( !1 | !2 )
(1 row)
select '!(!1|2)'::query_int;
?column?
-------------
!( !1 | 2 )
(1 row)
select '!(1|!2)'::query_int;
?column?
-------------
!( 1 | !2 )
(1 row)
select '!(1|2)'::query_int;
?column?
------------
!( 1 | 2 )
(1 row)
select '1&2'::query_int;
?column?
----------
1 & 2
(1 row)
select '!1&2'::query_int;
?column?
----------
!1 & 2
(1 row)
select '1&!2'::query_int;
?column?
----------
1 & !2
(1 row)
select '!1&!2'::query_int;
?column?
----------
!1 & !2
(1 row)
select '(1&2)'::query_int;
?column?
----------
1 & 2
(1 row)
select '1&(2)'::query_int;
?column?
----------
1 & 2
(1 row)
select '!(1)&2'::query_int;
?column?
----------
!1 & 2
(1 row)
select '!(1&2)'::query_int;
?column?
------------
!( 1 & 2 )
(1 row)
select '1|2&3'::query_int;
?column?
-----------
1 | 2 & 3
(1 row)
select '1|(2&3)'::query_int;
?column?
-----------
1 | 2 & 3
(1 row)
select '(1|2)&3'::query_int;
?column?
---------------
( 1 | 2 ) & 3
(1 row)
select '1|2&!3'::query_int;
?column?
------------
1 | 2 & !3
(1 row)
select '1|!2&3'::query_int;
?column?
------------
1 | !2 & 3
(1 row)
select '!1|2&3'::query_int;
?column?
------------
!1 | 2 & 3
(1 row)
select '!1|(2&3)'::query_int;
?column?
------------
!1 | 2 & 3
(1 row)
select '!(1|2)&3'::query_int;
?column?
----------------
!( 1 | 2 ) & 3
(1 row)
select '(!1|2)&3'::query_int;
?column?
----------------
( !1 | 2 ) & 3
(1 row)
select '1|(2|(4|(5|6)))'::query_int;
?column?
-------------------------------
1 | ( 2 | ( 4 | ( 5 | 6 ) ) )
(1 row)
select '1|2|4|5|6'::query_int;
?column?
-------------------------------
( ( ( 1 | 2 ) | 4 ) | 5 ) | 6
(1 row)
select '1&(2&(4&(5&6)))'::query_int;
?column?
-------------------
1 & 2 & 4 & 5 & 6
(1 row)
select '1&2&4&5&6'::query_int;
?column?
-------------------
1 & 2 & 4 & 5 & 6
(1 row)
select '1&(2&(4&(5|6)))'::query_int;
?column?
-----------------------
1 & 2 & 4 & ( 5 | 6 )
(1 row)
select '1&(2&(4&(5|!6)))'::query_int;
?column?
------------------------
1 & 2 & 4 & ( 5 | !6 )
(1 row)
CREATE TABLE test__int( a int[] ); CREATE TABLE test__int( a int[] );
\copy test__int from 'data/test__int.data' \copy test__int from 'data/test__int.data'
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
...@@ -11,12 +234,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}'; ...@@ -11,12 +234,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403 403
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
count count
------- -------
12 12
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23&50';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @@ '50&68';
count
-------
9
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
count
-------
21
(1 row)
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
count
-------
21
(1 row)
CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); CREATE INDEX text_idx on test__int using gist ( a gist__int_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
count count
...@@ -24,12 +283,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}'; ...@@ -24,12 +283,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403 403
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
count count
------- -------
12 12
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23&50';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @@ '50&68';
count
-------
9
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
count
-------
21
(1 row)
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
count
-------
21
(1 row)
drop index text_idx; drop index text_idx;
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
...@@ -38,9 +333,45 @@ SELECT count(*) from test__int WHERE a && '{23,50}'; ...@@ -38,9 +333,45 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403 403
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
count count
------- -------
12 12
(1 row) (1 row)
SELECT count(*) from test__int WHERE a @@ '23&50';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @@ '50&68';
count
-------
9
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
count
-------
21
(1 row)
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
count
-------
21
(1 row)
...@@ -6,21 +6,79 @@ ...@@ -6,21 +6,79 @@
\i _int.sql \i _int.sql
\set ECHO all \set ECHO all
--test query_int
select '1'::query_int;
select ' 1'::query_int;
select '1 '::query_int;
select ' 1 '::query_int;
select ' ! 1 '::query_int;
select '!1'::query_int;
select '1|2'::query_int;
select '1|!2'::query_int;
select '!1|2'::query_int;
select '!1|!2'::query_int;
select '!(!1|!2)'::query_int;
select '!(!1|2)'::query_int;
select '!(1|!2)'::query_int;
select '!(1|2)'::query_int;
select '1&2'::query_int;
select '!1&2'::query_int;
select '1&!2'::query_int;
select '!1&!2'::query_int;
select '(1&2)'::query_int;
select '1&(2)'::query_int;
select '!(1)&2'::query_int;
select '!(1&2)'::query_int;
select '1|2&3'::query_int;
select '1|(2&3)'::query_int;
select '(1|2)&3'::query_int;
select '1|2&!3'::query_int;
select '1|!2&3'::query_int;
select '!1|2&3'::query_int;
select '!1|(2&3)'::query_int;
select '!(1|2)&3'::query_int;
select '(!1|2)&3'::query_int;
select '1|(2|(4|(5|6)))'::query_int;
select '1|2|4|5|6'::query_int;
select '1&(2&(4&(5&6)))'::query_int;
select '1&2&4&5&6'::query_int;
select '1&(2&(4&(5|6)))'::query_int;
select '1&(2&(4&(5|!6)))'::query_int;
CREATE TABLE test__int( a int[] ); CREATE TABLE test__int( a int[] );
\copy test__int from 'data/test__int.data' \copy test__int from 'data/test__int.data'
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23|50';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23&50';
SELECT count(*) from test__int WHERE a @ '{20,23}';
SELECT count(*) from test__int WHERE a @@ '50&68';
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); CREATE INDEX text_idx on test__int using gist ( a gist__int_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23|50';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23&50';
SELECT count(*) from test__int WHERE a @ '{20,23}';
SELECT count(*) from test__int WHERE a @@ '50&68';
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
drop index text_idx; drop index text_idx;
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23|50';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
SELECT count(*) from test__int WHERE a @@ '23&50';
SELECT count(*) from test__int WHERE a @ '{20,23}';
SELECT count(*) from test__int WHERE a @@ '50&68';
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment