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

Lines changed: 8 additions & 2 deletions
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

Lines changed: 40 additions & 26 deletions
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

Lines changed: 7 additions & 4 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.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

Lines changed: 31 additions & 6 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.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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy