Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 74cdf92

Browse files
committed
Fixes:
> INDEXED searches in some cases DO NOT WORK. > Although simple search expressions (i.e. with a constant value on > the right side of an operator) work, performing a join (by putting > a field of some other table on the right side of an operator) produces > empty output. > WITHOUT indices, everything works fine. > submitted by: "Vadim B. Mikheev" <root@ais.sable.krasnoyarsk.su>
1 parent e5e12f6 commit 74cdf92

File tree

4 files changed

+86
-38
lines changed

4 files changed

+86
-38
lines changed

src/backend/access/nbtree.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: nbtree.h,v 1.1.1.1 1996/07/09 06:21:08 scrappy Exp $
9+
* $Id: nbtree.h,v 1.2 1996/07/30 07:55:10 scrappy Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -60,11 +60,17 @@ typedef BTPageOpaqueData *BTPageOpaque;
6060
* and recorded in the opaque entry of the scan in order to avoid
6161
* doing a ReadBuffer() for every tuple in the index. This avoids
6262
* semop() calls, which are expensive.
63+
*
64+
* And it's used to remember actual scankey info (we need in it
65+
* if some scankeys evaled at runtime.
6366
*/
6467

6568
typedef struct BTScanOpaqueData {
6669
Buffer btso_curbuf;
6770
Buffer btso_mrkbuf;
71+
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
72+
uint16 numberOfKeys; /* number of key attributes */
73+
ScanKey keyData; /* key descriptor */
6874
} BTScanOpaqueData;
6975

7076
typedef BTScanOpaqueData *BTScanOpaque;
@@ -248,7 +254,7 @@ extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup);
248254
extern void _bt_freeskey(ScanKey skey);
249255
extern void _bt_freestack(BTStack stack);
250256
extern void _bt_orderkeys(Relation relation, uint16 *numberOfKeys,
251-
ScanKey key);
257+
ScanKey key, uint16 *qual_ok);
252258
extern bool _bt_checkqual(IndexScanDesc scan, IndexTuple itup);
253259
extern BTItem _bt_formitem(IndexTuple itup);
254260

src/backend/access/nbtree/nbtree.c

+40-26
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.1.1.1 1996/07/09 06:21:12 scrappy Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.2 1996/07/30 07:56:00 scrappy Exp $
1212
*
1313
* NOTES
1414
* This file contains only the public interface routines.
@@ -330,32 +330,9 @@ char *
330330
btbeginscan(Relation rel, bool fromEnd, uint16 keysz, ScanKey scankey)
331331
{
332332
IndexScanDesc scan;
333-
StrategyNumber strat;
334-
BTScanOpaque so;
335333

336-
/* first order the keys in the qualification */
337-
if (keysz > 1)
338-
_bt_orderkeys(rel, &keysz, scankey);
339-
340-
/* now get the scan */
334+
/* get the scan */
341335
scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
342-
so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
343-
so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
344-
scan->opaque = so;
345-
346-
/* finally, be sure that the scan exploits the tree order */
347-
scan->scanFromEnd = false;
348-
scan->flags = 0x0;
349-
if (keysz > 0) {
350-
strat = _bt_getstrat(scan->relation, 1 /* XXX */,
351-
scankey[0].sk_procedure);
352-
353-
if (strat == BTLessStrategyNumber
354-
|| strat == BTLessEqualStrategyNumber)
355-
scan->scanFromEnd = true;
356-
} else {
357-
scan->scanFromEnd = true;
358-
}
359336

360337
/* register scan in case we change pages it's using */
361338
_bt_regscan(scan);
@@ -371,6 +348,7 @@ btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
371348
{
372349
ItemPointer iptr;
373350
BTScanOpaque so;
351+
StrategyNumber strat;
374352

375353
so = (BTScanOpaque) scan->opaque;
376354

@@ -388,12 +366,45 @@ btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
388366
ItemPointerSetInvalid(iptr);
389367
}
390368

369+
if ( so == NULL ) /* if called from btbeginscan */
370+
{
371+
so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
372+
so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
373+
so->keyData = (ScanKey) NULL;
374+
if ( scan->numberOfKeys > 0)
375+
so->keyData = (ScanKey) palloc (scan->numberOfKeys * sizeof(ScanKeyData));
376+
scan->opaque = so;
377+
scan->flags = 0x0;
378+
}
379+
391380
/* reset the scan key */
381+
so->numberOfKeys = scan->numberOfKeys;
382+
so->qual_ok = 1; /* may be changed by _bt_orderkeys */
392383
if (scan->numberOfKeys > 0) {
393384
memmove(scan->keyData,
394385
scankey,
395386
scan->numberOfKeys * sizeof(ScanKeyData));
387+
memmove(so->keyData,
388+
scankey,
389+
so->numberOfKeys * sizeof(ScanKeyData));
390+
/* order the keys in the qualification */
391+
if (so->numberOfKeys > 1)
392+
_bt_orderkeys(scan->relation, &so->numberOfKeys, so->keyData, &so->qual_ok);
396393
}
394+
395+
/* finally, be sure that the scan exploits the tree order */
396+
scan->scanFromEnd = false;
397+
if ( so->numberOfKeys > 0 ) {
398+
strat = _bt_getstrat(scan->relation, 1 /* XXX */,
399+
so->keyData[0].sk_procedure);
400+
401+
if (strat == BTLessStrategyNumber
402+
|| strat == BTLessEqualStrategyNumber)
403+
scan->scanFromEnd = true;
404+
} else {
405+
scan->scanFromEnd = true;
406+
}
407+
397408
}
398409

