summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/SETUP.sh2
-rwxr-xr-xBUILD/compile-pentium-gcov19
-rw-r--r--mysql-test/r/create.result16
-rw-r--r--mysql-test/r/ctype_create.result4
-rw-r--r--mysql-test/r/events.result6
-rw-r--r--mysql-test/t/alter_table.test1
-rw-r--r--mysql-test/t/create.test21
-rw-r--r--mysql-test/t/ctype_create.test5
-rw-r--r--mysql-test/t/events.test11
-rw-r--r--sql/item_timefunc.cc13
-rw-r--r--sql/log_event.cc62
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/mysqld.cc.rej17
-rw-r--r--sql/sql_binlog.cc12
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_db.cc46
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_parse.cc309
-rw-r--r--sql/sql_parse.cc.rej166
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_yacc.yy38
-rw-r--r--sql/table.cc42
-rw-r--r--sql/table.cc.rej17
-rw-r--r--tests/mysql_client_test.c32
-rw-r--r--tests/mysql_client_test.c.rej20
27 files changed, 634 insertions, 247 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 87aec7417f1..dfbf1547517 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -183,7 +183,7 @@ fi
# (http://samba.org/ccache) is installed, use it.
# We use 'grep' and hope 'grep' will work as expected
# (returns 0 if finds lines)
-if ccache -V > /dev/null 2>&1
+if ccache -V > /dev/null 2>&1 && test "$CCACHE_GCOV_VERSION_ENABLED" == "1"
then
echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC"
echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX"
diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov
index ca37f78e283..5633efaddf0 100755
--- a/BUILD/compile-pentium-gcov
+++ b/BUILD/compile-pentium-gcov
@@ -1,12 +1,21 @@
#! /bin/sh
+# Need to disable ccache, or we loose the gcov-needed compiler output files.
+
+CCACHE_GCOV_VERSION_ENABLED=0
+if ccache -V > /dev/null 2>&1
+then
+ CCACHE_VER=`ccache -V | head -1 | sed s/"ccache version "//`
+ if test "$CCACHE_VER" == "2.4-gcov"
+ then
+ CCACHE_GCOV_VERSION_ENABLED=1
+ fi
+fi
+export CCACHE_GCOV_VERSION_ENABLED
+
path=`dirname $0`
. "$path/SETUP.sh"
-# Need to disable ccache, or we loose the gcov-needed compiler output files.
-CCACHE_DISABLE=1
-export CCACHE_DISABLE
-
# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well
# as on the compiler command line), and this requires setting LDFLAGS for BDB.
export LDFLAGS="-fprofile-arcs -ftest-coverage"
@@ -14,7 +23,7 @@ export LDFLAGS="-fprofile-arcs -ftest-coverage"
# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the
# code with profiling information used by gcov.
# the -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl.
-extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM -DHAVE_MUTEX_THREAD_ONLY"
+extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM -DHAVE_MUTEX_THREAD_ONLY $debug_extra_flags"
extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
extra_configs="$extra_configs $max_configs"
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 5bc28e9eee5..7bef6c2efba 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -820,3 +820,19 @@ SELECT * from t2;
a b
1 1
drop table t1,t2;
+CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
+ERROR 42000: Unknown database 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+create database mysqltest;
+RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+drop database mysqltest;
+USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
diff --git a/mysql-test/r/ctype_create.result b/mysql-test/r/ctype_create.result
index 8a81991ea78..35461fce45a 100644
--- a/mysql-test/r/ctype_create.result
+++ b/mysql-test/r/ctype_create.result
@@ -72,3 +72,7 @@ mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin2 */
drop database mysqltest2;
ALTER DATABASE DEFAULT CHARACTER SET latin2;
ERROR 3D000: No database selected
+ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DEFAULT CHARACTER SET latin2;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ALTER DATABASE `` DEFAULT CHARACTER SET latin2;
+ERROR 42000: Incorrect database name ''
diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result
index abf6879fc3c..af864c57efa 100644
--- a/mysql-test/r/events.result
+++ b/mysql-test/r/events.result
@@ -394,4 +394,10 @@ create trigger t1_ai after insert on t1 for each row show create event e1;
ERROR 0A000: Not allowed to return a result set from a trigger
drop table t1;
drop event e1;
+SHOW EVENTS FROM aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+SHOW EVENTS FROM ``;
+ERROR 42000: Incorrect database name ''
+SHOW EVENTS FROM `events\\test`;
+Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
drop database events_test;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 168d011a2ac..78bbd23adf1 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -535,4 +535,3 @@ INSERT INTO `@0023sql1` VALUES (2);
SHOW CREATE TABLE `#sql2`;
SHOW CREATE TABLE `@0023sql1`;
DROP TABLE `#sql2`, `@0023sql1`;
-
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 1c9bd18d5d2..a2853ca3191 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -711,3 +711,24 @@ TRUNCATE table t2;
INSERT INTO t2 select * from t1;
SELECT * from t2;
drop table t1,t2;
+
+#
+# Test incorrect database names
+#
+
+--error 1102
+CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+--error 1102
+DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+--error 1049
+RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
+--error 1102
+RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+create database mysqltest;
+--error 1102
+RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+drop database mysqltest;
+--error 1102
+USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+--error 1102
+SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
diff --git a/mysql-test/t/ctype_create.test b/mysql-test/t/ctype_create.test
index e88004bbb8c..060c09a0459 100644
--- a/mysql-test/t/ctype_create.test
+++ b/mysql-test/t/ctype_create.test
@@ -100,3 +100,8 @@ drop database mysqltest2;
ALTER DATABASE DEFAULT CHARACTER SET latin2;
# End of 4.1 tests
+
+--error 1102
+ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DEFAULT CHARACTER SET latin2;
+--error 1102
+ALTER DATABASE `` DEFAULT CHARACTER SET latin2;
diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test
index 32863308687..6eb514fc13c 100644
--- a/mysql-test/t/events.test
+++ b/mysql-test/t/events.test
@@ -395,4 +395,15 @@ drop event e1;
##show processlist;
##select count(*) from mysql.event;
+#
+# Test wrong syntax
+#
+
+--error 1102
+SHOW EVENTS FROM aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+--error 1102
+SHOW EVENTS FROM ``;
+
+SHOW EVENTS FROM `events\\test`;
+
drop database events_test;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 64277f72637..d14feb2ba68 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1368,11 +1368,9 @@ bool get_interval_value(Item *args,interval_type int_type,
interval->second= array[0];
interval->second_part= array[1];
break;
- /* purecov: begin deadcode */
- case INTERVAL_LAST:
- DBUG_ASSERT(0);
- break;
- /* purecov: end */
+ case INTERVAL_LAST: /* purecov: begin deadcode */
+ DBUG_ASSERT(0);
+ break; /* purecov: end */
}
return 0;
}
@@ -2199,7 +2197,7 @@ void Item_extract::fix_length_and_dec()
case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break;
case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break;
case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break;
- case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
+ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
}
@@ -2269,8 +2267,7 @@ longlong Item_extract::val_int()
ltime.second_part)*neg;
case INTERVAL_SECOND_MICROSECOND: return ((longlong)ltime.second*1000000L+
ltime.second_part)*neg;
- case INTERVAL_LAST: DBUG_ASSERT(0); return(0); /* purecov: deadcode */
- /* purecov: end */
+ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
return 0; // Impossible
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 79e3a35cbe8..0f9e10e37c1 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5468,14 +5468,13 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
/*
- Unpack a row into a record.
+ Unpack a row into table->record[0].
SYNOPSIS
unpack_row()
rli Relay log info
table Table to unpack into
colcnt Number of columns to read from record
- record Record where the data should be unpacked
row Packed row data
cols Pointer to columns data to fill in
row_end Pointer to variable that will hold the value of the
@@ -5488,6 +5487,11 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
DESCRIPTION
+ The function will always unpack into the table->record[0]
+ record. This is because there are too many dependencies on
+ where the various member functions of Field and subclasses
+ expect to write.
+
The row is assumed to only consist of the fields for which the
bitset represented by 'arr' and 'bits'; the other parts of the
record are left alone.
@@ -5506,15 +5510,15 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
*/
static int
unpack_row(RELAY_LOG_INFO *rli,
- TABLE *table, uint const colcnt, byte *record,
+ TABLE *table, uint const colcnt,
char const *row, MY_BITMAP const *cols,
char const **row_end, ulong *master_reclength,
MY_BITMAP* const rw_set, Log_event_type const event_type)
{
+ byte *const record= table->record[0];
DBUG_ENTER("unpack_row");
DBUG_ASSERT(record && row);
- DBUG_PRINT("enter", ("row: 0x%lx record: 0x%lx", (long) row, (long) record));
- my_ptrdiff_t const offset= record - (byte*) table->record[0];
+ DBUG_PRINT("enter", ("row: 0x%lx table->record[0]: 0x%lx", (long) row, (long) record));
my_size_t master_null_bytes= table->s->null_bytes;
if (colcnt != table->s->fields)
@@ -5557,12 +5561,10 @@ unpack_row(RELAY_LOG_INFO *rli,
DBUG_ASSERT(table->record[0] <= f->ptr);
DBUG_ASSERT(f->ptr < (table->record[0] + table->s->reclength +
(f->pack_length_in_rec() == 0)));
- f->move_field_offset(offset);
DBUG_PRINT("info", ("unpacking column '%s' to 0x%lx", f->field_name,
(long) f->ptr));
ptr= f->unpack(f->ptr, ptr);
- f->move_field_offset(-offset);
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT(ptr != NULL);
}
@@ -5593,9 +5595,10 @@ unpack_row(RELAY_LOG_INFO *rli,
for ( ; *field_ptr ; ++field_ptr)
{
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
+ Field *const f= *field_ptr;
- if (event_type == WRITE_ROWS_EVENT &&
- ((*field_ptr)->flags & mask) == mask)
+ DBUG_PRINT("info", ("processing column '%s' @ 0x%lx", f->field_name, f->ptr));
+ if (event_type == WRITE_ROWS_EVENT && (f->flags & mask) == mask)
{
slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD,
"Field `%s` of table `%s`.`%s` "
@@ -5605,7 +5608,7 @@ unpack_row(RELAY_LOG_INFO *rli,
error = ER_NO_DEFAULT_FOR_FIELD;
}
else
- (*field_ptr)->set_default();
+ f->set_default();
}
DBUG_RETURN(error);
@@ -6461,10 +6464,8 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
DBUG_ASSERT(row_start && row_end);
int error;
- error= unpack_row(rli,
- table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
- table->write_set, WRITE_ROWS_EVENT);
+ error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end,
+ &m_master_reclength, table->write_set, WRITE_ROWS_EVENT);
bitmap_copy(table->read_set, table->write_set);
return error;
}
@@ -6685,7 +6686,7 @@ replace_record(THD *thd, TABLE *table,
present on the master from table->record[1], if there are any.
*/
copy_extra_record_fields(table, master_reclength, master_fields);
-
+
/*
REPLACE is defined as either INSERT or DELETE + INSERT. If
possible, we can replace it with an UPDATE, but that will not
@@ -7066,10 +7067,8 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
*/
DBUG_ASSERT(table->s->fields >= m_width);
- error= unpack_row(rli,
- table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
- table->read_set, DELETE_ROWS_EVENT);
+ error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end,
+ &m_master_reclength, table->read_set, DELETE_ROWS_EVENT);
/*
If we will access rows using the random access method, m_key will
be set to NULL, so we do not need to make a key copy in that case.
@@ -7203,25 +7202,30 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
*/
DBUG_ASSERT(table->s->fields >= m_width);
+ /*
+ We need to perform some juggling below since unpack_row() always
+ unpacks into table->record[0]. For more information, see the
+ comments for unpack_row().
+ */
+
/* record[0] is the before image for the update */
- error= unpack_row(rli,
- table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
- table->read_set, UPDATE_ROWS_EVENT);
+ error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end,
+ &m_master_reclength, table->read_set, UPDATE_ROWS_EVENT);
+ store_record(table, record[1]);
char const *next_start = *row_end;
/* m_after_image is the after image for the update */
- error= unpack_row(rli,
- table, m_width, m_after_image,
- next_start, &m_cols, row_end, &m_master_reclength,
- table->write_set, UPDATE_ROWS_EVENT);
+ error= unpack_row(rli, table, m_width, next_start, &m_cols, row_end,
+ &m_master_reclength, table->write_set, UPDATE_ROWS_EVENT);
+ bmove_align(m_after_image, table->record[0], table->s->reclength);
+ restore_record(table, record[1]);
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
#ifndef HAVE_purify
- DBUG_DUMP("record[0]", (const char *)table->record[0], m_master_reclength);
- DBUG_DUMP("m_after_image", (const char *)m_after_image, m_master_reclength);
+ DBUG_DUMP("record[0]", (const char *)table->record[0], table->s->reclength);
+ DBUG_DUMP("m_after_image", (const char *)m_after_image, table->s->reclength);
#endif
/*
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 356ff64d2e9..2a596a673f7 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1824,7 +1824,7 @@ int create_frm(THD *thd, const char *name, const char *db, const char *table,
HA_CREATE_INFO *create_info, uint keys);
void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
int rename_file_ext(const char * from,const char * to,const char * ext);
-bool check_db_name(char *db);
+bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name);
bool check_table_name(const char *name, uint length);
char *get_field(MEM_ROOT *mem, Field *field);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 423dfc19fdf..4acc7e4ee54 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5336,7 +5336,8 @@ master-ssl",
(gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
--skip-merge.",
- (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
+ 0},
{"myisam-recover", OPT_MYISAM_RECOVER,
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
(gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
diff --git a/sql/mysqld.cc.rej b/sql/mysqld.cc.rej
new file mode 100644
index 00000000000..62f0357622d
--- /dev/null
+++ b/sql/mysqld.cc.rej
@@ -0,0 +1,17 @@
+***************
+*** 5316,5322 ****
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
+ --skip-merge.",
+! (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
+--- 5336,5342 ----
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
+ --skip-merge.",
+! (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index a48c0ac0b31..b28d8189631 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -79,10 +79,16 @@ void mysql_client_binlog_statement(THD* thd)
char const *endptr= 0;
int bytes_decoded= base64_decode(strptr, coded_len, buf, &endptr);
+#ifndef HAVE_purify
+ /*
+ This debug printout should not be used for valgrind builds
+ since it will read from unassigned memory.
+ */
DBUG_PRINT("info",
("bytes_decoded: %d strptr: 0x%lx endptr: 0x%lx ('%c':%d)",
bytes_decoded, (long) strptr, (long) endptr, *endptr,
*endptr));
+#endif
if (bytes_decoded < 0)
{
@@ -146,11 +152,17 @@ void mysql_client_binlog_statement(THD* thd)
bufptr += event_len;
DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
+#ifndef HAVE_purify
+ /*
+ This debug printout should not be used for valgrind builds
+ since it will read from unassigned memory.
+ */
DBUG_PRINT("info",("bufptr+EVENT_TYPE_OFFSET: 0x%lx",
(long) (bufptr+EVENT_TYPE_OFFSET)));
DBUG_PRINT("info", ("bytes_decoded: %d bufptr: 0x%lx buf[EVENT_LEN_OFFSET]: %lu",
bytes_decoded, (long) bufptr,
uint4korr(bufptr+EVENT_LEN_OFFSET)));
+#endif
ev->thd= thd;
if (int err= ev->exec_event(thd->rli_fake))
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7b6cb47c4e7..e6f2ec7b041 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -425,6 +425,12 @@ public:
{ return strdup_root(mem_root,str); }
inline char *strmake(const char *str, uint size)
{ return strmake_root(mem_root,str,size); }
+ inline bool LEX_STRING_make(LEX_STRING *lex_str, const char *str, uint size)
+ {
+ return ((lex_str->str=
+ strmake_root(mem_root, str, (lex_str->length= size)))) == 0;
+ }
+
inline char *memdup(const char *str, uint size)
{ return memdup_root(mem_root,str,size); }
inline char *memdup_w_gap(const char *str, uint size, uint gap)
@@ -1628,8 +1634,7 @@ public:
return TRUE;
}
*p_db= strmake(db, db_length);
- if (p_db_length)
- *p_db_length= db_length;
+ *p_db_length= db_length;
return FALSE;
}
};
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 37096fd897e..0c154069bd6 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1302,8 +1302,8 @@ err:
bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
{
- int path_length, db_length;
- char *db_name;
+ int path_length;
+ LEX_STRING db_name;
bool system_db= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
@@ -1323,25 +1323,26 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
/* Called from SP to restore the original database, which was NULL */
DBUG_ASSERT(no_access_check);
system_db= 1;
- db_name= NULL;
- db_length= 0;
+ db_name.str= NULL;
+ db_name.length= 0;
goto end;
}
/*
Now we need to make a copy because check_db_name requires a
non-constant argument. TODO: fix check_db_name.
*/
- if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL)
+ if ((db_name.str= my_strdup(name, MYF(MY_WME))) == NULL)
DBUG_RETURN(1); /* the error is set */
- db_length= strlen(db_name);
- if (check_db_name(db_name))
+ db_name.length= strlen(db_name.str);
+ if (check_db_name(&db_name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db_name);
- my_free(db_name, MYF(0));
+ my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
- DBUG_PRINT("info",("Use database: %s", db_name));
- if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str))
+ DBUG_PRINT("info",("Use database: %s", db_name.str));
+ if (!my_strcasecmp(system_charset_info, db_name.str,
+ information_schema_name.str))
{
system_db= 1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1356,34 +1357,35 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
- db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) |
+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user,
+ db_name.str, 0) |
sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option ||
- check_grant_db(thd,db_name)))
+ check_grant_db(thd, db_name.str)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user,
sctx->priv_host,
- db_name);
+ db_name.str);
general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
- sctx->priv_user, sctx->priv_host, db_name);
- my_free(db_name,MYF(0));
+ sctx->priv_user, sctx->priv_host, db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
}
#endif
- if (check_db_dir_existence(db_name))
+ if (check_db_dir_existence(db_name.str))
{
- my_error(ER_BAD_DB_ERROR, MYF(0), db_name);
- my_free(db_name, MYF(0));
+ my_error(ER_BAD_DB_ERROR, MYF(0), db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
end:
x_free(thd->db);
- DBUG_ASSERT(db_name == NULL || db_name[0] != '\0');
- thd->reset_db(db_name, db_length); // THD::~THD will free this
+ DBUG_ASSERT(db_name.str == NULL || db_name.str[0] != '\0');
+ thd->reset_db(db_name.str, db_name.length); // THD::~THD will free this
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
sctx->db_access= db_access;
@@ -1397,7 +1399,7 @@ end:
{
HA_CREATE_INFO create;
- load_db_opt_by_name(thd, db_name, &create);
+ load_db_opt_by_name(thd, db_name.str, &create);
thd->db_charset= create.default_table_charset ?
create.default_table_charset :
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index ffd32bea42a..0f886bdf31d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -176,7 +176,8 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->reset_query_tables_list(FALSE);
lex->expr_allows_subselect= TRUE;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->event_parse_data= NULL;
lex->nest_level=0 ;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7e09675cb0a..90646043768 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -908,7 +908,8 @@ typedef struct st_lex : public Query_tables_list
/* The values of tok_start/tok_end as they were one call of MYSQLlex before */
const uchar *tok_start_prev, *tok_end_prev;
- char *length,*dec,*change,*name;
+ char *length,*dec,*change;
+ LEX_STRING name;
Table_ident *like_name;
char *help_arg;
char *backup_dir; /* For RESTORE/BACKUP */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2c130a45f77..5d7fdcae3f7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1055,11 +1055,14 @@ static int check_connection(THD *thd)
Old clients send null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of empty
password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
+ /* strlen() can't be easily deleted without changing protocol */
uint db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
@@ -1321,28 +1324,31 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->init_for_queries();
while (fgets(buff, thd->net.max_packet, file))
{
- ulong length= (ulong) strlen(buff);
- while (buff[length-1] != '\n' && !feof(file))
- {
- /*
- We got only a part of the current string. Will try to increase
- net buffer then read the rest of the current string.
- */
- if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
- {
- net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
- thd->fatal_error();
- break;
- }
- buff= (char*) thd->net.buff;
- fgets(buff + length, thd->net.max_packet - length, file);
- length+= (ulong) strlen(buff + length);
- }
- if (thd->is_fatal_error)
- break;
+ /* strlen() can't be deleted because fgets() doesn't return length */
+ ulong length= (ulong) strlen(buff);
+ while (buff[length-1] != '\n' && !feof(file))
+ {
+ /*
+ We got only a part of the current string. Will try to increase
+ net buffer then read the rest of the current string.
+ */
+ /* purecov: begin tested */
+ if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
+ {
+ net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
+ thd->fatal_error();
+ break;
+ }
+ buff= (char*) thd->net.buff;
+ fgets(buff + length, thd->net.max_packet - length, file);
+ length+= (ulong) strlen(buff + length);
+ /* purecov: end */
+ }
+ if (thd->is_fatal_error)
+ break; /* purecov: inspected */
while (length && (my_isspace(thd->charset(), buff[length-1]) ||
- buff[length-1] == ';'))
+ buff[length-1] == ';'))
length--;
buff[length]=0;
thd->query_length=length;
@@ -1427,24 +1433,30 @@ void cleanup_items(Item *item)
*/
static
-int mysql_table_dump(THD* thd, char* db, char* tbl_name)
+int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
{
TABLE* table;
TABLE_LIST* table_list;
int error = 0;
DBUG_ENTER("mysql_table_dump");
- db = (db && db[0]) ? db : thd->db;
+ if (db->length == 0)
+ {
+ db->str= thd->db; /* purecov: inspected */
+ db->length= thd->db_length; /* purecov: inspected */
+ }
if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(1); // out of memory
- table_list->db= db;
+ table_list->db= db->str;
table_list->table_name= table_list->alias= tbl_name;
table_list->lock_type= TL_READ_NO_INSERT;
table_list->prev_global= &table_list; // can be removed after merge with 4.1
- if (!db || check_db_name(db))
+ if (check_db_name(db))
{
- my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL");
+ /* purecov: begin inspected */
+ my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
goto err;
+ /* purecov: end */
}
if (lower_case_table_names)
my_casedn_str(files_charset_info, tbl_name);
@@ -1673,7 +1685,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB],
&LOCK_status);
thd->convert_string(&tmp, system_charset_info,
- packet, strlen(packet), thd->charset());
+ packet, packet_length-1, thd->charset());
if (!mysql_change_db(thd, tmp.str, FALSE))
{
general_log_print(thd, command, "%s",thd->db);
@@ -1691,7 +1703,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_TABLE_DUMP:
{
- char *db, *tbl_name;
+ char *tbl_name;
+ LEX_STRING db;
uint db_len= *(uchar*) packet;
if (db_len >= packet_length || db_len > NAME_LEN)
{
@@ -1707,34 +1720,41 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_other, &LOCK_status);
thd->enable_slow_log= opt_log_slow_admin_statements;
- db= thd->alloc(db_len + tbl_len + 2);
- if (!db)
+ db.str= thd->alloc(db_len + tbl_len + 2);
+ db.length= db_len;
+ if (!db.str)
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
break;
}
- tbl_name= strmake(db, packet + 1, db_len)+1;
+ tbl_name= strmake(db.str, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
- mysql_table_dump(thd, db, tbl_name);
+ mysql_table_dump(thd, &db, tbl_name);
break;
}
case COM_CHANGE_USER:
{
+ statistic_increment(thd->status_var.com_other, &LOCK_status);
+ char *user= (char*) packet, *packet_end= packet+ packet_length;
+ char *passwd= strend(user)+1;
+
thd->change_user();
thd->clear_error(); // if errors from rollback
- statistic_increment(thd->status_var.com_other, &LOCK_status);
- char *user= (char*) packet;
- char *passwd= strend(user)+1;
/*
Old clients send null-terminated string ('\0' for empty string) for
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
*/
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- *passwd++ : strlen(passwd);
+ char *save_db;
+ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd));
+ uint dummy_errors, save_db_length, db_length, res;
+ Security_context save_security_ctx= *thd->security_ctx;
+ USER_CONN *save_user_connect;
+
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
/* Small check for incoming packet */
@@ -1745,17 +1765,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
#endif
/* Convert database name to utf8 */
- uint dummy_errors;
+ /*
+ Handle problem with old bug in client protocol where db had an extra
+ \0
+ */
+ db_length= (packet_end - db);
+ if (db_length > 0 && db[db_length-1] == 0)
+ db_length--;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info, db, strlen(db),
+ system_charset_info, db, db_length,
thd->charset(), &dummy_errors)]= 0;
db= db_buff;
/* Save user and privileges */
- uint save_db_length= thd->db_length;
- char *save_db= thd->db;
- Security_context save_security_ctx= *thd->security_ctx;
- USER_CONN *save_user_connect= thd->user_connect;
+ save_db_length= thd->db_length;
+ save_db= thd->db;
+ save_user_connect= thd->user_connect;
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
{
@@ -1766,7 +1791,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Clear variables that are allocated */
thd->user_connect= 0;
- int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
+ res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
if (res)
{
@@ -1878,29 +1903,31 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
#else
{
- char *fields, *pend;
+ char *fields, *packet_end= packet + packet_length - 1, *arg_end;
/* Locked closure of all tables */
TABLE_LIST *locked_tables= NULL;
TABLE_LIST table_list;
LEX_STRING conv_name;
/* Saved variable value */
my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
-
+ uint dummy;
/* used as fields initializator */
lex_start(thd, 0, 0);
-
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
&LOCK_status);
bzero((char*) &table_list,sizeof(table_list));
- if (thd->copy_db_to(&table_list.db, 0))
+ if (thd->copy_db_to(&table_list.db, &dummy))
break;
- pend= strend(packet);
+ /*
+ We have name + wildcard in packet, separated by endzero
+ */
+ arg_end= strend(packet);
thd->convert_string(&conv_name, system_charset_info,
- packet, (uint) (pend-packet), thd->charset());
+ packet, (uint) (arg_end - packet), thd->charset());
table_list.alias= table_list.table_name= conv_name.str;
- packet= pend+1;
+ packet= arg_end + 1;
if (!my_strcasecmp(system_charset_info, table_list.db,
information_schema_name.str))
@@ -1910,7 +1937,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
table_list.schema_table= schema_table;
}
- thd->query_length= strlen(packet); // for simplicity: don't optimize
+ thd->query_length= (uint) (packet_end - packet); // Don't count end \0
if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
break;
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
@@ -1946,24 +1973,27 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
error=TRUE; // End server
break;
+#ifdef REMOVED
case COM_CREATE_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet), *alias;
+ LEX_STRING db, alias;
HA_CREATE_INFO create_info;
statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB],
&LOCK_status);
- // null test to handle EOM
- if (!db || !(alias= thd->strdup(db)) || check_db_name(db))
+ if (thd->LEX_STRING_make(&db, packet, packet_length -1) ||
+ thd->LEX_STRING_make(&alias, db.str, db.length) ||
+ check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
break;
}
- if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db)))
+ if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
+ is_schema_db(db.str)))
break;
general_log_print(thd, command, packet);
bzero(&create_info, sizeof(create_info));
- mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db),
+ mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
&create_info, 0);
break;
}
@@ -1971,14 +2001,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB],
&LOCK_status);
- char *db=thd->strdup(packet);
- /* null test to handle EOM */
- if (!db || check_db_name(db))
+ LEX_STRING db;
+
+ if (thd->LEX_STRING_make(&db, packet, packet_length - 1) ||
+ check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
break;
}
- if (check_access(thd,DROP_ACL,db,0,1,0,is_schema_db(db)))
+ if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -1986,10 +2017,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
break;
}
- general_log_print(thd, command, db);
- mysql_rm_db(thd, db, 0, 0);
+ general_log_print(thd, command, db.str);
+ mysql_rm_db(thd, db.str, 0, 0);
break;
}
+#endif
#ifndef EMBEDDED_LIBRARY
case COM_BINLOG_DUMP:
{
@@ -2071,37 +2103,47 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_STATISTICS:
{
- general_log_print(thd, command, NullS);
- statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
- &LOCK_status);
+ STATUS_VAR current_global_status_var;
+ ulong uptime;
+ uint length;
#ifndef EMBEDDED_LIBRARY
- char buff[200];
+ char buff[250];
+ uint buff_len= sizeof(buff);
#else
char *buff= thd->net.last_error;
+ uint buff_len= sizeof(thd->net.last_error);
#endif
- STATUS_VAR current_global_status_var;
+ general_log_print(thd, command, NullS);
+ statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
+ &LOCK_status);
calc_sum_of_all_status(&current_global_status_var);
-
- ulong uptime = (ulong) (thd->start_time - start_time);
- sprintf((char*) buff,
- "Uptime: %lu Threads: %d Questions: %lu Slow queries: %lu Opens: %lu Flush tables: %lu Open tables: %u Queries per second avg: %.3f",
- uptime,
- (int) thread_count, (ulong) thd->query_id,
- current_global_status_var.long_query_count,
- current_global_status_var.opened_tables, refresh_version,
- cached_open_tables(),
- (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) :
- (double) 0));
+ uptime= (ulong) (thd->start_time - start_time);
+ length= my_snprintf((char*) buff, buff_len - 1,
+ "Uptime: %lu Threads: %d Questions: %lu "
+ "Slow queries: %lu Opens: %lu Flush tables: %lu "
+ "Open tables: %u Queries per second avg: %.3f",
+ uptime,
+ (int) thread_count, (ulong) thd->query_id,
+ current_global_status_var.long_query_count,
+ current_global_status_var.opened_tables,
+ refresh_version,
+ cached_open_tables(),
+ (uptime ? (ulonglong2double(thd->query_id) /
+ (double) uptime) : (double) 0));
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
- sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK",
- (sf_malloc_cur_memory+1023L)/1024L,
- (sf_malloc_max_memory+1023L)/1024L);
+ {
+ char *end= buff + length;
+ length+= my_snprintf(end, buff_len - length - 1,
+ end," Memory in use: %ldK Max memory used: %ldK",
+ (sf_malloc_cur_memory+1023L)/1024L,
+ (sf_malloc_max_memory+1023L)/1024L);
+ }
#endif
#ifndef EMBEDDED_LIBRARY
- VOID(my_net_write(net, buff,(uint) strlen(buff)));
- VOID(net_flush(net));
+ VOID(my_net_write(net, buff, length));
+ VOID(net_flush(net));
#endif
break;
}
@@ -2298,26 +2340,28 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
#else
{
- char *db;
+ LEX_STRING db;
+ uint dummy;
if (lex->select_lex.db == NULL &&
- thd->copy_db_to(&lex->select_lex.db, 0))
+ thd->copy_db_to(&lex->select_lex.db, &dummy))
{
DBUG_RETURN(1);
}
- db= lex->select_lex.db;
- if (check_db_name(db))
+ db.str= lex->select_lex.db;
+ db.length= strlen(db.str);
+ if (check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db);
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
DBUG_RETURN(1);
}
- if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
- is_schema_db(db)))
+ if (check_access(thd, SELECT_ACL, db.str, &thd->col_access, 0, 0,
+ is_schema_db(db.str)))
DBUG_RETURN(1); /* purecov: inspected */
- if (!thd->col_access && check_grant_db(thd,db))
+ if (!thd->col_access && check_grant_db(thd, db.str))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
- db);
+ db.str);
DBUG_RETURN(1);
}
break;
@@ -2873,11 +2917,6 @@ mysql_execute_command(THD *thd)
if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
goto error;
}
- if (strlen(first_table->table_name) > NAME_LEN)
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->table_name);
- break;
- }
pthread_mutex_lock(&LOCK_active_mi);
/*
fetch_master_table will send the error to the client on failure.
@@ -3107,11 +3146,6 @@ end_with_restore_list:
if (lex->alter_info.flags & ALTER_DROP_PARTITION)
priv_needed|= DROP_ACL;
- if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
- goto error;
- }
/* Must be set in the parser */
DBUG_ASSERT(select_lex->db);
if (check_access(thd, priv_needed, first_table->db,
@@ -3127,11 +3161,11 @@ end_with_restore_list:
{
if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
goto error;
- if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
+ if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
{ // Rename of table
TABLE_LIST tmp_table;
bzero((char*) &tmp_table,sizeof(tmp_table));
- tmp_table.table_name=lex->name;
+ tmp_table.table_name= lex->name.str;
tmp_table.db=select_lex->db;
tmp_table.grant.privilege=priv;
if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
@@ -3159,7 +3193,7 @@ end_with_restore_list:
}
thd->enable_slow_log= opt_log_slow_admin_statements;
- res= mysql_alter_table(thd, select_lex->db, lex->name,
+ res= mysql_alter_table(thd, select_lex->db, lex->name.str,
&lex->create_info,
first_table, lex->create_list,
lex->key_list,
@@ -3771,9 +3805,10 @@ end_with_restore_list:
break;
}
char *alias;
- if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name))
+ if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
+ check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
/*
@@ -3785,17 +3820,18 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(lex->name) ||
- !rpl_filter->db_ok_with_wild_table(lex->name)))
+ (!rpl_filter->db_ok(lex->name.str) ||
+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd,CREATE_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+ if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
+ is_schema_db(lex->name.str)))
break;
- res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
- &lex->create_info, 0);
+ res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
+ lex->name.str), &lex->create_info, 0);
break;
}
case SQLCOM_DROP_DB:
@@ -3805,9 +3841,9 @@ end_with_restore_list:
res= -1;
break;
}
- if (check_db_name(lex->name))
+ if (check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
/*
@@ -3819,14 +3855,15 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(lex->name) ||
- !rpl_filter->db_ok_with_wild_table(lex->name)))
+ (!rpl_filter->db_ok(lex->name.str) ||
+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd,DROP_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+ if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
+ is_schema_db(lex->name.str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3834,7 +3871,7 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
+ res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
break;
}
case SQLCOM_RENAME_DB:
@@ -3860,6 +3897,11 @@ end_with_restore_list:
break;
}
#endif
+ if (check_db_name(newdb))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), newdb->str);
+ break;
+ }
if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
@@ -3881,11 +3923,10 @@ end_with_restore_list:
}
case SQLCOM_ALTER_DB:
{
- char *db= lex->name;
- DBUG_ASSERT(db); /* Must be set in the parser */
- if (!strip_sp(db) || check_db_name(db))
+ LEX_STRING *db= &lex->name;
+ if (check_db_name(db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db);
+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
break;
}
/*
@@ -3897,14 +3938,14 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(db) ||
- !rpl_filter->db_ok_with_wild_table(db)))
+ (!rpl_filter->db_ok(db->str) ||
+ !rpl_filter->db_ok_with_wild_table(db->str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd, ALTER_ACL, db, 0, 1, 0, is_schema_db(db)))
+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3912,17 +3953,17 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- res= mysql_alter_db(thd, db, &lex->create_info);
+ res= mysql_alter_db(thd, db->str, &lex->create_info);
break;
}
case SQLCOM_SHOW_CREATE_DB:
{
- if (!strip_sp(lex->name) || check_db_name(lex->name))
+ if (check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
- res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
+ res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
break;
}
case SQLCOM_CREATE_EVENT:
@@ -6308,7 +6349,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
}
if (table->is_derived_table() == FALSE && table->db.str &&
- check_db_name(table->db.str))
+ check_db_name(&table->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
DBUG_RETURN(0);
@@ -7592,7 +7633,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
/* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
/*
- Only do the check for PS, becasue we on execute we have to check that
+ Only do the check for PS, because we on execute we have to check that
against the opened tables to ensure we don't use a table that is part
of the view (which can only be done after the table has been opened).
*/
diff --git a/sql/sql_parse.cc.rej b/sql/sql_parse.cc.rej
new file mode 100644
index 00000000000..6e2bd03867d
--- /dev/null
+++ b/sql/sql_parse.cc.rej
@@ -0,0 +1,166 @@
+***************
+*** 67,109 ****
+ static void decrease_user_connections(USER_CONN *uc);
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ static bool check_multi_update_lock(THD *thd);
+- static void remove_escape(char *name);
+ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
+
+ const char *any_db="*any*"; // Special symbol for check_access
+
+! LEX_STRING command_name[]={
+! (char *)STRING_WITH_LEN("Sleep"),
+! (char *)STRING_WITH_LEN("Quit"),
+! (char *)STRING_WITH_LEN("Init DB"),
+! (char *)STRING_WITH_LEN("Query"),
+! (char *)STRING_WITH_LEN("Field List"),
+! (char *)STRING_WITH_LEN("Create DB"),
+! (char *)STRING_WITH_LEN("Drop DB"),
+! (char *)STRING_WITH_LEN("Refresh"),
+! (char *)STRING_WITH_LEN("Shutdown"),
+! (char *)STRING_WITH_LEN("Statistics"),
+! (char *)STRING_WITH_LEN("Processlist"),
+! (char *)STRING_WITH_LEN("Connect"),
+! (char *)STRING_WITH_LEN("Kill"),
+! (char *)STRING_WITH_LEN("Debug"),
+! (char *)STRING_WITH_LEN("Ping"),
+! (char *)STRING_WITH_LEN("Time"),
+! (char *)STRING_WITH_LEN("Delayed insert"),
+! (char *)STRING_WITH_LEN("Change user"),
+! (char *)STRING_WITH_LEN("Binlog Dump"),
+! (char *)STRING_WITH_LEN("Table Dump"),
+! (char *)STRING_WITH_LEN("Connect Out"),
+! (char *)STRING_WITH_LEN("Register Slave"),
+! (char *)STRING_WITH_LEN("Prepare"),
+! (char *)STRING_WITH_LEN("Execute"),
+! (char *)STRING_WITH_LEN("Long Data"),
+! (char *)STRING_WITH_LEN("Close stmt"),
+! (char *)STRING_WITH_LEN("Reset stmt"),
+! (char *)STRING_WITH_LEN("Set option"),
+! (char *)STRING_WITH_LEN("Fetch"),
+! (char *)STRING_WITH_LEN("Daemon"),
+! (char *)STRING_WITH_LEN("Error") // Last command number
+ };
+
+ const char *xa_state_names[]={
+--- 67,108 ----
+ static void decrease_user_connections(USER_CONN *uc);
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ static bool check_multi_update_lock(THD *thd);
+ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
+
+ const char *any_db="*any*"; // Special symbol for check_access
+
+! const LEX_STRING command_name[]={
+! C_STRING_WITH_LEN("Sleep"),
+! C_STRING_WITH_LEN("Quit"),
+! C_STRING_WITH_LEN("Init DB"),
+! C_STRING_WITH_LEN("Query"),
+! C_STRING_WITH_LEN("Field List"),
+! C_STRING_WITH_LEN("Create DB"),
+! C_STRING_WITH_LEN("Drop DB"),
+! C_STRING_WITH_LEN("Refresh"),
+! C_STRING_WITH_LEN("Shutdown"),
+! C_STRING_WITH_LEN("Statistics"),
+! C_STRING_WITH_LEN("Processlist"),
+! C_STRING_WITH_LEN("Connect"),
+! C_STRING_WITH_LEN("Kill"),
+! C_STRING_WITH_LEN("Debug"),
+! C_STRING_WITH_LEN("Ping"),
+! C_STRING_WITH_LEN("Time"),
+! C_STRING_WITH_LEN("Delayed insert"),
+! C_STRING_WITH_LEN("Change user"),
+! C_STRING_WITH_LEN("Binlog Dump"),
+! C_STRING_WITH_LEN("Table Dump"),
+! C_STRING_WITH_LEN("Connect Out"),
+! C_STRING_WITH_LEN("Register Slave"),
+! C_STRING_WITH_LEN("Prepare"),
+! C_STRING_WITH_LEN("Execute"),
+! C_STRING_WITH_LEN("Long Data"),
+! C_STRING_WITH_LEN("Close stmt"),
+! C_STRING_WITH_LEN("Reset stmt"),
+! C_STRING_WITH_LEN("Set option"),
+! C_STRING_WITH_LEN("Fetch"),
+! C_STRING_WITH_LEN("Daemon"),
+! C_STRING_WITH_LEN("Error") // Last command number
+ };
+
+ const char *xa_state_names[]={
+***************
+*** 1738,1744 ****
+ password. New clients send the size (1 byte) + string (not null
+ terminated, so also '\0' for empty string).
+ */
+! char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char *db= passwd;
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+--- 1736,1742 ----
+ password. New clients send the size (1 byte) + string (not null
+ terminated, so also '\0' for empty string).
+ */
+! char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char *db= passwd;
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+***************
+*** 2315,2321 ****
+ DBUG_RETURN(1);
+ }
+ db= lex->select_lex.db;
+- remove_escape(db); // Fix escaped '_'
+ if (check_db_name(db))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db);
+--- 2312,2317 ----
+ DBUG_RETURN(1);
+ }
+ db= lex->select_lex.db;
+ if (check_db_name(db))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db);
+***************
+*** 6310,6345 ****
+ }
+
+
+- /* Fix escaping of _, % and \ in database and table names (for ODBC) */
+-
+- static void remove_escape(char *name)
+- {
+- if (!*name) // For empty DB names
+- return;
+- char *to;
+- #ifdef USE_MB
+- char *strend=name+(uint) strlen(name);
+- #endif
+- for (to=name; *name ; name++)
+- {
+- #ifdef USE_MB
+- int l;
+- if (use_mb(system_charset_info) &&
+- (l = my_ismbchar(system_charset_info, name, strend)))
+- {
+- while (l--)
+- *to++ = *name++;
+- name--;
+- continue;
+- }
+- #endif
+- if (*name == '\\' && name[1])
+- name++; // Skip '\\'
+- *to++= *name;
+- }
+- *to=0;
+- }
+-
+ /****************************************************************************
+ ** save order by and tables in own lists
+ ****************************************************************************/
+--- 6296,6301 ----
+ }
+
+
+ /****************************************************************************
+ ** save order by and tables in own lists
+ ****************************************************************************/
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a0149b1a34d..1f00275621a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4631,7 +4631,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
DBUG_RETURN(TRUE);
}
- if (!src_db || check_db_name(src_db))
+ if (!src_db || check_db_name(&table_ident->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL");
DBUG_RETURN(-1);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6a829171125..14d9e83192a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -735,7 +735,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem
+ sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
%type <lex_str_ptr>
opt_table_alias
@@ -745,7 +745,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <simple_string>
remember_name remember_end opt_ident opt_db text_or_password
- opt_constraint constraint ident_or_empty
+ opt_constraint constraint
%type <string>
text_string opt_gconcat_separator
@@ -1229,7 +1229,8 @@ create:
lex->create_info.options=$2 | $4;
lex->create_info.db_type= lex->thd->variables.table_type;
lex->create_info.default_table_charset= NULL;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->like_name= 0;
}
create2
@@ -1269,7 +1270,7 @@ create:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CREATE_DB;
- lex->name=$4.str;
+ lex->name= $4;
lex->create_info.options=$3;
}
| CREATE
@@ -1504,7 +1505,7 @@ clear_privileges:
sp_name:
ident '.' ident
{
- if (!$1.str || check_db_name($1.str))
+ if (!$1.str || check_db_name(&$1))
{
my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
YYABORT;
@@ -3094,7 +3095,7 @@ size_number:
uint text_shift_number= 0;
longlong prefix_number;
char *start_ptr= $1.str;
- uint str_len= strlen(start_ptr);
+ uint str_len= $1.length;
char *end_ptr= start_ptr + str_len;
int error;
prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
@@ -4618,7 +4619,8 @@ alter:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->sql_command= SQLCOM_ALTER_TABLE;
lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
@@ -4628,7 +4630,6 @@ alter:
lex->key_list.empty();
lex->col_list.empty();
lex->select_lex.init_order();
- lex->name= 0;
lex->like_name= 0;
lex->select_lex.db=
((TABLE_LIST*) lex->select_lex.table_list.first)->db;
@@ -4653,7 +4654,8 @@ alter:
THD *thd= Lex->thd;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name= $3;
- if (lex->name == NULL && thd->copy_db_to(&lex->name, NULL))
+ if (lex->name.str == NULL &&
+ thd->copy_db_to(&lex->name.str, &lex->name.length))
YYABORT;
}
| ALTER PROCEDURE sp_name
@@ -4803,8 +4805,8 @@ opt_ev_sql_stmt: /* empty*/ { $$= 0;}
ident_or_empty:
- /* empty */ { $$= 0; }
- | ident { $$= $1.str; };
+ /* empty */ { $$.str= 0; $$.length= 0; }
+ | ident { $$= $1; };
alter_commands:
| DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; }
@@ -5082,19 +5084,20 @@ alter_list_item:
{
LEX *lex=Lex;
THD *thd= lex->thd;
+ uint dummy;
lex->select_lex.db=$3->db.str;
if (lex->select_lex.db == NULL &&
- thd->copy_db_to(&lex->select_lex.db, NULL))
+ thd->copy_db_to(&lex->select_lex.db, &dummy))
{
YYABORT;
}
if (check_table_name($3->table.str,$3->table.length) ||
- $3->db.str && check_db_name($3->db.str))
+ $3->db.str && check_db_name(&$3->db))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
YYABORT;
}
- lex->name= $3->table.str;
+ lex->name= $3->table;
lex->alter_info.flags|= ALTER_RENAME;
}
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
@@ -7627,7 +7630,7 @@ drop:
LEX *lex=Lex;
lex->sql_command= SQLCOM_DROP_DB;
lex->drop_if_exists=$3;
- lex->name=$4.str;
+ lex->name= $4;
}
| DROP FUNCTION_SYM if_exists sp_name
{
@@ -8274,7 +8277,7 @@ show_param:
{
Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
Lex->create_info.options=$3;
- Lex->name=$4.str;
+ Lex->name= $4;
}
| CREATE TABLE_SYM table_ident
{
@@ -10279,7 +10282,8 @@ grant_ident:
{
LEX *lex= Lex;
THD *thd= lex->thd;
- if (thd->copy_db_to(&lex->current_select->db, NULL))
+ uint dummy;
+ if (thd->copy_db_to(&lex->current_select->db, &dummy))
YYABORT;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
diff --git a/sql/table.cc b/sql/table.cc
index 0ddaf99810d..762206c7eb8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2254,7 +2254,7 @@ char *get_field(MEM_ROOT *mem, Field *field)
SYNPOSIS
check_db_name()
- name Name of database
+ org_name Name of database and length
NOTES
If lower_case_table_names is set then database is converted to lower case
@@ -2264,35 +2264,35 @@ char *get_field(MEM_ROOT *mem, Field *field)
1 error
*/
-bool check_db_name(char *name)
+bool check_db_name(LEX_STRING *org_name)
{
- char *start= name;
- /* Used to catch empty names and names with end space */
- bool last_char_is_space= TRUE;
+ char *name= org_name->str;
+
+ if (!org_name->length || org_name->length > NAME_LEN)
+ return 1;
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
- while (*name)
- {
#if defined(USE_MB) && defined(USE_MB_IDENT)
- last_char_is_space= my_isspace(system_charset_info, *name);
- if (use_mb(system_charset_info))
+ if (use_mb(system_charset_info))
+ {
+ bool last_char_is_space= TRUE;
+ char *end= name + org_name->length;
+ while (name < end)
{
- int len=my_ismbchar(system_charset_info, name,
- name+system_charset_info->mbmaxlen);
- if (len)
- {
- name += len;
- continue;
- }
+ int len;
+ last_char_is_space= my_isspace(system_charset_info, *name);
+ len= my_ismbchar(system_charset_info, name, end);
+ if (!len)
+ len= 1;
+ name+= len;
}
-#else
- last_char_is_space= *name==' ';
-#endif
- name++;
+ return last_char_is_space;
}
- return last_char_is_space || (uint) (name - start) > NAME_LEN;
+ else
+#endif
+ return org_name->str[org_name->length - 1] != ' '; /* purecov: inspected */
}
diff --git a/sql/table.cc.rej b/sql/table.cc.rej
new file mode 100644
index 00000000000..fd728ba9965
--- /dev/null
+++ b/sql/table.cc.rej
@@ -0,0 +1,17 @@
+***************
+*** 2246,2252 ****
+
+ bool check_db_name(char *name)
+ {
+! char *start=name;
+ /* Used to catch empty names and names with end space */
+ bool last_char_is_space= TRUE;
+
+--- 2257,2263 ----
+
+ bool check_db_name(char *name)
+ {
+! char *start= name;
+ /* Used to catch empty names and names with end space */
+ bool last_char_is_space= TRUE;
+
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 33656c0d10e..56b665b098e 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -33,6 +33,7 @@
#include <errmsg.h>
#include <my_getopt.h>
#include <m_string.h>
+#include <mysqld_error.h>
#define VER "2.1"
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
@@ -12017,13 +12018,21 @@ static void test_bug6081()
rc= simple_command(mysql, COM_DROP_DB, current_db,
(ulong)strlen(current_db), 0);
- myquery(rc);
+ if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
+ {
+ myerror(NULL); /* purecov: inspected */
+ die(__FILE__, __LINE__, "COM_DROP_DB failed"); /* purecov: inspected */
+ }
rc= simple_command(mysql, COM_DROP_DB, current_db,
(ulong)strlen(current_db), 0);
myquery_r(rc);
rc= simple_command(mysql, COM_CREATE_DB, current_db,
(ulong)strlen(current_db), 0);
- myquery(rc);
+ if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
+ {
+ myerror(NULL); /* purecov: inspected */
+ die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
+ }
rc= simple_command(mysql, COM_CREATE_DB, current_db,
(ulong)strlen(current_db), 0);
myquery_r(rc);
@@ -15476,6 +15485,24 @@ static void test_bug21206()
}
/*
+ Ensure we execute the status code while testing
+*/
+
+static void test_status()
+{
+ const char *status;
+ DBUG_ENTER("test_status");
+ myheader("test_status");
+
+ if (!(status= mysql_stat(mysql)))
+ {
+ myerror("mysql_stat failed"); /* purecov: inspected */
+ die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
Bug#21726: Incorrect result with multiple invocations of
LAST_INSERT_ID
@@ -15791,6 +15818,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug19671", test_bug19671 },
{ "test_bug21206", test_bug21206 },
{ "test_bug21726", test_bug21726 },
+ { "test_status", test_status},
{ 0, 0 }
};
diff --git a/tests/mysql_client_test.c.rej b/tests/mysql_client_test.c.rej
new file mode 100644
index 00000000000..400ffee8a5e
--- /dev/null
+++ b/tests/mysql_client_test.c.rej
@@ -0,0 +1,20 @@
+***************
+*** 15693,15700 ****
+ { "test_bug17667", test_bug17667 },
+ { "test_bug15752", test_bug15752 },
+ { "test_mysql_insert_id", test_mysql_insert_id },
+! { "test_bug19671", test_bug19671},
+! { "test_bug21206", test_bug21206},
+ { 0, 0 }
+ };
+
+--- 15776,15784 ----
+ { "test_bug17667", test_bug17667 },
+ { "test_bug15752", test_bug15752 },
+ { "test_mysql_insert_id", test_mysql_insert_id },
+! { "test_bug19671", test_bug19671 },
+! { "test_bug21206", test_bug21206 },
+! { "test_bug21726", test_bug21726 },
+ { 0, 0 }
+ };
+