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

Commitcbca6c4

Browse files
committed
Fix for bug #866. 7.3 contains new logic for avoiding redundant calls to
the index AM when we know we are fetching a unique row. However, thislogic did not consider the possibility that it would be asked to fetchbackwards. Also fix mark/restore to work correctly in this scenario.
1 parent9270f1c commitcbca6c4

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

‎src/backend/access/index/genam.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.36 2002/09/04 20:31:09 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.37 2003/01/08 19:41:40 tgl Exp $
1212
*
1313
* NOTES
1414
* many of the old access method routines have been turned into
@@ -107,6 +107,9 @@ RelationGetIndexScan(Relation indexRelation,
107107
/* mark cached function lookup data invalid; it will be set later */
108108
scan->fn_getnext.fn_oid=InvalidOid;
109109

110+
scan->unique_tuple_pos=0;
111+
scan->unique_tuple_mark=0;
112+
110113
pgstat_initstats(&scan->xs_pgstat_info,indexRelation);
111114

112115
/*

‎src/backend/access/index/indexam.c

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.62 2002/09/04 20:31:09 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.63 2003/01/08 19:41:40 tgl Exp $
1212
*
1313
* INTERFACE ROUTINES
1414
*index_open- open an index relation by relation OID
@@ -308,6 +308,8 @@ index_rescan(IndexScanDesc scan, ScanKey key)
308308
scan->kill_prior_tuple= false;/* for safety */
309309
scan->keys_are_unique= false;/* may be set by amrescan */
310310
scan->got_tuple= false;
311+
scan->unique_tuple_pos=0;
312+
scan->unique_tuple_mark=0;
311313

312314
OidFunctionCall2(procedure,
313315
PointerGetDatum(scan),
@@ -360,6 +362,8 @@ index_markpos(IndexScanDesc scan)
360362
SCAN_CHECKS;
361363
GET_SCAN_PROCEDURE(markpos,ammarkpos);
362364

365+
scan->unique_tuple_mark=scan->unique_tuple_pos;
366+
363367
OidFunctionCall1(procedure,PointerGetDatum(scan));
364368
}
365369

@@ -376,7 +380,13 @@ index_restrpos(IndexScanDesc scan)
376380
GET_SCAN_PROCEDURE(restrpos,amrestrpos);
377381

378382
scan->kill_prior_tuple= false;/* for safety */
379-
scan->got_tuple= false;
383+
384+
/*
385+
* We do not reset got_tuple; so if the scan is actually being
386+
* short-circuited by index_getnext, the effective position restoration
387+
* is done by restoring unique_tuple_pos.
388+
*/
389+
scan->unique_tuple_pos=scan->unique_tuple_mark;
380390

381391
OidFunctionCall1(procedure,PointerGetDatum(scan));
382392
}
@@ -398,6 +408,32 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
398408

399409
SCAN_CHECKS;
400410

411+
/*
412+
* Can skip entering the index AM if we already got a tuple and it
413+
* must be unique. Instead, we need a "short circuit" path that
414+
* just keeps track of logical scan position (before/on/after tuple).
415+
*
416+
* Note that we hold the pin on the single tuple's buffer throughout
417+
* the scan once we are in this state.
418+
*/
419+
if (scan->keys_are_unique&&scan->got_tuple)
420+
{
421+
if (ScanDirectionIsForward(direction))
422+
{
423+
if (scan->unique_tuple_pos <=0)
424+
scan->unique_tuple_pos++;
425+
}
426+
elseif (ScanDirectionIsBackward(direction))
427+
{
428+
if (scan->unique_tuple_pos >=0)
429+
scan->unique_tuple_pos--;
430+
}
431+
if (scan->unique_tuple_pos==0)
432+
returnheapTuple;
433+
else
434+
returnNULL;
435+
}
436+
401437
/* Release any previously held pin */
402438
if (BufferIsValid(scan->xs_cbuf))
403439
{
@@ -408,13 +444,6 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
408444
/* just make sure this is false... */
409445
scan->kill_prior_tuple= false;
410446

411-
/*
412-
* Can skip entering the index AM if we already got a tuple and it
413-
* must be unique.
414-
*/
415-
if (scan->keys_are_unique&&scan->got_tuple)
416-
returnNULL;
417-
418447
for (;;)
419448
{
420449
boolfound;
@@ -475,6 +504,12 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
475504
/* Success exit */
476505
scan->got_tuple= true;
477506

507+
/*
508+
* If we just fetched a known-unique tuple, then subsequent calls will
509+
* go through the short-circuit code above. unique_tuple_pos has been
510+
* initialized to 0, which is the correct state ("on row").
511+
*/
512+
478513
pgstat_count_index_getnext(&scan->xs_pgstat_info);
479514

480515
returnheapTuple;

‎src/include/access/relscan.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: relscan.h,v 1.29 2002/09/04 20:31:37 momjian Exp $
10+
* $Id: relscan.h,v 1.30 2003/01/08 19:41:40 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -70,6 +70,15 @@ typedef struct IndexScanDescData
7070

7171
FmgrInfofn_getnext;/* cached lookup info for AM's getnext fn */
7272

73+
/*
74+
* If keys_are_unique and got_tuple are both true, we stop calling the
75+
* index AM; it is then necessary for index_getnext to keep track of
76+
* the logical scan position for itself. It does that using
77+
* unique_tuple_pos: -1 = before row, 0 = on row, +1 = after row.
78+
*/
79+
intunique_tuple_pos;/* logical position */
80+
intunique_tuple_mark;/* logical marked position */
81+
7382
PgStat_Infoxs_pgstat_info;/* statistics collector hook */
7483
}IndexScanDescData;
7584

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp