Skip to content

Commit 21479a6

Browse files
author
Alexander Barkov
committed
MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH
The patch fixes the problem with loading information from system tables (e.g. event and help related tables) when PAD_CHAR_TO_FULL_LENGTH is enabled, as well as includes some additional minor improvements: - refactoring in get_field() to return an error rather than success if strmake_root() failed - removing of duplicate code in similar functions: char *get_field(MEM_ROOT *mem, Field *field) bool get_field(MEM_ROOT *mem, Field *field, String *res)
1 parent 69f1a32 commit 21479a6

File tree

6 files changed

+86
-19
lines changed

6 files changed

+86
-19
lines changed

mysql-test/r/events_1.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,26 @@ DROP EVENT ev1;
469469

470470
SHOW EVENTS;
471471
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
472+
#
473+
# MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH
474+
#
475+
CREATE TABLE t1 (a INT);
476+
CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1;
477+
SHOW EVENTS;
478+
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
479+
events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
480+
SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
481+
SHOW EVENTS;
482+
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
483+
events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
484+
DROP EVENT ev1;
485+
CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1;
486+
SHOW EVENTS;
487+
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
488+
events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
489+
DROP EVENT ev1;
490+
DROP TABLE t1;
491+
SET sql_mode=DEFAULT;
472492

473493
#
474494
# End of tests

mysql-test/r/help.result

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,21 @@ help 'impossible_category_1';
148148
source_category_name name is_it_category
149149
impossible_category_1 impossible_function_1 N
150150
impossible_category_1 impossible_function_2 N
151+
# MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH
152+
help 'impossible_function_1';
153+
name description example
154+
impossible_function_1 description of
155+
impossible_function1
156+
example of
157+
impossible_function1
158+
SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
159+
help 'impossible_function_1';
160+
name description example
161+
impossible_function_1 description of
162+
impossible_function1
163+
example of
164+
impossible_function1
165+
SET sql_mode=DEFAULT;
151166
alter table mysql.help_relation engine=innodb;
152167
alter table mysql.help_keyword engine=innodb;
153168
alter table mysql.help_topic engine=innodb;

mysql-test/t/events_1.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,25 @@ DROP EVENT ev1;
459459
SHOW EVENTS;
460460

461461

462+
--echo #
463+
--echo # MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH
464+
--echo #
465+
CREATE TABLE t1 (a INT);
466+
CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1;
467+
--replace_column 8 # 9 #
468+
SHOW EVENTS;
469+
SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
470+
--replace_column 8 # 9 #
471+
SHOW EVENTS;
472+
DROP EVENT ev1;
473+
CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1;
474+
--replace_column 8 # 9 #
475+
SHOW EVENTS;
476+
DROP EVENT ev1;
477+
DROP TABLE t1;
478+
SET sql_mode=DEFAULT;
479+
480+
462481
--echo
463482
--echo #
464483
--echo # End of tests

mysql-test/t/help.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ help '%function_7';
6161
help '%category_2';
6262
help 'impossible_function_1';
6363
help 'impossible_category_1';
64+
65+
--echo # MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH
66+
help 'impossible_function_1';
67+
SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
68+
help 'impossible_function_1';
69+
SET sql_mode=DEFAULT;
6470
##############
6571

6672
--disable_warnings

sql/sql_help.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
647647
TRUE Error and send_error already commited
648648
*/
649649

650-
bool mysqld_help(THD *thd, const char *mask)
650+
static bool mysqld_help_internal(THD *thd, const char *mask)
651651
{
652652
Protocol *protocol= thd->protocol;
653653
SQL_SELECT *select;
@@ -823,3 +823,12 @@ bool mysqld_help(THD *thd, const char *mask)
823823
DBUG_RETURN(TRUE);
824824
}
825825

826+
827+
bool mysqld_help(THD *thd, const char *mask)
828+
{
829+
ulonglong sql_mode_backup= thd->variables.sql_mode;
830+
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
831+
bool rc= mysqld_help_internal(thd, mask);
832+
thd->variables.sql_mode= sql_mode_backup;
833+
return rc;
834+
}

sql/table.cc

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3384,18 +3384,23 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res)
33843384
{
33853385
char buff[MAX_FIELD_WIDTH], *to;
33863386
String str(buff,sizeof(buff),&my_charset_bin);
3387-
uint length;
3387+
bool rc;
3388+
THD *thd= field->get_thd();
3389+
ulonglong sql_mode_backup= thd->variables.sql_mode;
3390+
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
33883391

33893392
field->val_str(&str);
3390-
if (!(length= str.length()))
3393+
if ((rc= !str.length() ||
3394+
!(to= strmake_root(mem, str.ptr(), str.length()))))
33913395
{
33923396
res->length(0);
3393-
return 1;
3397+
goto ex;
33943398
}
3395-
if (!(to= strmake_root(mem, str.ptr(), length)))
3396-
length= 0; // Safety fix
3397-
res->set(to, length, field->charset());
3398-
return 0;
3399+
res->set(to, str.length(), field->charset());
3400+
3401+
ex:
3402+
thd->variables.sql_mode= sql_mode_backup;
3403+
return rc;
33993404
}
34003405

34013406

@@ -3414,17 +3419,10 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res)
34143419

34153420
char *get_field(MEM_ROOT *mem, Field *field)
34163421
{
3417-
char buff[MAX_FIELD_WIDTH], *to;
3418-
String str(buff,sizeof(buff),&my_charset_bin);
3419-
uint length;
3420-
3421-
field->val_str(&str);
3422-
length= str.length();
3423-
if (!length || !(to= (char*) alloc_root(mem,length+1)))
3424-
return NullS;
3425-
memcpy(to,str.ptr(),(uint) length);
3426-
to[length]=0;
3427-
return to;
3422+
String str;
3423+
bool rc= get_field(mem, field, &str);
3424+
DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0');
3425+
return rc ? NullS : (char *) str.ptr();
34283426
}
34293427

34303428
/*

0 commit comments

Comments
 (0)