diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index ed072902730..36b86ae7a96 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -626,6 +626,7 @@ Create_file event for file_id: %u\n",exv->file_id); glob_description_event= (Format_description_log_event*) ev; print_event_info->common_header_len= glob_description_event->common_header_len; ev->print(result_file, print_event_info); + ev->temp_buf= 0; /* We don't want this event to be deleted now, so let's hide it (I (Guilhem) should later see if this triggers a non-serious Valgrind @@ -668,8 +669,16 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); end: rec_count++; + /* + Destroy the log_event object. If reading from a remote host, + set the temp_buf to NULL so that memory isn't freed twice. + */ if (ev) + { + if (remote_opt) + ev->temp_buf= 0; delete ev; + } DBUG_RETURN(0); } @@ -1151,6 +1160,11 @@ could be out of memory"); error= 1; goto err; } + /* + If reading from a remote host, ensure the temp_buf for the + Log_event class is pointing to the incoming stream. + */ + ev->register_temp_buf((char *) net->read_pos + 1); Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 114d3088fe8..ddbee3ec79c 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -629,21 +629,21 @@ SELECT DISTINCT @v5:= fruit_id, @v6:= fruit_name INTO @v7, @v8 FROM t1 WHERE fruit_name = 'APPLE'; SELECT @v5, @v6, @v7, @v8; @v5 @v6 @v7 @v8 -3 PEAR 3 PEAR +2 APPLE 2 APPLE SELECT DISTINCT @v5 + fruit_id, CONCAT(@v6, fruit_name) INTO @v9, @v10 FROM t1 WHERE fruit_name = 'APPLE'; SELECT @v5, @v6, @v7, @v8, @v9, @v10; @v5 @v6 @v7 @v8 @v9 @v10 -3 PEAR 3 PEAR 5 PEARAPPLE +2 APPLE 2 APPLE 4 APPLEAPPLE SELECT DISTINCT @v11:= @v5 + fruit_id, @v12:= CONCAT(@v6, fruit_name) INTO @v13, @v14 FROM t1 WHERE fruit_name = 'APPLE'; SELECT @v11, @v12, @v13, @v14; @v11 @v12 @v13 @v14 -6 PEARPEAR 6 PEARPEAR +4 APPLEAPPLE 4 APPLEAPPLE SELECT DISTINCT @v13, @v14 INTO @v15, @v16 FROM t1 WHERE fruit_name = 'APPLE'; SELECT @v15, @v16; @v15 @v16 -6 PEARPEAR +4 APPLEAPPLE SELECT DISTINCT 2 + 2, 'Bob' INTO @v17, @v18 FROM t1 WHERE fruit_name = 'APPLE'; SELECT @v17, @v18; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 23244d2b3c4..4cb8eb29f19 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -380,4 +380,6 @@ IS NOT NULL 1 *** Unsigned server_id 4294967295 is found: 1 *** SET @@global.server_id= 1; +RESET MASTER; +FLUSH LOGS; End of 5.0 tests diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 80b5dccc198..bfa95d8f92b 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -353,3 +353,14 @@ select @a:=f4, count(f4) from t1 group by 1 desc; 2.6 1 1.6 4 drop table t1; +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (0, 0), (2, 1), (2, 3), (1, 1), (30, 20); +SELECT a, b INTO @a, @b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; +SELECT @a, @b; +@a @b +2 3 +SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; +a b +2 3 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 1ca07a40df1..dd45f499866 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -294,4 +294,14 @@ echo *** Unsigned server_id $s_id_max is found: $s_id_unsigned ***; eval SET @@global.server_id= $save_server_id; --remove_file $binlog_file +# +# Bug #41943: mysqlbinlog.exe crashes if --hexdump option is used +# + +RESET MASTER; +FLUSH LOGS; + +# We do not need the results, just make sure that mysqlbinlog does not crash +--exec $MYSQL_BINLOG --hexdump --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 >/dev/null + --echo End of 5.0 tests diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 3a3e8f88f83..d39b49a0e87 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -237,3 +237,15 @@ select @a:=f2, count(f2) from t1 group by 1 desc; select @a:=f3, count(f3) from t1 group by 1 desc; select @a:=f4, count(f4) from t1 group by 1 desc; drop table t1; + +# +# Bug#42009: SELECT into variable gives different results to direct SELECT +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (0, 0), (2, 1), (2, 3), (1, 1), (30, 20); +SELECT a, b INTO @a, @b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; +SELECT @a, @b; +SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index e7e75ecd020..64d5030ad4a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4151,6 +4151,41 @@ Item_func_set_user_var::check(bool use_result_field) } +/** + @brief Evaluate and store item's result. + This function is invoked on "SELECT ... INTO @var ...". + + @param item An item to get value from. +*/ + +void Item_func_set_user_var::save_item_result(Item *item) +{ + DBUG_ENTER("Item_func_set_user_var::save_item_result"); + + switch (cached_result_type) { + case REAL_RESULT: + save_result.vreal= item->val_result(); + break; + case INT_RESULT: + save_result.vint= item->val_int_result(); + unsigned_flag= item->unsigned_flag; + break; + case STRING_RESULT: + save_result.vstr= item->str_result(&value); + break; + case DECIMAL_RESULT: + save_result.vdec= item->val_decimal_result(&decimal_buff); + break; + case ROW_RESULT: + default: + // Should never happen + DBUG_ASSERT(0); + break; + } + DBUG_VOID_RETURN; +} + + /* This functions is invoked on SET @variable or @variable:= expression. diff --git a/sql/item_func.h b/sql/item_func.h index 7e15a536cf2..33aeddfe6e6 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1308,6 +1308,7 @@ public: bool send(Protocol *protocol, String *str_arg); void make_field(Send_field *tmp_field); bool check(bool use_result_field); + void save_item_result(Item *item); bool update(); enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd, Item **ref); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4389fd5039e..bb6a51d48d7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2052,7 +2052,7 @@ bool select_dumpvar::send_data(List &items) { Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item); suv->fix_fields(thd, 0); - suv->check(0); + suv->save_item_result(item); suv->update(); } }