From 48c348f86ce09c668af7cf271757c3f156f28344 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 18 Nov 2010 11:53:49 -0500 Subject: [PATCH] Dept of second thoughts: don't try to push LIMIT below a SRF. If we have Limit->Result->Sort, the Result might be projecting a tlist that contains a set-returning function. If so, it's possible for the SRF to sometimes return zero rows, which means we could need to fetch more than N rows from the Sort in order to satisfy LIMIT N. So top-N sorting cannot be used in this scenario. --- src/backend/executor/nodeLimit.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index 5ed8664f66..c939752f37 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -23,6 +23,7 @@ #include "executor/executor.h" #include "executor/nodeLimit.h" +#include "nodes/nodeFuncs.h" static void recompute_limits(LimitState *node); static void pass_down_bound(LimitState *node, PlanState *child_node); @@ -344,7 +345,19 @@ pass_down_bound(LimitState *node, PlanState *child_node) } else if (IsA(child_node, ResultState)) { - if (outerPlanState(child_node)) + /* + * An extra consideration here is that if the Result is projecting + * a targetlist that contains any SRFs, we can't assume that every + * input tuple generates an output tuple, so a Sort underneath + * might need to return more than N tuples to satisfy LIMIT N. + * So we cannot use bounded sort. + * + * If Result supported qual checking, we'd have to punt on seeing + * a qual, too. Note that having a resconstantqual is not a + * showstopper: if that fails we're not getting any rows at all. + */ + if (outerPlanState(child_node) && + !expression_returns_set((Node *) child_node->plan->targetlist)) pass_down_bound(node, outerPlanState(child_node)); } } -- 2.11.0