8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
20
20
21
21
22
22
static 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 );
25
28
static void _bt_newroot (Relation rel , Buffer lbuf , Buffer rbuf );
26
29
static OffsetNumber _bt_pgaddtup (Relation rel , Buffer buf , int keysz , ScanKey itup_scankey , Size itemsize , BTItem btitem , BTItem afteritem );
27
30
static bool _bt_goesonpg (Relation rel , Buffer buf , Size keysz , ScanKey scankey , BTItem afteritem );
@@ -297,7 +300,7 @@ _bt_insertonpg(Relation rel,
297
300
hitemid = PageGetItemId (page , P_HIKEY );
298
301
hitem = (BTItem ) PageGetItem (page , hitemid );
299
302
if (maxoff > P_HIKEY &&
300
- !_bt_itemcmp (rel , keysz , hitem ,
303
+ !_bt_itemcmp (rel , keysz , scankey , hitem ,
301
304
(BTItem ) PageGetItem (page , PageGetItemId (page , P_FIRSTKEY )),
302
305
BTEqualStrategyNumber ))
303
306
elog (FATAL , "btree: bad key on the page in the chain of duplicates" );
@@ -373,7 +376,8 @@ _bt_insertonpg(Relation rel,
373
376
{
374
377
itid = PageGetItemId (page , offnum );
375
378
chkitem = (BTItem ) PageGetItem (page , itid );
376
- if (!_bt_itemcmp (rel , keysz , previtem , chkitem ,
379
+ if (!_bt_itemcmp (rel , keysz , scankey ,
380
+ previtem , chkitem ,
377
381
BTEqualStrategyNumber ))
378
382
{
379
383
if (currsize > maxsize )
@@ -471,9 +475,10 @@ _bt_insertonpg(Relation rel,
471
475
MAXALIGN (sizeof (BTPageOpaqueData ))
472
476
+ sizeof (ItemIdData );
473
477
llimit /= 2 ;
474
- firstright = _bt_findsplitloc (rel , page , start , maxoff , llimit );
478
+ firstright = _bt_findsplitloc (rel , keysz , scankey ,
479
+ page , start , maxoff , llimit );
475
480
476
- if (_bt_itemcmp (rel , keysz ,
481
+ if (_bt_itemcmp (rel , keysz , scankey ,
477
482
(BTItem ) PageGetItem (page , PageGetItemId (page , start )),
478
483
(BTItem ) PageGetItem (page , PageGetItemId (page , firstright )),
479
484
BTEqualStrategyNumber ))
@@ -503,7 +508,8 @@ _bt_insertonpg(Relation rel,
503
508
ItemPointerSet (& (stack -> bts_btitem -> bti_itup .t_tid ),
504
509
bknum , P_HIKEY );
505
510
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 ,
507
513
(BTItem ) PageGetItem (page ,
508
514
PageGetItemId (page , start )),
509
515
BTLessStrategyNumber ))
@@ -519,7 +525,7 @@ _bt_insertonpg(Relation rel,
519
525
}
520
526
521
527
/* split the buffer into left and right halves */
522
- rbuf = _bt_split (rel , buf , firstright );
528
+ rbuf = _bt_split (rel , keysz , scankey , buf , firstright );
523
529
524
530
/* which new page (left half or right half) gets the tuple? */
525
531
if (_bt_goesonpg (rel , buf , keysz , scankey , afteritem ))
@@ -550,7 +556,7 @@ _bt_insertonpg(Relation rel,
550
556
elog (FATAL , "btree: un-shifted page is empty" );
551
557
lowLeftItem = (BTItem ) PageGetItem (page ,
552
558
PageGetItemId (page , P_FIRSTKEY ));
553
- if (_bt_itemcmp (rel , keysz , lowLeftItem ,
559
+ if (_bt_itemcmp (rel , keysz , scankey , lowLeftItem ,
554
560
(BTItem ) PageGetItem (page , PageGetItemId (page , P_HIKEY )),
555
561
BTEqualStrategyNumber ))
556
562
lpageop -> btpo_flags |= BTP_CHAIN ;
@@ -613,7 +619,8 @@ l_spl: ;
613
619
{
614
620
ritem = (BTItem ) PageGetItem (rpage ,
615
621
PageGetItemId (rpage , P_FIRSTKEY ));
616
- if (_bt_itemcmp (rel , keysz , ritem ,
622
+ if (_bt_itemcmp (rel , keysz , scankey ,
623
+ ritem ,
617
624
(BTItem ) PageGetItem (rpage ,
618
625
PageGetItemId (rpage , P_HIKEY )),
619
626
BTEqualStrategyNumber ))
@@ -663,13 +670,16 @@ l_spl: ;
663
670
* possible in splitting leftmost page) and current parent
664
671
* item == new_item. - vadim 05/27/97
665
672
*/
666
- if (_bt_itemcmp (rel , keysz , stack -> bts_btitem , new_item ,
673
+ if (_bt_itemcmp (rel , keysz , scankey ,
674
+ stack -> bts_btitem , new_item ,
667
675
BTGreaterStrategyNumber ) ||
668
676
(!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 )))
673
683
{
674
684
do_update = true;
675
685
@@ -831,7 +841,8 @@ l_spl: ;
831
841
* pin and lock on buf are maintained.
832
842
*/
833
843
static Buffer
834
- _bt_split (Relation rel , Buffer buf , OffsetNumber firstright )
844
+ _bt_split (Relation rel , Size keysz , ScanKey scankey ,
845
+ Buffer buf , OffsetNumber firstright )
835
846
{
836
847
Buffer rbuf ;
837
848
Page origpage ;
@@ -915,7 +926,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
915
926
{
916
927
Size llimit = PageGetFreeSpace (leftpage ) / 2 ;
917
928
918
- firstright = _bt_findsplitloc (rel , origpage , start , maxoff , llimit );
929
+ firstright = _bt_findsplitloc (rel , keysz , scankey ,
930
+ origpage , start , maxoff , llimit );
919
931
}
920
932
921
933
for (i = start ; i <= maxoff ; i = OffsetNumberNext (i ))
@@ -1027,6 +1039,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
1027
1039
*/
1028
1040
static OffsetNumber
1029
1041
_bt_findsplitloc (Relation rel ,
1042
+ Size keysz ,
1043
+ ScanKey scankey ,
1030
1044
Page page ,
1031
1045
OffsetNumber start ,
1032
1046
OffsetNumber maxoff ,
@@ -1039,12 +1053,10 @@ _bt_findsplitloc(Relation rel,
1039
1053
BTItem safeitem ,
1040
1054
nxtitem ;
1041
1055
Size nbytes ;
1042
- int natts ;
1043
1056
1044
1057
if (start >= maxoff )
1045
1058
elog (FATAL , "btree: cannot split if start (%d) >= maxoff (%d)" ,
1046
1059
start , maxoff );
1047
- natts = rel -> rd_rel -> relnatts ;
1048
1060
saferight = start ;
1049
1061
safeitemid = PageGetItemId (page , saferight );
1050
1062
nbytes = ItemIdGetLength (safeitemid ) + sizeof (ItemIdData );
@@ -1064,7 +1076,7 @@ _bt_findsplitloc(Relation rel,
1064
1076
* at isn't equal to the last safe one we saw, then it's our new
1065
1077
* safe tuple.
1066
1078
*/
1067
- if (!_bt_itemcmp (rel , natts ,
1079
+ if (!_bt_itemcmp (rel , keysz , scankey ,
1068
1080
safeitem , nxtitem , BTEqualStrategyNumber ))
1069
1081
{
1070
1082
safeitem = nxtitem ;
@@ -1345,92 +1357,94 @@ _bt_goesonpg(Relation rel,
1345
1357
}
1346
1358
1347
1359
/*
1348
- * _bt_itemcmp () -- compare item1 to item2 using a requested
1349
- * strategy (<, <=, =, >=, >)
1360
+ * _bt_tuplecompare () -- compare two IndexTuples,
1361
+ * return -1, 0, or +1
1350
1362
*
1351
1363
*/
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 )
1358
1370
{
1359
1371
TupleDesc tupDes ;
1360
- IndexTuple indexTuple1 ,
1361
- indexTuple2 ;
1362
- Datum attrDatum1 ,
1363
- attrDatum2 ;
1364
1372
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 ;
1380
1374
1381
1375
tupDes = RelationGetDescr (rel );
1382
- indexTuple1 = & (item1 -> bti_itup );
1383
- indexTuple2 = & (item2 -> bti_itup );
1384
1376
1385
1377
for (i = 1 ; i <= keysz ; i ++ )
1386
1378
{
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 );
1389
1387
1390
1388
/* see comments about NULLs handling in btbuild */
1391
- if (isFirstNull ) /* attr in item1 is NULL */
1389
+ if (isFirstNull ) /* attr in tuple1 is NULL */
1392
1390
{
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 ;
1395
1393
else
1396
- compare = ( strat == BTGreaterStrategyNumber ) ? true : false;
1394
+ compare = 1 ; /* NULL ">" not-NULL */
1397
1395
}
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 */
1401
1399
}
1402
1400
else
1403
- compare = _bt_invokestrat (rel , i , strat , attrDatum1 , attrDatum2 );
1404
-
1405
- if (compare ) /* true for one of ">, <, =" */
1406
1401
{
1407
- if ( strat != BTEqualStrategyNumber )
1408
- return true ;
1402
+ compare = ( int32 ) FMGR_PTR2 ( & entry -> sk_func ,
1403
+ attrDatum1 , attrDatum2 ) ;
1409
1404
}
1410
- else
1411
- /* false for one of ">, <, =" */
1412
- {
1413
- if (strat == BTEqualStrategyNumber )
1414
- return false;
1415
1405
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 */
1432
1408
}
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;
1434
1448
}
1435
1449
1436
1450
/*
@@ -1585,7 +1599,7 @@ _bt_shift(Relation rel, Buffer buf, BTStack stack, int keysz,
1585
1599
/* init old page opaque */
1586
1600
pageop -> btpo_flags = npageop -> btpo_flags ; /* restore flags */
1587
1601
pageop -> btpo_flags &= ~BTP_CHAIN ;
1588
- if (_bt_itemcmp (rel , keysz , hikey , btitem , BTEqualStrategyNumber ))
1602
+ if (_bt_itemcmp (rel , keysz , scankey , hikey , btitem , BTEqualStrategyNumber ))
1589
1603
pageop -> btpo_flags |= BTP_CHAIN ;
1590
1604
pageop -> btpo_prev = npageop -> btpo_prev ; /* restore prev */
1591
1605
pageop -> btpo_next = nbknum ; /* next points to the new page */
0 commit comments