88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.54 2000/01/26 05:55:58 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.55 2000/02/18 06:32:33 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
2020
2121
2222static InsertIndexResult _bt_insertonpg (Relation rel , Buffer buf , BTStack stack , int keysz , ScanKey scankey , BTItem btitem , BTItem afteritem );
23- static Buffer _bt_split (Relation rel , Buffer buf , OffsetNumber firstright );
24- static OffsetNumber _bt_findsplitloc (Relation rel , Page page , OffsetNumber start , OffsetNumber maxoff , Size llimit );
23+ static Buffer _bt_split (Relation rel , Size keysz , ScanKey scankey ,
24+ Buffer buf , OffsetNumber firstright );
25+ static OffsetNumber _bt_findsplitloc (Relation rel , Size keysz , ScanKey scankey ,
26+ Page page , OffsetNumber start ,
27+ OffsetNumber maxoff , Size llimit );
2528static void _bt_newroot (Relation rel , Buffer lbuf , Buffer rbuf );
2629static OffsetNumber _bt_pgaddtup (Relation rel , Buffer buf , int keysz , ScanKey itup_scankey , Size itemsize , BTItem btitem , BTItem afteritem );
2730static bool _bt_goesonpg (Relation rel , Buffer buf , Size keysz , ScanKey scankey , BTItem afteritem );
@@ -297,7 +300,7 @@ _bt_insertonpg(Relation rel,
297300 hitemid = PageGetItemId (page , P_HIKEY );
298301 hitem = (BTItem ) PageGetItem (page , hitemid );
299302 if (maxoff > P_HIKEY &&
300- !_bt_itemcmp (rel , keysz , hitem ,
303+ !_bt_itemcmp (rel , keysz , scankey , hitem ,
301304 (BTItem ) PageGetItem (page , PageGetItemId (page , P_FIRSTKEY )),
302305 BTEqualStrategyNumber ))
303306 elog (FATAL , "btree: bad key on the page in the chain of duplicates" );
@@ -373,7 +376,8 @@ _bt_insertonpg(Relation rel,
373376 {
374377 itid = PageGetItemId (page , offnum );
375378 chkitem = (BTItem ) PageGetItem (page , itid );
376- if (!_bt_itemcmp (rel , keysz , previtem , chkitem ,
379+ if (!_bt_itemcmp (rel , keysz , scankey ,
380+ previtem , chkitem ,
377381 BTEqualStrategyNumber ))
378382 {
379383 if (currsize > maxsize )
@@ -471,9 +475,10 @@ _bt_insertonpg(Relation rel,
471475 MAXALIGN (sizeof (BTPageOpaqueData ))
472476 + sizeof (ItemIdData );
473477 llimit /= 2 ;
474- firstright = _bt_findsplitloc (rel , page , start , maxoff , llimit );
478+ firstright = _bt_findsplitloc (rel , keysz , scankey ,
479+ page , start , maxoff , llimit );
475480
476- if (_bt_itemcmp (rel , keysz ,
481+ if (_bt_itemcmp (rel , keysz , scankey ,
477482 (BTItem ) PageGetItem (page , PageGetItemId (page , start )),
478483 (BTItem ) PageGetItem (page , PageGetItemId (page , firstright )),
479484 BTEqualStrategyNumber ))
@@ -503,7 +508,8 @@ _bt_insertonpg(Relation rel,
503508 ItemPointerSet (& (stack -> bts_btitem -> bti_itup .t_tid ),
504509 bknum , P_HIKEY );
505510 pbuf = _bt_getstackbuf (rel , stack , BT_WRITE );
506- if (_bt_itemcmp (rel , keysz , stack -> bts_btitem ,
511+ if (_bt_itemcmp (rel , keysz , scankey ,
512+ stack -> bts_btitem ,
507513 (BTItem ) PageGetItem (page ,
508514 PageGetItemId (page , start )),
509515 BTLessStrategyNumber ))
@@ -519,7 +525,7 @@ _bt_insertonpg(Relation rel,
519525 }
520526
521527 /* split the buffer into left and right halves */
522- rbuf = _bt_split (rel , buf , firstright );
528+ rbuf = _bt_split (rel , keysz , scankey , buf , firstright );
523529
524530 /* which new page (left half or right half) gets the tuple? */
525531 if (_bt_goesonpg (rel , buf , keysz , scankey , afteritem ))
@@ -550,7 +556,7 @@ _bt_insertonpg(Relation rel,
550556 elog (FATAL , "btree: un-shifted page is empty" );
551557 lowLeftItem = (BTItem ) PageGetItem (page ,
552558 PageGetItemId (page , P_FIRSTKEY ));
553- if (_bt_itemcmp (rel , keysz , lowLeftItem ,
559+ if (_bt_itemcmp (rel , keysz , scankey , lowLeftItem ,
554560 (BTItem ) PageGetItem (page , PageGetItemId (page , P_HIKEY )),
555561 BTEqualStrategyNumber ))
556562 lpageop -> btpo_flags |= BTP_CHAIN ;
@@ -613,7 +619,8 @@ l_spl: ;
613619 {
614620 ritem = (BTItem ) PageGetItem (rpage ,
615621 PageGetItemId (rpage , P_FIRSTKEY ));
616- if (_bt_itemcmp (rel , keysz , ritem ,
622+ if (_bt_itemcmp (rel , keysz , scankey ,
623+ ritem ,
617624 (BTItem ) PageGetItem (rpage ,
618625 PageGetItemId (rpage , P_HIKEY )),
619626 BTEqualStrategyNumber ))
@@ -663,13 +670,16 @@ l_spl: ;
663670 * possible in splitting leftmost page) and current parent
664671 * item == new_item. - vadim 05/27/97
665672 */
666- if (_bt_itemcmp (rel , keysz , stack -> bts_btitem , new_item ,
673+ if (_bt_itemcmp (rel , keysz , scankey ,
674+ stack -> bts_btitem , new_item ,
667675 BTGreaterStrategyNumber ) ||
668676 (!shifted &&
669- _bt_itemcmp (rel , keysz , stack -> bts_btitem ,
670- new_item , BTEqualStrategyNumber ) &&
671- _bt_itemcmp (rel , keysz , lowLeftItem ,
672- new_item , BTLessStrategyNumber )))
677+ _bt_itemcmp (rel , keysz , scankey ,
678+ stack -> bts_btitem , new_item ,
679+ BTEqualStrategyNumber ) &&
680+ _bt_itemcmp (rel , keysz , scankey ,
681+ lowLeftItem , new_item ,
682+ BTLessStrategyNumber )))
673683 {
674684 do_update = true;
675685
@@ -831,7 +841,8 @@ l_spl: ;
831841 * pin and lock on buf are maintained.
832842 */
833843static Buffer
834- _bt_split (Relation rel , Buffer buf , OffsetNumber firstright )
844+ _bt_split (Relation rel , Size keysz , ScanKey scankey ,
845+ Buffer buf , OffsetNumber firstright )
835846{
836847 Buffer rbuf ;
837848 Page origpage ;
@@ -915,7 +926,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
915926 {
916927 Size llimit = PageGetFreeSpace (leftpage ) / 2 ;
917928
918- firstright = _bt_findsplitloc (rel , origpage , start , maxoff , llimit );
929+ firstright = _bt_findsplitloc (rel , keysz , scankey ,
930+ origpage , start , maxoff , llimit );
919931 }
920932
921933 for (i = start ; i <= maxoff ; i = OffsetNumberNext (i ))
@@ -1027,6 +1039,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
10271039 */
10281040static OffsetNumber
10291041_bt_findsplitloc (Relation rel ,
1042+ Size keysz ,
1043+ ScanKey scankey ,
10301044 Page page ,
10311045 OffsetNumber start ,
10321046 OffsetNumber maxoff ,
@@ -1039,12 +1053,10 @@ _bt_findsplitloc(Relation rel,
10391053 BTItem safeitem ,
10401054 nxtitem ;
10411055 Size nbytes ;
1042- int natts ;
10431056
10441057 if (start >= maxoff )
10451058 elog (FATAL , "btree: cannot split if start (%d) >= maxoff (%d)" ,
10461059 start , maxoff );
1047- natts = rel -> rd_rel -> relnatts ;
10481060 saferight = start ;
10491061 safeitemid = PageGetItemId (page , saferight );
10501062 nbytes = ItemIdGetLength (safeitemid ) + sizeof (ItemIdData );
@@ -1064,7 +1076,7 @@ _bt_findsplitloc(Relation rel,
10641076 * at isn't equal to the last safe one we saw, then it's our new
10651077 * safe tuple.
10661078 */
1067- if (!_bt_itemcmp (rel , natts ,
1079+ if (!_bt_itemcmp (rel , keysz , scankey ,
10681080 safeitem , nxtitem , BTEqualStrategyNumber ))
10691081 {
10701082 safeitem = nxtitem ;
@@ -1345,92 +1357,94 @@ _bt_goesonpg(Relation rel,
13451357}
13461358
13471359/*
1348- * _bt_itemcmp () -- compare item1 to item2 using a requested
1349- * strategy (<, <=, =, >=, >)
1360+ * _bt_tuplecompare () -- compare two IndexTuples,
1361+ * return -1, 0, or +1
13501362 *
13511363 */
1352- bool
1353- _bt_itemcmp (Relation rel ,
1354- Size keysz ,
1355- BTItem item1 ,
1356- BTItem item2 ,
1357- StrategyNumber strat )
1364+ int32
1365+ _bt_tuplecompare (Relation rel ,
1366+ Size keysz ,
1367+ ScanKey scankey ,
1368+ IndexTuple tuple1 ,
1369+ IndexTuple tuple2 )
13581370{
13591371 TupleDesc tupDes ;
1360- IndexTuple indexTuple1 ,
1361- indexTuple2 ;
1362- Datum attrDatum1 ,
1363- attrDatum2 ;
13641372 int i ;
1365- bool isFirstNull ,
1366- isSecondNull ;
1367- bool compare ;
1368- bool useEqual = false;
1369-
1370- if (strat == BTLessEqualStrategyNumber )
1371- {
1372- useEqual = true;
1373- strat = BTLessStrategyNumber ;
1374- }
1375- else if (strat == BTGreaterEqualStrategyNumber )
1376- {
1377- useEqual = true;
1378- strat = BTGreaterStrategyNumber ;
1379- }
1373+ int32 compare = 0 ;
13801374
13811375 tupDes = RelationGetDescr (rel );
1382- indexTuple1 = & (item1 -> bti_itup );
1383- indexTuple2 = & (item2 -> bti_itup );
13841376
13851377 for (i = 1 ; i <= keysz ; i ++ )
13861378 {
1387- attrDatum1 = index_getattr (indexTuple1 , i , tupDes , & isFirstNull );
1388- attrDatum2 = index_getattr (indexTuple2 , i , tupDes , & isSecondNull );
1379+ ScanKey entry = & scankey [i - 1 ];
1380+ Datum attrDatum1 ,
1381+ attrDatum2 ;
1382+ bool isFirstNull ,
1383+ isSecondNull ;
1384+
1385+ attrDatum1 = index_getattr (tuple1 , i , tupDes , & isFirstNull );
1386+ attrDatum2 = index_getattr (tuple2 , i , tupDes , & isSecondNull );
13891387
13901388 /* see comments about NULLs handling in btbuild */
1391- if (isFirstNull ) /* attr in item1 is NULL */
1389+ if (isFirstNull ) /* attr in tuple1 is NULL */
13921390 {
1393- if (isSecondNull ) /* attr in item2 is NULL too */
1394- compare = ( strat == BTEqualStrategyNumber ) ? true : false ;
1391+ if (isSecondNull ) /* attr in tuple2 is NULL too */
1392+ compare = 0 ;
13951393 else
1396- compare = ( strat == BTGreaterStrategyNumber ) ? true : false;
1394+ compare = 1 ; /* NULL ">" not-NULL */
13971395 }
1398- else if (isSecondNull ) /* attr in item1 is NOT_NULL and */
1399- { /* and attr in item2 is NULL */
1400- compare = ( strat == BTLessStrategyNumber ) ? true : false;
1396+ else if (isSecondNull ) /* attr in tuple1 is NOT_NULL and */
1397+ { /* attr in tuple2 is NULL */
1398+ compare = -1 ; /* not-NULL "<" NULL */
14011399 }
14021400 else
1403- compare = _bt_invokestrat (rel , i , strat , attrDatum1 , attrDatum2 );
1404-
1405- if (compare ) /* true for one of ">, <, =" */
14061401 {
1407- if ( strat != BTEqualStrategyNumber )
1408- return true ;
1402+ compare = ( int32 ) FMGR_PTR2 ( & entry -> sk_func ,
1403+ attrDatum1 , attrDatum2 ) ;
14091404 }
1410- else
1411- /* false for one of ">, <, =" */
1412- {
1413- if (strat == BTEqualStrategyNumber )
1414- return false;
14151405
1416- /*
1417- * if original strat was "<=, >=" OR "<, >" but some
1418- * attribute(s) left - need to test for Equality
1419- */
1420- if (useEqual || i < keysz )
1421- {
1422- if (isFirstNull || isSecondNull )
1423- compare = (isFirstNull && isSecondNull ) ? true : false;
1424- else
1425- compare = _bt_invokestrat (rel , i , BTEqualStrategyNumber ,
1426- attrDatum1 , attrDatum2 );
1427- if (compare ) /* item1' and item2' attributes are equal */
1428- continue ; /* - try to compare next attributes */
1429- }
1430- return false;
1431- }
1406+ if (compare != 0 )
1407+ break ; /* done when we find unequal attributes */
14321408 }
1433- return true;
1409+
1410+ return compare ;
1411+ }
1412+
1413+ /*
1414+ * _bt_itemcmp() -- compare two BTItems using a requested
1415+ * strategy (<, <=, =, >=, >)
1416+ *
1417+ */
1418+ bool
1419+ _bt_itemcmp (Relation rel ,
1420+ Size keysz ,
1421+ ScanKey scankey ,
1422+ BTItem item1 ,
1423+ BTItem item2 ,
1424+ StrategyNumber strat )
1425+ {
1426+ int32 compare ;
1427+
1428+ compare = _bt_tuplecompare (rel , keysz , scankey ,
1429+ & (item1 -> bti_itup ),
1430+ & (item2 -> bti_itup ));
1431+
1432+ switch (strat )
1433+ {
1434+ case BTLessStrategyNumber :
1435+ return (bool ) (compare < 0 );
1436+ case BTLessEqualStrategyNumber :
1437+ return (bool ) (compare <= 0 );
1438+ case BTEqualStrategyNumber :
1439+ return (bool ) (compare == 0 );
1440+ case BTGreaterEqualStrategyNumber :
1441+ return (bool ) (compare >= 0 );
1442+ case BTGreaterStrategyNumber :
1443+ return (bool ) (compare > 0 );
1444+ }
1445+
1446+ elog (ERROR , "_bt_itemcmp: bogus strategy %d" , (int ) strat );
1447+ return false;
14341448}
14351449
14361450/*
@@ -1585,7 +1599,7 @@ _bt_shift(Relation rel, Buffer buf, BTStack stack, int keysz,
15851599 /* init old page opaque */
15861600 pageop -> btpo_flags = npageop -> btpo_flags ; /* restore flags */
15871601 pageop -> btpo_flags &= ~BTP_CHAIN ;
1588- if (_bt_itemcmp (rel , keysz , hikey , btitem , BTEqualStrategyNumber ))
1602+ if (_bt_itemcmp (rel , keysz , scankey , hikey , btitem , BTEqualStrategyNumber ))
15891603 pageop -> btpo_flags |= BTP_CHAIN ;
15901604 pageop -> btpo_prev = npageop -> btpo_prev ; /* restore prev */
15911605 pageop -> btpo_next = nbknum ; /* next points to the new page */
0 commit comments