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

Commitd5a4b69

Browse files
committed
Fix assertion failure when a SELECT DISTINCT ON expression is volatile.
In this case we generate two PathKey references to the expression (one forDISTINCT and one for ORDER BY) and they really need to refer to the sameEquivalenceClass. However get_eclass_for_sort_expr was being overly paranoidand creating two different EC's. Correct behavior is to use the SortGroupRefindex to decide whether two references to volatile expressions that areequal() (ie textually equivalent) should be considered the same.Backpatch to 8.4. Possibly this should be changed in 8.3 as well, butI'll refrain in the absence of evidence of a visible failure in that branch.Per bug #5049.
1 parent8c5463a commitd5a4b69

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

‎src/backend/optimizer/path/equivclass.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.19 2009/06/11 14:48:58momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.20 2009/09/12 00:04:58tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -357,7 +357,7 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
357357
* EquivalenceClass for it.
358358
*
359359
* sortref is the SortGroupRef of the originating SortGroupClause, if any,
360-
* or zero if not.
360+
* or zero if not. (It should never be zero if the expression is volatile!)
361361
*
362362
* This can be used safely both before and after EquivalenceClass merging;
363363
* since it never causes merging it does not invalidate any existing ECs
@@ -388,8 +388,12 @@ get_eclass_for_sort_expr(PlannerInfo *root,
388388
EquivalenceClass*cur_ec= (EquivalenceClass*)lfirst(lc1);
389389
ListCell*lc2;
390390

391-
/* Never match to a volatile EC */
392-
if (cur_ec->ec_has_volatile)
391+
/*
392+
* Never match to a volatile EC, except when we are looking at another
393+
* reference to the same volatile SortGroupClause.
394+
*/
395+
if (cur_ec->ec_has_volatile&&
396+
(sortref==0||sortref!=cur_ec->ec_sortref))
393397
continue;
394398

395399
if (!equal(opfamilies,cur_ec->ec_opfamilies))
@@ -433,6 +437,10 @@ get_eclass_for_sort_expr(PlannerInfo *root,
433437
newec->ec_broken= false;
434438
newec->ec_sortref=sortref;
435439
newec->ec_merged=NULL;
440+
441+
if (newec->ec_has_volatile&&sortref==0)/* should not happen */
442+
elog(ERROR,"volatile EquivalenceClass has no sortref");
443+
436444
newem=add_eq_member(newec,expr,pull_varnos((Node*)expr),
437445
false,expr_datatype);
438446

‎src/backend/optimizer/path/pathkeys.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.98 2009/07/17 23:19:34 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.99 2009/09/12 00:04:59 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -635,6 +635,15 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
635635
exprType((Node*)tle->expr),
636636
exprTypmod((Node*)tle->expr),
637637
0);
638+
639+
/*
640+
* Note: it might look funny to be setting sortref = 0 for
641+
* a reference to a volatile sub_eclass. However, the
642+
* expression is *not* volatile in the outer query: it's
643+
* just a Var referencing whatever the subquery emitted.
644+
* (IOW, the outer query isn't going to re-execute the
645+
* volatile expression itself.) So this is okay.
646+
*/
638647
outer_ec=
639648
get_eclass_for_sort_expr(root,
640649
outer_expr,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,10 @@ SELECT DISTINCT ON (string4, ten) string4, ten, two
6666
VVVVxx | 0 | 0
6767
(40 rows)
6868

69+
-- bug #5049: early 8.4.x chokes on volatile DISTINCT ON clauses
70+
select distinct on (1) floor(random()) as r, f1 from int4_tbl order by 1,2;
71+
r | f1
72+
---+-------------
73+
0 | -2147483647
74+
(1 row)
75+

‎src/test/regress/sql/select_distinct_on.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ SELECT DISTINCT ON (string4, ten) string4, two, ten
1414
SELECT DISTINCTON (string4, ten) string4, ten, two
1515
FROM tmp
1616
ORDER BY string4 using<, ten using>, two using<;
17+
18+
-- bug #5049: early 8.4.x chokes on volatile DISTINCT ON clauses
19+
select distincton (1) floor(random())as r, f1from int4_tblorder by1,2;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp