Commit ea195d37 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-9949 Connect Engine: long SRCDEF leads to broken table

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
parent 09464dde
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
#define SQL_CREATE_OPTIONS_INCLUDED #define SQL_CREATE_OPTIONS_INCLUDED
#include "sql_class.h" #include "sql_class.h"
//#include "handler.h"
enum { ENGINE_OPTION_MAX_LENGTH=32767 };
class engine_option_value: public Sql_alloc class engine_option_value: public Sql_alloc
{ {
......
...@@ -6506,8 +6506,8 @@ ER_PARTITION_EXCHANGE_FOREIGN_KEY ...@@ -6506,8 +6506,8 @@ ER_PARTITION_EXCHANGE_FOREIGN_KEY
swe "Tabellen att byta ut mot partition har foreign key referenser: '%-.64s'" swe "Tabellen att byta ut mot partition har foreign key referenser: '%-.64s'"
ER_NO_SUCH_KEY_VALUE ER_NO_SUCH_KEY_VALUE
eng "Key value '%-.192s' was not found in table '%-.192s.%-.192s'" eng "Key value '%-.192s' was not found in table '%-.192s.%-.192s'"
ER_RPL_INFO_DATA_TOO_LONG ER_VALUE_TOO_LONG
eng "Data for column '%s' too long" eng "Too long value for '%s'"
ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE
eng "Replication event checksum verification failed while reading from network." eng "Replication event checksum verification failed while reading from network."
ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE
......
...@@ -5730,12 +5730,16 @@ create_table_option: ...@@ -5730,12 +5730,16 @@ create_table_option:
} }
| IDENT_sys equal TEXT_STRING_sys | 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) new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->create_info.option_list, engine_option_value($1, $3, true, &Lex->create_info.option_list,
&Lex->option_list_last); &Lex->option_list_last);
} }
| IDENT_sys equal ident | 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) new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->create_info.option_list, engine_option_value($1, $3, false, &Lex->create_info.option_list,
&Lex->option_list_last); &Lex->option_list_last);
...@@ -6440,12 +6444,16 @@ attribute: ...@@ -6440,12 +6444,16 @@ attribute:
} }
| IDENT_sys equal TEXT_STRING_sys | 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) new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->last_field->option_list, engine_option_value($1, $3, true, &Lex->last_field->option_list,
&Lex->option_list_last); &Lex->option_list_last);
} }
| IDENT_sys equal ident | 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) new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->last_field->option_list, engine_option_value($1, $3, false, &Lex->last_field->option_list,
&Lex->option_list_last); &Lex->option_list_last);
...@@ -6834,12 +6842,16 @@ all_key_opt: ...@@ -6834,12 +6842,16 @@ all_key_opt:
{ Lex->last_key->key_create_info.comment= $2; } { Lex->last_key->key_create_info.comment= $2; }
| IDENT_sys equal TEXT_STRING_sys | 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) new (thd->mem_root)
engine_option_value($1, $3, true, &Lex->option_list, engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last); &Lex->option_list_last);
} }
| IDENT_sys equal ident | 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) new (thd->mem_root)
engine_option_value($1, $3, false, &Lex->option_list, engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last); &Lex->option_list_last);
......
...@@ -4783,7 +4783,11 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) ...@@ -4783,7 +4783,11 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
DBUG_RETURN(rc); DBUG_RETURN(rc);
// Get the share info from the .frm file // 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 // Now we can work
if ((pos= share->option_struct)) { if ((pos= share->option_struct)) {
if (check_privileges(thd, pos, db)) if (check_privileges(thd, pos, db))
...@@ -4796,12 +4800,6 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) ...@@ -4796,12 +4800,6 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
} // endif open_table_def } // 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); free_table_share(share);
} else // Temporary file } else // Temporary file
ok= true; ok= true;
......
This diff is collapsed.
This diff was suppressed by a .gitattributes entry.
This diff is collapsed.
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