*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.45 2000/01/26 05:56:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.46 2000/02/05 23:19:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (estate->es_evTuple != NULL &&
estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
{
- int iptr;
+ List *qual;
ExecClearTuple(slot);
if (estate->es_evTupleNull[node->scan.scanrelid - 1])
slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
slot->ttc_shouldFree = false;
- for (iptr = 0; iptr < numIndices; iptr++)
+ scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
+
+ /* Does the tuple meet any of the OR'd indxqual conditions? */
+ foreach(qual, node->indxqualorig)
{
- scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
- if (ExecQual(nth(iptr, node->indxqualorig),
+ if (ExecQual((List *) lfirst(qual),
scanstate->cstate.cs_ExprContext,
false))
break;
}
- if (iptr == numIndices) /* would not be returned by indices */
+ if (qual == NIL) /* would not be returned by indices */
slot->val = NULL;
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[node->scan.scanrelid - 1] = true;
- return (slot);
+
+ return slot;
}
tuple = &(indexstate->iss_htup);
{
bool prev_matches = false;
int prev_index;
+ List *qual;
- /* ----------------
+ /*
* store the scanned tuple in the scan tuple slot of
* the scan state. Eventually we will only do this and not
* return a tuple. Note: we pass 'false' because tuples
* returned by amgetnext are pointers onto disk pages and
* must not be pfree()'d.
- * ----------------
*/
ExecStoreTuple(tuple, /* tuple to store */
slot, /* slot to store in */
ReleaseBuffer(buffer);
/*
- * We must check to see if the current tuple would have
- * been matched by an earlier index, so we don't double
- * report it. We do this by passing the tuple through
- * ExecQual and look for failure with all previous
- * qualifications.
+ * We must check to see if the current tuple was already
+ * matched by an earlier index, so we don't double-report it.
+ * We do this by passing the tuple through ExecQual and
+ * checking for failure with all previous qualifications.
*/
+ scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
+ qual = node->indxqualorig;
for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
prev_index++)
{
- scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
- if (ExecQual(nth(prev_index, node->indxqualorig),
+ if (ExecQual((List *) lfirst(qual),
scanstate->cstate.cs_ExprContext,
false))
{
prev_matches = true;
break;
}
+ qual = lnext(qual);
}
if (!prev_matches)
- return slot;
- else
- ExecClearTuple(slot);
+ return slot; /* OK to return tuple */
+ /* Duplicate tuple, so drop it and loop back for another */
+ ExecClearTuple(slot);
}
}
if (indexNumber < numIndices)
scanDescs = indexstate->iss_ScanDescs;
scanKeys = indexstate->iss_ScanKeys;
runtimeKeyInfo = (Pointer *) indexstate->iss_RuntimeKeyInfo;
- indxqual = node->indxqual;
numScanKeys = indexstate->iss_NumScanKeys;
indexstate->iss_IndexPtr = -1;
if (ScanDirectionIsBackward(node->indxorderdir))
/*
* get the index qualifications and recalculate the appropriate values
*/
+ indxqual = node->indxqual;
for (i = 0; i < numIndices; i++)
{
- qual = nth(i, indxqual);
+ qual = lfirst(indxqual);
+ indxqual = lnext(indxqual);
n_keys = numScanKeys[i];
scan_keys = (ScanKey) scanKeys[i];
* ----------------
*/
indxid = node->indxid;
- indxqual = node->indxqual;
numIndices = length(indxid);
indexPtr = -1;
* build the index scan keys from the index qualification
* ----------------
*/
+ indxqual = node->indxqual;
for (i = 0; i < numIndices; i++)
{
int j;
ScanKey scan_keys;
int *run_keys;
- qual = nth(i, indxqual);
+ qual = lfirst(indxqual);
+ indxqual = lnext(indxqual);
n_keys = length(qual);
scan_keys = (n_keys <= 0) ? NULL :
(ScanKey) palloc(n_keys * sizeof(ScanKeyData));
clause = nth(j, qual);
op = (Oper *) clause->oper;
- if (!IsA(op, Oper))
- elog(ERROR, "ExecInitIndexScan: op not an Oper!");
+ if (!IsA(clause, Expr) || !IsA(op, Oper))
+ elog(ERROR, "ExecInitIndexScan: indxqual not an opclause!");
opid = op->opid;
*/
for (i = 0; i < numIndices; i++)
{
- Oid indexOid;
-
- indexOid = (Oid) nthi(i, indxid);
+ Oid indexOid = (Oid) nthi(i, indxid);
if (indexOid != 0)
{