Review: B-Tree emulation for GIN

Started by Ibrar Ahmedabout 17 years ago35 messages
#1Ibrar Ahmed
ibrar.ahmad@gmail.com
1 attachment(s)

Hi Teodor Sigaev,

I am getting server crash in contrib regression. May be I am doing something
wrong here. Regression diff is attached.

BTW these queries work fine outside the regression.

--
Ibrar Ahmed
EnterpriseDB http://www.enterprisedb.com

Attachments:

regression.diffsapplication/octet-stream; name=regression.diffsDownload
*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/int2.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/int2.out	Wed Dec 17 23:18:03 2008
***************
*** 5,44 ****
  INSERT INTO test_int2 VALUES (-2),(-1),(0),(1),(2),(3);
  CREATE INDEX idx_int2 ON test_int2 USING gin (i);
  SELECT * FROM test_int2 WHERE i<1::int2 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
! (3 rows)
! 
! SELECT * FROM test_int2 WHERE i<=1::int2 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
!   1
! (4 rows)
! 
! SELECT * FROM test_int2 WHERE i=1::int2 ORDER BY i;
!  i 
! ---
!  1
! (1 row)
! 
! SELECT * FROM test_int2 WHERE i>=1::int2 ORDER BY i;
!  i 
! ---
!  1
!  2
!  3
! (3 rows)
! 
! SELECT * FROM test_int2 WHERE i>1::int2 ORDER BY i;
!  i 
! ---
!  2
!  3
! (2 rows)
! 
--- 5,11 ----
  INSERT INTO test_int2 VALUES (-2),(-1),(0),(1),(2),(3);
  CREATE INDEX idx_int2 ON test_int2 USING gin (i);
  SELECT * FROM test_int2 WHERE i<1::int2 ORDER BY i;
! server closed the connection unexpectedly
! 	This probably means the server terminated abnormally
! 	before or while processing the request.
! connection to server was lost

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/int4.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/int4.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_int4 (
! 	i int4
! );
! INSERT INTO test_int4 VALUES (-2),(-1),(0),(1),(2),(3);
! CREATE INDEX idx_int4 ON test_int4 USING gin (i);
! SELECT * FROM test_int4 WHERE i<1::int4 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
! (3 rows)
! 
! SELECT * FROM test_int4 WHERE i<=1::int4 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
!   1
! (4 rows)
! 
! SELECT * FROM test_int4 WHERE i=1::int4 ORDER BY i;
!  i 
! ---
!  1
! (1 row)
! 
! SELECT * FROM test_int4 WHERE i>=1::int4 ORDER BY i;
!  i 
! ---
!  1
!  2
!  3
! (3 rows)
! 
! SELECT * FROM test_int4 WHERE i>1::int4 ORDER BY i;
!  i 
! ---
!  2
!  3
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/int8.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/int8.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_int8 (
! 	i int8
! );
! INSERT INTO test_int8 VALUES (-2),(-1),(0),(1),(2),(3);
! CREATE INDEX idx_int8 ON test_int8 USING gin (i);
! SELECT * FROM test_int8 WHERE i<1::int8 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
! (3 rows)
! 
! SELECT * FROM test_int8 WHERE i<=1::int8 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
!   1
! (4 rows)
! 
! SELECT * FROM test_int8 WHERE i=1::int8 ORDER BY i;
!  i 
! ---
!  1
! (1 row)
! 
! SELECT * FROM test_int8 WHERE i>=1::int8 ORDER BY i;
!  i 
! ---
!  1
!  2
!  3
! (3 rows)
! 
! SELECT * FROM test_int8 WHERE i>1::int8 ORDER BY i;
!  i 
! ---
!  2
!  3
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/float4.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/float4.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_float4 (
! 	i float4
! );
! INSERT INTO test_float4 VALUES (-2),(-1),(0),(1),(2),(3);
! CREATE INDEX idx_float4 ON test_float4 USING gin (i);
! SELECT * FROM test_float4 WHERE i<1::float4 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
! (3 rows)
! 
! SELECT * FROM test_float4 WHERE i<=1::float4 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
!   1
! (4 rows)
! 
! SELECT * FROM test_float4 WHERE i=1::float4 ORDER BY i;
!  i 
! ---
!  1
! (1 row)
! 
! SELECT * FROM test_float4 WHERE i>=1::float4 ORDER BY i;
!  i 
! ---
!  1
!  2
!  3
! (3 rows)
! 
! SELECT * FROM test_float4 WHERE i>1::float4 ORDER BY i;
!  i 
! ---
!  2
!  3
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/float8.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/float8.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_float8 (
! 	i float8
! );
! INSERT INTO test_float8 VALUES (-2),(-1),(0),(1),(2),(3);
! CREATE INDEX idx_float8 ON test_float8 USING gin (i);
! SELECT * FROM test_float8 WHERE i<1::float8 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
! (3 rows)
! 
! SELECT * FROM test_float8 WHERE i<=1::float8 ORDER BY i;
!  i  
! ----
!  -2
!  -1
!   0
!   1
! (4 rows)
! 
! SELECT * FROM test_float8 WHERE i=1::float8 ORDER BY i;
!  i 
! ---
!  1
! (1 row)
! 
! SELECT * FROM test_float8 WHERE i>=1::float8 ORDER BY i;
!  i 
! ---
!  1
!  2
!  3
! (3 rows)
! 
! SELECT * FROM test_float8 WHERE i>1::float8 ORDER BY i;
!  i 
! ---
!  2
!  3
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/money.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/money.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_money (
! 	i money
! );
! INSERT INTO test_money VALUES ('-2'),('-1'),('0'),('1'),('2'),('3');
! CREATE INDEX idx_money ON test_money USING gin (i);
! SELECT * FROM test_money WHERE i<'1'::money ORDER BY i;
!    i    
! --------
!  -$2.00
!  -$1.00
!   $0.00
! (3 rows)
! 
! SELECT * FROM test_money WHERE i<='1'::money ORDER BY i;
!    i    
! --------
!  -$2.00
!  -$1.00
!   $0.00
!   $1.00
! (4 rows)
! 
! SELECT * FROM test_money WHERE i='1'::money ORDER BY i;
!    i   
! -------
!  $1.00
! (1 row)
! 
! SELECT * FROM test_money WHERE i>='1'::money ORDER BY i;
!    i   
! -------
!  $1.00
!  $2.00
!  $3.00
! (3 rows)
! 
! SELECT * FROM test_money WHERE i>'1'::money ORDER BY i;
!    i   
! -------
!  $2.00
!  $3.00
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/oid.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/oid.out	Wed Dec 17 23:18:03 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_oid (
! 	i oid
! );
! INSERT INTO test_oid VALUES (0),(1),(2),(3),(4),(5);
! CREATE INDEX idx_oid ON test_oid USING gin (i);
! SELECT * FROM test_oid WHERE i<3::oid ORDER BY i;
!  i 
! ---
!  0
!  1
!  2
! (3 rows)
! 
! SELECT * FROM test_oid WHERE i<=3::oid ORDER BY i;
!  i 
! ---
!  0
!  1
!  2
!  3
! (4 rows)
! 
! SELECT * FROM test_oid WHERE i=3::oid ORDER BY i;
!  i 
! ---
!  3
! (1 row)
! 
! SELECT * FROM test_oid WHERE i>=3::oid ORDER BY i;
!  i 
! ---
!  3
!  4
!  5
! (3 rows)
! 
! SELECT * FROM test_oid WHERE i>3::oid ORDER BY i;
!  i 
! ---
!  4
!  5
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/timestamp.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/timestamp.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_timestamp (
! 	i timestamp
! );
! INSERT INTO test_timestamp VALUES 
! 	( '2004-10-26 03:55:08' ),
! 	( '2004-10-26 04:55:08' ),
! 	( '2004-10-26 05:55:08' ),
! 	( '2004-10-26 08:55:08' ),
! 	( '2004-10-26 09:55:08' ),
! 	( '2004-10-26 10:55:08' )
! ;
! CREATE INDEX idx_timestamp ON test_timestamp USING gin (i);
! SELECT * FROM test_timestamp WHERE i<'2004-10-26 08:55:08'::timestamp ORDER BY i;
!             i             
! --------------------------
!  Tue Oct 26 03:55:08 2004
!  Tue Oct 26 04:55:08 2004
!  Tue Oct 26 05:55:08 2004
! (3 rows)
! 
! SELECT * FROM test_timestamp WHERE i<='2004-10-26 08:55:08'::timestamp ORDER BY i;
!             i             
! --------------------------
!  Tue Oct 26 03:55:08 2004
!  Tue Oct 26 04:55:08 2004
!  Tue Oct 26 05:55:08 2004
!  Tue Oct 26 08:55:08 2004
! (4 rows)
! 
! SELECT * FROM test_timestamp WHERE i='2004-10-26 08:55:08'::timestamp ORDER BY i;
!             i             
! --------------------------
!  Tue Oct 26 08:55:08 2004
! (1 row)
! 
! SELECT * FROM test_timestamp WHERE i>='2004-10-26 08:55:08'::timestamp ORDER BY i;
!             i             
! --------------------------
!  Tue Oct 26 08:55:08 2004
!  Tue Oct 26 09:55:08 2004
!  Tue Oct 26 10:55:08 2004
! (3 rows)
! 
! SELECT * FROM test_timestamp WHERE i>'2004-10-26 08:55:08'::timestamp ORDER BY i;
!             i             
! --------------------------
!  Tue Oct 26 09:55:08 2004
!  Tue Oct 26 10:55:08 2004
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/timestamptz.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/timestamptz.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_timestamptz (
! 	i timestamptz
! );
! INSERT INTO test_timestamptz VALUES 
! 	( '2004-10-26 03:55:08' ),
! 	( '2004-10-26 04:55:08' ),
! 	( '2004-10-26 05:55:08' ),
! 	( '2004-10-26 08:55:08' ),
! 	( '2004-10-26 09:55:08' ),
! 	( '2004-10-26 10:55:08' )
! ;
! CREATE INDEX idx_timestamptz ON test_timestamptz USING gin (i);
! SELECT * FROM test_timestamptz WHERE i<'2004-10-26 08:55:08'::timestamptz ORDER BY i;
!               i               
! ------------------------------
!  Tue Oct 26 03:55:08 2004 PDT
!  Tue Oct 26 04:55:08 2004 PDT
!  Tue Oct 26 05:55:08 2004 PDT
! (3 rows)
! 
! SELECT * FROM test_timestamptz WHERE i<='2004-10-26 08:55:08'::timestamptz ORDER BY i;
!               i               
! ------------------------------
!  Tue Oct 26 03:55:08 2004 PDT
!  Tue Oct 26 04:55:08 2004 PDT
!  Tue Oct 26 05:55:08 2004 PDT
!  Tue Oct 26 08:55:08 2004 PDT
! (4 rows)
! 
! SELECT * FROM test_timestamptz WHERE i='2004-10-26 08:55:08'::timestamptz ORDER BY i;
!               i               
! ------------------------------
!  Tue Oct 26 08:55:08 2004 PDT
! (1 row)
! 
! SELECT * FROM test_timestamptz WHERE i>='2004-10-26 08:55:08'::timestamptz ORDER BY i;
!               i               
! ------------------------------
!  Tue Oct 26 08:55:08 2004 PDT
!  Tue Oct 26 09:55:08 2004 PDT
!  Tue Oct 26 10:55:08 2004 PDT
! (3 rows)
! 
! SELECT * FROM test_timestamptz WHERE i>'2004-10-26 08:55:08'::timestamptz ORDER BY i;
!               i               
! ------------------------------
!  Tue Oct 26 09:55:08 2004 PDT
!  Tue Oct 26 10:55:08 2004 PDT
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/time.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/time.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_time (
! 	i time
! );
! INSERT INTO test_time VALUES 
! 	( '03:55:08' ),
! 	( '04:55:08' ),
! 	( '05:55:08' ),
! 	( '08:55:08' ),
! 	( '09:55:08' ),
! 	( '10:55:08' )
! ;
! CREATE INDEX idx_time ON test_time USING gin (i);
! SELECT * FROM test_time WHERE i<'08:55:08'::time ORDER BY i;
!     i     
! ----------
!  03:55:08
!  04:55:08
!  05:55:08
! (3 rows)
! 
! SELECT * FROM test_time WHERE i<='08:55:08'::time ORDER BY i;
!     i     
! ----------
!  03:55:08
!  04:55:08
!  05:55:08
!  08:55:08
! (4 rows)
! 
! SELECT * FROM test_time WHERE i='08:55:08'::time ORDER BY i;
!     i     
! ----------
!  08:55:08
! (1 row)
! 
! SELECT * FROM test_time WHERE i>='08:55:08'::time ORDER BY i;
!     i     
! ----------
!  08:55:08
!  09:55:08
!  10:55:08
! (3 rows)
! 
! SELECT * FROM test_time WHERE i>'08:55:08'::time ORDER BY i;
!     i     
! ----------
!  09:55:08
!  10:55:08
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/timetz.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/timetz.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_timetz (
! 	i timetz
! );
! INSERT INTO test_timetz VALUES 
! 	( '03:55:08 GMT+2' ),
! 	( '04:55:08 GMT+2' ),
! 	( '05:55:08 GMT+2' ),
! 	( '08:55:08 GMT+2' ),
! 	( '09:55:08 GMT+2' ),
! 	( '10:55:08 GMT+2' )
! ;
! CREATE INDEX idx_timetz ON test_timetz USING gin (i);
! SELECT * FROM test_timetz WHERE i<'08:55:08 GMT+2'::timetz ORDER BY i;
!       i      
! -------------
!  03:55:08-02
!  04:55:08-02
!  05:55:08-02
! (3 rows)
! 
! SELECT * FROM test_timetz WHERE i<='08:55:08 GMT+2'::timetz ORDER BY i;
!       i      
! -------------
!  03:55:08-02
!  04:55:08-02
!  05:55:08-02
!  08:55:08-02
! (4 rows)
! 
! SELECT * FROM test_timetz WHERE i='08:55:08 GMT+2'::timetz ORDER BY i;
!       i      
! -------------
!  08:55:08-02
! (1 row)
! 
! SELECT * FROM test_timetz WHERE i>='08:55:08 GMT+2'::timetz ORDER BY i;
!       i      
! -------------
!  08:55:08-02
!  09:55:08-02
!  10:55:08-02
! (3 rows)
! 
! SELECT * FROM test_timetz WHERE i>'08:55:08 GMT+2'::timetz ORDER BY i;
!       i      
! -------------
!  09:55:08-02
!  10:55:08-02
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/date.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/date.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_date (
! 	i date
! );
! INSERT INTO test_date VALUES 
! 	( '2004-10-23' ),
! 	( '2004-10-24' ),
! 	( '2004-10-25' ),
! 	( '2004-10-26' ),
! 	( '2004-10-27' ),
! 	( '2004-10-28' )
! ;
! CREATE INDEX idx_date ON test_date USING gin (i);
! SELECT * FROM test_date WHERE i<'2004-10-26'::date ORDER BY i;
!      i      
! ------------
!  10-23-2004
!  10-24-2004
!  10-25-2004
! (3 rows)
! 
! SELECT * FROM test_date WHERE i<='2004-10-26'::date ORDER BY i;
!      i      
! ------------
!  10-23-2004
!  10-24-2004
!  10-25-2004
!  10-26-2004
! (4 rows)
! 
! SELECT * FROM test_date WHERE i='2004-10-26'::date ORDER BY i;
!      i      
! ------------
!  10-26-2004
! (1 row)
! 
! SELECT * FROM test_date WHERE i>='2004-10-26'::date ORDER BY i;
!      i      
! ------------
!  10-26-2004
!  10-27-2004
!  10-28-2004
! (3 rows)
! 
! SELECT * FROM test_date WHERE i>'2004-10-26'::date ORDER BY i;
!      i      
! ------------
!  10-27-2004
!  10-28-2004
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/interval.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/interval.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_interval (
! 	i interval
! );
! INSERT INTO test_interval VALUES 
! 	( '03:55:08' ),
! 	( '04:55:08' ),
! 	( '05:55:08' ),
! 	( '08:55:08' ),
! 	( '09:55:08' ),
! 	( '10:55:08' )
! ;
! CREATE INDEX idx_interval ON test_interval USING gin (i);
! SELECT * FROM test_interval WHERE i<'08:55:08'::interval ORDER BY i;
!             i             
! --------------------------
!  @ 3 hours 55 mins 8 secs
!  @ 4 hours 55 mins 8 secs
!  @ 5 hours 55 mins 8 secs
! (3 rows)
! 
! SELECT * FROM test_interval WHERE i<='08:55:08'::interval ORDER BY i;
!             i             
! --------------------------
!  @ 3 hours 55 mins 8 secs
!  @ 4 hours 55 mins 8 secs
!  @ 5 hours 55 mins 8 secs
!  @ 8 hours 55 mins 8 secs
! (4 rows)
! 
! SELECT * FROM test_interval WHERE i='08:55:08'::interval ORDER BY i;
!             i             
! --------------------------
!  @ 8 hours 55 mins 8 secs
! (1 row)
! 
! SELECT * FROM test_interval WHERE i>='08:55:08'::interval ORDER BY i;
!              i             
! ---------------------------
!  @ 8 hours 55 mins 8 secs
!  @ 9 hours 55 mins 8 secs
!  @ 10 hours 55 mins 8 secs
! (3 rows)
! 
! SELECT * FROM test_interval WHERE i>'08:55:08'::interval ORDER BY i;
!              i             
! ---------------------------
!  @ 9 hours 55 mins 8 secs
!  @ 10 hours 55 mins 8 secs
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/macaddr.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/macaddr.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_macaddr (
! 	i macaddr
! );
! INSERT INTO test_macaddr VALUES 
! 	( '22:00:5c:03:55:08' ),
! 	( '22:00:5c:04:55:08' ),
! 	( '22:00:5c:05:55:08' ),
! 	( '22:00:5c:08:55:08' ),
! 	( '22:00:5c:09:55:08' ),
! 	( '22:00:5c:10:55:08' )
! ;
! CREATE INDEX idx_macaddr ON test_macaddr USING gin (i);
! SELECT * FROM test_macaddr WHERE i<'22:00:5c:08:55:08'::macaddr ORDER BY i;
!          i         
! -------------------
!  22:00:5c:03:55:08
!  22:00:5c:04:55:08
!  22:00:5c:05:55:08
! (3 rows)
! 
! SELECT * FROM test_macaddr WHERE i<='22:00:5c:08:55:08'::macaddr ORDER BY i;
!          i         
! -------------------
!  22:00:5c:03:55:08
!  22:00:5c:04:55:08
!  22:00:5c:05:55:08
!  22:00:5c:08:55:08
! (4 rows)
! 
! SELECT * FROM test_macaddr WHERE i='22:00:5c:08:55:08'::macaddr ORDER BY i;
!          i         
! -------------------
!  22:00:5c:08:55:08
! (1 row)
! 
! SELECT * FROM test_macaddr WHERE i>='22:00:5c:08:55:08'::macaddr ORDER BY i;
!          i         
! -------------------
!  22:00:5c:08:55:08
!  22:00:5c:09:55:08
!  22:00:5c:10:55:08
! (3 rows)
! 
! SELECT * FROM test_macaddr WHERE i>'22:00:5c:08:55:08'::macaddr ORDER BY i;
!          i         
! -------------------
!  22:00:5c:09:55:08
!  22:00:5c:10:55:08
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/inet.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/inet.out	Wed Dec 17 23:18:03 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_inet (
! 	i inet
! );
! INSERT INTO test_inet VALUES 
! 	( '1.2.3.4/16' ),
! 	( '1.2.4.4/16' ),
! 	( '1.2.5.4/16' ),
! 	( '1.2.6.4/16' ),
! 	( '1.2.7.4/16' ),
! 	( '1.2.8.4/16' )
! ;
! CREATE INDEX idx_inet ON test_inet USING gin (i);
! SELECT * FROM test_inet WHERE i<'1.2.6.4/16'::inet ORDER BY i;
!      i      
! ------------
!  1.2.3.4/16
!  1.2.4.4/16
!  1.2.5.4/16
! (3 rows)
! 
! SELECT * FROM test_inet WHERE i<='1.2.6.4/16'::inet ORDER BY i;
!      i      
! ------------
!  1.2.3.4/16
!  1.2.4.4/16
!  1.2.5.4/16
!  1.2.6.4/16
! (4 rows)
! 
! SELECT * FROM test_inet WHERE i='1.2.6.4/16'::inet ORDER BY i;
!      i      
! ------------
!  1.2.6.4/16
! (1 row)
! 
! SELECT * FROM test_inet WHERE i>='1.2.6.4/16'::inet ORDER BY i;
!      i      
! ------------
!  1.2.6.4/16
!  1.2.7.4/16
!  1.2.8.4/16
! (3 rows)
! 
! SELECT * FROM test_inet WHERE i>'1.2.6.4/16'::inet ORDER BY i;
!      i      
! ------------
!  1.2.7.4/16
!  1.2.8.4/16
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/cidr.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/cidr.out	Wed Dec 17 23:18:04 2008
***************
*** 1,51 ****
! set enable_seqscan=off;
! CREATE TABLE test_cidr (
! 	i cidr
! );
! INSERT INTO test_cidr VALUES 
! 	( '1.2.3.4' ),
! 	( '1.2.4.4' ),
! 	( '1.2.5.4' ),
! 	( '1.2.6.4' ),
! 	( '1.2.7.4' ),
! 	( '1.2.8.4' )
! ;
! CREATE INDEX idx_cidr ON test_cidr USING gin (i);
! SELECT * FROM test_cidr WHERE i<'1.2.6.4'::cidr ORDER BY i;
!      i      
! ------------
!  1.2.3.4/32
!  1.2.4.4/32
!  1.2.5.4/32
! (3 rows)
! 
! SELECT * FROM test_cidr WHERE i<='1.2.6.4'::cidr ORDER BY i;
!      i      
! ------------
!  1.2.3.4/32
!  1.2.4.4/32
!  1.2.5.4/32
!  1.2.6.4/32
! (4 rows)
! 
! SELECT * FROM test_cidr WHERE i='1.2.6.4'::cidr ORDER BY i;
!      i      
! ------------
!  1.2.6.4/32
! (1 row)
! 
! SELECT * FROM test_cidr WHERE i>='1.2.6.4'::cidr ORDER BY i;
!      i      
! ------------
!  1.2.6.4/32
!  1.2.7.4/32
!  1.2.8.4/32
! (3 rows)
! 
! SELECT * FROM test_cidr WHERE i>'1.2.6.4'::cidr ORDER BY i;
!      i      
! ------------
!  1.2.7.4/32
!  1.2.8.4/32
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/text.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/text.out	Wed Dec 17 23:18:04 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_text (
! 	i text
! );
! INSERT INTO test_text VALUES ('aaa'),('a'),('abc'),('abb'),('axy'),('xyz');
! CREATE INDEX idx_text ON test_text USING gin (i);
! SELECT * FROM test_text WHERE i<'abc' ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
! (3 rows)
! 
! SELECT * FROM test_text WHERE i<='abc' ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
!  abc
! (4 rows)
! 
! SELECT * FROM test_text WHERE i='abc' ORDER BY i;
!   i  
! -----
!  abc
! (1 row)
! 
! SELECT * FROM test_text WHERE i>='abc' ORDER BY i;
!   i  
! -----
!  abc
!  axy
!  xyz
! (3 rows)
! 
! SELECT * FROM test_text WHERE i>'abc' ORDER BY i;
!   i  
! -----
!  axy
!  xyz
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/varchar.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/varchar.out	Wed Dec 17 23:18:04 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_varchar (
! 	i varchar
! );
! INSERT INTO test_varchar VALUES ('aaa'),('a'),('abc'),('abb'),('axy'),('xyz');
! CREATE INDEX idx_varchar ON test_varchar USING gin (i);
! SELECT * FROM test_varchar WHERE i<'abc'::varchar ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
! (3 rows)
! 
! SELECT * FROM test_varchar WHERE i<='abc'::varchar ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
!  abc
! (4 rows)
! 
! SELECT * FROM test_varchar WHERE i='abc'::varchar ORDER BY i;
!   i  
! -----
!  abc
! (1 row)
! 
! SELECT * FROM test_varchar WHERE i>='abc'::varchar ORDER BY i;
!   i  
! -----
!  abc
!  axy
!  xyz
! (3 rows)
! 
! SELECT * FROM test_varchar WHERE i>'abc'::varchar ORDER BY i;
!   i  
! -----
!  axy
!  xyz
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/char.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/char.out	Wed Dec 17 23:18:04 2008
***************
*** 1,37 ****
! set enable_seqscan=off;
! CREATE TABLE test_char (
! 	i "char"
! );
! INSERT INTO test_char VALUES ('a'),('b'),('c'),('d'),('e'),('f');
! CREATE INDEX idx_char ON test_char USING gin (i);
! SELECT * FROM test_char WHERE i<'d'::"char" ORDER BY i;
!  i 
! ---
! (0 rows)
! 
! SELECT * FROM test_char WHERE i<='d'::"char" ORDER BY i;
!  i 
! ---
! (0 rows)
! 
! SELECT * FROM test_char WHERE i='d'::"char" ORDER BY i;
!  i 
! ---
!  d
! (1 row)
! 
! SELECT * FROM test_char WHERE i>='d'::"char" ORDER BY i;
!  i 
! ---
!  d
!  e
!  f
! (3 rows)
! 
! SELECT * FROM test_char WHERE i>'d'::"char" ORDER BY i;
!  i 
! ---
!  e
!  f
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/bytea.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/bytea.out	Wed Dec 17 23:18:04 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_bytea (
! 	i bytea
! );
! INSERT INTO test_bytea VALUES ('aaa'),('a'),('abc'),('abb'),('axy'),('xyz');
! CREATE INDEX idx_bytea ON test_bytea USING gin (i);
! SELECT * FROM test_bytea WHERE i<'abc'::bytea ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
! (3 rows)
! 
! SELECT * FROM test_bytea WHERE i<='abc'::bytea ORDER BY i;
!   i  
! -----
!  a
!  aaa
!  abb
!  abc
! (4 rows)
! 
! SELECT * FROM test_bytea WHERE i='abc'::bytea ORDER BY i;
!   i  
! -----
!  abc
! (1 row)
! 
! SELECT * FROM test_bytea WHERE i>='abc'::bytea ORDER BY i;
!   i  
! -----
!  abc
!  axy
!  xyz
! (3 rows)
! 
! SELECT * FROM test_bytea WHERE i>'abc'::bytea ORDER BY i;
!   i  
! -----
!  axy
!  xyz
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/bit.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/bit.out	Wed Dec 17 23:18:04 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_bit (
! 	i bit(3)
! );
! INSERT INTO test_bit VALUES ('001'),('010'),('011'),('100'),('101'),('110');
! CREATE INDEX idx_bit ON test_bit USING gin (i);
! SELECT * FROM test_bit WHERE i<'100'::bit(3) ORDER BY i;
!   i  
! -----
!  001
!  010
!  011
! (3 rows)
! 
! SELECT * FROM test_bit WHERE i<='100'::bit(3) ORDER BY i;
!   i  
! -----
!  001
!  010
!  011
!  100
! (4 rows)
! 
! SELECT * FROM test_bit WHERE i='100'::bit(3) ORDER BY i;
!   i  
! -----
!  100
! (1 row)
! 
! SELECT * FROM test_bit WHERE i>='100'::bit(3) ORDER BY i;
!   i  
! -----
!  100
!  101
!  110
! (3 rows)
! 
! SELECT * FROM test_bit WHERE i>'100'::bit(3) ORDER BY i;
!   i  
! -----
!  101
!  110
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

