From 7df721af0ee61fa94eb973c52b9b1bff9bc45300 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 23 Dec 2000 18:49:41 +0000
Subject: [PATCH] Compute reasonable cost and output-row-count estimates for
 LIMIT plan nodes.

---
 src/backend/optimizer/plan/createplan.c | 45 ++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index bfb97bc1eb5..f872ca3fdda 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.101 2000/11/16 22:30:24 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.102 2000/12/23 18:49:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1733,6 +1733,49 @@ make_limit(List *tlist, Plan *lefttree,
 
 	copy_plan_costsize(plan, lefttree);
 
+	/*
+	 * If offset/count are constants, adjust the output rows count and costs
+	 * accordingly.  This is only a cosmetic issue if we are at top level,
+	 * but if we are building a subquery then it's important to report
+	 * correct info to the outer planner.
+	 */
+	if (limitOffset && IsA(limitOffset, Const))
+	{
+		Const	   *limito = (Const *) limitOffset;
+		int32		offset = DatumGetInt32(limito->constvalue);
+
+		if (!limito->constisnull && offset > 0)
+		{
+			if (offset > plan->plan_rows)
+				offset = (int32) plan->plan_rows;
+			if (plan->plan_rows > 0)
+				plan->startup_cost +=
+					(plan->total_cost - plan->startup_cost)
+					* ((double) offset) / plan->plan_rows;
+			plan->plan_rows -= offset;
+			if (plan->plan_rows < 1)
+				plan->plan_rows = 1;
+		}
+	}
+	if (limitCount && IsA(limitCount, Const))
+	{
+		Const	   *limitc = (Const *) limitCount;
+		int32		count = DatumGetInt32(limitc->constvalue);
+
+		if (!limitc->constisnull && count >= 0)
+		{
+			if (count > plan->plan_rows)
+				count = (int32) plan->plan_rows;
+			if (plan->plan_rows > 0)
+				plan->total_cost = plan->startup_cost +
+					(plan->total_cost - plan->startup_cost)
+					* ((double) count) / plan->plan_rows;
+			plan->plan_rows = count;
+			if (plan->plan_rows < 1)
+				plan->plan_rows = 1;
+		}
+	}
+
 	plan->state = (EState *) NULL;
 	plan->targetlist = tlist;
 	plan->qual = NIL;
-- 
GitLab