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

Commit0889bd0

Browse files
committed
Further thought shows that has_distinct_on_clause() needs to take much
more care with resjunk tlist entries than it was doing. The originalcoding ignored resjunk entries entirely, but a resjunk entry that isin either the distinctClause or sortClause lists indicates that DISTINCTON was used. It's important for ruleutils.c to get this right, else wemay dump views using DISTINCT ON incorrectly.
1 parent421467c commit0889bd0

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

‎src/backend/optimizer/util/clauses.c

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.87 2001/07/3117:56:31 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.88 2001/07/3120:16:33 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -736,9 +736,31 @@ pull_constant_clauses(List *quals, List **constantQual)
736736
* think of a better place for it...
737737
*****************************************************************************/
738738

739+
/*
740+
* Test whether a sort/group reference value appears in the given list of
741+
* SortClause (or GroupClause) nodes.
742+
*
743+
* Because GroupClause is typedef'd as SortClause, either kind of
744+
* node list can be passed without casting.
745+
*/
746+
staticbool
747+
sortgroupref_is_present(Indexsortgroupref,List*clauselist)
748+
{
749+
List*clause;
750+
751+
foreach(clause,clauselist)
752+
{
753+
SortClause*scl= (SortClause*)lfirst(clause);
754+
755+
if (scl->tleSortGroupRef==sortgroupref)
756+
return true;
757+
}
758+
return false;
759+
}
760+
739761
/*
740762
* Test whether a query uses DISTINCT ON, ie, has a distinct-list that is
741-
*just a subset of the output columns.
763+
*not the same as the set of output columns.
742764
*/
743765
bool
744766
has_distinct_on_clause(Query*query)
@@ -750,30 +772,43 @@ has_distinct_on_clause(Query *query)
750772
return false;
751773
/*
752774
* If the DISTINCT list contains all the nonjunk targetlist items,
753-
* then it's a simple DISTINCT, else it's DISTINCT ON. We do not
754-
* require the lists to be in the same order (since the parser may
755-
* have adjusted the DISTINCT clause ordering to agree with ORDER BY).
775+
* and nothing else (ie, no junk tlist items), then it's a simple
776+
* DISTINCT, else it's DISTINCT ON. We do not require the lists to be
777+
* in the same order (since the parser may have adjusted the DISTINCT
778+
* clause ordering to agree with ORDER BY). Furthermore, a non-DISTINCT
779+
* junk tlist item that is in the sortClause is also evidence of
780+
* DISTINCT ON, since we don't allow ORDER BY on junk tlist items when
781+
* plain DISTINCT is used.
782+
*
783+
* This code assumes that the DISTINCT list is valid, ie, all its entries
784+
* match some entry of the tlist.
756785
*/
757786
foreach(targetList,query->targetList)
758787
{
759788
TargetEntry*tle= (TargetEntry*)lfirst(targetList);
760-
Indexressortgroupref;
761-
List*distinctClause;
789+
Indexressortgroupref=tle->resdom->ressortgroupref;
762790

763-
if (tle->resdom->resjunk)
764-
continue;
765-
ressortgroupref=tle->resdom->ressortgroupref;
766791
if (ressortgroupref==0)
792+
{
793+
if (tle->resdom->resjunk)
794+
continue;/* we can ignore unsorted junk cols */
767795
return true;/* definitely not in DISTINCT list */
768-
foreach(distinctClause,query->distinctClause)
796+
}
797+
if (sortgroupref_is_present(ressortgroupref,query->distinctClause))
769798
{
770-
SortClause*scl= (SortClause*)lfirst(distinctClause);
771-
772-
if (scl->tleSortGroupRef==ressortgroupref)
773-
break;/* found TLE in DISTINCT */
799+
if (tle->resdom->resjunk)
800+
return true;/* junk TLE in DISTINCT means DISTINCT ON */
801+
/* else this TLE is okay, keep looking */
802+
}
803+
else
804+
{
805+
/* This TLE is not in DISTINCT list */
806+
if (!tle->resdom->resjunk)
807+
return true;/* non-junk, non-DISTINCT, so DISTINCT ON */
808+
if (sortgroupref_is_present(ressortgroupref,query->sortClause))
809+
return true;/* sorted, non-distinct junk */
810+
/* unsorted junk is okay, keep looking */
774811
}
775-
if (distinctClause==NIL)
776-
return true;/* this TLE is not in DISTINCT list */
777812
}
778813
/* It's a simple DISTINCT */
779814
return false;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp