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