You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.7 KiB

  1. /* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  13. #include "mysql_priv.h"
  14. #include "base64.h"
  15. /*
  16. Execute a BINLOG statement
  17. TODO: This currently assumes a MySQL 5.x binlog.
  18. When we'll have binlog with a different format, to execute the
  19. BINLOG command properly the server will need to know which format
  20. the BINLOG command's event is in. mysqlbinlog should then send
  21. the Format_description_log_event of the binlog it reads and the
  22. server thread should cache this format into
  23. rli->description_event_for_exec.
  24. */
  25. void mysql_client_binlog_statement(THD* thd)
  26. {
  27. DBUG_PRINT("info",("binlog base64: '%*s'",
  28. (thd->lex->comment.length < 2048 ?
  29. thd->lex->comment.length : 2048),
  30. thd->lex->comment.str));
  31. /*
  32. Temporarily turn off send_ok, since different events handle this
  33. differently
  34. */
  35. my_bool nsok= thd->net.no_send_ok;
  36. thd->net.no_send_ok= TRUE;
  37. const my_size_t coded_len= thd->lex->comment.length + 1;
  38. const my_size_t event_len= base64_needed_decoded_length(coded_len);
  39. DBUG_ASSERT(coded_len > 0);
  40. /*
  41. Allocation
  42. */
  43. if (!thd->rli_fake)
  44. thd->rli_fake= new RELAY_LOG_INFO;
  45. const Format_description_log_event *desc=
  46. new Format_description_log_event(4);
  47. const char *error= 0;
  48. char *buf= (char *) my_malloc(event_len, MYF(MY_WME));
  49. Log_event *ev = 0;
  50. int res;
  51. /*
  52. Out of memory check
  53. */
  54. if (!(thd->rli_fake && desc && buf))
  55. {
  56. my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
  57. goto end;
  58. }
  59. thd->rli_fake->sql_thd= thd;
  60. thd->rli_fake->no_storage= TRUE;
  61. res= base64_decode(thd->lex->comment.str, coded_len, buf);
  62. DBUG_PRINT("info",("binlog base64 decoded_len=%d, event_len=%d\n",
  63. res, uint4korr(buf + EVENT_LEN_OFFSET)));
  64. /*
  65. Note that 'res' is the correct event length, 'event_len' was
  66. calculated based on the base64-string that possibly contained
  67. extra spaces, so it can be longer than the real event.
  68. */
  69. if (res < EVENT_LEN_OFFSET
  70. || (uint) res != uint4korr(buf+EVENT_LEN_OFFSET))
  71. {
  72. my_error(ER_SYNTAX_ERROR, MYF(0));
  73. goto end;
  74. }
  75. ev= Log_event::read_log_event(buf, res, &error, desc);
  76. DBUG_PRINT("info",("binlog base64 err=%s", error));
  77. if (!ev)
  78. {
  79. /*
  80. This could actually be an out-of-memory, but it is more
  81. likely causes by a bad statement
  82. */
  83. my_error(ER_SYNTAX_ERROR, MYF(0));
  84. goto end;
  85. }
  86. DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
  87. DBUG_PRINT("info",("buf+EVENT_TYPE_OFFSET=%d", buf+EVENT_TYPE_OFFSET));
  88. ev->thd= thd;
  89. if (ev->exec_event(thd->rli_fake))
  90. {
  91. my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
  92. goto end;
  93. }
  94. /*
  95. Restore setting of no_send_ok
  96. */
  97. thd->net.no_send_ok= nsok;
  98. DBUG_PRINT("info",("binlog base64 execution finished successfully"));
  99. send_ok(thd);
  100. end:
  101. /*
  102. Restore setting of no_send_ok
  103. */
  104. thd->net.no_send_ok= nsok;
  105. if (ev)
  106. delete ev;
  107. if (desc)
  108. delete desc;
  109. if (buf)
  110. my_free(buf, MYF(0));
  111. }