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

Commit174b552

Browse files
committed
There are some bugs about backward scanning using
indexes.1. Index Scan using plural indexids never scan backward as to the order of indexids.2. The cursor using Index scan is not usable after moving past the end.This patch solves above bugs.Moreover the change of _bt_first() would be useful to extendORDER BY patch by Jan Wieck for all descending order cases.Hiroshi Inoue
1 parentdf6e504 commit174b552

File tree

3 files changed

+102
-22
lines changed

3 files changed

+102
-22
lines changed

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

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.42 1999/03/28 20:31:58 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.43 1999/04/13 17:18:28 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -733,7 +733,8 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
733733
returnres;
734734
}
735735

736-
}while (keysok >=so->numberOfFirstKeys);
736+
}while (keysok >=so->numberOfFirstKeys||
737+
(keysok==-1&&ScanDirectionIsBackward(dir)));
737738

738739
ItemPointerSetInvalid(current);
739740
so->btso_curbuf=InvalidBuffer;
@@ -775,6 +776,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
775776
BTScanOpaqueso;
776777
ScanKeyDataskdata;
777778
Sizekeysok;
779+
inti;
780+
intnKeyIndex=-1;
778781

779782
rel=scan->relation;
780783
so= (BTScanOpaque)scan->opaque;
@@ -790,11 +793,34 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
790793
{
791794
_bt_orderkeys(rel,so);
792795

793-
strat=_bt_getstrat(rel,1,so->keyData[0].sk_procedure);
796+
if (ScanDirectionIsBackward(dir))
797+
{
798+
for (i=0;i<so->numberOfKeys;i++)
799+
{
800+
if (so->keyData[i].sk_attno!=1)
801+
break;
802+
strat=_bt_getstrat(rel,so->keyData[i].sk_attno,
803+
so->keyData[i].sk_procedure);
804+
if (strat==BTLessStrategyNumber||
805+
strat==BTLessEqualStrategyNumber||
806+
strat==BTEqualStrategyNumber)
807+
{
808+
nKeyIndex=i;
809+
break;
810+
}
811+
}
812+
}
813+
else
814+
{
815+
strat=_bt_getstrat(rel,1,so->keyData[0].sk_procedure);
794816

795-
/* NOTE: it assumes ForwardScanDirection */
796-
if (strat==BTLessStrategyNumber||
797-
strat==BTLessEqualStrategyNumber)
817+
if (strat==BTLessStrategyNumber||
818+
strat==BTLessEqualStrategyNumber)
819+
;
820+
else
821+
nKeyIndex=0;
822+
}
823+
if (nKeyIndex<0)
798824
scan->scanFromEnd= true;
799825
}
800826
else
@@ -823,8 +849,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
823849
return (RetrieveIndexResult)NULL;
824850
}
825851
proc=index_getprocid(rel,1,BTORDER_PROC);
826-
ScanKeyEntryInitialize(&skdata,so->keyData[0].sk_flags,1,proc,
827-
so->keyData[0].sk_argument);
852+
ScanKeyEntryInitialize(&skdata,so->keyData[nKeyIndex].sk_flags,
853+
1,proc,so->keyData[nKeyIndex].sk_argument);
828854

829855
stack=_bt_search(rel,1,&skdata,&buf);
830856
_bt_freestack(stack);
@@ -897,7 +923,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
897923

898924
/* it's yet other place to add some code latter for is(not)null */
899925

900-
strat=_bt_getstrat(rel,1,so->keyData[0].sk_procedure);
926+
strat=_bt_getstrat(rel,1,so->keyData[nKeyIndex].sk_procedure);
901927

902928
switch (strat)
903929
{
@@ -914,9 +940,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
914940
result=_bt_compare(rel,itupdesc,page,1,&skdata,offnum);
915941
}while (result <=0);
916942

917-
/* if this is true, the key we just looked at is gone */
918-
if (result>0)
919-
_bt_twostep(scan,&buf,ForwardScanDirection);
920943
}
921944
break;
922945

@@ -946,6 +969,21 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
946969
ItemPointerSetInvalid(&(scan->currentItemData));
947970
return (RetrieveIndexResult)NULL;
948971
}
972+
elseif (ScanDirectionIsBackward(dir))
973+
{
974+
do
975+
{
976+
if (!_bt_twostep(scan,&buf,ForwardScanDirection))
977+
break;
978+
979+
offnum=ItemPointerGetOffsetNumber(current);
980+
page=BufferGetPage(buf);
981+
result=_bt_compare(rel,itupdesc,page,1,&skdata,offnum);
982+
}while (result==0);
983+
984+
if (result<0)
985+
_bt_twostep(scan,&buf,BackwardScanDirection);
986+
}
949987
break;
950988

