diff options
author | unknown <cmiller@zippy.cornsilk.net> | 2008-05-14 19:23:54 -0400 |
---|---|---|
committer | unknown <cmiller@zippy.cornsilk.net> | 2008-05-14 19:23:54 -0400 |
commit | cae6079f5a93d9e2621187a4afb4b3cd3e333483 (patch) | |
tree | e9ff580afba695fee7ea25cc25326ed1994ad640 /sql/sp.cc | |
parent | ab6e91cf3af9ef3d69e80420eef1ada05d66b9f7 (diff) | |
download | mariadb-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.cc | 32 |
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(')'); |