Repair problems with EvalPlanQual where target table is scanned as
authorTom Lane <[email protected]>
Mon, 11 Feb 2002 20:10:50 +0000 (20:10 +0000)
committerTom Lane <[email protected]>
Mon, 11 Feb 2002 20:10:50 +0000 (20:10 +0000)
inner indexscan (ie, one with runtime keys).  ExecIndexReScan must
compute or recompute runtime keys even if we are rescanning in the
EPQ case.  TidScan seems to have comparable problems.  Per bug
noted by Barry Lind 11-Feb-02.

src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeTidscan.c

index 50c0003ac9a0768bfed28fd09c4db8d9e7b332b7..ba41d229c3e8d7fde32cf425c5355c6ffd7b4732 100644 (file)
@@ -301,24 +301,13 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
        IndexScanState *indexstate;
        ExprContext *econtext;
        ScanDirection direction;
+       int                     numIndices;
        IndexScanDescPtr scanDescs;
        ScanKey    *scanKeys;
-       IndexScanDesc scan;
-       ScanKey         skey;
-       int                     numIndices;
-       int                     i;
        int               **runtimeKeyInfo;
        int                *numScanKeys;
-       List       *indxqual;
-       List       *qual;
-       int                     n_keys;
-       ScanKey         scan_keys;
-       int                *run_keys;
+       int                     i;
        int                     j;
-       Expr       *clause;
-       Node       *scanexpr;
-       Datum           scanvalue;
-       bool            isNull;
 
        estate = node->scan.plan.state;
        indexstate = node->indxstate;
@@ -330,10 +319,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
        scanKeys = indexstate->iss_ScanKeys;
        runtimeKeyInfo = indexstate->iss_RuntimeKeyInfo;
        numScanKeys = indexstate->iss_NumScanKeys;
-       if (ScanDirectionIsBackward(node->indxorderdir))
-               indexstate->iss_IndexPtr = numIndices;
-       else
-               indexstate->iss_IndexPtr = -1;
 
        if (econtext)
        {
@@ -359,28 +344,27 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
                ResetExprContext(econtext);
        }
 
-       /* If this is re-scanning of PlanQual ... */
-       if (estate->es_evTuple != NULL &&
-               estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
-       {
-               estate->es_evTupleNull[node->scan.scanrelid - 1] = false;
-               return;
-       }
-
        /*
-        * get the index qualifications and recalculate the appropriate values
+        * If we are doing runtime key calculations (ie, the index keys depend
+        * on data from an outer scan), compute the new key values
         */
-       indxqual = node->indxqual;
-       for (i = 0; i < numIndices; i++)
+       if (runtimeKeyInfo)
        {
-               qual = lfirst(indxqual);
-               indxqual = lnext(indxqual);
-               n_keys = numScanKeys[i];
-               scan_keys = (ScanKey) scanKeys[i];
+               List       *indxqual;
 
-               if (runtimeKeyInfo)
+               indxqual = node->indxqual;
+               for (i = 0; i < numIndices; i++)
                {
+                       List       *qual = lfirst(indxqual);
+                       int                     n_keys;
+                       ScanKey         scan_keys;
+                       int                *run_keys;
+
+                       indxqual = lnext(indxqual);
+                       n_keys = numScanKeys[i];
+                       scan_keys = scanKeys[i];
                        run_keys = runtimeKeyInfo[i];
+
                        for (j = 0; j < n_keys; j++)
                        {
                                /*
@@ -398,7 +382,11 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
                                 */
                                if (run_keys[j] != NO_OP)
                                {
-                                       clause = nth(j, qual);
+                                       Expr       *clause = nth(j, qual);
+                                       Node       *scanexpr;
+                                       Datum           scanvalue;
+                                       bool            isNull;
+
                                        scanexpr = (run_keys[j] == RIGHT_OP) ?
                                                (Node *) get_rightop(clause) :
                                                (Node *) get_leftop(clause);
@@ -415,13 +403,31 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
                                }
                        }
                }
-               scan = scanDescs[i];
-               skey = scanKeys[i];
-               index_rescan(scan, direction, skey);
-       }
 
-       if (runtimeKeyInfo)
                indexstate->iss_RuntimeKeysReady = true;
+       }
+
+       /* If this is re-scanning of PlanQual ... */
+       if (estate->es_evTuple != NULL &&
+               estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
+       {
+               estate->es_evTupleNull[node->scan.scanrelid - 1] = false;
+               return;
+       }
+
+       /* reset index scans */
+       if (ScanDirectionIsBackward(node->indxorderdir))
+               indexstate->iss_IndexPtr = numIndices;
+       else
+               indexstate->iss_IndexPtr = -1;
+
+       for (i = 0; i < numIndices; i++)
+       {
+               IndexScanDesc scan = scanDescs[i];
+               ScanKey         skey = scanKeys[i];
+
+               index_rescan(scan, direction, skey);
+       }
 }
 
 /* ----------------------------------------------------------------
index 32d6f3016f582a175023125b06bcd050639b3ade..267e609624b3965e658257f7acaf70ca30eb4db9 100644 (file)
@@ -108,6 +108,11 @@ TidNext(TidScan *node)
                if (estate->es_evTupleNull[node->scan.scanrelid - 1])
                        return slot;            /* return empty slot */
 
+               /*
+                * XXX shouldn't we check here to make sure tuple matches TID list?
+                * In runtime-key case this is not certain, is it?
+                */
+
                ExecStoreTuple(estate->es_evTuple[node->scan.scanrelid - 1],
                                           slot, InvalidBuffer, false);
 
@@ -250,9 +255,8 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
        TidScanState *tidstate;
        ItemPointerData *tidList;
 
-       tidstate = node->tidstate;
        estate = node->scan.plan.state;
-       tidstate->tss_TidPtr = -1;
+       tidstate = node->tidstate;
        tidList = tidstate->tss_TidList;
 
        /* If we are being passed an outer tuple, save it for runtime key calc */
@@ -260,6 +264,13 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
                node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
                        exprCtxt->ecxt_outertuple;
 
+       /* do runtime calc of target TIDs, if needed */
+       if (node->needRescan)
+               tidstate->tss_NumTids =
+                       TidListCreate(node->tideval,
+                                                 node->scan.scanstate->cstate.cs_ExprContext,
+                                                 tidList);
+
        /* If this is re-scanning of PlanQual ... */
        if (estate->es_evTuple != NULL &&
                estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
@@ -268,9 +279,7 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
                return;
        }
 
-       tidstate->tss_NumTids = TidListCreate(node->tideval,
-                                                        node->scan.scanstate->cstate.cs_ExprContext,
-                                                                                 tidList);
+       tidstate->tss_TidPtr = -1;
 
        /*
         * perhaps return something meaningful
@@ -432,7 +441,9 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent)
        tidList = (ItemPointerData *) palloc(length(node->tideval) * sizeof(ItemPointerData));
        numTids = 0;
        if (!node->needRescan)
-               numTids = TidListCreate(node->tideval, scanstate->cstate.cs_ExprContext, tidList);
+               numTids = TidListCreate(node->tideval,
+                                                               scanstate->cstate.cs_ExprContext,
+                                                               tidList);
        tidPtr = -1;
 
        CXT1_printf("ExecInitTidScan: context is %d\n", CurrentMemoryContext);