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.
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
1. Added support for toastable keys
2. Improved split algorithm for intbig (selection speedup is about 30%)
......
This diff is collapsed.
......@@ -2,6 +2,51 @@
--
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
--
......@@ -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
SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE _int_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = '_int4';
FROM pg_operator o, pg_type t, pg_type tq
WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid )
and t.typname = '_int4'
and tq.typname='query_int';
-- make sure we have the right operators
-- SELECT * from _int_ops_tmp;
......@@ -157,6 +203,23 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
and opcname = 'gist__int_ops'
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;
......@@ -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
SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE _int_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = '_int4';
FROM pg_operator o, pg_type t, pg_type tq
WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid )
and t.typname = '_int4'
and tq.typname='query_int';
-- make sure we have the right operators
-- SELECT * from _int_ops_tmp;
......@@ -295,6 +359,22 @@ INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
and opcname = 'gist__intbig_ops'
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;
......
......@@ -3,6 +3,229 @@
-- does not depend on contents of seg.sql.
--
\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[] );
\copy test__int from 'data/test__int.data'
SELECT count(*) from test__int WHERE a && '{23,50}';
......@@ -11,12 +234,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403
(1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}';
count
-------
12
(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 );
SELECT count(*) from test__int WHERE a && '{23,50}';
count
......@@ -24,12 +283,48 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403
(1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}';
count
-------
12
(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;
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
SELECT count(*) from test__int WHERE a && '{23,50}';
......@@ -38,9 +333,45 @@ SELECT count(*) from test__int WHERE a && '{23,50}';
403
(1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}';
count
-------
12
(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 @@
\i _int.sql
\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[] );
\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 @ '{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 );
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;
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 @ '{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