Commit d44dd54b authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-6400: "ANALYZE SELECT ... INTO @var" doesn't set @var

Make ANALYZE work for
- ANALYZE SELECT ... INTO @var
- ANALYZE INSERT SELECT ...;
- ANALYZE SELECT .. INTO OUTFILE
parent fec5ab5a
......@@ -276,3 +276,20 @@ select * from t1;
a b
1 2
drop table t1;
#
# MDEV-6400 "ANALYZE SELECT ... INTO @var" doesn't set @var
#
create table t1(a int);
insert into t1 values (1),(2);
analyze select a from t1 where a <2 into @var;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2 100.00 50.00 Using where
analyze select a from t1 into @var;
ERROR 42000: Result consisted of more than one row
analyze insert into t1 select * from t1;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2 100.00 100.00 Using temporary
analyze select * into outfile '../../tmp/data1.tmp' from t1;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 4 100.00 100.00
drop table t1;
......@@ -217,3 +217,19 @@ analyze replace t1 values (1,2);
select * from t1;
drop table t1;
--echo #
--echo # MDEV-6400 "ANALYZE SELECT ... INTO @var" doesn't set @var
--echo #
create table t1(a int);
insert into t1 values (1),(2);
analyze select a from t1 where a <2 into @var;
--error ER_TOO_MANY_ROWS
analyze select a from t1 into @var;
analyze insert into t1 select * from t1;
analyze select * into outfile '../../tmp/data1.tmp' from t1;
--remove_file $MYSQLTEST_VARDIR/tmp/data1.tmp
drop table t1;
......@@ -2710,7 +2710,7 @@ bool select_to_file::send_eof()
if (mysql_file_close(file, MYF(MY_WME)) || thd->is_error())
error= true;
if (!error)
if (!error && !suppress_my_ok)
{
::my_ok(thd,row_count);
}
......@@ -3786,11 +3786,14 @@ bool select_dumpvar::send_eof()
if (thd->is_error())
return true;
::my_ok(thd,row_count);
if (!suppress_my_ok)
::my_ok(thd,row_count);
return 0;
}
bool
select_materialize_with_stats::
create_result_table(THD *thd_arg, List<Item> *column_types,
......
......@@ -3956,6 +3956,14 @@ class select_result :public select_result_sink
{
unit->offset_limit_cnt= 0;
}
/*
This returns
- FALSE if the class sends output row to the client
- TRUE if the output is set elsewhere (a file, @variable, or table).
Currently all intercepting classes derive from select_result_interceptor.
*/
virtual bool is_result_interceptor()=0;
};
......@@ -3986,6 +3994,8 @@ class select_result_explain_buffer : public select_result_sink
/*
This is a select_result_sink which stores the data in text form.
It is only used to save EXPLAIN output.
*/
class select_result_text_buffer : public select_result_sink
......@@ -4014,7 +4024,7 @@ class select_result_text_buffer : public select_result_sink
class select_result_interceptor: public select_result
{
public:
select_result_interceptor()
select_result_interceptor() : suppress_my_ok(false)
{
DBUG_ENTER("select_result_interceptor::select_result_interceptor");
DBUG_PRINT("enter", ("this 0x%lx", (ulong) this));
......@@ -4022,6 +4032,15 @@ class select_result_interceptor: public select_result
} /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
bool send_result_set_metadata(List<Item> &fields, uint flag) { return FALSE; }
bool is_result_interceptor() { return true; }
/*
Instruct the object to not call my_ok(). Client output will be handled
elsewhere. (this is used by ANALYZE $stmt feature).
*/
void disable_my_ok_calls() { suppress_my_ok= true; }
protected:
bool suppress_my_ok;
};
......@@ -4040,6 +4059,7 @@ class select_send :public select_result {
virtual bool check_simple_select() const { return FALSE; }
void abort_result_set();
virtual void cleanup();
bool is_result_interceptor() { return true; }
};
......
......@@ -3712,6 +3712,10 @@ bool select_insert::send_eof()
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
}
if (suppress_my_ok)
DBUG_RETURN(0);
char buff[160];
if (info.ignore)
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
......
......@@ -3814,6 +3814,9 @@ mysql_execute_command(THD *thd)
lex->duplicates,
lex->ignore)))
{
if (lex->analyze_stmt)
((select_result_interceptor*)sel_result)->disable_my_ok_calls();
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
/*
Invalidate the table in the query cache if something changed
......@@ -3833,7 +3836,7 @@ mysql_execute_command(THD *thd)
delete sel_result;
}
if (!res && explain)
if (!res && (explain || lex->analyze_stmt))
res= thd->lex->explain->send_explain(thd);
/* revert changes for SP */
......@@ -5649,12 +5652,18 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
else
{
Protocol *save_protocol;
Protocol *save_protocol= NULL;
if (lex->analyze_stmt)
{
result= new select_send_analyze();
save_protocol= thd->protocol;
thd->protocol= new Protocol_discard(thd);
if (result && result->is_result_interceptor())
((select_result_interceptor*)result)->disable_my_ok_calls();
else
{
DBUG_ASSERT(thd->protocol);
result= new select_send_analyze();
save_protocol= thd->protocol;
thd->protocol= new Protocol_discard(thd);
}
}
else
{
......@@ -5668,8 +5677,11 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
if (lex->analyze_stmt)
{
delete thd->protocol;
thd->protocol= save_protocol;
if (save_protocol)
{
delete thd->protocol;
thd->protocol= save_protocol;
}
if (!res)
res= thd->lex->explain->send_explain(thd);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment