summaryrefslogtreecommitdiff
path: root/src/backend/access/nbtree/nbtutils.c
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1997-03-18 18:41:37 +0000
committerMarc G. Fournier <scrappy@hub.org>1997-03-18 18:41:37 +0000
commitd1463050658950afd25ef2457182a498b6b3a6b4 (patch)
tree76ad055d2f01e42f7b3ec88f6ec5f788dee67143 /src/backend/access/nbtree/nbtutils.c
parentc3d637ac3a79fa899cccada4c4ce185697245015 (diff)
downloadpostgresql-d1463050658950afd25ef2457182a498b6b3a6b4.tar.gz
Patches for Vadim's multikey indexing...
Diffstat (limited to 'src/backend/access/nbtree/nbtutils.c')
-rw-r--r--src/backend/access/nbtree/nbtutils.c252
1 files changed, 142 insertions, 110 deletions
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 703acd62fa..6d0a40ef13 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.7 1996/11/05 10:35:38 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.8 1997/03/18 18:38:46 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -80,7 +80,7 @@ _bt_freestack(BTStack stack)
* more than one qual clauses using this index.
*/
void
-_bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key, uint16 *qual_ok)
+_bt_orderkeys(Relation relation, BTScanOpaque so)
{
ScanKey xform;
ScanKeyData *cur;
@@ -89,42 +89,137 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key, uint16 *qual
long test;
int i, j;
int init[BTMaxStrategyNumber+1];
+ ScanKey key;
+ uint16 numberOfKeys, new_numberOfKeys = 0;
+ AttrNumber attno = 1;
- /* haven't looked at any strategies yet */
- for (i = 0; i <= BTMaxStrategyNumber; i++)
- init[i] = 0;
+ numberOfKeys = so->numberOfKeys;
+ key = so->keyData;
+
+ if ( numberOfKeys <= 1 )
+ return;
/* get space for the modified array of keys */
nbytes = BTMaxStrategyNumber * sizeof(ScanKeyData);
xform = (ScanKey) palloc(nbytes);
- memset(xform, 0, nbytes);
-
- /* get the strategy map for this index/attribute pair */
- /*
- * XXX
- * When we support multiple keys in a single index, this is what
- * we'll want to do. At present, the planner is hosed, so we
- * hard-wire the attribute number below. Postgres only does single-
- * key indices...
- * map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- * BTMaxStrategyNumber,
- * key->data[0].attributeNumber);
- */
+ cur = &key[0];
+ if ( cur->sk_attno != 1 )
+ elog (WARN, "_bt_orderkeys: key(s) for attribute 1 missed");
+
+ memset(xform, 0, nbytes);
map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
BTMaxStrategyNumber,
- 1 /* XXX */ );
+ attno);
+ for (j = 0; j <= BTMaxStrategyNumber; j++)
+ init[j] = 0;
/* check each key passed in */
- for (i = *numberOfKeys; --i >= 0; ) {
- cur = &key[i];
- for (j = BTMaxStrategyNumber; --j >= 0; ) {
+ for (i = 0; ; )
+ {
+ if ( i < numberOfKeys )
+ cur = &key[i];
+ if ( i == numberOfKeys || cur->sk_attno != attno )
+ {
+ if ( cur->sk_attno != attno + 1 && i < numberOfKeys )
+ {
+ elog (WARN, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
+ }
+ /*
+ * If = has been specified, no other key will be used.
+ * In case of key < 2 && key == 1 and so on
+ * we have to set qual_ok to 0
+ */
+ if (init[BTEqualStrategyNumber - 1])
+ {
+ ScanKeyData *eq, *chk;
+
+ eq = &xform[BTEqualStrategyNumber - 1];
+ for (j = BTMaxStrategyNumber; --j >= 0; )
+ {
+ if ( j == (BTEqualStrategyNumber - 1) || init[j] == 0 )
+ continue;
+ chk = &xform[j];
+ test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
+ if (!test)
+ so->qual_ok = 0;
+ }
+ init[BTLessStrategyNumber - 1] = 0;
+ init[BTLessEqualStrategyNumber - 1] = 0;
+ init[BTGreaterEqualStrategyNumber - 1] = 0;
+ init[BTGreaterStrategyNumber - 1] = 0;
+ }
+
+ /* only one of <, <= */
+ if (init[BTLessStrategyNumber - 1]
+ && init[BTLessEqualStrategyNumber - 1])
+ {
+ ScanKeyData *lt, *le;
+
+ lt = &xform[BTLessStrategyNumber - 1];
+ le = &xform[BTLessEqualStrategyNumber - 1];
+ /*
+ * DO NOT use the cached function stuff here -- this is key
+ * ordering, happens only when the user expresses a hokey
+ * qualification, and gets executed only once, anyway. The
+ * transform maps are hard-coded, and can't be initialized
+ * in the correct way.
+ */
+ test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
+ if (test)
+ init[BTLessEqualStrategyNumber - 1] = 0;
+ else
+ init[BTLessStrategyNumber - 1] = 0;
+ }
+
+ /* only one of >, >= */
+ if (init[BTGreaterStrategyNumber - 1]
+ && init[BTGreaterEqualStrategyNumber - 1])
+ {
+ ScanKeyData *gt, *ge;
+
+ gt = &xform[BTGreaterStrategyNumber - 1];
+ ge = &xform[BTGreaterEqualStrategyNumber - 1];
+
+ /* see note above on function cache */
+ test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
+ if (test)
+ init[BTGreaterEqualStrategyNumber - 1] = 0;
+ else
+ init[BTGreaterStrategyNumber - 1] = 0;
+ }
+
+ /* okay, reorder and count */
+ for (j = BTMaxStrategyNumber; --j >= 0; )
+ if (init[j])
+ key[new_numberOfKeys++] = xform[j];
+
+ if ( attno == 1 )
+ so->numberOfFirstKeys = new_numberOfKeys;
+
+ if ( i == numberOfKeys )
+ break;
+
+ /* initialization for new attno */
+ attno = cur->sk_attno;
+ memset(xform, 0, nbytes);
+ map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
+ BTMaxStrategyNumber,
+ attno);
+ /* haven't looked at any strategies yet */
+ for (j = 0; j <= BTMaxStrategyNumber; j++)
+ init[j] = 0;
+ }
+
+ for (j = BTMaxStrategyNumber; --j >= 0; )
+ {
if (cur->sk_procedure == map->entry[j].sk_procedure)
- break;
+ break;
}
/* have we seen one of these before? */
- if (init[j]) {
+ if (init[j])
+ {
/* yup, use the appropriate value */
test =
(long) FMGR_PTR2(cur->sk_func, cur->sk_procedure,
@@ -132,97 +227,18 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key, uint16 *qual
if (test)
xform[j].sk_argument = cur->sk_argument;
else if ( j == (BTEqualStrategyNumber - 1) )
- *qual_ok = 0; /* key == a && key == b, but a != b */
- } else {
+ so->qual_ok = 0; /* key == a && key == b, but a != b */
+ } else
+ {
/* nope, use this value */
memmove(&xform[j], cur, sizeof(*cur));
-
init[j] = 1;
}
- }
-
- /* if = has been specified, no other key will be used */
- /*
- * XXX
- * But in case of key < 2 && key == 1 and so on
- * we have to set qual_ok to 0
- */
- if (init[BTEqualStrategyNumber - 1]) {
-
- ScanKeyData *eq, *chk;
-
- eq = &xform[BTEqualStrategyNumber - 1];
-
- for (j = BTMaxStrategyNumber; --j >= 0; )
- {
- if ( j == (BTEqualStrategyNumber - 1) || init[j] == 0 )
- continue;
-
- chk = &xform[j];
-
- test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
- if (!test)
- *qual_ok = 0;
- }
-
- init[BTLessStrategyNumber - 1] = 0;
- init[BTLessEqualStrategyNumber - 1] = 0;
- init[BTGreaterEqualStrategyNumber - 1] = 0;
- init[BTGreaterStrategyNumber - 1] = 0;
+ i++;
}
- /* only one of <, <= */
- if (init[BTLessStrategyNumber - 1]
- && init[BTLessEqualStrategyNumber - 1]) {
-
- ScanKeyData *lt, *le;
-
- lt = &xform[BTLessStrategyNumber - 1];
- le = &xform[BTLessEqualStrategyNumber - 1];
-
- /*
- * DO NOT use the cached function stuff here -- this is key
- * ordering, happens only when the user expresses a hokey
- * qualification, and gets executed only once, anyway. The
- * transform maps are hard-coded, and can't be initialized
- * in the correct way.
- */
-
- test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
-
- if (test)
- init[BTLessEqualStrategyNumber - 1] = 0;
- else
- init[BTLessStrategyNumber - 1] = 0;
- }
-
- /* only one of >, >= */
- if (init[BTGreaterStrategyNumber - 1]
- && init[BTGreaterEqualStrategyNumber - 1]) {
-
- ScanKeyData *gt, *ge;
-
- gt = &xform[BTGreaterStrategyNumber - 1];
- ge = &xform[BTGreaterEqualStrategyNumber - 1];
-
- /* see note above on function cache */
- test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
-
- if (test)
- init[BTGreaterEqualStrategyNumber - 1] = 0;
- else
- init[BTGreaterStrategyNumber - 1] = 0;
- }
-
- /* okay, reorder and count */
- j = 0;
-
- for (i = BTMaxStrategyNumber; --i >= 0; )
- if (init[i])
- key[j++] = xform[i];
-
- *numberOfKeys = j;
+ so->numberOfKeys = new_numberOfKeys;
pfree(xform);
}
@@ -230,9 +246,25 @@ _bt_orderkeys(Relation relation, uint16 *numberOfKeys, ScanKey key, uint16 *qual
bool
_bt_checkqual(IndexScanDesc scan, IndexTuple itup)
{
- if (scan->numberOfKeys > 0)
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+ if (so->numberOfKeys > 0)
+ return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
+ so->numberOfKeys, so->keyData));
+ else
+ return (true);
+}
+
+bool
+_bt_checkforkeys(IndexScanDesc scan, IndexTuple itup, Size keysz)
+{
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+ if ( keysz > 0 && so->numberOfKeys >= keysz )
return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
- scan->numberOfKeys, scan->keyData));
+ keysz, so->keyData));
else
return (true);
}