1 /* Copyright (C) 2009-2020 Kentoku Shiba
2 Copyright (C) 2019-2020 MariaDB corp
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
16
17 #define MYSQL_SERVER 1
18 #include <my_global.h>
19 #include "mysql_version.h"
20 #include "spd_environ.h"
21 #if MYSQL_VERSION_ID < 50500
22 #include "mysql_priv.h"
23 #include <mysql/plugin.h>
24 #else
25 #include "sql_priv.h"
26 #include "probes_mysql.h"
27 #include "sql_class.h"
28 #include "sql_partition.h"
29 #include "sql_base.h"
30 #include "sql_servers.h"
31 #include "tztime.h"
32 #endif
33 #include "spd_err.h"
34 #include "spd_param.h"
35 #include "spd_db_include.h"
36 #include "spd_include.h"
37 #include "spd_sys_table.h"
38 #include "ha_spider.h"
39 #include "spd_db_conn.h"
40 #include "spd_trx.h"
41 #include "spd_conn.h"
42 #include "spd_table.h"
43 #include "spd_direct_sql.h"
44 #include "spd_udf.h"
45 #include "spd_malloc.h"
46
47 #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100004
48 #define SPIDER_NEED_INIT_ONE_TABLE_FOR_FIND_TEMPORARY_TABLE
49 #endif
50
51 extern const char **spd_defaults_extra_file;
52 extern const char **spd_defaults_file;
53
54 extern handlerton *spider_hton_ptr;
55 extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
56
57 #ifdef HAVE_PSI_INTERFACE
58 extern PSI_mutex_key spd_key_mutex_mta_conn;
59 extern PSI_mutex_key spd_key_mutex_bg_direct_sql;
60 extern PSI_cond_key spd_key_cond_bg_direct_sql;
61 #endif
62
63 extern HASH spider_open_connections;
64 extern HASH spider_ipport_conns;
65 extern pthread_mutex_t spider_conn_mutex;
66 extern pthread_mutex_t spider_conn_id_mutex;
67 extern pthread_mutex_t spider_ipport_conn_mutex;
68 extern ulonglong spider_conn_id;
69
70 /* UTC time zone for timestamp columns */
71 extern Time_zone *UTC;
72
spider_udf_calc_hash(char * key,uint mod)73 uint spider_udf_calc_hash(
74 char *key,
75 uint mod
76 ) {
77 uint sum = 0;
78 DBUG_ENTER("spider_udf_calc_hash");
79 while (*key != '\0')
80 {
81 sum += *key;
82 key++;
83 }
84 DBUG_PRINT("info",("spider calc hash = %u", sum % mod));
85 DBUG_RETURN(sum % mod);
86 }
87
spider_udf_direct_sql_create_table_list(SPIDER_DIRECT_SQL * direct_sql,char * table_name_list,uint table_name_list_length)88 int spider_udf_direct_sql_create_table_list(
89 SPIDER_DIRECT_SQL *direct_sql,
90 char *table_name_list,
91 uint table_name_list_length
92 ) {
93 int table_count, roop_count, length;
94 char *tmp_ptr, *tmp_ptr2, *tmp_ptr3, *tmp_name_ptr;
95 THD *thd = direct_sql->trx->thd;
96 DBUG_ENTER("spider_udf_direct_sql_create_table_list");
97 tmp_ptr = table_name_list;
98 while (*tmp_ptr == ' ')
99 tmp_ptr++;
100 if (*tmp_ptr)
101 table_count = 1;
102 else {
103 direct_sql->table_count = 0;
104 DBUG_RETURN(0);
105 }
106
107 while (TRUE)
108 {
109 if ((tmp_ptr2 = strchr(tmp_ptr, ' ')))
110 {
111 table_count++;
112 tmp_ptr = tmp_ptr2 + 1;
113 while (*tmp_ptr == ' ')
114 tmp_ptr++;
115 } else
116 break;
117 }
118 #if MYSQL_VERSION_ID < 50500
119 if (!(direct_sql->db_names = (char**)
120 spider_bulk_malloc(spider_current_trx, 31, MYF(MY_WME | MY_ZEROFILL),
121 &direct_sql->db_names, (uint) (sizeof(char*) * table_count),
122 &direct_sql->table_names, (uint) (sizeof(char*) * table_count),
123 &direct_sql->tables, (uint) (sizeof(TABLE*) * table_count),
124 &tmp_name_ptr, (uint) (sizeof(char) * (
125 table_name_list_length +
126 thd->db_length * table_count +
127 2 * table_count
128 )),
129 &direct_sql->iop, (uint) (sizeof(int) * table_count),
130 NullS))
131 )
132 #else
133 if (!(direct_sql->db_names = (char**)
134 spider_bulk_malloc(spider_current_trx, 31, MYF(MY_WME | MY_ZEROFILL),
135 &direct_sql->db_names, (uint) (sizeof(char*) * table_count),
136 &direct_sql->table_names, (uint) (sizeof(char*) * table_count),
137 &direct_sql->tables, (uint) (sizeof(TABLE*) * table_count),
138 &tmp_name_ptr, (uint) (sizeof(char) * (
139 table_name_list_length +
140 SPIDER_THD_db_length(thd) * table_count +
141 2 * table_count
142 )),
143 &direct_sql->iop, (uint) (sizeof(int) * table_count),
144 &direct_sql->table_list, (uint) (sizeof(TABLE_LIST) * table_count),
145 &direct_sql->real_table_bitmap,
146 (uint) (sizeof(uchar) * ((table_count + 7) / 8)),
147 NullS))
148 )
149 #endif
150 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
151
152 tmp_ptr = table_name_list;
153 while (*tmp_ptr == ' ')
154 tmp_ptr++;
155 roop_count = 0;
156 while (TRUE)
157 {
158 if ((tmp_ptr2 = strchr(tmp_ptr, ' ')))
159 *tmp_ptr2 = '\0';
160
161 direct_sql->db_names[roop_count] = tmp_name_ptr;
162
163 if ((tmp_ptr3 = strchr(tmp_ptr, '.')))
164 {
165 /* exist database name */
166 *tmp_ptr3 = '\0';
167 length = strlen(tmp_ptr);
168 memcpy(tmp_name_ptr, tmp_ptr, length + 1);
169 tmp_name_ptr += length + 1;
170 tmp_ptr = tmp_ptr3 + 1;
171 } else {
172 if (SPIDER_THD_db_str(thd))
173 {
174 memcpy(tmp_name_ptr, SPIDER_THD_db_str(thd),
175 SPIDER_THD_db_length(thd) + 1);
176 tmp_name_ptr += SPIDER_THD_db_length(thd) + 1;
177 } else {
178 direct_sql->db_names[roop_count] = (char *) "";
179 }
180 }
181
182 direct_sql->table_names[roop_count] = tmp_name_ptr;
183 length = strlen(tmp_ptr);
184 memcpy(tmp_name_ptr, tmp_ptr, length + 1);
185 tmp_name_ptr += length + 1;
186
187 DBUG_PRINT("info",("spider db=%s",
188 direct_sql->db_names[roop_count]));
189 DBUG_PRINT("info",("spider table_name=%s",
190 direct_sql->table_names[roop_count]));
191
192 if (!tmp_ptr2)
193 break;
194 tmp_ptr = tmp_ptr2 + 1;
195 while (*tmp_ptr == ' ')
196 tmp_ptr++;
197 roop_count++;
198 }
199 direct_sql->table_count = table_count;
200 DBUG_RETURN(0);
201 }
202
spider_udf_direct_sql_create_conn_key(SPIDER_DIRECT_SQL * direct_sql)203 int spider_udf_direct_sql_create_conn_key(
204 SPIDER_DIRECT_SQL *direct_sql
205 ) {
206 char *tmp_name, port_str[6];
207 DBUG_ENTER("spider_udf_direct_sql_create_conn_key");
208
209 uint roop_count2;
210 bool tables_on_different_db_are_joinable = TRUE;
211 direct_sql->dbton_id = SPIDER_DBTON_SIZE;
212 DBUG_PRINT("info",("spider direct_sql->tgt_wrapper=%s",
213 direct_sql->tgt_wrapper));
214 for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++)
215 {
216 DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", roop_count2,
217 spider_dbton[roop_count2].wrapper ?
218 spider_dbton[roop_count2].wrapper : "NULL"));
219 if (
220 spider_dbton[roop_count2].wrapper &&
221 !strcmp(direct_sql->tgt_wrapper, spider_dbton[roop_count2].wrapper)
222 ) {
223 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
224 if (direct_sql->access_mode == 0)
225 {
226 #endif
227 if (spider_dbton[roop_count2].db_access_type ==
228 SPIDER_DB_ACCESS_TYPE_SQL)
229 {
230 direct_sql->dbton_id = roop_count2;
231 break;
232 }
233 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
234 } else {
235 if (spider_dbton[roop_count2].db_access_type ==
236 SPIDER_DB_ACCESS_TYPE_NOSQL)
237 {
238 direct_sql->dbton_id = roop_count2;
239 break;
240 }
241 }
242 #endif
243 }
244 }
245 if (direct_sql->dbton_id == SPIDER_DBTON_SIZE)
246 {
247 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
248 if (direct_sql->access_mode == 0)
249 {
250 #endif
251 my_printf_error(
252 ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM,
253 ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR,
254 MYF(0), direct_sql->tgt_wrapper);
255 DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM);
256 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
257 } else {
258 my_printf_error(
259 ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM,
260 ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR,
261 MYF(0), direct_sql->tgt_wrapper);
262 DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM);
263 }
264 #endif
265 }
266
267 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
268 if (direct_sql->access_mode == 0)
269 {
270 #endif
271 tables_on_different_db_are_joinable =
272 spider_dbton[direct_sql->dbton_id].db_util->
273 tables_on_different_db_are_joinable();
274 direct_sql->conn_key_length
275 = 1
276 + direct_sql->tgt_wrapper_length + 1
277 + direct_sql->tgt_host_length + 1
278 + 5 + 1
279 + direct_sql->tgt_socket_length + 1
280 + (tables_on_different_db_are_joinable ?
281 0 : direct_sql->tgt_default_db_name_length + 1)
282 + direct_sql->tgt_username_length + 1
283 + direct_sql->tgt_password_length + 1
284 + direct_sql->tgt_ssl_ca_length + 1
285 + direct_sql->tgt_ssl_capath_length + 1
286 + direct_sql->tgt_ssl_cert_length + 1
287 + direct_sql->tgt_ssl_cipher_length + 1
288 + direct_sql->tgt_ssl_key_length + 1
289 + 1 + 1
290 + direct_sql->tgt_default_file_length + 1
291 + direct_sql->tgt_default_group_length + 1
292 + direct_sql->tgt_dsn_length;
293 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
294 } else {
295 direct_sql->conn_key_length
296 = 1
297 + direct_sql->tgt_wrapper_length + 1
298 + direct_sql->tgt_host_length + 1
299 + 5 + 1
300 + direct_sql->tgt_socket_length;
301 }
302 #endif
303 if (!(direct_sql->conn_key = (char *)
304 spider_malloc(spider_current_trx, 9, direct_sql->conn_key_length + 1,
305 MYF(MY_WME | MY_ZEROFILL)))
306 )
307 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
308 if (direct_sql->connection_channel > 48)
309 *direct_sql->conn_key = '0' + 48 - direct_sql->connection_channel;
310 else
311 *direct_sql->conn_key = '0' + direct_sql->connection_channel;
312 DBUG_PRINT("info",("spider tgt_wrapper=%s", direct_sql->tgt_wrapper));
313 tmp_name = strmov(direct_sql->conn_key + 1, direct_sql->tgt_wrapper);
314 DBUG_PRINT("info",("spider tgt_host=%s", direct_sql->tgt_host));
315 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_host);
316 my_sprintf(port_str, (port_str, "%05ld", direct_sql->tgt_port));
317 DBUG_PRINT("info",("spider port_str=%s", port_str));
318 tmp_name = strmov(tmp_name + 1, port_str);
319 if (direct_sql->tgt_socket)
320 {
321 DBUG_PRINT("info",("spider tgt_socket=%s", direct_sql->tgt_socket));
322 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_socket);
323 } else
324 tmp_name++;
325 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
326 if (direct_sql->access_mode == 0)
327 {
328 #endif
329 if (!tables_on_different_db_are_joinable)
330 {
331 if (direct_sql->tgt_default_db_name)
332 {
333 DBUG_PRINT("info",("spider tgt_default_db_name=%s",
334 direct_sql->tgt_default_db_name));
335 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_default_db_name);
336 } else
337 tmp_name++;
338 }
339 if (direct_sql->tgt_username)
340 {
341 DBUG_PRINT("info",("spider tgt_username=%s", direct_sql->tgt_username));
342 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_username);
343 } else
344 tmp_name++;
345 if (direct_sql->tgt_password)
346 {
347 DBUG_PRINT("info",("spider tgt_password=%s", direct_sql->tgt_password));
348 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_password);
349 } else
350 tmp_name++;
351 if (direct_sql->tgt_ssl_ca)
352 {
353 DBUG_PRINT("info",("spider tgt_ssl_ca=%s", direct_sql->tgt_ssl_ca));
354 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_ssl_ca);
355 } else
356 tmp_name++;
357 if (direct_sql->tgt_ssl_capath)
358 {
359 DBUG_PRINT("info",("spider tgt_ssl_capath=%s",
360 direct_sql->tgt_ssl_capath));
361 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_ssl_capath);
362 } else
363 tmp_name++;
364 if (direct_sql->tgt_ssl_cert)
365 {
366 DBUG_PRINT("info",("spider tgt_ssl_cert=%s", direct_sql->tgt_ssl_cert));
367 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_ssl_cert);
368 } else
369 tmp_name++;
370 if (direct_sql->tgt_ssl_cipher)
371 {
372 DBUG_PRINT("info",("spider tgt_ssl_cipher=%s",
373 direct_sql->tgt_ssl_cipher));
374 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_ssl_cipher);
375 } else
376 tmp_name++;
377 if (direct_sql->tgt_ssl_key)
378 {
379 DBUG_PRINT("info",("spider tgt_ssl_key=%s", direct_sql->tgt_ssl_key));
380 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_ssl_key);
381 } else
382 tmp_name++;
383 tmp_name++;
384 *tmp_name = '0' + ((char) direct_sql->tgt_ssl_vsc);
385 if (direct_sql->tgt_default_file)
386 {
387 DBUG_PRINT("info",("spider tgt_default_file=%s",
388 direct_sql->tgt_default_file));
389 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_default_file);
390 } else
391 tmp_name++;
392 if (direct_sql->tgt_default_group)
393 {
394 DBUG_PRINT("info",("spider tgt_default_group=%s",
395 direct_sql->tgt_default_group));
396 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_default_group);
397 } else
398 tmp_name++;
399 if (direct_sql->tgt_dsn)
400 {
401 DBUG_PRINT("info",("spider tgt_dsn=%s",
402 direct_sql->tgt_dsn));
403 tmp_name = strmov(tmp_name + 1, direct_sql->tgt_dsn);
404 } else
405 tmp_name++;
406 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
407 }
408 #endif
409 #ifdef SPIDER_HAS_HASH_VALUE_TYPE
410 direct_sql->conn_key_hash_value = my_calc_hash(&spider_open_connections,
411 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length);
412 #endif
413 DBUG_RETURN(0);
414 }
415
spider_udf_direct_sql_create_conn(const SPIDER_DIRECT_SQL * direct_sql,int * error_num)416 SPIDER_CONN *spider_udf_direct_sql_create_conn(
417 const SPIDER_DIRECT_SQL *direct_sql,
418 int *error_num
419 ) {
420 SPIDER_CONN *conn;
421 SPIDER_IP_PORT_CONN *ip_port_conn;
422 char *tmp_name, *tmp_host, *tmp_username, *tmp_password, *tmp_socket;
423 char *tmp_wrapper, *tmp_db, *tmp_ssl_ca, *tmp_ssl_capath, *tmp_ssl_cert;
424 char *tmp_ssl_cipher, *tmp_ssl_key, *tmp_default_file, *tmp_default_group;
425 char *tmp_dsn;
426 int *need_mon;
427 bool tables_on_different_db_are_joinable = TRUE;
428 DBUG_ENTER("spider_udf_direct_sql_create_conn");
429
430 if (unlikely(!UTC))
431 {
432 /* UTC time zone for timestamp columns */
433 String tz_00_name(STRING_WITH_LEN("+00:00"), &my_charset_bin);
434 UTC = my_tz_find(current_thd, &tz_00_name);
435 }
436
437 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
438 if (direct_sql->access_mode == 0)
439 {
440 #endif
441 tables_on_different_db_are_joinable =
442 spider_dbton[direct_sql->dbton_id].db_util->
443 tables_on_different_db_are_joinable();
444 if (!(conn = (SPIDER_CONN *)
445 spider_bulk_malloc(spider_current_trx, 32, MYF(MY_WME | MY_ZEROFILL),
446 &conn, (uint) (sizeof(*conn)),
447 &tmp_name, (uint) (direct_sql->conn_key_length + 1),
448 &tmp_host, (uint) (direct_sql->tgt_host_length + 1),
449 &tmp_username, (uint) (direct_sql->tgt_username_length + 1),
450 &tmp_password, (uint) (direct_sql->tgt_password_length + 1),
451 &tmp_socket, (uint) (direct_sql->tgt_socket_length + 1),
452 &tmp_wrapper, (uint) (direct_sql->tgt_wrapper_length + 1),
453 &tmp_db, (uint) (tables_on_different_db_are_joinable ?
454 0 : direct_sql->tgt_default_db_name_length + 1),
455 &tmp_ssl_ca, (uint) (direct_sql->tgt_ssl_ca_length + 1),
456 &tmp_ssl_capath, (uint) (direct_sql->tgt_ssl_capath_length + 1),
457 &tmp_ssl_cert, (uint) (direct_sql->tgt_ssl_cert_length + 1),
458 &tmp_ssl_cipher, (uint) (direct_sql->tgt_ssl_cipher_length + 1),
459 &tmp_ssl_key, (uint) (direct_sql->tgt_ssl_key_length + 1),
460 &tmp_default_file,
461 (uint) (direct_sql->tgt_default_file_length + 1),
462 &tmp_default_group,
463 (uint) (direct_sql->tgt_default_group_length + 1),
464 &tmp_dsn,
465 (uint) (direct_sql->tgt_dsn_length + 1),
466 &need_mon, (uint) (sizeof(int)),
467 NullS))
468 ) {
469 *error_num = HA_ERR_OUT_OF_MEM;
470 goto error_alloc_conn;
471 }
472 conn->default_database.init_calc_mem(138);
473 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
474 } else {
475 if (!(conn = (SPIDER_CONN *)
476 spider_bulk_malloc(spider_current_trx, 33, MYF(MY_WME | MY_ZEROFILL),
477 &conn, (uint) (sizeof(*conn)),
478 &tmp_name, (uint) (direct_sql->conn_key_length + 1),
479 &tmp_host, (uint) (direct_sql->tgt_host_length + 1),
480 &tmp_socket, (uint) (direct_sql->tgt_socket_length + 1),
481 &tmp_wrapper, (uint) (direct_sql->tgt_wrapper_length + 1),
482 &need_mon, (uint) (sizeof(int)),
483 NullS))
484 ) {
485 *error_num = HA_ERR_OUT_OF_MEM;
486 goto error_alloc_conn;
487 }
488 conn->default_database.init_calc_mem(103);
489 }
490 #endif
491
492 conn->conn_key_length = direct_sql->conn_key_length;
493 conn->conn_key = tmp_name;
494 memcpy(conn->conn_key, direct_sql->conn_key, direct_sql->conn_key_length);
495 conn->tgt_wrapper_length = direct_sql->tgt_wrapper_length;
496 conn->tgt_wrapper = tmp_wrapper;
497 memcpy(conn->tgt_wrapper, direct_sql->tgt_wrapper,
498 direct_sql->tgt_wrapper_length);
499 conn->tgt_host_length = direct_sql->tgt_host_length;
500 conn->tgt_host = tmp_host;
501 memcpy(conn->tgt_host, direct_sql->tgt_host, direct_sql->tgt_host_length);
502 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
503 if (direct_sql->access_mode == 0)
504 {
505 #endif
506 conn->tgt_port = direct_sql->tgt_port;
507 conn->tgt_socket_length = direct_sql->tgt_socket_length;
508 conn->tgt_socket = tmp_socket;
509 memcpy(conn->tgt_socket, direct_sql->tgt_socket,
510 direct_sql->tgt_socket_length);
511 if (!tables_on_different_db_are_joinable)
512 {
513 conn->tgt_db_length = direct_sql->tgt_default_db_name_length;
514 conn->tgt_db = tmp_db;
515 memcpy(conn->tgt_db, direct_sql->tgt_default_db_name,
516 direct_sql->tgt_default_db_name_length);
517 }
518 conn->tgt_username_length = direct_sql->tgt_username_length;
519 conn->tgt_username = tmp_username;
520 memcpy(conn->tgt_username, direct_sql->tgt_username,
521 direct_sql->tgt_username_length);
522 conn->tgt_password_length = direct_sql->tgt_password_length;
523 conn->tgt_password = tmp_password;
524 memcpy(conn->tgt_password, direct_sql->tgt_password,
525 direct_sql->tgt_password_length);
526 conn->tgt_ssl_ca_length = direct_sql->tgt_ssl_ca_length;
527 if (conn->tgt_ssl_ca_length)
528 {
529 conn->tgt_ssl_ca = tmp_ssl_ca;
530 memcpy(conn->tgt_ssl_ca, direct_sql->tgt_ssl_ca,
531 direct_sql->tgt_ssl_ca_length);
532 } else
533 conn->tgt_ssl_ca = NULL;
534 conn->tgt_ssl_capath_length = direct_sql->tgt_ssl_capath_length;
535 if (conn->tgt_ssl_capath_length)
536 {
537 conn->tgt_ssl_capath = tmp_ssl_capath;
538 memcpy(conn->tgt_ssl_capath, direct_sql->tgt_ssl_capath,
539 direct_sql->tgt_ssl_capath_length);
540 } else
541 conn->tgt_ssl_capath = NULL;
542 conn->tgt_ssl_cert_length = direct_sql->tgt_ssl_cert_length;
543 if (conn->tgt_ssl_cert_length)
544 {
545 conn->tgt_ssl_cert = tmp_ssl_cert;
546 memcpy(conn->tgt_ssl_cert, direct_sql->tgt_ssl_cert,
547 direct_sql->tgt_ssl_cert_length);
548 } else
549 conn->tgt_ssl_cert = NULL;
550 conn->tgt_ssl_cipher_length = direct_sql->tgt_ssl_cipher_length;
551 if (conn->tgt_ssl_cipher_length)
552 {
553 conn->tgt_ssl_cipher = tmp_ssl_cipher;
554 memcpy(conn->tgt_ssl_cipher, direct_sql->tgt_ssl_cipher,
555 direct_sql->tgt_ssl_cipher_length);
556 } else
557 conn->tgt_ssl_cipher = NULL;
558 conn->tgt_ssl_key_length = direct_sql->tgt_ssl_key_length;
559 if (conn->tgt_ssl_key_length)
560 {
561 conn->tgt_ssl_key = tmp_ssl_key;
562 memcpy(conn->tgt_ssl_key, direct_sql->tgt_ssl_key,
563 direct_sql->tgt_ssl_key_length);
564 } else
565 conn->tgt_ssl_key = NULL;
566 conn->tgt_default_file_length = direct_sql->tgt_default_file_length;
567 if (conn->tgt_default_file_length)
568 {
569 conn->tgt_default_file = tmp_default_file;
570 memcpy(conn->tgt_default_file, direct_sql->tgt_default_file,
571 direct_sql->tgt_default_file_length);
572 } else
573 conn->tgt_default_file = NULL;
574 conn->tgt_default_group_length = direct_sql->tgt_default_group_length;
575 if (conn->tgt_default_group_length)
576 {
577 conn->tgt_default_group = tmp_default_group;
578 memcpy(conn->tgt_default_group, direct_sql->tgt_default_group,
579 direct_sql->tgt_default_group_length);
580 } else
581 conn->tgt_default_group = NULL;
582 conn->tgt_dsn_length = direct_sql->tgt_dsn_length;
583 if (conn->tgt_dsn_length)
584 {
585 conn->tgt_dsn = tmp_dsn;
586 memcpy(conn->tgt_dsn, direct_sql->tgt_dsn,
587 direct_sql->tgt_dsn_length);
588 } else
589 conn->tgt_dsn = NULL;
590 conn->tgt_ssl_vsc = direct_sql->tgt_ssl_vsc;
591 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
592 } else {
593 conn->hs_port = direct_sql->tgt_port;
594 if (direct_sql->tgt_socket)
595 {
596 conn->hs_sock_length = direct_sql->tgt_socket_length;
597 conn->hs_sock = tmp_socket;
598 memcpy(conn->hs_sock, direct_sql->tgt_socket,
599 direct_sql->tgt_socket_length);
600 }
601 }
602 #endif
603 conn->dbton_id = direct_sql->dbton_id;
604 conn->conn_need_mon = need_mon;
605 conn->need_mon = need_mon;
606 if (!(conn->db_conn = spider_dbton[conn->dbton_id].create_db_conn(conn)))
607 {
608 *error_num = HA_ERR_OUT_OF_MEM;
609 goto error_db_conn_create;
610 }
611 if ((*error_num = conn->db_conn->init()))
612 {
613 goto error_db_conn_init;
614 }
615 conn->join_trx = 0;
616 conn->thd = NULL;
617 conn->table_lock = 0;
618 conn->semi_trx_isolation = -2;
619 conn->semi_trx_isolation_chk = FALSE;
620 conn->semi_trx_chk = FALSE;
621 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
622 if (direct_sql->access_mode == 0)
623 {
624 #endif
625 conn->conn_kind = SPIDER_CONN_KIND_MYSQL;
626 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
627 } else if (direct_sql->access_mode == 1)
628 {
629 conn->conn_kind = SPIDER_CONN_KIND_HS_READ;
630 } else {
631 conn->conn_kind = SPIDER_CONN_KIND_HS_WRITE;
632 }
633 #endif
634
635 #if MYSQL_VERSION_ID < 50500
636 if (pthread_mutex_init(&conn->mta_conn_mutex, MY_MUTEX_INIT_FAST))
637 #else
638 if (mysql_mutex_init(spd_key_mutex_mta_conn, &conn->mta_conn_mutex,
639 MY_MUTEX_INIT_FAST))
640 #endif
641 {
642 *error_num = HA_ERR_OUT_OF_MEM;
643 goto error_mta_conn_mutex_init;
644 }
645
646 if (unlikely((*error_num = spider_conn_init(conn))))
647 {
648 goto error_conn_init;
649 }
650
651 if ((*error_num = spider_db_udf_direct_sql_connect(direct_sql, conn)))
652 goto error;
653 conn->ping_time = (time_t) time((time_t*) 0);
654 conn->connect_error_time = conn->ping_time;
655 pthread_mutex_lock(&spider_conn_id_mutex);
656 conn->conn_id = spider_conn_id;
657 ++spider_conn_id;
658 pthread_mutex_unlock(&spider_conn_id_mutex);
659
660 pthread_mutex_lock(&spider_ipport_conn_mutex);
661 #ifdef SPIDER_HAS_HASH_VALUE_TYPE
662 if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value(
663 &spider_ipport_conns, conn->conn_key_hash_value,
664 (uchar*)conn->conn_key, conn->conn_key_length)))
665 #else
666 if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search(
667 &spider_ipport_conns, (uchar*)conn->conn_key, conn->conn_key_length)))
668 #endif
669 { /* exists, +1 */
670 pthread_mutex_unlock(&spider_ipport_conn_mutex);
671 pthread_mutex_lock(&ip_port_conn->mutex);
672 if (spider_param_max_connections())
673 { /* enable conncetion pool */
674 if (ip_port_conn->ip_port_count >= spider_param_max_connections())
675 { /* bigger than the max num of connections, free conn and return NULL */
676 pthread_mutex_unlock(&ip_port_conn->mutex);
677 goto error_too_many_ipport_count;
678 }
679 }
680 ip_port_conn->ip_port_count++;
681 pthread_mutex_unlock(&ip_port_conn->mutex);
682 }
683 else
684 {// do not exist
685 ip_port_conn = spider_create_ipport_conn(conn);
686 if (!ip_port_conn) {
687 /* failed, always do not effect 'create conn' */
688 pthread_mutex_unlock(&spider_ipport_conn_mutex);
689 DBUG_RETURN(conn);
690 }
691 if (my_hash_insert(&spider_ipport_conns, (uchar *)ip_port_conn)) {
692 /* insert failed, always do not effect 'create conn' */
693 pthread_mutex_unlock(&spider_ipport_conn_mutex);
694 DBUG_RETURN(conn);
695 }
696 pthread_mutex_unlock(&spider_ipport_conn_mutex);
697 }
698 conn->ip_port_conn = ip_port_conn;
699
700 DBUG_RETURN(conn);
701
702 error:
703 DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
704 error_too_many_ipport_count:
705 spider_conn_done(conn);
706 error_conn_init:
707 pthread_mutex_destroy(&conn->mta_conn_mutex);
708 error_mta_conn_mutex_init:
709 error_db_conn_init:
710 delete conn->db_conn;
711 error_db_conn_create:
712 spider_free(spider_current_trx, conn, MYF(0));
713 error_alloc_conn:
714 DBUG_RETURN(NULL);
715 }
716
spider_udf_direct_sql_get_conn(const SPIDER_DIRECT_SQL * direct_sql,SPIDER_TRX * trx,int * error_num)717 SPIDER_CONN *spider_udf_direct_sql_get_conn(
718 const SPIDER_DIRECT_SQL *direct_sql,
719 SPIDER_TRX *trx,
720 int *error_num
721 ) {
722 SPIDER_CONN *conn = NULL;
723 DBUG_ENTER("spider_udf_direct_sql_get_conn");
724 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
725 DBUG_PRINT("info",("spider direct_sql->access_mode=%d",
726 direct_sql->access_mode));
727 #endif
728
729 #ifdef SPIDER_HAS_HASH_VALUE_TYPE
730 if (
731 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
732 (direct_sql->access_mode == 0 &&
733 #endif
734 !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value(
735 &trx->trx_conn_hash, direct_sql->conn_key_hash_value,
736 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
737 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
738 ) ||
739 (direct_sql->access_mode == 1 &&
740 !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value(
741 &trx->trx_direct_hs_r_conn_hash, direct_sql->conn_key_hash_value,
742 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
743 ) ||
744 (direct_sql->access_mode == 2 &&
745 !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value(
746 &trx->trx_direct_hs_w_conn_hash, direct_sql->conn_key_hash_value,
747 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
748 )
749 #endif
750 )
751 #else
752 if (
753 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
754 (direct_sql->access_mode == 0 &&
755 #endif
756 !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_conn_hash,
757 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
758 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
759 ) ||
760 (direct_sql->access_mode == 1 &&
761 !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_direct_hs_r_conn_hash,
762 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
763 ) ||
764 (direct_sql->access_mode == 2 &&
765 !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_direct_hs_w_conn_hash,
766 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length))
767 )
768 #endif
769 )
770 #endif
771 {
772 if (
773 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
774 (direct_sql->access_mode == 0 &&
775 #endif
776 (
777 (spider_param_conn_recycle_mode(trx->thd) & 1) ||
778 spider_param_conn_recycle_strict(trx->thd)
779 )
780 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
781 ) ||
782 (direct_sql->access_mode == 1 &&
783 (
784 (spider_param_hs_r_conn_recycle_mode(trx->thd) & 1) ||
785 spider_param_hs_r_conn_recycle_strict(trx->thd)
786 )
787 ) ||
788 (direct_sql->access_mode == 2 &&
789 (
790 (spider_param_hs_w_conn_recycle_mode(trx->thd) & 1) ||
791 spider_param_hs_w_conn_recycle_strict(trx->thd)
792 )
793 )
794 #endif
795 ) {
796 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
797 if (direct_sql->access_mode == 0)
798 {
799 #endif
800 pthread_mutex_lock(&spider_conn_mutex);
801 #ifdef SPIDER_HAS_HASH_VALUE_TYPE
802 if (!(conn = (SPIDER_CONN*) my_hash_search_using_hash_value(
803 &spider_open_connections, direct_sql->conn_key_hash_value,
804 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)))
805 #else
806 if (!(conn = (SPIDER_CONN*) my_hash_search(&spider_open_connections,
807 (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)))
808 #endif
809 {
810 pthread_mutex_unlock(&spider_conn_mutex);
811 DBUG_PRINT("info",("spider create new conn"));
812 if(!(conn = spider_udf_direct_sql_create_conn(direct_sql,
813 error_num)))
814 goto error;
815 } else {
816 #ifdef HASH_UPDATE_WITH_HASH_VALUE
817 my_hash_delete_with_hash_value(&spider_open_connections,
818 conn->conn_key_hash_value, (uchar*) conn);
819 #else
820 my_hash_delete(&spider_open_connections, (uchar*) conn);
821 #endif
822 pthread_mutex_unlock(&spider_conn_mutex);
823 DBUG_PRINT("info",("spider get global conn"));
824 }
825 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
826 }
827 #endif
828 } else {
829 DBUG_PRINT("info",("spider create new conn"));
830 /* conn_recycle_strict = 0 and conn_recycle_mode = 0 or 2 */
831 if(!(conn = spider_udf_direct_sql_create_conn(direct_sql, error_num)))
832 goto error;
833 }
834 conn->thd = trx->thd;
835 conn->priority = direct_sql->priority;
836
837 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
838 if (direct_sql->access_mode == 0)
839 {
840 #endif
841 uint old_elements = trx->trx_conn_hash.array.max_element;
842 #ifdef HASH_UPDATE_WITH_HASH_VALUE
843 if (my_hash_insert_with_hash_value(&trx->trx_conn_hash,
844 direct_sql->conn_key_hash_value, (uchar*) conn))
845 #else
846 if (my_hash_insert(&trx->trx_conn_hash, (uchar*) conn))
847 #endif
848 {
849 spider_free_conn(conn);
850 *error_num = HA_ERR_OUT_OF_MEM;
851 goto error;
852 }
853 if (trx->trx_conn_hash.array.max_element > old_elements)
854 {
855 spider_alloc_calc_mem(spider_current_trx,
856 trx->trx_conn_hash,
857 (trx->trx_conn_hash.array.max_element - old_elements) *
858 trx->trx_conn_hash.array.size_of_element);
859 }
860 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
861 } else if (direct_sql->access_mode == 1)
862 {
863 uint old_elements = trx->trx_direct_hs_r_conn_hash.array.max_element;
864 #ifdef HASH_UPDATE_WITH_HASH_VALUE
865 if (my_hash_insert_with_hash_value(&trx->trx_direct_hs_r_conn_hash,
866 direct_sql->conn_key_hash_value, (uchar*) conn))
867 #else
868 if (my_hash_insert(&trx->trx_direct_hs_r_conn_hash, (uchar*) conn))
869 #endif
870 {
871 spider_free_conn(conn);
872 *error_num = HA_ERR_OUT_OF_MEM;
873 goto error;
874 }
875 if (trx->trx_direct_hs_r_conn_hash.array.max_element > old_elements)
876 {
877 spider_alloc_calc_mem(spider_current_trx,
878 trx->trx_direct_hs_r_conn_hash,
879 (trx->trx_direct_hs_r_conn_hash.array.max_element - old_elements) *
880 trx->trx_direct_hs_r_conn_hash.array.size_of_element);
881 }
882 } else {
883 uint old_elements = trx->trx_direct_hs_w_conn_hash.array.max_element;
884 #ifdef HASH_UPDATE_WITH_HASH_VALUE
885 if (my_hash_insert_with_hash_value(&trx->trx_direct_hs_w_conn_hash,
886 direct_sql->conn_key_hash_value, (uchar*) conn))
887 #else
888 if (my_hash_insert(&trx->trx_direct_hs_w_conn_hash, (uchar*) conn))
889 #endif
890 {
891 spider_free_conn(conn);
892 *error_num = HA_ERR_OUT_OF_MEM;
893 goto error;
894 }
895 if (trx->trx_direct_hs_w_conn_hash.array.max_element > old_elements)
896 {
897 spider_alloc_calc_mem(spider_current_trx,
898 trx->trx_direct_hs_w_conn_hash,
899 (trx->trx_direct_hs_w_conn_hash.array.max_element - old_elements) *
900 trx->trx_direct_hs_w_conn_hash.array.size_of_element);
901 }
902 }
903 #endif
904 }
905
906 if (conn->queued_connect)
907 {
908 if ((*error_num = spider_db_udf_direct_sql_connect(direct_sql, conn)))
909 goto error;
910 conn->queued_connect = FALSE;
911 }
912
913 if (conn->queued_ping)
914 conn->queued_ping = FALSE;
915
916 DBUG_PRINT("info",("spider conn=%p", conn));
917 DBUG_PRINT("info",("spider conn->conn_kind=%u", conn->conn_kind));
918 DBUG_RETURN(conn);
919
920 error:
921 DBUG_RETURN(NULL);
922 }
923
spider_udf_direct_sql_get_server(SPIDER_DIRECT_SQL * direct_sql)924 int spider_udf_direct_sql_get_server(
925 SPIDER_DIRECT_SQL *direct_sql
926 ) {
927 MEM_ROOT mem_root;
928 int error_num, length;
929 FOREIGN_SERVER *server, server_buf;
930 DBUG_ENTER("spider_udf_direct_sql_get_server");
931 SPD_INIT_ALLOC_ROOT(&mem_root, 65, 0, MYF(MY_WME));
932
933 if (!(server
934 = get_server_by_name(&mem_root, direct_sql->server_name, &server_buf)))
935 {
936 error_num = ER_FOREIGN_SERVER_DOESNT_EXIST;
937 goto error_get_server;
938 }
939
940 if (!direct_sql->tgt_wrapper && server->scheme)
941 {
942 direct_sql->tgt_wrapper_length = strlen(server->scheme);
943 if (!(direct_sql->tgt_wrapper =
944 spider_create_string(server->scheme, direct_sql->tgt_wrapper_length)))
945 {
946 error_num = HA_ERR_OUT_OF_MEM;
947 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
948 goto error;
949 }
950 DBUG_PRINT("info",("spider tgt_wrapper=%s", direct_sql->tgt_wrapper));
951 }
952
953 if (!direct_sql->tgt_host && server->host)
954 {
955 direct_sql->tgt_host_length = strlen(server->host);
956 if (!(direct_sql->tgt_host =
957 spider_create_string(server->host, direct_sql->tgt_host_length)))
958 {
959 error_num = HA_ERR_OUT_OF_MEM;
960 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
961 goto error;
962 }
963 DBUG_PRINT("info",("spider tgt_host=%s", direct_sql->tgt_host));
964 }
965
966 if (direct_sql->tgt_port == -1)
967 {
968 direct_sql->tgt_port = server->port;
969 DBUG_PRINT("info",("spider tgt_port=%ld", direct_sql->tgt_port));
970 }
971
972 if (!direct_sql->tgt_socket && server->socket)
973 {
974 direct_sql->tgt_socket_length = strlen(server->socket);
975 if (!(direct_sql->tgt_socket =
976 spider_create_string(server->socket, direct_sql->tgt_socket_length)))
977 {
978 error_num = HA_ERR_OUT_OF_MEM;
979 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
980 goto error;
981 }
982 DBUG_PRINT("info",("spider tgt_socket=%s", direct_sql->tgt_socket));
983 }
984
985 if (!direct_sql->tgt_default_db_name && server->db &&
986 (length = strlen(server->db)))
987 {
988 direct_sql->tgt_default_db_name_length = length;
989 if (!(direct_sql->tgt_default_db_name =
990 spider_create_string(server->db, length)))
991 {
992 error_num = HA_ERR_OUT_OF_MEM;
993 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
994 goto error;
995 }
996 DBUG_PRINT("info",("spider tgt_default_db_name=%s",
997 direct_sql->tgt_default_db_name));
998 }
999
1000 if (!direct_sql->tgt_username && server->username)
1001 {
1002 direct_sql->tgt_username_length = strlen(server->username);
1003 if (!(direct_sql->tgt_username =
1004 spider_create_string(server->username, direct_sql->tgt_username_length)))
1005 {
1006 error_num = HA_ERR_OUT_OF_MEM;
1007 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1008 goto error;
1009 }
1010 DBUG_PRINT("info",("spider tgt_username=%s", direct_sql->tgt_username));
1011 }
1012
1013 if (!direct_sql->tgt_password && server->password)
1014 {
1015 direct_sql->tgt_password_length = strlen(server->password);
1016 if (!(direct_sql->tgt_password =
1017 spider_create_string(server->password, direct_sql->tgt_password_length)))
1018 {
1019 error_num = HA_ERR_OUT_OF_MEM;
1020 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1021 goto error;
1022 }
1023 DBUG_PRINT("info",("spider tgt_password=%s", direct_sql->tgt_password));
1024 }
1025
1026 free_root(&mem_root, MYF(0));
1027 DBUG_RETURN(0);
1028
1029 error_get_server:
1030 my_error(error_num, MYF(0), direct_sql->server_name);
1031 error:
1032 free_root(&mem_root, MYF(0));
1033 DBUG_RETURN(error_num);
1034 }
1035
1036 #define SPIDER_PARAM_STR_LEN(name) name ## _length
1037 #define SPIDER_PARAM_STR(title_name, param_name) \
1038 if (!strncasecmp(tmp_ptr, title_name, title_length)) \
1039 { \
1040 DBUG_PRINT("info",("spider " title_name " start")); \
1041 if (!direct_sql->param_name) \
1042 { \
1043 if ((direct_sql->param_name = spider_get_string_between_quote( \
1044 start_ptr, TRUE, ¶m_string_parse))) \
1045 direct_sql->SPIDER_PARAM_STR_LEN(param_name) = \
1046 strlen(direct_sql->param_name); \
1047 else { \
1048 error_num = param_string_parse.print_param_error(); \
1049 goto error; \
1050 } \
1051 DBUG_PRINT("info",("spider " title_name "=%s", direct_sql->param_name)); \
1052 } \
1053 break; \
1054 }
1055 #define SPIDER_PARAM_HINT_WITH_MAX(title_name, param_name, check_length, max_size, min_val, max_val) \
1056 if (!strncasecmp(tmp_ptr, title_name, check_length)) \
1057 { \
1058 DBUG_PRINT("info",("spider " title_name " start")); \
1059 DBUG_PRINT("info",("spider max_size=%d", max_size)); \
1060 int hint_num = atoi(tmp_ptr + check_length) - 1; \
1061 DBUG_PRINT("info",("spider hint_num=%d", hint_num)); \
1062 DBUG_PRINT("info",("spider direct_sql->param_name=%p", \
1063 direct_sql->param_name)); \
1064 if (direct_sql->param_name) \
1065 { \
1066 if (hint_num < 0 || hint_num >= max_size) \
1067 { \
1068 error_num = param_string_parse.print_param_error(); \
1069 goto error; \
1070 } else if (direct_sql->param_name[hint_num] != -1) \
1071 break; \
1072 char *hint_str = spider_get_string_between_quote(start_ptr, FALSE); \
1073 if (hint_str) \
1074 { \
1075 direct_sql->param_name[hint_num] = atoi(hint_str); \
1076 if (direct_sql->param_name[hint_num] < min_val) \
1077 direct_sql->param_name[hint_num] = min_val; \
1078 else if (direct_sql->param_name[hint_num] > max_val) \
1079 direct_sql->param_name[hint_num] = max_val; \
1080 } else { \
1081 error_num = param_string_parse.print_param_error(); \
1082 goto error; \
1083 } \
1084 DBUG_PRINT("info",("spider " title_name "[%d]=%d", hint_num, \
1085 direct_sql->param_name[hint_num])); \
1086 } else { \
1087 error_num = param_string_parse.print_param_error(); \
1088 goto error; \
1089 } \
1090 break; \
1091 }
1092 #define SPIDER_PARAM_INT_WITH_MAX(title_name, param_name, min_val, max_val) \
1093 if (!strncasecmp(tmp_ptr, title_name, title_length)) \
1094 { \
1095 DBUG_PRINT("info",("spider " title_name " start")); \
1096 if (direct_sql->param_name == -1) \
1097 { \
1098 if ((tmp_ptr2 = spider_get_string_between_quote( \
1099 start_ptr, FALSE))) \
1100 { \
1101 direct_sql->param_name = atoi(tmp_ptr2); \
1102 if (direct_sql->param_name < min_val) \
1103 direct_sql->param_name = min_val; \
1104 else if (direct_sql->param_name > max_val) \
1105 direct_sql->param_name = max_val; \
1106 param_string_parse.set_param_value(tmp_ptr2, \
1107 tmp_ptr2 + \
1108 strlen(tmp_ptr2) + 1); \
1109 } else { \
1110 error_num = param_string_parse.print_param_error(); \
1111 goto error; \
1112 } \
1113 DBUG_PRINT("info",("spider " title_name "=%d", \
1114 (int) direct_sql->param_name)); \
1115 } \
1116 break; \
1117 }
1118 #define SPIDER_PARAM_INT(title_name, param_name, min_val) \
1119 if (!strncasecmp(tmp_ptr, title_name, title_length)) \
1120 { \
1121 DBUG_PRINT("info",("spider " title_name " start")); \
1122 if (direct_sql->param_name == -1) \
1123 { \
1124 if ((tmp_ptr2 = spider_get_string_between_quote( \
1125 start_ptr, FALSE))) \
1126 { \
1127 direct_sql->param_name = atoi(tmp_ptr2); \
1128 if (direct_sql->param_name < min_val) \
1129 direct_sql->param_name = min_val; \
1130 param_string_parse.set_param_value(tmp_ptr2, \
1131 tmp_ptr2 + \
1132 strlen(tmp_ptr2) + 1); \
1133 } else { \
1134 error_num = param_string_parse.print_param_error(); \
1135 goto error; \
1136 } \
1137 DBUG_PRINT("info",("spider " title_name "=%d", direct_sql->param_name)); \
1138 } \
1139 break; \
1140 }
1141 #define SPIDER_PARAM_LONGLONG(title_name, param_name, min_val) \
1142 if (!strncasecmp(tmp_ptr, title_name, title_length)) \
1143 { \
1144 DBUG_PRINT("info",("spider " title_name " start")); \
1145 if (direct_sql->param_name == -1) \
1146 { \
1147 if ((tmp_ptr2 = spider_get_string_between_quote( \
1148 start_ptr, FALSE))) \
1149 { \
1150 direct_sql->param_name = \
1151 my_strtoll10(tmp_ptr2, (char**) NULL, &error_num); \
1152 if (direct_sql->param_name < min_val) \
1153 direct_sql->param_name = min_val; \
1154 param_string_parse.set_param_value(tmp_ptr2, \
1155 tmp_ptr2 + \
1156 strlen(tmp_ptr2) + 1); \
1157 } else { \
1158 error_num = param_string_parse.print_param_error(); \
1159 goto error; \
1160 } \
1161 DBUG_PRINT("info",("spider " title_name "=%lld", \
1162 direct_sql->param_name)); \
1163 } \
1164 break; \
1165 }
1166
spider_udf_parse_direct_sql_param(SPIDER_TRX * trx,SPIDER_DIRECT_SQL * direct_sql,const char * param,int param_length)1167 int spider_udf_parse_direct_sql_param(
1168 SPIDER_TRX *trx,
1169 SPIDER_DIRECT_SQL *direct_sql,
1170 const char *param,
1171 int param_length
1172 ) {
1173 int error_num = 0, roop_count;
1174 char *param_string = NULL;
1175 char *sprit_ptr;
1176 char *tmp_ptr, *tmp_ptr2, *start_ptr;
1177 int title_length;
1178 SPIDER_PARAM_STRING_PARSE param_string_parse;
1179 DBUG_ENTER("spider_udf_parse_direct_sql_param");
1180 direct_sql->tgt_port = -1;
1181 direct_sql->tgt_ssl_vsc = -1;
1182 direct_sql->table_loop_mode = -1;
1183 direct_sql->priority = -1;
1184 direct_sql->connect_timeout = -1;
1185 direct_sql->net_read_timeout = -1;
1186 direct_sql->net_write_timeout = -1;
1187 direct_sql->bulk_insert_rows = -1;
1188 direct_sql->connection_channel = -1;
1189 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1190 direct_sql->access_mode = -1;
1191 #endif
1192 #if MYSQL_VERSION_ID < 50500
1193 #else
1194 direct_sql->use_real_table = -1;
1195 #endif
1196 direct_sql->error_rw_mode = -1;
1197 for (roop_count = 0; roop_count < direct_sql->table_count; roop_count++)
1198 direct_sql->iop[roop_count] = -1;
1199
1200 if (param_length == 0)
1201 goto set_default;
1202 DBUG_PRINT("info",("spider create param_string string"));
1203 if (
1204 !(param_string = spider_create_string(
1205 param,
1206 param_length))
1207 ) {
1208 error_num = HA_ERR_OUT_OF_MEM;
1209 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1210 goto error_alloc_param_string;
1211 }
1212 DBUG_PRINT("info",("spider param_string=%s", param_string));
1213
1214 sprit_ptr = param_string;
1215 param_string_parse.init(param_string, ER_SPIDER_INVALID_UDF_PARAM_NUM);
1216 while (sprit_ptr)
1217 {
1218 tmp_ptr = sprit_ptr;
1219 while (*tmp_ptr == ' ' || *tmp_ptr == '\r' ||
1220 *tmp_ptr == '\n' || *tmp_ptr == '\t')
1221 tmp_ptr++;
1222
1223 if (*tmp_ptr == '\0')
1224 break;
1225
1226 title_length = 0;
1227 start_ptr = tmp_ptr;
1228 while (*start_ptr != ' ' && *start_ptr != '\'' &&
1229 *start_ptr != '"' && *start_ptr != '\0' &&
1230 *start_ptr != '\r' && *start_ptr != '\n' &&
1231 *start_ptr != '\t')
1232 {
1233 title_length++;
1234 start_ptr++;
1235 }
1236 param_string_parse.set_param_title(tmp_ptr, tmp_ptr + title_length);
1237 if ((error_num = param_string_parse.get_next_parameter_head(
1238 start_ptr, &sprit_ptr)))
1239 {
1240 goto error;
1241 }
1242
1243 switch (title_length)
1244 {
1245 case 0:
1246 error_num = param_string_parse.print_param_error();
1247 if (error_num)
1248 goto error;
1249 continue;
1250 case 3:
1251 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1252 SPIDER_PARAM_INT_WITH_MAX("acm", access_mode, 0, 2);
1253 #endif
1254 SPIDER_PARAM_LONGLONG("bir", bulk_insert_rows, 0);
1255 SPIDER_PARAM_INT_WITH_MAX("cch", connection_channel, 0, 63);
1256 SPIDER_PARAM_INT("cto", connect_timeout, 0);
1257 SPIDER_PARAM_STR("dff", tgt_default_file);
1258 SPIDER_PARAM_STR("dfg", tgt_default_group);
1259 SPIDER_PARAM_STR("dsn", tgt_dsn);
1260 SPIDER_PARAM_LONGLONG("prt", priority, 0);
1261 SPIDER_PARAM_INT("rto", net_read_timeout, 0);
1262 SPIDER_PARAM_STR("sca", tgt_ssl_ca);
1263 SPIDER_PARAM_STR("sch", tgt_ssl_cipher);
1264 SPIDER_PARAM_STR("scp", tgt_ssl_capath);
1265 SPIDER_PARAM_STR("scr", tgt_ssl_cert);
1266 SPIDER_PARAM_STR("sky", tgt_ssl_key);
1267 SPIDER_PARAM_STR("srv", server_name);
1268 SPIDER_PARAM_INT_WITH_MAX("svc", tgt_ssl_vsc, 0, 1);
1269 SPIDER_PARAM_INT_WITH_MAX("tlm", table_loop_mode, 0, 2);
1270 #if MYSQL_VERSION_ID < 50500
1271 #else
1272 SPIDER_PARAM_INT_WITH_MAX("urt", use_real_table, 0, 1);
1273 #endif
1274 SPIDER_PARAM_INT("wto", net_write_timeout, 0);
1275 error_num = param_string_parse.print_param_error();
1276 goto error;
1277 case 4:
1278 SPIDER_PARAM_INT_WITH_MAX("erwm", error_rw_mode, 0, 1);
1279 SPIDER_PARAM_STR("host", tgt_host);
1280 SPIDER_PARAM_INT_WITH_MAX("port", tgt_port, 0, 65535);
1281 SPIDER_PARAM_STR("user", tgt_username);
1282 error_num = param_string_parse.print_param_error();
1283 goto error;
1284 case 6:
1285 SPIDER_PARAM_STR("server", server_name);
1286 SPIDER_PARAM_STR("socket", tgt_socket);
1287 SPIDER_PARAM_HINT_WITH_MAX("iop", iop, 3, direct_sql->table_count, 0, 2);
1288 SPIDER_PARAM_STR("ssl_ca", tgt_ssl_ca);
1289 error_num = param_string_parse.print_param_error();
1290 goto error;
1291 case 7:
1292 SPIDER_PARAM_STR("wrapper", tgt_wrapper);
1293 SPIDER_PARAM_STR("ssl_key", tgt_ssl_key);
1294 error_num = param_string_parse.print_param_error();
1295 goto error;
1296 case 8:
1297 SPIDER_PARAM_STR("database", tgt_default_db_name);
1298 SPIDER_PARAM_STR("password", tgt_password);
1299 SPIDER_PARAM_LONGLONG("priority", priority, 0);
1300 SPIDER_PARAM_STR("ssl_cert", tgt_ssl_cert);
1301 error_num = param_string_parse.print_param_error();
1302 goto error;
1303 case 10:
1304 SPIDER_PARAM_STR("ssl_cipher", tgt_ssl_cipher);
1305 SPIDER_PARAM_STR("ssl_capath", tgt_ssl_capath);
1306 error_num = param_string_parse.print_param_error();
1307 goto error;
1308 case 11:
1309 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1310 SPIDER_PARAM_INT_WITH_MAX("access_mode", access_mode, 0, 2);
1311 #endif
1312 error_num = param_string_parse.print_param_error();
1313 goto error;
1314 case 12:
1315 SPIDER_PARAM_STR("default_file", tgt_default_file);
1316 error_num = param_string_parse.print_param_error();
1317 goto error;
1318 case 13:
1319 SPIDER_PARAM_STR("default_group", tgt_default_group);
1320 SPIDER_PARAM_INT_WITH_MAX("error_rw_mode", error_rw_mode, 0, 1);
1321 error_num = param_string_parse.print_param_error();
1322 goto error;
1323 case 14:
1324 #if MYSQL_VERSION_ID < 50500
1325 #else
1326 SPIDER_PARAM_INT_WITH_MAX("use_real_table", use_real_table, 0, 1);
1327 #endif
1328 error_num = param_string_parse.print_param_error();
1329 goto error;
1330 case 15:
1331 SPIDER_PARAM_INT_WITH_MAX("table_loop_mode", table_loop_mode, 0, 2);
1332 SPIDER_PARAM_INT("connect_timeout", connect_timeout, 0);
1333 error_num = param_string_parse.print_param_error();
1334 goto error;
1335 case 16:
1336 SPIDER_PARAM_LONGLONG("bulk_insert_rows", bulk_insert_rows, 1);
1337 SPIDER_PARAM_INT("net_read_timeout", net_read_timeout, 0);
1338 error_num = param_string_parse.print_param_error();
1339 goto error;
1340 case 17:
1341 SPIDER_PARAM_INT("net_write_timeout", net_write_timeout, 0);
1342 error_num = param_string_parse.print_param_error();
1343 goto error;
1344 case 18:
1345 SPIDER_PARAM_INT_WITH_MAX(
1346 "connection_channel", connection_channel, 0, 63);
1347 error_num = param_string_parse.print_param_error();
1348 goto error;
1349 case 22:
1350 SPIDER_PARAM_INT_WITH_MAX("ssl_verify_server_cert", tgt_ssl_vsc, 0, 1);
1351 error_num = param_string_parse.print_param_error();
1352 goto error;
1353 default:
1354 error_num = param_string_parse.print_param_error();
1355 goto error;
1356 }
1357
1358 /* Verify that the remainder of the parameter value is whitespace */
1359 if ((error_num = param_string_parse.has_extra_parameter_values()))
1360 goto error;
1361 }
1362
1363 set_default:
1364 if ((error_num = spider_udf_set_direct_sql_param_default(
1365 trx,
1366 direct_sql
1367 )))
1368 goto error;
1369
1370 if (param_string)
1371 {
1372 spider_free(spider_current_trx, param_string, MYF(0));
1373 }
1374 DBUG_RETURN(0);
1375
1376 error:
1377 if (param_string)
1378 {
1379 spider_free(spider_current_trx, param_string, MYF(0));
1380 }
1381 error_alloc_param_string:
1382 DBUG_RETURN(error_num);
1383 }
1384
spider_udf_set_direct_sql_param_default(SPIDER_TRX * trx,SPIDER_DIRECT_SQL * direct_sql)1385 int spider_udf_set_direct_sql_param_default(
1386 SPIDER_TRX *trx,
1387 SPIDER_DIRECT_SQL *direct_sql
1388 ) {
1389 bool check_socket;
1390 bool check_database;
1391 bool socket_has_default_value;
1392 bool database_has_default_value;
1393 int error_num, roop_count;
1394 DBUG_ENTER("spider_udf_set_direct_sql_param_default");
1395 if (direct_sql->server_name)
1396 {
1397 if ((error_num = spider_udf_direct_sql_get_server(direct_sql)))
1398 DBUG_RETURN(error_num);
1399 }
1400
1401 if (
1402 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1403 direct_sql->access_mode == 0 &&
1404 #endif
1405 !direct_sql->tgt_socket &&
1406 (!direct_sql->tgt_host || !strcmp(direct_sql->tgt_host, my_localhost))
1407 ) {
1408 check_socket = TRUE;
1409 } else {
1410 check_socket = FALSE;
1411 }
1412 if (!direct_sql->tgt_default_db_name)
1413 {
1414 check_database = TRUE;
1415 } else {
1416 check_database = FALSE;
1417 }
1418 if (check_socket || check_database)
1419 {
1420 socket_has_default_value = check_socket;
1421 database_has_default_value = check_database;
1422 if (direct_sql->tgt_wrapper)
1423 {
1424 for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
1425 {
1426 DBUG_PRINT("info",("spider direct_sql->tgt_wrapper=%s",
1427 direct_sql->tgt_wrapper));
1428 DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", roop_count,
1429 spider_dbton[roop_count].wrapper ?
1430 spider_dbton[roop_count].wrapper : "NULL"));
1431 if (
1432 spider_dbton[roop_count].wrapper &&
1433 !strcmp(direct_sql->tgt_wrapper,
1434 spider_dbton[roop_count].wrapper)
1435 ) {
1436 if (spider_dbton[roop_count].db_access_type ==
1437 SPIDER_DB_ACCESS_TYPE_SQL)
1438 {
1439 if (check_socket)
1440 {
1441 socket_has_default_value = spider_dbton[roop_count].
1442 db_util->socket_has_default_value();
1443 }
1444 if (check_database)
1445 {
1446 database_has_default_value = spider_dbton[roop_count].
1447 db_util->database_has_default_value();
1448 }
1449 break;
1450 }
1451 }
1452 }
1453 }
1454 } else {
1455 socket_has_default_value = FALSE;
1456 database_has_default_value = FALSE;
1457 }
1458
1459 if (database_has_default_value)
1460 {
1461 DBUG_PRINT("info",("spider create default tgt_default_db_name"));
1462 direct_sql->tgt_default_db_name_length = SPIDER_THD_db_length(trx->thd);
1463 if (
1464 !(direct_sql->tgt_default_db_name = spider_create_string(
1465 SPIDER_THD_db_str(trx->thd),
1466 direct_sql->tgt_default_db_name_length))
1467 ) {
1468 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1469 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1470 }
1471 }
1472
1473 if (!direct_sql->tgt_wrapper)
1474 {
1475 DBUG_PRINT("info",("spider create default tgt_wrapper"));
1476 direct_sql->tgt_wrapper_length = SPIDER_DB_WRAPPER_LEN;
1477 if (
1478 !(direct_sql->tgt_wrapper = spider_create_string(
1479 SPIDER_DB_WRAPPER_STR,
1480 direct_sql->tgt_wrapper_length))
1481 ) {
1482 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1483 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1484 }
1485 }
1486
1487 if (!direct_sql->tgt_host)
1488 {
1489 DBUG_PRINT("info",("spider create default tgt_host"));
1490 direct_sql->tgt_host_length = strlen(my_localhost);
1491 if (
1492 !(direct_sql->tgt_host = spider_create_string(
1493 my_localhost,
1494 direct_sql->tgt_host_length))
1495 ) {
1496 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1497 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1498 }
1499 }
1500
1501 if (
1502 !direct_sql->tgt_default_file &&
1503 direct_sql->tgt_default_group &&
1504 (*spd_defaults_file || *spd_defaults_extra_file)
1505 ) {
1506 DBUG_PRINT("info",("spider create default tgt_default_file"));
1507 if (*spd_defaults_extra_file)
1508 {
1509 direct_sql->tgt_default_file_length = strlen(*spd_defaults_extra_file);
1510 if (
1511 !(direct_sql->tgt_default_file = spider_create_string(
1512 *spd_defaults_extra_file,
1513 direct_sql->tgt_default_file_length))
1514 ) {
1515 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1516 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1517 }
1518 } else {
1519 direct_sql->tgt_default_file_length = strlen(*spd_defaults_file);
1520 if (
1521 !(direct_sql->tgt_default_file = spider_create_string(
1522 *spd_defaults_file,
1523 direct_sql->tgt_default_file_length))
1524 ) {
1525 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1526 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1527 }
1528 }
1529 }
1530
1531 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1532 if (direct_sql->access_mode == -1)
1533 direct_sql->access_mode = 0;
1534 #endif
1535
1536 if (direct_sql->tgt_port == -1)
1537 {
1538 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1539 if (direct_sql->access_mode == 1)
1540 direct_sql->tgt_port = 9998;
1541 else if (direct_sql->access_mode == 2)
1542 direct_sql->tgt_port = 9999;
1543 else
1544 #endif
1545 direct_sql->tgt_port = MYSQL_PORT;
1546 }
1547 else if (direct_sql->tgt_port < 0)
1548 direct_sql->tgt_port = 0;
1549 else if (direct_sql->tgt_port > 65535)
1550 direct_sql->tgt_port = 65535;
1551
1552 if (direct_sql->tgt_ssl_vsc == -1)
1553 direct_sql->tgt_ssl_vsc = 0;
1554
1555 if (socket_has_default_value)
1556 {
1557 DBUG_PRINT("info",("spider create default tgt_socket"));
1558 direct_sql->tgt_socket_length = strlen((char *) MYSQL_UNIX_ADDR);
1559 if (
1560 !(direct_sql->tgt_socket = spider_create_string(
1561 (char *) MYSQL_UNIX_ADDR,
1562 direct_sql->tgt_socket_length))
1563 ) {
1564 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1565 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1566 }
1567 }
1568
1569 if (direct_sql->table_loop_mode == -1)
1570 direct_sql->table_loop_mode = 0;
1571 if (direct_sql->priority == -1)
1572 direct_sql->priority = 1000000;
1573 if (direct_sql->connect_timeout == -1)
1574 direct_sql->connect_timeout = 6;
1575 if (direct_sql->net_read_timeout == -1)
1576 direct_sql->net_read_timeout = 600;
1577 if (direct_sql->net_write_timeout == -1)
1578 direct_sql->net_write_timeout = 600;
1579 if (direct_sql->bulk_insert_rows == -1)
1580 direct_sql->bulk_insert_rows = 3000;
1581 if (direct_sql->connection_channel == -1)
1582 direct_sql->connection_channel = 0;
1583 #if MYSQL_VERSION_ID < 50500
1584 #else
1585 if (direct_sql->use_real_table == -1)
1586 direct_sql->use_real_table = 0;
1587 #endif
1588 if (direct_sql->error_rw_mode == -1)
1589 direct_sql->error_rw_mode = 0;
1590 for (roop_count = 0; roop_count < direct_sql->table_count; roop_count++)
1591 {
1592 if (direct_sql->iop[roop_count] == -1)
1593 direct_sql->iop[roop_count] = 0;
1594 }
1595 DBUG_RETURN(0);
1596 }
1597
spider_udf_free_direct_sql_alloc(SPIDER_DIRECT_SQL * direct_sql,my_bool bg)1598 void spider_udf_free_direct_sql_alloc(
1599 SPIDER_DIRECT_SQL *direct_sql,
1600 my_bool bg
1601 ) {
1602 SPIDER_BG_DIRECT_SQL *bg_direct_sql;
1603 DBUG_ENTER("spider_udf_free_direct_sql_alloc");
1604 #ifndef WITHOUT_SPIDER_BG_SEARCH
1605 if (bg)
1606 {
1607 pthread_mutex_lock(direct_sql->bg_mutex);
1608 bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) direct_sql->parent;
1609 if (bg_direct_sql->direct_sql == direct_sql)
1610 bg_direct_sql->direct_sql = direct_sql->next;
1611 if (direct_sql->next)
1612 direct_sql->next->prev = direct_sql->prev;
1613 if (direct_sql->prev)
1614 direct_sql->prev->next = direct_sql->next;
1615 pthread_cond_signal(direct_sql->bg_cond);
1616 pthread_mutex_unlock(direct_sql->bg_mutex);
1617 }
1618 #endif
1619 #if MYSQL_VERSION_ID < 50500
1620 #else
1621 if (direct_sql->real_table_used && direct_sql->open_tables_thd)
1622 {
1623 spider_sys_close_table(direct_sql->open_tables_thd,
1624 &direct_sql->open_tables_backup);
1625 }
1626 #endif
1627 if (direct_sql->server_name)
1628 {
1629 spider_free(spider_current_trx, direct_sql->server_name, MYF(0));
1630 }
1631 if (direct_sql->tgt_default_db_name)
1632 {
1633 spider_free(spider_current_trx, direct_sql->tgt_default_db_name, MYF(0));
1634 }
1635 if (direct_sql->tgt_host)
1636 {
1637 spider_free(spider_current_trx, direct_sql->tgt_host, MYF(0));
1638 }
1639 if (direct_sql->tgt_username)
1640 {
1641 spider_free(spider_current_trx, direct_sql->tgt_username, MYF(0));
1642 }
1643 if (direct_sql->tgt_password)
1644 {
1645 spider_free(spider_current_trx, direct_sql->tgt_password, MYF(0));
1646 }
1647 if (direct_sql->tgt_socket)
1648 {
1649 spider_free(spider_current_trx, direct_sql->tgt_socket, MYF(0));
1650 }
1651 if (direct_sql->tgt_wrapper)
1652 {
1653 spider_free(spider_current_trx, direct_sql->tgt_wrapper, MYF(0));
1654 }
1655 if (direct_sql->tgt_ssl_ca)
1656 {
1657 spider_free(spider_current_trx, direct_sql->tgt_ssl_ca, MYF(0));
1658 }
1659 if (direct_sql->tgt_ssl_capath)
1660 {
1661 spider_free(spider_current_trx, direct_sql->tgt_ssl_capath, MYF(0));
1662 }
1663 if (direct_sql->tgt_ssl_cert)
1664 {
1665 spider_free(spider_current_trx, direct_sql->tgt_ssl_cert, MYF(0));
1666 }
1667 if (direct_sql->tgt_ssl_cipher)
1668 {
1669 spider_free(spider_current_trx, direct_sql->tgt_ssl_cipher, MYF(0));
1670 }
1671 if (direct_sql->tgt_ssl_key)
1672 {
1673 spider_free(spider_current_trx, direct_sql->tgt_ssl_key, MYF(0));
1674 }
1675 if (direct_sql->tgt_default_file)
1676 {
1677 spider_free(spider_current_trx, direct_sql->tgt_default_file, MYF(0));
1678 }
1679 if (direct_sql->tgt_default_group)
1680 {
1681 spider_free(spider_current_trx, direct_sql->tgt_default_group, MYF(0));
1682 }
1683 if (direct_sql->tgt_dsn)
1684 {
1685 spider_free(spider_current_trx, direct_sql->tgt_dsn, MYF(0));
1686 }
1687 if (direct_sql->conn_key)
1688 {
1689 spider_free(spider_current_trx, direct_sql->conn_key, MYF(0));
1690 }
1691 if (direct_sql->db_names)
1692 {
1693 spider_free(spider_current_trx, direct_sql->db_names, MYF(0));
1694 }
1695 spider_free(spider_current_trx, direct_sql, MYF(0));
1696 DBUG_VOID_RETURN;
1697 }
1698
spider_direct_sql_body(UDF_INIT * initid,UDF_ARGS * args,char * is_null,char * error,my_bool bg)1699 long long spider_direct_sql_body(
1700 UDF_INIT *initid,
1701 UDF_ARGS *args,
1702 char *is_null,
1703 char *error,
1704 my_bool bg
1705 ) {
1706 int error_num, roop_count;
1707 SPIDER_DIRECT_SQL *direct_sql = NULL, *tmp_direct_sql;
1708 THD *thd = current_thd;
1709 SPIDER_TRX *trx;
1710 SPIDER_CONN *conn;
1711 char *sql;
1712 TABLE_LIST table_list;
1713 SPIDER_BG_DIRECT_SQL *bg_direct_sql;
1714 #if MYSQL_VERSION_ID < 50500
1715 #else
1716 TABLE_LIST *real_table_list_last = NULL;
1717 uint use_real_table = 0;
1718 #endif
1719 DBUG_ENTER("spider_direct_sql_body");
1720 SPIDER_BACKUP_DASTATUS;
1721 if (!(direct_sql = (SPIDER_DIRECT_SQL *)
1722 spider_bulk_malloc(spider_current_trx, 34, MYF(MY_WME | MY_ZEROFILL),
1723 &direct_sql, (uint) (sizeof(SPIDER_DIRECT_SQL)),
1724 &sql, (uint) (sizeof(char) * args->lengths[0]),
1725 NullS))
1726 ) {
1727 error_num = HA_ERR_OUT_OF_MEM;
1728 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1729 goto error;
1730 }
1731 #ifndef WITHOUT_SPIDER_BG_SEARCH
1732 if (bg)
1733 {
1734 bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) initid->ptr;
1735 pthread_mutex_lock(&bg_direct_sql->bg_mutex);
1736 tmp_direct_sql = (SPIDER_DIRECT_SQL *) bg_direct_sql->direct_sql;
1737 bg_direct_sql->direct_sql = direct_sql;
1738 if (tmp_direct_sql)
1739 {
1740 tmp_direct_sql->prev = direct_sql;
1741 direct_sql->next = tmp_direct_sql;
1742 }
1743 pthread_mutex_unlock(&bg_direct_sql->bg_mutex);
1744 direct_sql->bg_mutex = &bg_direct_sql->bg_mutex;
1745 direct_sql->bg_cond = &bg_direct_sql->bg_cond;
1746 direct_sql->parent = bg_direct_sql;
1747 bg_direct_sql->called_cnt++;
1748 }
1749 #endif
1750 if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
1751 {
1752 if (error_num == HA_ERR_OUT_OF_MEM)
1753 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1754 goto error;
1755 }
1756 direct_sql->trx = trx;
1757
1758 if (args->args[1])
1759 {
1760 if ((error_num = spider_udf_direct_sql_create_table_list(
1761 direct_sql,
1762 args->args[1],
1763 args->lengths[1]
1764 ))) {
1765 if (error_num == HA_ERR_OUT_OF_MEM)
1766 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1767 goto error;
1768 }
1769 } else {
1770 if ((error_num = spider_udf_direct_sql_create_table_list(
1771 direct_sql,
1772 (char *) "",
1773 0
1774 ))) {
1775 if (error_num == HA_ERR_OUT_OF_MEM)
1776 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1777 goto error;
1778 }
1779 }
1780 if (args->args[2])
1781 {
1782 if ((error_num = spider_udf_parse_direct_sql_param(
1783 trx,
1784 direct_sql,
1785 args->args[2],
1786 args->lengths[2]
1787 ))) {
1788 goto error;
1789 }
1790 } else {
1791 if ((error_num = spider_udf_parse_direct_sql_param(
1792 trx,
1793 direct_sql,
1794 "",
1795 0
1796 ))) {
1797 goto error;
1798 }
1799 }
1800 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1801 if (trx->trx_start && direct_sql->access_mode != 1)
1802 {
1803 #endif
1804 trx->updated_in_this_trx = TRUE;
1805 DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE"));
1806 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
1807 }
1808 #endif
1809 #if MYSQL_VERSION_ID < 50500
1810 #else
1811 use_real_table = spider_param_udf_ds_use_real_table(thd,
1812 direct_sql->use_real_table);
1813 #endif
1814 for (roop_count = 0; roop_count < direct_sql->table_count; roop_count++)
1815 {
1816 #ifdef SPIDER_NEED_INIT_ONE_TABLE_FOR_FIND_TEMPORARY_TABLE
1817 #ifdef SPIDER_use_LEX_CSTRING_for_database_tablename_alias
1818 LEX_CSTRING db_name =
1819 {
1820 direct_sql->db_names[roop_count],
1821 strlen(direct_sql->db_names[roop_count])
1822 };
1823 LEX_CSTRING tbl_name =
1824 {
1825 direct_sql->table_names[roop_count],
1826 strlen(direct_sql->table_names[roop_count])
1827 };
1828 table_list.init_one_table(&db_name, &tbl_name, 0, TL_WRITE);
1829 #else
1830 table_list.init_one_table(direct_sql->db_names[roop_count],
1831 strlen(direct_sql->db_names[roop_count]),
1832 direct_sql->table_names[roop_count],
1833 strlen(direct_sql->table_names[roop_count]),
1834 direct_sql->table_names[roop_count], TL_WRITE);
1835 #endif
1836 #else
1837 SPIDER_TABLE_LIST_db_str(&table_list) = direct_sql->db_names[roop_count];
1838 SPIDER_TABLE_LIST_table_name_str(&table_list) =
1839 direct_sql->table_names[roop_count];
1840 #endif
1841 if (!(direct_sql->tables[roop_count] =
1842 spider_find_temporary_table(thd, &table_list)))
1843 {
1844 #if MYSQL_VERSION_ID < 50500
1845 #else
1846 if (!use_real_table)
1847 {
1848 #endif
1849 error_num = ER_SPIDER_UDF_TMP_TABLE_NOT_FOUND_NUM;
1850 my_printf_error(ER_SPIDER_UDF_TMP_TABLE_NOT_FOUND_NUM,
1851 ER_SPIDER_UDF_TMP_TABLE_NOT_FOUND_STR,
1852 MYF(0), SPIDER_TABLE_LIST_db_str(&table_list),
1853 SPIDER_TABLE_LIST_table_name_str(&table_list));
1854 goto error;
1855 #if MYSQL_VERSION_ID < 50500
1856 #else
1857 }
1858 TABLE_LIST *tables = &direct_sql->table_list[roop_count];
1859 #ifdef SPIDER_use_LEX_CSTRING_for_database_tablename_alias
1860 table_list.init_one_table(
1861 &table_list.db, &table_list.table_name, 0, TL_WRITE);
1862 #else
1863 tables->init_one_table(
1864 SPIDER_TABLE_LIST_db_str(&table_list),
1865 SPIDER_TABLE_LIST_db_length(&table_list),
1866 SPIDER_TABLE_LIST_table_name_str(&table_list),
1867 SPIDER_TABLE_LIST_table_name_length(&table_list),
1868 SPIDER_TABLE_LIST_table_name_str(&table_list), TL_WRITE);
1869 #endif
1870 MDL_REQUEST_INIT(&tables->mdl_request, MDL_key::TABLE,
1871 SPIDER_TABLE_LIST_db_str(&table_list),
1872 SPIDER_TABLE_LIST_table_name_str(&table_list),
1873 MDL_SHARED_WRITE, MDL_TRANSACTION);
1874 if (!direct_sql->table_list_first)
1875 {
1876 direct_sql->table_list_first = tables;
1877 } else {
1878 real_table_list_last->next_global = tables;
1879 }
1880 real_table_list_last = tables;
1881 spider_set_bit(direct_sql->real_table_bitmap, roop_count);
1882 direct_sql->real_table_used = TRUE;
1883 #endif
1884 }
1885 }
1886 if ((error_num = spider_udf_direct_sql_create_conn_key(direct_sql)))
1887 {
1888 if (error_num == HA_ERR_OUT_OF_MEM)
1889 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1890 goto error;
1891 }
1892 if (!(conn = spider_udf_direct_sql_get_conn(direct_sql, trx, &error_num)))
1893 {
1894 if (error_num == HA_ERR_OUT_OF_MEM)
1895 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1896 goto error;
1897 }
1898 conn->error_mode = 0;
1899 direct_sql->conn = conn;
1900 if ((error_num = spider_db_udf_check_and_set_set_names(trx)))
1901 {
1902 if (error_num == HA_ERR_OUT_OF_MEM)
1903 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1904 goto error;
1905 }
1906 if (args->args[0])
1907 {
1908 direct_sql->sql_length = args->lengths[0];
1909 memcpy(sql, args->args[0], direct_sql->sql_length);
1910 } else
1911 direct_sql->sql_length = 0;
1912 direct_sql->sql = sql;
1913
1914 #ifndef WITHOUT_SPIDER_BG_SEARCH
1915 if (bg)
1916 {
1917 if ((error_num = spider_udf_bg_direct_sql(direct_sql)))
1918 {
1919 if (error_num == HA_ERR_OUT_OF_MEM)
1920 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1921 goto error;
1922 }
1923 } else {
1924 #endif
1925 if (conn->bg_init)
1926 pthread_mutex_lock(&conn->bg_conn_mutex);
1927 if ((error_num = spider_db_udf_direct_sql(direct_sql)))
1928 {
1929 if (conn->bg_init)
1930 pthread_mutex_unlock(&conn->bg_conn_mutex);
1931 if (direct_sql->modified_non_trans_table)
1932 thd->transaction->stmt.modified_non_trans_table = TRUE;
1933 if (error_num == HA_ERR_OUT_OF_MEM)
1934 my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
1935 goto error;
1936 }
1937 if (conn->bg_init)
1938 pthread_mutex_unlock(&conn->bg_conn_mutex);
1939 if (direct_sql->modified_non_trans_table)
1940 thd->transaction->stmt.modified_non_trans_table = TRUE;
1941 #ifndef WITHOUT_SPIDER_BG_SEARCH
1942 }
1943 if (!bg)
1944 {
1945 #endif
1946 spider_udf_free_direct_sql_alloc(direct_sql, FALSE);
1947 #ifndef WITHOUT_SPIDER_BG_SEARCH
1948 }
1949 #endif
1950 DBUG_RETURN(1);
1951
1952 error:
1953 if (direct_sql)
1954 {
1955 if (
1956 direct_sql->error_rw_mode &&
1957 spider_db_conn_is_network_error(error_num)
1958 ) {
1959 SPIDER_RESTORE_DASTATUS;
1960 spider_udf_free_direct_sql_alloc(direct_sql, bg);
1961 DBUG_RETURN(1);
1962 }
1963 spider_udf_free_direct_sql_alloc(direct_sql, bg);
1964 }
1965 *error = 1;
1966 DBUG_RETURN(0);
1967 }
1968
1969 my_bool spider_direct_sql_init_body(
1970 UDF_INIT *initid,
1971 UDF_ARGS *args,
1972 char *message,
1973 my_bool bg
1974 ) {
1975 SPIDER_BG_DIRECT_SQL *bg_direct_sql;
1976 DBUG_ENTER("spider_direct_sql_init_body");
1977 if (args->arg_count != 3)
1978 {
1979 strcpy(message, "spider_(bg)_direct_sql() requires 3 arguments");
1980 goto error;
1981 }
1982 if (
1983 args->arg_type[0] != STRING_RESULT ||
1984 args->arg_type[1] != STRING_RESULT ||
1985 args->arg_type[2] != STRING_RESULT
1986 ) {
1987 strcpy(message, "spider_(bg)_direct_sql() requires string arguments");
1988 goto error;
1989 }
1990 #ifndef WITHOUT_SPIDER_BG_SEARCH
1991 if (bg)
1992 {
1993 if (!(bg_direct_sql = (SPIDER_BG_DIRECT_SQL *)
1994 spider_malloc(spider_current_trx, 10, sizeof(SPIDER_BG_DIRECT_SQL),
1995 MYF(MY_WME | MY_ZEROFILL)))
1996 ) {
1997 strcpy(message, "spider_bg_direct_sql() out of memory");
1998 goto error;
1999 }
2000 #if MYSQL_VERSION_ID < 50500
2001 if (pthread_mutex_init(&bg_direct_sql->bg_mutex, MY_MUTEX_INIT_FAST))
2002 #else
2003 if (mysql_mutex_init(spd_key_mutex_bg_direct_sql,
2004 &bg_direct_sql->bg_mutex, MY_MUTEX_INIT_FAST))
2005 #endif
2006 {
2007 strcpy(message, "spider_bg_direct_sql() out of memory");
2008 goto error_mutex_init;
2009 }
2010 #if MYSQL_VERSION_ID < 50500
2011 if (pthread_cond_init(&bg_direct_sql->bg_cond, NULL))
2012 #else
2013 if (mysql_cond_init(spd_key_cond_bg_direct_sql,
2014 &bg_direct_sql->bg_cond, NULL))
2015 #endif
2016 {
2017 strcpy(message, "spider_bg_direct_sql() out of memory");
2018 goto error_cond_init;
2019 }
2020 initid->ptr = (char *) bg_direct_sql;
2021 }
2022 #endif
2023 DBUG_RETURN(FALSE);
2024
2025 #ifndef WITHOUT_SPIDER_BG_SEARCH
2026 error_cond_init:
2027 pthread_mutex_destroy(&bg_direct_sql->bg_mutex);
2028 error_mutex_init:
2029 spider_free(spider_current_trx, bg_direct_sql, MYF(0));
2030 #endif
2031 error:
2032 DBUG_RETURN(TRUE);
2033 }
2034
2035 void spider_direct_sql_deinit_body(
2036 UDF_INIT *initid
2037 ) {
2038 SPIDER_BG_DIRECT_SQL *bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) initid->ptr;
2039 DBUG_ENTER("spider_direct_sql_deinit_body");
2040 if (bg_direct_sql)
2041 {
2042 pthread_mutex_lock(&bg_direct_sql->bg_mutex);
2043 while (bg_direct_sql->direct_sql)
2044 pthread_cond_wait(&bg_direct_sql->bg_cond, &bg_direct_sql->bg_mutex);
2045 pthread_mutex_unlock(&bg_direct_sql->bg_mutex);
2046 if (bg_direct_sql->modified_non_trans_table)
2047 {
2048 THD *thd = current_thd;
2049 thd->transaction->stmt.modified_non_trans_table = TRUE;
2050 }
2051 pthread_cond_destroy(&bg_direct_sql->bg_cond);
2052 pthread_mutex_destroy(&bg_direct_sql->bg_mutex);
2053 spider_free(spider_current_trx, bg_direct_sql, MYF(0));
2054 }
2055 DBUG_VOID_RETURN;
2056 }
2057
2058 #ifndef WITHOUT_SPIDER_BG_SEARCH
2059 void spider_direct_sql_bg_start(
2060 UDF_INIT *initid
2061 ) {
2062 SPIDER_BG_DIRECT_SQL *bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) initid->ptr;
2063 DBUG_ENTER("spider_direct_sql_bg_start");
2064 bg_direct_sql->called_cnt = 0;
2065 bg_direct_sql->bg_error = 0;
2066 DBUG_VOID_RETURN;
2067 }
2068
2069 long long spider_direct_sql_bg_end(
2070 UDF_INIT *initid
2071 ) {
2072 THD *thd = current_thd;
2073 SPIDER_BG_DIRECT_SQL *bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) initid->ptr;
2074 DBUG_ENTER("spider_direct_sql_bg_end");
2075 pthread_mutex_lock(&bg_direct_sql->bg_mutex);
2076 while (bg_direct_sql->direct_sql)
2077 pthread_cond_wait(&bg_direct_sql->bg_cond, &bg_direct_sql->bg_mutex);
2078 pthread_mutex_unlock(&bg_direct_sql->bg_mutex);
2079 if (bg_direct_sql->modified_non_trans_table)
2080 thd->transaction->stmt.modified_non_trans_table = TRUE;
2081 if (bg_direct_sql->bg_error)
2082 {
2083 my_message(bg_direct_sql->bg_error, bg_direct_sql->bg_error_msg, MYF(0));
2084 DBUG_RETURN(0);
2085 }
2086 DBUG_RETURN(bg_direct_sql->called_cnt);
2087 }
2088
2089 int spider_udf_bg_direct_sql(
2090 SPIDER_DIRECT_SQL *direct_sql
2091 ) {
2092 int error_num;
2093 SPIDER_CONN *conn = direct_sql->conn;
2094 DBUG_ENTER("spider_udf_bg_direct_sql");
2095 if ((error_num = spider_create_conn_thread(conn)))
2096 DBUG_RETURN(error_num);
2097 if (!pthread_mutex_trylock(&conn->bg_conn_mutex))
2098 {
2099 DBUG_PRINT("info",("spider get bg_conn_mutex"));
2100 conn->bg_target = direct_sql;
2101 conn->bg_direct_sql = TRUE;
2102 conn->bg_caller_sync_wait = TRUE;
2103 pthread_mutex_lock(&conn->bg_conn_sync_mutex);
2104 pthread_cond_signal(&conn->bg_conn_cond);
2105 pthread_mutex_unlock(&conn->bg_conn_mutex);
2106 pthread_cond_wait(&conn->bg_conn_sync_cond, &conn->bg_conn_sync_mutex);
2107 pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
2108 conn->bg_caller_sync_wait = FALSE;
2109 } else {
2110 DBUG_PRINT("info",("spider get put job stack"));
2111 bool bg_get_job_stack = FALSE;
2112 pthread_mutex_lock(&conn->bg_job_stack_mutex);
2113 uint old_elements = conn->bg_job_stack.max_element;
2114 if (insert_dynamic(&conn->bg_job_stack, (uchar *) &direct_sql))
2115 {
2116 pthread_mutex_unlock(&conn->bg_job_stack_mutex);
2117 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
2118 }
2119 if (conn->bg_job_stack.max_element > old_elements)
2120 {
2121 spider_alloc_calc_mem(spider_current_trx,
2122 conn->bg_job_stack,
2123 (conn->bg_job_stack.max_element - old_elements) *
2124 conn->bg_job_stack.size_of_element);
2125 }
2126 if (!conn->bg_get_job_stack_off)
2127 bg_get_job_stack = TRUE;
2128 pthread_mutex_unlock(&conn->bg_job_stack_mutex);
2129 if (bg_get_job_stack)
2130 {
2131 DBUG_PRINT("info",("spider get bg_conn_mutex"));
2132 pthread_mutex_lock(&conn->bg_conn_mutex);
2133 conn->bg_target = NULL;
2134 conn->bg_get_job_stack = TRUE;
2135 conn->bg_direct_sql = TRUE;
2136 conn->bg_caller_sync_wait = TRUE;
2137 pthread_mutex_lock(&conn->bg_conn_sync_mutex);
2138 pthread_cond_signal(&conn->bg_conn_cond);
2139 pthread_mutex_unlock(&conn->bg_conn_mutex);
2140 pthread_cond_wait(&conn->bg_conn_sync_cond, &conn->bg_conn_sync_mutex);
2141 pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
2142 conn->bg_caller_sync_wait = FALSE;
2143 }
2144 }
2145 DBUG_RETURN(0);
2146 }
2147 #endif
2148