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.

655 lines
17 KiB

MDEV-5120 Test suite test maria-no-logging fails The reason for the failure was a bug in an include file on debian that causes 'struct stat' to have different sized depending on the environment. This patch fixes so that we always include my_global.h or my_config.h before we include any other files. Other things: - Removed #include <my_global.h> in some include files; Better to always do this at the top level to have as few "always-include-this-file-first' files as possible. - Removed usage of some include files that where already included by my_global.h or by other files. client/mysql_plugin.c: Use my_global.h first client/mysqlslap.c: Remove duplicated include files extra/comp_err.c: Remove duplicated include files include/m_string.h: Remove duplicated include files include/maria.h: Remove duplicated include files libmysqld/emb_qcache.cc: Use my_global.h first plugin/semisync/semisync.h: Use my_pthread.h first sql/datadict.cc: Use my_global.h first sql/debug_sync.cc: Use my_global.h first sql/derror.cc: Use my_global.h first sql/des_key_file.cc: Use my_global.h first sql/discover.cc: Use my_global.h first sql/event_data_objects.cc: Use my_global.h first sql/event_db_repository.cc: Use my_global.h first sql/event_parse_data.cc: Use my_global.h first sql/event_queue.cc: Use my_global.h first sql/event_scheduler.cc: Use my_global.h first sql/events.cc: Use my_global.h first sql/field.cc: Use my_global.h first Remove duplicated include files sql/field_conv.cc: Use my_global.h first sql/filesort.cc: Use my_global.h first Remove duplicated include files sql/gstream.cc: Use my_global.h first sql/ha_ndbcluster.cc: Use my_global.h first sql/ha_ndbcluster_binlog.cc: Use my_global.h first sql/ha_ndbcluster_cond.cc: Use my_global.h first sql/ha_partition.cc: Use my_global.h first sql/handler.cc: Use my_global.h first sql/hash_filo.cc: Use my_global.h first sql/hostname.cc: Use my_global.h first sql/init.cc: Use my_global.h first sql/item.cc: Use my_global.h first sql/item_buff.cc: Use my_global.h first sql/item_cmpfunc.cc: Use my_global.h first sql/item_create.cc: Use my_global.h first sql/item_geofunc.cc: Use my_global.h first sql/item_inetfunc.cc: Use my_global.h first sql/item_row.cc: Use my_global.h first sql/item_strfunc.cc: Use my_global.h first sql/item_subselect.cc: Use my_global.h first sql/item_sum.cc: Use my_global.h first sql/item_timefunc.cc: Use my_global.h first sql/item_xmlfunc.cc: Use my_global.h first sql/key.cc: Use my_global.h first sql/lock.cc: Use my_global.h first sql/log.cc: Use my_global.h first sql/log_event.cc: Use my_global.h first sql/log_event_old.cc: Use my_global.h first sql/mf_iocache.cc: Use my_global.h first sql/mysql_install_db.cc: Remove duplicated include files sql/mysqld.cc: Remove duplicated include files sql/net_serv.cc: Remove duplicated include files sql/opt_range.cc: Use my_global.h first sql/opt_subselect.cc: Use my_global.h first sql/opt_sum.cc: Use my_global.h first sql/parse_file.cc: Use my_global.h first sql/partition_info.cc: Use my_global.h first sql/procedure.cc: Use my_global.h first sql/protocol.cc: Use my_global.h first sql/records.cc: Use my_global.h first sql/records.h: Don't include my_global.h Better to do this at the upper level sql/repl_failsafe.cc: Use my_global.h first sql/rpl_filter.cc: Use my_global.h first sql/rpl_gtid.cc: Use my_global.h first sql/rpl_handler.cc: Use my_global.h first sql/rpl_injector.cc: Use my_global.h first sql/rpl_record.cc: Use my_global.h first sql/rpl_record_old.cc: Use my_global.h first sql/rpl_reporting.cc: Use my_global.h first sql/rpl_rli.cc: Use my_global.h first sql/rpl_tblmap.cc: Use my_global.h first sql/rpl_utility.cc: Use my_global.h first sql/set_var.cc: Added comment sql/slave.cc: Use my_global.h first sql/sp.cc: Use my_global.h first sql/sp_cache.cc: Use my_global.h first sql/sp_head.cc: Use my_global.h first sql/sp_pcontext.cc: Use my_global.h first sql/sp_rcontext.cc: Use my_global.h first sql/spatial.cc: Use my_global.h first sql/sql_acl.cc: Use my_global.h first sql/sql_admin.cc: Use my_global.h first sql/sql_analyse.cc: Use my_global.h first sql/sql_audit.cc: Use my_global.h first sql/sql_base.cc: Use my_global.h first sql/sql_binlog.cc: Use my_global.h first sql/sql_bootstrap.cc: Use my_global.h first Use my_global.h first sql/sql_cache.cc: Use my_global.h first sql/sql_class.cc: Use my_global.h first sql/sql_client.cc: Use my_global.h first sql/sql_connect.cc: Use my_global.h first sql/sql_crypt.cc: Use my_global.h first sql/sql_cursor.cc: Use my_global.h first sql/sql_db.cc: Use my_global.h first sql/sql_delete.cc: Use my_global.h first sql/sql_derived.cc: Use my_global.h first sql/sql_do.cc: Use my_global.h first sql/sql_error.cc: Use my_global.h first sql/sql_explain.cc: Use my_global.h first sql/sql_expression_cache.cc: Use my_global.h first sql/sql_handler.cc: Use my_global.h first sql/sql_help.cc: Use my_global.h first sql/sql_insert.cc: Use my_global.h first sql/sql_lex.cc: Use my_global.h first sql/sql_load.cc: Use my_global.h first sql/sql_locale.cc: Use my_global.h first sql/sql_manager.cc: Use my_global.h first sql/sql_parse.cc: Use my_global.h first sql/sql_partition.cc: Use my_global.h first sql/sql_plugin.cc: Added comment sql/sql_prepare.cc: Use my_global.h first sql/sql_priv.h: Added error if we use this before including my_global.h This check is here becasue so many files includes sql_priv.h first. sql/sql_profile.cc: Use my_global.h first sql/sql_reload.cc: Use my_global.h first sql/sql_rename.cc: Use my_global.h first sql/sql_repl.cc: Use my_global.h first sql/sql_select.cc: Use my_global.h first sql/sql_servers.cc: Use my_global.h first sql/sql_show.cc: Added comment sql/sql_signal.cc: Use my_global.h first sql/sql_statistics.cc: Use my_global.h first sql/sql_table.cc: Use my_global.h first sql/sql_tablespace.cc: Use my_global.h first sql/sql_test.cc: Use my_global.h first sql/sql_time.cc: Use my_global.h first sql/sql_trigger.cc: Use my_global.h first sql/sql_udf.cc: Use my_global.h first sql/sql_union.cc: Use my_global.h first sql/sql_update.cc: Use my_global.h first sql/sql_view.cc: Use my_global.h first sql/sys_vars.cc: Added comment sql/table.cc: Use my_global.h first sql/thr_malloc.cc: Use my_global.h first sql/transaction.cc: Use my_global.h first sql/uniques.cc: Use my_global.h first sql/unireg.cc: Use my_global.h first sql/unireg.h: Removed inclusion of my_global.h storage/archive/ha_archive.cc: Added comment storage/blackhole/ha_blackhole.cc: Use my_global.h first storage/csv/ha_tina.cc: Use my_global.h first storage/csv/transparent_file.cc: Use my_global.h first storage/federated/ha_federated.cc: Use my_global.h first storage/federatedx/federatedx_io.cc: Use my_global.h first storage/federatedx/federatedx_io_mysql.cc: Use my_global.h first storage/federatedx/federatedx_io_null.cc: Use my_global.h first storage/federatedx/federatedx_txn.cc: Use my_global.h first storage/heap/ha_heap.cc: Use my_global.h first storage/innobase/handler/handler0alter.cc: Use my_global.h first storage/maria/ha_maria.cc: Use my_global.h first storage/maria/unittest/ma_maria_log_cleanup.c: Remove duplicated include files storage/maria/unittest/test_file.c: Added comment storage/myisam/ha_myisam.cc: Move sql_plugin.h first as this includes my_global.h storage/myisammrg/ha_myisammrg.cc: Use my_global.h first storage/oqgraph/oqgraph_thunk.cc: Use my_config.h and my_global.h first One could not include my_global.h before oqgraph_thunk.h (don't know why) storage/spider/ha_spider.cc: Use my_global.h first storage/spider/hs_client/config.cpp: Use my_global.h first storage/spider/hs_client/escape.cpp: Use my_global.h first storage/spider/hs_client/fatal.cpp: Use my_global.h first storage/spider/hs_client/hstcpcli.cpp: Use my_global.h first storage/spider/hs_client/socket.cpp: Use my_global.h first storage/spider/hs_client/string_util.cpp: Use my_global.h first storage/spider/spd_conn.cc: Use my_global.h first storage/spider/spd_copy_tables.cc: Use my_global.h first storage/spider/spd_db_conn.cc: Use my_global.h first storage/spider/spd_db_handlersocket.cc: Use my_global.h first storage/spider/spd_db_mysql.cc: Use my_global.h first storage/spider/spd_db_oracle.cc: Use my_global.h first storage/spider/spd_direct_sql.cc: Use my_global.h first storage/spider/spd_i_s.cc: Use my_global.h first storage/spider/spd_malloc.cc: Use my_global.h first storage/spider/spd_param.cc: Use my_global.h first storage/spider/spd_ping_table.cc: Use my_global.h first storage/spider/spd_sys_table.cc: Use my_global.h first storage/spider/spd_table.cc: Use my_global.h first storage/spider/spd_trx.cc: Use my_global.h first storage/xtradb/handler/handler0alter.cc: Use my_global.h first storage/xtradb/handler/i_s.cc: Use my_global.h first
11 years ago
  1. /*
  2. Copyright (c) 2007, Antony T Curtis
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are
  6. met:
  7. * Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. * Neither the name of FederatedX nor the names of its
  10. contributors may be used to endorse or promote products derived from
  11. this software without specific prior written permission.
  12. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  15. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  16. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  18. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  19. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  20. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  22. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #define MYSQL_SERVER 1
  25. #include <my_global.h>
  26. #include "sql_priv.h"
  27. #include <mysqld_error.h>
  28. #include <mysql.h>
  29. #include "ha_federatedx.h"
  30. #include "m_string.h"
  31. #include "mysqld_error.h"
  32. #include "sql_servers.h"
  33. #define SAVEPOINT_REALIZED 1
  34. #define SAVEPOINT_RESTRICT 2
  35. #define SAVEPOINT_EMITTED 4
  36. typedef struct federatedx_savepoint
  37. {
  38. ulong level;
  39. uint flags;
  40. } SAVEPT;
  41. struct mysql_position
  42. {
  43. MYSQL_RES* result;
  44. MYSQL_ROW_OFFSET offset;
  45. };
  46. class federatedx_io_mysql :public federatedx_io
  47. {
  48. MYSQL mysql; /* MySQL connection */
  49. DYNAMIC_ARRAY savepoints;
  50. bool requested_autocommit;
  51. bool actual_autocommit;
  52. int actual_query(const char *buffer, size_t length);
  53. bool test_all_restrict() const;
  54. public:
  55. federatedx_io_mysql(FEDERATEDX_SERVER *);
  56. ~federatedx_io_mysql() override;
  57. // 1st arg is the implicit `this`
  58. int simple_query(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 2, 3);
  59. int query(const char *buffer, size_t length) override;
  60. FEDERATEDX_IO_RESULT *store_result() override;
  61. size_t max_query_size() const override;
  62. my_ulonglong affected_rows() const override;
  63. my_ulonglong last_insert_id() const override;
  64. int error_code() override;
  65. const char *error_str() override;
  66. void reset() override;
  67. int commit() override;
  68. int rollback() override;
  69. int savepoint_set(ulong sp) override;
  70. ulong savepoint_release(ulong sp) override;
  71. ulong savepoint_rollback(ulong sp) override;
  72. void savepoint_restrict(ulong sp) override;
  73. ulong last_savepoint() const override;
  74. ulong actual_savepoint() const override;
  75. bool is_autocommit() const override;
  76. bool table_metadata(ha_statistics *stats, const char *table_name,
  77. uint table_name_length, uint flag) override;
  78. /* resultset operations */
  79. void free_result(FEDERATEDX_IO_RESULT *io_result) override;
  80. unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result) override;
  81. my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result) override;
  82. FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result,
  83. FEDERATEDX_IO_ROWS **current= NULL) override;
  84. ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result) override;
  85. const char *get_column_data(FEDERATEDX_IO_ROW *row,
  86. unsigned int column) override;
  87. bool is_column_null(const FEDERATEDX_IO_ROW *row,
  88. unsigned int column) const override;
  89. size_t get_ref_length() const override;
  90. void mark_position(FEDERATEDX_IO_RESULT *io_result,
  91. void *ref, FEDERATEDX_IO_ROWS *current) override;
  92. int seek_position(FEDERATEDX_IO_RESULT **io_result,
  93. const void *ref) override;
  94. void set_thd(void *thd) override;
  95. };
  96. federatedx_io *instantiate_io_mysql(MEM_ROOT *server_root,
  97. FEDERATEDX_SERVER *server)
  98. {
  99. return new (server_root) federatedx_io_mysql(server);
  100. }
  101. federatedx_io_mysql::federatedx_io_mysql(FEDERATEDX_SERVER *aserver)
  102. : federatedx_io(aserver),
  103. requested_autocommit(TRUE), actual_autocommit(TRUE)
  104. {
  105. DBUG_ENTER("federatedx_io_mysql::federatedx_io_mysql");
  106. bzero(&mysql, sizeof(MYSQL));
  107. bzero(&savepoints, sizeof(DYNAMIC_ARRAY));
  108. my_init_dynamic_array(PSI_INSTRUMENT_ME, &savepoints, sizeof(SAVEPT), 16, 16, MYF(0));
  109. DBUG_VOID_RETURN;
  110. }
  111. federatedx_io_mysql::~federatedx_io_mysql()
  112. {
  113. DBUG_ENTER("federatedx_io_mysql::~federatedx_io_mysql");
  114. mysql_close(&mysql);
  115. delete_dynamic(&savepoints);
  116. DBUG_VOID_RETURN;
  117. }
  118. void federatedx_io_mysql::reset()
  119. {
  120. reset_dynamic(&savepoints);
  121. set_active(FALSE);
  122. requested_autocommit= TRUE;
  123. mysql.reconnect= 1;
  124. }
  125. int federatedx_io_mysql::commit()
  126. {
  127. int error= 0;
  128. DBUG_ENTER("federatedx_io_mysql::commit");
  129. if (!actual_autocommit && (error= actual_query("COMMIT", 6)))
  130. rollback();
  131. reset();
  132. DBUG_RETURN(error);
  133. }
  134. int federatedx_io_mysql::rollback()
  135. {
  136. int error= 0;
  137. DBUG_ENTER("federatedx_io_mysql::rollback");
  138. if (!actual_autocommit)
  139. error= actual_query("ROLLBACK", 8);
  140. else
  141. error= ER_WARNING_NOT_COMPLETE_ROLLBACK;
  142. reset();
  143. DBUG_RETURN(error);
  144. }
  145. ulong federatedx_io_mysql::last_savepoint() const
  146. {
  147. SAVEPT *savept= NULL;
  148. DBUG_ENTER("federatedx_io_mysql::last_savepoint");
  149. if (savepoints.elements)
  150. savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
  151. DBUG_RETURN(savept ? savept->level : 0);
  152. }
  153. ulong federatedx_io_mysql::actual_savepoint() const
  154. {
  155. SAVEPT *savept= NULL;
  156. size_t index= savepoints.elements;
  157. DBUG_ENTER("federatedx_io_mysql::last_savepoint");
  158. while (index)
  159. {
  160. savept= dynamic_element(&savepoints, --index, SAVEPT *);
  161. if (savept->flags & SAVEPOINT_REALIZED)
  162. break;
  163. savept= NULL;
  164. }
  165. DBUG_RETURN(savept ? savept->level : 0);
  166. }
  167. bool federatedx_io_mysql::is_autocommit() const
  168. {
  169. return actual_autocommit;
  170. }
  171. int federatedx_io_mysql::savepoint_set(ulong sp)
  172. {
  173. int error;
  174. SAVEPT savept;
  175. DBUG_ENTER("federatedx_io_mysql::savepoint_set");
  176. DBUG_PRINT("info",("savepoint=%lu", sp));
  177. DBUG_ASSERT(sp > last_savepoint());
  178. savept.level= sp;
  179. savept.flags= 0;
  180. if ((error= insert_dynamic(&savepoints, (uchar*) &savept) ? -1 : 0))
  181. goto err;
  182. set_active(TRUE);
  183. mysql.reconnect= 0;
  184. requested_autocommit= FALSE;
  185. err:
  186. DBUG_RETURN(error);
  187. }
  188. ulong federatedx_io_mysql::savepoint_release(ulong sp)
  189. {
  190. SAVEPT *savept, *last= NULL;
  191. DBUG_ENTER("federatedx_io_mysql::savepoint_release");
  192. DBUG_PRINT("info",("savepoint=%lu", sp));
  193. while (savepoints.elements)
  194. {
  195. savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
  196. if (savept->level < sp)
  197. break;
  198. if ((savept->flags & (SAVEPOINT_REALIZED | SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED)
  199. last= savept;
  200. savepoints.elements--;
  201. }
  202. if (last)
  203. {
  204. char buffer[STRING_BUFFER_USUAL_SIZE];
  205. size_t length= my_snprintf(buffer, sizeof(buffer),
  206. "RELEASE SAVEPOINT save%lu", last->level);
  207. actual_query(buffer, length);
  208. }
  209. DBUG_RETURN(last_savepoint());
  210. }
  211. ulong federatedx_io_mysql::savepoint_rollback(ulong sp)
  212. {
  213. SAVEPT *savept;
  214. size_t index;
  215. DBUG_ENTER("federatedx_io_mysql::savepoint_release");
  216. DBUG_PRINT("info",("savepoint=%lu", sp));
  217. while (savepoints.elements)
  218. {
  219. savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
  220. if (savept->level <= sp)
  221. break;
  222. savepoints.elements--;
  223. }
  224. for (index= savepoints.elements, savept= NULL; index;)
  225. {
  226. savept= dynamic_element(&savepoints, --index, SAVEPT *);
  227. if (savept->flags & SAVEPOINT_REALIZED)
  228. break;
  229. savept= NULL;
  230. }
  231. if (savept && !(savept->flags & SAVEPOINT_RESTRICT))
  232. {
  233. char buffer[STRING_BUFFER_USUAL_SIZE];
  234. size_t length= my_snprintf(buffer, sizeof(buffer),
  235. "ROLLBACK TO SAVEPOINT save%lu", savept->level);
  236. actual_query(buffer, length);
  237. }
  238. DBUG_RETURN(last_savepoint());
  239. }
  240. void federatedx_io_mysql::savepoint_restrict(ulong sp)
  241. {
  242. SAVEPT *savept;
  243. size_t index= savepoints.elements;
  244. DBUG_ENTER("federatedx_io_mysql::savepoint_restrict");
  245. while (index)
  246. {
  247. savept= dynamic_element(&savepoints, --index, SAVEPT *);
  248. if (savept->level > sp)
  249. continue;
  250. if (savept->level < sp)
  251. break;
  252. savept->flags|= SAVEPOINT_RESTRICT;
  253. break;
  254. }
  255. DBUG_VOID_RETURN;
  256. }
  257. int federatedx_io_mysql::simple_query(const char *fmt, ...)
  258. {
  259. char buffer[STRING_BUFFER_USUAL_SIZE];
  260. size_t length;
  261. int error;
  262. va_list arg;
  263. DBUG_ENTER("federatedx_io_mysql::simple_query");
  264. va_start(arg, fmt);
  265. length= my_vsnprintf(buffer, sizeof(buffer), fmt, arg);
  266. va_end(arg);
  267. error= query(buffer, length);
  268. DBUG_RETURN(error);
  269. }
  270. bool federatedx_io_mysql::test_all_restrict() const
  271. {
  272. bool result= FALSE;
  273. SAVEPT *savept;
  274. size_t index= savepoints.elements;
  275. DBUG_ENTER("federatedx_io_mysql::test_all_restrict");
  276. while (index)
  277. {
  278. savept= dynamic_element(&savepoints, --index, SAVEPT *);
  279. if ((savept->flags & (SAVEPOINT_REALIZED |
  280. SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED ||
  281. (savept->flags & SAVEPOINT_EMITTED))
  282. DBUG_RETURN(FALSE);
  283. if (savept->flags & SAVEPOINT_RESTRICT)
  284. result= TRUE;
  285. }
  286. DBUG_RETURN(result);
  287. }
  288. int federatedx_io_mysql::query(const char *buffer, size_t length)
  289. {
  290. int error;
  291. bool wants_autocommit= requested_autocommit | is_readonly();
  292. DBUG_ENTER("federatedx_io_mysql::query");
  293. if (!wants_autocommit && test_all_restrict())
  294. wants_autocommit= TRUE;
  295. if (wants_autocommit != actual_autocommit)
  296. {
  297. if ((error= actual_query(wants_autocommit ? "SET AUTOCOMMIT=1"
  298. : "SET AUTOCOMMIT=0", 16)))
  299. DBUG_RETURN(error);
  300. mysql.reconnect= wants_autocommit ? 1 : 0;
  301. actual_autocommit= wants_autocommit;
  302. }
  303. if (!actual_autocommit && last_savepoint() != actual_savepoint())
  304. {
  305. SAVEPT *savept= dynamic_element(&savepoints, savepoints.elements - 1,
  306. SAVEPT *);
  307. if (!(savept->flags & SAVEPOINT_RESTRICT))
  308. {
  309. char buf[STRING_BUFFER_USUAL_SIZE];
  310. size_t len= my_snprintf(buf, sizeof(buf),
  311. "SAVEPOINT save%lu", savept->level);
  312. if ((error= actual_query(buf, len)))
  313. DBUG_RETURN(error);
  314. set_active(TRUE);
  315. savept->flags|= SAVEPOINT_EMITTED;
  316. }
  317. savept->flags|= SAVEPOINT_REALIZED;
  318. }
  319. if (!(error= actual_query(buffer, length)))
  320. set_active(is_active() || !actual_autocommit);
  321. DBUG_RETURN(error);
  322. }
  323. int federatedx_io_mysql::actual_query(const char *buffer, size_t length)
  324. {
  325. int error;
  326. DBUG_ENTER("federatedx_io_mysql::actual_query");
  327. if (!mysql.net.vio)
  328. {
  329. my_bool my_true= 1;
  330. my_bool my_false= 0;
  331. if (!(mysql_init(&mysql)))
  332. DBUG_RETURN(-1);
  333. /*
  334. BUG# 17044 Federated Storage Engine is not UTF8 clean
  335. Add set names to whatever charset the table is at open
  336. of table
  337. */
  338. /* this sets the csname like 'set names utf8' */
  339. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, get_charsetname());
  340. mysql_options(&mysql, MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY, &my_true);
  341. mysql_options(&mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &my_false);
  342. if (!mysql_real_connect(&mysql, get_hostname(), get_username(),
  343. get_password(), get_database(), get_port(),
  344. get_socket(), 0))
  345. DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
  346. if ((error= mysql_real_query(&mysql, STRING_WITH_LEN("set time_zone='+00:00'"))))
  347. DBUG_RETURN(error);
  348. mysql.reconnect= 1;
  349. }
  350. error= mysql_real_query(&mysql, buffer, (ulong)length);
  351. DBUG_RETURN(error);
  352. }
  353. size_t federatedx_io_mysql::max_query_size() const
  354. {
  355. return mysql.net.max_packet_size;
  356. }
  357. my_ulonglong federatedx_io_mysql::affected_rows() const
  358. {
  359. return mysql.affected_rows;
  360. }
  361. my_ulonglong federatedx_io_mysql::last_insert_id() const
  362. {
  363. return mysql.insert_id;
  364. }
  365. int federatedx_io_mysql::error_code()
  366. {
  367. return mysql_errno(&mysql);
  368. }
  369. const char *federatedx_io_mysql::error_str()
  370. {
  371. return mysql_error(&mysql);
  372. }
  373. FEDERATEDX_IO_RESULT *federatedx_io_mysql::store_result()
  374. {
  375. FEDERATEDX_IO_RESULT *result;
  376. DBUG_ENTER("federatedx_io_mysql::store_result");
  377. result= (FEDERATEDX_IO_RESULT *) mysql_store_result(&mysql);
  378. DBUG_RETURN(result);
  379. }
  380. void federatedx_io_mysql::free_result(FEDERATEDX_IO_RESULT *io_result)
  381. {
  382. mysql_free_result((MYSQL_RES *) io_result);
  383. }
  384. unsigned int federatedx_io_mysql::get_num_fields(FEDERATEDX_IO_RESULT *io_result)
  385. {
  386. return mysql_num_fields((MYSQL_RES *) io_result);
  387. }
  388. my_ulonglong federatedx_io_mysql::get_num_rows(FEDERATEDX_IO_RESULT *io_result)
  389. {
  390. return mysql_num_rows((MYSQL_RES *) io_result);
  391. }
  392. FEDERATEDX_IO_ROW *federatedx_io_mysql::fetch_row(FEDERATEDX_IO_RESULT *io_result,
  393. FEDERATEDX_IO_ROWS **current)
  394. {
  395. MYSQL_RES *result= (MYSQL_RES*)io_result;
  396. if (current)
  397. *current= (FEDERATEDX_IO_ROWS *) result->data_cursor;
  398. return (FEDERATEDX_IO_ROW *) mysql_fetch_row(result);
  399. }
  400. ulong *federatedx_io_mysql::fetch_lengths(FEDERATEDX_IO_RESULT *io_result)
  401. {
  402. return mysql_fetch_lengths((MYSQL_RES *) io_result);
  403. }
  404. const char *federatedx_io_mysql::get_column_data(FEDERATEDX_IO_ROW *row,
  405. unsigned int column)
  406. {
  407. return ((MYSQL_ROW)row)[column];
  408. }
  409. bool federatedx_io_mysql::is_column_null(const FEDERATEDX_IO_ROW *row,
  410. unsigned int column) const
  411. {
  412. return !((MYSQL_ROW)row)[column];
  413. }
  414. bool federatedx_io_mysql::table_metadata(ha_statistics *stats,
  415. const char *table_name,
  416. uint table_name_length, uint flag)
  417. {
  418. char status_buf[FEDERATEDX_QUERY_BUFFER_SIZE];
  419. FEDERATEDX_IO_RESULT *result= 0;
  420. FEDERATEDX_IO_ROW *row;
  421. String status_query_string(status_buf, sizeof(status_buf), &my_charset_bin);
  422. int error;
  423. status_query_string.length(0);
  424. status_query_string.append(STRING_WITH_LEN("SHOW TABLE STATUS LIKE "));
  425. append_ident(&status_query_string, table_name,
  426. table_name_length, value_quote_char);
  427. if (query(status_query_string.ptr(), status_query_string.length()))
  428. goto error;
  429. status_query_string.length(0);
  430. result= store_result();
  431. /*
  432. We're going to use fields num. 4, 12 and 13 of the resultset,
  433. so make sure we have these fields.
  434. */
  435. if (!result || (get_num_fields(result) < 14))
  436. goto error;
  437. if (!get_num_rows(result))
  438. goto error;
  439. if (!(row= fetch_row(result)))
  440. goto error;
  441. /*
  442. deleted is set in ha_federatedx::info
  443. */
  444. /*
  445. need to figure out what this means as far as federatedx is concerned,
  446. since we don't have a "file"
  447. data_file_length = ?
  448. index_file_length = ?
  449. delete_length = ?
  450. */
  451. if (!is_column_null(row, 4))
  452. stats->records= (ha_rows) my_strtoll10(get_column_data(row, 4),
  453. (char**) 0, &error);
  454. if (!is_column_null(row, 5))
  455. stats->mean_rec_length= (ulong) my_strtoll10(get_column_data(row, 5),
  456. (char**) 0, &error);
  457. stats->data_file_length= stats->records * stats->mean_rec_length;
  458. if (!is_column_null(row, 12))
  459. stats->update_time= (time_t) my_strtoll10(get_column_data(row, 12),
  460. (char**) 0, &error);
  461. if (!is_column_null(row, 13))
  462. stats->check_time= (time_t) my_strtoll10(get_column_data(row, 13),
  463. (char**) 0, &error);
  464. free_result(result);
  465. return 0;
  466. error:
  467. if (!mysql_errno(&mysql))
  468. {
  469. mysql.net.last_errno= ER_NO_SUCH_TABLE;
  470. strmake_buf(mysql.net.last_error, "Remote table does not exist");
  471. }
  472. free_result(result);
  473. return 1;
  474. }
  475. size_t federatedx_io_mysql::get_ref_length() const
  476. {
  477. return sizeof(mysql_position);
  478. }
  479. void federatedx_io_mysql::mark_position(FEDERATEDX_IO_RESULT *io_result,
  480. void *ref, FEDERATEDX_IO_ROWS *current)
  481. {
  482. mysql_position& pos= *reinterpret_cast<mysql_position*>(ref);
  483. pos.result= (MYSQL_RES *) io_result;
  484. pos.offset= (MYSQL_ROW_OFFSET) current;
  485. }
  486. int federatedx_io_mysql::seek_position(FEDERATEDX_IO_RESULT **io_result,
  487. const void *ref)
  488. {
  489. const mysql_position& pos= *reinterpret_cast<const mysql_position*>(ref);
  490. if (!pos.result || !pos.offset)
  491. return HA_ERR_END_OF_FILE;
  492. pos.result->current_row= 0;
  493. pos.result->data_cursor= pos.offset;
  494. *io_result= (FEDERATEDX_IO_RESULT*) pos.result;
  495. return 0;
  496. }
  497. void federatedx_io_mysql::set_thd(void *thd)
  498. {
  499. mysql.net.thd= thd;
  500. }