Skip to content

Commit 864412f

Browse files
committed
Recognize that IN subqueries return already-unique results if they use
UNION/INTERSECT/EXCEPT (without ALL). This adds on to the previous optimization for subqueries using DISTINCT.
1 parent 5c625a9 commit 864412f

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

src/backend/optimizer/util/pathnode.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.99 2004/01/05 23:39:54 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.100 2004/01/19 03:49:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -33,6 +33,7 @@
3333
#include "utils/syscache.h"
3434

3535

36+
static bool is_distinct_query(Query *query);
3637
static bool hash_safe_tlist(List *tlist);
3738

3839

@@ -553,16 +554,14 @@ create_unique_path(Query *root, RelOptInfo *rel, Path *subpath)
553554
pathnode->subpath = subpath;
554555

555556
/*
556-
* If the input is a subquery that uses DISTINCT, we don't need to do
557-
* anything; its output is already unique. (Are there any other cases
558-
* in which we can easily prove the input must be distinct?)
557+
* If the input is a subquery whose output must be unique already,
558+
* we don't need to do anything.
559559
*/
560560
if (rel->rtekind == RTE_SUBQUERY)
561561
{
562562
RangeTblEntry *rte = rt_fetch(rel->relid, root->rtable);
563-
Query *subquery = rte->subquery;
564563

565-
if (has_distinct_clause(subquery))
564+
if (is_distinct_query(rte->subquery))
566565
{
567566
pathnode->umethod = UNIQUE_PATH_NOOP;
568567
pathnode->rows = rel->rows;
@@ -667,6 +666,36 @@ create_unique_path(Query *root, RelOptInfo *rel, Path *subpath)
667666
return pathnode;
668667
}
669668

669+
/*
670+
* is_distinct_query - does query never return duplicate rows?
671+
*/
672+
static bool
673+
is_distinct_query(Query *query)
674+
{
675+
/* DISTINCT (but not DISTINCT ON) guarantees uniqueness */
676+
if (has_distinct_clause(query))
677+
return true;
678+
679+
/* UNION, INTERSECT, EXCEPT guarantee uniqueness, except with ALL */
680+
if (query->setOperations)
681+
{
682+
SetOperationStmt *topop = (SetOperationStmt *) query->setOperations;
683+
684+
Assert(IsA(topop, SetOperationStmt));
685+
Assert(topop->op != SETOP_NONE);
686+
687+
if (!topop->all)
688+
return true;
689+
}
690+
691+
/*
692+
* XXX Are there any other cases in which we can easily see the result
693+
* must be distinct?
694+
*/
695+
696+
return false;
697+
}
698+
670699
/*
671700
* hash_safe_tlist - can datatypes of given tlist be hashed?
672701
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy