summaryrefslogtreecommitdiff
path: root/sql/sp.cc
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2008-05-14 19:23:54 -0400
committerunknown <cmiller@zippy.cornsilk.net>2008-05-14 19:23:54 -0400
commitcae6079f5a93d9e2621187a4afb4b3cd3e333483 (patch)
treee9ff580afba695fee7ea25cc25326ed1994ad640 /sql/sp.cc
parentab6e91cf3af9ef3d69e80420eef1ada05d66b9f7 (diff)
downloadmariadb-git-cae6079f5a93d9e2621187a4afb4b3cd3e333483.tar.gz
Bug#36570: Parse error of CREATE PROCEDURE stmt with comments on \
slave The stored-routine code took the contents of the (lowest) parser and copied it directly to the binlog, which causes problems if there is a special case of interpretation at the parser level -- which there is, in the "/*!VER */" comments. The trailing "*/" caused errors on the slave, naturally. Now, since by that point we have /properly/ created parse-tree (as the rest of the server should do!) for the stored-routine CREATE, we can construct a perfect statement from that information, instead of writing uncertain information from an unknown parser state. Fortunately, there's already a function nearby that does exactly that. mysql-test/r/binlog_innodb.result: Offsets changed due to quoting. mysql-test/r/ctype_cp932_binlog.result: Offsets changed due to quoting. mysql-test/r/mysqlbinlog.result: Case changed in result due to interpretation of data instead of literal recitation. mysql-test/r/rpl_sp.result: Offsets changed due to quoting. Added tests. mysql-test/t/rpl_sp.test: Add version-limiting quotes to exercise bug#36570. Test that backtick-quoted identifiers and labels work also. sql/sp.cc: In create_string, we may not have a sp_name parameter yet, so instead pass the char* and length of the only member we'd get out of it. Having done that, we can use the same function to write the CREATE (FUNC|TRIG|PROC) statement to the binlog as we always used to display the statement to the user.
Diffstat (limited to 'sql/sp.cc')
-rw-r--r--sql/sp.cc32
1 files changed, 19 insertions, 13 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index 7224d3c4f0e..390a23b91b1 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -25,7 +25,7 @@
static bool
create_string(THD *thd, String *buf,
int sp_type,
- sp_name *name,
+ const char *name, ulong namelen,
const char *params, ulong paramslen,
const char *returns, ulong returnslen,
const char *body, ulong bodylen,
@@ -427,7 +427,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
if (!create_string(thd, &defstr,
type,
- name,
+ name->m_name.str, name->m_name.length,
params, strlen(params),
returns, strlen(returns),
body, strlen(body),
@@ -518,6 +518,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
DBUG_ENTER("db_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
sp->m_name.str));
+ String retstr(64);
if (!(table= open_proc_table_for_update(thd)))
ret= SP_OPEN_TABLE_FAILED;
@@ -568,7 +569,6 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store(sp->m_params.str, sp->m_params.length, system_charset_info);
if (sp->m_type == TYPE_ENUM_FUNCTION)
{
- String retstr(64);
sp_returns_type(thd, retstr, sp);
table->field[MYSQL_PROC_FIELD_RETURNS]->
store(retstr.ptr(), retstr.length(), system_charset_info);
@@ -625,13 +625,19 @@ db_create_routine(THD *thd, int type, sp_head *sp)
String log_query;
log_query.set_charset(system_charset_info);
- log_query.append(STRING_WITH_LEN("CREATE "));
- append_definer(thd, &log_query, &thd->lex->definer->user,
- &thd->lex->definer->host);
- log_query.append(thd->lex->stmt_definition_begin,
- (char *)sp->m_body_begin -
- thd->lex->stmt_definition_begin +
- sp->m_body.length);
+
+ if (!create_string(thd, &log_query,
+ sp->m_type,
+ sp->m_name.str, sp->m_name.length,
+ sp->m_params.str, sp->m_params.length,
+ retstr.c_ptr(), retstr.length(),
+ sp->m_body.str, sp->m_body.length,
+ sp->m_chistics, &(thd->lex->definer->user),
+ &(thd->lex->definer->host)))
+ {
+ ret= SP_INTERNAL_ERROR;
+ goto done;
+ }
/* Such a statement can always go directly to binlog, no trans cache */
Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0,
@@ -1798,7 +1804,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
static bool
create_string(THD *thd, String *buf,
int type,
- sp_name *name,
+ const char *name, ulong namelen,
const char *params, ulong paramslen,
const char *returns, ulong returnslen,
const char *body, ulong bodylen,
@@ -1807,7 +1813,7 @@ create_string(THD *thd, String *buf,
const LEX_STRING *definer_host)
{
/* Make some room to begin with */
- if (buf->alloc(100 + name->m_qname.length + paramslen + returnslen + bodylen +
+ if (buf->alloc(100 + namelen + paramslen + returnslen + bodylen +
chistics->comment.length + 10 /* length of " DEFINER= "*/ +
USER_HOST_BUFF_SIZE))
return FALSE;
@@ -1818,7 +1824,7 @@ create_string(THD *thd, String *buf,
buf->append(STRING_WITH_LEN("FUNCTION "));
else
buf->append(STRING_WITH_LEN("PROCEDURE "));
- append_identifier(thd, buf, name->m_name.str, name->m_name.length);
+ append_identifier(thd, buf, name, namelen);
buf->append('(');
buf->append(params, paramslen);
buf->append(')');