Repair problems with EvalPlanQual where target table is scanned as
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 11 Feb 2002 20:10:50 +0000 (20:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 5afee29f5271130d2ffdd33d293ac2298b2994e6..bde5bce334dbc9b1d2aa66379a1ef79bef3fd795 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.65 2001/11/12 17:18:06 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.66 2002/02/11 20:10:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 fb2e3d53d37920891a5ae0990e4af5d630cf6cc7..08685571cab4acc4863db757e637f285af50f945 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.21 2001/10/28 06:25:43 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.22 2002/02/11 20:10:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);