Skip to content

Commit

Permalink
Merge 10.3 into 10.4
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-m committed May 22, 2019
2 parents 1921df6 + 592dc59 commit cf77951
Show file tree
Hide file tree
Showing 18 changed files with 299 additions and 73 deletions.
57 changes: 57 additions & 0 deletions mysql-test/main/order_by.result
Original file line number Diff line number Diff line change
Expand Up @@ -3343,6 +3343,63 @@ C
B
DROP TABLE t1;
#
# MDEV-16214: Incorrect plan taken by the optimizer , uses INDEX instead of ref access with ORDER BY
#
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2(
id int primary key,
key1 int,key2 int,
col1 int,
key(key1), key(key2)
);
insert into t2
select
A.a + B.a*10 + C.a*100,
A.a + 10*B.a, A.a + 10*B.a,
123456
from t1 A, t1 B, t1 C;
# here type should show ref not index
explain select
(SELECT concat(id, '-', key1, '-', col1)
FROM t2
WHERE
t2.key1 = t1.a and t2.key1 IS NOT NULL
ORDER BY
t2.key2 ASC
LIMIT 1)
from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a 10 Using index condition; Using where; Using filesort
select
(SELECT concat(id, '-', key1, '-', col1)
FROM t2
WHERE
t2.key1 = t1.a and t2.key1 IS NOT NULL
ORDER BY
t2.key2 ASC
LIMIT 1)
from t1;
(SELECT concat(id, '-', key1, '-', col1)
FROM t2
WHERE
t2.key1 = t1.a and t2.key1 IS NOT NULL
ORDER BY
t2.key2 ASC
LIMIT 1)
900-0-123456
901-1-123456
902-2-123456
903-3-123456
904-4-123456
905-5-123456
906-6-123456
907-7-123456
908-8-123456
909-9-123456
drop table t1,t2;
#
# MDEV-17761: Odd optimizer choice with ORDER BY LIMIT and condition selectivity
#
create table t1(a int);
Expand Down
37 changes: 37 additions & 0 deletions mysql-test/main/order_by.test
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,43 @@ ORDER BY id+1 DESC;

DROP TABLE t1;

--echo #
--echo # MDEV-16214: Incorrect plan taken by the optimizer , uses INDEX instead of ref access with ORDER BY
--echo #

create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

create table t2(
id int primary key,
key1 int,key2 int,
col1 int,
key(key1), key(key2)
);

insert into t2
select
A.a + B.a*10 + C.a*100,
A.a + 10*B.a, A.a + 10*B.a,
123456
from t1 A, t1 B, t1 C;

let $query= select
(SELECT concat(id, '-', key1, '-', col1)
FROM t2
WHERE
t2.key1 = t1.a and t2.key1 IS NOT NULL
ORDER BY
t2.key2 ASC
LIMIT 1)
from t1;

--echo # here type should show ref not index
eval explain $query;
eval $query;

drop table t1,t2;

--echo #
--echo # MDEV-17761: Odd optimizer choice with ORDER BY LIMIT and condition selectivity
--echo #
Expand Down
7 changes: 7 additions & 0 deletions mysql-test/suite/versioning/r/create.result
Original file line number Diff line number Diff line change
Expand Up @@ -520,5 +520,12 @@ row_end bigint as row end,
period for system_time (row_start, row_end)
) engine=myisam with system versioning;
ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
create table t (
a int,
row_start datetime(6) generated always as row start,
row_end datetime(6) generated always as row end,
period for system_time(row_start, row_end)
) with system versioning;
ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t`
drop database test;
create database test;
19 changes: 19 additions & 0 deletions mysql-test/suite/versioning/r/partition.result
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,25 @@ set timestamp=1523466002.799571;
insert into t1 values (11),(12);
set timestamp=1523466004.169435;
delete from t1 where pk in (11, 12);
#
# MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
#
create or replace table t1 (pk int) with system versioning
partition by system_time interval 7 second (
partition ver_p1 history,
partition ver_pn current);
alter table t1
partition by system_time interval column_get(column_create(7,7), 7 as int) second (
partition ver_p1 history,
partition ver_pn current);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`pk` int(11) DEFAULT NULL
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME INTERVAL 7 SECOND
(PARTITION `ver_p1` HISTORY ENGINE = DEFAULT_ENGINE,
PARTITION `ver_pn` CURRENT ENGINE = DEFAULT_ENGINE)
# Test cleanup
drop database test;
create database test;
14 changes: 14 additions & 0 deletions mysql-test/suite/versioning/r/replace.result
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,19 @@ insert into t1 values (1,1);
create or replace table t2 (c int);
create or replace view v as select t1.* from t1 join t2;
replace into v (a, b) select a, b from t1;
drop table t1;
CREATE TABLE t1 (
pk INT AUTO_INCREMENT,
f INT,
row_start SYS_DATATYPE AS ROW START INVISIBLE,
row_end SYS_DATATYPE AS ROW END INVISIBLE,
PRIMARY KEY(pk),
UNIQUE(f),
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING;
INSERT INTO t1 () VALUES (),(),(),(),(),();
UPDATE IGNORE t1 SET f = 1;
REPLACE t1 SELECT * FROM t1;
DROP TABLE t1;
drop database test;
create database test;
9 changes: 9 additions & 0 deletions mysql-test/suite/versioning/t/create.test
Original file line number Diff line number Diff line change
Expand Up @@ -387,5 +387,14 @@ create or replace table t1 (
period for system_time (row_start, row_end)
) engine=myisam with system versioning;

--error ER_VERS_FIELD_WRONG_TYPE
create table t (
a int,
row_start datetime(6) generated always as row start,
row_end datetime(6) generated always as row end,
period for system_time(row_start, row_end)
) with system versioning;


drop database test;
create database test;
14 changes: 14 additions & 0 deletions mysql-test/suite/versioning/t/partition.test
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,20 @@ insert into t1 values (11),(12);
set timestamp=1523466004.169435;
delete from t1 where pk in (11, 12);

--echo #
--echo # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
--echo #
create or replace table t1 (pk int) with system versioning
partition by system_time interval 7 second (
partition ver_p1 history,
partition ver_pn current);
alter table t1
partition by system_time interval column_get(column_create(7,7), 7 as int) second (
partition ver_p1 history,
partition ver_pn current);
--replace_result $default_engine DEFAULT_ENGINE
show create table t1;

--echo # Test cleanup
drop database test;
create database test;
17 changes: 17 additions & 0 deletions mysql-test/suite/versioning/t/replace.test
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ insert into t1 values (1,1);
create or replace table t2 (c int);
create or replace view v as select t1.* from t1 join t2;
replace into v (a, b) select a, b from t1;
drop table t1;

--replace_result $sys_datatype_expl SYS_DATATYPE
eval CREATE TABLE t1 (
pk INT AUTO_INCREMENT,
f INT,
row_start $sys_datatype_expl AS ROW START INVISIBLE,
row_end $sys_datatype_expl AS ROW END INVISIBLE,
PRIMARY KEY(pk),
UNIQUE(f),
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING;
INSERT INTO t1 () VALUES (),(),(),(),(),();
UPDATE IGNORE t1 SET f = 1;
REPLACE t1 SELECT * FROM t1;
DROP TABLE t1;


drop database test;
create database test;
3 changes: 1 addition & 2 deletions sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7650,8 +7650,7 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name,

static bool is_versioning_timestamp(const Create_field *f)
{
return (f->type_handler() == &type_handler_datetime2 ||
f->type_handler() == &type_handler_timestamp2) &&
return f->type_handler() == &type_handler_timestamp2 &&
f->length == MAX_DATETIME_FULL_WIDTH;
}

Expand Down
11 changes: 10 additions & 1 deletion sql/partition_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,20 @@ class partition_info : public Sql_alloc
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
vers_info->interval.type= int_type;
vers_info->interval.start= start;
return get_interval_value(thd, item, int_type, &vers_info->interval.step) ||
if (item->fix_fields_if_needed_for_scalar(thd, &item))
return true;
bool error= get_interval_value(thd, item, int_type, &vers_info->interval.step) ||
vers_info->interval.step.neg || vers_info->interval.step.second_part ||
!(vers_info->interval.step.year || vers_info->interval.step.month ||
vers_info->interval.step.day || vers_info->interval.step.hour ||
vers_info->interval.step.minute || vers_info->interval.step.second);
if (error)
{
my_error(ER_PART_WRONG_VALUE, MYF(0),
thd->lex->create_last_non_select_table->table_name.str,
"INTERVAL");
}
return error;
}
bool vers_set_limit(ulonglong limit)
{
Expand Down
49 changes: 35 additions & 14 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10569,31 +10569,35 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
j->ref.null_rejecting|= (key_part_map)1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
/*
Todo: we should remove this check for thd->lex->describe on the next
line. With SHOW EXPLAIN code, EXPLAIN printout code no longer depends
on it. However, removing the check caused change in lots of query
plans! Does the optimizer depend on the contents of
table_ref->key_copy ? If yes, do we produce incorrect EXPLAINs?
We don't want to compute heavy expressions in EXPLAIN, an example would
select * from t1 where t1.key=(select thats very heavy);

(select thats very heavy) => is a constant here
eg: (select avg(order_cost) from orders) => constant but expensive
*/
if (!keyuse->val->used_tables() && !thd->lex->describe)
{ // Compare against constant
store_key_item tmp(thd,
store_key_item tmp(thd,
keyinfo->key_part[i].field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
keyinfo->key_part[i].length,
keyuse->val,
FALSE);
if (unlikely(thd->is_fatal_error))
DBUG_RETURN(TRUE);
tmp.copy();
if (unlikely(thd->is_fatal_error))
DBUG_RETURN(TRUE);
tmp.copy();
j->ref.const_ref_part_map |= key_part_map(1) << i ;
}
else
*ref_key++= get_store_key(thd,
keyuse,join->const_table_map,
&keyinfo->key_part[i],
key_buff, maybe_null);
{
*ref_key++= get_store_key(thd,
keyuse,join->const_table_map,
&keyinfo->key_part[i],
key_buff, maybe_null);
if (!keyuse->val->used_tables())
j->ref.const_ref_part_map |= key_part_map(1) << i ;
}
/*
Remember if we are going to use REF_OR_NULL
But only if field _really_ can be null i.e. we force JT_REF
Expand Down Expand Up @@ -25925,6 +25929,15 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
{
if (!(eta->ref_list.append_str(thd->mem_root, "const")))
return 1;
/*
create_ref_for_key() handles keypart=const equalities as follows:
- non-EXPLAIN execution will copy the "const" to lookup tuple
immediately and will not add an element to ref.key_copy
- EXPLAIN will put an element into ref.key_copy. Since we've
just printed "const" for it, we should skip it here
*/
if (thd->lex->describe)
key_ref++;
}
else
{
Expand Down Expand Up @@ -27661,7 +27674,15 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
*/
if (ref_key >= 0 && ref_key != MAX_KEY && tab->type == JT_REF)
{
if (table->quick_keys.is_set(ref_key))
/*
If ref access uses keypart=const for all its key parts,
and quick select uses the same # of key parts, then they are equivalent.
Reuse #rows estimate from quick select as it is more precise.
*/
if (tab->ref.const_ref_part_map ==
make_prev_keypart_map(tab->ref.key_parts) &&
table->quick_keys.is_set(ref_key) &&
table->quick_key_parts[ref_key] == tab->ref.key_parts)
refkey_rows_estimate= table->quick_rows[ref_key];
else
{
Expand Down
5 changes: 0 additions & 5 deletions sql/sql_yacc.yy
Original file line number Diff line number Diff line change
Expand Up @@ -5974,12 +5974,7 @@ opt_versioning_rotation:
{
partition_info *part_info= Lex->part_info;
if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4)))
{
my_error(ER_PART_WRONG_VALUE, MYF(0),
Lex->create_last_non_select_table->table_name.str,
"INTERVAL");
MYSQL_YYABORT;
}
}
| LIMIT ulonglong_num
{
Expand Down
5 changes: 0 additions & 5 deletions sql/sql_yacc_ora.yy
Original file line number Diff line number Diff line change
Expand Up @@ -5999,12 +5999,7 @@ opt_versioning_rotation:
{
partition_info *part_info= Lex->part_info;
if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4)))
{
my_error(ER_PART_WRONG_VALUE, MYF(0),
Lex->create_last_non_select_table->table_name.str,
"INTERVAL");
MYSQL_YYABORT;
}
}
| LIMIT ulonglong_num
{
Expand Down
1 change: 0 additions & 1 deletion sql/table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2314,7 +2314,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
switch (handler->real_field_type())
{
case MYSQL_TYPE_TIMESTAMP2:
case MYSQL_TYPE_DATETIME2:
break;
case MYSQL_TYPE_LONGLONG:
if (vers_can_native)
Expand Down
Loading

0 comments on commit cf77951

Please sign in to comment.