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