mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
Repair intarray's problems with TOASTed input, avoid scribbling on
source data, improve split algorithm for intbig_ops. Oleg Bartunov with some kibitzing from Tom Lane.
This commit is contained in:
parent
9e07c9a39c
commit
2ef6e7ee18
@ -10,6 +10,12 @@ All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov
|
|||||||
(oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
|
(oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
|
||||||
for additional information.
|
for additional information.
|
||||||
|
|
||||||
|
CHANGES:
|
||||||
|
|
||||||
|
March 19, 2001
|
||||||
|
1. Added support for toastable keys
|
||||||
|
2. Improved split algorithm for intbig (selection speedup is about 30%)
|
||||||
|
|
||||||
INSTALLATION:
|
INSTALLATION:
|
||||||
|
|
||||||
gmake
|
gmake
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
format for these routines is dictated by Postgres architecture.
|
format for these routines is dictated by Postgres architecture.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define GIST_DEBUG
|
||||||
|
#define GIST_QUERY_DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
@ -17,32 +22,46 @@
|
|||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "storage/bufpage.h"
|
#include "storage/bufpage.h"
|
||||||
|
|
||||||
|
/* number ranges for compression */
|
||||||
#define MAXNUMRANGE 100
|
#define MAXNUMRANGE 100
|
||||||
|
|
||||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
||||||
#define abs(a) ((a) < (0) ? -(a) : (a))
|
#define abs(a) ((a) < (0) ? -(a) : (a))
|
||||||
|
|
||||||
#define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
|
/* dimension of array */
|
||||||
#ifdef PGSQL71
|
|
||||||
#define ARRSIZE(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
|
|
||||||
#else
|
|
||||||
#define ARRSIZE(x) getNitems( ARR_NDIM(x), ARR_DIMS(x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NDIM 1
|
#define NDIM 1
|
||||||
|
|
||||||
#define ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRSIZE( x ) ) ? 0 : 1 ) : 1 ) : 1 )
|
/* useful macros for accessing int4 arrays */
|
||||||
#define SORT(x) if ( ARRSIZE( x ) > 1 ) isort( (void*)ARRPTR( x ), ARRSIZE( x ) );
|
#define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
|
||||||
|
#ifdef PGSQL71
|
||||||
|
#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
|
||||||
|
#else
|
||||||
|
#define ARRNELEMS(x) getNitems( ARR_NDIM(x), ARR_DIMS(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : 1 ) : 1 )
|
||||||
|
|
||||||
|
#define SORT(x) \
|
||||||
|
do { \
|
||||||
|
if ( ARRNELEMS( x ) > 1 ) \
|
||||||
|
isort( (void*)ARRPTR( x ), ARRNELEMS( x ) ); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define PREPAREARR(x) \
|
#define PREPAREARR(x) \
|
||||||
if ( ARRSIZE( x ) > 1 ) {\
|
do { \
|
||||||
if ( isort( (void*)ARRPTR( x ), ARRSIZE( x ) ) )\
|
if ( ARRNELEMS( x ) > 1 ) \
|
||||||
x = _int_unique( x );\
|
if ( isort( (void*)ARRPTR( x ), ARRNELEMS( x ) ) ) \
|
||||||
}
|
x = _int_unique( x ); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* "wish" function */
|
||||||
|
#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
|
||||||
|
|
||||||
|
|
||||||
/* bigint defines */
|
/* bigint defines */
|
||||||
#define BITBYTE 8
|
#define BITBYTE 8
|
||||||
#define SIGLENINT 128
|
#define SIGLENINT 64 /* >122 => key will toast, so very slow!!! */
|
||||||
#define SIGLEN ( sizeof(int)*SIGLENINT )
|
#define SIGLEN ( sizeof(int)*SIGLENINT )
|
||||||
#define SIGLENBIT (SIGLEN*BITBYTE)
|
#define SIGLENBIT (SIGLEN*BITBYTE)
|
||||||
|
|
||||||
@ -50,10 +69,6 @@ typedef char BITVEC[SIGLEN];
|
|||||||
typedef char* BITVECP;
|
typedef char* BITVECP;
|
||||||
#define SIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) )
|
#define SIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) )
|
||||||
|
|
||||||
#define NULLIFY(a) MemSet( a, 0, sizeof( BITVEC ) )
|
|
||||||
#define NEWSIG(a) \
|
|
||||||
a=(BITVECP) malloc( sizeof( BITVEC ) );\
|
|
||||||
NULLIFY(a);
|
|
||||||
|
|
||||||
#define LOOPBYTE(a) \
|
#define LOOPBYTE(a) \
|
||||||
for(i=0;i<SIGLEN;i++) {\
|
for(i=0;i<SIGLEN;i++) {\
|
||||||
@ -71,13 +86,7 @@ typedef char* BITVECP;
|
|||||||
#define SETBIT(x,i) GETBYTEBIT(x,i) |= ( 0x01 << ( (i) % BITBYTE ) )
|
#define SETBIT(x,i) GETBYTEBIT(x,i) |= ( 0x01 << ( (i) % BITBYTE ) )
|
||||||
#define GETBIT(x,i) ( (GETBYTEBIT(x,i) >> ( (i) % BITBYTE )) & 0x01 )
|
#define GETBIT(x,i) ( (GETBYTEBIT(x,i) >> ( (i) % BITBYTE )) & 0x01 )
|
||||||
|
|
||||||
#define union_sig(a,b,r) LOOPBYTE(r[i] = a[i] | b[i])
|
|
||||||
#define inter_sig(a,b,r) LOOPBYTE(r[i] = a[i] & b[i])
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define GIST_DEBUG
|
|
||||||
#define GIST_QUERY_DEBUG
|
|
||||||
*/
|
|
||||||
#ifdef GIST_DEBUG
|
#ifdef GIST_DEBUG
|
||||||
static void printarr ( ArrayType * a, int num ) {
|
static void printarr ( ArrayType * a, int num ) {
|
||||||
char bbb[16384];
|
char bbb[16384];
|
||||||
@ -87,7 +96,7 @@ static void printarr ( ArrayType * a, int num ) {
|
|||||||
d = ARRPTR( a );
|
d = ARRPTR( a );
|
||||||
*bbb = '\0';
|
*bbb = '\0';
|
||||||
cur = bbb;
|
cur = bbb;
|
||||||
for(l=0; l<min( num, ARRSIZE( a ));l++) {
|
for(l=0; l<min( num, ARRNELEMS( a ));l++) {
|
||||||
sprintf(cur,"%d ", d[l] );
|
sprintf(cur,"%d ", d[l] );
|
||||||
cur = strchr( cur, '\0' ) ;
|
cur = strchr( cur, '\0' ) ;
|
||||||
}
|
}
|
||||||
@ -119,12 +128,13 @@ static ArrayType * resize_intArrayType( ArrayType * a, int num );
|
|||||||
static int internal_size( int *a, int len );
|
static int internal_size( int *a, int len );
|
||||||
static ArrayType * _int_unique( ArrayType * a );
|
static ArrayType * _int_unique( ArrayType * a );
|
||||||
|
|
||||||
/* common gist function*/
|
/* common GiST function*/
|
||||||
static GIST_SPLITVEC * _int_common_picksplit(bytea *entryvec,
|
static GIST_SPLITVEC * _int_common_picksplit(bytea *entryvec,
|
||||||
GIST_SPLITVEC *v,
|
GIST_SPLITVEC *v,
|
||||||
formarray unionf,
|
formarray unionf,
|
||||||
formarray interf,
|
formarray interf,
|
||||||
formfloat sizef);
|
formfloat sizef,
|
||||||
|
float coef);
|
||||||
static float * _int_common_penalty(GISTENTRY *origentry,
|
static float * _int_common_penalty(GISTENTRY *origentry,
|
||||||
GISTENTRY *newentry,
|
GISTENTRY *newentry,
|
||||||
float *result,
|
float *result,
|
||||||
@ -147,7 +157,7 @@ bool * g_int_same(ArrayType *b1, ArrayType *b2, bool *result);
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** R-tree suport functions
|
** R-tree support functions
|
||||||
*/
|
*/
|
||||||
bool inner_int_contains(ArrayType *a, ArrayType *b);
|
bool inner_int_contains(ArrayType *a, ArrayType *b);
|
||||||
bool inner_int_overlap(ArrayType *a, ArrayType *b);
|
bool inner_int_overlap(ArrayType *a, ArrayType *b);
|
||||||
@ -199,6 +209,8 @@ g_int_consistent(GISTENTRY *entry,
|
|||||||
bool retval;
|
bool retval;
|
||||||
|
|
||||||
/* sort query for fast search, key is already sorted */
|
/* sort query for fast search, key is already sorted */
|
||||||
|
/* XXX are we sure it's safe to scribble on the query object here? */
|
||||||
|
/* XXX what about toasted input? */
|
||||||
if ( ARRISNULL( query ) ) return FALSE;
|
if ( ARRISNULL( query ) ) return FALSE;
|
||||||
PREPAREARR( query );
|
PREPAREARR( query );
|
||||||
|
|
||||||
@ -238,21 +250,29 @@ g_int_compress(GISTENTRY *entry)
|
|||||||
int i,min,cand;
|
int i,min,cand;
|
||||||
|
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
if ( ! retval )
|
|
||||||
elog(ERROR,"Can't allocate memory for compression");
|
|
||||||
|
|
||||||
if ( ARRISNULL( (ArrayType *) entry->pred ) ) {
|
#ifdef PGSQL71
|
||||||
|
if ( entry->pred )
|
||||||
|
r = (ArrayType *)PG_DETOAST_DATUM_COPY( entry->pred );
|
||||||
|
else
|
||||||
|
r = NULL;
|
||||||
|
#else
|
||||||
|
r = copy_intArrayType( (ArrayType *) entry->pred );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( ARRISNULL( r ) ) {
|
||||||
#ifdef GIST_DEBUG
|
#ifdef GIST_DEBUG
|
||||||
elog(NOTICE,"COMP IN: NULL");
|
elog(NOTICE,"COMP IN: NULL");
|
||||||
#endif
|
#endif
|
||||||
gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset,
|
if ( r ) if ( (char*)r != (char*)entry->pred ) pfree(r);
|
||||||
0, FALSE);
|
|
||||||
|
gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset,
|
||||||
|
0, FALSE);
|
||||||
return( retval );
|
return( retval );
|
||||||
}
|
}
|
||||||
|
|
||||||
r = copy_intArrayType( (ArrayType *) entry->pred );
|
|
||||||
if ( entry->leafkey ) PREPAREARR( r );
|
if ( entry->leafkey ) PREPAREARR( r );
|
||||||
len = ARRSIZE( r );
|
len = ARRNELEMS( r );
|
||||||
|
|
||||||
#ifdef GIST_DEBUG
|
#ifdef GIST_DEBUG
|
||||||
elog(NOTICE, "COMP IN: %d leaf; %d rel; %d page; %d offset; %d bytes; %d elems", entry->leafkey, (int)entry->rel, (int)entry->page, (int)entry->offset, (int)entry->bytes, len);
|
elog(NOTICE, "COMP IN: %d leaf; %d rel; %d page; %d offset; %d bytes; %d elems", entry->leafkey, (int)entry->rel, (int)entry->page, (int)entry->offset, (int)entry->bytes, len);
|
||||||
@ -297,10 +317,21 @@ g_int_decompress(GISTENTRY *entry)
|
|||||||
int *din;
|
int *din;
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
if ( entry->bytes < ARR_OVERHEAD( NDIM ) || ARRISNULL( (ArrayType *) entry->pred ) ) {
|
#ifdef PGSQL71
|
||||||
|
if ( entry->pred )
|
||||||
|
in = (ArrayType *)PG_DETOAST_DATUM( entry->pred );
|
||||||
|
else
|
||||||
|
in = NULL;
|
||||||
|
#else
|
||||||
|
in = (ArrayType *) entry->pred;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( entry->bytes < ARR_OVERHEAD( NDIM ) || ARRISNULL( in ) ) {
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
if ( ! retval )
|
|
||||||
elog(ERROR,"Can't allocate memory for decompression");
|
#ifdef PGSQL71
|
||||||
|
if ( in ) if ( (char*)in != (char*)entry->pred ) pfree(in);
|
||||||
|
#endif
|
||||||
gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset, 0, FALSE);
|
gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset, 0, FALSE);
|
||||||
#ifdef GIST_DEBUG
|
#ifdef GIST_DEBUG
|
||||||
elog(NOTICE,"DECOMP IN: NULL");
|
elog(NOTICE,"DECOMP IN: NULL");
|
||||||
@ -309,8 +340,7 @@ g_int_decompress(GISTENTRY *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
in = (ArrayType *) entry->pred;
|
lenin = ARRNELEMS(in);
|
||||||
lenin = ARRSIZE(in);
|
|
||||||
din = ARRPTR(in);
|
din = ARRPTR(in);
|
||||||
|
|
||||||
if ( lenin < 2*MAXNUMRANGE ) { /*not comressed value*/
|
if ( lenin < 2*MAXNUMRANGE ) { /*not comressed value*/
|
||||||
@ -333,9 +363,11 @@ g_int_decompress(GISTENTRY *entry)
|
|||||||
if ( (!i) || *(dr-1) != j )
|
if ( (!i) || *(dr-1) != j )
|
||||||
*dr++ = j;
|
*dr++ = j;
|
||||||
|
|
||||||
|
#ifdef PGSQL71
|
||||||
|
if ( (char*)in != (char*)entry->pred ) pfree(in);
|
||||||
|
#endif
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
if ( ! retval )
|
|
||||||
elog(ERROR,"Can't allocate memory for decompression");
|
|
||||||
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
|
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
|
||||||
|
|
||||||
return(retval);
|
return(retval);
|
||||||
@ -355,11 +387,11 @@ GIST_SPLITVEC *
|
|||||||
g_int_picksplit(bytea *entryvec,
|
g_int_picksplit(bytea *entryvec,
|
||||||
GIST_SPLITVEC *v)
|
GIST_SPLITVEC *v)
|
||||||
{
|
{
|
||||||
|
|
||||||
return _int_common_picksplit( entryvec, v,
|
return _int_common_picksplit( entryvec, v,
|
||||||
inner_int_union,
|
inner_int_union,
|
||||||
inner_int_inter,
|
inner_int_inter,
|
||||||
rt__int_size);
|
rt__int_size,
|
||||||
|
1e-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -387,6 +419,7 @@ bool
|
|||||||
_int_contains ( ArrayType *a, ArrayType *b ) {
|
_int_contains ( ArrayType *a, ArrayType *b ) {
|
||||||
bool res;
|
bool res;
|
||||||
ArrayType *an, *bn;
|
ArrayType *an, *bn;
|
||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
||||||
|
|
||||||
an = copy_intArrayType( a );
|
an = copy_intArrayType( a );
|
||||||
@ -408,8 +441,8 @@ inner_int_contains ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
||||||
|
|
||||||
na = ARRSIZE( a );
|
na = ARRNELEMS( a );
|
||||||
nb = ARRSIZE( b );
|
nb = ARRNELEMS( b );
|
||||||
da = ARRPTR( a );
|
da = ARRPTR( a );
|
||||||
db = ARRPTR( b );
|
db = ARRPTR( b );
|
||||||
|
|
||||||
@ -444,39 +477,62 @@ _int_same ( ArrayType *a, ArrayType *b ) {
|
|||||||
int na , nb ;
|
int na , nb ;
|
||||||
int n;
|
int n;
|
||||||
int *da, *db;
|
int *da, *db;
|
||||||
|
bool result;
|
||||||
|
ArrayType *an, *bn;
|
||||||
bool anull = ARRISNULL( a );
|
bool anull = ARRISNULL( a );
|
||||||
bool bnull = ARRISNULL( b );
|
bool bnull = ARRISNULL( b );
|
||||||
|
|
||||||
if ( anull || bnull )
|
if ( anull || bnull )
|
||||||
return ( anull && bnull ) ? TRUE : FALSE;
|
return ( anull && bnull ) ? TRUE : FALSE;
|
||||||
|
|
||||||
SORT( a );
|
an = copy_intArrayType( a );
|
||||||
SORT( b );
|
bn = copy_intArrayType( b );
|
||||||
na = ARRSIZE( a );
|
|
||||||
nb = ARRSIZE( b );
|
|
||||||
da = ARRPTR( a );
|
|
||||||
db = ARRPTR( b );
|
|
||||||
|
|
||||||
if ( na != nb ) return FALSE;
|
SORT( an );
|
||||||
|
SORT( bn );
|
||||||
|
na = ARRNELEMS( an );
|
||||||
|
nb = ARRNELEMS( bn );
|
||||||
|
da = ARRPTR( an );
|
||||||
|
db = ARRPTR( bn );
|
||||||
|
|
||||||
n = 0;
|
result = FALSE;
|
||||||
|
|
||||||
|
if ( na == nb )
|
||||||
|
{
|
||||||
|
result = TRUE;
|
||||||
for(n=0; n<na; n++)
|
for(n=0; n<na; n++)
|
||||||
if ( da[n] != db[n] )
|
if ( da[n] != db[n] )
|
||||||
return FALSE;
|
{
|
||||||
|
result = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
pfree( an ); pfree( bn );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _int_overlap -- does a overlap b?
|
/* _int_overlap -- does a overlap b?
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
_int_overlap ( ArrayType *a, ArrayType *b ) {
|
_int_overlap ( ArrayType *a, ArrayType *b ) {
|
||||||
|
bool result;
|
||||||
|
ArrayType *an, *bn;
|
||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
||||||
|
|
||||||
SORT(a);
|
an = copy_intArrayType( a );
|
||||||
SORT(b);
|
bn = copy_intArrayType( b );
|
||||||
|
|
||||||
return inner_int_overlap( a, b );
|
SORT(an);
|
||||||
|
SORT(bn);
|
||||||
|
|
||||||
|
result = inner_int_overlap( an, bn );
|
||||||
|
|
||||||
|
pfree( an ); pfree( bn );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -487,8 +543,8 @@ inner_int_overlap ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
||||||
|
|
||||||
na = ARRSIZE( a );
|
na = ARRNELEMS( a );
|
||||||
nb = ARRSIZE( b );
|
nb = ARRNELEMS( b );
|
||||||
da = ARRPTR( a );
|
da = ARRPTR( a );
|
||||||
db = ARRPTR( b );
|
db = ARRPTR( b );
|
||||||
|
|
||||||
@ -510,10 +566,21 @@ inner_int_overlap ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
ArrayType *
|
ArrayType *
|
||||||
_int_union ( ArrayType *a, ArrayType *b ) {
|
_int_union ( ArrayType *a, ArrayType *b ) {
|
||||||
if ( ! ARRISNULL( a ) ) SORT(a);
|
ArrayType *result;
|
||||||
if ( ! ARRISNULL( b ) ) SORT(b);
|
ArrayType *an, *bn;
|
||||||
|
|
||||||
return inner_int_union( a, b );
|
an = copy_intArrayType( a );
|
||||||
|
bn = copy_intArrayType( b );
|
||||||
|
|
||||||
|
if ( ! ARRISNULL( an ) ) SORT(an);
|
||||||
|
if ( ! ARRISNULL( bn ) ) SORT(bn);
|
||||||
|
|
||||||
|
result = inner_int_union( an, bn );
|
||||||
|
|
||||||
|
if (an) pfree( an );
|
||||||
|
if (bn) pfree( bn );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayType *
|
ArrayType *
|
||||||
@ -534,8 +601,8 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
|
|||||||
if ( r ) {
|
if ( r ) {
|
||||||
dr = ARRPTR( r );
|
dr = ARRPTR( r );
|
||||||
} else {
|
} else {
|
||||||
na = ARRSIZE( a );
|
na = ARRNELEMS( a );
|
||||||
nb = ARRSIZE( b );
|
nb = ARRNELEMS( b );
|
||||||
da = ARRPTR( a );
|
da = ARRPTR( a );
|
||||||
db = ARRPTR( b );
|
db = ARRPTR( b );
|
||||||
|
|
||||||
@ -555,7 +622,7 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ARRSIZE(r) > 1 )
|
if ( ARRNELEMS(r) > 1 )
|
||||||
r = _int_unique( r );
|
r = _int_unique( r );
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@ -564,12 +631,22 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
ArrayType *
|
ArrayType *
|
||||||
_int_inter ( ArrayType *a, ArrayType *b ) {
|
_int_inter ( ArrayType *a, ArrayType *b ) {
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
|
ArrayType *result;
|
||||||
|
ArrayType *an, *bn;
|
||||||
|
|
||||||
SORT(a);
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
|
||||||
SORT(b);
|
|
||||||
|
|
||||||
return inner_int_inter( a, b );
|
an = copy_intArrayType( a );
|
||||||
|
bn = copy_intArrayType( b );
|
||||||
|
|
||||||
|
SORT(an);
|
||||||
|
SORT(bn);
|
||||||
|
|
||||||
|
result = inner_int_inter( an, bn );
|
||||||
|
|
||||||
|
pfree( an ); pfree( bn );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayType *
|
ArrayType *
|
||||||
@ -583,10 +660,10 @@ inner_int_inter ( ArrayType *a, ArrayType *b ) {
|
|||||||
elog(NOTICE, "inner_inter %d %d", ARRISNULL( a ), ARRISNULL( b ) );
|
elog(NOTICE, "inner_inter %d %d", ARRISNULL( a ), ARRISNULL( b ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return NULL;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
|
||||||
|
|
||||||
na = ARRSIZE( a );
|
na = ARRNELEMS( a );
|
||||||
nb = ARRSIZE( b );
|
nb = ARRNELEMS( b );
|
||||||
da = ARRPTR( a );
|
da = ARRPTR( a );
|
||||||
db = ARRPTR( b );
|
db = ARRPTR( b );
|
||||||
r = new_intArrayType( min(na, nb) );
|
r = new_intArrayType( min(na, nb) );
|
||||||
@ -605,7 +682,7 @@ inner_int_inter ( ArrayType *a, ArrayType *b ) {
|
|||||||
|
|
||||||
if ( (dr - ARRPTR(r)) == 0 ) {
|
if ( (dr - ARRPTR(r)) == 0 ) {
|
||||||
pfree( r );
|
pfree( r );
|
||||||
return NULL;
|
return new_intArrayType(0);
|
||||||
} else
|
} else
|
||||||
return resize_intArrayType(r, dr - ARRPTR(r) );
|
return resize_intArrayType(r, dr - ARRPTR(r) );
|
||||||
}
|
}
|
||||||
@ -616,7 +693,7 @@ rt__int_size(ArrayType *a, float *size)
|
|||||||
if ( ARRISNULL( a ) )
|
if ( ARRISNULL( a ) )
|
||||||
*size = 0.0;
|
*size = 0.0;
|
||||||
else
|
else
|
||||||
*size = (float)ARRSIZE( a );
|
*size = (float)ARRNELEMS( a );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -654,8 +731,7 @@ new_intArrayType( int num ) {
|
|||||||
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
|
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
|
||||||
|
|
||||||
r = (ArrayType *) palloc( nbytes );
|
r = (ArrayType *) palloc( nbytes );
|
||||||
if ( ! r )
|
|
||||||
elog(ERROR, "Can't allocate memory for new array");
|
|
||||||
MemSet(r, 0, nbytes);
|
MemSet(r, 0, nbytes);
|
||||||
r->size = nbytes;
|
r->size = nbytes;
|
||||||
r->ndim = NDIM;
|
r->ndim = NDIM;
|
||||||
@ -672,11 +748,9 @@ static ArrayType *
|
|||||||
resize_intArrayType( ArrayType * a, int num ) {
|
resize_intArrayType( ArrayType * a, int num ) {
|
||||||
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
|
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
|
||||||
|
|
||||||
if ( num == ARRSIZE(a) ) return a;
|
if ( num == ARRNELEMS(a) ) return a;
|
||||||
|
|
||||||
a = (ArrayType *) repalloc( a, nbytes );
|
a = (ArrayType *) repalloc( a, nbytes );
|
||||||
if ( ! a )
|
|
||||||
elog(ERROR, "Can't reallocate memory for new array");
|
|
||||||
|
|
||||||
a->size = nbytes;
|
a->size = nbytes;
|
||||||
*( (int*)ARR_DIMS(a) ) = num;
|
*( (int*)ARR_DIMS(a) ) = num;
|
||||||
@ -686,8 +760,8 @@ resize_intArrayType( ArrayType * a, int num ) {
|
|||||||
static ArrayType *
|
static ArrayType *
|
||||||
copy_intArrayType( ArrayType * a ) {
|
copy_intArrayType( ArrayType * a ) {
|
||||||
ArrayType * r;
|
ArrayType * r;
|
||||||
if ( ! a ) return NULL;
|
if ( ARRISNULL(a) ) return NULL;
|
||||||
r = new_intArrayType( ARRSIZE(a) );
|
r = new_intArrayType( ARRNELEMS(a) );
|
||||||
memmove(r,a,VARSIZE(a));
|
memmove(r,a,VARSIZE(a));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -708,7 +782,7 @@ internal_size (int *a, int len ) {
|
|||||||
static ArrayType *
|
static ArrayType *
|
||||||
_int_unique( ArrayType * r ) {
|
_int_unique( ArrayType * r ) {
|
||||||
int *tmp, *dr, *data;
|
int *tmp, *dr, *data;
|
||||||
int num = ARRSIZE(r);
|
int num = ARRNELEMS(r);
|
||||||
data = tmp = dr = ARRPTR( r );
|
data = tmp = dr = ARRPTR( r );
|
||||||
while( tmp - data < num )
|
while( tmp - data < num )
|
||||||
if ( *tmp != *dr )
|
if ( *tmp != *dr )
|
||||||
@ -721,15 +795,14 @@ _int_unique( ArrayType * r ) {
|
|||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
** intbig functions
|
** intbig functions
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gensign(BITVEC sign, int * a, int len) {
|
gensign(BITVEC sign, int * a, int len) {
|
||||||
int i;
|
int i;
|
||||||
NULLIFY(sign);
|
/* we assume that the sign vector is previously zeroed */
|
||||||
for(i=0; i<len; i++) {
|
for(i=0; i<len; i++) {
|
||||||
SETBIT( sign, (*a)%SIGLENBIT );
|
SETBIT( sign, (*a)%SIGLENBIT );
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -777,20 +850,13 @@ rt__intbig_size(ArrayType *a, float* sz) {
|
|||||||
|
|
||||||
static ArrayType *
|
static ArrayType *
|
||||||
_intbig_union(ArrayType *a, ArrayType *b) {
|
_intbig_union(ArrayType *a, ArrayType *b) {
|
||||||
ArrayType * r = NULL;
|
ArrayType * r;
|
||||||
BITVECP da, db, dr;
|
BITVECP da, db, dr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( ARRISNULL( a ) && ARRISNULL( b ) ) return new_intArrayType(0);
|
if ( ARRISNULL( a ) && ARRISNULL( b ) ) return new_intArrayType(0);
|
||||||
|
if ( ARRISNULL( a ) ) return copy_intArrayType( b );
|
||||||
if ( ARRISNULL( a ) ) {
|
if ( ARRISNULL( b ) ) return copy_intArrayType( a );
|
||||||
r = copy_intArrayType( b );
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
if ( ARRISNULL( b ) ) {
|
|
||||||
r = copy_intArrayType( a );
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = new_intArrayType( SIGLENINT );
|
r = new_intArrayType( SIGLENINT );
|
||||||
|
|
||||||
@ -802,14 +868,14 @@ _intbig_union(ArrayType *a, ArrayType *b) {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
static ArrayType *
|
static ArrayType *
|
||||||
_intbig_inter(ArrayType *a, ArrayType *b) {
|
_intbig_inter(ArrayType *a, ArrayType *b) {
|
||||||
ArrayType * r = NULL;
|
ArrayType * r;
|
||||||
BITVECP da, db, dr;
|
BITVECP da, db, dr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return NULL;
|
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
|
||||||
|
|
||||||
r = new_intArrayType( SIGLENINT );
|
r = new_intArrayType( SIGLENINT );
|
||||||
|
|
||||||
@ -821,7 +887,7 @@ _intbig_inter(ArrayType *a, ArrayType *b) {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
bool *
|
bool *
|
||||||
g_intbig_same(ArrayType *a, ArrayType *b, bool *result) {
|
g_intbig_same(ArrayType *a, ArrayType *b, bool *result) {
|
||||||
BITVECP da, db;
|
BITVECP da, db;
|
||||||
@ -862,8 +928,6 @@ g_intbig_compress(GISTENTRY *entry) {
|
|||||||
if ( ! entry->leafkey ) return entry;
|
if ( ! entry->leafkey ) return entry;
|
||||||
|
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
if ( ! retval )
|
|
||||||
elog(ERROR,"Can't allocate memory for compression");
|
|
||||||
|
|
||||||
if ( ARRISNULL( in ) ) {
|
if ( ARRISNULL( in ) ) {
|
||||||
#ifdef PGSQL71
|
#ifdef PGSQL71
|
||||||
@ -876,7 +940,7 @@ g_intbig_compress(GISTENTRY *entry) {
|
|||||||
r = new_intArrayType( SIGLENINT );
|
r = new_intArrayType( SIGLENINT );
|
||||||
gensign( SIGPTR( r ),
|
gensign( SIGPTR( r ),
|
||||||
ARRPTR ( in ),
|
ARRPTR ( in ),
|
||||||
ARRSIZE( in ) );
|
ARRNELEMS( in ) );
|
||||||
|
|
||||||
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
|
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
|
||||||
|
|
||||||
@ -889,72 +953,28 @@ g_intbig_compress(GISTENTRY *entry) {
|
|||||||
|
|
||||||
GISTENTRY *
|
GISTENTRY *
|
||||||
g_intbig_decompress(GISTENTRY *entry) {
|
g_intbig_decompress(GISTENTRY *entry) {
|
||||||
|
#ifdef PGSQL71
|
||||||
|
ArrayType *key;
|
||||||
|
key = (ArrayType *)PG_DETOAST_DATUM( entry->pred );
|
||||||
|
if ( (char*)key != (char*)entry->pred ) {
|
||||||
|
GISTENTRY *retval;
|
||||||
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
|
|
||||||
|
gistentryinit(*retval, (char *)key, entry->rel, entry->page, entry->offset, VARSIZE( key ), FALSE);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
GIST_SPLITVEC *
|
GIST_SPLITVEC *
|
||||||
g_intbig_picksplit(bytea *entryvec, GIST_SPLITVEC *v) {
|
g_intbig_picksplit(bytea *entryvec, GIST_SPLITVEC *v) {
|
||||||
|
return _int_common_picksplit( entryvec, v,
|
||||||
|
_intbig_union,
|
||||||
|
_intbig_inter,
|
||||||
|
rt__intbig_size,
|
||||||
|
1.0);
|
||||||
|
|
||||||
OffsetNumber k;
|
|
||||||
ArrayType *datum_l, *datum_r, *datum_alpha;
|
|
||||||
ArrayType *unionarr;
|
|
||||||
float size_l, size_r;
|
|
||||||
int nbytes;
|
|
||||||
OffsetNumber *left, *right;
|
|
||||||
OffsetNumber maxoff;
|
|
||||||
|
|
||||||
#ifdef GIST_DEBUG
|
|
||||||
elog(NOTICE, "--------picksplit %d",(VARSIZE(entryvec) - VARHDRSZ)/sizeof(GISTENTRY));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
maxoff = ((VARSIZE(entryvec) - VARHDRSZ)/sizeof(GISTENTRY)) - 2;
|
|
||||||
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
|
|
||||||
v->spl_left = (OffsetNumber *) palloc(nbytes);
|
|
||||||
v->spl_right = (OffsetNumber *) palloc(nbytes);
|
|
||||||
left = v->spl_left;
|
|
||||||
v->spl_nleft = 0;
|
|
||||||
right = v->spl_right;
|
|
||||||
v->spl_nright = 0;
|
|
||||||
|
|
||||||
maxoff = OffsetNumberNext(maxoff);
|
|
||||||
datum_l = datum_r = NULL;
|
|
||||||
|
|
||||||
for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k)) {
|
|
||||||
datum_alpha = (ArrayType *)(((GISTENTRY *)(VARDATA(entryvec)))[k].pred);
|
|
||||||
|
|
||||||
if ( k != FirstOffsetNumber ) {
|
|
||||||
unionarr = (ArrayType *)_intbig_union(datum_l, datum_alpha);
|
|
||||||
if ( datum_l ) pfree(datum_l);
|
|
||||||
datum_l = unionarr;
|
|
||||||
rt__intbig_size((ArrayType *)unionarr, &size_l);
|
|
||||||
*left++ = k;
|
|
||||||
v->spl_nleft++;
|
|
||||||
} else {
|
|
||||||
unionarr = (ArrayType *)_intbig_union(datum_r, datum_alpha);
|
|
||||||
if ( datum_r ) pfree(datum_r);
|
|
||||||
datum_r = unionarr;
|
|
||||||
rt__intbig_size((ArrayType *)unionarr, &size_r);
|
|
||||||
*right++ = k;
|
|
||||||
v->spl_nright++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( *(left-1) > *(right-1) ) {
|
|
||||||
*right = FirstOffsetNumber;
|
|
||||||
*(left-1) = InvalidOffsetNumber;
|
|
||||||
} else {
|
|
||||||
*left = FirstOffsetNumber;
|
|
||||||
*(right-1) = InvalidOffsetNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
v->spl_ldatum = (char *)datum_l;
|
|
||||||
v->spl_rdatum = (char *)datum_r;
|
|
||||||
|
|
||||||
#ifdef GIST_DEBUG
|
|
||||||
elog(NOTICE, "--------ENDpicksplit %d %d",v->spl_nleft, v->spl_nright);
|
|
||||||
#endif
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayType *
|
ArrayType *
|
||||||
@ -965,7 +985,6 @@ g_intbig_union(bytea *entryvec, int *sizep) {
|
|||||||
float *
|
float *
|
||||||
g_intbig_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result){
|
g_intbig_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result){
|
||||||
_int_common_penalty( origentry, newentry, result, _intbig_union, rt__intbig_size);
|
_int_common_penalty( origentry, newentry, result, _intbig_union, rt__intbig_size);
|
||||||
*result= SIGLENBIT - *result;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,13 +993,13 @@ g_intbig_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy)
|
|||||||
bool retval;
|
bool retval;
|
||||||
ArrayType * q;
|
ArrayType * q;
|
||||||
|
|
||||||
|
/* XXX what about toasted input? */
|
||||||
if ( ARRISNULL( query ) ) return FALSE;
|
if ( ARRISNULL( query ) ) return FALSE;
|
||||||
|
|
||||||
q = new_intArrayType( SIGLENINT );
|
q = new_intArrayType( SIGLENINT );
|
||||||
|
|
||||||
gensign( SIGPTR( q ),
|
gensign( SIGPTR( q ),
|
||||||
ARRPTR( query ),
|
ARRPTR( query ),
|
||||||
ARRSIZE( query ) );
|
ARRNELEMS( query ) );
|
||||||
|
|
||||||
switch(strategy) {
|
switch(strategy) {
|
||||||
case RTOverlapStrategyNumber:
|
case RTOverlapStrategyNumber:
|
||||||
@ -1042,9 +1061,10 @@ _int_common_union(bytea *entryvec, int *sizep, formarray unionf) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*****************************************
|
||||||
** The GiST Penalty method for _intments
|
* The GiST Penalty method for _intments *
|
||||||
*/
|
*****************************************/
|
||||||
|
|
||||||
float *
|
float *
|
||||||
_int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
|
_int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
|
||||||
formarray unionf,
|
formarray unionf,
|
||||||
@ -1063,7 +1083,7 @@ _int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
|
|||||||
pfree((char *)ud);
|
pfree((char *)ud);
|
||||||
|
|
||||||
#ifdef GIST_DEBUG
|
#ifdef GIST_DEBUG
|
||||||
elog(NOTICE, "--penalty\t%g\t%g\t%g", *result, tmp1, tmp2);
|
elog(NOTICE, "--penalty\t%g", *result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
@ -1078,7 +1098,8 @@ _int_common_picksplit(bytea *entryvec,
|
|||||||
GIST_SPLITVEC *v,
|
GIST_SPLITVEC *v,
|
||||||
formarray unionf,
|
formarray unionf,
|
||||||
formarray interf,
|
formarray interf,
|
||||||
formfloat sizef)
|
formfloat sizef,
|
||||||
|
float coef)
|
||||||
{
|
{
|
||||||
OffsetNumber i, j;
|
OffsetNumber i, j;
|
||||||
ArrayType *datum_alpha, *datum_beta;
|
ArrayType *datum_alpha, *datum_beta;
|
||||||
@ -1163,7 +1184,6 @@ _int_common_picksplit(bytea *entryvec,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
maxoff = OffsetNumberNext(maxoff);
|
maxoff = OffsetNumberNext(maxoff);
|
||||||
|
|
||||||
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
|
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
|
||||||
|
|
||||||
|
|
||||||
@ -1192,7 +1212,7 @@ _int_common_picksplit(bytea *entryvec,
|
|||||||
(*sizef)((ArrayType *)union_dr, &size_beta);
|
(*sizef)((ArrayType *)union_dr, &size_beta);
|
||||||
|
|
||||||
/* pick which page to add it to */
|
/* pick which page to add it to */
|
||||||
if (size_alpha - size_l < size_beta - size_r) {
|
if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, coef)) {
|
||||||
if ( datum_l ) pfree(datum_l);
|
if ( datum_l ) pfree(datum_l);
|
||||||
if ( union_dr ) pfree(union_dr);
|
if ( union_dr ) pfree(union_dr);
|
||||||
datum_l = union_dl;
|
datum_l = union_dl;
|
||||||
@ -1208,7 +1228,6 @@ _int_common_picksplit(bytea *entryvec,
|
|||||||
v->spl_nright++;
|
v->spl_nright++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**left = *right = FirstOffsetNumber;*/ /* sentinel value, see dosplit() */
|
|
||||||
|
|
||||||
if ( *(left-1) > *(right-1) ) {
|
if ( *(left-1) > *(right-1) ) {
|
||||||
*right = FirstOffsetNumber;
|
*right = FirstOffsetNumber;
|
||||||
@ -1218,7 +1237,6 @@ _int_common_picksplit(bytea *entryvec,
|
|||||||
*(right-1) = InvalidOffsetNumber;
|
*(right-1) = InvalidOffsetNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
v->spl_ldatum = (char *)datum_l;
|
v->spl_ldatum = (char *)datum_l;
|
||||||
v->spl_rdatum = (char *)datum_r;
|
v->spl_rdatum = (char *)datum_r;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ CREATE TABLE test__int( a int[] );
|
|||||||
SELECT count(*) from test__int WHERE a && '{23,50}';
|
SELECT count(*) from test__int WHERE a && '{23,50}';
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
345
|
403
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
||||||
@ -21,7 +21,7 @@ CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ) with ( islossy
|
|||||||
SELECT count(*) from test__int WHERE a && '{23,50}';
|
SELECT count(*) from test__int WHERE a && '{23,50}';
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
345
|
403
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
||||||
@ -35,7 +35,7 @@ CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ) with ( islo
|
|||||||
SELECT count(*) from test__int WHERE a && '{23,50}';
|
SELECT count(*) from test__int WHERE a && '{23,50}';
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
345
|
403
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
SELECT count(*) from test__int WHERE a @ '{23,50}';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user