Обсуждение: OR clause - check code

Поиск
Список
Период
Сортировка

OR clause - check code

От
Bruce Momjian
Дата:
Vadim, would you please review this code, and let me know if it is
correct.  I am unsure about the calls to ExecStoreTuple(), ExecQual()
(is proper context used?), and placement of ReleaseBuffer().  Do I need
to free the tuple buffer if I decide it doesn't meet my ExecQual test?

You will see the old code, then the new for IndexNext().

---------------------------------------------------------------------------


***************
*** 120,155 ****
     *  appropriate heap tuple.. else return NULL.
     * ----------------
     */
!   while ((result = index_getnext(scandesc, direction)) != NULL)
    {
!       tuple = heap_fetch(heapRelation, false, &result->heap_iptr, &buffer);
!       /* be tidy */
!       pfree(result);
!
!       if (tuple != NULL)
        {
!           /* ----------------
!            *  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
!            *  were not created with palloc() and so should not be pfree()'d.
!            * ----------------
!            */
!           ExecStoreTuple(tuple,       /* tuple to store */
!                           slot,       /* slot to store in */
!                           buffer,     /* buffer associated with tuple  */
!                           false);     /* don't pfree */
!
!           return slot;
!       }
!       else
!       {
            if (BufferIsValid(buffer))
                ReleaseBuffer(buffer);
        }
    }
-
    /* ----------------
     *  if we get here it means the index scan failed so we
     *  are at the end of the scan..
--- 119,170 ----
     *  appropriate heap tuple.. else return NULL.
     * ----------------
     */
!   while (indexstate->iss_IndexPtr < numIndices)
    {
!       scandesc = scanDescs[indexstate->iss_IndexPtr];
!       while ((result = index_getnext(scandesc, direction)) != NULL)
        {
!           tuple = heap_fetch(heapRelation, false, &result->heap_iptr, &buffer);
!           /* be tidy */
!           pfree(result);
!
!           if (tuple != NULL)
!           {
!               bool        prev_matches = false;
!               int         prev_index;
!
!               /* ----------------
!                *  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
!                *  were not created with palloc() and so should not be pfree()'d.
!                * ----------------
!                */
!               ExecStoreTuple(tuple,       /* tuple to store */
!                               slot,       /* slot to store in */
!                               buffer,     /* buffer associated with tuple  */
!                               false);     /* don't pfree */
!
!               for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
!                                                               prev_index++)
!               {
!                   if (ExecQual(nth(prev_index, node->indxqual),
!                       scanstate->cstate.cs_ExprContext))
!                   {
!                       prev_matches = true;
!                       break;
!                   }
!               }
!               if (!prev_matches)
!                   return slot;
!           }
            if (BufferIsValid(buffer))
                ReleaseBuffer(buffer);
        }
+       if (indexstate->iss_IndexPtr < numIndices)
+           indexstate->iss_IndexPtr++;
    }
    /* ----------------
     *  if we get here it means the index scan failed so we
     *  are at the end of the scan..

--
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)

Re: [HACKERS] OR clause - check code

От
Vadim Mikheev
Дата:
Bruce Momjian wrote:
>
> Vadim, would you please review this code, and let me know if it is
> correct.  I am unsure about the calls to ExecStoreTuple(), ExecQual()
> (is proper context used?), and placement of ReleaseBuffer().  Do I need
   ^^^^^^^^^^^^^^^^^^^^^^
Yes.
execScan.c:ExecScan() sets econtext->ecxt_scantuple = slot <--
returned by Seq/Index scan -- before check Scan qual and
so econtext->ecxt_scantuple already points to the slot where
you store new tuple. It seems that no one change this pointer...

But did you try to use multi-index scan in inner plan of
Nestloop? It seems that you should add this to ExecIndexReScan():

if (exprCtxt != NULL)
    node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
        exprCtxt->ecxt_outertuple;

Also, ExecIndexReScan() evaluates run-time keys for _current_
index scan only - this must be changed and indexstate->iss_IndexPtr
must be setted to 0.

> to free the tuple buffer if I decide it doesn't meet my ExecQual test?

Yes, you have to free buffer.

Vadim

Re: [HACKERS] OR clause - check code

От
Bruce Momjian
Дата:
> Bruce Momjian wrote:
> >
> > Vadim, would you please review this code, and let me know if it is
> > correct.  I am unsure about the calls to ExecStoreTuple(), ExecQual()
> > (is proper context used?), and placement of ReleaseBuffer().  Do I need
>    ^^^^^^^^^^^^^^^^^^^^^^
> Yes.
> execScan.c:ExecScan() sets econtext->ecxt_scantuple = slot <--
> returned by Seq/Index scan -- before check Scan qual and
> so econtext->ecxt_scantuple already points to the slot where
> you store new tuple. It seems that no one change this pointer...
>
> But did you try to use multi-index scan in inner plan of
> Nestloop? It seems that you should add this to ExecIndexReScan():

No.  I just don't understand the behavior of the various join types on
index use.

>
> if (exprCtxt != NULL)
>     node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
>         exprCtxt->ecxt_outertuple;

Added.

>
> Also, ExecIndexReScan() evaluates run-time keys for _current_
> index scan only - this must be changed and indexstate->iss_IndexPtr
> must be setted to 0.

I have added this to the code.

> > to free the tuple buffer if I decide it doesn't meet my ExecQual test?
>
> Yes, you have to free buffer.

Done.

Vadim, I am going to send you the current nodeIndexscan.c for your
review, to make sure I made the proper changes.

--
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)