1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2011-2013 Kentoku SHIBA |
4 | Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2.1 of the License, or (at your option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with this library; if not, write to the Free Software |
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ |
20 | |
21 | #include "mrn_mysql.h" |
22 | |
23 | #if MYSQL_VERSION_ID >= 50500 |
24 | # include <sql_servers.h> |
25 | # include <sql_base.h> |
26 | #endif |
27 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
28 | # include <partition_info.h> |
29 | #endif |
30 | #include <sql_plugin.h> |
31 | |
32 | #include "mrn_err.h" |
33 | #include "mrn_table.hpp" |
34 | #include "mrn_mysql_compat.h" |
35 | #include "mrn_variables.hpp" |
36 | #include <mrn_lock.hpp> |
37 | |
38 | #ifdef MRN_MARIADB_P |
39 | # if MYSQL_VERSION_ID >= 100100 |
40 | # define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE) |
41 | # else |
42 | # define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name)) |
43 | # endif |
44 | #else |
45 | # if MYSQL_VERSION_ID >= 50603 |
46 | # define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE) |
47 | # else |
48 | # define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name)) |
49 | # endif |
50 | #endif |
51 | |
52 | #if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P) |
53 | # define MRN_PLUGIN_DATA(plugin, type) plugin_data<type>(plugin) |
54 | #else |
55 | # define MRN_PLUGIN_DATA(plugin, type) plugin_data(plugin, type) |
56 | #endif |
57 | |
58 | #define LEX_STRING_IS_EMPTY(string) \ |
59 | ((string).length == 0 || !(string).str || (string).str[0] == '\0') |
60 | |
61 | #define MRN_DEFAULT_STR "DEFAULT" |
62 | #define MRN_DEFAULT_LEN (sizeof(MRN_DEFAULT_STR) - 1) |
63 | #define MRN_GROONGA_STR "GROONGA" |
64 | #define MRN_GROONGA_LEN (sizeof(MRN_GROONGA_STR) - 1) |
65 | |
66 | #ifdef MRN_HAVE_TABLE_DEF_CACHE |
67 | extern HASH *mrn_table_def_cache; |
68 | #endif |
69 | |
70 | #ifdef __cplusplus |
71 | extern "C" { |
72 | #endif |
73 | |
74 | #ifdef HAVE_PSI_INTERFACE |
75 | # ifdef WIN32 |
76 | # ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE |
77 | extern PSI_mutex_key *mrn_table_share_lock_share; |
78 | # endif |
79 | extern PSI_mutex_key *mrn_table_share_lock_ha_data; |
80 | # endif |
81 | extern PSI_mutex_key mrn_share_mutex_key; |
82 | extern PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key; |
83 | #endif |
84 | |
85 | extern HASH mrn_open_tables; |
86 | extern mysql_mutex_t mrn_open_tables_mutex; |
87 | extern HASH mrn_long_term_share; |
88 | extern mysql_mutex_t mrn_long_term_share_mutex; |
89 | extern char *mrn_default_tokenizer; |
90 | extern char *mrn_default_wrapper_engine; |
91 | extern handlerton *mrn_hton_ptr; |
92 | extern HASH mrn_allocated_thds; |
93 | extern mysql_mutex_t mrn_allocated_thds_mutex; |
94 | |
95 | static char *mrn_get_string_between_quote(const char *ptr) |
96 | { |
97 | const char *start_ptr, *end_ptr, *tmp_ptr, *esc_ptr; |
98 | bool find_flg = FALSE, esc_flg = FALSE; |
99 | MRN_DBUG_ENTER_FUNCTION(); |
100 | |
101 | start_ptr = strchr(ptr, '\''); |
102 | end_ptr = strchr(ptr, '"'); |
103 | if (start_ptr && (!end_ptr || start_ptr < end_ptr)) |
104 | { |
105 | tmp_ptr = ++start_ptr; |
106 | while (!find_flg) |
107 | { |
108 | if (!(end_ptr = strchr(tmp_ptr, '\''))) |
109 | DBUG_RETURN(NULL); |
110 | esc_ptr = tmp_ptr; |
111 | while (!find_flg) |
112 | { |
113 | esc_ptr = strchr(esc_ptr, '\\'); |
114 | if (!esc_ptr || esc_ptr > end_ptr) |
115 | find_flg = TRUE; |
116 | else if (esc_ptr == end_ptr - 1) |
117 | { |
118 | esc_flg = TRUE; |
119 | tmp_ptr = end_ptr + 1; |
120 | break; |
121 | } else { |
122 | esc_flg = TRUE; |
123 | esc_ptr += 2; |
124 | } |
125 | } |
126 | } |
127 | } else if (end_ptr) |
128 | { |
129 | start_ptr = end_ptr; |
130 | tmp_ptr = ++start_ptr; |
131 | while (!find_flg) |
132 | { |
133 | if (!(end_ptr = strchr(tmp_ptr, '"'))) |
134 | DBUG_RETURN(NULL); |
135 | esc_ptr = tmp_ptr; |
136 | while (!find_flg) |
137 | { |
138 | esc_ptr = strchr(esc_ptr, '\\'); |
139 | if (!esc_ptr || esc_ptr > end_ptr) |
140 | find_flg = TRUE; |
141 | else if (esc_ptr == end_ptr - 1) |
142 | { |
143 | esc_flg = TRUE; |
144 | tmp_ptr = end_ptr + 1; |
145 | break; |
146 | } else { |
147 | esc_flg = TRUE; |
148 | esc_ptr += 2; |
149 | } |
150 | } |
151 | } |
152 | } else |
153 | DBUG_RETURN(NULL); |
154 | |
155 | size_t length = end_ptr - start_ptr; |
156 | char * = (char *)mrn_my_malloc(length + 1, MYF(MY_WME)); |
157 | if (esc_flg) { |
158 | size_t = 0; |
159 | const char *current_ptr = start_ptr; |
160 | while (current_ptr < end_ptr) { |
161 | if (*current_ptr != '\\') { |
162 | extracted_string[extracted_index] = *current_ptr; |
163 | ++extracted_index; |
164 | current_ptr++; |
165 | continue; |
166 | } |
167 | |
168 | if (current_ptr + 1 == end_ptr) { |
169 | break; |
170 | } |
171 | |
172 | switch (*(current_ptr + 1)) |
173 | { |
174 | case 'b': |
175 | extracted_string[extracted_index] = '\b'; |
176 | break; |
177 | case 'n': |
178 | extracted_string[extracted_index] = '\n'; |
179 | break; |
180 | case 'r': |
181 | extracted_string[extracted_index] = '\r'; |
182 | break; |
183 | case 't': |
184 | extracted_string[extracted_index] = '\t'; |
185 | break; |
186 | default: |
187 | extracted_string[extracted_index] = *(current_ptr + 1); |
188 | break; |
189 | } |
190 | ++extracted_index; |
191 | } |
192 | } else { |
193 | memcpy(extracted_string, start_ptr, length); |
194 | extracted_string[length] = '\0'; |
195 | } |
196 | |
197 | DBUG_RETURN(extracted_string); |
198 | } |
199 | |
200 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
201 | void mrn_get_partition_info(const char *table_name, uint table_name_length, |
202 | const TABLE *table, partition_element **part_elem, |
203 | partition_element **sub_elem) |
204 | { |
205 | partition_info *part_info = table->part_info; |
206 | partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL; |
207 | bool tmp_flg = FALSE, tmp_find_flg = FALSE; |
208 | MRN_DBUG_ENTER_FUNCTION(); |
209 | *part_elem = NULL; |
210 | *sub_elem = NULL; |
211 | if (!part_info) |
212 | DBUG_VOID_RETURN; |
213 | |
214 | if (table_name && !memcmp(table_name + table_name_length - 5, "#TMP#" , 5)) |
215 | tmp_flg = TRUE; |
216 | |
217 | DBUG_PRINT("info" , ("mroonga table_name=%s" , table_name)); |
218 | List_iterator<partition_element> part_it(part_info->partitions); |
219 | while ((*part_elem = part_it++)) |
220 | { |
221 | if ((*part_elem)->subpartitions.elements) |
222 | { |
223 | List_iterator<partition_element> sub_it((*part_elem)->subpartitions); |
224 | while ((*sub_elem = sub_it++)) |
225 | { |
226 | char subpartition_name[FN_REFLEN + 1]; |
227 | int error = mrn_create_subpartition_name(subpartition_name, |
228 | sizeof(subpartition_name), |
229 | table->s->path.str, |
230 | (*part_elem)->partition_name, |
231 | (*sub_elem)->partition_name, |
232 | NORMAL_PART_NAME); |
233 | if (error != 0) |
234 | DBUG_VOID_RETURN; |
235 | DBUG_PRINT("info" , ("mroonga subpartition name=%s" , subpartition_name)); |
236 | if (table_name && |
237 | memcmp(table_name, subpartition_name, table_name_length + 1) == 0) |
238 | DBUG_VOID_RETURN; |
239 | if ( |
240 | tmp_flg && |
241 | table_name && |
242 | *(subpartition_name + table_name_length - 5) == '\0' && |
243 | memcmp(table_name, subpartition_name, table_name_length - 5) == 0 |
244 | ) { |
245 | tmp_part_elem = *part_elem; |
246 | tmp_sub_elem = *sub_elem; |
247 | tmp_flg = FALSE; |
248 | tmp_find_flg = TRUE; |
249 | } |
250 | } |
251 | } else { |
252 | char partition_name[FN_REFLEN + 1]; |
253 | int error = mrn_create_partition_name(partition_name, |
254 | sizeof(partition_name), |
255 | table->s->path.str, |
256 | (*part_elem)->partition_name, |
257 | NORMAL_PART_NAME, |
258 | TRUE); |
259 | if (error != 0) |
260 | DBUG_VOID_RETURN; |
261 | DBUG_PRINT("info" , ("mroonga partition name=%s" , partition_name)); |
262 | if (table_name && |
263 | memcmp(table_name, partition_name, table_name_length + 1) == 0) |
264 | DBUG_VOID_RETURN; |
265 | if ( |
266 | tmp_flg && |
267 | table_name && |
268 | *(partition_name + table_name_length - 5) == '\0' && |
269 | memcmp(table_name, partition_name, table_name_length - 5) == 0 |
270 | ) { |
271 | tmp_part_elem = *part_elem; |
272 | tmp_flg = FALSE; |
273 | tmp_find_flg = TRUE; |
274 | } |
275 | } |
276 | } |
277 | if (tmp_find_flg) |
278 | { |
279 | *part_elem = tmp_part_elem; |
280 | *sub_elem = tmp_sub_elem; |
281 | DBUG_PRINT("info" , ("mroonga tmp find" )); |
282 | DBUG_VOID_RETURN; |
283 | } |
284 | *part_elem = NULL; |
285 | *sub_elem = NULL; |
286 | DBUG_PRINT("info" , ("mroonga no hit" )); |
287 | DBUG_VOID_RETURN; |
288 | } |
289 | #endif |
290 | |
291 | #define MRN_PARAM_STR_LEN(name) name ## _length |
292 | #define MRN_PARAM_STR(title_name, param_name) \ |
293 | if (!strncasecmp(tmp_ptr, title_name, title_length)) \ |
294 | { \ |
295 | DBUG_PRINT("info", ("mroonga " title_name " start")); \ |
296 | if (!share->param_name) \ |
297 | { \ |
298 | if ((share->param_name = mrn_get_string_between_quote( \ |
299 | start_ptr))) \ |
300 | share->MRN_PARAM_STR_LEN(param_name) = strlen(share->param_name); \ |
301 | else { \ |
302 | error = ER_MRN_INVALID_TABLE_PARAM_NUM; \ |
303 | my_printf_error(error, ER_MRN_INVALID_TABLE_PARAM_STR, \ |
304 | MYF(0), tmp_ptr); \ |
305 | goto error; \ |
306 | } \ |
307 | DBUG_PRINT("info", ("mroonga " title_name "=%s", share->param_name)); \ |
308 | } \ |
309 | break; \ |
310 | } |
311 | |
312 | #define MRN_PARAM_STR_LIST(title_name, param_name, param_pos) \ |
313 | if (!strncasecmp(tmp_ptr, title_name, title_length)) \ |
314 | { \ |
315 | DBUG_PRINT("info", ("mroonga " title_name " start")); \ |
316 | if (share->param_name && !share->param_name[param_pos]) \ |
317 | { \ |
318 | if ((share->param_name[param_pos] = mrn_get_string_between_quote( \ |
319 | start_ptr))) \ |
320 | share->MRN_PARAM_STR_LEN(param_name)[param_pos] = \ |
321 | strlen(share->param_name[param_pos]); \ |
322 | else { \ |
323 | error = ER_MRN_INVALID_TABLE_PARAM_NUM; \ |
324 | my_printf_error(error, ER_MRN_INVALID_TABLE_PARAM_STR, \ |
325 | MYF(0), tmp_ptr); \ |
326 | goto error; \ |
327 | } \ |
328 | DBUG_PRINT("info", ("mroonga " title_name "[%d]=%s", param_pos, \ |
329 | share->param_name[param_pos])); \ |
330 | } \ |
331 | break; \ |
332 | } |
333 | |
334 | int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) |
335 | { |
336 | int i, error = 0; |
337 | int title_length; |
338 | const char *sprit_ptr[2]; |
339 | const char *tmp_ptr, *start_ptr; |
340 | char *params_string = NULL; |
341 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
342 | partition_element *part_elem; |
343 | partition_element *sub_elem; |
344 | #endif |
345 | MRN_DBUG_ENTER_FUNCTION(); |
346 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
347 | mrn_get_partition_info(share->table_name, share->table_name_length, table, |
348 | &part_elem, &sub_elem); |
349 | #endif |
350 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
351 | for (i = 4; i > 0; i--) |
352 | #else |
353 | for (i = 2; i > 0; i--) |
354 | #endif |
355 | { |
356 | const char *params_string_value = NULL; |
357 | uint params_string_length = 0; |
358 | switch (i) |
359 | { |
360 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
361 | case 4: |
362 | if (!sub_elem || !sub_elem->part_comment) |
363 | continue; |
364 | DBUG_PRINT("info" , ("mroonga create sub comment string" )); |
365 | params_string_value = sub_elem->part_comment; |
366 | params_string_length = strlen(params_string_value); |
367 | DBUG_PRINT("info" , |
368 | ("mroonga sub comment string=%s" , params_string_value)); |
369 | break; |
370 | case 3: |
371 | if (!part_elem || !part_elem->part_comment) |
372 | continue; |
373 | DBUG_PRINT("info" , ("mroonga create part comment string" )); |
374 | params_string_value = part_elem->part_comment; |
375 | params_string_length = strlen(params_string_value); |
376 | DBUG_PRINT("info" , |
377 | ("mroonga part comment string=%s" , params_string_value)); |
378 | break; |
379 | #endif |
380 | case 2: |
381 | if (LEX_STRING_IS_EMPTY(table->s->comment)) |
382 | continue; |
383 | DBUG_PRINT("info" , ("mroonga create comment string" )); |
384 | params_string_value = table->s->comment.str; |
385 | params_string_length = table->s->comment.length; |
386 | DBUG_PRINT("info" , |
387 | ("mroonga comment string=%.*s" , |
388 | params_string_length, params_string_value)); |
389 | break; |
390 | default: |
391 | if (LEX_STRING_IS_EMPTY(table->s->connect_string)) |
392 | continue; |
393 | DBUG_PRINT("info" , ("mroonga create connect_string string" )); |
394 | params_string_value = table->s->connect_string.str; |
395 | params_string_length = table->s->connect_string.length; |
396 | DBUG_PRINT("info" , |
397 | ("mroonga connect_string=%.*s" , |
398 | params_string_length, params_string_value)); |
399 | break; |
400 | } |
401 | |
402 | if (!params_string_value) { |
403 | continue; |
404 | } |
405 | |
406 | { |
407 | params_string = mrn_my_strndup(params_string_value, |
408 | params_string_length, |
409 | MYF(MY_WME)); |
410 | if (!params_string) { |
411 | error = HA_ERR_OUT_OF_MEM; |
412 | goto error; |
413 | } |
414 | |
415 | sprit_ptr[0] = params_string; |
416 | while (sprit_ptr[0]) |
417 | { |
418 | if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) |
419 | { |
420 | sprit_ptr[1]++; |
421 | } |
422 | tmp_ptr = sprit_ptr[0]; |
423 | sprit_ptr[0] = sprit_ptr[1]; |
424 | while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || |
425 | *tmp_ptr == '\n' || *tmp_ptr == '\t') |
426 | tmp_ptr++; |
427 | |
428 | if (*tmp_ptr == '\0') |
429 | continue; |
430 | |
431 | DBUG_PRINT("info" , ("mroonga title_str=%s" , tmp_ptr)); |
432 | title_length = 0; |
433 | start_ptr = tmp_ptr; |
434 | while (*start_ptr != ' ' && *start_ptr != '\'' && |
435 | *start_ptr != '"' && *start_ptr != '\0' && |
436 | *start_ptr != '\r' && *start_ptr != '\n' && |
437 | *start_ptr != '\t' && *start_ptr != ',') |
438 | { |
439 | title_length++; |
440 | start_ptr++; |
441 | } |
442 | DBUG_PRINT("info" , ("mroonga title_length=%u" , title_length)); |
443 | |
444 | switch (title_length) |
445 | { |
446 | case 6: |
447 | MRN_PARAM_STR("engine" , engine); |
448 | break; |
449 | case 10: |
450 | MRN_PARAM_STR("normalizer" , normalizer); |
451 | break; |
452 | case 13: |
453 | MRN_PARAM_STR("token_filters" , token_filters); |
454 | break; |
455 | case 17: |
456 | MRN_PARAM_STR("default_tokenizer" , default_tokenizer); |
457 | break; |
458 | default: |
459 | break; |
460 | } |
461 | } |
462 | |
463 | my_free(params_string); |
464 | params_string = NULL; |
465 | } |
466 | } |
467 | |
468 | if (!share->engine && mrn_default_wrapper_engine) |
469 | { |
470 | share->engine_length = strlen(mrn_default_wrapper_engine); |
471 | if ( |
472 | !(share->engine = mrn_my_strndup(mrn_default_wrapper_engine, |
473 | share->engine_length, |
474 | MYF(MY_WME))) |
475 | ) { |
476 | error = HA_ERR_OUT_OF_MEM; |
477 | goto error; |
478 | } |
479 | } |
480 | |
481 | if (share->engine) |
482 | { |
483 | LEX_CSTRING engine_name; |
484 | if ( |
485 | ( |
486 | share->engine_length == MRN_DEFAULT_LEN && |
487 | !strncasecmp(share->engine, MRN_DEFAULT_STR, MRN_DEFAULT_LEN) |
488 | ) || |
489 | ( |
490 | share->engine_length == MRN_GROONGA_LEN && |
491 | !strncasecmp(share->engine, MRN_GROONGA_STR, MRN_GROONGA_LEN) |
492 | ) |
493 | ) { |
494 | my_free(share->engine); |
495 | share->engine = NULL; |
496 | share->engine_length = 0; |
497 | } else { |
498 | engine_name.str = share->engine; |
499 | engine_name.length = share->engine_length; |
500 | if (!(share->plugin = MRN_HA_RESOLVE_BY_NAME(&engine_name))) |
501 | { |
502 | my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), share->engine); |
503 | error = ER_UNKNOWN_STORAGE_ENGINE; |
504 | goto error; |
505 | } |
506 | share->hton = MRN_PLUGIN_DATA(share->plugin, handlerton *); |
507 | share->wrapper_mode = TRUE; |
508 | } |
509 | } |
510 | |
511 | error: |
512 | if (params_string) |
513 | my_free(params_string); |
514 | DBUG_RETURN(error); |
515 | } |
516 | |
517 | bool mrn_is_geo_key(const KEY *key_info) |
518 | { |
519 | return key_info->algorithm == HA_KEY_ALG_UNDEF && |
520 | KEY_N_KEY_PARTS(key_info) == 1 && |
521 | key_info->key_part[0].field->type() == MYSQL_TYPE_GEOMETRY; |
522 | } |
523 | |
524 | int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) |
525 | { |
526 | int error; |
527 | char *param_string = NULL; |
528 | #if MYSQL_VERSION_ID >= 50500 |
529 | int title_length; |
530 | char *sprit_ptr[2]; |
531 | char *tmp_ptr, *start_ptr; |
532 | #endif |
533 | THD *thd = current_thd; |
534 | MRN_DBUG_ENTER_FUNCTION(); |
535 | |
536 | #if MYSQL_VERSION_ID >= 50500 |
537 | if (key_info->comment.length == 0) |
538 | { |
539 | if (share->key_tokenizer[i]) { |
540 | my_free(share->key_tokenizer[i]); |
541 | } |
542 | share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); |
543 | if (!share->key_tokenizer[i]) { |
544 | error = HA_ERR_OUT_OF_MEM; |
545 | goto error; |
546 | } |
547 | share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); |
548 | |
549 | DBUG_RETURN(0); |
550 | } |
551 | DBUG_PRINT("info" , ("mroonga create comment string" )); |
552 | if ( |
553 | !(param_string = mrn_my_strndup(key_info->comment.str, |
554 | key_info->comment.length, |
555 | MYF(MY_WME))) |
556 | ) { |
557 | error = HA_ERR_OUT_OF_MEM; |
558 | goto error_alloc_param_string; |
559 | } |
560 | DBUG_PRINT("info" , ("mroonga comment string=%s" , param_string)); |
561 | |
562 | sprit_ptr[0] = param_string; |
563 | while (sprit_ptr[0]) |
564 | { |
565 | if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) |
566 | { |
567 | *sprit_ptr[1] = '\0'; |
568 | sprit_ptr[1]++; |
569 | } |
570 | tmp_ptr = sprit_ptr[0]; |
571 | sprit_ptr[0] = sprit_ptr[1]; |
572 | while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || |
573 | *tmp_ptr == '\n' || *tmp_ptr == '\t') |
574 | tmp_ptr++; |
575 | |
576 | if (*tmp_ptr == '\0') |
577 | continue; |
578 | |
579 | title_length = 0; |
580 | start_ptr = tmp_ptr; |
581 | while (*start_ptr != ' ' && *start_ptr != '\'' && |
582 | *start_ptr != '"' && *start_ptr != '\0' && |
583 | *start_ptr != '\r' && *start_ptr != '\n' && |
584 | *start_ptr != '\t') |
585 | { |
586 | title_length++; |
587 | start_ptr++; |
588 | } |
589 | |
590 | switch (title_length) |
591 | { |
592 | case 5: |
593 | MRN_PARAM_STR_LIST("table" , index_table, i); |
594 | break; |
595 | case 6: |
596 | push_warning_printf(thd, MRN_SEVERITY_WARNING, |
597 | ER_WARN_DEPRECATED_SYNTAX, |
598 | ER(ER_WARN_DEPRECATED_SYNTAX), |
599 | "parser" , "tokenizer" ); |
600 | MRN_PARAM_STR_LIST("parser" , key_tokenizer, i); |
601 | break; |
602 | case 9: |
603 | MRN_PARAM_STR_LIST("tokenizer" , key_tokenizer, i); |
604 | break; |
605 | default: |
606 | break; |
607 | } |
608 | } |
609 | #endif |
610 | if (!share->key_tokenizer[i]) { |
611 | share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); |
612 | if (!share->key_tokenizer[i]) { |
613 | error = HA_ERR_OUT_OF_MEM; |
614 | goto error; |
615 | } |
616 | share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); |
617 | } |
618 | |
619 | if (param_string) |
620 | my_free(param_string); |
621 | DBUG_RETURN(0); |
622 | |
623 | error: |
624 | if (param_string) |
625 | my_free(param_string); |
626 | #if MYSQL_VERSION_ID >= 50500 |
627 | error_alloc_param_string: |
628 | #endif |
629 | DBUG_RETURN(error); |
630 | } |
631 | |
632 | int mrn_parse_index_param(MRN_SHARE *share, TABLE *table) |
633 | { |
634 | int error; |
635 | MRN_DBUG_ENTER_FUNCTION(); |
636 | for (uint i = 0; i < table->s->keys; i++) |
637 | { |
638 | KEY *key_info = &table->s->key_info[i]; |
639 | bool is_wrapper_mode = share->engine != NULL; |
640 | |
641 | if (is_wrapper_mode) { |
642 | if (!(key_info->flags & HA_FULLTEXT) && !mrn_is_geo_key(key_info)) { |
643 | continue; |
644 | } |
645 | } |
646 | |
647 | if ((error = mrn_add_index_param(share, key_info, i))) |
648 | goto error; |
649 | } |
650 | DBUG_RETURN(0); |
651 | |
652 | error: |
653 | DBUG_RETURN(error); |
654 | } |
655 | |
656 | int mrn_add_column_param(MRN_SHARE *share, Field *field, int i) |
657 | { |
658 | int error; |
659 | char *param_string = NULL; |
660 | int title_length; |
661 | char *sprit_ptr[2]; |
662 | char *tmp_ptr, *start_ptr; |
663 | |
664 | MRN_DBUG_ENTER_FUNCTION(); |
665 | |
666 | if (share->wrapper_mode) { |
667 | DBUG_RETURN(0); |
668 | } |
669 | |
670 | DBUG_PRINT("info" , ("mroonga create comment string" )); |
671 | if ( |
672 | !(param_string = mrn_my_strndup(field->comment.str, |
673 | field->comment.length, |
674 | MYF(MY_WME))) |
675 | ) { |
676 | error = HA_ERR_OUT_OF_MEM; |
677 | goto error_alloc_param_string; |
678 | } |
679 | DBUG_PRINT("info" , ("mroonga comment string=%s" , param_string)); |
680 | |
681 | sprit_ptr[0] = param_string; |
682 | while (sprit_ptr[0]) |
683 | { |
684 | if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) |
685 | { |
686 | *sprit_ptr[1] = '\0'; |
687 | sprit_ptr[1]++; |
688 | } |
689 | tmp_ptr = sprit_ptr[0]; |
690 | sprit_ptr[0] = sprit_ptr[1]; |
691 | while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || |
692 | *tmp_ptr == '\n' || *tmp_ptr == '\t') |
693 | tmp_ptr++; |
694 | |
695 | if (*tmp_ptr == '\0') |
696 | continue; |
697 | |
698 | title_length = 0; |
699 | start_ptr = tmp_ptr; |
700 | while (*start_ptr != ' ' && *start_ptr != '\'' && |
701 | *start_ptr != '"' && *start_ptr != '\0' && |
702 | *start_ptr != '\r' && *start_ptr != '\n' && |
703 | *start_ptr != '\t') |
704 | { |
705 | title_length++; |
706 | start_ptr++; |
707 | } |
708 | |
709 | switch (title_length) |
710 | { |
711 | case 4: |
712 | MRN_PARAM_STR_LIST("type" , col_type, i); |
713 | break; |
714 | case 5: |
715 | MRN_PARAM_STR_LIST("flags" , col_flags, i); |
716 | break; |
717 | case 12: |
718 | MRN_PARAM_STR_LIST("groonga_type" , col_type, i); |
719 | break; |
720 | default: |
721 | break; |
722 | } |
723 | } |
724 | |
725 | if (param_string) |
726 | my_free(param_string); |
727 | DBUG_RETURN(0); |
728 | |
729 | error: |
730 | if (param_string) |
731 | my_free(param_string); |
732 | error_alloc_param_string: |
733 | DBUG_RETURN(error); |
734 | } |
735 | |
736 | int mrn_parse_column_param(MRN_SHARE *share, TABLE *table) |
737 | { |
738 | int error; |
739 | MRN_DBUG_ENTER_FUNCTION(); |
740 | for (uint i = 0; i < table->s->fields; i++) |
741 | { |
742 | Field *field = table->s->field[i]; |
743 | |
744 | if (LEX_STRING_IS_EMPTY(field->comment)) { |
745 | continue; |
746 | } |
747 | |
748 | if ((error = mrn_add_column_param(share, field, i))) |
749 | goto error; |
750 | } |
751 | DBUG_RETURN(0); |
752 | |
753 | error: |
754 | DBUG_RETURN(error); |
755 | } |
756 | |
757 | int mrn_free_share_alloc( |
758 | MRN_SHARE *share |
759 | ) { |
760 | uint i; |
761 | MRN_DBUG_ENTER_FUNCTION(); |
762 | if (share->engine) |
763 | my_free(share->engine); |
764 | if (share->default_tokenizer) |
765 | my_free(share->default_tokenizer); |
766 | if (share->normalizer) |
767 | my_free(share->normalizer); |
768 | if (share->token_filters) |
769 | my_free(share->token_filters); |
770 | for (i = 0; i < share->table_share->keys; i++) |
771 | { |
772 | if (share->index_table && share->index_table[i]) |
773 | my_free(share->index_table[i]); |
774 | if (share->key_tokenizer[i]) |
775 | my_free(share->key_tokenizer[i]); |
776 | } |
777 | for (i = 0; i < share->table_share->fields; i++) |
778 | { |
779 | if (share->col_flags && share->col_flags[i]) |
780 | my_free(share->col_flags[i]); |
781 | if (share->col_type && share->col_type[i]) |
782 | my_free(share->col_type[i]); |
783 | } |
784 | DBUG_RETURN(0); |
785 | } |
786 | |
787 | void mrn_free_long_term_share(MRN_LONG_TERM_SHARE *long_term_share) |
788 | { |
789 | MRN_DBUG_ENTER_FUNCTION(); |
790 | { |
791 | mrn::Lock lock(&mrn_long_term_share_mutex); |
792 | my_hash_delete(&mrn_long_term_share, (uchar*) long_term_share); |
793 | } |
794 | mysql_mutex_destroy(&long_term_share->auto_inc_mutex); |
795 | my_free(long_term_share); |
796 | DBUG_VOID_RETURN; |
797 | } |
798 | |
799 | MRN_LONG_TERM_SHARE *mrn_get_long_term_share(const char *table_name, |
800 | uint table_name_length, |
801 | int *error) |
802 | { |
803 | MRN_LONG_TERM_SHARE *long_term_share; |
804 | char *tmp_name; |
805 | MRN_DBUG_ENTER_FUNCTION(); |
806 | DBUG_PRINT("info" , ("mroonga: table_name=%s" , table_name)); |
807 | mrn::Lock lock(&mrn_long_term_share_mutex); |
808 | if (!(long_term_share = (MRN_LONG_TERM_SHARE*) |
809 | my_hash_search(&mrn_long_term_share, (uchar*) table_name, |
810 | table_name_length))) |
811 | { |
812 | if (!(long_term_share = (MRN_LONG_TERM_SHARE *) |
813 | mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), |
814 | &long_term_share, sizeof(*long_term_share), |
815 | &tmp_name, table_name_length + 1, |
816 | NullS)) |
817 | ) { |
818 | *error = HA_ERR_OUT_OF_MEM; |
819 | goto error_alloc_long_term_share; |
820 | } |
821 | long_term_share->table_name = tmp_name; |
822 | long_term_share->table_name_length = table_name_length; |
823 | memcpy(long_term_share->table_name, table_name, table_name_length); |
824 | if (mysql_mutex_init(mrn_long_term_share_auto_inc_mutex_key, |
825 | &long_term_share->auto_inc_mutex, |
826 | MY_MUTEX_INIT_FAST) != 0) |
827 | { |
828 | *error = HA_ERR_OUT_OF_MEM; |
829 | goto error_init_auto_inc_mutex; |
830 | } |
831 | if (my_hash_insert(&mrn_long_term_share, (uchar*) long_term_share)) |
832 | { |
833 | *error = HA_ERR_OUT_OF_MEM; |
834 | goto error_hash_insert; |
835 | } |
836 | } |
837 | DBUG_RETURN(long_term_share); |
838 | |
839 | error_hash_insert: |
840 | mysql_mutex_destroy(&long_term_share->auto_inc_mutex); |
841 | error_init_auto_inc_mutex: |
842 | my_free(long_term_share); |
843 | error_alloc_long_term_share: |
844 | DBUG_RETURN(NULL); |
845 | } |
846 | |
847 | MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) |
848 | { |
849 | MRN_SHARE *share; |
850 | char *tmp_name, **index_table, **key_tokenizer, **col_flags, **col_type; |
851 | uint length, *wrap_key_nr, *index_table_length; |
852 | uint *key_tokenizer_length, *col_flags_length, *col_type_length, i, j; |
853 | KEY *wrap_key_info; |
854 | TABLE_SHARE *wrap_table_share; |
855 | MRN_DBUG_ENTER_FUNCTION(); |
856 | length = (uint) strlen(table_name); |
857 | mrn::Lock lock(&mrn_open_tables_mutex); |
858 | if (!(share = (MRN_SHARE*) my_hash_search(&mrn_open_tables, |
859 | (uchar*) table_name, length))) |
860 | { |
861 | if (!(share = (MRN_SHARE *) |
862 | mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), |
863 | &share, sizeof(*share), |
864 | &tmp_name, length + 1, |
865 | &index_table, sizeof(char *) * table->s->keys, |
866 | &index_table_length, sizeof(uint) * table->s->keys, |
867 | &key_tokenizer, sizeof(char *) * table->s->keys, |
868 | &key_tokenizer_length, sizeof(uint) * table->s->keys, |
869 | &col_flags, sizeof(char *) * table->s->fields, |
870 | &col_flags_length, sizeof(uint) * table->s->fields, |
871 | &col_type, sizeof(char *) * table->s->fields, |
872 | &col_type_length, sizeof(uint) * table->s->fields, |
873 | &wrap_key_nr, sizeof(*wrap_key_nr) * table->s->keys, |
874 | &wrap_key_info, sizeof(*wrap_key_info) * table->s->keys, |
875 | &wrap_table_share, sizeof(*wrap_table_share), |
876 | NullS)) |
877 | ) { |
878 | *error = HA_ERR_OUT_OF_MEM; |
879 | goto error_alloc_share; |
880 | } |
881 | share->use_count = 0; |
882 | share->table_name_length = length; |
883 | share->table_name = tmp_name; |
884 | share->index_table = index_table; |
885 | share->index_table_length = index_table_length; |
886 | share->key_tokenizer = key_tokenizer; |
887 | share->key_tokenizer_length = key_tokenizer_length; |
888 | share->col_flags = col_flags; |
889 | share->col_flags_length = col_flags_length; |
890 | share->col_type = col_type; |
891 | share->col_type_length = col_type_length; |
892 | mrn_my_stpmov(share->table_name, table_name); |
893 | share->table_share = table->s; |
894 | |
895 | if ( |
896 | (*error = mrn_parse_table_param(share, table)) || |
897 | (*error = mrn_parse_column_param(share, table)) || |
898 | (*error = mrn_parse_index_param(share, table)) |
899 | ) |
900 | goto error_parse_table_param; |
901 | |
902 | if (share->wrapper_mode) |
903 | { |
904 | j = 0; |
905 | for (i = 0; i < table->s->keys; i++) |
906 | { |
907 | if (table->s->key_info[i].algorithm != HA_KEY_ALG_FULLTEXT && |
908 | !mrn_is_geo_key(&table->s->key_info[i])) |
909 | { |
910 | wrap_key_nr[i] = j; |
911 | memcpy(&wrap_key_info[j], &table->s->key_info[i], |
912 | sizeof(*wrap_key_info)); |
913 | j++; |
914 | } else { |
915 | wrap_key_nr[i] = MAX_KEY; |
916 | } |
917 | } |
918 | share->wrap_keys = j; |
919 | share->base_keys = table->s->keys; |
920 | share->base_key_info = table->s->key_info; |
921 | share->base_primary_key = table->s->primary_key; |
922 | if (i) |
923 | { |
924 | share->wrap_key_nr = wrap_key_nr; |
925 | share->wrap_key_info = wrap_key_info; |
926 | if (table->s->primary_key == MAX_KEY) |
927 | share->wrap_primary_key = MAX_KEY; |
928 | else |
929 | share->wrap_primary_key = wrap_key_nr[table->s->primary_key]; |
930 | } else { |
931 | share->wrap_key_nr = NULL; |
932 | share->wrap_key_info = NULL; |
933 | share->wrap_primary_key = MAX_KEY; |
934 | } |
935 | memcpy(wrap_table_share, table->s, sizeof(*wrap_table_share)); |
936 | mrn_init_sql_alloc(current_thd, &(wrap_table_share->mem_root)); |
937 | wrap_table_share->keys = share->wrap_keys; |
938 | wrap_table_share->key_info = share->wrap_key_info; |
939 | wrap_table_share->primary_key = share->wrap_primary_key; |
940 | wrap_table_share->keys_in_use.init(share->wrap_keys); |
941 | wrap_table_share->keys_for_keyread.init(share->wrap_keys); |
942 | #ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE |
943 | # ifdef WIN32 |
944 | mysql_mutex_init(*mrn_table_share_lock_share, |
945 | &(wrap_table_share->LOCK_share), MY_MUTEX_INIT_SLOW); |
946 | # else |
947 | mysql_mutex_init(key_TABLE_SHARE_LOCK_share, |
948 | &(wrap_table_share->LOCK_share), MY_MUTEX_INIT_SLOW); |
949 | # endif |
950 | #endif |
951 | #ifdef WIN32 |
952 | mysql_mutex_init(*mrn_table_share_lock_ha_data, |
953 | &(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST); |
954 | #else |
955 | mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data, |
956 | &(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST); |
957 | #endif |
958 | share->wrap_table_share = wrap_table_share; |
959 | } |
960 | |
961 | if (mysql_mutex_init(mrn_share_mutex_key, |
962 | &share->record_mutex, |
963 | MY_MUTEX_INIT_FAST) != 0) |
964 | { |
965 | *error = HA_ERR_OUT_OF_MEM; |
966 | goto error_init_mutex; |
967 | } |
968 | thr_lock_init(&share->lock); |
969 | if (!(share->long_term_share = mrn_get_long_term_share(table_name, length, |
970 | error))) |
971 | { |
972 | goto error_get_long_term_share; |
973 | } |
974 | if (my_hash_insert(&mrn_open_tables, (uchar*) share)) |
975 | { |
976 | *error = HA_ERR_OUT_OF_MEM; |
977 | goto error_hash_insert; |
978 | } |
979 | } |
980 | share->use_count++; |
981 | DBUG_RETURN(share); |
982 | |
983 | error_hash_insert: |
984 | error_get_long_term_share: |
985 | mysql_mutex_destroy(&share->record_mutex); |
986 | error_init_mutex: |
987 | error_parse_table_param: |
988 | mrn_free_share_alloc(share); |
989 | my_free(share); |
990 | error_alloc_share: |
991 | DBUG_RETURN(NULL); |
992 | } |
993 | |
994 | int mrn_free_share(MRN_SHARE *share) |
995 | { |
996 | MRN_DBUG_ENTER_FUNCTION(); |
997 | mrn::Lock lock(&mrn_open_tables_mutex); |
998 | if (!--share->use_count) |
999 | { |
1000 | my_hash_delete(&mrn_open_tables, (uchar*) share); |
1001 | if (share->wrapper_mode) |
1002 | plugin_unlock(NULL, share->plugin); |
1003 | mrn_free_share_alloc(share); |
1004 | thr_lock_delete(&share->lock); |
1005 | mysql_mutex_destroy(&share->record_mutex); |
1006 | if (share->wrapper_mode) { |
1007 | #ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE |
1008 | mysql_mutex_destroy(&(share->wrap_table_share->LOCK_share)); |
1009 | #endif |
1010 | mysql_mutex_destroy(&(share->wrap_table_share->LOCK_ha_data)); |
1011 | free_root(&(share->wrap_table_share->mem_root), MYF(0)); |
1012 | } |
1013 | my_free(share); |
1014 | } |
1015 | DBUG_RETURN(0); |
1016 | } |
1017 | |
1018 | TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error) |
1019 | { |
1020 | TABLE_SHARE *share; |
1021 | THD *thd = current_thd; |
1022 | MRN_DBUG_ENTER_FUNCTION(); |
1023 | #if defined(MRN_HAVE_TDC_ACQUIRE_SHARE) && \ |
1024 | !defined(MRN_TDC_ACQUIRE_SHARE_REQUIRE_KEY) |
1025 | share = tdc_acquire_share(thd, table_list, GTS_TABLE); |
1026 | #else |
1027 | uint key_length; |
1028 | # ifdef MRN_HAVE_GET_TABLE_DEF_KEY |
1029 | const char *key; |
1030 | key_length = get_table_def_key(table_list, &key); |
1031 | # else |
1032 | char key[MAX_DBKEY_LENGTH]; |
1033 | key_length = create_table_def_key(thd, key, table_list, FALSE); |
1034 | # endif |
1035 | # ifdef MRN_HAVE_TABLE_DEF_CACHE |
1036 | my_hash_value_type hash_value; |
1037 | hash_value = my_calc_hash(mrn_table_def_cache, (uchar*) key, key_length); |
1038 | share = get_table_share(thd, table_list, key, key_length, 0, error, |
1039 | hash_value); |
1040 | # elif defined(MRN_HAVE_TDC_ACQUIRE_SHARE) |
1041 | share = tdc_acquire_share(thd, table_list, GTS_TABLE); |
1042 | # else |
1043 | share = get_table_share(thd, table_list, key, key_length, 0, error); |
1044 | # endif |
1045 | #endif |
1046 | DBUG_RETURN(share); |
1047 | } |
1048 | |
1049 | TABLE_SHARE *mrn_create_tmp_table_share(TABLE_LIST *table_list, const char *path, |
1050 | int *error) |
1051 | { |
1052 | uint key_length; |
1053 | TABLE_SHARE *share; |
1054 | THD *thd = current_thd; |
1055 | |
1056 | MRN_DBUG_ENTER_FUNCTION(); |
1057 | #ifdef MRN_HAVE_GET_TABLE_DEF_KEY |
1058 | const char *key; |
1059 | key_length = get_table_def_key(table_list, &key); |
1060 | #else |
1061 | char key[MAX_DBKEY_LENGTH]; |
1062 | key_length = create_table_def_key(thd, key, table_list, FALSE); |
1063 | #endif |
1064 | #if MYSQL_VERSION_ID >= 100002 && defined(MRN_MARIADB_P) |
1065 | share = alloc_table_share(table_list->db.str, table_list->table_name.str, key, |
1066 | key_length); |
1067 | #else |
1068 | share = alloc_table_share(table_list, key, key_length); |
1069 | #endif |
1070 | if (!share) |
1071 | { |
1072 | *error = ER_CANT_OPEN_FILE; |
1073 | DBUG_RETURN(NULL); |
1074 | } |
1075 | share->tmp_table = NO_TMP_TABLE; // TODO: is this right? |
1076 | share->path.str = (char *) path; |
1077 | share->path.length = strlen(share->path.str); |
1078 | share->normalized_path.str = mrn_my_strdup(path, MYF(MY_WME)); |
1079 | share->normalized_path.length = strlen(share->normalized_path.str); |
1080 | if (open_table_def(thd, share, GTS_TABLE)) |
1081 | { |
1082 | *error = ER_CANT_OPEN_FILE; |
1083 | DBUG_RETURN(NULL); |
1084 | } |
1085 | DBUG_RETURN(share); |
1086 | } |
1087 | |
1088 | void mrn_free_tmp_table_share(TABLE_SHARE *tmp_table_share) |
1089 | { |
1090 | MRN_DBUG_ENTER_FUNCTION(); |
1091 | const char *normalized_path = tmp_table_share->normalized_path.str; |
1092 | free_table_share(tmp_table_share); |
1093 | my_free((char*) normalized_path); |
1094 | DBUG_VOID_RETURN; |
1095 | } |
1096 | |
1097 | KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error) |
1098 | { |
1099 | uint *wrap_key_nr = share->wrap_key_nr, i, j; |
1100 | KEY *wrap_key_info; |
1101 | MRN_DBUG_ENTER_FUNCTION(); |
1102 | if (share->wrap_keys) |
1103 | { |
1104 | if (!(wrap_key_info = (KEY *) |
1105 | mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), |
1106 | &wrap_key_info, sizeof(*wrap_key_info) * share->wrap_keys, |
1107 | NullS)) |
1108 | ) { |
1109 | *error = HA_ERR_OUT_OF_MEM; |
1110 | DBUG_RETURN(NULL); |
1111 | } |
1112 | for (i = 0; i < table->s->keys; i++) |
1113 | { |
1114 | j = wrap_key_nr[i]; |
1115 | if (j < MAX_KEY) |
1116 | { |
1117 | memcpy(&wrap_key_info[j], &table->key_info[i], |
1118 | sizeof(*wrap_key_info)); |
1119 | } |
1120 | } |
1121 | } else |
1122 | wrap_key_info = NULL; |
1123 | *error = 0; |
1124 | DBUG_RETURN(wrap_key_info); |
1125 | } |
1126 | |
1127 | void mrn_set_bitmap_by_key(MY_BITMAP *map, KEY *key_info) |
1128 | { |
1129 | uint i; |
1130 | MRN_DBUG_ENTER_FUNCTION(); |
1131 | for (i = 0; i < KEY_N_KEY_PARTS(key_info); i++) |
1132 | { |
1133 | Field *field = key_info->key_part[i].field; |
1134 | bitmap_set_bit(map, field->field_index); |
1135 | } |
1136 | DBUG_VOID_RETURN; |
1137 | } |
1138 | |
1139 | st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create) |
1140 | { |
1141 | MRN_DBUG_ENTER_FUNCTION(); |
1142 | st_mrn_slot_data *slot_data = |
1143 | (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr); |
1144 | if (slot_data == NULL) { |
1145 | slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data)); |
1146 | slot_data->last_insert_record_id = GRN_ID_NIL; |
1147 | slot_data->first_wrap_hton = NULL; |
1148 | slot_data->alter_create_info = NULL; |
1149 | slot_data->disable_keys_create_info = NULL; |
1150 | slot_data->alter_connect_string = NULL; |
1151 | slot_data->alter_comment = NULL; |
1152 | *thd_ha_data(thd, mrn_hton_ptr) = (void *) slot_data; |
1153 | { |
1154 | mrn::Lock lock(&mrn_allocated_thds_mutex); |
1155 | if (my_hash_insert(&mrn_allocated_thds, (uchar*) thd)) |
1156 | { |
1157 | free(slot_data); |
1158 | DBUG_RETURN(NULL); |
1159 | } |
1160 | } |
1161 | } |
1162 | DBUG_RETURN(slot_data); |
1163 | } |
1164 | |
1165 | void mrn_clear_slot_data(THD *thd) |
1166 | { |
1167 | MRN_DBUG_ENTER_FUNCTION(); |
1168 | st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE); |
1169 | if (slot_data) { |
1170 | if (slot_data->first_wrap_hton) { |
1171 | st_mrn_wrap_hton *tmp_wrap_hton; |
1172 | st_mrn_wrap_hton *wrap_hton = slot_data->first_wrap_hton; |
1173 | while (wrap_hton) |
1174 | { |
1175 | tmp_wrap_hton = wrap_hton->next; |
1176 | free(wrap_hton); |
1177 | wrap_hton = tmp_wrap_hton; |
1178 | } |
1179 | slot_data->first_wrap_hton = NULL; |
1180 | } |
1181 | slot_data->alter_create_info = NULL; |
1182 | slot_data->disable_keys_create_info = NULL; |
1183 | if (slot_data->alter_connect_string) { |
1184 | my_free(slot_data->alter_connect_string); |
1185 | slot_data->alter_connect_string = NULL; |
1186 | } |
1187 | if (slot_data->alter_comment) { |
1188 | my_free(slot_data->alter_comment); |
1189 | slot_data->alter_comment = NULL; |
1190 | } |
1191 | } |
1192 | DBUG_VOID_RETURN; |
1193 | } |
1194 | |
1195 | #ifdef __cplusplus |
1196 | } |
1197 | #endif |
1198 | |