Updates to make GIST work with multi-key indexes (from Oleg Bartunov

and Teodor Sigaev).  Declare key values as Datum where appropriate,
rather than char* (Tom Lane).
This commit is contained in:
Tom Lane 2001-05-31 18:16:55 +00:00
parent e1107fc285
commit 3043810d97
9 changed files with 842 additions and 438 deletions

View File

@ -45,7 +45,7 @@ NDBOX *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep);
bool *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result); bool *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result);
/* /*
** R-tree suport functions ** R-tree support functions
*/ */
bool cube_same(NDBOX * a, NDBOX * b); bool cube_same(NDBOX * a, NDBOX * b);
bool cube_different(NDBOX * a, NDBOX * b); bool cube_different(NDBOX * a, NDBOX * b);
@ -168,13 +168,15 @@ g_cube_consistent(GISTENTRY *entry,
{ {
/* /*
* * if entry is not leaf, use g_cube_internal_consistent, * else use * if entry is not leaf, use g_cube_internal_consistent, else use
* g_cube_leaf_consistent * g_cube_leaf_consistent
*/ */
if (GIST_LEAF(entry)) if (GIST_LEAF(entry))
return (g_cube_leaf_consistent((NDBOX *) (entry->pred), query, strategy)); return g_cube_leaf_consistent((NDBOX *) DatumGetPointer(entry->key),
query, strategy);
else else
return (g_cube_internal_consistent((NDBOX *) (entry->pred), query, strategy)); return g_cube_internal_consistent((NDBOX *) DatumGetPointer(entry->key),
query, strategy);
} }
@ -194,7 +196,7 @@ g_cube_union(bytea *entryvec, int *sizep)
* fprintf(stderr, "union\n"); * fprintf(stderr, "union\n");
*/ */
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
tmp = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred; tmp = (NDBOX *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[0]).key);
/* /*
* sizep = sizeof(NDBOX); -- NDBOX has variable size * sizep = sizeof(NDBOX); -- NDBOX has variable size
@ -204,14 +206,8 @@ g_cube_union(bytea *entryvec, int *sizep)
for (i = 1; i < numranges; i++) for (i = 1; i < numranges; i++)
{ {
out = g_cube_binary_union(tmp, (NDBOX *) out = g_cube_binary_union(tmp, (NDBOX *)
(((GISTENTRY *) (VARDATA(entryvec)))[i]).pred, DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i]).key),
sizep); sizep);
/*
* fprintf(stderr, "\t%s ^ %s -> %s\n", cube_out(tmp),
* cube_out((NDBOX *)(((GISTENTRY
* *)(VARDATA(entryvec)))[i]).pred), cube_out(out));
*/
if (i > 1) if (i > 1)
pfree(tmp); pfree(tmp);
tmp = out; tmp = out;
@ -243,15 +239,16 @@ g_cube_decompress(GISTENTRY *entry)
float * float *
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{ {
Datum ud; NDBOX *ud;
float tmp1, float tmp1,
tmp2; tmp2;
ud = (Datum) cube_union((NDBOX *) (origentry->pred), (NDBOX *) (newentry->pred)); ud = cube_union((NDBOX *) DatumGetPointer(origentry->key),
rt_cube_size((NDBOX *) ud, &tmp1); (NDBOX *) DatumGetPointer(newentry->key));
rt_cube_size((NDBOX *) (origentry->pred), &tmp2); rt_cube_size(ud, &tmp1);
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
*result = tmp1 - tmp2; *result = tmp1 - tmp2;
pfree((char *) ud); pfree(ud);
/* /*
* fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result); * fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result);
@ -308,16 +305,16 @@ g_cube_picksplit(bytea *entryvec,
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
{ {
datum_alpha = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[i].key);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
{ {
datum_beta = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred); datum_beta = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[j].key);
/* compute the wasted space by unioning these guys */ /* compute the wasted space by unioning these guys */
/* size_waste = size_union - size_inter; */ /* size_waste = size_union - size_inter; */
union_d = (NDBOX *) cube_union(datum_alpha, datum_beta); union_d = cube_union(datum_alpha, datum_beta);
rt_cube_size(union_d, &size_union); rt_cube_size(union_d, &size_union);
inter_d = (NDBOX *) cube_inter(datum_alpha, datum_beta); inter_d = cube_inter(datum_alpha, datum_beta);
rt_cube_size(inter_d, &size_inter); rt_cube_size(inter_d, &size_inter);
size_waste = size_union - size_inter; size_waste = size_union - size_inter;
@ -346,12 +343,12 @@ g_cube_picksplit(bytea *entryvec,
right = v->spl_right; right = v->spl_right;
v->spl_nright = 0; v->spl_nright = 0;
datum_alpha = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred); datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[seed_1].key);
datum_l = (NDBOX *) cube_union(datum_alpha, datum_alpha); datum_l = cube_union(datum_alpha, datum_alpha);
rt_cube_size((NDBOX *) datum_l, &size_l); rt_cube_size(datum_l, &size_l);
datum_beta = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred);; datum_beta = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[seed_2].key);
datum_r = (NDBOX *) cube_union(datum_beta, datum_beta); datum_r = cube_union(datum_beta, datum_beta);
rt_cube_size((NDBOX *) datum_r, &size_r); rt_cube_size(datum_r, &size_r);
/* /*
* Now split up the regions between the two seeds. An important * Now split up the regions between the two seeds. An important
@ -389,11 +386,11 @@ g_cube_picksplit(bytea *entryvec,
} }
/* okay, which page needs least enlargement? */ /* okay, which page needs least enlargement? */
datum_alpha = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[i].key);
union_dl = (NDBOX *) cube_union(datum_l, datum_alpha); union_dl = cube_union(datum_l, datum_alpha);
union_dr = (NDBOX *) cube_union(datum_r, datum_alpha); union_dr = cube_union(datum_r, datum_alpha);
rt_cube_size((NDBOX *) union_dl, &size_alpha); rt_cube_size(union_dl, &size_alpha);
rt_cube_size((NDBOX *) union_dr, &size_beta); rt_cube_size(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)
@ -417,8 +414,8 @@ g_cube_picksplit(bytea *entryvec,
} }
*left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */ *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
v->spl_ldatum = (char *) datum_l; v->spl_ldatum = PointerGetDatum(datum_l);
v->spl_rdatum = (char *) datum_r; v->spl_rdatum = PointerGetDatum(datum_r);
return v; return v;
} }

View File

@ -34,11 +34,7 @@
/* useful macros for accessing int4 arrays */ /* useful macros for accessing int4 arrays */
#define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) ) #define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
#ifdef PGSQL71
#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x)) #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 ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : 1 ) : 1 )
@ -228,14 +224,17 @@ g_int_consistent(GISTENTRY *entry,
switch (strategy) switch (strategy)
{ {
case RTOverlapStrategyNumber: case RTOverlapStrategyNumber:
retval = (bool) inner_int_overlap((ArrayType *) (entry->pred), query); retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
query);
break; break;
case RTSameStrategyNumber: case RTSameStrategyNumber:
case RTContainsStrategyNumber: case RTContainsStrategyNumber:
retval = (bool) inner_int_contains((ArrayType *) (entry->pred), query); retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
query);
break; break;
case RTContainedByStrategyNumber: case RTContainedByStrategyNumber:
retval = (bool) inner_int_overlap((ArrayType *) (entry->pred), query); retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
query);
break; break;
default: default:
retval = FALSE; retval = FALSE;
@ -265,14 +264,10 @@ g_int_compress(GISTENTRY *entry)
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
#ifdef PGSQL71 if (DatumGetPointer(entry->key) != NULL)
if (entry->pred) r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->pred);
else else
r = NULL; r = NULL;
#else
r = copy_intArrayType((ArrayType *) entry->pred);
#endif
if (ARRISNULL(r)) if (ARRISNULL(r))
{ {
@ -280,10 +275,10 @@ g_int_compress(GISTENTRY *entry)
elog(NOTICE, "COMP IN: NULL"); elog(NOTICE, "COMP IN: NULL");
#endif #endif
if (r) if (r)
if ((char *) r != (char *) entry->pred) if (r != (ArrayType *) DatumGetPointer(entry->key))
pfree(r); pfree(r);
gistentryinit(*retval, (char *) NULL, entry->rel, entry->page, entry->offset, gistentryinit(*retval, (Datum) 0, entry->rel, entry->page, entry->offset,
0, FALSE); 0, FALSE);
return (retval); return (retval);
} }
@ -322,7 +317,8 @@ g_int_compress(GISTENTRY *entry)
r = resize_intArrayType(r, len); r = resize_intArrayType(r, len);
} }
gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
return (retval); return (retval);
} }
@ -340,25 +336,19 @@ g_int_decompress(GISTENTRY *entry)
int i, int i,
j; j;
#ifdef PGSQL71 if (DatumGetPointer(entry->key) != NULL)
if (entry->pred) in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
in = (ArrayType *) PG_DETOAST_DATUM(entry->pred);
else else
in = NULL; in = NULL;
#else
in = (ArrayType *) entry->pred;
#endif
if (entry->bytes < ARR_OVERHEAD(NDIM) || ARRISNULL(in)) if (entry->bytes < ARR_OVERHEAD(NDIM) || ARRISNULL(in))
{ {
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
#ifdef PGSQL71
if (in) if (in)
if ((char *) in != (char *) entry->pred) if (in != (ArrayType *) DatumGetPointer(entry->key))
pfree(in); pfree(in);
#endif gistentryinit(*retval, (Datum) 0, 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");
#endif #endif
@ -372,7 +362,7 @@ g_int_decompress(GISTENTRY *entry)
if (lenin < 2 * MAXNUMRANGE) if (lenin < 2 * MAXNUMRANGE)
{ /* not comressed value */ { /* not comressed value */
/* sometimes strange bytesize */ /* sometimes strange bytesize */
gistentryinit(*entry, (char *) in, entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE); gistentryinit(*entry, PointerGetDatum(in), entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE);
return (entry); return (entry);
} }
@ -390,13 +380,11 @@ g_int_decompress(GISTENTRY *entry)
if ((!i) || *(dr - 1) != j) if ((!i) || *(dr - 1) != j)
*dr++ = j; *dr++ = j;
#ifdef PGSQL71 if (in != (ArrayType *) DatumGetPointer(entry->key))
if ((char *) in != (char *) entry->pred)
pfree(in); pfree(in);
#endif
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
return (retval); return (retval);
} }
@ -835,9 +823,6 @@ new_intArrayType(int num)
MemSet(r, 0, nbytes); MemSet(r, 0, nbytes);
r->size = nbytes; r->size = nbytes;
r->ndim = NDIM; r->ndim = NDIM;
#ifndef PGSQL71
SET_LO_FLAG(false, r);
#endif
*((int *) ARR_DIMS(r)) = num; *((int *) ARR_DIMS(r)) = num;
*((int *) ARR_LBOUND(r)) = 1; *((int *) ARR_LBOUND(r)) = 1;
@ -1056,14 +1041,10 @@ g_intbig_compress(GISTENTRY *entry)
ArrayType *r, ArrayType *r,
*in; *in;
#ifdef PGSQL71 if (DatumGetPointer(entry->key) != NULL)
if (entry->pred) in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
in = (ArrayType *) PG_DETOAST_DATUM(entry->pred);
else else
in = NULL; in = NULL;
#else
in = (ArrayType *) entry->pred;
#endif
if (!entry->leafkey) if (!entry->leafkey)
return entry; return entry;
@ -1072,12 +1053,10 @@ g_intbig_compress(GISTENTRY *entry)
if (ARRISNULL(in)) if (ARRISNULL(in))
{ {
#ifdef PGSQL71
if (in) if (in)
if ((char *) in != (char *) entry->pred) if (in != (ArrayType *) DatumGetPointer(entry->key))
pfree(in); pfree(in);
#endif gistentryinit(*retval, (Datum) 0, entry->rel, entry->page, entry->offset, 0, FALSE);
gistentryinit(*retval, (char *) NULL, entry->rel, entry->page, entry->offset, 0, FALSE);
return (retval); return (retval);
} }
@ -1086,13 +1065,11 @@ g_intbig_compress(GISTENTRY *entry)
ARRPTR(in), ARRPTR(in),
ARRNELEMS(in)); ARRNELEMS(in));
gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
#ifdef PGSQL71
if (in) if (in)
if ((char *) in != (char *) entry->pred) if (in != (ArrayType *) DatumGetPointer(entry->key))
pfree(in); pfree(in);
#endif
return (retval); return (retval);
} }
@ -1100,20 +1077,18 @@ g_intbig_compress(GISTENTRY *entry)
GISTENTRY * GISTENTRY *
g_intbig_decompress(GISTENTRY *entry) g_intbig_decompress(GISTENTRY *entry)
{ {
#ifdef PGSQL71
ArrayType *key; ArrayType *key;
key = (ArrayType *) PG_DETOAST_DATUM(entry->pred); key = (ArrayType *) PG_DETOAST_DATUM(entry->key);
if ((char *) key != (char *) entry->pred) if (key != (ArrayType *) DatumGetPointer(entry->key))
{ {
GISTENTRY *retval; GISTENTRY *retval;
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, (char *) key, entry->rel, entry->page, entry->offset, VARSIZE(key), FALSE); gistentryinit(*retval, PointerGetDatum(key), entry->rel, entry->page, entry->offset, VARSIZE(key), FALSE);
return retval; return retval;
} }
#endif
return entry; return entry;
} }
@ -1159,14 +1134,14 @@ g_intbig_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy)
switch (strategy) switch (strategy)
{ {
case RTOverlapStrategyNumber: case RTOverlapStrategyNumber:
retval = (bool) _intbig_overlap((ArrayType *) (entry->pred), q); retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q);
break; break;
case RTSameStrategyNumber: case RTSameStrategyNumber:
case RTContainsStrategyNumber: case RTContainsStrategyNumber:
retval = (bool) _intbig_contains((ArrayType *) (entry->pred), q); retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->key), q);
break; break;
case RTContainedByStrategyNumber: case RTContainedByStrategyNumber:
retval = (bool) _intbig_overlap((ArrayType *) (entry->pred), q); retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q);
break; break;
default: default:
retval = FALSE; retval = FALSE;
@ -1196,12 +1171,12 @@ _int_common_union(bytea *entryvec, int *sizep, formarray unionf)
#endif #endif
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
tmp = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred; tmp = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[0].key);
for (i = 1; i < numranges; i++) for (i = 1; i < numranges; i++)
{ {
out = (*unionf) (tmp, (ArrayType *) out = (*unionf) (tmp, (ArrayType *)
(((GISTENTRY *) (VARDATA(entryvec)))[i]).pred); DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key));
if (i > 1 && tmp) if (i > 1 && tmp)
pfree(tmp); pfree(tmp);
tmp = out; tmp = out;
@ -1232,18 +1207,19 @@ _int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
formarray unionf, formarray unionf,
formfloat sizef) formfloat sizef)
{ {
Datum ud; ArrayType *ud;
float tmp1, float tmp1,
tmp2; tmp2;
#ifdef GIST_DEBUG #ifdef GIST_DEBUG
elog(NOTICE, "penalty"); elog(NOTICE, "penalty");
#endif #endif
ud = (Datum) (*unionf) ((ArrayType *) (origentry->pred), (ArrayType *) (newentry->pred)); ud = (*unionf) ((ArrayType *) DatumGetPointer(origentry->key),
(*sizef) ((ArrayType *) ud, &tmp1); (ArrayType *) DatumGetPointer(newentry->key));
(*sizef) ((ArrayType *) (origentry->pred), &tmp2); (*sizef) (ud, &tmp1);
(*sizef) ((ArrayType *) DatumGetPointer(origentry->key), &tmp2);
*result = tmp1 - tmp2; *result = tmp1 - tmp2;
pfree((char *) ud); pfree(ud);
#ifdef GIST_DEBUG #ifdef GIST_DEBUG
elog(NOTICE, "--penalty\t%g", *result); elog(NOTICE, "--penalty\t%g", *result);
@ -1304,10 +1280,10 @@ _int_common_picksplit(bytea *entryvec,
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
{ {
datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
{ {
datum_beta = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred); datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].key);
/* compute the wasted space by unioning these guys */ /* compute the wasted space by unioning these guys */
/* size_waste = size_union - size_inter; */ /* size_waste = size_union - size_inter; */
@ -1342,12 +1318,12 @@ _int_common_picksplit(bytea *entryvec,
right = v->spl_right; right = v->spl_right;
v->spl_nright = 0; v->spl_nright = 0;
datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred); datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].key);
datum_l = copy_intArrayType(datum_alpha); datum_l = copy_intArrayType(datum_alpha);
(*sizef) ((ArrayType *) datum_l, &size_l); (*sizef) (datum_l, &size_l);
datum_beta = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred); datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].key);
datum_r = copy_intArrayType(datum_beta); datum_r = copy_intArrayType(datum_beta);
(*sizef) ((ArrayType *) datum_r, &size_r); (*sizef) (datum_r, &size_r);
/* /*
* Now split up the regions between the two seeds. An important * Now split up the regions between the two seeds. An important
@ -1386,11 +1362,11 @@ _int_common_picksplit(bytea *entryvec,
} }
/* okay, which page needs least enlargement? */ /* okay, which page needs least enlargement? */
datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
union_dl = (ArrayType *) (*unionf) (datum_l, datum_alpha); union_dl = (*unionf) (datum_l, datum_alpha);
union_dr = (ArrayType *) (*unionf) (datum_r, datum_alpha); union_dr = (*unionf) (datum_r, datum_alpha);
(*sizef) ((ArrayType *) union_dl, &size_alpha); (*sizef) (union_dl, &size_alpha);
(*sizef) ((ArrayType *) union_dr, &size_beta); (*sizef) (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 + WISH_F(v->spl_nleft, v->spl_nright, coef)) if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, coef))
@ -1428,8 +1404,8 @@ _int_common_picksplit(bytea *entryvec,
*(right - 1) = InvalidOffsetNumber; *(right - 1) = InvalidOffsetNumber;
} }
v->spl_ldatum = (char *) datum_l; v->spl_ldatum = PointerGetDatum(datum_l);
v->spl_rdatum = (char *) datum_r; v->spl_rdatum = PointerGetDatum(datum_r);
#ifdef GIST_DEBUG #ifdef GIST_DEBUG
elog(NOTICE, "--------ENDpicksplit %d %d", v->spl_nleft, v->spl_nright); elog(NOTICE, "--------ENDpicksplit %d %d", v->spl_nleft, v->spl_nright);

View File

@ -225,9 +225,9 @@ gseg_consistent(GISTENTRY *entry,
* gseg_leaf_consistent * gseg_leaf_consistent
*/ */
if (GIST_LEAF(entry)) if (GIST_LEAF(entry))
return (gseg_leaf_consistent((SEG *) (entry->pred), query, strategy)); return (gseg_leaf_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
else else
return (gseg_internal_consistent((SEG *) (entry->pred), query, strategy)); return (gseg_internal_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
} }
/* /*
@ -247,22 +247,14 @@ gseg_union(bytea *entryvec, int *sizep)
#endif #endif
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
tmp = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred; tmp = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[0].key);
*sizep = sizeof(SEG); *sizep = sizeof(SEG);
for (i = 1; i < numranges; i++) for (i = 1; i < numranges; i++)
{ {
out = gseg_binary_union(tmp, (SEG *) out = gseg_binary_union(tmp, (SEG *)
(((GISTENTRY *) (VARDATA(entryvec)))[i]).pred, DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key),
sizep); sizep);
#ifdef GIST_DEBUG
/*
* fprintf(stderr, "\t%s ^ %s -> %s\n", seg_out(tmp), seg_out((SEG
* *)(((GISTENTRY *)(VARDATA(entryvec)))[i]).pred), seg_out(out));
*/
#endif
if (i > 1) if (i > 1)
pfree(tmp); pfree(tmp);
tmp = out; tmp = out;
@ -294,15 +286,16 @@ gseg_decompress(GISTENTRY *entry)
float * float *
gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{ {
Datum ud; SEG *ud;
float tmp1, float tmp1,
tmp2; tmp2;
ud = (Datum) seg_union((SEG *) (origentry->pred), (SEG *) (newentry->pred)); ud = seg_union((SEG *) DatumGetPointer(origentry->key),
rt_seg_size((SEG *) ud, &tmp1); (SEG *) DatumGetPointer(newentry->key));
rt_seg_size((SEG *) (origentry->pred), &tmp2); rt_seg_size(ud, &tmp1);
rt_seg_size((SEG *) DatumGetPointer(origentry->key), &tmp2);
*result = tmp1 - tmp2; *result = tmp1 - tmp2;
pfree((char *) ud); pfree(ud);
#ifdef GIST_DEBUG #ifdef GIST_DEBUG
fprintf(stderr, "penalty\n"); fprintf(stderr, "penalty\n");
@ -362,16 +355,16 @@ gseg_picksplit(bytea *entryvec,
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
{ {
datum_alpha = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
{ {
datum_beta = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred); datum_beta = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].key);
/* compute the wasted space by unioning these guys */ /* compute the wasted space by unioning these guys */
/* size_waste = size_union - size_inter; */ /* size_waste = size_union - size_inter; */
union_d = (SEG *) seg_union(datum_alpha, datum_beta); union_d = seg_union(datum_alpha, datum_beta);
rt_seg_size(union_d, &size_union); rt_seg_size(union_d, &size_union);
inter_d = (SEG *) seg_inter(datum_alpha, datum_beta); inter_d = seg_inter(datum_alpha, datum_beta);
rt_seg_size(inter_d, &size_inter); rt_seg_size(inter_d, &size_inter);
size_waste = size_union - size_inter; size_waste = size_union - size_inter;
@ -400,12 +393,12 @@ gseg_picksplit(bytea *entryvec,
right = v->spl_right; right = v->spl_right;
v->spl_nright = 0; v->spl_nright = 0;
datum_alpha = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred); datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].key);
datum_l = (SEG *) seg_union(datum_alpha, datum_alpha); datum_l = seg_union(datum_alpha, datum_alpha);
rt_seg_size((SEG *) datum_l, &size_l); rt_seg_size(datum_l, &size_l);
datum_beta = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred);; datum_beta = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].key);
datum_r = (SEG *) seg_union(datum_beta, datum_beta); datum_r = seg_union(datum_beta, datum_beta);
rt_seg_size((SEG *) datum_r, &size_r); rt_seg_size(datum_r, &size_r);
/* /*
* Now split up the regions between the two seeds. An important * Now split up the regions between the two seeds. An important
@ -443,11 +436,11 @@ gseg_picksplit(bytea *entryvec,
} }
/* okay, which page needs least enlargement? */ /* okay, which page needs least enlargement? */
datum_alpha = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
union_dl = (SEG *) seg_union(datum_l, datum_alpha); union_dl = seg_union(datum_l, datum_alpha);
union_dr = (SEG *) seg_union(datum_r, datum_alpha); union_dr = seg_union(datum_r, datum_alpha);
rt_seg_size((SEG *) union_dl, &size_alpha); rt_seg_size(union_dl, &size_alpha);
rt_seg_size((SEG *) union_dr, &size_beta); rt_seg_size(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)
@ -471,8 +464,8 @@ gseg_picksplit(bytea *entryvec,
} }
*left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */ *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
v->spl_ldatum = (char *) datum_l; v->spl_ldatum = PointerGetDatum(datum_l);
v->spl_rdatum = (char *) datum_r; v->spl_rdatum = PointerGetDatum(datum_r);
return v; return v;
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.27 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.28 2001/05/31 18:16:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -238,16 +238,21 @@ gistindex_keytest(IndexTuple tuple,
while (scanKeySize > 0) while (scanKeySize > 0)
{ {
datum = index_getattr(tuple, datum = index_getattr(tuple,
1, key[0].sk_attno,
tupdesc, tupdesc,
&isNull); &isNull);
if (isNull || IndexTupleSize(tuple) == sizeof(IndexTupleData) ) if (isNull)
{ {
/* XXX eventually should check if SK_ISNULL */ /* XXX eventually should check if SK_ISNULL */
return false; return false;
} }
gistdentryinit(giststate, &de, (char *) datum, r, p, offset, /* this code from backend/access/common/indexvalid.c. But why and what???
if (key[0].sk_flags & SK_ISNULL)
return false;
*/
gistdentryinit(giststate, key[0].sk_attno-1, &de,
datum, r, p, offset,
IndexTupleSize(tuple) - sizeof(IndexTupleData), IndexTupleSize(tuple) - sizeof(IndexTupleData),
FALSE); FALSE);
@ -266,16 +271,16 @@ gistindex_keytest(IndexTuple tuple,
ObjectIdGetDatum(key[0].sk_procedure)); ObjectIdGetDatum(key[0].sk_procedure));
} }
if ( (char*)de.pred != (char*)datum ) if ( de.key != datum )
if ( de.pred ) pfree( de.pred ); if ( DatumGetPointer(de.key) != NULL )
pfree( DatumGetPointer(de.key) );
if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE)) if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
return false; return false;
scanKeySize -= 1; scanKeySize--;
key++; key++;
} }
return true; return true;
} }
@ -284,7 +289,7 @@ static OffsetNumber
gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir) gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
{ {
OffsetNumber maxoff; OffsetNumber maxoff;
char *it; IndexTuple it;
GISTPageOpaque po; GISTPageOpaque po;
GISTScanOpaque so; GISTScanOpaque so;
GISTSTATE *giststate; GISTSTATE *giststate;
@ -307,8 +312,8 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
while (n >= FirstOffsetNumber && n <= maxoff) while (n >= FirstOffsetNumber && n <= maxoff)
{ {
it = (char *) PageGetItem(p, PageGetItemId(p, n)); it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
if (gistindex_keytest((IndexTuple) it, if (gistindex_keytest(it,
RelationGetDescr(s->relation), RelationGetDescr(s->relation),
s->numberOfKeys, s->keyData, giststate, s->numberOfKeys, s->keyData, giststate,
s->relation, p, n)) s->relation, p, n))

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.34 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.35 2001/05/31 18:16:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -122,7 +122,7 @@ gistrescan(PG_FUNCTION_ARGS)
s->keyData[i].sk_procedure s->keyData[i].sk_procedure
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno, = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
s->keyData[i].sk_procedure); s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn; s->keyData[i].sk_func = p->giststate->consistentFn[i];
} }
} }
else else
@ -153,7 +153,7 @@ gistrescan(PG_FUNCTION_ARGS)
s->keyData[i].sk_procedure s->keyData[i].sk_procedure
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno, = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
s->keyData[i].sk_procedure); s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn; s->keyData[i].sk_func = p->giststate->consistentFn[i];
} }
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.48 2001/03/22 06:16:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.49 2001/05/31 18:16:54 tgl Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId
@ -410,13 +410,13 @@ index_getprocid(Relation irel,
uint16 procnum) uint16 procnum)
{ {
RegProcedure *loc; RegProcedure *loc;
int natts; int nproc;
natts = irel->rd_rel->relnatts; nproc = irel->rd_am->amsupport;
loc = irel->rd_support; loc = irel->rd_support;
Assert(loc != NULL); Assert(loc != NULL);
return loc[(natts * (procnum - 1)) + (attnum - 1)]; return loc[(nproc * (attnum - 1)) + (procnum - 1)];
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.48 2001/05/30 20:52:32 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.49 2001/05/31 18:16:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -120,13 +120,15 @@ DefineIndex(char *heapRelationName,
/* /*
* XXX Hardwired hacks to check for limitations on supported index * XXX Hardwired hacks to check for limitations on supported index
* types. We really ought to be learning this info from entries in the * types. We really ought to be learning this info from entries in the
* pg_am table, instead of having it wired in here! * pg_am table, instead of having it wired-in here!
*/ */
if (unique && accessMethodId != BTREE_AM_OID) if (unique && accessMethodId != BTREE_AM_OID)
elog(ERROR, "DefineIndex: unique indices are only available with the btree access method"); elog(ERROR, "DefineIndex: unique indices are only available with the btree access method");
if (numberOfAttributes > 1 && accessMethodId != BTREE_AM_OID) if (numberOfAttributes > 1 &&
elog(ERROR, "DefineIndex: multi-column indices are only available with the btree access method"); !( accessMethodId == BTREE_AM_OID ||
accessMethodId == GIST_AM_OID))
elog(ERROR, "DefineIndex: multi-column indices are only available with the btree or GiST access methods");
/* /*
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96 * WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: gist.h,v 1.27 2001/05/30 19:53:39 tgl Exp $ * $Id: gist.h,v 1.28 2001/05/31 18:16:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -65,13 +65,13 @@ typedef struct GISTSTACK
typedef struct GISTSTATE typedef struct GISTSTATE
{ {
FmgrInfo consistentFn; FmgrInfo consistentFn[INDEX_MAX_KEYS];
FmgrInfo unionFn; FmgrInfo unionFn[INDEX_MAX_KEYS];
FmgrInfo compressFn; FmgrInfo compressFn[INDEX_MAX_KEYS];
FmgrInfo decompressFn; FmgrInfo decompressFn[INDEX_MAX_KEYS];
FmgrInfo penaltyFn; FmgrInfo penaltyFn[INDEX_MAX_KEYS];
FmgrInfo picksplitFn; FmgrInfo picksplitFn[INDEX_MAX_KEYS];
FmgrInfo equalFn; FmgrInfo equalFn[INDEX_MAX_KEYS];
bool haskeytype; bool haskeytype;
bool keytypbyval; bool keytypbyval;
} GISTSTATE; } GISTSTATE;
@ -121,21 +121,30 @@ typedef struct GIST_SPLITVEC
{ {
OffsetNumber *spl_left; /* array of entries that go left */ OffsetNumber *spl_left; /* array of entries that go left */
int spl_nleft; /* size of this array */ int spl_nleft; /* size of this array */
char *spl_ldatum; /* Union of keys in spl_left */ Datum spl_ldatum; /* Union of keys in spl_left */
Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in spl_left */
int spl_lattrsize[INDEX_MAX_KEYS];
OffsetNumber *spl_right; /* array of entries that go right */ OffsetNumber *spl_right; /* array of entries that go right */
int spl_nright; /* size of the array */ int spl_nright; /* size of the array */
char *spl_rdatum; /* Union of keys in spl_right */ Datum spl_rdatum; /* Union of keys in spl_right */
Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in spl_right */
int spl_rattrsize[INDEX_MAX_KEYS];
int *spl_idgrp;
int *spl_ngrp; /* number in each group */
char *spl_grpflag; /* flags of each group */
} GIST_SPLITVEC; } GIST_SPLITVEC;
/* /*
* An entry on a GiST node. Contains the key (pred), as well as * An entry on a GiST node. Contains the key, as well as
* its own location (rel,page,offset) which can supply the matching * its own location (rel,page,offset) which can supply the matching
* pointer. The size of the pred is in bytes, and leafkey is a flag to * pointer. The size of the key is in bytes, and leafkey is a flag to
* tell us if the entry is in a leaf node. * tell us if the entry is in a leaf node.
*/ */
typedef struct GISTENTRY typedef struct GISTENTRY
{ {
char *pred; Datum key;
Relation rel; Relation rel;
Page page; Page page;
OffsetNumber offset; OffsetNumber offset;
@ -146,43 +155,20 @@ typedef struct GISTENTRY
/* /*
* macro to initialize a GISTENTRY * macro to initialize a GISTENTRY
*/ */
#define gistentryinit(e, pr, r, pg, o, b, l)\ #define gistentryinit(e, k, r, pg, o, b, l) \
do {(e).pred = (pr); (e).rel = (r); (e).page = (pg); (e).offset = (o); (e).bytes = (b); (e).leafkey = (l);} while (0) do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
(e).offset = (o); (e).bytes = (b); (e).leafkey = (l); } while (0)
/* defined in gist.c */
#define TRLOWER(tr) (((tr)->bytes))
#define TRUPPER(tr) (&((tr)->bytes[MAXALIGN(VARSIZE(TRLOWER(tr)))]))
typedef struct txtrange
{
int32 vl_len;
/*
* flag: NINF means that lower is negative infinity; PINF means that *
* upper is positive infinity. 0 means that both are numbers.
*/
int32 flag;
char bytes[2];
} TXTRANGE;
typedef struct intrange
{
int lower;
int upper;
/*
* flag: NINF means that lower is negative infinity; PINF means that *
* upper is positive infinity. 0 means that both are numbers.
*/
int flag;
} INTRANGE;
/* gist.c */
extern Datum gistbuild(PG_FUNCTION_ARGS); extern Datum gistbuild(PG_FUNCTION_ARGS);
extern Datum gistinsert(PG_FUNCTION_ARGS); extern Datum gistinsert(PG_FUNCTION_ARGS);
extern Datum gistdelete(PG_FUNCTION_ARGS); extern Datum gistdelete(PG_FUNCTION_ARGS);
extern void _gistdump(Relation r); extern void _gistdump(Relation r);
extern void gistfreestack(GISTSTACK *s); extern void gistfreestack(GISTSTACK *s);
extern void initGISTstate(GISTSTATE *giststate, Relation index); extern void initGISTstate(GISTSTATE *giststate, Relation index);
extern void gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
Relation r, Page pg, OffsetNumber o, int b, bool l); Datum k, Relation r, Page pg, OffsetNumber o,
int b, bool l);
extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber, extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber,
RegProcedure); RegProcedure);