88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
1010 * IDENTIFICATION
11- *$PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.14 2006/05/24 11:01:39 teodor Exp $
11+ *$PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.15 2006/05/29 12:50:06 teodor Exp $
1212 *-------------------------------------------------------------------------
1313 */
1414#include "postgres.h"
@@ -262,6 +262,16 @@ gistMakeUnionKey( GISTSTATE *giststate, int attno,
262262}
263263}
264264
265+ static bool
266+ gistKeyIsEQ (GISTSTATE * giststate ,int attno ,Datum a ,Datum b ) {
267+ bool result ;
268+
269+ FunctionCall3 (& giststate -> equalFn [attno ],
270+ a ,b ,
271+ PointerGetDatum (& result ));
272+ return result ;
273+ }
274+
265275/*
266276 * Forms union of oldtup and addtup, if union == oldtup then return NULL
267277 */
@@ -300,19 +310,8 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
300310continue ;
301311
302312if ( !addisnull [i ] ) {
303- if (oldisnull [i ] )
313+ if (oldisnull [i ]|| gistKeyIsEQ ( giststate , i , oldentries [ i ]. key , attrS [ i ]) == false )
304314neednew = true;
305- else {
306- bool result ;
307-
308- FunctionCall3 (& giststate -> equalFn [i ],
309- oldentries [i ].key ,
310- attrS [i ],
311- PointerGetDatum (& result ));
312-
313- if (!result )
314- neednew = true;
315- }
316315}
317316}
318317
@@ -395,7 +394,6 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
395394{
396395int j ;
397396int len ;
398- bool result ;
399397
400398if (spl -> spl_idgrp [spl -> spl_left [i ]])
401399continue ;
@@ -405,11 +403,7 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
405403{
406404if (spl -> spl_idgrp [spl -> spl_right [j ]])
407405continue ;
408- FunctionCall3 (& giststate -> equalFn [attno ],
409- valvec [spl -> spl_left [i ]].key ,
410- valvec [spl -> spl_right [j ]].key ,
411- PointerGetDatum (& result ));
412- if (result )
406+ if (gistKeyIsEQ (giststate ,attno ,valvec [spl -> spl_left [i ]].key ,valvec [spl -> spl_right [j ]].key ))
413407{
414408spl -> spl_idgrp [spl -> spl_right [j ]]= curid ;
415409len ++ ;
@@ -425,11 +419,7 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
425419{
426420if (spl -> spl_idgrp [spl -> spl_left [j ]])
427421continue ;
428- FunctionCall3 (& giststate -> equalFn [attno ],
429- valvec [spl -> spl_left [i ]].key ,
430- valvec [spl -> spl_left [j ]].key ,
431- PointerGetDatum (& result ));
432- if (result )
422+ if (gistKeyIsEQ (giststate ,attno ,valvec [spl -> spl_left [i ]].key ,valvec [spl -> spl_left [j ]].key ))
433423{
434424spl -> spl_idgrp [spl -> spl_left [j ]]= curid ;
435425len ++ ;
@@ -758,7 +748,14 @@ gistpenalty(GISTSTATE *giststate, int attno,
758748return penalty ;
759749}
760750
761- void
751+ /*
752+ * Calls user picksplit method for attno columns to split vector to
753+ * two vectors. May use attno+n columns data to
754+ * get better split.
755+ * Returns TRUE if left and right unions of attno columns are the same,
756+ * so caller may find better split
757+ */
758+ bool
762759gistUserPicksplit (Relation r ,GistEntryVector * entryvec ,int attno ,GIST_SPLITVEC * v ,
763760IndexTuple * itup ,int len ,GISTSTATE * giststate )
764761{
@@ -787,24 +784,36 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVE
787784 */
788785if (giststate -> tupdesc -> natts > 1 && attno + 1 != giststate -> tupdesc -> natts )
789786{
790- int MaxGrpId ;
787+ if (gistKeyIsEQ (giststate ,attno ,v -> spl_ldatum ,v -> spl_rdatum ) ) {
788+ /*
789+ * Left and right key's unions are equial, so
790+ * we can get better split by following columns. Note,
791+ * uninons for attno columns are already done.
792+ */
793+
794+ return true;
795+ }else {
796+ int MaxGrpId ;
791797
792- v -> spl_idgrp = (int * )palloc0 (sizeof (int )* entryvec -> n );
793- v -> spl_grpflag = (char * )palloc0 (sizeof (char )* entryvec -> n );
794- v -> spl_ngrp = (int * )palloc (sizeof (int )* entryvec -> n );
798+ v -> spl_idgrp = (int * )palloc0 (sizeof (int )* entryvec -> n );
799+ v -> spl_grpflag = (char * )palloc0 (sizeof (char )* entryvec -> n );
800+ v -> spl_ngrp = (int * )palloc (sizeof (int )* entryvec -> n );
795801
796- MaxGrpId = gistfindgroup (giststate ,entryvec -> vector ,v ,attno );
802+ MaxGrpId = gistfindgroup (giststate ,entryvec -> vector ,v ,attno );
797803
798- /* form union of sub keys for each page (l,p) */
799- gistunionsubkey (giststate ,itup ,v ,attno + 1 );
804+ /* form union of sub keys for each page (l,p) */
805+ gistunionsubkey (giststate ,itup ,v ,attno + 1 );
800806
801- /*
802- * if possible, we insert equivalent tuples with control by penalty
803- * for a subkey(s)
804- */
805- if (MaxGrpId > 1 )
806- gistadjsubkey (r ,itup ,len ,v ,giststate ,attno );
807+ /*
808+ * if possible, we insert equivalent tuples with control by penalty
809+ * for a subkey(s)
810+ */
811+ if (MaxGrpId > 1 )
812+ gistadjsubkey (r ,itup ,len ,v ,giststate ,attno );
813+ }
807814}
815+
816+ return false;
808817}
809818
810819/*