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, &param_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