951989
caseBTGreaterEqualStrategyNumber:
@@ -1026,6 +1064,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
10261064
so->btso_curbuf=buf;
10271065
return_bt_next(scan,dir);
10281066
}
1067+
elseif (keysok==-1&&ScanDirectionIsBackward(dir))
1068+
{
1069+
so->btso_curbuf=buf;
1070+
return_bt_next(scan,dir);
1071+
}
10291072
else
10301073
{
10311074
ItemPointerSetInvalid(current);
@@ -1495,6 +1538,11 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
14951538
so->btso_curbuf=buf;
14961539
return_bt_next(scan,dir);
14971540
}
1541+
elseif (keysok==-1&&ScanDirectionIsBackward(dir))
1542+
{
1543+
so->btso_curbuf=buf;
1544+
return_bt_next(scan,dir);
1545+
}
14981546
else
14991547
{
15001548
ItemPointerSetInvalid(current);

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.25 1999/02/1323:14:37 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.26 1999/04/1317:18:29 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -367,8 +367,14 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size *keysok)
367367
&isNull);
368368

369369
/* btree doesn't support 'A is null' clauses, yet */
370-
if (isNull||key[0].sk_flags&SK_ISNULL)
370+
if (key[0].sk_flags&SK_ISNULL)
371371
return false;
372+
if (isNull)
373+
{
374+
if (*keysok<so->numberOfFirstKeys)
375+
*keysok=-1;
376+
return false;
377+
}
372378

373379
if (key[0].sk_flags&SK_COMMUTE)
374380
{

‎src/backend/executor/nodeIndexscan.c

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.33 1999/02/21 03:48:40 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.34 1999/04/13 17:18:29 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -96,6 +96,8 @@ IndexNext(IndexScan *node)
9696
Bufferbuffer=InvalidBuffer;
9797
intnumIndices;
9898

99+
boolbBackward;
100+
intindexNumber;
99101
/* ----------------
100102
*extract necessary information from index scan node
101103
* ----------------
@@ -151,8 +153,26 @@ IndexNext(IndexScan *node)
151153
*appropriate heap tuple.. else return NULL.
152154
* ----------------
153155
*/
154-
while (indexstate->iss_IndexPtr<numIndices)
155-
{
156+
bBackward=ScanDirectionIsBackward(direction);
157+
if (bBackward)
158+
{
159+
indexNumber=numIndices-indexstate->iss_IndexPtr-1;
160+
if (indexNumber<0)
161+
{
162+
indexNumber=0;
163+
indexstate->iss_IndexPtr=numIndices-1;
164+
}
165+
}
166+
else
167+
{
168+
if ((indexNumber=indexstate->iss_IndexPtr)<0)
169+
{
170+
indexNumber=0;
171+
indexstate->iss_IndexPtr=0;
172+
}
173+
}
174+
while (indexNumber<numIndices)
175+
{
156176
scandesc=scanDescs[indexstate->iss_IndexPtr];
157177
while ((result=index_getnext(scandesc,direction))!=NULL)
158178
{
@@ -204,8 +224,14 @@ IndexNext(IndexScan *node)
204224
if (BufferIsValid(buffer))
205225
ReleaseBuffer(buffer);
206226
}
207-
if (indexstate->iss_IndexPtr<numIndices)
208-
indexstate->iss_IndexPtr++;
227+
if (indexNumber<numIndices)
228+
{
229+
indexNumber++;
230+
if (bBackward)
231+
indexstate->iss_IndexPtr--;
232+
else
233+
indexstate->iss_IndexPtr++;
234+
}
209235
}
210236
/* ----------------
211237
*if we get here it means the index scan failed so we
@@ -294,7 +320,7 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
294320
runtimeKeyInfo= (Pointer*)indexstate->iss_RuntimeKeyInfo;
295321
indxqual=node->indxqual;
296322
numScanKeys=indexstate->iss_NumScanKeys;
297-
indexstate->iss_IndexPtr=0;
323+
indexstate->iss_IndexPtr=-1;
298324

299325
/* If this is re-scanning of PlanQual ... */
300326
if (estate->es_evTuple!=NULL&&
@@ -611,7 +637,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
611637
*/
612638
indexstate=makeNode(IndexScanState);
613639
indexstate->iss_NumIndices=0;
614-
indexstate->iss_IndexPtr=0;
640+
indexstate->iss_IndexPtr=-1;
615641
indexstate->iss_ScanKeys=NULL;
616642
indexstate->iss_NumScanKeys=NULL;
617643
indexstate->iss_RuntimeKeyInfo=NULL;
@@ -635,7 +661,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
635661
indxid=node->indxid;
636662
indxqual=node->indxqual;
637663
numIndices=length(indxid);
638-
indexPtr=0;
664+
indexPtr=-1;
639665

640666
CXT1_printf("ExecInitIndexScan: context is %d\n",CurrentMemoryContext);
641667

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp