* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.137 2006/05/24 11:01:39 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.138 2006/05/29 12:50:06 teodor Exp $
*
*-------------------------------------------------------------------------
*/
/*
* all keys are not-null
*/
- gistUserPicksplit(r, entryvec, attno, v, itup, len, giststate);
+ if ( gistUserPicksplit(r, entryvec, attno, v, itup, len, giststate) && attno+1 != r->rd_att->natts )
+ /*
+ * Splitting on attno column is not optimized: unions of left and right
+ * page are the same, we will try to split page by
+ * following columns
+ */
+ gistSplitByKey(r, page, itup, len, giststate, v, entryvec, attno+1);
}
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.14 2006/05/24 11:01:39 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.15 2006/05/29 12:50:06 teodor Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
}
}
+static bool
+gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b) {
+ bool result;
+
+ FunctionCall3(&giststate->equalFn[attno],
+ a, b,
+ PointerGetDatum(&result));
+ return result;
+}
+
/*
* Forms union of oldtup and addtup, if union == oldtup then return NULL
*/
continue;
if ( !addisnull[i] ) {
- if ( oldisnull[i] )
+ if ( oldisnull[i] || gistKeyIsEQ(giststate, i, oldentries[i].key, attrS[i])==false )
neednew = true;
- else {
- bool result;
-
- FunctionCall3(&giststate->equalFn[i],
- oldentries[i].key,
- attrS[i],
- PointerGetDatum(&result));
-
- if (!result)
- neednew = true;
- }
}
}
{
int j;
int len;
- bool result;
if (spl->spl_idgrp[spl->spl_left[i]])
continue;
{
if (spl->spl_idgrp[spl->spl_right[j]])
continue;
- FunctionCall3(&giststate->equalFn[attno],
- valvec[spl->spl_left[i]].key,
- valvec[spl->spl_right[j]].key,
- PointerGetDatum(&result));
- if (result)
+ if (gistKeyIsEQ(giststate, attno, valvec[spl->spl_left[i]].key, valvec[spl->spl_right[j]].key))
{
spl->spl_idgrp[spl->spl_right[j]] = curid;
len++;
{
if (spl->spl_idgrp[spl->spl_left[j]])
continue;
- FunctionCall3(&giststate->equalFn[attno],
- valvec[spl->spl_left[i]].key,
- valvec[spl->spl_left[j]].key,
- PointerGetDatum(&result));
- if (result)
+ if (gistKeyIsEQ(giststate, attno, valvec[spl->spl_left[i]].key, valvec[spl->spl_left[j]].key))
{
spl->spl_idgrp[spl->spl_left[j]] = curid;
len++;
return penalty;
}
-void
+/*
+ * Calls user picksplit method for attno columns to split vector to
+ * two vectors. May use attno+n columns data to
+ * get better split.
+ * Returns TRUE if left and right unions of attno columns are the same,
+ * so caller may find better split
+ */
+bool
gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
IndexTuple *itup, int len, GISTSTATE *giststate)
{
*/
if (giststate->tupdesc->natts > 1 && attno+1 != giststate->tupdesc->natts)
{
- int MaxGrpId;
+ if ( gistKeyIsEQ(giststate, attno, v->spl_ldatum, v->spl_rdatum) ) {
+ /*
+ * Left and right key's unions are equial, so
+ * we can get better split by following columns. Note,
+ * uninons for attno columns are already done.
+ */
+
+ return true;
+ } else {
+ int MaxGrpId;
- v->spl_idgrp = (int *) palloc0(sizeof(int) * entryvec->n);
- v->spl_grpflag = (char *) palloc0(sizeof(char) * entryvec->n);
- v->spl_ngrp = (int *) palloc(sizeof(int) * entryvec->n);
+ v->spl_idgrp = (int *) palloc0(sizeof(int) * entryvec->n);
+ v->spl_grpflag = (char *) palloc0(sizeof(char) * entryvec->n);
+ v->spl_ngrp = (int *) palloc(sizeof(int) * entryvec->n);
- MaxGrpId = gistfindgroup(giststate, entryvec->vector, v, attno);
+ MaxGrpId = gistfindgroup(giststate, entryvec->vector, v, attno);
- /* form union of sub keys for each page (l,p) */
- gistunionsubkey(giststate, itup, v, attno + 1);
+ /* form union of sub keys for each page (l,p) */
+ gistunionsubkey(giststate, itup, v, attno + 1);
- /*
- * if possible, we insert equivalent tuples with control by penalty
- * for a subkey(s)
- */
- if (MaxGrpId > 1)
- gistadjsubkey(r, itup, len, v, giststate, attno);
+ /*
+ * if possible, we insert equivalent tuples with control by penalty
+ * for a subkey(s)
+ */
+ if (MaxGrpId > 1)
+ gistadjsubkey(r, itup, len, v, giststate, attno);
+ }
}
+
+ return false;
}
/*
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.16 2006/05/24 11:01:39 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.17 2006/05/29 12:50:06 teodor Exp $
*
*-------------------------------------------------------------------------
*/
extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
Datum k, Relation r, Page pg, OffsetNumber o,
int b, bool l, bool isNull);
-void gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
+bool gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
IndexTuple *itup, int len, GISTSTATE *giststate);
/* gistvacuum.c */