1--source include/have_optimizer_trace.inc 2 3let $DEFAULT_TRACE_MEM_SIZE=1048576; # 1MB 4eval set optimizer_trace_max_mem_size=$DEFAULT_TRACE_MEM_SIZE; 5 6set end_markers_in_json=on; 7set optimizer_trace="enabled=on"; 8 9SET @old_sql_mode = @@sql_mode; 10SET @@sql_mode='ONLY_FULL_GROUP_BY'; 11 12--echo # 13--echo # Bug#16021396 ONLY_FULL_GROUP_BY REJECTS VALID QUERY USING VIEW 14--echo # 15create table t1(a int, b int, c int) engine=InnoDB; 16let $count=2; 17while($count) 18{ 19if ($count == 2) 20{ 21let $viewtype=merge; 22} 23if ($count == 1) 24{ 25let $viewtype=temptable; 26} 27dec $count; 28eval create algorithm=$viewtype view v1 as select t1.a*2 as a, t1.b*2 as b, t1.c*2 as c from t1; 29show create view v1; 30select sin(b) as z from t1 group by sin(b); 31select sin(b) as z from v1 group by sin(b); 32select sin(b) as z from t1 group by b; 33select sin(b) as z from v1 group by b; 34select sin(b) as z from v1 group by z; 35drop view v1; 36} 37drop table t1; 38 39--echo # From testcase of Bug#16903135: 40 41CREATE TABLE group_by_test2 ( 42 id int unsigned primary key, 43 cat int unsigned not null, 44 name varchar(10), 45 num int unsigned 46); 47 48INSERT INTO group_by_test2 (id,cat,name,num) VALUES 49(1,10,'foo',2), 50(2,11,'foo',1), 51(3,22,'bar',3), 52(4,23,'bar',7), 53(5,34,'test',7); 54 55let $query= 56SELECT 57 cat, 58 name, 59 SUM(num) 60FROM 61 group_by_test2 62GROUP BY 63 cat; 64 65--error ER_WRONG_FIELD_WITH_GROUP 66eval $query; 67 68ALTER TABLE group_by_test2 ADD UNIQUE INDEX (cat); 69eval $query; 70--error ER_WRONG_FIELD_WITH_GROUP 71eval $query WITH ROLLUP; 72--echo # Expressions of group columns are ok: 73SELECT 74 cat, 75length(cat), 76 SUM(num) 77FROM 78 group_by_test2 79GROUP BY 80 cat 81WITH ROLLUP; 82 83DROP TABLE group_by_test2; 84 85--echo # Test from Bug #18993257 SELECT AGGR + NON-AGGR FROM JOIN WITH VIEW IS NOT REJECTED BY ONLY_FULL_GROUP_BY 86 87CREATE TABLE t1 ( 88 col_int_key INT, 89 col_varchar_key VARCHAR(1) 90); 91 92CREATE TABLE t2 ( 93 pk INTEGER, 94 col_int_key INTEGER 95); 96 97CREATE VIEW view_b AS SELECT * FROM t2; 98 99--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS 100SELECT MIN( alias2.col_int_key ), 101 alias2.col_int_key 102FROM t1 AS alias1, t2 AS alias2 103WHERE alias1.col_int_key IS NULL; 104 105--echo # Same with view: 106--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS 107SELECT MIN( alias2.col_int_key ), 108 alias2.col_int_key 109FROM t1 AS alias1, view_b AS alias2 110WHERE alias1.col_int_key IS NULL; 111 112DROP TABLE t1, t2; 113DROP VIEW view_b; 114 115--echo # 116--echo # WL#2489; Recognizing some functional dependencies 117--echo # 118 119--source include/show_json_object.inc 120let $show_trace= 121SELECT show_json_object('"functional_dependencies_of_GROUP_columns": {', TRACE) 122FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; 123 124create table t1( 125a int, 126b int not null, 127c int not null, 128d int, 129unique key(b,c), 130unique key(b,d) 131); 132 133--error ER_WRONG_FIELD_WITH_GROUP 134select sin(a) as z from t1 group by b; 135--error ER_WRONG_FIELD_WITH_GROUP 136select sin(a) as z from t1 group by d,b; 137 138--echo # {b,c} UNIQUE NOT NULL => {c,b}->a 139select sin(a) as z from t1 group by c,b; 140select sin(a+b*c) as z from t1 group by c,b; 141--echo # In PS mode, we see nothing below, because only_full_group_by 142--echo # checks are done at PREPARE, whereas trace below is from EXECUTE. 143eval $show_trace; 144 145--echo # With outer references: 146--error ER_WRONG_FIELD_WITH_GROUP 147select (select sin(a)) as z from t1 group by d,b; 148select (select sin(a)) as z from t1 group by c,b; 149--echo # If key columns are in function, functional dependency disappears 150--error ER_WRONG_FIELD_WITH_GROUP 151select sin(a) as z from t1 group by c*2,b*2; 152 153--echo # FDs are recognized, like in SQL standard: 154--echo # b=2 => c->{b,c} => c->a as (b,c) is unique not null. 155select sin(a) as z from t1 where b=2 group by c; 156eval $show_trace; 157 158--echo # t2.a=t1.a => {t1.b,t1.c}->t2.a 159select sin(t2.a) as z from t1, t1 as t2 160 where t2.a=t1.a group by t1.b,t1.c; 161eval $show_trace; 162 163--echo # t2.b=t1.b and t2.c=t1.c => {t1.b,t1.c}->{all cols of t2} 164select sin(t2.a) as z from t1, t1 as t2 165 where t2.b=t1.b and t2.c=t1.c group by t1.b,t1.c; 166eval $show_trace; 167 168--echo # t2.b=t1.b and t2.c=t1.c => {t1.b,t1.c}->{all cols of t2} 169--echo # Moreover, {t1.b,t1.c}->{t1.d}. 170--echo # So t3.b=t2.b and t3.c=t1.d => {t1.b,t1.c}->{all cols of t3}. 171select t3.a from t1, t1 as t2, t1 as t3 172where 173 t3.b=t2.b and t3.c=t1.d and 174 t2.b=t1.b and t2.c=t1.c 175group by t1.b,t1.c; 176eval $show_trace; 177 178--echo # 3 tables: 179--echo # {t1.b,t1.c}->{t1.*}->{t2.b,t2.c}->{t2.*}->{t3.pk}->{t3.b} 180create table t3(pk int primary key, b int); 181select t3.b from t1,t1 as t2,t3 182 where t3.pk=t2.d and t2.b=t1.b and t2.c=t1.a 183 group by t1.b,t1.c; 184drop table t3; 185 186--echo # With subq 187select (select t1.b from t1 188 where t2.b=t1.b 189 group by t1.a) from t1 as t2; 190 191--echo # Outer join. 192create table t2 like t1; 193delete from t1; 194insert into t1 (a,b) values(1,10),(2,20); 195insert into t2 (a,b) values(1,-10); 196--echo # In result, t2.a is NULL for both rows, values of t1.a are 1 and 2 197select t1.a,t2.a from t1 left join t2 on t2.a=t1.a and t2.b=t1.b; 198--echo # So this query would choose one arbitrary value of t1.a - wrong: 199--error ER_WRONG_FIELD_WITH_GROUP 200select t1.a from t1 left join t2 on t2.a=t1.a and t2.b=t1.b group by t2.a; 201 202--echo # Also problem for FD with constant: 203select t1.a,t2.a from t1 left join t2 on 42=t1.a and t2.b=t1.b; 204--error ER_WRONG_FIELD_WITH_GROUP 205select t1.a from t1 left join t2 on 42=t1.a and t2.b=t1.b group by t2.a; 206 207--error ER_WRONG_FIELD_WITH_GROUP 208select t1.a from t1 left join t2 on t2.b=t1.a group by t2.b; 209--error ER_WRONG_FIELD_WITH_GROUP 210select t1.a from t1 left join t2 on 42=t1.a group by t2.a; 211 212--error ER_WRONG_FIELD_WITH_GROUP 213select t1.c from t1 left join t2 on t1.a=t1.c group by t1.a; 214--error ER_WRONG_FIELD_WITH_GROUP 215select t1.b from t1 left join t2 on t1.c=t1.b and t1.a=t1.c group by t1.a; 216select t1.a,t2.c from t1 left join t2 on t1.a=t2.c 217and cos(t2.c+t2.b)>0.5 and sin(t1.a+t2.d)<0.9 group by t1.a; 218 219--echo # with keys: 220select t1.a,t2.d from t1 left join t2 on t1.a=t2.c and t1.d=t2.b 221and cos(t2.c+t2.b)>0.5 and sin(t1.a+t2.d)<0.9 group by t1.a,t1.d; 222 223--echo # with non-determinism: 224--error ER_WRONG_FIELD_WITH_GROUP 225select t1.a,t2.c from t1 left join t2 on t1.a=t2.c 226and cos(t2.c+rand())>0.5 group by t1.a; 227select t1.a, ANY_VALUE(t2.c) from t1 left join t2 on t1.a=t2.c 228and cos(t2.c+rand())>0.5 group by t1.a; 229 230--echo # with parameter: 231prepare s from 'select t1.a,t2.c from t1 left join t2 on t1.a=t2.c 232and cos(t2.c+ ? )>0.5 group by t1.a'; 233execute s using @dummy; 234 235--echo # No OR 236--error ER_WRONG_FIELD_WITH_GROUP 237select t1.a,t2.c from t1 left join t2 on t1.a=t2.c 238and cos(t2.c+t2.b)>0.5 OR sin(t2.d)<0.9 group by t1.a; 239 240--echo # With subq 241--error ER_WRONG_FIELD_WITH_GROUP 242select t2.b from t1 left join t1 as t2 on t1.a=t2.b and t1.b group by t1.a; 243--error ER_WRONG_FIELD_WITH_GROUP 244select t2.b from t1 left join t1 as t2 on t1.a=t2.b and (select t1.b) group by t1.a; 245 246--echo # Test ANY_VALUE: 247select ANY_VALUE(t1.b) from t1 left join t2 on t1.c=t1.b and t1.a=t1.c group by t1.a; 248--error ER_WRONG_FIELD_WITH_GROUP 249select 3+(5*t1.b) from t1 left join t2 on t1.c=t1.b and t1.a=t1.c group by t1.a; 250select 3+(5*ANY_VALUE(t1.b)) from t1 left join t2 on t1.c=t1.b and t1.a=t1.c group by t1.a; 251delete from t1; 252insert into t1 (a,b) values(1,10),(1,20),(2,30),(2,40); 253--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS 254select a, sum(b) from t1; 255select any_value(a), sum(b) from t1; 256--echo # different order of input rows, different "any_value": 257select any_value(a), sum(b) from (select * from t1 order by a desc) as d; 258--error ER_WRONG_FIELD_WITH_GROUP 259select a,b,sum(c) from t1 group by a; 260select a,any_value(b),sum(c) from t1 group by a; 261select a,any_value(b),sum(c) 262from (select * from t1 order by a desc, b desc) as d 263group by a; 264 265--echo # With view. 266 267let $count=3; 268while($count) 269{ 270set @optimizer_switch_saved=@@optimizer_switch; 271let $source_query=select t1.a*2 as a, t1.b as b, t1.c as c, t1.d as d, t1.a as e from t1; 272if ($count == 3) 273{ 274--echo # Merged view 275eval create algorithm=merge view v1 as $source_query; 276show create view v1; 277let $source=v1; 278let $source_no_alias=v1; 279} 280if ($count == 2) 281{ 282--echo # Materialized view 283eval create algorithm=temptable view v1 as $source_query; 284show create view v1; 285let $source=v1; 286let $source_no_alias=v1; 287} 288if ($count == 1) 289{ 290--echo # Materialized derived table 291set optimizer_switch='derived_merge=off'; 292let $source=($source_query) as v1; 293let $source_no_alias=($source_query); 294} 295 296--error ER_WRONG_FIELD_WITH_GROUP 297eval select sin(a) as z from $source group by b; 298--error ER_WRONG_FIELD_WITH_GROUP 299eval select sin(a) as z from $source group by d,b; 300eval select sin(a) as z from $source group by c,b; 301--error ER_WRONG_FIELD_WITH_GROUP 302eval select (select sin(a)) as z from $source group by d,b; 303eval select (select sin(a)) as z from $source group by c,b; 304--error ER_WRONG_FIELD_WITH_GROUP 305eval select sin(a) as z from t1 group by c*2,b*2; 306eval select sin(a+b*c) as z from $source group by c,b; 307eval $show_trace; 308 309eval select sin(a) as z from $source where b=2 group by c; 310 311--echo # {v1.b,v1.c}->v1.a->t2.a 312eval select sin(t2.a) as z from $source, $source_no_alias as t2 313 where t2.a=v1.a group by v1.b,v1.c; 314eval $show_trace; 315 316eval select sin(t2.a) as z from $source, $source_no_alias as t2 317 where t2.b=v1.b and t2.c=v1.c group by v1.b,v1.c; 318 319--echo # With materialized view we get more dependencies than needed, due to implementation. 320eval select t3.a from $source, $source_no_alias as t2, $source_no_alias as t3 321where 322 t3.b=t2.b and t3.c=v1.d and 323 t2.b=v1.b and t2.c=v1.c 324group by v1.b,v1.c; 325eval $show_trace; 326 327--echo # If we simply went to real_item(), we would have WHERE 2*a=b, or 328--echo # GROUP BY 2*t1.a, so we would not find FDs. The original item 329--echo # (direct_view_ref here) must also be considered! 330eval select a from $source where a=b group by b; 331eval $show_trace; 332eval select b from $source where a=b group by a; 333eval $show_trace; 334 335eval select v1.c from $source where v1.c=v1.a group by v1.a; 336eval $show_trace; 337eval select v1.a from $source group by v1.e; 338eval $show_trace; 339eval select v1.c from $source where v1.c=v1.a group by v1.e; 340eval $show_trace; 341--echo # View appears only in WHERE 342eval select t2.d from $source, t1 as t2 where v1.a=t2.d and v1.e=t2.a group by t2.a; 343eval $show_trace; 344 345drop view if exists v1; 346 347--echo # FD due to view's WHERE: 348 349let $source_query=select t1.a*2 as a, t1.b as b from t1; 350if ($count == 3) 351{ 352eval create algorithm=merge view v1 as $source_query; 353} 354if ($count == 2) 355{ 356eval create algorithm=temptable view v1 as $source_query; 357} 358if ($count == 1) 359{ 360let $source=($source_query) as v1; 361let $source_no_alias=($source_query); 362} 363 364--error ER_WRONG_FIELD_WITH_GROUP 365eval select a from $source group by b; 366drop view if exists v1; 367 368let $source_query=select t1.a*2 as a, t1.b as b from t1 where t1.a=t1.b; 369if ($count == 3) 370{ 371--echo # Merged view 372eval create algorithm=merge view v1 as $source_query; 373} 374if ($count == 2) 375{ 376--echo # Materialized view 377eval create algorithm=temptable view v1 as $source_query; 378} 379if ($count == 1) 380{ 381--echo # Derived table 382let $source=($source_query) as v1; 383let $source_no_alias=($source_query); 384} 385eval select a from $source group by b; 386eval $show_trace; 387 388drop view if exists v1; 389 390--echo # Aggregates in view 391 392let $source_query=select sum(t1.a) as a, sum(t1.b) as b from t1; 393if ($count == 3) 394{ 395--echo # Aggregates => skipping Merged view 396} 397if ($count == 2) 398{ 399--echo # Materialized view 400eval create algorithm=temptable view v1 as $source_query; 401} 402if ($count == 1) 403{ 404--echo # Derived table 405let $source=($source_query) as v1; 406let $source_no_alias=($source_query); 407} 408if ($count <= 2) 409{ 410eval select a from $source group by b; 411eval $show_trace; 412} 413 414drop view if exists v1; 415 416--echo # Aggregates + GROUP BY in view 417 418--echo # We group by b*5, to show that it works with GROUP expressions, not only fields. 419let $source_query=select a, b*5 as b, sum(t1.c) as c, sum(t1.d) as d from t1 group by a,b*5; 420if ($count == 3) 421{ 422--echo # Aggregates => skipping Merged view 423} 424if ($count == 2) 425{ 426--echo # Materialized view 427eval create algorithm=temptable view v1 as $source_query; 428} 429if ($count == 1) 430{ 431--echo # Derived table 432let $source=($source_query) as v1; 433let $source_no_alias=($source_query); 434} 435if ($count <= 2) 436{ 437--error ER_WRONG_FIELD_WITH_GROUP 438eval select a from $source group by b; 439--error ER_WRONG_FIELD_WITH_GROUP 440eval select c from $source group by b; 441--error ER_WRONG_FIELD_WITH_GROUP 442eval select c from $source group by b,d; 443--error ER_WRONG_FIELD_WITH_GROUP 444eval select a,c from $source group by a; 445eval select d,c from $source group by b,a; 446eval $show_trace; 447} 448 449drop view if exists v1; 450 451dec $count; 452set optimizer_switch=@optimizer_switch_saved; 453} 454 455--echo # Derived table in merged view 456create algorithm=temptable view v2 457as select a as a, 2*a as b from t1; 458create algorithm=merge view v1 459 as select v2.a as a, 3*v2.b as b from v2; 460select v1.b from v1 group by v1.a; 461eval $show_trace; 462 463select t2.a from t1 as t2, v1 where t2.a=v1.b group by v1.a; 464eval $show_trace; 465 466--echo # FDs in a view are those of the underlying query expression. 467--echo # FDs in a query expression: expressions in the SELECT list must be 468--echo # deterministic. 469drop view v1; 470create algorithm=merge view v1 471 as select v2.a as a, rand()*v2.b as b from v2; 472--error ER_WRONG_FIELD_WITH_GROUP 473select v1.b from v1 group by v1.a; 474drop view v1; 475create algorithm=temptable view v1 476 as select v2.a as a, rand()*v2.b as b from v2; 477--error ER_WRONG_FIELD_WITH_GROUP 478select v1.b from v1 group by v1.a; 479 480drop view v1,v2; 481 482--echo # Item_direct_view_ref pointing to Item_direct_view_ref pointing to 483--echo # Item_field (a rare case!) 484create algorithm=merge view v2 as select 2*a as a, 2*b as b from t1; 485create algorithm=merge view v1 as select a, 3*b as b from v2 where a=b; 486select 1 from (select a,b+0 from v1 group by a) as d; 487drop view v1,v2; 488 489--echo # Some fun cases with aggregates in derived table. 490 491--echo # Inner query is valid: t1.a -> t1.b (equality in WHERE). Outer query: 492--echo # d.b -> t1.b (underlying column of d.b) -> t1.a (equality) 493--echo # -> sum(1) (because t1.a is all group columns so determines 494--echo # sum()) -> d.s (because sum() is underlying of d.s) 495select d.s from 496 (select b, sum(1) as s from t1 where a=b group by a) as d 497group by d.b; 498 499alter table t1 add column pk int primary key auto_increment; 500--echo # Inner query: t1.pk -> t1.* (pk). Outer query: 501--echo # d.b,d.c -> t1.b,t1.c (their underlying columns) -> t1.pk (because 502--echo # t1.b,t1.c is unique) -> sum(1) (because t1.pk is all group columns so 503--echo # determines sum()) -> d.s (because sum() is underlying of d.s) 504select d.s from 505 (select b, c, sum(d) as s from t1 group by pk) as d 506group by d.b,d.c; 507 508--echo # Outer query: 509--echo # d.c -> t1.b*3 (underlying column of d.c) -> sum(a) (because t1.b*3 510--echo # is all group expressions) -> d.s 511select d.s from 512 (select b*3 as c, sum(a) as s from t1 group by b*3) as d 513group by d.c; 514 515drop table t1,t2; 516 517 518--echo # Testcase from Reviewers 519 520create table customer1(pk int primary key, a int); 521create table customer2(pk int primary key, b int); 522CREATE algorithm=merge VIEW customer as SELECT pk,a,b 523FROM customer1 JOIN customer2 USING (pk); 524 525let $query=select customer.pk, customer.b 526from customer 527group by customer.pk; 528 529eval $query; 530--echo # View is merged. Show FDs. Note that in --ps-protocol, the trace 531--echo # is that of execution, so contains no group-by checks. 532eval $show_trace; 533 534drop view customer; 535CREATE algorithm=temptable VIEW customer as SELECT pk,a,b 536FROM customer1 JOIN customer2 USING (pk); 537eval $query; 538eval $show_trace; 539 540--echo # Benefit from outer-join-to-inner conversion. 541insert into customer1 values(0,10),(1,20); 542insert into customer2 values(0,10),(1,20); 543 544--echo # 1) no conversion, no FD from customer2.b to customer1.a. 545--error ER_WRONG_FIELD_WITH_GROUP 546explain select customer1.a, count(*) 547 from customer1 left join customer2 on customer1.a=customer2.b 548 where customer1.pk in (7,9) 549 group by customer2.b; 550 551--echo # 2) null-complemented row can't pass WHERE => conversion 552--echo # => FD from customer2.b to customer1.a. 553explain select customer1.a, count(*) 554 from customer1 left join customer2 on customer1.a=customer2.b 555 where customer2.pk in (7,9) 556 group by customer2.b; 557 558drop table customer1,customer2; 559drop view customer; 560 561--echo # FDs of JOIN...USING and NATURAL JOIN 562 563create table t1(pk int primary key, a int); 564create table t2(pk int primary key, b int); 565 566select t1.pk, t1.a from t1 join t2 on t1.pk=t2.pk group by t1.pk; 567select t1.pk, t1.a from t1 join t2 using(pk) group by t1.pk; 568select t1.pk, t1.a from t1 natural join t2 group by t1.pk; 569select t1.pk, t1.a from t1 left join t2 using(pk) group by t1.pk; 570select t1.pk, t1.a from t1 natural left join t2 group by t1.pk; 571 572select t1.pk, t2.b from t1 join t2 on t1.pk=t2.pk group by t1.pk; 573select t1.pk, t2.b from t1 join t2 using(pk) group by t1.pk; 574select t1.pk, t2.b from t1 natural join t2 group by t1.pk; 575select t1.pk, t2.b from t1 left join t2 using(pk) group by t1.pk; 576eval $show_trace; 577select t1.pk, t2.b from t1 natural left join t2 group by t1.pk; 578 579--echo # Equivalent queries, with RIGHT JOIN 580select t1.pk, t2.b from t2 right join t1 using(pk) group by t1.pk; 581select t1.pk, t2.b from t2 natural right join t1 group by t1.pk; 582 583--error ER_WRONG_FIELD_WITH_GROUP 584select t1.pk, t2.b from t1 left join t2 on t1.pk>t2.pk group by t1.pk; 585--echo # Even in --ps-protocol we see the group-by checks in trace because 586--echo # there has been no execution (due to error). 587eval $show_trace; 588 589--error ER_WRONG_FIELD_WITH_GROUP 590select t1.pk, t2.b from t2 right join t1 on t1.pk>t2.pk group by t1.pk; 591 592drop table t1,t2; 593 594--echo # Cases where FDs from weak side do not propagate 595 596create table t1(a int, b int); 597insert into t1 values(null,0),(null,1); 598 599let $query= 600select d.a,d.c 601from t1 left join (select a, coalesce(a,3) as c from t1) as d 602on t1.b>0; 603eval $query; 604--echo # Now group it by d.a: 605--error ER_WRONG_FIELD_WITH_GROUP 606eval $query group by d.a; 607eval $show_trace; 608 609let $query= 610select d.a,d.c 611from t1 left join (select a, count(a) as c from t1 group by a) as d 612on t1.b+d.c>0; 613eval $query; 614--echo # Now group it by d.a: 615--error ER_WRONG_FIELD_WITH_GROUP 616eval $query group by d.a; 617eval $show_trace; 618 619let $query= 620select d.m,d.c 621from t1 left join (select max(a) as m, count(a) as c from t1) as d 622on t1.b+d.c>0; 623eval $query; 624--echo # Now group it by d.m: 625--error ER_WRONG_FIELD_WITH_GROUP 626eval $query group by d.m; 627eval $show_trace; 628--echo # Now group it by d.c which is non-nullable: 629eval $query group by d.c; 630eval $show_trace; 631 632drop table t1; 633create table t1(pk int primary key, a int); 634 635--echo # Not valid per the standard, because: 636--echo # 1) In t3, t3.pk->t3.a holds. 637--echo # 2) In R1 the result of "(t2 left join t3 on 1)", t3.pk->t3.a 638--echo # holds, by application of: there is a functional dependency in the 639--echo # weak side t3, and t3.pk is not nullable in t3. 640--echo # 3) In R2 the result of "t1 left join (t2 left join t3 on 1) on 1", 641--echo # t3.pk->t3.a doesn't hold anymore, because: it's a dependency in the 642--echo # weak side (weak side is R1), and t3.pk is nullable _when 643--echo # seen as a column of R1_ (in R1 t3.pk can be NULL, if the row of t3 644--echo # is actually a null-complemented one). 645--echo # But for us it is valid, because we have refined the logic: the 646--echo # pk-based FD satisfies the requirement that a NULL value of t3.pk 647--echo # implies a NULL value of t3.a (indeed, the NULL value of t3.pk can 648--echo # only come from null-complementing of the row of t3 in R1, in which 649--echo # case t3.a is also NULL). 650select t3.a 651 from t1 left join (t1 as t2 left join t1 as t3 on 1) on 1 652 group by t3.pk; 653eval $show_trace; 654 655--echo # Outer reference - why we use resolved_used_tables(): 656select (select t1.a from t1 as t2 limit 1) from t1 group by pk; 657 658--echo # We don't build the FD list if not needed 659select t1.a*3 from t1 group by t1.a; 660eval $show_trace; 661 662drop table t1; 663 664--echo # Tricky cases with "ON col=literal" propagating. 665create table t1(a int, b int); 666insert into t1 values(); 667insert into t1 values(10,11); 668create table t2(c int, d int); 669insert into t2 values(2,3); 670 671let $query= 672select t4.d 673 from t1 left join (t2 as t3 join t2 as t4 on t4.d=3) on t1.a=10; 674eval $query; 675--echo # Equivalent to T1 LJ (T2, T3) ON T4.D=3 AND T1.A=10 676--echo # (this is what simplify_joins() does). 677--echo # For T4.D=3, DJS is {T1.A} which is not group column. 678--error ER_WRONG_FIELD_WITH_GROUP 679eval $query group by ""; 680 681let $query= 682select t4.d 683 from t1 left join (t2 as t3 left join t2 as t4 on t4.d=3) on t1.a=10; 684eval $query; 685--echo # For T4.D=3, DJS={}, not NULL-friendly, and embedding is on weak side 686--echo # so FD cannot propagate. 687--error ER_WRONG_FIELD_WITH_GROUP 688eval $query group by ""; 689 690let $query= 691select t4.d 692 from t1 join (t2 as t3 left join t2 as t4 on t4.d=3) on t1.a=10; 693eval $query; 694--echo # For T4.D=3, DJS={}, not NULL-friendly, but embedding is on weak side 695--echo # so FD can propagate. 696eval $query group by ""; 697 698--echo # With a view 699 700create view v1 as select a as a, 2*a as b, coalesce(a,3) as c from t1; 701 702let $query= 703select v1.b from t1 left join v1 on 1; 704eval $query; 705--echo # If v1.a is NULL then v1.b is NULL: a->b is NULL-friendly 706eval $query group by v1.a; 707 708let $query= 709select v1.c from t1 left join v1 on 1; 710eval $query; 711--echo # If v1.a is NULL then v1.c may not be NULL: a->c is not NULL-friendly 712--error ER_WRONG_FIELD_WITH_GROUP 713eval $query group by v1.a; 714 715drop view v1; 716 717--echo # Constant view item 718create view v1 as select a as a, 2 as b from t1; 719let $query= 720select t1.a, v1.b from t1 left join v1 on t1.a is not null; 721--echo # Because of BUG#17023060, the result is wrong, should be 722--echo # [10,2 ; 10,2 ; NULL,NULL], which would show that {}->{v1.b} does not 723--echo # hold in the result, even though v1.b is constant (=2) in v1. 724eval $query; 725--echo # We correctly reject this: 726--error ER_WRONG_FIELD_WITH_GROUP 727eval $query group by v1.a; 728 729drop view v1; 730drop table t1,t2; 731 732create table emp(empno int, ename char(1), deptno int); 733create table dept(deptno int primary key, dname char(1)); 734let $view_rest= 735VIEW empdept AS 736SELECT emp.empno, emp.ename, dept.deptno, dept.dname 737FROM emp LEFT OUTER JOIN dept ON (emp.deptno = dept.deptno); 738 739let $query= 740SELECT dname, COUNT(*) 741FROM empdept 742GROUP BY deptno; 743 744eval CREATE algorithm=merge $view_rest; 745eval EXPLAIN $query; 746--echo # There is pk-based FD dept.Depno->dept.dname in dept 747--echo # and it propagates in the view-which-became-nest because it is 748--echo # NULL-friendly. 749eval $query; 750drop view empdept; 751 752eval CREATE algorithm=temptable $view_rest; 753eval EXPLAIN $query; 754--echo # There is pk-based FD dept.Depno->dept.dname in dept 755--echo # and it propagates in the materialized view because it is 756--echo # NULL-friendly, and then in the top query because the view is not in 757--echo # the weak side of an outer join. 758eval $query; 759 760--echo # More tests, for code coverage. 761 762--echo # UNION in derived table 763--error ER_WRONG_FIELD_WITH_GROUP 764select emp.ename 765from 766(select 1 as empno union select 2) deriv, 767emp 768where emp.empno=deriv.empno 769group by emp.empno; 770 771drop view empdept; 772 773--echo # Make the key-searching loop meet view columns which don't wrap a 774--echo # column (CONCAT). 775 776CREATE VIEW empdept AS 777SELECT emp.empno, emp.ename, dept.deptno, concat("",dept.dname) as dname 778FROM emp LEFT JOIN dept ON (emp.deptno = dept.deptno); 779 780--error ER_WRONG_FIELD_WITH_GROUP 781SELECT ename, COUNT(*) FROM empdept WHERE empno=dname and empno=deptno GROUP BY empno; 782 783drop table emp,dept; 784drop view empdept; 785 786--echo # 787--echo # Bug#19636980 ASSERT `TABLE->OUTER_JOIN' FAILED IN GROUP_CHECK::FIND_FD_IN_JOINED_TABLE 788--echo # 789 790CREATE TABLE t1 ( 791 c1 INT, 792 c2 INT, 793 c4 DATE, 794 c5 VARCHAR(1) 795); 796 797CREATE TABLE t2 ( 798 c1 INT, 799 c2 INT, 800 c3 INT, 801 c5 VARCHAR(1) 802); 803 804--echo # alias1.c5 is not FD, the error is detected at SELECT time 805CREATE VIEW v1 AS 806 SELECT alias1.c4 AS field1 807 FROM t1 AS alias1 808 INNER JOIN t1 AS alias2 809 ON 1 810GROUP BY field1 811ORDER BY alias1.c5; 812 813--error ER_WRONG_FIELD_WITH_GROUP 814SELECT * FROM v1; 815 816DROP VIEW v1; 817 818--echo # alias1.c5 is FD (WHERE contains: alias1.c5='d') 819CREATE VIEW v1 AS 820 SELECT alias1.c4 AS field1, alias1.c4 AS field2 821 FROM t1 AS alias1 822 INNER JOIN t1 AS alias2 823 ON (alias2.c1 = alias1.c2) 824 WHERE ( NOT EXISTS ( 825 SELECT SQ1_alias1.c5 AS SQ1_field1 826 FROM t2 AS SQ1_alias1 827 WHERE SQ1_alias1.c3 < alias1.c1 828 )) 829 AND (alias1.c5 = alias1.c5 830 AND alias1.c5 = 'd' 831 ) 832GROUP BY field1, field2 833ORDER BY alias1.c5, field1, field2 834; 835 836SELECT * FROM v1; 837 838DROP VIEW v1; 839DROP TABLE t1,t2; 840 841--echo # 842--echo # Bug#19636409 ASSERT `(MAP_OF_NEW_EQ_FDS...` IN GROUP_CHECK::IS_FD_ON_SOURCE ON SELECT 843--echo # 844 845CREATE TABLE t1 ( 846 pk int NOT NULL, 847 c1 datetime, 848 c2 varchar(1), 849 c3 date, 850 c4 date, 851 c5 varchar(1), 852 PRIMARY KEY (pk) 853); 854 855CREATE VIEW v1 AS 856 SELECT c3 AS subfield11, 857 pk AS subfield12, 858 c2 AS subfield13 859 FROM t1 860 GROUP BY subfield11, subfield12 861; 862 863--echo # This query is valid. Indeed: field3 i.e. t1.c2 is part of GROUP BY, 864--echo # so, in a group: 865--echo # - all rows have the same value of t1.c2, noted val_c2, 866--echo # - so all rows, which necessarily match WHERE, matched with a row of 867--echo # v1 having subfield11=val_c2 and subfield12=val_c2 (due to IN 868--echo # predicate), 869--echo # - thus both grouping columns of v1's query expression are constant 870--echo # (to val_c2) 871--echo # - thus v1.subfield13 is constant too (grouping columns determine the 872--echo # SELECT list) 873--echo # - so, due to IN, this determines the value of t1.pk (t1 is the top 874--echo # query's table). 875--echo # - so t1.pk is constant, so all columns of t1 are constant. 876--echo # Which proves that it makes sense to search FDs in semijoin 877--echo # equalities. 878--echo # In other words: a semijoin is like a join except that it eliminates 879--echo # duplicates, but duplicates are irrelevant to the decision whether a 880--echo # column is functionally dependent on a set of columns. 881 882SELECT c5 AS field1, 883 c4 AS field2, 884 c2 AS field3, 885 c1 AS field4 886FROM t1 887WHERE ( c2, c2, pk ) IN ( 888 SELECT * FROM v1 889) 890GROUP BY field1, field3, field3; 891 892--echo # 893--echo # Bug#19687724 FUNCTIONAL DEPENDENCIES ARE NOT RECOGNIZED IN EQUALITIES BETWEEN ROWS 894--echo # 895 896--echo # Inspired by query above, but with a join: 897SELECT c5 AS field1, 898 c4 AS field2, 899 c2 AS field3, 900 c1 AS field4 901FROM t1, v1 902WHERE ( c2, c2, pk ) = (subfield11, subfield12, subfield13) 903GROUP BY field1, field3, field3; 904 905--echo # With constants: 906SELECT c5 AS field1, 907 c4 AS field2, 908 c2 AS field3, 909 c1 AS field4 910FROM t1 911WHERE ( c2, c2, pk ) = (1, 2, 3) 912GROUP BY field1, field3, field3; 913 914DROP TABLE t1; 915 916CREATE TABLE t1(a INT, b INT, c INT, d INT); 917SELECT a,b,c,d FROM t1 WHERE a=c AND b=d GROUP by a,b; 918SELECT a,b,c,d FROM t1 WHERE (a,b)=(c,d) GROUP BY a,b; 919--error ER_WRONG_FIELD_WITH_GROUP 920SELECT a,b,c,d FROM t1 WHERE (a,b)=(c,d+1) GROUP BY a,b; 921DROP TABLE t1; 922 923DROP VIEW v1; 924 925--echo # 926--echo # Bug #20031708 ASSERT ON GROUP_CHECK::IS_FD_ON_SOURCE 927--echo # 928 929CREATE TABLE t1 ( 930 col_varchar_10_utf8 VARCHAR(10) CHARACTER SET utf8, 931 col_int_key INT, 932 pk INT PRIMARY KEY 933); 934 935CREATE TABLE t2 ( 936 col_varchar_10_utf8 VARCHAR(10) CHARACTER SET utf8 DEFAULT NULL, 937 col_int_key INT DEFAULT NULL, 938 pk INT PRIMARY KEY 939); 940 941CREATE VIEW v2 AS SELECT * FROM t2; 942 943--echo # The reporter's testcase: 944 945let $query= 946SELECT COUNT(*), t1.col_int_key 947FROM v2 LEFT OUTER JOIN t1 948 ON v2.col_varchar_10_utf8 = t1.col_varchar_10_utf8 949WHERE v2.pk = 4; 950 951--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS 952eval $query; 953 954DROP VIEW v2; 955 956--echo # A variant: one column is an expression: 957CREATE VIEW v2 AS SELECT 958 CONCAT(col_varchar_10_utf8,' ') AS col_varchar_10_utf8, 959 col_int_key, 960 pk 961FROM t2; 962 963--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS 964eval $query; 965 966DROP VIEW v2; 967 968--echo # Query used in the commit comment: view column involving two tables 969CREATE VIEW v2 AS 970 SELECT t1.pk, t2.col_int_key+1 as c, t1.pk+t2.col_int_key as p 971 FROM t1, t2; 972 973--echo # FDs will be discovered in this order: {}->v2.pk, v2.pk->v2.c, 974--echo # v2.c->v2.p 975SELECT COUNT(*), v2.p 976FROM v2 977WHERE v2.c=v2.p and v2.c=v2.pk AND v2.pk = 4; 978DROP VIEW v2; 979 980--echo # If in the query specification defining a view, a base table's pk is 981--echo # determined, 982--echo # and the view's column is a function of this base table's columns, 983--echo # then the view's column is also determined. 984--echo # So, in this view's result, {v2.pk}->{v2.coa}: 985CREATE ALGORITHM=MERGE VIEW v2 AS 986 SELECT t2.pk, COALESCE(t2.pk, 3) AS coa 987 FROM t1 LEFT JOIN t2 ON 0; 988 989--echo # And thus {pk}->{coa} holds in the result of this query using the view; 990--echo # if there is NULL-complementing in the LEFT JOIN below then (pk,coa) 991--echo # will be (NULL,NULL) and if there is not it will be (non-NULL,3): 992--echo # v2.coa is determined by v2.pk. The key fact is that v2.pk is not 993--echo # NULLable so this is a NFFD. 994SELECT v2.pk, v2.coa 995 FROM t1 LEFT JOIN v2 AS v2 ON 0 996 GROUP BY v2.pk; 997 998DROP VIEW v2; 999DROP TABLE t1,t2; 1000 1001--echo # 1002--echo # Bug#21807579 FUNCTIONAL DEPENDENCIES ARE NOT RECOGNIZED IN GENERATED COLUMNS 1003--echo # 1004 1005CREATE TABLE t ( a INT, c INT GENERATED ALWAYS AS (a+2), d INT GENERATED ALWAYS AS (c+2) ); 1006--echo # {a}->{c}, {c}->{d} and {a}->{d} hold. 1007SELECT c FROM t GROUP BY a; 1008SELECT d FROM t GROUP BY c; 1009SELECT d FROM t GROUP BY a; 1010SELECT 1+c FROM t GROUP BY a; 1011SELECT 1+d FROM t GROUP BY c; 1012SELECT 1+d FROM t GROUP BY a; 1013--echo # {t2.a}->{t2.d}->{t1.c}->{t1.d} 1014SELECT t1.d FROM t as t1, t as t2 WHERE t2.d=t1.c GROUP BY t2.a; 1015--error ER_WRONG_FIELD_WITH_GROUP 1016SELECT t1.d FROM t as t1, t as t2 WHERE t2.d>t1.c GROUP BY t2.a; 1017DROP TABLE t; 1018 1019--echo # A non-NULL-friendly dependency. 1020CREATE TABLE t ( a INT, 1021c INT GENERATED ALWAYS AS (COALESCE(a,3)) ); 1022INSERT INTO t (a) VALUES(NULL); 1023CREATE TABLE u ( a INT ); 1024INSERT INTO u VALUES(0),(1); 1025--echo # Even though {a}->{c} holds in 't', it doesn't propagate to the left 1026--echo # join's result 1027SELECT t.a,t.c FROM u LEFT JOIN t ON u.a>0; 1028--error ER_WRONG_FIELD_WITH_GROUP 1029SELECT t.a,t.c FROM u LEFT JOIN t ON u.a>0 GROUP BY t.a; 1030DROP TABLE t,u; 1031 1032DROP FUNCTION show_json_object; 1033