Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit916b232

Browse files
committed
Clean up and document btree code for ordering keys. Neat stuff,
actually, but who could understand it with no comments? Fix bugwhile at it: _bt_orderkeys would try to invoke comparisons onNULL inputs, given the right sort of redundant quals.
1 parentda1ad32 commit916b232

File tree

3 files changed

+284
-191
lines changed

3 files changed

+284
-191
lines changed

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.61 2000/07/21 06:42:32 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.62 2000/07/25 04:47:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -374,7 +374,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
374374
BTItembtitem;
375375
IndexTupleitup;
376376
BTScanOpaqueso;
377-
Sizekeysok;
377+
boolcontinuescan;
378378

379379
rel=scan->relation;
380380
so= (BTScanOpaque)scan->opaque;
@@ -396,16 +396,14 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
396396
btitem= (BTItem)PageGetItem(page,PageGetItemId(page,offnum));
397397
itup=&btitem->bti_itup;
398398

399-
if (_bt_checkkeys(scan,itup,&keysok))
399+
if (_bt_checkkeys(scan,itup,dir,&continuescan))
400400
{
401401
/* tuple passes all scan key conditions, so return it */
402-
Assert(keysok==so->numberOfKeys);
403402
returnFormRetrieveIndexResult(current,&(itup->t_tid));
404403
}
405404

406405
/* This tuple doesn't pass, but there might be more that do */
407-
}while (keysok >=so->numberOfFirstKeys||
408-
(keysok== ((Size)-1)&&ScanDirectionIsBackward(dir)));
406+
}while (continuescan);
409407

410408
/* No more items, so close down the current-item info */
411409
ItemPointerSetInvalid(current);
@@ -442,11 +440,10 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
442440
RegProcedureproc;
443441
int32result;
444442
BTScanOpaqueso;
445-
Sizekeysok;
446-
boolstrategyCheck;
447-
ScanKeyscankeys=0;
443+
boolcontinuescan;
444+
ScanKeyscankeys=NULL;
448445
intkeysCount=0;
449-
int*nKeyIs=0;
446+
int*nKeyIs=NULL;
450447
inti,
451448
j;
452449
StrategyNumberstrat_total;
@@ -455,71 +452,74 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
455452
so= (BTScanOpaque)scan->opaque;
456453

457454
/*
458-
* Order the keys inthe qualificationandbe sure that the scan
459-
*exploits the tree order.
455+
* Order thescankeys inour canonical fashionandeliminate any
456+
*redundant keys.
460457
*/
461-
so->numberOfFirstKeys=0;/* may be changed by _bt_orderkeys */
462-
so->qual_ok=1;/* may be changed by _bt_orderkeys */
463-
scan->scanFromEnd= false;
464-
strategyCheck= false;
465-
if (so->numberOfKeys>0)
466-
{
467-
_bt_orderkeys(rel,so);
458+
_bt_orderkeys(rel,so);
468459

469-
if (so->qual_ok)
470-
strategyCheck= true;
471-
}
460+
/*
461+
* Quit now if _bt_orderkeys() discovered that the scan keys can
462+
* never be satisfied (eg, x == 1 AND x > 2).
463+
*/
464+
if (!so->qual_ok)
465+
return (RetrieveIndexResult)NULL;
466+
467+
/*
468+
* Examine the scan keys to discover where we need to start the scan.
469+
*/
470+
scan->scanFromEnd= false;
472471
strat_total=BTEqualStrategyNumber;
473-
if (strategyCheck)
472+
if (so->numberOfKeys>0)
474473
{
475-
AttrNumberattno;
476-
477474
nKeyIs= (int*)palloc(so->numberOfKeys*sizeof(int));
478475
for (i=0;i<so->numberOfKeys;i++)
479476
{
480-
attno=so->keyData[i].sk_attno;
481-
if (attno==keysCount)
477+
AttrNumberattno=so->keyData[i].sk_attno;
478+
479+
/* ignore keys for already-determined attrs */
480+
if (attno <=keysCount)
482481
continue;
482+
/* if we didn't find a boundary for the preceding attr, quit */
483483
if (attno>keysCount+1)
484484
break;
485485
strat=_bt_getstrat(rel,attno,
486486
so->keyData[i].sk_procedure);
487+
/*
488+
* Can we use this key as a starting boundary for this attr?
489+
*
490+
* We can use multiple keys if they look like, say, = >= =
491+
* but we have to stop after accepting a > or < boundary.
492+
*/
487493
if (strat==strat_total||
488494
strat==BTEqualStrategyNumber)
489495
{
490496
nKeyIs[keysCount++]=i;
491-
continue;
492497
}
493-
if (ScanDirectionIsBackward(dir)&&
494-
(strat==BTLessStrategyNumber||
495-
strat==BTLessEqualStrategyNumber))
498+
elseif (ScanDirectionIsBackward(dir)&&
499+
(strat==BTLessStrategyNumber||
500+
strat==BTLessEqualStrategyNumber))
496501
{
497502
nKeyIs[keysCount++]=i;
498503
strat_total=strat;
499504
if (strat==BTLessStrategyNumber)
500505
break;
501-
continue;
502506
}
503-
if (ScanDirectionIsForward(dir)&&
504-
(strat==BTGreaterStrategyNumber||
505-
strat==BTGreaterEqualStrategyNumber))
507+
elseif (ScanDirectionIsForward(dir)&&
508+
(strat==BTGreaterStrategyNumber||
509+
strat==BTGreaterEqualStrategyNumber))
506510
{
507511
nKeyIs[keysCount++]=i;
508512
strat_total=strat;
509513
if (strat==BTGreaterStrategyNumber)
510514
break;
511-
continue;
512515
}
513516
}
514-
if (!keysCount)
517+
if (keysCount==0)
515518
scan->scanFromEnd= true;
516519
}
517520
else
518521
scan->scanFromEnd= true;
519522

520-
if (so->qual_ok==0)
521-
return (RetrieveIndexResult)NULL;
522-
523523
/* if we just need to walk down one edge of the tree, do that */
524524
if (scan->scanFromEnd)
525525
{
@@ -529,16 +529,14 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
529529
}
530530

531531
/*
532-
* Okay, we want something more complicated. What we'll do is use the
533-
* first item in the scan key passed in (which has been correctly
534-
* ordered to take advantage of index ordering) to position ourselves
535-
* at the right place in the scan.
532+
* We want to start the scan somewhere within the index. Set up a
533+
* scankey we can use to search for the correct starting point.
536534
*/
537535
scankeys= (ScanKey)palloc(keysCount*sizeof(ScanKeyData));
538536
for (i=0;i<keysCount;i++)
539537
{
540538
j=nKeyIs[i];
541-
/* _bt_orderkeys disallows it, but it's place to add some codelatter */
539+
/* _bt_orderkeys disallows it, but it's place to add some codelater */
542540
if (so->keyData[j].sk_flags&SK_ISNULL)
543541
{
544542
pfree(nKeyIs);
@@ -578,6 +576,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
578576
blkno=BufferGetBlockNumber(buf);
579577
page=BufferGetPage(buf);
580578

579+
/* position to the precise item on the page */
581580
offnum=_bt_binsrch(rel,buf,keysCount,scankeys);
582581

583582
ItemPointerSet(current,blkno,offnum);
@@ -595,7 +594,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
595594
* call _bt_endpoint() to set up a scan starting at that index endpoint,
596595
* as appropriate for the desired scan type.
597596
*
598-
* it's yet other place to add some codelatter for is(not)null ...
597+
* it's yet other place to add some codelater for is(not)null ...
599598
*----------
600599
*/
601600

@@ -737,13 +736,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
737736
itup=&btitem->bti_itup;
738737

739738
/* is the first item actually acceptable? */
740-
if (_bt_checkkeys(scan,itup,&keysok))
739+
if (_bt_checkkeys(scan,itup,dir,&continuescan))
741740
{
742741
/* yes, return it */
743742
res=FormRetrieveIndexResult(current,&(itup->t_tid));
744743
}
745-
elseif (keysok >=so->numberOfFirstKeys||
746-
(keysok== ((Size)-1)&&ScanDirectionIsBackward(dir)))
744+
elseif (continuescan)
747745
{
748746
/* no, but there might be another one that is */
749747
res=_bt_next(scan,dir);
@@ -906,7 +904,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
906904
IndexTupleitup;
907905
BTScanOpaqueso;
908906
RetrieveIndexResultres;
909-
Sizekeysok;
907+
boolcontinuescan;
910908

911909
rel=scan->relation;
912910
current=&(scan->currentItemData);
@@ -1012,13 +1010,12 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
10121010
itup=&(btitem->bti_itup);
10131011

10141012
/* see if we picked a winner */
1015-
if (_bt_checkkeys(scan,itup,&keysok))
1013+
if (_bt_checkkeys(scan,itup,dir,&continuescan))
10161014
{
10171015
/* yes, return it */
10181016
res=FormRetrieveIndexResult(current,&(itup->t_tid));
10191017
}
1020-
elseif (keysok >=so->numberOfFirstKeys||
1021-
(keysok== ((Size)-1)&&ScanDirectionIsBackward(dir)))
1018+
elseif (continuescan)
10221019
{
10231020
/* no, but there might be another one that is */
10241021
res=_bt_next(scan,dir);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp