Thank you for looking at it
On Mon, Apr 1, 2019 at 12:34 AM Andres Freund <and...@anarazel.de> wrote:

> Hi,
>
> On 2019-03-29 12:04:50 +0300, Surafel Temesgen wrote:
>
> > +                             if (node->limitOption == PERCENTAGE)
> > +                             {
> > +                                     while (node->position -
> node->offset < node->count)
> > +                                     {
> > +                                             slot =
> MakeSingleTupleTableSlot(tupleDescriptor, &TTSOpsMinimalTuple);
> > +                                             if
> (tuplestore_gettupleslot(node->tupleStore, true, true, slot))
>
> There's several blocks like this - how's this not going to be a resource
> leak? As far as I can tell you're just going to create new slots, and
> their previous contents aren't going to be cleared?   I think there very
> rarely are cases where an executor node's *Next function (or its
> subsidiaries) creates slots. Normally you ought to create them *once* on
> the *Init function.
>
>
create it in init stage is good idea. i make it this way because
tuplestore_gettupleslot
work with TTSOpsMinimalTuple


> You might not directly leak memory, because this is probably running in
> a short lived context, but you'll leak tuple desc references etc. (Or if
> it were a heap buffer slot, buffer pins).
>
>
> > +                     /* In PERCENTAGE case the result is already in
> tuplestore */
> > +                     if (node->limitOption == PERCENTAGE)
> > +                     {
> > +                             slot =
> MakeSingleTupleTableSlot(tupleDescriptor, &TTSOpsMinimalTuple);
> > +                             if
> (tuplestore_gettupleslot(node->tupleStore, false, false, slot))
> > +                             {
> > +                                     node->subSlot = slot;
> > +                                     node->lstate = LIMIT_INWINDOW;
> > +                             }
> > +                             else
> > +                                     elog(ERROR, "LIMIT subplan failed
> to run backwards");
> > +                     }
> > +                     else if (node->limitOption == EXACT_NUMBER)
> > +                     {
> >                       /*
> >                        * Backing up from subplan EOF, so re-fetch
> previous tuple; there
> >                        * should be one!  Note previous tuple must be in
> window.
> > @@ -194,6 +329,7 @@ ExecLimit(PlanState *pstate)
> >                       node->subSlot = slot;
> >                       node->lstate = LIMIT_INWINDOW;
> >                       /* position does not change 'cause we didn't
> advance it before */
> > +                     }
>
> The indentation here looks wrong...
>
> >                       break;
> >
> >               case LIMIT_WINDOWEND:
> > @@ -278,17 +414,29 @@ recompute_limits(LimitState *node)
> >               /* Interpret NULL count as no count (LIMIT ALL) */
> >               if (isNull)
> >               {
> > -                     node->count = 0;
> > +                     node->count = 1;
> >                       node->noCount = true;
>
> Huh?
>
>
> >               }
> >               else
> >               {
> > -                     node->count = DatumGetInt64(val);
> > -                     if (node->count < 0)
> > -                             ereport(ERROR,
> > -
>  (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE),
> > -                                              errmsg("LIMIT must not be
> negative")));
> > -                     node->noCount = false;
> > +                     if (node->limitOption == PERCENTAGE)
> > +                     {
> > +                             /*
> > +                              * We expect to return at least one row
> (unless there
> > +                              * are no rows in the subplan), and we'll
> update this
> > +                              * count later as we go.
> > +                              */
> > +                             node->count = 0;
> > +                             node->percent = DatumGetFloat8(val);
> > +                     }
> > +                     else
> > +                     {
> > +                             node->count = DatumGetInt64(val);
> > +                             if (node->count < 0)
> > +                                     ereport(ERROR,
> > +
>  (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE),
> > +                                                      errmsg("LIMIT
> must not be negative")));
> > +                     }
>
> Shouldn't we error out with a negative count, regardless of PERCENT? Or
> is that prevented elsewhere?
>

yes it should error out .will fix it in next patch


> >               }
> >       }
> >       else
> > @@ -299,8 +447,10 @@ recompute_limits(LimitState *node)
> >       }
> >
> >       /* Reset position to start-of-scan */
> > -     node->position = 0;
> > +     node->position = 0;;
>
> unnecessary
>
>
> >       if (parse->sortClause)
> >       {
> > -             current_rel = create_ordered_paths(root,
> > -
>         current_rel,
> > -
>         final_target,
> > -
>         final_target_parallel_safe,
> > -
>         have_postponed_srfs ? -1.0 :
> > -
>         limit_tuples);
> > +
> > +             /* In PERCENTAGE option there are no bound on the number
> of output tuples */
> > +             if (parse->limitOption == PERCENTAGE)
> > +                     current_rel = create_ordered_paths(root,
> > +
>                 current_rel,
> > +
>                 final_target,
> > +
>                 final_target_parallel_safe,
> > +
>                 have_postponed_srfs ? -1.0 :
> > +
>                 -1.0);
> > +             else
> > +                     current_rel = create_ordered_paths(root,
> > +
>                 current_rel,
> > +
>                 final_target,
> > +
>                 final_target_parallel_safe,
> > +
>                 have_postponed_srfs ? -1.0 :
> > +
>                 limit_tuples);
>
> I'd rather not duplicate those two calls, and just have the limit_tuples
> computation inside an if.
>
>
-1.0 means there are no limit. In percentage case the query execute until
the end


> >  offset_clause:
> > @@ -15435,6 +15442,7 @@ reserved_keyword:
> >                       | ONLY
> >                       | OR
> >                       | ORDER
> > +                     | PERCENT
> >                       | PLACING
> >                       | PRIMARY
> >                       | REFERENCES
>
> Are we really ok with adding a new reserved keyword 'PERCENT' for this?
> That seems awfully likely to already exist in columns etc. Is there a
> chance we can use a less strong category?
>
>
There are already a case in regression test. I will make it unreserved
keyword in
next patch

regards
Surafel

Reply via email to