1--source include/have_optimizer_trace.inc 2set optimizer_trace_max_mem_size=10000000,@@session.optimizer_trace="enabled=on"; 3let $show_trace= 4select json_extract(trace,"$.steps[*].join_optimization.steps[*].refine_plan") from information_schema.optimizer_trace; 5 6--echo # WL#461: allow outer references in derived tables and CTEs 7 8create table t1(a int, b int); 9insert into t1 (a) values(1),(2); 10create table t2 select * from t1; 11analyze table t1,t2; 12 13set optimizer_switch='derived_merge=on'; 14 15let $c=2; 16while ($c) 17{ 18dec $c; 19 20--echo # Deep nesting: all intermediate subqueries are marked DEPENDENT 21 22let $query= 23select * from t1 where 24 (select count(*) from (select * from (select * from t1 t2 25 where 2=(select 2 from (select t1.a) dt1))dt3)dt4); 26eval explain $query; 27eval $query; 28 29--echo # If reference is removed, not DEPENDENT 30 31let $query= 32select * from t1 where 33 (select count(*) from (select * from (select * from t1 t2 34 where 2=(select 2 from (select 42) dt1))dt3)dt4); 35eval explain $query; 36eval $query; 37 38--echo # Outer ref is in SELECT list of derived table's definition 39 40# Justifies delete-all-rows in clear_corr_derived_etc 41 42let $query= 43select 44(select dt.a from 45 (select t1.a as a, t2.a as b from t2) dt where dt.b=t1.a) 46as subq 47from t1; 48 49eval explain $query; 50eval $query; 51 52--echo # In WHERE 53 54let $query= 55select 56(select dt.b from 57 (select t2.a as b from t2 where t1.a=t2.a) dt) 58as subq 59from t1; 60 61eval explain $query; 62eval $query; 63 64--echo # In GROUP BY 65 66# Justifies calling unit->execute() in 67# TABLE_LIST::materialized_derived(), instead of 68# first_select()->join->exec(), so that we get delete_all_rows on 69# group-by tmp table 70 71let $query= 72select 73(select dt.b from 74 (select sum(t2.a) as b from t2 group by t1.a) dt) 75as subq 76from t1; 77 78eval explain $query; 79eval $query; 80 81--echo # In HAVING 82 83# Justifies not marking derived table as const (even if it has one 84# row, as here), in SELECT_LEX_UNIT::optimize: 85# if const it's substituted during optimization and 86# thus const over all executions. 87 88let $query= 89select 90(select dt.b from 91 (select sum(t2.a) as b from t2 having t1.a=sum(t2.a)-1) dt) 92as subq 93from t1; 94 95eval explain $query; 96eval $query; 97 98let $query= 99select 100(select dt.b from 101 (select sum(t2.a) as b from t2 having t1.a=sum(t2.a)-2) dt) 102as subq 103from t1; 104 105eval explain $query; 106eval $query; 107 108--echo # In ORDER BY 109 110let $query= 111select 112(select dt.b from 113 (select t2.a as b from t2 order by if(t1.a=1,t2.a,-t2.a) limit 1) dt) 114as subq 115from t1; 116 117eval explain $query; 118eval $query; 119 120--echo # In window functions 121 122let $query= 123select 124(select dt.b from 125 (select t2.a, sum(t1.a*10+t2.a) over (order by if(t1.a=1,t2.a,-t2.a)) as b 126 from t2) dt where dt.a=1) 127as subq 128from t1; 129 130eval explain $query; 131eval $query; 132 133--echo # CTE referenced twice 134 135let $query= 136select 137(with dt as (select t1.a as a, t2.a as b from t2) 138 select dt2.a from dt dt1, dt dt2 where dt1.b=t1.a and dt2.b=dt1.b) 139as subq 140from t1; 141 142eval explain $query; 143eval $query; 144 145--echo Recursive CTE 146# Justifies: 147# - else if (tl->is_recursive_reference()) 148# branch in clear_corr... 149# - !tl->table->is_created() && 150# added before open_tmp_table(rec ref) in unit's execution 151# - removed empty() of fake_select_lex's table list at end of unit's 152# execution 153# - the said empty() should be done only if (full) in cleanup; same 154# for nullifying fake_select_lex->recursive_reference. 155 156select 157 (with recursive dt as 158 (select t1.a as a union select a+1 from dt where a<10) 159 select dt1.a from dt dt1 where dt1.a=t1.a 160 ) as subq 161from t1; 162 163select 164 (with recursive dt as 165 (select t1.a as a union select a+1 from dt where a<10) 166 select concat(count(*), ' - ', avg(dt.a)) from dt 167 ) as subq 168from t1; 169 170# Same with UNION ALL 171select 172 (with recursive dt as 173 (select t1.a as a union all select a+1 from dt where a<10) 174 select concat(count(*), ' - ', avg(dt.a)) from dt 175 ) as subq 176from t1; 177 178# cte-2-ref 179 180select 181(with dt as (select t1.a as a, t2.a as b from t2) 182 select dt2.a from dt dt1, dt dt2 where dt1.b=t1.a and dt2.b=dt1.b) 183as subq 184from t1; 185 186--echo # Two references to same CTE at different levels of nesting. 187# Justifies: 188# - clearing the CTE's tmp table at the right point of execution: when 189# executing the unit which owns the WITH clause, instead of when 190# executing the query block which owns the CTE reference (otherwise 191# deeper nested CTE user would empty table under feet of less nested 192# CTE user) 193# - adding OUTER_REF_TABLE_BIT in fix_outer_field() (this is 194# due to the added loop in that function, which assumed 195# mark_as_dependent adds the bit, but it doesn't). So it's a post-fix 196# for previous revision, but was discovered only after implementing 197# the first item. Without this BIT, subq to the right of "=" is 198# considered constant, so all execs of =() use the same value of the 199# subq (in a ref access). 200 201let $query= 202select (with dt as (select t1.a as a from t2 limit 1) select * from dt dt1 where dt1.a=(select * from dt as dt2)) as subq from t1; 203 204eval explain $query; 205eval explain format=tree $query; # Demonstrates printing of CTEs printed multiple times. 206eval $query; 207 208# Same with HAVING to test similar change in Item_ref::fix_fields 209let $query= 210select (with dt as (select t2.a as a from t2 having t1.a=t2.a limit 1) select * from dt dt1 where dt1.a=(select * from dt as dt2)) as subq from t1; 211 212eval explain $query; 213eval $query; 214 215--echo # Scope of outer ref in CTE 216select (select * from (select t1.a) cte) from t1; 217# Equivalent query with CTE. 218# Per the std, when we evaluate a query expression, we start with 219# evaluation of its WITH clause elements (CTEs). 220# Evaluate subquery, so evaluate CTE, t1.a is available: ok 221select (with cte as (select t1.a) select * from cte) from t1; 222# Now same CTE is defined in top query. 223# Evaluate top query, so evaluate CTE, t1.a is not yet available: 224# error. Justifies the push_context in find_common_table_expr() which 225# itself implies the new "complex" loop in fix_outer_field() 226--error ER_UNKNOWN_TABLE 227with cte as (select t1.a) select (select * from cte) from t1; 228 229--echo # NOT IN(subquery using derived), handled with subquery materialization 230 231let $query= 232select * from t1 233where a not in (select dt.f+1 from (select t2.a as f from t2) dt); 234 235eval explain $query; 236eval $query; 237 238--echo # Now put an outer reference inside derived table: 239--echo # subquery is properly seen as correlated and subquery 240--echo # materialization is thus not used. 241 242let $query= 243select * from t1 244where a not in (select dt.f+1 from (select 0*t1.a+t2.a as f from t2) dt); 245 246eval explain $query; 247eval $query; 248 249--echo # Verify that a non-lateral derived table with an outer 250--echo # reference makes the semijoin be correlated and thus blocks 251--echo # semijoin-materialization-scan. 252create table t11 (a int); 253insert into t11 254 with recursive cte as (select 1 as a union all select a+1 from cte where a<124) 255 select * from cte; 256alter table t11 add index(a); 257create table t12 like t11; 258analyze table t11,t12; 259--echo # No outer ref: mat-scan chosen 260explain select 261 /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ 262 * from t11 where a in (select /*+ QB_NAME(subq1) NO_MERGE(dt) */ * 263 from (select t12.a from t12) dt); 264--echo # outer ref: mat-scan not chosen 265explain select 266 /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ 267 * from t11 where a in (select /*+ QB_NAME(subq1) NO_MERGE(dt) */ * 268 from (select t12.a+0*t11.a from t12) dt); 269DROP TABLE t11,t12; 270 271--echo LATERAL 272 273--echo # prevents join buffer if materialized (but not if merged) 274explain select dt.a from t1, lateral (select t1.a from t2) dt; 275 276--echo # no right join 277--error ER_TF_FORBIDDEN_JOIN_TYPE 278explain select dt.a from t1 right join lateral (select t1.a from t2) dt on 1; 279 280--echo # no bad left join either 281--error ER_BAD_FIELD_ERROR 282explain select dt.a from lateral (select t1.a from t2) dt left join t1 on 1; 283 284--echo # more complex case 285 286# Justifies call to propagate_table_maps() in 287# TABLE_LIST::resolve_derived() 288 289--error ER_TF_FORBIDDEN_JOIN_TYPE 290explain SELECT * FROM t1 291LEFT JOIN 292lateral (select t1.a) as dt ON t1.a=dt.a 293RIGHT JOIN 294lateral (select dt.a) as dt1 ON dt.a=dt1.a; 295 296--echo # LATERAL DT depending on LATERAL DT 297 298# Justifies resolving _and_ materializing dt before resolving dt1, 299# i.e. changing the order in SELECT_LEX::resolve_derived(). 300 301explain SELECT * FROM t1 302JOIN 303lateral (select t1.a) as dt ON t1.a=dt.a 304JOIN 305lateral (select dt.a) as dt1 ON dt.a=dt1.a; 306 307--echo # Placing lateral outer ref in SELECT list then HAVING 308 309--sorted_result 310select t1.a, dt.a from t1, lateral (select t1.a+t2.a as a from t2) dt; 311 312select t1.a, dt.a from t1, lateral (select t2.a as a from t2 having t1.a) dt; 313 314--echo # Inside view 315create view v1 as 316 select t1.a as f1, dt.a as f2 317 from t1, lateral (select t1.a+t2.a as a from t2) dt; 318show create view v1; 319--sorted_result 320select * from v1; 321drop view v1; 322 323--echo # Coverage for various branches in Item_ref::fix_fields 324 325# I took obscure queries copied from various existing tests, which 326# cover the interested code lines, and modified them to include 327# derived tables. 328 329SELECT COUNT(*) FROM t1 GROUP BY t1.a HAVING t1.a IN (SELECT t3.a 330FROM t1 AS t3 WHERE t3.b IN (SELECT b FROM t2, lateral (select t1.a) dt)); 331 332create view v1 as select a, b from t1; 333 334# used to crash; 335# as LATERAL table looks into the table to the left, which may be 336# view, it uses find_table_in_table_ref(), which expects a view 337# to be either merged or materialized at this stage; this justifies 338# resolving the LATERAL table a bit later than ordinary derived table: 339# i.e. at the same time as table function, in 340# SELECT_LEX::resolve_derived. See bug#27152428 341 342select vq1.b,dt.b from v1 vq1, lateral (select vq1.b) dt; 343 344# still coverage for item_ref::fix_fields 345select b from v1 vq1, lateral (select count(*) from v1 vq2 having vq1.b = 3) dt; 346 347drop view v1; 348 349SELECT 350/*+ SET_VAR(optimizer_switch = 'materialization=off,semijoin=off') */ 351* FROM t1 AS ta, lateral (select 1 WHERE ta.a IN (SELECT b FROM t2 AS tb WHERE tb.b >= SOME(SELECT SUM(tc.a) as sg FROM t1 as tc GROUP BY tc.b HAVING ta.a=tc.b))) dt; 352 353# Justifies that "sut" may be NULL, so use if(sut) when adding 354# OUTER_REF_TABLE_BIT in Item_ref::fix_fields, fix_outer_field 355 356select (select dt.a from (select 1 as a, t2.a as b from t2 having 357t1.a) dt where dt.b=t1.a) as subq from t1; 358 359select (select dt.a from (select 1 as a, 3 as b from t2 having t1.a) 360dt where dt.b=t1.a) as subq from t1; 361 362--echo # Aggregation in outer context 363 364# Justifies that check_sum_func(), when it calls set_aggregation(), 365# doesn't stop as soon as unit->item is nullptr: otherwise we wouldn't 366# mark the scalar subquery, leading to wrong results. 367# Also justifies not resetting allow_sum_func to 0 when resolving a 368# derived table: we want to allow aggregated outer references. 369select (select f from (select max(t1.a) as f) as dt) as g from t1; 370 371select (select f from lateral (select max(t1.a) as f) as dt) as g from t1; 372 373--echo # LATERAL doesn't allow an aggregate to resolve to the 374--echo # immediate parent (because reading of FROM tables happens 375--echo # before aggregation). So it resolves in the derived table, so 376--echo # the outer query doesn't produce a single-row result. 377# This was the simplest behaviour to implement. 378# SQL Server and PG reject such query. SQL2015 does not really 379# describe this case. 380 381select t1.a, f from t1, lateral (select max(t1.a) as f) as dt; 382 383--echo # We support CTE inside derived table 384 385select * from t1, 386lateral (with qn as (select t1.a) select (select max(a) from qn)) as dt; 387 388--echo # Coverage for crash in Item_ident::fix_after_pullout: 389--echo # when we merge a derived table contained in a derived table, 390--echo # and the merged one contains an outer ref to the top query. 391 392select (select * from (select * from (select t1.a from t2) as dt limit 1) dt2) from t1; 393 394--echo # Semijoin containing a correlated derived table, DT must 395--echo # become LATERAL 396 397# Justifies making a non-lateral DT become a lateral one in 398# fix_tables_after_pullout. 399# Indeed, before semijoin merging "dt" has 400# an outer non-lateral ref to t1 so just needs to be materialized 401# when its owner (the IN subquery) starts execution. 402# But after semijoin merging 'dt' changes owner and we have: 403# /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` 404# semi join ((/* select#3 */ select `test`.`t1`.`a` AS `a`) `dt`) 405# where (`dt`.`a` = `test`.`t1`.`a`) 406# so 'dt' now has "lateral" refs (to t1), so we give it the LATERAL 407# word so that it is rematerialized every time and not only when its 408# owner (top query) starts execution. 409 410let $query= 411select a from t1 where a in (select a from (select t1.a) dt); 412eval explain $query; 413eval $query; 414 415# Justifies adding bits to dep_tables in fix_tables_after_pullout 416 417create table t3 as with recursive cte as (select 1 as a union select a+1 from cte where a<20) select * from cte; 418analyze table t3; 419 420# Before semijoin merging, dt has a non-lateral outer ref (to t3), so 421# its dep_tables is 0. 422# After merging, t3 has 20 rows, so optimizer would put 'dt' first in 423# plan, then t3, if dep_tables were left to 0, and this would give a 424# wrong result (20,20), as actually 'dt' depends on t3 and must be 425# after t3 in plan. 426 427let $query= 428select min(a),max(a) from t3 where a in (select /*+ no_merge() */ a from (select t3.a from t1) dt); 429eval explain $query; 430eval $query; 431 432drop table t3; 433 434--echo # DT containing a correlated DT which must become LATERAL 435 436# Justifies making a non-lateral DT become a lateral one in 437# fix_tables_after_pullout, see the "semijoin" text above. 438 439let $query= 440select * from t1, lateral (select * from (select * from (select t1.a from t2) as dt limit 1) dt2) dt3; 441 442eval explain format=tree $query; # Demonstrates Materialize -> Temporary table (forced rematerialization always). 443eval explain $query; 444eval $query; 445 446# Here "dt2" must be made lateral, as its referenced table t0 will be 447# a neighbour in FROM after merging 448 449let $query= 450select * from t1 as t0, 451lateral 452(select dt3.* from t1, lateral (select * from (select * from (select t0.a 453from t2) as dt limit 1) dt2) dt3) dt4; 454 455eval explain $query; 456eval $query; 457 458# and here "dt2" needn't be made lateral, as t0 remains in outer 459# query. 460 461let $query= 462select /*+ no_merge() */ * from t1 as t0, 463lateral 464(select dt3.* from t1, lateral (select * from (select * from (select t0.a 465from t2) as dt limit 1) dt2) dt3) dt4; 466 467eval explain $query; 468eval $query; 469 470# In the second execution of this test, with all merging disabled, 471# we observe that dt3 loses its LATERAL in the EXPLAIN warning, 472# because it doesn't actually reference neighbour tables of the same 473# FROM clause. 474 475# Note that by adding LATERAL where it was not, we change a bit the 476# meaning of the query, fortunately name resolution in execution of a 477# prepared stmt uses cached_table. If it didn't, the last column would 478# contain 42 instead of 1 or 2, if in a prepared stmt. 479 480let $query= 481select * from t1, lateral (select * from (select 42) t1, (select t1.a) dt2) dt3; 482eval explain $query; 483eval $query; 484 485--echo without semijoin: index_subquery needs to re-materialize 486 487# Justifies clear_corr_derived_tmp_tables in subselect_indexsubquery_engine::exec 488 489let $query= 490select a from t1 where a in (select /*+ no_semijoin() */ a from (select t1.a) dt); 491eval explain $query; 492eval $query; 493 494# Justifies clear_corr_ctes in subselect_indexsubquery_engine::exec 495 496select a from t1 where a in (with cte as (select t1.a) 497 select /*+ no_semijoin() */ a from cte); 498 499--echo # Count rematerializations 500 501--echo # In all three plans, handler_write is 2, showing that we 502--echo # rematerialize only when necessary (when row of t1 changes) 503let $query= 504select straight_join * from t1, t2, lateral (select t1.a) as dt; 505eval explain $query; 506flush status; 507eval $query; 508--echo # when a row of t1 produces two rows of t2 passed to "dt", 509--echo # it still makes one materialization. 510show status like "handler_write"; 511 512let $query= 513select straight_join * from t1, lateral (select t1.a) as dt, t2; 514eval explain $query; 515flush status; 516--sorted_result 517eval $query; 518show status like "handler_write"; 519 520let $query= 521select straight_join * from t2, t1, lateral (select t1.a) as dt; 522eval explain $query; 523flush status; 524--sorted_result 525eval $query; 526--echo # Due to join buffer, order t2-t1 produces rows as a 527--echo # non-buffered t1-t2 plan: t1 buffers all rows of t2, then for 528--echo # each row of t1 it's joined to all rows of t2 and passed to t2; 529--echo # when a row of t1 produces two rows of t2 passed to "dt", 530--echo # it still makes one materialization. 531show status like "handler_write"; 532 533--echo # Let the planner find the best plan. 534--echo # It doesn't work so well, because of 535--echo # optimizer_prune_level=1 (see bug#28629788): order specified by 536--echo # the user is sorted by number of rows, which leaves it 537--echo # unchanged (Card(t1)=Card(t2)=Card(dt)); then it is the first 538--echo # explored plan so it's explored in full, and later t1-dt is rejected as 539--echo # more expensive than t1-t2. Whereas if t1-dt had been explored 540--echo # deeper, we'd see t1-dt-t2 is actually the cheapest, because 541--echo # it reads dt the least number of times (and dt has a high read 542--echo # cost because Temptable::scan_time() is incredibly high but 543--echo # that's another issue; see bug#28631100). 544--echo # t2 cannot use join buffering as between "dt" and its 545--echo # dependency t1: join buffering would interlace rows of t1 546--echo # thus cause more rematerializations. 547 548let $query= 549select * from t1, t2, lateral (select t1.a) as dt; 550eval explain $query; 551flush status; 552eval $query; 553show status like "handler_write"; 554 555--echo # This one finds the best plan. Yes we simply swapped tables in the query, 556--echo # and it yields a different plan. This is because the order specified by 557--echo # the user is sorted by number of rows, which leaves it 558--echo # unchanged (Card(t1)=Card(t2)=Card(dt), then it is the first 559--echo # explored plan so it's explored in full and so is never pruned by 560--echo # prune_level=1, and it is the best plan. Best as: it reads 561--echo # "dt" less, and t2 uses join buffering (which is ok as it's 562--echo # after "dt"). 563--echo # If prune_level=0, all 3 variants here produce this plan. 564let $query= 565select * from t1, lateral (select t1.a) as dt, t2; 566eval explain $query; 567flush status; 568--sorted_result 569eval $query; 570show status like "handler_write"; 571 572--echo # This one is intermediate: t1 uses join buffer (good), but 573--echo # "dt" is last (bad, as it has high scan cost). 574 575let $query= 576select * from t2, t1, lateral (select t1.a) as dt; 577eval explain $query; 578flush status; 579--sorted_result 580eval $query; 581show status like "handler_write"; 582 583--echo # Show the trace of planning of lateral derived tables 584let $query= 585select * from t1, lateral (select t1.a from t2 as t3, t2 as t4) as dt, t2; 586eval explain $query; 587select trace from information_schema.optimizer_trace; 588 589--echo # LDT depending on const table only 590 591create table t3(a int) engine=innodb; 592insert into t3 values(3); 593analyze table t3; 594let $query= 595select * from t3, lateral (select t3.a+1) as dt; 596eval explain $query; 597eval $query; 598drop table t3; 599 600 601--echo # Two LDTs depending on different tables 602let $query= 603select * from t2, t1, lateral (select t1.a) as dt, 604 lateral (select t2.a) as dt2; 605eval explain $query; 606eval $query; 607 608--echo # Two LDTs depending on one same table 609 610let $query= 611select * from t2, t1, lateral (select t1.a) as dt, 612 lateral (select t1.a+1) as dt2; 613eval explain $query; 614eval explain format=json $query; 615--sorted_result 616eval $query; 617 618--echo # One LDT depending on two tables. The "rematerialize" tag is 619--echo # properly added to the 2nd dependency only. 620 621let $query= 622select * from t2, t1, lateral (select t1.a+t2.a) as dt; 623eval explain $query; 624eval explain format=json $query; 625eval $query; 626eval $show_trace; 627 628--echo # Test when a dependency of LDT uses BKA: BKA code must 629--echo # refresh LDT's content when it provides a row. 630set @old_opt_switch=@@optimizer_switch; 631set @@optimizer_switch="batched_key_access=on,mrr_cost_based=off"; 632CREATE TABLE t11 (t11a int, t11b int); 633INSERT INTO t11 VALUES (99, NULL),(99, 3),(99,0); 634CREATE TABLE t12 (t12a int, t12b int, KEY idx (t12b)); 635INSERT INTO t12 VALUES (100,0),(150,200),(999, 0),(999, NULL); 636ANALYZE TABLE t11,t12; 637let $query= 638SELECT * FROM t11 LEFT JOIN t12 force index (idx) ON t12.t12b = t11.t11b 639JOIN LATERAL (SELECT t12a) dt; 640eval explain $query; 641flush status; 642eval $query; 643show status like "handler_write"; 644DROP TABLE t11,t12; 645set @@optimizer_switch=@old_opt_switch; 646 647--echo # Test that with an auto_key on the lateral DT, the index is 648--echo # properly emptied and re-filled when re-materializing. 649--echo # If index weren't emptied, we'd see too many "11" matches for 2nd 650--echo # row of t1; and if not re-filled, we'd see no matches for that. 651 652create table t3 (a int, b int); 653insert into t3 values(1, 10), (1, 11), (2, 10), (2, 11); 654analyze table t3; 655let $query= 656select * from t1, lateral (select t3.b from t3 where t3.a=t1.a) dt 657 where dt.b=t1.a+9; 658--echo # Note the auto_key with "Using index", to test the index as 659--echo # much as possible. 660eval explain $query; 661eval $query; 662drop table t3; 663 664set optimizer_switch='derived_merge=off'; 665 666} 667 668--echo # Reserved word 669--error ER_PARSE_ERROR 670create table lateral(a int); 671 672drop table t1,t2; 673 674--echo # 675--echo # Bug#28723670 RECENT REGRESSION: CRASH/ASSERTION IN FIND_FIELD_IN_TABLE_REF 676--echo # 677 678CREATE TABLE t(x INT); 679--echo # Don't search for 'y' in top SELECT 680--error ER_BAD_FIELD_ERROR 681SELECT 1 FROM 682 (SELECT 1 FROM (SELECT (SELECT y FROM t) FROM t) AS a) AS b; 683DROP TABLE t; 684 685--echo # 686--echo # Bug#28976533 ASSERTION `JOIN->BEST_READ < DOUBLE(1.79769313486231570814527423731704357E+308L) 687--echo # 688 689CREATE TABLE bb ( 690pk INTEGER AUTO_INCREMENT, 691col_int INTEGER , 692col_int_key INTEGER , 693col_time_key TIME , 694col_time TIME , 695col_datetime_key DATETIME , 696col_datetime DATETIME , 697col_varchar_key VARCHAR(20) , 698col_varchar VARCHAR(20) , 699PRIMARY KEY (pk DESC), 700KEY (col_time_key), 701KEY (col_time_key DESC) 702); 703 704SET SQL_MODE=''; 705let $query= 706SELECT 707grandparent1.col_varchar_key AS g1 FROM bb AS grandparent1 708LEFT JOIN bb AS grandparent2 USING ( col_time ) 709WHERE grandparent1.col_int_key IN 710( 711 WITH qn AS ( 712 SELECT parent1.col_int AS p1 713 FROM bb AS parent1 LEFT JOIN bb AS parent2 USING ( col_varchar ) 714 WHERE parent1.col_varchar_key IN 715 ( 716 WITH qn1 AS ( 717 SELECT DISTINCT child1.col_varchar_key AS C1 718 FROM bb AS child1 LEFT JOIN bb AS child2 719 ON child1.col_varchar_key <= child2.col_varchar 720 WHERE child1.col_time > grandparent1.col_datetime 721 ) 722 SELECT * FROM qn1 723 ) 724 AND parent1.col_time_key BETWEEN '2008-03-18' AND 725 '2004-11-14' 726 ) 727 SELECT /*+ MERGE(qn) */ * FROM qn 728) 729GROUP BY grandparent1.col_int; 730 731eval EXPLAIN $query; 732eval $query; 733 734DROP TABLE bb; 735SET SQL_MODE=DEFAULT; 736 737--echo # 738--echo # Bug #29268512: ASSERTION FAILED: INITED == NONE INTERMITTENTLY 739--echo # 740 741CREATE TABLE t1 ( 742 f1 integer 743); 744 745INSERT INTO t1 VALUES (0),(1); 746 747CREATE TABLE t2 ( 748 f2 integer 749); 750 751SELECT * FROM t1, LATERAL ( SELECT MAX(1) FROM t2 GROUP BY t1.f1 ) AS l1; 752 753DROP TABLE t1, t2; 754 755--echo # 756--echo # Bug #29334082: Still crashing in actual_key_parts() / assert inited == INDEX 757--echo # 758 759CREATE TABLE t1 ( f1 INTEGER ); 760CREATE TABLE t2 ( f2 LONGBLOB ); 761 762INSERT INTO t1 VALUES (1); 763INSERT INTO t2 VALUES ('abc'),('def'); 764 765# The longblob requires deduplication by means of a hidden hash field, 766# which triggers a special path in MaterializeIterator that involves an index. 767SELECT STD(0) FROM t2, LATERAL ( SELECT f1 FROM t1 GROUP BY f2,f1 ) AS d1; 768 769DROP TABLE t1, t2; 770 771--echo # 772--echo # Bug#28954838 ASSERTION `(REMAINING_TABLES_AFTER != 0) || ((CUR_EMBEDDING_MAP == 0) && (JOIN-> 773--echo # 774 775CREATE TABLE t1 ( 776 pk INTEGER, 777 col_int INT not null, 778 col_int_key INT not null, 779 col_time_gckey TIME, 780 col_varchar VARCHAR(20) not null, 781 col_varchar_key VARCHAR(15) not null 782); 783 784CREATE TABLE t2 ( 785 pk INTEGER, 786 col_int INT not null, 787 col_varchar VARCHAR(20) not null, 788 col_varchar_key VARCHAR(15) not null 789); 790 791SET OPTIMIZER_SWITCH='derived_merge=off'; 792 793SELECT table1.col_varchar_key AS field1, 794 table2.col_time_gckey AS field2 795FROM t2 AS table1 STRAIGHT_JOIN t1 AS table2 796 ON table2.col_varchar_key = table1.col_varchar_key 797WHERE table2.col_int_key IN 798 (WITH qn AS 799 (SELECT sq1_t1.col_int AS sq1_field1 800 FROM t2 AS sq1_t1 801 WHERE sq1_t1.col_varchar_key = table2.col_varchar OR 802 EXISTS (WITH qn1 AS 803 (SELECT c_sq1_t1.col_int_key AS c_sq1_field1 804 FROM t1 AS c_sq1_t1 805 WHERE c_sq1_t1.col_varchar_key > sq1_t1.col_varchar OR 806 c_sq1_t1.col_int <> c_sq1_t1.pk 807 ) 808 SELECT * FROM qn1 809 ) 810 ) 811 SELECT * FROM qn 812 ) AND 813 EXISTS (WITH qn AS 814 (SELECT sq2_t1.col_varchar AS sq2_field1 815 FROM t1 AS sq2_t1 STRAIGHT_JOIN 816 t2 AS sq2_t2 INNER JOIN t1 AS sq2_t3 817 ON sq2_t3.col_varchar = sq2_t2.col_varchar_key 818 ON sq2_t3.col_int = sq2_t2.pk 819 ) 820 SELECT * FROM qn 821 ) AND 822 table2.col_varchar_key <> 'j'; 823 824SET OPTIMIZER_SWITCH=DEFAULT; 825DROP TABLE t1,t2; 826 827--echo # 828--echo # Bug#28955358 VIRTUAL LONGLONG FIELD_NEWDATE::VAL_DATE_TEMPORAL(): ASSERTION `!TABLE || (!TAB 829--echo # 830 831CREATE TABLE t1 ( 832pk INTEGER, col_int_key INTEGER NOT NULL, 833col_date_key DATE NOT NULL, col_datetime DATETIME NOT NULL 834); 835 836INSERT INTO t1 VALUES (0, 0, '2006-07-18', '2001-09-06 02:13:59.021506'); 837 838# outer reference inside derived table 'qn' 839 840SELECT /*+ no_merge() */ outr.pk AS x 841FROM ( SELECT * FROM t1 ) AS outr 842WHERE outr.col_int_key IN 843( SELECT /*+ no_merge() no_semijoin() */ 2 844 FROM (SELECT 1 AS x FROM t1 AS innr WHERE outr.col_date_key ) AS 845 qn ) 846ORDER BY outr.col_datetime; 847 848# outer reference inside JSON_TABLE 849 850SELECT /*+ no_merge() */ outr.pk AS x 851FROM ( SELECT * FROM t1 ) AS outr 852WHERE outr.col_int_key IN 853( SELECT /*+ no_merge() no_semijoin() */ id 854 FROM JSON_TABLE( IF(outr.col_date_key<>NOW(), 855 '[{"a":"3"},{"a":2},{"b":1},{"a":0}]', 856 '') , 857 '$[*]' columns (id for ordinality, 858 jpath varchar(100) path '$.a', 859 jexst int exists path '$.b') ) AS 860 qn ) 861ORDER BY outr.col_datetime; 862 863DROP TABLE t1; 864 865# This bug was also wrongly accepting a bad GROUP BY query 866# without functional dependency: 867 868CREATE TABLE t1(pk INT PRIMARY KEY, a INT); 869--error ER_WRONG_FIELD_WITH_GROUP 870EXPLAIN SELECT pk FROM t1 GROUP BY a; 871--error ER_WRONG_FIELD_WITH_GROUP 872EXPLAIN SELECT (SELECT pk FROM (SELECT t1.pk) dt) FROM t1 GROUP BY a; 873DROP TABLE t1; 874 875--echo # 876--echo # Bug#28960857 ASSERTION FAILED: !TR->DERIVED_WHERE_COND || TR->DERIVED_WHERE_COND->FIXED 877--echo # Bug#28960789 ASSERTION FAILED: TRANSL->ITEM->FIXED, 878--echo # 879 880CREATE TABLE t0007 ( 881 c0008 date NOT NULL, 882 c0009 char(234) NOT NULL 883); 884 885CREATE TABLE t0008 ( 886 c0005 tinytext NOT NULL 887); 888 889CREATE TABLE t0009 ( 890 c0000 time NOT NULL 891); 892 893SET SQL_MODE=0; 894 895SELECT (SELECT t0007.c0009 FROM (SELECT t0007.c0008 AS c0003 896 FROM t0009 ) AS t0005 ) FROM t0007 897GROUP BY -23; 898 899SELECT (SELECT c0009 900 FROM (SELECT 1 AS c0003 901 FROM t0009 INNER JOIN t0008 902 ON t0008.c0005 903 WHERE t0007.c0008 904 ) AS t0005 905 GROUP BY c0008 906 ), 907 COUNT(c0009) 908FROM t0007 909GROUP BY 1, 1; 910 911DROP TABLE t0007, t0008, t0009; 912SET SQL_MODE=DEFAULT; 913 914--echo # 915--echo # Bug #29514504: WRONG RESULT WITH CORRELATED LATERAL JOIN 916--echo # 917 918# 919# In this case, the derived table has an aggregation function that can get zero 920# input rows, _and_ is evaluated multiple times (due to LATERAL). If so, 921# we have to be careful to properly reset the value we write to the derived 922# table, or the value from the previous iteration would leak through. 923# 924CREATE TABLE t1 (id INTEGER); 925CREATE TABLE t2 (id INTEGER); 926INSERT INTO t1 VALUES (10), (20), (30); 927INSERT INTO t2 VALUES (20), (20); 928SELECT * FROM t1 JOIN LATERAL ( 929 SELECT GROUP_CONCAT(t.id) AS c FROM t2 t WHERE (t.id = t1.id) 930) d0 ON (1); 931 932DROP TABLE t1, t2; 933 934--echo # 935--echo # Bug #30110851: SUBQUERY INVOLVES COUNT() AGGREGATE FUNCTION PERFORMANCE REGRESSION 936--echo # 937 938CREATE TABLE t1 ( f1 INTEGER NOT NULL, f2 INTEGER NOT NULL ); 939CREATE TABLE t2 ( f1 INTEGER NOT NULL, f2 INTEGER NOT NULL ); 940CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; 941CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT ( SELECT f2 FROM v1 WHERE v1.f1 = t2.f1 ) AS f3 FROM t2; 942 943# 944# Both materializations here should be marked as non-rematerialize 945# (ie., not “Temporary table”). In particular, the materialization 946# in the SELECT clause should be reused for each iteration, even though 947# the index lookup against it is outer-correlated, and it is part of 948# a query block which is also itself outer-correlated. 949# 950EXPLAIN FORMAT=TREE SELECT * FROM v2 WHERE f3 = 3; 951 952DROP TABLE t1, t2; 953DROP VIEW v1, v2; 954 955--echo # 956--echo # Bug#30627575 ASSERT: `INITED == NONE' IN HANDLER::HA_INDEX_INIT() AT SQL/HANDLER.CC 957--echo # 958 959CREATE TABLE t1( 960a INT, 961b INT NOT NULL, 962c INT NOT NULL, 963d INT, 964UNIQUE KEY (c,b) 965); 966INSERT INTO t1 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); 967CREATE TABLE t2( 968a INT, 969b INT, 970UNIQUE KEY(a,b) 971); 972INSERT INTO t2 VALUES (NULL, NULL), (NULL, NULL), (NULL, 1), (1, NULL), (1, 1), (1,2); 973ANALYZE TABLE t1,t2; 974 975# Should show "using index for group-by" 976EXPLAIN SELECT * FROM t1 JOIN LATERAL (SELECT a+t1.a from t2 GROUP BY a) AS dt; 977 978SELECT * FROM t1 JOIN LATERAL (SELECT a+t1.a from t2 GROUP BY a) AS dt; 979 980DROP TABLE t1, t2; 981