399410
void
@@ -411,7 +422,8 @@ btmovescan(IndexScanDesc scan, Datum v)
411422
ItemPointerSetInvalid(iptr);
412423
}
413424

414-
scan->keyData[0].sk_argument = v;
425+
/* scan->keyData[0].sk_argument = v; */
426+
so->keyData[0].sk_argument = v;
415427
}
416428

417429
/*
@@ -445,6 +457,8 @@ btendscan(IndexScanDesc scan)
445457

446458
/* be tidy */
447459
#ifdef PERFECT_MMGR
460+
if ( so->keyData != (ScanKey) NULL )
461+
pfree (so->keyData);
448462
pfree (scan->opaque);
449463
#endif /* PERFECT_MMGR */
450464
}

src/backend/access/nbtree/nbtsearch.c

+7-4
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.1.1.1 1996/07/09 06:21:12 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.2 1996/07/30 07:56:02 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -604,14 +604,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
604604
BTScanOpaque so;
605605
ScanKeyData skdata;
606606

607+
so = (BTScanOpaque) scan->opaque;
608+
if ( so->qual_ok == 0 ) /* may be set by _bt_orderkeys */
609+
return ((RetrieveIndexResult) NULL);
610+
607611
/* if we just need to walk down one edge of the tree, do that */
608612
if (scan->scanFromEnd)
609613
return (_bt_endpoint(scan, dir));
610614

611615
rel = scan->relation;
612616
itupdesc = RelationGetTupleDescriptor(scan->relation);
613617
current = &(scan->currentItemData);
614-
so = (BTScanOpaque) scan->opaque;
615618

616619
/*
617620
* Okay, we want something more complicated. What we'll do is use
@@ -628,7 +631,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
628631
*/
629632
proc = index_getprocid(rel, 1, BTORDER_PROC);
630633
ScanKeyEntryInitialize(&skdata, 0x0, 1, proc,
631-
scan->keyData[0].sk_argument);
634+
so->keyData[0].sk_argument);
632635

633636
stack = _bt_search(rel, 1, &skdata, &buf);
634637
_bt_freestack(stack);
@@ -666,7 +669,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
666669
*/
667670

668671
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
669-
strat = _bt_getstrat(rel, 1, scan->keyData[0].sk_procedure);
672+
strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure);
670673

671674
switch (strat) {
672675
case BTLessStrategyNumber:

src/backend/access/nbtree/nbtutils.c

+31-6
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.1.1.1 1996/07/09 06:21:12 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.2 1996/07/30 07:56:04 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -82,7 +82,7 @@ _bt_freestack(BTStack stack)
8282
* more than one qual clauses using this index.
8383
*/
8484
void
85-
_bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key)
85+
_bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key, uint16 *qual_ok)
8686
{
8787
ScanKey xform;
8888
ScanKeyData *cur;
@@ -133,6 +133,8 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key)
133133
cur->sk_argument, xform[j].sk_argument);
134134
if (test)
135135
xform[j].sk_argument = cur->sk_argument;
136+
else if ( j == (BTEqualStrategyNumber - 1) )
137+
*qual_ok = 0; /* key == a && key == b, but a != b */
136138
} else {
137139
/* nope, use this value */
138140
memmove(&xform[j], cur, sizeof(*cur));
@@ -142,7 +144,30 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key)
142144
}
143145

144146
/* if = has been specified, no other key will be used */
147+
/*
148+
* XXX
149+
* But in case of key < 2 && key == 1 and so on
150+
* we have to set qual_ok to 0
151+
*/
145152
if (init[BTEqualStrategyNumber - 1]) {
153+
154+
ScanKeyData *eq, *chk;
155+
156+
eq = &xform[BTEqualStrategyNumber - 1];
157+
158+
for (j = BTMaxStrategyNumber; --j >= 0; )
159+
{
160+
if ( j == (BTEqualStrategyNumber - 1) || init[j] == 0 )
161+
continue;
162+
163+
chk = &xform[j];
164+
165+
test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
166+
167+
if (!test)
168+
*qual_ok = 0;
169+
}
170+
146171
init[BTLessStrategyNumber - 1] = 0;
147172
init[BTLessEqualStrategyNumber - 1] = 0;
148173
init[BTGreaterEqualStrategyNumber - 1] = 0;
@@ -166,7 +191,7 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key)
166191
* in the correct way.
167192
*/
168193

169-
test = (long) fmgr(le->sk_procedure, le->sk_argument, lt->sk_argument);
194+
test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
170195

171196
if (test)
172197
init[BTLessEqualStrategyNumber - 1] = 0;
@@ -184,12 +209,12 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key)
184209
ge = &xform[BTGreaterEqualStrategyNumber - 1];
185210

186211
/* see note above on function cache */
187-
test = (long) fmgr(ge->sk_procedure, gt->sk_argument, gt->sk_argument);
212+
test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
188213

189214
if (test)
190-
init[BTGreaterStrategyNumber - 1] = 0;
191-
else
192215
init[BTGreaterEqualStrategyNumber - 1] = 0;
216+
else
217+
init[BTGreaterStrategyNumber - 1] = 0;
193218
}
194219

195220
/* okay, reorder and count */

0 commit comments

Comments
 (0)