From 94ad392fd86b53f798c7de9489afe901e1f3a9b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Oct 2013 13:45:49 +0300 Subject: [PATCH 1/3] MDEV-5143: update of a joined table with a nested subquery with a syntax error crashes mysqld with signal 11 Added check of SELECT_LEX::handle_derived() result. --- mysql-test/r/derived.result | 27 +++++++++++++++++++++++++++ mysql-test/t/derived.test | 34 ++++++++++++++++++++++++++++++++++ sql/sql_derived.cc | 3 ++- sql/sql_prepare.cc | 8 +++++++- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 1042ee79e8c..e68636e0394 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -438,5 +438,32 @@ CALL p(); id drop procedure p; drop temporary table t1; +# +# MDEV-5143: update of a joined table with a nested subquery with +# a syntax error crashes mysqld with signal 11 +# +create table t1 (id int(11) not null auto_increment, val varchar(100) null,primary key (id)); +create table t2 (id int(11) not null auto_increment, val varchar(100) null,primary key (id)); +insert into t1 (val) values('a'); +insert into t2 (val) values('1'); +update +( +select +val +from +( +select +v.val +from +t2 wrong_table_alias +) t4 +) t3 +inner join t1 on +t1.id=t3.val +set +t1.val=t3.val +; +ERROR 42S22: Unknown column 'v.val' in 'field list' +drop table t1, t2; # End of 5.3 tests set optimizer_switch=@save_derived_optimizer_switch; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index b0db0e8100a..2a5ba77f38e 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -350,6 +350,40 @@ drop procedure p; drop temporary table t1; + +--echo # +--echo # MDEV-5143: update of a joined table with a nested subquery with +--echo # a syntax error crashes mysqld with signal 11 +--echo # + +create table t1 (id int(11) not null auto_increment, val varchar(100) null,primary key (id)); +create table t2 (id int(11) not null auto_increment, val varchar(100) null,primary key (id)); + +insert into t1 (val) values('a'); +insert into t2 (val) values('1'); + +--error ER_BAD_FIELD_ERROR +update + ( + select + val + from + ( + select + v.val + from + t2 wrong_table_alias + ) t4 + ) t3 + inner join t1 on + t1.id=t3.val +set + t1.val=t3.val +; + +drop table t1, t2; + + --echo # End of 5.3 tests set optimizer_switch=@save_derived_optimizer_switch; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index db6ab1fb269..9d04beaf73e 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -619,7 +619,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) { sl->context.outer_context= 0; // Prepare underlying views/DT first. - sl->handle_derived(lex, DT_PREPARE); + if ((res= sl->handle_derived(lex, DT_PREPARE))) + goto exit; if (derived->outer_join) { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 552b2145540..b4160991493 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2485,7 +2485,13 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) /* Fix ORDER list */ for (order= sl->order_list.first; order; order= order->next) order->item= &order->item_ptr; - sl->handle_derived(lex, DT_REINIT); + { +#ifndef DBUG_OFF + bool res= +#endif + sl->handle_derived(lex, DT_REINIT); + DBUG_ASSERT(res == 0); + } } { SELECT_LEX_UNIT *unit= sl->master_unit(); From 883af99e7dac91e3f258135a2053e6b8e3c05fc3 Mon Sep 17 00:00:00 2001 From: "timour@askmonty.org" Date: Tue, 29 Oct 2013 12:39:03 +0200 Subject: [PATCH 2/3] MDEV-5104 crash in Item_field::used_tables with broken order by Analysis: st_select_lex_unit::prepare() computes can_skip_order_by as TRUE. As a result join->prepare() gets called with order == NULL, and doesn't do name resolution for the inner ORDER clause. Due to this the prepare phase doesn't detect that the query references non-exiting function and field. Later join->optimize() calls update_used_tables() for a non-resolved Item_field, which understandably has no Field object. This call results in a crash. Solution: Resolve unnecessary ORDER BY clauses to detect if they reference non-exising objects. Then remove such clauses from the JOIN object. --- mysql-test/r/group_by.result | 5 +++++ mysql-test/r/subselect.result | 2 +- mysql-test/r/subselect_no_mat.result | 2 +- mysql-test/r/subselect_no_opts.result | 2 +- mysql-test/r/subselect_no_scache.result | 2 +- mysql-test/r/subselect_no_semijoin.result | 2 +- mysql-test/t/group_by.test | 7 +++++++ sql/item_subselect.cc | 1 + sql/sql_select.cc | 19 ++++++++++++++----- sql/sql_select.h | 4 ++-- sql/sql_union.cc | 3 ++- 11 files changed, 36 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 07cccf149ee..1bcec672e26 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -2407,4 +2407,9 @@ a 200 set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# +# MDEV-5104 crash in Item_field::used_tables with broken order by +# +(select 1 order by x(y)) order by 1; +ERROR 42S22: Unknown column 'y' in 'order clause' # End of 5.3 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 8503164dde2..19381353669 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -193,7 +193,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`))) select (select a from t3 where a ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`))) select (select a from t3 where a ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`))) select (select a from t3 where a ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`))) select (select a from t3 where a ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`))) select (select a from t3 where aorder_list.elements + select_lex->group_list.elements, select_lex->order_list.first, + false, select_lex->group_list.first, select_lex->having, NULL, select_lex, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 82a2471f99b..46797d66bb2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -556,8 +556,8 @@ int JOIN::prepare(Item ***rref_pointer_array, TABLE_LIST *tables_init, uint wild_num, COND *conds_init, uint og_num, - ORDER *order_init, ORDER *group_init, - Item *having_init, + ORDER *order_init, bool skip_order_by, + ORDER *group_init, Item *having_init, ORDER *proc_param_init, SELECT_LEX *select_lex_arg, SELECT_LEX_UNIT *unit_arg) { @@ -671,7 +671,16 @@ JOIN::prepare(Item ***rref_pointer_array, DBUG_RETURN(-1); /* purecov: inspected */ ref_pointer_array= *rref_pointer_array; - + + /* Resolve the ORDER BY that was skipped, then remove it. */ + if (skip_order_by && select_lex != select_lex->master_unit()->global_parameters) + { + if (setup_order(thd, (*rref_pointer_array), tables_list, fields_list, + all_fields, select_lex->order_list.first)) + DBUG_RETURN(-1); + select_lex->order_list.empty(); + } + if (having) { nesting_map save_allow_sum_func= thd->lex->allow_sum_func; @@ -2952,7 +2961,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, else { if ((err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, + conds, og_num, order, false, group, having, proc_param, select_lex, unit))) { goto err; @@ -2976,7 +2985,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, thd_proc_info(thd, "init"); thd->lex->used_tables=0; if ((err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, proc_param, + conds, og_num, order, false, group, having, proc_param, select_lex, unit))) { goto err; diff --git a/sql/sql_select.h b/sql/sql_select.h index d75be9ae0fe..be595972671 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1294,8 +1294,8 @@ public: } int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, - COND *conds, uint og_num, ORDER *order, ORDER *group, - Item *having, ORDER *proc_param, SELECT_LEX *select, + COND *conds, uint og_num, ORDER *order, bool skip_order_by, + ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit); bool prepare_stage2(); int optimize(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 942392c4c98..5c4a9a8db5f 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -318,6 +318,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, sl->group_list.elements, can_skip_order_by ? NULL : sl->order_list.first, + can_skip_order_by, sl->group_list.first, sl->having, (is_union_select ? NULL : @@ -501,7 +502,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, 0, 0, global_parameters->order_list.elements, // og_num global_parameters->order_list.first, // order - NULL, NULL, NULL, + false, NULL, NULL, NULL, fake_select_lex, this); fake_select_lex->table_list.empty(); } From 5ce11d8b4ca2a57968656925a69ed8114d5374f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2013 17:50:13 +0200 Subject: [PATCH 3/3] MariaDB made be compiled by gcc 4.8.1 There was 2 problems: 1) coping/moving of the same type (usually casting) as sizeof() (solved in different ways depends on the cause); 2) using 'const' in SSL_CTX::getVerifyCallback() which return object (not reference) and so copy of the object will be created and 'const' has no sens. --- extra/yassl/include/yassl_int.hpp | 2 +- extra/yassl/src/yassl_int.cpp | 2 +- mysys/md5.c | 2 +- sql/field.cc | 4 ++-- storage/maria/ma_blockrec.c | 2 +- storage/maria/ma_checksum.c | 2 +- storage/maria/ma_key.c | 2 +- storage/myisam/mi_checksum.c | 2 +- storage/myisam/mi_key.c | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 686e958d7e1..e5ee00bc21c 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -440,7 +440,7 @@ public: const Ciphers& GetCiphers() const; const DH_Parms& GetDH_Parms() const; const Stats& GetStats() const; - const VerifyCallback getVerifyCallback() const; + VerifyCallback getVerifyCallback() const; pem_password_cb GetPasswordCb() const; void* GetUserData() const; bool GetSessionCacheOff() const; diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 64feb8e44d5..65e17b01544 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1852,7 +1852,7 @@ SSL_CTX::GetCA_List() const } -const VerifyCallback SSL_CTX::getVerifyCallback() const +VerifyCallback SSL_CTX::getVerifyCallback() const { return verifyCallback_; } diff --git a/mysys/md5.c b/mysys/md5.c index 2388cebedc4..22a5e409a09 100644 --- a/mysys/md5.c +++ b/mysys/md5.c @@ -176,7 +176,7 @@ my_MD5Final (unsigned char digest[16], my_MD5Context *ctx) putu32(ctx->buf[1], digest + 4); putu32(ctx->buf[2], digest + 8); putu32(ctx->buf[3], digest + 12); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } #ifndef ASM_MD5 diff --git a/sql/field.cc b/sql/field.cc index 60ec8fcea57..933025ba896 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7433,7 +7433,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) if (!String::needs_conversion(length, cs, field_charset, &dummy_offset)) { Field_blob::store_length(length); - bmove(ptr+packlength,(char*) &from,sizeof(char*)); + bmove(ptr + packlength, &from, sizeof(char*)); return 0; } if (tmpstr.copy(from, length, cs)) @@ -8071,7 +8071,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) value.copy(from, length, cs); from= value.ptr(); } - bmove(ptr + packlength, (char*) &from, sizeof(char*)); + bmove(ptr + packlength, &from, sizeof(char*)); } return 0; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index eeaff327dc4..ad10d950189 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -7171,7 +7171,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn, memcpy(field_pos, field_length_data, size_length); field_length_data+= size_length; - memcpy(field_pos + size_length, &header, sizeof(&header)); + memcpy(field_pos + size_length, &header, sizeof(header)); header+= blob_length; *blob_lengths++= blob_length; break; diff --git a/storage/maria/ma_checksum.c b/storage/maria/ma_checksum.c index 61ec638053a..da2d40d3687 100644 --- a/storage/maria/ma_checksum.c +++ b/storage/maria/ma_checksum.c @@ -58,7 +58,7 @@ ha_checksum _ma_checksum(MARIA_HA *info, const uchar *record) length= _ma_calc_blob_length(blob_size_length, pos); if (length) { - memcpy((char*) &pos, pos + blob_size_length, sizeof(char*)); + memcpy(&pos, pos + blob_size_length, sizeof(char*)); crc= my_checksum(crc, pos, length); } continue; diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index 1e60e6a8c06..d0efc8fd43d 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -589,7 +589,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr, if (unpack_blobs) { memcpy(record+keyseg->start+keyseg->bit_start, - (char*) &blob_ptr,sizeof(char*)); + &blob_ptr, sizeof(char*)); memcpy(blob_ptr,key,length); blob_ptr+=length; diff --git a/storage/myisam/mi_checksum.c b/storage/myisam/mi_checksum.c index 8c408ef7ff5..13dd52db22e 100644 --- a/storage/myisam/mi_checksum.c +++ b/storage/myisam/mi_checksum.c @@ -40,7 +40,7 @@ ha_checksum mi_checksum(MI_INFO *info, const uchar *buf) length=_mi_calc_blob_length(column->length- portable_sizeof_char_ptr, buf); - memcpy((char*) &pos, buf+column->length- portable_sizeof_char_ptr, + memcpy(&pos, buf+column->length- portable_sizeof_char_ptr, sizeof(char*)); break; } diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index a3d38269e61..01e32780b17 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -425,7 +425,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, if (unpack_blobs) { memcpy(record+keyseg->start+keyseg->bit_start, - (char*) &blob_ptr,sizeof(char*)); + &blob_ptr, sizeof(char *)); memcpy(blob_ptr,key,length); blob_ptr+=length;