Skip to content

Commit

Permalink
MDEV-9949 Connect Engine: long SRCDEF leads to broken table
Browse files Browse the repository at this point in the history
Two bugs here:
* the server could create an frm (with a long attribute
  value) that it could not read back
* Connect engine opened files from inside DROP TABLE
  and was ignoring the error (correctly) but was not
  hiding it from the server (incorrectly). This caused
  a crash later when DROP TABLE was finishing successfully
  while stmt_da already have seen an error.

Also added a text case for
  MDEV-7935 CREATE TABLE ... AS SELECT ... can cause a Server crash (Assertion `0' in Protocol::end_statement)
because Connect stopped clearing the error status
in stmt_da as a fix for MDEV-7935
  • Loading branch information
vuvova committed May 4, 2016
1 parent 09464dd commit ea195d3
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 10 deletions.
3 changes: 2 additions & 1 deletion sql/create_options.h
Expand Up @@ -23,7 +23,8 @@
#define SQL_CREATE_OPTIONS_INCLUDED

#include "sql_class.h"
//#include "handler.h"

enum { ENGINE_OPTION_MAX_LENGTH=32767 };

class engine_option_value: public Sql_alloc
{
Expand Down
4 changes: 2 additions & 2 deletions sql/share/errmsg-utf8.txt
Expand Up @@ -6506,8 +6506,8 @@ ER_PARTITION_EXCHANGE_FOREIGN_KEY
swe "Tabellen att byta ut mot partition har foreign key referenser: '%-.64s'"
ER_NO_SUCH_KEY_VALUE
eng "Key value '%-.192s' was not found in table '%-.192s.%-.192s'"
ER_RPL_INFO_DATA_TOO_LONG
eng "Data for column '%s' too long"
ER_VALUE_TOO_LONG
eng "Too long value for '%s'"
ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE
eng "Replication event checksum verification failed while reading from network."
ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE
Expand Down
12 changes: 12 additions & 0 deletions sql/sql_yacc.yy
Expand Up @@ -5730,12 +5730,16 @@ create_table_option:
}
| IDENT_sys equal TEXT_STRING_sys
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->create_info.option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->create_info.option_list,
&Lex->option_list_last);
Expand Down Expand Up @@ -6440,12 +6444,16 @@ attribute:
}
| IDENT_sys equal TEXT_STRING_sys
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->last_field->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->last_field->option_list,
&Lex->option_list_last);
Expand Down Expand Up @@ -6834,12 +6842,16 @@ all_key_opt:
{ Lex->last_key->key_create_info.comment= $2; }
| IDENT_sys equal TEXT_STRING_sys
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last);
Expand Down
12 changes: 5 additions & 7 deletions storage/connect/ha_connect.cc
Expand Up @@ -4783,7 +4783,11 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
DBUG_RETURN(rc);

// Get the share info from the .frm file
if (!open_table_def(thd, share)) {
Dummy_error_handler error_handler;
thd->push_internal_handler(&error_handler);
bool got_error= open_table_def(thd, share);
thd->pop_internal_handler();
if (!got_error) {
// Now we can work
if ((pos= share->option_struct)) {
if (check_privileges(thd, pos, db))
Expand All @@ -4796,12 +4800,6 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)

} // endif open_table_def

// This below was done to avoid DBUG_ASSERT in some case that
// we don't know anymore what they were. It was suppressed because
// it did cause assertion in other cases (see MDEV-7935)
// } else // Avoid infamous DBUG_ASSERT
// thd->get_stmt_da()->reset_diagnostics_area();

free_table_share(share);
} else // Temporary file
ok= true;
Expand Down
13 changes: 13 additions & 0 deletions storage/connect/mysql-test/connect/r/drop-open-error.result

Large diffs are not rendered by default.

Binary file not shown.
1 change: 1 addition & 0 deletions storage/connect/mysql-test/connect/t/drop-open-error.opt
@@ -0,0 +1 @@
--secure-file-priv=""
29 changes: 29 additions & 0 deletions storage/connect/mysql-test/connect/t/drop-open-error.test

Large diffs are not rendered by default.

0 comments on commit ea195d3

Please sign in to comment.