Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1a1832e

Browse files
committed
Avoid inserting no-op Limit plan nodes.
This was discussed in connection with the patch to avoid inserting no-opResult nodes, but not actually implemented therein.
1 parentfb60e72 commit1a1832e

File tree

2 files changed

+84
-33
lines changed

2 files changed

+84
-33
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static void preprocess_rowmarks(PlannerInfo *root);
6868
staticdoublepreprocess_limit(PlannerInfo*root,
6969
doubletuple_fraction,
7070
int64*offset_est,int64*count_est);
71+
staticboollimit_needed(Query*parse);
7172
staticvoidpreprocess_groupclause(PlannerInfo*root);
7273
staticboolchoose_hashed_grouping(PlannerInfo*root,
7374
doubletuple_fraction,doublelimit_tuples,
@@ -1825,7 +1826,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
18251826
/*
18261827
* Finally, if there is a LIMIT/OFFSET clause, add the LIMIT node.
18271828
*/
1828-
if (parse->limitCount||parse->limitOffset)
1829+
if (limit_needed(parse))
18291830
{
18301831
result_plan= (Plan*)make_limit(result_plan,
18311832
parse->limitOffset,
@@ -2296,6 +2297,60 @@ preprocess_limit(PlannerInfo *root, double tuple_fraction,
22962297
returntuple_fraction;
22972298
}
22982299

2300+
/*
2301+
* limit_needed - do we actually need a Limit plan node?
2302+
*
2303+
* If we have constant-zero OFFSET and constant-null LIMIT, we can skip adding
2304+
* a Limit node. This is worth checking for because "OFFSET 0" is a common
2305+
* locution for an optimization fence. (Because other places in the planner
2306+
* merely check whether parse->limitOffset isn't NULL, it will still work as
2307+
* an optimization fence --- we're just suppressing unnecessary run-time
2308+
* overhead.)
2309+
*
2310+
* This might look like it could be merged into preprocess_limit, but there's
2311+
* a key distinction: here we need hard constants in OFFSET/LIMIT, whereas
2312+
* in preprocess_limit it's good enough to consider estimated values.
2313+
*/
2314+
staticbool
2315+
limit_needed(Query*parse)
2316+
{
2317+
Node*node;
2318+
2319+
node=parse->limitCount;
2320+
if (node)
2321+
{
2322+
if (IsA(node,Const))
2323+
{
2324+
/* NULL indicates LIMIT ALL, ie, no limit */
2325+
if (!((Const*)node)->constisnull)
2326+
return true;/* LIMIT with a constant value */
2327+
}
2328+
else
2329+
return true;/* non-constant LIMIT */
2330+
}
2331+
2332+
node=parse->limitOffset;
2333+
if (node)
2334+
{
2335+
if (IsA(node,Const))
2336+
{
2337+
/* Treat NULL as no offset; the executor would too */
2338+
if (!((Const*)node)->constisnull)
2339+
{
2340+
int64offset=DatumGetInt64(((Const*)node)->constvalue);
2341+
2342+
/* Executor would treat less-than-zero same as zero */
2343+
if (offset>0)
2344+
return true;/* OFFSET with a positive value */
2345+
}
2346+
}
2347+
else
2348+
return true;/* non-constant OFFSET */
2349+
}
2350+
2351+
return false;/* don't need a Limit plan node */
2352+
}
2353+
22992354

23002355
/*
23012356
* preprocess_groupclause - do preparatory work on GROUP BY clause

‎src/test/regress/expected/updatable_views.out

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -542,36 +542,34 @@ SELECT * FROM rw_view2;
542542
(2 rows)
543543

544544
EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2;
545-
QUERY PLAN
546-
------------------------------------------------------------------
545+
QUERY PLAN
546+
----------------------------------------------------------------
547547
Update on base_tbl
548548
-> Nested Loop
549549
-> Index Scan using base_tbl_pkey on base_tbl
550550
Index Cond: (a = 2)
551551
-> Subquery Scan on rw_view1
552552
Filter: ((rw_view1.a < 10) AND (rw_view1.a = 2))
553-
-> Limit
554-
-> Bitmap Heap Scan on base_tbl base_tbl_1
555-
Recheck Cond: (a > 0)
556-
-> Bitmap Index Scan on base_tbl_pkey
557-
Index Cond: (a > 0)
558-
(11 rows)
553+
-> Bitmap Heap Scan on base_tbl base_tbl_1
554+
Recheck Cond: (a > 0)
555+
-> Bitmap Index Scan on base_tbl_pkey
556+
Index Cond: (a > 0)
557+
(10 rows)
559558

560559
EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2;
561-
QUERY PLAN
562-
------------------------------------------------------------------
560+
QUERY PLAN
561+
----------------------------------------------------------------
563562
Delete on base_tbl
564563
-> Nested Loop
565564
-> Index Scan using base_tbl_pkey on base_tbl
566565
Index Cond: (a = 2)
567566
-> Subquery Scan on rw_view1
568567
Filter: ((rw_view1.a < 10) AND (rw_view1.a = 2))
569-
-> Limit
570-
-> Bitmap Heap Scan on base_tbl base_tbl_1
571-
Recheck Cond: (a > 0)
572-
-> Bitmap Index Scan on base_tbl_pkey
573-
Index Cond: (a > 0)
574-
(11 rows)
568+
-> Bitmap Heap Scan on base_tbl base_tbl_1
569+
Recheck Cond: (a > 0)
570+
-> Bitmap Index Scan on base_tbl_pkey
571+
Index Cond: (a > 0)
572+
(10 rows)
575573

576574
DROP TABLE base_tbl CASCADE;
577575
NOTICE: drop cascades to 2 other objects
@@ -775,30 +773,28 @@ SELECT * FROM rw_view2;
775773
(2 rows)
776774

777775
EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2;
778-
QUERY PLAN
779-
------------------------------------------------------------
776+
QUERY PLAN
777+
----------------------------------------------------------
780778
Update on rw_view1 rw_view1_1
781779
-> Subquery Scan on rw_view1
782780
Filter: ((rw_view1.a < 10) AND (rw_view1.a = 2))
783-
-> Limit
784-
-> Bitmap Heap Scan on base_tbl
785-
Recheck Cond: (a > 0)
786-
-> Bitmap Index Scan on base_tbl_pkey
787-
Index Cond: (a > 0)
788-
(8 rows)
781+
-> Bitmap Heap Scan on base_tbl
782+
Recheck Cond: (a > 0)
783+
-> Bitmap Index Scan on base_tbl_pkey
784+
Index Cond: (a > 0)
785+
(7 rows)
789786

790787
EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2;
791-
QUERY PLAN
792-
------------------------------------------------------------
788+
QUERY PLAN
789+
----------------------------------------------------------
793790
Delete on rw_view1 rw_view1_1
794791
-> Subquery Scan on rw_view1
795792
Filter: ((rw_view1.a < 10) AND (rw_view1.a = 2))
796-
-> Limit
797-
-> Bitmap Heap Scan on base_tbl
798-
Recheck Cond: (a > 0)
799-
-> Bitmap Index Scan on base_tbl_pkey
800-
Index Cond: (a > 0)
801-
(8 rows)
793+
-> Bitmap Heap Scan on base_tbl
794+
Recheck Cond: (a > 0)
795+
-> Bitmap Index Scan on base_tbl_pkey
796+
Index Cond: (a > 0)
797+
(7 rows)
802798

803799
DROP TABLE base_tbl CASCADE;
804800
NOTICE: drop cascades to 2 other objects

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp