|
| 1 | +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
| 2 | + |
| 3 | +--source include/turn_off_only_full_group_by.inc |
| 4 | + |
| 5 | +insert into t1 values(100,1,2),(200,1,1),(300,2,1),(400,2,2); |
| 6 | +analyze table t1; |
| 7 | + |
| 8 | +eval select distinct b from $source order by c; |
| 9 | +eval select distinct min(b) from $source group by a order by min(c); |
| 10 | +# just to see that if source is a view, it is merged |
| 11 | +--replace_column 9 # |
| 12 | +eval explain select distinct min(b) from $source group by a order by min(c); |
| 13 | + |
| 14 | +--echo Insert rows in different order: |
| 15 | +delete from t1; |
| 16 | +insert into t1 values(200,1,1),(100,1,2),(400,2,2),(300,2,1); |
| 17 | +analyze table t1; |
| 18 | + |
| 19 | +--echo And get a different order. Query is executed like this: |
| 20 | +--echo - First, DISTINCT, using a tmp MEMORY table with a unique |
| 21 | +--echo index, thus if two rows have the same 'b' but a different 'c', |
| 22 | +--echo the second row is rejected, so the first value of 'c' wins |
| 23 | +--echo (=> randomness of 'c') |
| 24 | +--echo - Second, ORDER BY on the random 'c'. |
| 25 | +eval select distinct b from $source order by c; |
| 26 | + |
| 27 | +--echo Random order too (same reason): |
| 28 | +eval select distinct min(b) from $source group by a order by min(c); |
| 29 | + |
| 30 | +--source include/restore_sql_mode_after_turn_off_only_full_group_by.inc |
| 31 | + |
| 32 | +--echo This query gives random order: |
| 33 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 34 | +eval select distinct b from $source order by c; |
| 35 | +--echo and this one too: |
| 36 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 37 | +eval select distinct b from $source order by b-1,b+1,c; |
| 38 | + |
| 39 | +--echo and this one too: |
| 40 | +--error ER_AGGREGATE_IN_ORDER_NOT_SELECT |
| 41 | +eval select distinct min(b) from $source group by a order by min(c); |
| 42 | + |
| 43 | +--echo Not random (though Standard bans aggregates from ORDER BY): |
| 44 | +eval select distinct min(b) from $source group by a order by min(b); |
| 45 | +--error ER_AGGREGATE_IN_ORDER_NOT_SELECT |
| 46 | +eval select distinct min(b) from $source group by a order by -min(b); |
| 47 | +--echo All group exprs are in select list => DISTINCT is removed => no error |
| 48 | +eval select distinct a, min(b) from $source group by a order by max(b-2)-min(c*5); |
| 49 | + |
| 50 | +--echo This one is standard: |
| 51 | +eval select distinct min(b) as z from $source group by a order by z; |
| 52 | + |
| 53 | +--echo Other queries: |
| 54 | +eval select distinct b from $source where b<0 order by rand(); |
| 55 | +eval select distinct b from $source order by 45.0+3; |
| 56 | +eval select (select distinct b from $source_no_alias as S2 where b=7 order by S3.a) from $source_no_alias as S3; |
| 57 | +eval select distinct b from $source order by abs(b); |
| 58 | +eval select distinct b as z from $source order by abs(z); |
| 59 | + |
| 60 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 61 | +eval select distinct b from $source order by abs(b+a); |
| 62 | + |
| 63 | +eval select distinct abs(b) as z from $source order by z; |
| 64 | +eval select distinct abs(b) as z from $source order by abs(b); |
| 65 | +eval select distinct abs(b) from $source order by abs(b); |
| 66 | + |
| 67 | +--echo Not ok: ABS(b)+1 is neither a SELECTed expression nor an alias |
| 68 | +--echo to one, and mentions a column of FROM tables. |
| 69 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 70 | +eval select distinct abs(b) as z from $source order by abs(b)+1; |
| 71 | +eval select distinct abs(b) as z from $source order by z+1; |
| 72 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 73 | +eval select distinct abs(b) from $source order by abs(b)+1; |
| 74 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 75 | +eval select distinct abs(b) as z from $source order by floor(10*b); |
| 76 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 77 | +eval select distinct abs(b) from $source order by floor(10*b); |
| 78 | +--echo Two offending columns; error message needs to report only one |
| 79 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 80 | +eval select distinct abs(b) from $source order by floor(10*b),floor(10*a); |
| 81 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 82 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 83 | + (select floor(10*S2.b) from $source_no_alias as S3 limit 1); |
| 84 | +--echo Ok as S2.b in SELECT list |
| 85 | +eval select distinct abs(b),b from $source_no_alias as S2 order by |
| 86 | + (select floor(10*S2.b) from $source_no_alias as S3 limit 1); |
| 87 | +--echo Ok as subq does not use columns of FROM clause of ordered Q. |
| 88 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 89 | + (select floor(10*S3.b) from $source_no_alias as S3 limit 1); |
| 90 | +--echo Subq as alias => ok |
| 91 | +eval select distinct abs(b), |
| 92 | + (select floor(10*S3.b) from $source_no_alias as S3 limit 1) as subq |
| 93 | + from $source_no_alias as S2 order by subq; |
| 94 | +--echo Bad field in left or right argument of ALL/ANY(subq): |
| 95 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 96 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 97 | + floor(10*S2.b) IN (select floor(10*S3.b) from $source_no_alias as S3); |
| 98 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 99 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 100 | + floor(10*S2.b) > ALL(select floor(10*S3.b) from $source_no_alias as S3); |
| 101 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 102 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 103 | + floor(10*10) IN (select floor(10*S2.b) from $source_no_alias as S3); |
| 104 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 105 | +eval select distinct abs(b) from $source_no_alias as S2 order by |
| 106 | + floor(10*10) > ALL(select floor(10*S2.b) from $source_no_alias as S3); |
| 107 | + |
| 108 | +--echo Aggregates: |
| 109 | +--error ER_AGGREGATE_IN_ORDER_NOT_SELECT |
| 110 | +SELECT distinct 1 FROM t1 group by a order by count(*); |
| 111 | +--error ER_AGGREGATE_IN_ORDER_NOT_SELECT |
| 112 | +SELECT distinct 1 FROM t1 group by a order by count(*)-count(*); |
| 113 | +--echo Test ANY_VALUE |
| 114 | +SELECT distinct 1 FROM t1 group by a order by any_value(count(*)-count(b)); |
| 115 | +SELECT distinct 1 FROM t1 group by a order by any_value(count(*))-any_value(count(b)); |
| 116 | +--echo All group exprs are in select list => DISTINCT is removed => no error |
| 117 | +--sorted_result |
| 118 | +SELECT distinct a, min(b) FROM t1 group by a order by count(*)-count(*); |
| 119 | +--error ER_AGGREGATE_IN_ORDER_NOT_SELECT |
| 120 | +SELECT distinct 1 FROM t1 group by a order by count(*)-count(b); |
| 121 | +--echo aggregation in outer Q => constant in inner Q |
| 122 | +select * from t1 as t2 where t2.a in |
| 123 | + (SELECT distinct 1 FROM t1 group by a order by count(t2.a)-max(t2.a)); |
| 124 | +--echo ORDER BY expressions are in SELECT list => ok |
| 125 | +SELECT distinct 1, count(*)-count(b) FROM t1 group by a order by count(*)-count(b); |
| 126 | +--echo Without GROUP BY, aggregates yield a single row, no random order |
| 127 | +SELECT distinct sum(a) FROM t1 order by count(*)-count(*); |
| 128 | +SELECT distinct sum(a) FROM t1 order by count(*)-count(b); |
| 129 | + |
| 130 | +--echo Verify that DISTINCT is optimized away even if the aggregate |
| 131 | +--echo function is hidden in a subquery |
| 132 | +EXPLAIN SELECT DISTINCT MAX(b) FROM t1; |
| 133 | +EXPLAIN SELECT DISTINCT (SELECT MAX(t1.b) FROM t1 AS t2 LIMIT 1) FROM t1; |
| 134 | +--echo but if the subquery is the aggregation query, DISTINCT must stay: |
| 135 | +EXPLAIN SELECT DISTINCT (SELECT MAX(t1.b+0*t2.a) FROM t1 AS t2 LIMIT 1) FROM t1; |
| 136 | +--echo QA's query is properly rejected: |
| 137 | +--error ER_FIELD_IN_ORDER_NOT_SELECT |
| 138 | +eval SELECT DISTINCT GP1.a AS g1 FROM $source_no_alias AS GP1 |
| 139 | +WHERE GP1.a >= 0 |
| 140 | +ORDER BY GP1.b LIMIT 8; |
| 141 | + |
| 142 | +--echo result order does change depending on chosen plan. |
| 143 | +--sorted_result |
| 144 | +eval SELECT DISTINCT GP1.a AS g1 FROM $source_no_alias AS GP1 |
| 145 | +WHERE GP1.a >= 0 |
| 146 | +ORDER BY 2+ANY_VALUE(GP1.b) LIMIT 8; |
| 147 | + |
| 148 | +truncate table t1; |
0 commit comments