From 6d0aed42c5ea202eabf9f44d777a3e258d14ee60 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 22 Jun 2017 17:15:10 +0400 Subject: [PATCH] MDEV-12070 - Introduce thd_query_safe() from MySQL 5.7 Merged relevant part of MySQL revision: https://github.com/mysql/mysql-server/commit/565d20b44f24fcc855dc616164d87b03cfad10bc --- sql/sql_class.cc | 37 ++++++++++++++++++----- sql/sql_class.h | 3 +- storage/innobase/handler/ha_innodb.cc | 17 +---------- storage/innobase/handler/handler0alter.cc | 4 ++- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f8cf8295881..3ad3b6adf89 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4509,26 +4509,47 @@ extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd) return(thd->charset()); } -/** - OBSOLETE : there's no way to ensure the string is null terminated. - Use thd_query_string instead() -*/ -extern "C" char **thd_query(MYSQL_THD thd) -{ - return (&thd->query_string.string.str); -} /** Get the current query string for the thread. + This function is not thread safe and can be used only by thd owner thread. + @param The MySQL internal thread pointer @return query string and length. May be non-null-terminated. */ extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd) { + DBUG_ASSERT(thd == current_thd); return(&thd->query_string.string); } + +/** + Get the current query string for the thread. + + @param thd The MySQL internal thread pointer + @param buf Buffer where the query string will be copied + @param buflen Length of the buffer + + @return Length of the query + + @note This function is thread safe as the query string is + accessed under mutex protection and the string is copied + into the provided buffer. @see thd_query_string(). +*/ + +extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen) +{ + mysql_mutex_lock(&thd->LOCK_thd_data); + size_t len= MY_MIN(buflen - 1, thd->query_length()); + memcpy(buf, thd->query(), len); + mysql_mutex_unlock(&thd->LOCK_thd_data); + buf[len]= '\0'; + return len; +} + + extern "C" int thd_slave_thread(const MYSQL_THD thd) { return(thd->slave_thread); diff --git a/sql/sql_class.h b/sql/sql_class.h index 2d1bf8a9886..0a1be8c13c8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -153,7 +153,7 @@ extern MYSQL_PLUGIN_IMPORT const char **errmesg; extern bool volatile shutdown_in_progress; extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd); -extern "C" char **thd_query(MYSQL_THD thd); +extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen); /** @class CSET_STRING @@ -183,7 +183,6 @@ public: CHARSET_INFO *charset() const { return cs; } friend LEX_STRING * thd_query_string (MYSQL_THD thd); - friend char **thd_query(MYSQL_THD thd); }; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a54176f8410..d8a4d8d2742 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2462,22 +2462,7 @@ innobase_get_stmt_safe( char* buf, size_t buflen) { - LEX_STRING* stmt; - size_t length=0; - - ut_ad(buflen > 1); - - stmt = thd ? thd_query_string(thd) : NULL; - - if (stmt && stmt->str) { - length = stmt->length >= buflen ? buflen - 1 : stmt->length; - memcpy(buf, stmt->str, length); - buf[length]='\0'; - } else { - buf[0]='\0'; - } - - return (length); + return thd_query_safe(thd, buf, buflen); } /**********************************************************************//** diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 107205e0375..2631f525dba 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4471,11 +4471,13 @@ prepare_inplace_alter_table_dict( || !innobase_fulltext_exist(altered_table))) { /* InnoDB can perform an online operation (LOCK=NONE). */ } else { + size_t query_length; /* This should have been blocked in check_if_supported_inplace_alter(). */ ut_ad(0); my_error(ER_NOT_SUPPORTED_YET, MYF(0), - thd_query(ctx->prebuilt->trx->mysql_thd)); + innobase_get_stmt_unsafe(ctx->prebuilt->trx->mysql_thd, + &query_length)); goto error_handled; }