*** /home/ibrar/work/pgsql/contrib/btree_gin/expected/varbit.out	Wed Dec 17 19:30:39 2008
--- /home/ibrar/work/pgsql/contrib/btree_gin/results/varbit.out	Wed Dec 17 23:18:04 2008
***************
*** 1,44 ****
! set enable_seqscan=off;
! CREATE TABLE test_varbit (
! 	i varbit
! );
! INSERT INTO test_varbit VALUES ('001'),('010'),('011'),('100'),('101'),('110');
! CREATE INDEX idx_varbit ON test_varbit USING gin (i);
! SELECT * FROM test_varbit WHERE i<'100'::varbit ORDER BY i;
!   i  
! -----
!  001
!  010
!  011
! (3 rows)
! 
! SELECT * FROM test_varbit WHERE i<='100'::varbit ORDER BY i;
!   i  
! -----
!  001
!  010
!  011
!  100
! (4 rows)
! 
! SELECT * FROM test_varbit WHERE i='100'::varbit ORDER BY i;
!   i  
! -----
!  100
! (1 row)
! 
! SELECT * FROM test_varbit WHERE i>='100'::varbit ORDER BY i;
!   i  
! -----
!  100
!  101
!  110
! (3 rows)
! 
! SELECT * FROM test_varbit WHERE i>'100'::varbit ORDER BY i;
!   i  
! -----
!  101
!  110
! (2 rows)
! 
--- 1 ----
! psql: FATAL:  the database system is in recovery mode

======================================================================

#2Teodor Sigaev
teodor@sigaev.ru
In reply to: Ibrar Ahmed (#1)
Re: Review: B-Tree emulation for GIN

will see, may be it's needed to update the patch

Ibrar Ahmed wrote:

Hi Teodor Sigaev,

I am getting server crash in contrib regression. May be I am doing
something wrong here. Regression diff is attached.

BTW these queries work fine outside the regression.

--
Ibrar Ahmed
EnterpriseDB http://www.enterprisedb.com

------------------------------------------------------------------------

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

#3Teodor Sigaev
teodor@sigaev.ru
In reply to: Ibrar Ahmed (#1)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

Updated patch.

Ibrar Ahmed wrote:

Hi Teodor Sigaev,

I am getting server crash in contrib regression. May be I am doing
something wrong here. Regression diff is attached.

BTW these queries work fine outside the regression.

--
Ibrar Ahmed
EnterpriseDB http://www.enterprisedb.com

------------------------------------------------------------------------

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

gin_extra-0.2.gzapplication/x-tar; name=gin_extra-0.2.gzDownload
#4Ibrar Ahmed
ibrar.ahmad@gmail.com
In reply to: Teodor Sigaev (#3)
Re: Review: B-Tree emulation for GIN

Thanks,

On Fri, Dec 19, 2008 at 3:26 PM, Teodor Sigaev <teodor@sigaev.ru> wrote:

Updated patch.

Ibrar Ahmed wrote:

Hi Teodor Sigaev,

I am getting server crash in contrib regression. May be I am doing
something wrong here. Regression diff is attached.

BTW these queries work fine outside the regression.

--
Ibrar Ahmed
EnterpriseDB http://www.enterprisedb.com

------------------------------------------------------------------------

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW:
http://www.sigaev.ru/

--
Ibrar Ahmed
EnterpriseDB http://www.enterprisedb.com

#5Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#3)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

On Fri, 2008-12-19 at 13:26 +0300, Teodor Sigaev wrote:

Updated patch.

I have merged this with HEAD, written a brief document (which is mostly
a copy of the btree-gist page), added the module to the contrib
Makefile, and made some very minor changes. Patch attached.

A couple comments:

1. Right now, to implement "less than" you need to start at the
beginning of the index and scan until you reach the supplied query
datum. This is because GIN doesn't support backwards scans
( http://archives.postgresql.org/pgsql-hackers/2008-07/msg01146.php ).

Unfortunately, that means numeric is not supportable for btree-gin
because there is no left-most value from which to start the scan. Do you
see an easy workaround to support numeric?

2. Why do you create a shell type "int32" from btree_gin.sql? I tried
doing a search-and-replace to use "int4" instead, and it seems to work
fine (and eliminates the warnings). I left it with int32 in my version
of the patch because I thought you may have some reason for using it.

Regards,
Jeff Davis

Attachments:

btree-gin.20081228.patch.gzapplication/x-gzip; name=btree-gin.20081228.patch.gzDownload
#6Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#5)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

On Sun, 2008-12-28 at 23:41 -0800, Jeff Davis wrote:

2. Why do you create a shell type "int32" from btree_gin.sql? I tried
doing a search-and-replace to use "int4" instead, and it seems to work
fine (and eliminates the warnings). I left it with int32 in my version
of the patch because I thought you may have some reason for using it.

Attached an updated patch with this change.

Regards,
Jeff Davis

Attachments:

btree-gin.20090111.patch.gzapplication/x-gzip; name=btree-gin.20090111.patch.gzDownload
#7Teodor Sigaev
teodor@sigaev.ru
In reply to: Jeff Davis (#5)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

I have merged this with HEAD, written a brief document (which is mostly
a copy of the btree-gist page), added the module to the contrib
Makefile, and made some very minor changes. Patch attached.

Thank you

A couple comments:

1. Right now, to implement "less than" you need to start at the
beginning of the index and scan until you reach the supplied query
datum. This is because GIN doesn't support backwards scans
( http://archives.postgresql.org/pgsql-hackers/2008-07/msg01146.php ).

Unfortunately, that means numeric is not supportable for btree-gin
because there is no left-most value from which to start the scan. Do you
see an easy workaround to support numeric?

Hmm, let we use minimal varlena struct (with size equal to VARHDRSZ) as
left-most (and fake) value. It is never used for any actual argument except
compare function, so, new compare function is provided. New version of patch is
attached and it based on on your patch (btree-gin.20090111.patch.gz).

2. Why do you create a shell type "int32" from btree_gin.sql? I tried
doing a search-and-replace to use "int4" instead, and it seems to work
fine (and eliminates the warnings). I left it with int32 in my version
of the patch because I thought you may have some reason for using it.

My mistake, thank you for fix
--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.7.gzapplication/x-tar; name=btree_gin-0.7.gzDownload
#8Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#7)
Re: Review: B-Tree emulation for GIN

On Fri, 2009-01-16 at 17:42 +0300, Teodor Sigaev wrote:

Unfortunately, that means numeric is not supportable for btree-gin
because there is no left-most value from which to start the scan. Do you
see an easy workaround to support numeric?

Hmm, let we use minimal varlena struct (with size equal to VARHDRSZ) as
left-most (and fake) value. It is never used for any actual argument except
compare function, so, new compare function is provided. New version of patch is
attached and it based on on your patch (btree-gin.20090111.patch.gz).

Looks good to me. I updated the CommitFest wiki to point to this patch.

I like the fact that this patch does not modify the numeric ADT. It
still relies on the fact that the numeric type will never make use of
the minimal varlena struct, however. I bring this up in case someone
sees it as a problem.

Thanks,
Jeff Davis

#9Alvaro Herrera
alvherre@commandprompt.com
In reply to: Jeff Davis (#8)
Re: Review: B-Tree emulation for GIN

Jeff Davis escribi�:

I like the fact that this patch does not modify the numeric ADT. It
still relies on the fact that the numeric type will never make use of
the minimal varlena struct, however. I bring this up in case someone
sees it as a problem.

Greg Stark was working on a patch to make certain values use the short
representation.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#10Teodor Sigaev
teodor@sigaev.ru
In reply to: Alvaro Herrera (#9)
Re: Review: B-Tree emulation for GIN

still relies on the fact that the numeric type will never make use of
the minimal varlena struct, however. I bring this up in case someone
sees it as a problem.

Greg Stark was working on a patch to make certain values use the short
representation.

Fake value contains only VARHDRSZ bytes.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Davis (#8)
Re: Review: B-Tree emulation for GIN

Jeff Davis <pgsql@j-davis.com> writes:

I like the fact that this patch does not modify the numeric ADT. It
still relies on the fact that the numeric type will never make use of
the minimal varlena struct, however. I bring this up in case someone
sees it as a problem.

I'm pretty certain I recall Greg Stark recommending that we adopt
something like that as the standard numeric representation of zero.
It didn't get done yet, but it might happen someday.

regards, tom lane

#12Jeff Davis
pgsql@j-davis.com
In reply to: Tom Lane (#11)
Re: Review: B-Tree emulation for GIN

On Mon, 2009-01-19 at 11:35 -0500, Tom Lane wrote:

Jeff Davis <pgsql@j-davis.com> writes:

I like the fact that this patch does not modify the numeric ADT. It
still relies on the fact that the numeric type will never make use of
the minimal varlena struct, however. I bring this up in case someone
sees it as a problem.

I'm pretty certain I recall Greg Stark recommending that we adopt
something like that as the standard numeric representation of zero.
It didn't get done yet, but it might happen someday.

Then we should use the previous version of the patch here:

http://archives.postgresql.org/message-id/1231709713.25019.129.camel@jdavis

Was there any talk of supporting a +/- infinity in numeric? If we did
that, it would allow numeric to be supported for btree-gin.

Regards,
Jeff Davis

#13Teodor Sigaev
teodor@sigaev.ru
In reply to: Tom Lane (#11)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

I'm pretty certain I recall Greg Stark recommending that we adopt
something like that as the standard numeric representation of zero.
It didn't get done yet, but it might happen someday.

Changes:
- use NULL as left-most value. It's safe because NULL numeric value
cannot be an argument for any function except gin_numeric_cmp and it
cannot be returned in regular SQL query.
- fix uninstall script for support numeric type.
--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.8.gzapplication/x-tar; name=btree_gin-0.8.gzDownload
#14Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#13)
Re: Review: B-Tree emulation for GIN

On Mon, 2009-01-19 at 20:15 +0300, Teodor Sigaev wrote:

Changes:
- use NULL as left-most value. It's safe because NULL numeric value
cannot be an argument for any function except gin_numeric_cmp and it
cannot be returned in regular SQL query.

gin_numeric_cmp() can be called from regular SQL. I missed this before,
but that function will segfault if you call gin_numeric_cmp(NULL, 1) (in
v0.7 at least).

I know you mean a C NULL, not a SQL NULL, but it reminded me to test SQL
NULL.

And how does GIN handle SQL NULL values in the column? Does it index
them at all, or just ignore them?

Regards,
Jeff Davis

#15Teodor Sigaev
teodor@sigaev.ru
In reply to: Jeff Davis (#14)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

gin_numeric_cmp() can be called from regular SQL. I missed this before,
but that function will segfault if you call gin_numeric_cmp(NULL, 1) (in
v0.7 at least).

Fixed, gin_numeric_cmp is marked as strict.

And how does GIN handle SQL NULL values in the column? Does it index
them at all, or just ignore them?

SQL NULL: GIN doesn't support it (amindexnulls/amsearchnulls == false)
C NULL: NULL-numeric could be returned only by gin_extract_query_numeric which
cannot be called by user directly because of internal type of argument.
GIN doesn't do anything with values returned by gin_extract_query_numeric except
providing they as an argument for comparing functions.
--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.9.gzapplication/x-tar; name=btree_gin-0.9.gzDownload
#16Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#15)
Re: Review: B-Tree emulation for GIN

On Mon, 2009-01-19 at 21:41 +0300, Teodor Sigaev wrote:

And how does GIN handle SQL NULL values in the column? Does it index
them at all, or just ignore them?

SQL NULL: GIN doesn't support it (amindexnulls/amsearchnulls == false)
C NULL: NULL-numeric could be returned only by gin_extract_query_numeric which
cannot be called by user directly because of internal type of argument.
GIN doesn't do anything with values returned by gin_extract_query_numeric except
providing they as an argument for comparing functions.

Ok, I understand now. I will look at this later.

Regards,
Jeff Davis

#17Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#15)
Re: Review: B-Tree emulation for GIN

On Mon, 2009-01-19 at 21:41 +0300, Teodor Sigaev wrote:

gin_numeric_cmp() can be called from regular SQL. I missed this before,
but that function will segfault if you call gin_numeric_cmp(NULL, 1) (in
v0.7 at least).

Fixed, gin_numeric_cmp is marked as strict.

And how does GIN handle SQL NULL values in the column? Does it index
them at all, or just ignore them?

SQL NULL: GIN doesn't support it (amindexnulls/amsearchnulls == false)
C NULL: NULL-numeric could be returned only by gin_extract_query_numeric which
cannot be called by user directly because of internal type of argument.
GIN doesn't do anything with values returned by gin_extract_query_numeric except
providing they as an argument for comparing functions.

Ok, looks good. I updated the wiki to show this as the latest version of
the patch.

Thanks,
Jeff Davis

#18Tom Lane
tgl@sss.pgh.pa.us
In reply to: Teodor Sigaev (#15)
Re: Review: B-Tree emulation for GIN

Looked at this a bit ... do you think it's really a good idea to remove
the strategy number argument of comparePartial? The argument given in
the docs for it is that it might be needed to determine when to end the
scan, and that still seems plausible to me.

The description of extractQuery's extra_data parameter seems confusing
too. AFAICS it is incorrect, or at least misleading, to describe it as
void ** extra_data[]; it is really void ***extra_data, because there is
only one object there not an array.

regards, tom lane

#19Teodor Sigaev
teodor@sigaev.ru
In reply to: Tom Lane (#18)
Re: Review: B-Tree emulation for GIN

Looked at this a bit ... do you think it's really a good idea to remove
the strategy number argument of comparePartial? The argument given in
the docs for it is that it might be needed to determine when to end the
scan, and that still seems plausible to me.

Strategy number is not removed, it's replaced by pointer to opclass-specific
data on per key basis. Actually, partial match feature is new for 8.4 and there
is no any compatibility problem. None of existing opclasses (except
contrib/btree_gin) uses strategy number in comparePartial.

The description of extractQuery's extra_data parameter seems confusing
too. AFAICS it is incorrect, or at least misleading, to describe it as
void ** extra_data[]; it is really void ***extra_data, because there is
only one object there not an array.

It's really array, see fillScanKey() in ginscan.c, line 61 of patched file.
extractQuery could provide data for each returned key.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

#20Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#19)
Re: Review: B-Tree emulation for GIN

On Wed, 2009-02-04 at 20:22 +0300, Teodor Sigaev wrote:

The description of extractQuery's extra_data parameter seems confusing
too. AFAICS it is incorrect, or at least misleading, to describe it as
void ** extra_data[]; it is really void ***extra_data, because there is
only one object there not an array.

It's really array, see fillScanKey() in ginscan.c, line 61 of patched file.
extractQuery could provide data for each returned key.

If I understand correctly, the extra_data parameter to extractQuery()
should mean "a pointer to an array of void*". "void **extra_data[]"
might be misinterpreted as "an array of void**".

Would "void *(*extra_data)[]" be more descriptive? I'm not an expert on
style questions like this, but it seems to match the parameter lists for
comparePartial() and consistent().

"void ***extra_data" seems reasonable, too.

Regards,
Jeff Davis

#21Jeff Davis
pgsql@j-davis.com
In reply to: Teodor Sigaev (#15)
Re: Review: B-Tree emulation for GIN

On Mon, 2009-01-19 at 21:41 +0300, Teodor Sigaev wrote:

gin_numeric_cmp() can be called from regular SQL. I missed this before,
but that function will segfault if you call gin_numeric_cmp(NULL, 1) (in
v0.7 at least).

Fixed, gin_numeric_cmp is marked as strict.

And how does GIN handle SQL NULL values in the column? Does it index
them at all, or just ignore them?

SQL NULL: GIN doesn't support it (amindexnulls/amsearchnulls == false)
C NULL: NULL-numeric could be returned only by gin_extract_query_numeric which
cannot be called by user directly because of internal type of argument.
GIN doesn't do anything with values returned by gin_extract_query_numeric except
providing they as an argument for comparing functions.

Looking through the code again, gin_compare_prefix_##type looks a little
confusing.

Is there a reason for using:
(data->strategy == BTLessStrategyNumber ||
data->strategy == BTLessEqualStrategyNumber ) ?
PointerGetDatum(data->datum) : a
rather than just using:
PointerGetDatum(data->datum)

Also, it might be a little less confusing if you used two separate
variables rather than using "res" for two purposes.

Regards,
Jeff Davis

#22Teodor Sigaev
teodor@sigaev.ru
In reply to: Jeff Davis (#21)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

Looking through the code again, gin_compare_prefix_##type looks a little
confusing.

Is there a reason for using:
(data->strategy == BTLessStrategyNumber ||
data->strategy == BTLessEqualStrategyNumber ) ?
PointerGetDatum(data->datum) : a
rather than just using:
PointerGetDatum(data->datum)

Added comments:
/*
* Datum a is a value from extract_query method and for BTLess*
* strategy it is a left-most value. So, use original datum from
* QueryInfo to decide stop scanning on not. Datum b is always
* from index.
*/

Also, it might be a little less confusing if you used two separate
variables rather than using "res" for two purposes.

done
--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.10.gzapplication/x-tar; name=btree_gin-0.10.gzDownload
#23Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Teodor Sigaev (#22)
Re: Review: B-Tree emulation for GIN

The GIN_EXTRACT_VALUE macro returns a pointer to a static 'entries'
variable. That doesn't seem safe. Is it really never possible to have to
two GIN searches in a plan, both calling and using the value returned
by extractValue simultaneously? In any case that seems like a pretty
weak assumption.

You might want to declare extra_data as just "void *", instead of an
array of pointers. The data type implementation might want to store
something there that's not per-key, but applies to the whole query. I
see that you're passing it to comparePartial, but that seems to be just
future-proofing. What kind of a data type are you envisioning that would
make use of it? It seems that you could pass the same information in the
partial key Datum itself that extractQuery returns. You're currently
using it as a way to avoid some palloc's in gin_tsquery_consistent().
That seems like a pretty dirty hack. I doubt there's any meaningful
performance advantage from that, but if there is, I think you could use
a statically allocated array instead.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#24Teodor Sigaev
teodor@sigaev.ru
In reply to: Heikki Linnakangas (#23)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

The GIN_EXTRACT_VALUE macro returns a pointer to a static 'entries'
variable. That doesn't seem safe. Is it really never possible to have to
two GIN searches in a plan, both calling and using the value returned
by extractValue simultaneously? In any case that seems like a pretty
weak assumption.

Fixed.

You might want to declare extra_data as just "void *", instead of an
array of pointers. The data type implementation might want to store
something there that's not per-key, but applies to the whole query. I
see that you're passing it to comparePartial, but that seems to be just
future-proofing. What kind of a data type are you envisioning that would

wildspeed module (http://www.sigaev.ru/cvsweb/cvsweb.cgi/wildspeed/) - for each
key from it's needed to store some info. Right now it's coded directly in Datum,
but it looks ugly (at least for me).

It's possible to clarify interface by introducing new type:

typedef void* OpaquePtr;

Then, prototypes will be:
extractQuery(..., OpaquePtr* extra_data[])
consistent(...., OpaquePtr extra_data[])
comparePartial(..., OpaquePtr extra_data)

Or another option: partial match feature is new for 8.4, so we could change
interface:
typedef struct KeyData {
bool pmatch,
void *extra_data;
} KeyData;

Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, KeyData* data[])
bool consistent(bool check[], StrategyNumber n, Datum query, bool *recheck,
KeyData data[])
comparePartial(Datum partial_key, Datum key, KeyData *data);

make use of it? It seems that you could pass the same information in the
partial key Datum itself that extractQuery returns. You're currently
using it as a way to avoid some palloc's in gin_tsquery_consistent().
That seems like a pretty dirty hack. I doubt there's any meaningful
performance advantage from that, but if there is, I think you could use
a statically allocated array instead.

It's easy to un-dirty that hack, but before I'd like to see your comments about
thoughts above.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.11.gzapplication/x-tar; name=btree_gin-0.11.gzDownload
����Ibtree_gin-0.11�}{{�6�����@�=����$��b��:�����RK��{�}��ms#��H%q�=�����I�/�R���$��`0����ssC��d}N�O�7n�s�v��~���Mk8�=o�����[��"QZ����5#F+�F��zck��M��{��{��FC����F����zV�1>����v��Z��
��m���Bo��2���yc���;�?��[����t�;�����j�]�s�^�B��o��k�Nf��>���c��N����7����]�����z��:���"���OwF(C��7��� Qs$��$&�?an�WWW�������uI�������O�?_��T�B�{�O��s����\��3��
rY��2��������0���������������GG�g�{bO�����}���x7pk�=�A:��������;�(�]�N���s<������+�S�^��j�8fG�6��-M�mac�|�Q"W����ZL[*��%u����3�I���*�Y�4;�f�i��@�dS*��AZr���AO�|�I��(+�~������N����F��G����3�������w���G����	�c�hurvs�>]L��9afXgfL�yP�aw�����/l�N��������������Q�0\��t��yq�qB�c9,+����2�e��>���o�
�'yK�
T&������	���2��
s}��.����*�"����|���H����Ej�|0'�R��6!�����'�����"�I5i�;�}��=���=�r����8����b�	�ur<�h���k���������j�n��wZ�Z�;��P�1�����1� ]����k�m� �a�m�J�*��~k�Q��J�J�GN/��g��a\D������Sd���^����y^�ku�5w�fg7��C��aV�0��Y:8D1��(������	H��O>�3��O����#�����'P7����6�W��)r��|r��&�b��%��-&���nh���O�;�����G @F�s�����)����>\���[�|G��su�G�y�j���Z�����N�#��k{(������O���m�9��$��qq\\
"nA�84l��|��a���u��������h�.��E,ZY���o.N�J�� Y�Z1*
��b�o���YL�`���W����w&��Z8�z������ Y���;�qo��wf���T�r���	a}�N`|�(M#MQ'�������5�~��L� ����yE#Q`"��~-35P)^�`c�:����������u�K���������Mk�o�T�}�
�T����R1pK���7F��v���
Wp���fk�����������W����b@u��jR��87#����
�.��7����G�������Sk1P]�����y��l_�)]���N�G+�n*�~~R�.2�V5���z��|z�
��:W�x���~�
��_H����_>u�~�)������_q��~�%c�����U���sG�U�Le�6�9c8�@W,�R���m���f�e��fk���
f�(H:
���X���h-h���t��W�'�L�|A��i���&t*���s�:8����1�f3{t�f	!������Jd�Xf�3%W�G��W�L_muC��10� �a�aS��vdi�&�V��Z����Z\o��������'��T8mAN������v`������lrp@~:���!�Z�A������&�	w����-}?����	;�?]�.�����h��n���d;
�8M�������=|��	���f�%s����DB(w:�'�]����?B�'����=��R�/�!�i��S
�y;��q3�p8��_ -S�OI#Y�r%��=D��t�cj�P��W�bQ���e�T[���R5rk�g:/F�4��qGCUB4:QQ(��]mTb� �4�n��%�S�yVzcG�_�p���>����pe]	�!�����i��
@e@��h1���[�@��3�y!/�M�X7e*�
�t�!�R��]o7�rO�Y��uO��z�����$yR4|�(U"�R-����](�����D�S�uiN��:/^��G�.��`@�9�����a�0�j�L�2�,.y��&4i��hj��>kB1���{s88�x���������n{��v����
��i�>/���"M���n�`�	-�n�:M������?��+��R~���P��n�M�tQ{���s�u�Z��y-��D��Y�v�&�������j��n��:Lv�`��;X��69I*�`����)�����m�������m����s���3�m����x[g�_�)+���
�k{'x���������+�0F�h}w����o�4�f�Ic���<���F��Q3���P��|x/��zuD������T0������
w[�O���8�?���s���T
*���N��m��.�KREfs�����k�+�%W��.��2M����VF4����
&��vF�?�+2�W����������q����'�i�>Z����+6#�������us��
�O�P��-�7hx�$MN4[���8��3�zSZ�W��,k4q�3k�a��z��(�1���]r~u�7^H7�������q�����jqm��%^�������������Sf�1���o�J�|�z;\j���%��������?[�tk�No������������d`}����K�}�����W�����\���������������*'��}>�����bl������^�8�����0��0�����
��_L�����?x��1���K���lw���e�O/����|�V Mh���X�?�J�D��
����dR���4+�����F�'���F�O5:�������|z�99{s��wu��T�A�������6\4 ���z���H����'��������\��]�����~?���!7c�����C&���'�P����Ll�<���������{�O�j\J3M��5��������C���|xg�	����m�\;�6~�����n�j�{�����!-��;��1����
|���b��5�`u�iE�n���kk�
�f2J.J���,�����	�
1T����f�Y	[��D�����o��VS��_��^������m�u#�o&���=�$��`�����j�`�������S��)h��ns�������v�icg��\v����w���w�G��.>l�5 �?_}2�����K~�4���
J�S�>�ak����J��+�Vk��d�q�jd!�@	�
T�C�u�������f^O�VV��g�{������& ��]�~\
�!�e��%������t����hp|vzu|����o��<h�����_h��HV���e���/�������s���]��fL^���S���\U�������I�&-Q�E��d��Fv����$����b�j<�JP��
J�Mopv����"���\�_�fl*�t��k�s�g�.z����@�b��~��f�t�
Y#o!z=x�k��y���5�:S=L�'@@�x�(2�R�O[l��g���������mc����EQ�}r�0
�d�G\�������g����@�� �I@R1&���x���Rj��������	���u�I�v����b���-�6]Z�IP$#[x�@"#(b#�\P$g���9F����(���HV��im-���D���$��k�Z�`�n���;0��5�H+����Q� �T��R,��W�Q�����PT���`�A3�6���%%c��0U_�*k�J1f��uxtA��]Sz���Z��>��,7D���
���H��'�v��6�����y�(-������5t�4]5X����f������o���jS��A����cO�*��|1�0u?MC��2�������X������db��~������������E������|
>�m�	+�h{a�N��c4cV/�bev��kySA�G��E������-���R��
%_l���K��U��Q0|P4�,�dq����;�A�M���|����j!�q� }�N�Mp
��Zc��$F�� ��C;=�������S2u�
.�5-n����dy([�oh�����j��7����H�UKh?�|��NV��x_y�����ZX�Q5�Y���_�����=bqQE�k����&��7���Ss��*��)`�7qS�2����;�c�)�����'�=i<)�y�Zl-Co����7W���}�qp��9|���&6������F���"6���W�(�X"��7�u���]M�+
��:���J=���h�Q�CjN��@�_��K;�|�/�~p9H�b��za(������.i_�(�CX�<����r|��<??��9e���O$G���dU��L<�����QV���>���q"El/r�>;�bH�#���;��M�D�������.������\G�W�����0��A�������i��s�5!}$|@~���%������i 7�0�����m��[�@dP����4��\��F�����P��5���K|��{:���������=#tL�;�F&<�!�p���1������l�^��	�(���v�W������A�
/q3���v����Pc�	W����:iz�p�u4z����)H��[z;}���9)MUx_[�n{�bAW���`�T5a)�u����Q����.�a�A]���R��BWw<-�fVt���u�+�T���F�s�Q����	���Q {#��qi�NZH���/��p�H�`�BB��H	~3�:={�{g��Z ��E=\.�T{��PJ���
K��+R���7�<MN�K�I���l,��%�|IW�>&�������z������_0�����^��i4�	�)����V��5x�*+��>t��LGm���EgZM6,.J4,�F���� d�t%��#�s~*��������?k��,�T���h��u/7?`����r�������������J-�D����B%�%JzjE��PO��'�~���r�}K��C�1q��5U���'�91#�UCB���
����?w��A��76�������J������}�i��u�����%�~������gut�i�0���qUkB��9��GU|����
c���=�=��}�@[t���.��~+1�9��MT�n�a����fc3��Wg���"��R�p?�y���t� ��?M0i�k����.����p��F�T��J-8*�H���o5R#]�&�:r�2X�V,��D,�;e+���Xrg�6-\�6�`x�X'�K7c�!HZx�w�t�
�#�'g<��#�k'M����>�d��rdr��+�r�<OC��;������C�9��x���3[�
���H�Vb$����s���=[q�\,wzy��8>�a������YP���R#��S��z\}��;Iz�����=e�J,��7 }�^���g�D&�N#nrb��pv��t*Z�(k��f���s�)�����4��W#��u8�����s��������%=���	��Z���`�� �t����S�	0��$�(^*�(7�8H��k������%�������/�x��7�i�����UF[��"�U%�@�t:���`��]�`�E�.�E����Q�WV����j�G
-\H|o�m�P�>��>Tp��O���_�~<=<�}�����<|�#G����rp��}�L���:
�D�>� �eGQI���R)l�B)B�W�y��p��?�S��+w�a��{{x�~@�B����=���e���a/����wn&����_�5-Ap�����Z�6��j)���@�1��3L����2������,�,�[^��-����Jf�3����P�>(�L�!EALh��3��c�$�^�����R�)��~�����������1!a��1!����	�PC���.�	�{��|L�$���8�W��cB':O::u�H??&$l9?&d���1�j(:E0������1i2�zt������O�`_��Q"X;#�/���:�����T��
��R�����NM���#�&C�����z�����/�z���	��S�K��`����`��-,;:Q}`G�����K���Y�Ez�Pj��A��������A�X��U�Ve�D�U��
3X*R�"��T��$EP���KF�@�4a�xd\��u��k��&�u�T���9'$�7'd7�Rq@���R����\Z`�d,P��-�#�C��)�U��W�?9��� �E��ANIw�����J�
/*Q�_�����������=q�L�|L��mY ���!��"��J�M������=�B���|�W�mN����Tc�l}�T�[6�����I����/�P�/%qS.Y
�t�5��E!���W�H�dH�H��P�"=y�A��~�X��2�pab
K��PH��	��	�"2{5x��!I�*�#�B)��5m
T����P�������9!Be�9�����

���#���BQ�����th�I�&��,�)����=�I��O6���������J���}��q,{�iL����5������3F���&!O�`��D���^
�����{�<9d��F	�@���wa����.1���.��)�S���Xl��vUYz�"I�"��D'	�<zTb������fH{�0����r!Ik�|d����! �H
4l�*�&Jt'����$I�<��

�<2*`�:T��f�C����hC�0 ���6�
�A���R0Q9AN011���I( �H�(��wZc{-��J(I�<��`%���~�������uO.���c�����}������QZ~��P�G���H�2~n������9;�h��h��+�8���i��+�8��2,�?&�`&�M�P�k>���K��"�d����J5���)�a|�U�|��;�UZv������J"��T�`4E��nM�6�]:VDdI��B��G�
Z�+���O*�.�\�l���8����8afK�	YD��
��J8~�ne�l�r�	����c����~�O��T��ev^4HXo^$�l�������ShZ���.�3_2������@��G���~��I�bW?�T?'B�,<'N�Z�R�"*$����(�b��`W�%cGB�,�>�:zp��'sWT9�Y��
P�>>=��b��HnbK�'�n����������Mv�HS|��'�xvrr�it���yf}{�	h��.|�9q�����%�WH���x�v[����>��xB��g���q�77��C3��m�����>�Gk[)�<���~�b�gw����H�>�}�h4�_��w����u���������O��~&�����9�.H��9�����Y#o/�NB���c��G�W���=&4����y�w��Sw��:Wq�W������E��'���Q�A��0�R����+��o"#��"������-��9K��i������$�,�	�p@�Q	DV�	[������	@���<������O��-6�?8zG?���;�il����q�+�	���u%��-���c��c1%
���,����z������{������)���3�ixL)D�����t����������$R�A���kh��r���dd����[���_������U\���������@��� �^���n�+Y8��Z��!P'g.�`D?m�y�q}�Cx~tM��S���G`C�Qy��nBh2����<x��<���oe��<�	�����W#er/���(�C9���r�J<T���C���<Is��z�DB��H^#�77Z[��	>�;�������������7�����Y����H��${{�[��`�������X��}s�%����mq���L�#��p�Y����f��Tl��r	78��S����e�IQ��=�,�4F�'������nx�k�F�n�7��-	���m��m����]��N
RF��H�@J@�$��c���Q��D\�#W��*��"b<�\�j'�2e)+2,:����M�v#W�B���B,� ��J���!�*��U���m�S6��'���J���X��[0.[o�G��7��R�x^]�C�R���
�h��	^�Q�0/�Z��:��%F3��r�Fl+���J{�����5gLhE����kTD���Ww������;�zu����N��;�^�)����Ww��������xu'��y�����W+J+����Wg2�����W�Q�W�K�Y>-h�<ZW���%�^�N������)�r�f�����I��V��Q��U�����4�*���)PA	�8X��cXd���#����mq��.�M.dH����Yr��j�&�	��N�v�V!�N�������""#�9�%�7(C��~+��PdCs�PfP�RL��T�D�8(V�a4#�/)_$#���2��D���$���k4��Z�<C�k�����U?�@	��k[�W��J����"e+��_�1-=� ���2������>�<�9� hL������r��#��~�������f��0����D�8(V���vb�Zz�@��5e��_;1}��Q���t�~d��wC~K�1��u�>L����e������i��h'om'ou��^&n5��g�.���������`�p9����D�}D9���a���ss�lo��3�H�m���vJ��.���U<����:��@h��^}�������W�<�f	i/S��������,X����h:�;���z#����Hf���Hl���"~���ylNu�=�S�HaZ�k
��}T������d��t_�6��J�u��y	�p�NB�����?9~D��n�7������L<�W����IHe���*�u����ob�uU8����M�:�������x��N���nC�u���.#`���*D�]�������$�-���:����K?Y����&�hze���2|2�v�X������]�����H]����o�W�WD�>��p���e�,F��x/($��2�!A���*��n�b�
��@lHdF�!�W2�%��������� /4�)2�H���6�j'4�e�(�pb3VdF��rMp�xws1�1�/���
&<]g�������9mn.X-��A���S��H&�:���Z�m���	���&��t�����(�}4"��i�2�����fy�T�A	[>*q��$t��vN�t���|�#n�������#q.�Z�O��2�S�o�WR���}����FO�HqWJ���6{�rP��M���2��A����8���r���f3<�<��9��cs�J[�Z��-�86��;6~mO�P>��> ���!c��ar�K�'��!���<��QT�g�S���X���r��j�$�D_���,%D�_
�<���L - 4�� GU�2\2�QAd��7R��e��*�CT���T��*)U��JJU<��R���TC�du�q��1OF�x���|�T�����o�I�D�X,��S���iFX��������NL&�BDK�E\n��%"v���;��R�&����v�S�<u*�+�_��EF��gdy*�9���w��$�G�Kv	��p	�K��p/W?	��=%�_7s���S]93H�FT���ts(�����BEhq^(��o
�t=��a������m�Pm?�H��U%?�~h=�g�~��K��W�}p����y�nh�N/Z���d��.��Kx�I�F$�u��5Gg*��1!�i�G�nwd�l�A��	e��m����#}��@��l����MU"G�0�1"���H��V[�u����*Ta�e'0eAoHe�!y�+q[�sM~��^v��^N\�#��@���k)��Icg�~p�H����%�7-8_�f'�DK�)"��#�sX��#��x�����D_JT��}a��w���i@����:�P
���m���e�+#��-�t�D���������-TH���2sYj%�����
?�R��A"+
2�$l����v6(�@{$�
��*4�<�LmF�g��9h��qae�+|���G_�x�L��2qY�����7v�k;���m�4��S���N�`��F��
"�6F�g� �=�K�R���R����]�5=���!\e�*uPV�S�����z��Y>!�J�D�f��?�J���R����Uj�0<���9U�O�*q�T�c��M���>O�4}NW���JL��*j��Hy"�������x(����Q��P�����8��!N�X*yNR���������+���W���_l��W���T~���=��4���������g�>���q<%�1v<~����B�,�)K���h�1]��6*'�q���?O�Q[��A7%��)~M��f����:Y�1v�NU��Z@s����t�:@��0)f�}&L�S^���R�L��G�;=�Do�"9��]I��,7�����2�����g�����|���?���!$��)y�G��[��������v<�f�=��p��������#:t��yJG�s7���Q���"�_�1��1�H60�*�������iG�f�5��-
QQ����J9'"�i��D��iW1R�,���G>hL������d��P�4�b'3<{���
yL�@�j�������<d���A����*H�x��	Z��}LBUGT��U��W������-���*Qd9�DZ�WeN�u����U����?^���[�����.�o�^���ox^�����O��Nq~��������|����W�|�]���f���Z��/��w���K��]t[lc�F��@������'�����;Z��!���*/0��Zm9��.�Yu���Kn-]f�hc�������S�������e�����Y�f�?��?shu�g�]hs�"�5��9�>��VLw(���H��cAW��6��d���*[.�k���
6NV�D�����B.��q�����=ln��[o����L#�te�\�Y��]�}��������������r�#\v���{���p��&��\����g����x\�k�n���������:?6��Vo��6�}�
db#��%���H�C���<�1|0���s�J $u��Ty
{������_f��Q��v�|�-!f��\��-��R�|5`���P!�Mu�`����f�oeX�~���X�N~m�g��|�9�+�Y�R�te��r���v�S�r�M�Tf�/��vrl�Wr��r��������ry\%c+	���Y*�PB��twI�N�0�6������pZ�1�"���oewn+�+[�-��|g1u�n��WYGi(�|I���O�8V�[/w�o���;>�f��������.g�������������q��/�\�3O2���������Q�v������k���/�.�(��uF������/�x��\�l|�����U��[�-S+!����{�W���x���K^&3���xn�T��d�+V������G�c*��@���E<����_��;��u
�ubM���=���l��������o��;�~5QG
��;�Ys�j6�o��1VE
�~[��{�h�9�n#�v%��Xa��t\��*�A��J*-�*�0Q��hU�
5�U��1v��F���Jt�
�>��0[�
�BV����gyD����R����f
���w���h�RUT� �����\����.Re�Z/�����B���+E�!��j�P�^8���*��Va��^�2�]a���+��H8���G��K�
2�V\!Zu� ���J�B%�b�1�N���6����
"�8���c��N��L�����Wa�B�f���J��J
?�WZbU�a��
�����G��*�0�I��j�;k^c{_W��2��Lc���������,_���<�uW�WU���*��`T�[��q�*�-������u��+�6Zy����O���wy%$���V�����CX�������R��n����D|�s�
g<�T''���bO@/����g�Fl��6��z��d�S	9���O��\��]�~<=<�}�����<|�#G�����.O�����K�.�E����Q/l��QVU��ZX]������C�B�=V���HEPs�g��R��G�������n���6/���Y������H��j]��2���q�C|{�	���l��x{�x�Zu��l21d������d��\�>��E��2�g�����o���8����_�����a��
���aHS�/��0�����]���������x�O������wW�����O�������*S�u��d���s2��c���������n����5�]�ah
�l�����G�Fs�f�N
�(�&|��3{d� ����r�����u�wi���
���
hilO��
bed��/�_�AV��1�C����t�69?:����������77���75]F:#h�BvP��_L�)-���~ux���=�����}:(��>�R#����VI�y���N?W�Q�7������z5L��:�[A��~|����	��IJ��M���X���$��-FE6�4!�a�s���Fzwu��6�%s@��j���$^��L4���Z�UT^�������"P7����}{��\�'x��
�t	B5wj��}�4���Zf�!�z?��k-*�����)���~@��=�l�-)����0���}�1�!m��:3-�+�
�Nx@�y��F�f�!��:�u3t�7�z�f��y��[�vp1�<�����8����xZ����g0S�3I(,��K0�������_�";���o������~�9nS��"�������u�#�812h�6(�w�X\�;�m��n���m��T���pp�s'���
@���B�}C+"���3�mZ��H�\�����{h��C�n
��{JV����BB>Z.R����L��������i�}��wx)��{�������r���7�9���C^	!�����Q���~q~]�@���w��.�5���K��C8q����u*����n�YL���������NWi�%��(�g10^9�RP5k���s�_}7�=w=�vn�z�-$tY7����~�8�����1���lw�E��6�
���r�#h{>!_����N^��������-�`3���Ys���q�Q�ID�.�����-����6yw|J��-�c�C+��,�2q��N����B����x����>:����8��
��vqP����v��#]��]xC��V;IT������>;������?J)Qe�Ie����u�O^clK$"��I����|9�,+4�tIg��k�O��7E��QhDZ�X��������E���x��i"B�{v��>9kS�'�8H3�P;	m�r�6�������M�MC4�yL,�tO�`h�L�����(�7��b4tG�-��v��������&�������
B~t?��9�-�v��7�1�nt|3�|*���\`��d�3Lt!���Q��J��-��z��g.���(f"��sk2v�,x7��Yl�{7��m<����Y�m-Z��g������%�����=%�~�E�������PqY���j�}���{1��M�lw��;�����^���W�����6�5����5(9����5�S7����<���x�
o��&�2��5���gxd�'����?�[w��1���`N}��#y���Y����|���������������`#��h4{c��1�u6�a7�j�r��G[�u0 ��������
���eE4������\L�$�r9E���$�	�n<��y'��ag�����4@��Fg:{�g��]�?���C�����+f��������<�_8������r�?F�P�6���m���r�X�k��V�e'�.^��}�
�:B-o�p����A��<���)G�&��}U��"y��"��0[�����1d����y�V����$����rPc"��H�e�25u,��kbgC�*yw:��miR�(0c6>������x�$Y�p?a/Uc��H�����}�����1��N�qm`:�[��F��4���vxG�I�B�)�8N�[��`���~����'f!����t�=��A6q@4�Q��F=v�Y���N������_~}|��L��l������8&c�9��rn��@��s��yLv��gZc����<:�umC�i�]�����q�5�]�a���pt�b:�S�D���1�D�����;�	�% T���6���n�5�j3nj��F6����,��#zh��
DL��^(�����qh|�����Q�w�P��|&=P(���ph��f������_��9�K���p@�P�!/CW�=�����tQ+��L�`\~_�I�nhXR��m
�+��f8;������"�sV��%���h���$Q� �Q4��P��%x4�`�9��KG����)��)�f�6�����V��e|M	�[��f��ZZ�1.h��/2L�62��>��J[������x�b8�Qx]j|�!������}wB6r=�lk��8h��,�l�Z���BuZ�3��5�&5��.x�zU!��yQ@k7@��1@��Wj
2R��=����"�gM8"n|���5����S�����
��-�!�D��
����&��<�����|����?��R-�Xy|�B�i���������o�9����zsGZ��(����r�����#��\��*���M�#X��3x4�`>��cg����{.����#�2�Bb��[:�����:�	�:��&��b@;gZ��O]2���b{�?�&g��9��<�M���M�=���&ddQ�S_:�
�x ����X���/���48��p�[,�h*���>�D0+�]�w N�����f���B��s���#�"Q'�t����AT�a;��vk�Y���	�������W%�-j/BH��2����	���D�-��coK�{������BQi1���G`��P:��	e������=��<��5��d��$g��[�TP��
#25Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Teodor Sigaev (#24)
Re: Review: B-Tree emulation for GIN

Teodor Sigaev wrote:

You might want to declare extra_data as just "void *", instead of an
array of pointers. The data type implementation might want to store
something there that's not per-key, but applies to the whole query. I
see that you're passing it to comparePartial, but that seems to be
just future-proofing. What kind of a data type are you envisioning
that would

wildspeed module (http://www.sigaev.ru/cvsweb/cvsweb.cgi/wildspeed/) -
for each key from it's needed to store some info. Right now it's coded
directly in Datum, but it looks ugly (at least for me).

Ok, I guess it's best to leave it as you had in the patch then.

make use of it? It seems that you could pass the same information in
the partial key Datum itself that extractQuery returns. You're
currently using it as a way to avoid some palloc's in
gin_tsquery_consistent(). That seems like a pretty dirty hack. I doubt
there's any meaningful performance advantage from that, but if there
is, I think you could use a statically allocated array instead.

It's easy to un-dirty that hack, but before I'd like to see your
comments about thoughts above.

Yeah, please revert that hack.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#26Teodor Sigaev
teodor@sigaev.ru
In reply to: Heikki Linnakangas (#25)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

It's easy to un-dirty that hack, but before I'd like to see your
comments about thoughts above.

Yeah, please revert that hack.

Done. Also, I changed void *extra_data to Pointer extra_data and corresponding
**extra_data and ***extra_data to simplify understanding.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

btree_gin-0.12.gzapplication/x-tar; name=btree_gin-0.12.gzDownload
#27Tom Lane
tgl@sss.pgh.pa.us
In reply to: Teodor Sigaev (#19)
Re: Review: B-Tree emulation for GIN

[ back to this patch... ]

Teodor Sigaev <teodor@sigaev.ru> writes:

Looked at this a bit ... do you think it's really a good idea to remove
the strategy number argument of comparePartial? The argument given in
the docs for it is that it might be needed to determine when to end the
scan, and that still seems plausible to me.

Strategy number is not removed, it's replaced by pointer to opclass-specific
data on per key basis. Actually, partial match feature is new for 8.4 and there
is no any compatibility problem. None of existing opclasses (except
contrib/btree_gin) uses strategy number in comparePartial.

I'm still not real happy about omitting the strategy number from
comparePartial's arguments. Yes, the extractQuery function can make
up for that if it has to, but why should it have to? It seems to me
to be inconsistent that the consistent function gets the strategy
number but comparePartial doesn't.

I know that there's not a backwards compatibility issue here, but it
still seems to me that you're forcing opclasses to do things the hard
way (allocating an extra_data entry) when they might only need
information that's already part of the call signature for existing
functions.

regards, tom lane

#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#27)
Re: Review: B-Tree emulation for GIN

BTW ... while I'm thinking about it: it seems to me to be a serious
error that the consistent() function isn't given nkeys so that it can
know the length of the arrays it's being handed. I suppose it's
possible for it to re-deduce nkeys by examining the query datum, but
that could be quite expensive; and it's certainly error-prone to have
to keep extractQuery() and consistent() in sync on this. Since we are
adding arguments to consistent() anyway for 8.4, I propose that its
signature ought to be

bool consistent(bool check[], StrategyNumber n, Datum query,
int32 nkeys, bool *recheck, Pointer extra_data[])

where the first three arguments are what existed in 8.3.

regards, tom lane

#29Andrew Gierth
andrew@tao11.riddles.org.uk
In reply to: Ibrar Ahmed (#1)
Re: Review: B-Tree emulation for GIN

"Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes:

Tom> BTW ... while I'm thinking about it: it seems to me to be a
Tom> serious error that the consistent() function isn't given nkeys
Tom> so that it can know the length of the arrays it's being handed.
Tom> I suppose it's possible for it to re-deduce nkeys by examining
Tom> the query datum, but that could be quite expensive; and it's
Tom> certainly error-prone to have to keep extractQuery() and
Tom> consistent() in sync on this.

I ran into exactly this problem in hstore; the omission of nkeys there
is seriously annoying.

--
Andrew (irc:RhodiumToad)

#30Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Gierth (#29)
Re: Review: B-Tree emulation for GIN

Andrew Gierth <andrew@tao11.riddles.org.uk> writes:

"Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes:
Tom> BTW ... while I'm thinking about it: it seems to me to be a
Tom> serious error that the consistent() function isn't given nkeys
Tom> so that it can know the length of the arrays it's being handed.

I ran into exactly this problem in hstore; the omission of nkeys there
is seriously annoying.

It's de-omitted ...

regards, tom lane

#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Teodor Sigaev (#26)
Re: Review: B-Tree emulation for GIN

Teodor Sigaev <teodor@sigaev.ru> writes:

[ btree_gin 0.12 ]

Committed with some editorializations. There are still a few loose
ends:

* the question about zero-key queries that I mentioned before

* After this new look at the code I think that matchPartialInPendingList
is completely broken. Surely it's an infinite loop if the
comparePartial function returns -1. I also don't understand why it
stops short of examining the tuple at maxoff, or for that matter why
it's doing any searching at all when the code that's calling it seems
to be implementing a binary search. I think that part of the code
needs more testing and commenting.

* In keyGetItem(), it's not at all clear what the assumptions are for
the contents of the entryRes[] array and for the interaction with a
LossyPage entry. Is it intentional that you run through the array
comparing to a LossyPage key before deciding to exit the loop? It
seems like that might be affecting the behavior at the next call,
but if so you're making some undocumented assumptions about the way
comparison of a lossy-page pointer is going to behave. I thought it'd
be cleaner to move the ItemPointerIsLossyPage check up to before that
loop (right after the ItemPointerIsMax test) but the more I look at it
the less sure I am if that would break things. That code needs more
commenting too.

* I'd also like to come to some agreement about getting rid of the
fail-on-NULL-scankey problem in newScanKey(). As I noted in the
comment there, we could make that work cleanly if we are willing to
assume that all GIN-indexable operators are strict. We already assume
the same for hash and btree operators, so it doesn't seem like a big
problem to do this, but I wonder if there are any objections.

regards, tom lane

#32Jeff Davis
pgsql@j-davis.com
In reply to: Tom Lane (#31)
Re: Review: B-Tree emulation for GIN

On Wed, 2009-03-25 at 19:31 -0400, Tom Lane wrote:

* I'd also like to come to some agreement about getting rid of the
fail-on-NULL-scankey problem in newScanKey(). As I noted in the
comment there, we could make that work cleanly if we are willing to
assume that all GIN-indexable operators are strict. We already assume
the same for hash and btree operators, so it doesn't seem like a big
problem to do this, but I wonder if there are any objections.

"IS NULL" is indexable in a btree and non-strict, so there is at least
some precedent.

Also, if extractQuery is non-strict, shouldn't we call it and see if it
returns some useful keys? If so, I don't see a reason to assume that
nothing matches.

If the opclass author wants a search against NULL to mean "matches
nothing", they can just make extractQuery non-strict and return -1.

However, if extractQuery is strict or returns NULL, I'm fine with either
an error or assuming "nothing matches". I don't see a functionality
difference either way, so we should just document whatever seems to make
the most sense.

Regards,
Jeff Davis

#33Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Davis (#32)
Re: Review: B-Tree emulation for GIN

Jeff Davis <pgsql@j-davis.com> writes:

Also, if extractQuery is non-strict, shouldn't we call it and see if it
returns some useful keys?

Perhaps. One risk factor for approaching it that way is that there are
probably a lot of opclasses out there that haven't bothered to mark
these functions strict, since it's never mattered before. (A handy
example is that the brand new btree_gin opclasses did not bother, as
submitted; though in a fit of paranoia I made them do so before
committing.) If the extractQuery function isn't actually guarding
against this, you'll get a crash.

That's not a showstopper reason not to change, of course, but it does
mean that I'd like to see an actual use case for a non-strict GIN index
operator before taking any risk. Note that IS NULL isn't an operator,
so even if we were to try to support it in GIN, that would be a
different code path (just as it is in btree).

regards, tom lane

#34Teodor Sigaev
teodor@sigaev.ru
In reply to: Tom Lane (#31)
1 attachment(s)
Re: Review: B-Tree emulation for GIN

* After this new look at the code I think that matchPartialInPendingList
is completely broken. Surely it's an infinite loop if the
comparePartial function returns -1. I also don't understand why it

fixed

stops short of examining the tuple at maxoff, or for that matter why
it's doing any searching at all when the code that's calling it seems
to be implementing a binary search. I think that part of the code
needs more testing and commenting.

Tuples of rows are stored in pending list in the same order as in entry tree
(order by (attrnum, Datum)). So, it's possible to use binary search. By test's
binary search presents about 5-15% of performance.

But heap's row could be one page or on several pages. If page contains
several rows, each row is checked separately and tuples of one heap row are
placed from pendingPosition->firstOffset up to pendingPosition->lastOffset.
The page is marked by GIN_LIST_FULLROW flag if it contains all tuples of row(s)
or it's a last page in page's chain containing single heap row.

scanGetCandidate() always returns offset range for tuples of one heap row.
Although it may return NOT all tuples of row, if so then collectDatumForItem()
will ask scanGetCandidate() about next portion of tuples of that heap row. It's
safe because tuple's of one heap row are continuosly stored in pending list.

* In keyGetItem(), it's not at all clear what the assumptions are for
the contents of the entryRes[] array and for the interaction with a
LossyPage entry. Is it intentional that you run through the array
comparing to a LossyPage key before deciding to exit the loop? It
seems like that might be affecting the behavior at the next call,
but if so you're making some undocumented assumptions about the way
comparison of a lossy-page pointer is going to behave. I thought it'd
be cleaner to move the ItemPointerIsLossyPage check up to before that
loop (right after the ItemPointerIsMax test) but the more I look at it
the less sure I am if that would break things. That code needs more
commenting too.

entryRes[] array is used for two purposes:
- as an argument for consistentFn
- to store information about entries which was a minimal on previous
call/loop. So, only that entries should be renewed by entryGetItem()
call. Lossy page is encoded as ItemPointer with greatest offset (0xffff),
so keyGetItem() could return items from page and then return the same
page as lossy. This is not a problem because of usage of TIDBitmap to
callect all results.

So, algorithm of keyGetItem could be described as:
1 renew all entries which is equal to previous result (entryGetItems returns
them in increasing order)
2 find minimal entries
3 fill up entryRes[] to new values and check lossy or call consistentFn

* I'd also like to come to some agreement about getting rid of the
fail-on-NULL-scankey problem in newScanKey(). As I noted in the
comment there, we could make that work cleanly if we are willing to
assume that all GIN-indexable operators are strict. We already assume
the same for hash and btree operators, so it doesn't seem like a big
problem to do this, but I wonder if there are any objections.

Agree. I changed the GIN code, but don't know where is other places to change
to fixate this agreement.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

Attachments:

gin.patch.gzapplication/x-tar; name=gin.patch.gzDownload
#35Tom Lane
tgl@sss.pgh.pa.us
In reply to: Teodor Sigaev (#34)
Re: Review: B-Tree emulation for GIN

Teodor Sigaev <teodor@sigaev.ru> writes:

[ fixes for the GIN stuff I complained about before ]

This all looks good to me, please apply. One little suggestion:

! /*
! * entryRes array is used for:
! * - as an argument for consistentFn
! * - entry->curItem with corresponding key->entryRes[i] == false are greater
! * than key->curItem, so next loop/call they should be renewed
! * by entryGetItem(). So, we need to set up an array before
! * checking of lossy page.
! */

pgindent will reflow this comment block, since it's not at the left
margin. To keep the formatting looking good you'll need to add /*--------

* I'd also like to come to some agreement about getting rid of the
fail-on-NULL-scankey problem in newScanKey(). As I noted in the
comment there, we could make that work cleanly if we are willing to
assume that all GIN-indexable operators are strict. We already assume
the same for hash and btree operators, so it doesn't seem like a big
problem to do this, but I wonder if there are any objections.

Agree. I changed the GIN code, but don't know where is other places
to change to fixate this agreement.

I don't think there is anything else that needs to be done for that.

regards, tom lane