1 /* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
2 Copyright (c) 2008, 2021, MariaDB
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
16
17
18 /* Some general useful functions */
19
20 #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
21 #include "sql_priv.h"
22 #include "table.h"
23 #include "key.h" // find_ref_key
24 #include "sql_table.h" // build_table_filename,
25 // primary_key_name
26 #include "sql_parse.h" // free_items
27 #include "strfunc.h" // unhex_type2
28 #include "sql_partition.h" // mysql_unpack_partition,
29 // fix_partition_func, partition_info
30 #include "sql_acl.h" // *_ACL, acl_getroot_no_password
31 #include "sql_base.h"
32 #include "create_options.h"
33 #include "sql_trigger.h"
34 #include <m_ctype.h>
35 #include "my_md5.h"
36 #include "my_bit.h"
37 #include "sql_select.h"
38 #include "sql_derived.h"
39 #include "sql_statistics.h"
40 #include "discover.h"
41 #include "mdl.h" // MDL_wait_for_graph_visitor
42 #include "sql_view.h"
43 #include "rpl_filter.h"
44 #include "sql_cte.h"
45 #include "ha_sequence.h"
46 #include "sql_show.h"
47 #include "opt_trace.h"
48
49 /* For MySQL 5.7 virtual fields */
50 #define MYSQL57_GENERATED_FIELD 128
51 #define MYSQL57_GCOL_HEADER_SIZE 4
52
53 class Table_arena: public Query_arena
54 {
55 public:
Table_arena(MEM_ROOT * mem_root,enum enum_state state_arg)56 Table_arena(MEM_ROOT *mem_root, enum enum_state state_arg) :
57 Query_arena(mem_root, state_arg){}
type() const58 virtual Type type() const
59 {
60 return TABLE_ARENA;
61 }
62 };
63
64 struct extra2_fields
65 {
66 LEX_CUSTRING version;
67 LEX_CUSTRING options;
68 Lex_ident engine;
69 LEX_CUSTRING gis;
70 LEX_CUSTRING field_flags;
71 LEX_CUSTRING system_period;
72 LEX_CUSTRING application_period;
resetextra2_fields73 void reset()
74 { bzero((void*)this, sizeof(*this)); }
75 };
76
77 static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *,
78 TABLE *, String *, Virtual_column_info **, bool *);
79 static bool check_vcol_forward_refs(Field *, Virtual_column_info *,
80 bool check_constraint);
81
82 /* INFORMATION_SCHEMA name */
83 LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")};
84
85 /* PERFORMANCE_SCHEMA name */
86 LEX_CSTRING PERFORMANCE_SCHEMA_DB_NAME= {STRING_WITH_LEN("performance_schema")};
87
88 /* MYSQL_SCHEMA name */
89 LEX_CSTRING MYSQL_SCHEMA_NAME= {STRING_WITH_LEN("mysql")};
90
91 /* GENERAL_LOG name */
92 LEX_CSTRING GENERAL_LOG_NAME= {STRING_WITH_LEN("general_log")};
93
94 /* SLOW_LOG name */
95 LEX_CSTRING SLOW_LOG_NAME= {STRING_WITH_LEN("slow_log")};
96
97 LEX_CSTRING TRANSACTION_REG_NAME= {STRING_WITH_LEN("transaction_registry")};
98 LEX_CSTRING MYSQL_PROC_NAME= {STRING_WITH_LEN("proc")};
99
100 /*
101 Keyword added as a prefix when parsing the defining expression for a
102 virtual column read from the column definition saved in the frm file
103 */
104 static LEX_CSTRING parse_vcol_keyword= { STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
105
106 static std::atomic<ulong> last_table_id;
107
108 /* Functions defined in this file */
109
110 static bool fix_type_pointers(const char ***typelib_value_names,
111 uint **typelib_value_lengths,
112 TYPELIB *point_to_type, uint types,
113 char *names, size_t names_length);
114
115 static uint find_field(Field **fields, uchar *record, uint start, uint length);
116
117 inline bool is_system_table_name(const char *name, size_t length);
118
119 /**************************************************************************
120 Object_creation_ctx implementation.
121 **************************************************************************/
122
set_n_backup(THD * thd)123 Object_creation_ctx *Object_creation_ctx::set_n_backup(THD *thd)
124 {
125 Object_creation_ctx *backup_ctx;
126 DBUG_ENTER("Object_creation_ctx::set_n_backup");
127
128 backup_ctx= create_backup_ctx(thd);
129 change_env(thd);
130
131 DBUG_RETURN(backup_ctx);
132 }
133
restore_env(THD * thd,Object_creation_ctx * backup_ctx)134 void Object_creation_ctx::restore_env(THD *thd, Object_creation_ctx *backup_ctx)
135 {
136 if (!backup_ctx)
137 return;
138
139 backup_ctx->change_env(thd);
140
141 delete backup_ctx;
142 }
143
144 /**************************************************************************
145 Default_object_creation_ctx implementation.
146 **************************************************************************/
147
Default_object_creation_ctx(THD * thd)148 Default_object_creation_ctx::Default_object_creation_ctx(THD *thd)
149 : m_client_cs(thd->variables.character_set_client),
150 m_connection_cl(thd->variables.collation_connection)
151 { }
152
Default_object_creation_ctx(CHARSET_INFO * client_cs,CHARSET_INFO * connection_cl)153 Default_object_creation_ctx::Default_object_creation_ctx(
154 CHARSET_INFO *client_cs, CHARSET_INFO *connection_cl)
155 : m_client_cs(client_cs),
156 m_connection_cl(connection_cl)
157 { }
158
159 Object_creation_ctx *
create_backup_ctx(THD * thd) const160 Default_object_creation_ctx::create_backup_ctx(THD *thd) const
161 {
162 return new Default_object_creation_ctx(thd);
163 }
164
change_env(THD * thd) const165 void Default_object_creation_ctx::change_env(THD *thd) const
166 {
167 thd->update_charset(m_client_cs, m_connection_cl);
168 }
169
170 /**************************************************************************
171 View_creation_ctx implementation.
172 **************************************************************************/
173
create(THD * thd)174 View_creation_ctx *View_creation_ctx::create(THD *thd)
175 {
176 View_creation_ctx *ctx= new (thd->mem_root) View_creation_ctx(thd);
177
178 return ctx;
179 }
180
181 /*************************************************************************/
182
create(THD * thd,TABLE_LIST * view)183 View_creation_ctx * View_creation_ctx::create(THD *thd,
184 TABLE_LIST *view)
185 {
186 View_creation_ctx *ctx= new (thd->mem_root) View_creation_ctx(thd);
187
188 /* Throw a warning if there is NULL cs name. */
189
190 if (!view->view_client_cs_name.str ||
191 !view->view_connection_cl_name.str)
192 {
193 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
194 ER_VIEW_NO_CREATION_CTX,
195 ER_THD(thd, ER_VIEW_NO_CREATION_CTX),
196 view->db.str,
197 view->table_name.str);
198
199 ctx->m_client_cs= system_charset_info;
200 ctx->m_connection_cl= system_charset_info;
201
202 return ctx;
203 }
204
205 /* Resolve cs names. Throw a warning if there is unknown cs name. */
206
207 bool invalid_creation_ctx;
208
209 invalid_creation_ctx= resolve_charset(view->view_client_cs_name.str,
210 system_charset_info,
211 &ctx->m_client_cs);
212
213 invalid_creation_ctx= resolve_collation(view->view_connection_cl_name.str,
214 system_charset_info,
215 &ctx->m_connection_cl) ||
216 invalid_creation_ctx;
217
218 if (invalid_creation_ctx)
219 {
220 sql_print_warning("View '%s'.'%s': there is unknown charset/collation "
221 "names (client: '%s'; connection: '%s').",
222 view->db.str,
223 view->table_name.str,
224 (const char *) view->view_client_cs_name.str,
225 (const char *) view->view_connection_cl_name.str);
226
227 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
228 ER_VIEW_INVALID_CREATION_CTX,
229 ER_THD(thd, ER_VIEW_INVALID_CREATION_CTX),
230 view->db.str,
231 view->table_name.str);
232 }
233
234 return ctx;
235 }
236
237 /*************************************************************************/
238
239 /* Get column name from column hash */
240
get_field_name(Field ** buff,size_t * length,my_bool not_used)241 static uchar *get_field_name(Field **buff, size_t *length,
242 my_bool not_used __attribute__((unused)))
243 {
244 *length= (uint) (*buff)->field_name.length;
245 return (uchar*) (*buff)->field_name.str;
246 }
247
248
249 /*
250 Returns pointer to '.frm' extension of the file name.
251
252 SYNOPSIS
253 fn_frm_ext()
254 name file name
255
256 DESCRIPTION
257 Checks file name part starting with the rightmost '.' character,
258 and returns it if it is equal to '.frm'.
259
260 RETURN VALUES
261 Pointer to the '.frm' extension or NULL if not a .frm file
262 */
263
fn_frm_ext(const char * name)264 const char *fn_frm_ext(const char *name)
265 {
266 const char *res= strrchr(name, '.');
267 if (res && !strcmp(res, reg_ext))
268 return res;
269 return 0;
270 }
271
272
get_table_category(const LEX_CSTRING * db,const LEX_CSTRING * name)273 TABLE_CATEGORY get_table_category(const LEX_CSTRING *db,
274 const LEX_CSTRING *name)
275 {
276 DBUG_ASSERT(db != NULL);
277 DBUG_ASSERT(name != NULL);
278
279 #ifdef WITH_WSREP
280 if (my_strcasecmp(system_charset_info, db->str, "mysql") == 0 &&
281 my_strcasecmp(system_charset_info, name->str, "wsrep_streaming_log") == 0)
282 {
283 return TABLE_CATEGORY_INFORMATION;
284 }
285 #endif /* WITH_WSREP */
286 if (is_infoschema_db(db))
287 return TABLE_CATEGORY_INFORMATION;
288
289 if (lex_string_eq(&PERFORMANCE_SCHEMA_DB_NAME, db))
290 return TABLE_CATEGORY_PERFORMANCE;
291
292 if (lex_string_eq(&MYSQL_SCHEMA_NAME, db))
293 {
294 if (is_system_table_name(name->str, name->length))
295 return TABLE_CATEGORY_SYSTEM;
296
297 if (lex_string_eq(&GENERAL_LOG_NAME, name))
298 return TABLE_CATEGORY_LOG;
299
300 if (lex_string_eq(&SLOW_LOG_NAME, name))
301 return TABLE_CATEGORY_LOG;
302
303 if (lex_string_eq(&TRANSACTION_REG_NAME, name))
304 return TABLE_CATEGORY_LOG;
305 }
306
307 return TABLE_CATEGORY_USER;
308 }
309
310
311 /*
312 Allocate and setup a TABLE_SHARE structure
313
314 SYNOPSIS
315 alloc_table_share()
316 db Database name
317 table_name Table name
318 key Table cache key (db \0 table_name \0...)
319 key_length Length of key
320
321 RETURN
322 0 Error (out of memory)
323 # Share
324 */
325
alloc_table_share(const char * db,const char * table_name,const char * key,uint key_length)326 TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,
327 const char *key, uint key_length)
328 {
329 MEM_ROOT mem_root;
330 TABLE_SHARE *share;
331 char *key_buff, *path_buff;
332 char path[FN_REFLEN];
333 uint path_length;
334 DBUG_ENTER("alloc_table_share");
335 DBUG_PRINT("enter", ("table: '%s'.'%s'", db, table_name));
336
337 path_length= build_table_filename(path, sizeof(path) - 1,
338 db, table_name, "", 0);
339 init_sql_alloc(&mem_root, "table_share", TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
340 if (multi_alloc_root(&mem_root,
341 &share, sizeof(*share),
342 &key_buff, key_length,
343 &path_buff, path_length + 1,
344 NULL))
345 {
346 bzero((char*) share, sizeof(*share));
347
348 share->set_table_cache_key(key_buff, key, key_length);
349
350 share->path.str= path_buff;
351 share->path.length= path_length;
352 strmov(path_buff, path);
353 share->normalized_path.str= share->path.str;
354 share->normalized_path.length= path_length;
355 share->table_category= get_table_category(& share->db, & share->table_name);
356 share->open_errno= ENOENT;
357 /* The following will be updated in open_table_from_share */
358 share->can_do_row_logging= 1;
359 if (share->table_category == TABLE_CATEGORY_LOG)
360 share->no_replicate= 1;
361 if (key_length > 6 &&
362 my_strnncoll(table_alias_charset, (const uchar*) key, 6,
363 (const uchar*) "mysql", 6) == 0)
364 share->not_usable_by_query_cache= 1;
365
366 init_sql_alloc(&share->stats_cb.mem_root, "share_stats",
367 TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
368
369 memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
370 mysql_mutex_init(key_TABLE_SHARE_LOCK_share,
371 &share->LOCK_share, MY_MUTEX_INIT_SLOW);
372 mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data,
373 &share->LOCK_ha_data, MY_MUTEX_INIT_FAST);
374
375 DBUG_EXECUTE_IF("simulate_big_table_id",
376 if (last_table_id < UINT_MAX32)
377 last_table_id= UINT_MAX32 - 1;);
378 /*
379 There is one reserved number that cannot be used. Remember to
380 change this when 6-byte global table id's are introduced.
381 */
382 do
383 {
384 share->table_map_id=
385 last_table_id.fetch_add(1, std::memory_order_relaxed);
386 } while (unlikely(share->table_map_id == ~0UL ||
387 share->table_map_id == 0));
388 }
389 DBUG_RETURN(share);
390 }
391
392
393 /*
394 Initialize share for temporary tables
395
396 SYNOPSIS
397 init_tmp_table_share()
398 thd thread handle
399 share Share to fill
400 key Table_cache_key, as generated from tdc_create_key.
401 must start with db name.
402 key_length Length of key
403 table_name Table name
404 path Path to file (possible in lower case) without .frm
405
406 NOTES
407 This is different from alloc_table_share() because temporary tables
408 don't have to be shared between threads or put into the table def
409 cache, so we can do some things notable simpler and faster
410
411 If table is not put in thd->temporary_tables (happens only when
412 one uses OPEN TEMPORARY) then one can specify 'db' as key and
413 use key_length= 0 as neither table_cache_key or key_length will be used).
414 */
415
init_tmp_table_share(THD * thd,TABLE_SHARE * share,const char * key,uint key_length,const char * table_name,const char * path)416 void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
417 uint key_length, const char *table_name,
418 const char *path)
419 {
420 DBUG_ENTER("init_tmp_table_share");
421 DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name));
422
423 bzero((char*) share, sizeof(*share));
424 /*
425 This can't be MY_THREAD_SPECIFIC for slaves as they are freed
426 during cleanup() from Relay_log_info::close_temporary_tables()
427 */
428 init_sql_alloc(&share->mem_root, "tmp_table_share", TABLE_ALLOC_BLOCK_SIZE,
429 0, MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC));
430 share->table_category= TABLE_CATEGORY_TEMPORARY;
431 share->tmp_table= INTERNAL_TMP_TABLE;
432 share->db.str= (char*) key;
433 share->db.length= strlen(key);
434 share->table_cache_key.str= (char*) key;
435 share->table_cache_key.length= key_length;
436 share->table_name.str= (char*) table_name;
437 share->table_name.length= strlen(table_name);
438 share->path.str= (char*) path;
439 share->normalized_path.str= (char*) path;
440 share->path.length= share->normalized_path.length= strlen(path);
441 share->frm_version= FRM_VER_CURRENT;
442 share->not_usable_by_query_cache= 1;
443 share->can_do_row_logging= 0; // No row logging
444
445 /*
446 table_map_id is also used for MERGE tables to suppress repeated
447 compatibility checks.
448 */
449 share->table_map_id= (ulong) thd->query_id;
450 DBUG_VOID_RETURN;
451 }
452
453
454 /**
455 Release resources (plugins) used by the share and free its memory.
456 TABLE_SHARE is self-contained -- it's stored in its own MEM_ROOT.
457 Free this MEM_ROOT.
458 */
459
destroy()460 void TABLE_SHARE::destroy()
461 {
462 uint idx;
463 KEY *info_it;
464 DBUG_ENTER("TABLE_SHARE::destroy");
465 DBUG_PRINT("info", ("db: %s table: %s", db.str, table_name.str));
466
467 if (ha_share)
468 {
469 delete ha_share;
470 ha_share= NULL; // Safety
471 }
472
473 delete_stat_values_for_table_share(this);
474 delete sequence;
475 free_root(&stats_cb.mem_root, MYF(0));
476
477 /* The mutexes are initialized only for shares that are part of the TDC */
478 if (tmp_table == NO_TMP_TABLE)
479 {
480 mysql_mutex_destroy(&LOCK_share);
481 mysql_mutex_destroy(&LOCK_ha_data);
482 }
483 my_hash_free(&name_hash);
484
485 plugin_unlock(NULL, db_plugin);
486 db_plugin= NULL;
487
488 /* Release fulltext parsers */
489 info_it= key_info;
490 for (idx= keys; idx; idx--, info_it++)
491 {
492 if (info_it->flags & HA_USES_PARSER)
493 {
494 plugin_unlock(NULL, info_it->parser);
495 info_it->flags= 0;
496 }
497 }
498
499 #ifdef WITH_PARTITION_STORAGE_ENGINE
500 plugin_unlock(NULL, default_part_plugin);
501 #endif /* WITH_PARTITION_STORAGE_ENGINE */
502
503 PSI_CALL_release_table_share(m_psi);
504
505 /*
506 Make a copy since the share is allocated in its own root,
507 and free_root() updates its argument after freeing the memory.
508 */
509 MEM_ROOT own_root= mem_root;
510 free_root(&own_root, MYF(0));
511 DBUG_VOID_RETURN;
512 }
513
514 /*
515 Free table share and memory used by it
516
517 SYNOPSIS
518 free_table_share()
519 share Table share
520 */
521
free_table_share(TABLE_SHARE * share)522 void free_table_share(TABLE_SHARE *share)
523 {
524 DBUG_ENTER("free_table_share");
525 DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str));
526 share->destroy();
527 DBUG_VOID_RETURN;
528 }
529
530
531 /**
532 Return TRUE if a table name matches one of the system table names.
533 Currently these are:
534
535 help_category, help_keyword, help_relation, help_topic,
536 proc, event
537 time_zone, time_zone_leap_second, time_zone_name, time_zone_transition,
538 time_zone_transition_type
539
540 This function trades accuracy for speed, so may return false
541 positives. Presumably mysql.* database is for internal purposes only
542 and should not contain user tables.
543 */
544
is_system_table_name(const char * name,size_t length)545 inline bool is_system_table_name(const char *name, size_t length)
546 {
547 CHARSET_INFO *ci= system_charset_info;
548
549 return (
550 /* mysql.proc table */
551 (length == 4 &&
552 my_tolower(ci, name[0]) == 'p' &&
553 my_tolower(ci, name[1]) == 'r' &&
554 my_tolower(ci, name[2]) == 'o' &&
555 my_tolower(ci, name[3]) == 'c') ||
556
557 (length > 4 &&
558 (
559 /* one of mysql.help* tables */
560 (my_tolower(ci, name[0]) == 'h' &&
561 my_tolower(ci, name[1]) == 'e' &&
562 my_tolower(ci, name[2]) == 'l' &&
563 my_tolower(ci, name[3]) == 'p') ||
564
565 /* one of mysql.time_zone* tables */
566 (my_tolower(ci, name[0]) == 't' &&
567 my_tolower(ci, name[1]) == 'i' &&
568 my_tolower(ci, name[2]) == 'm' &&
569 my_tolower(ci, name[3]) == 'e') ||
570
571 /* one of mysql.*_stat tables, but not mysql.innodb* tables*/
572 ((my_tolower(ci, name[length-5]) == 's' &&
573 my_tolower(ci, name[length-4]) == 't' &&
574 my_tolower(ci, name[length-3]) == 'a' &&
575 my_tolower(ci, name[length-2]) == 't' &&
576 my_tolower(ci, name[length-1]) == 's') &&
577 !(my_tolower(ci, name[0]) == 'i' &&
578 my_tolower(ci, name[1]) == 'n' &&
579 my_tolower(ci, name[2]) == 'n' &&
580 my_tolower(ci, name[3]) == 'o')) ||
581
582 /* mysql.event table */
583 (my_tolower(ci, name[0]) == 'e' &&
584 my_tolower(ci, name[1]) == 'v' &&
585 my_tolower(ci, name[2]) == 'e' &&
586 my_tolower(ci, name[3]) == 'n' &&
587 my_tolower(ci, name[4]) == 't')
588 )
589 )
590 );
591 }
592
593
594 /*
595 Read table definition from a binary / text based .frm file
596
597 SYNOPSIS
598 open_table_def()
599 thd Thread handler
600 share Fill this with table definition
601 flags Bit mask of the following flags: OPEN_VIEW
602
603 NOTES
604 This function is called when the table definition is not cached in
605 table definition cache
606 The data is returned in 'share', which is allocated by
607 alloc_table_share().. The code assumes that share is initialized.
608 */
609
open_table_def(THD * thd,TABLE_SHARE * share,uint flags)610 enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
611 {
612 bool error_given= false;
613 File file;
614 uchar *buf;
615 uchar head[FRM_HEADER_SIZE];
616 char path[FN_REFLEN];
617 size_t frmlen, read_length;
618 uint length;
619 DBUG_ENTER("open_table_def");
620 DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str,
621 share->table_name.str, share->normalized_path.str));
622
623 share->error= OPEN_FRM_OPEN_ERROR;
624
625 length=(uint) (strxmov(path, share->normalized_path.str, reg_ext, NullS) -
626 path);
627 if (flags & GTS_FORCE_DISCOVERY)
628 {
629 DBUG_ASSERT(flags & GTS_TABLE);
630 DBUG_ASSERT(flags & GTS_USE_DISCOVERY);
631 mysql_file_delete_with_symlink(key_file_frm, path, "", MYF(0));
632 file= -1;
633 }
634 else
635 file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0));
636
637 if (file < 0)
638 {
639 if ((flags & GTS_TABLE) && (flags & GTS_USE_DISCOVERY))
640 {
641 ha_discover_table(thd, share);
642 error_given= true;
643 }
644 goto err_not_open;
645 }
646
647 if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP)))
648 {
649 share->error = my_errno == HA_ERR_FILE_TOO_SHORT
650 ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR;
651 goto err;
652 }
653
654 if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0)
655 {
656 share->is_view= 1;
657 if (flags & GTS_VIEW)
658 {
659 LEX_CSTRING pathstr= { path, length };
660 /*
661 Create view file parser and hold it in TABLE_SHARE member
662 view_def.
663 */
664 share->view_def= sql_parse_prepare(&pathstr, &share->mem_root, true);
665 if (!share->view_def)
666 share->error= OPEN_FRM_ERROR_ALREADY_ISSUED;
667 else
668 share->error= OPEN_FRM_OK;
669 }
670 else
671 share->error= OPEN_FRM_NOT_A_TABLE;
672 goto err;
673 }
674 if (!is_binary_frm_header(head))
675 {
676 /* No handling of text based files yet */
677 share->error = OPEN_FRM_CORRUPTED;
678 goto err;
679 }
680 if (!(flags & GTS_TABLE))
681 {
682 share->error = OPEN_FRM_NOT_A_VIEW;
683 goto err;
684 }
685
686 frmlen= uint4korr(head+10);
687 set_if_smaller(frmlen, FRM_MAX_SIZE); // safety
688
689 if (!(buf= (uchar*)my_malloc(frmlen, MYF(MY_THREAD_SPECIFIC|MY_WME))))
690 goto err;
691
692 memcpy(buf, head, sizeof(head));
693
694 read_length= mysql_file_read(file, buf + sizeof(head),
695 frmlen - sizeof(head), MYF(MY_WME));
696 if (read_length == 0 || read_length == (size_t)-1)
697 {
698 share->error = OPEN_FRM_READ_ERROR;
699 my_free(buf);
700 goto err;
701 }
702 mysql_file_close(file, MYF(MY_WME));
703
704 frmlen= read_length + sizeof(head);
705
706 share->init_from_binary_frm_image(thd, false, buf, frmlen);
707 /*
708 Don't give any additional errors. If there would be a problem,
709 init_from_binary_frm_image would call my_error() itself.
710 */
711 error_given= true;
712 my_free(buf);
713
714 goto err_not_open;
715
716 err:
717 mysql_file_close(file, MYF(MY_WME));
718
719 err_not_open:
720 /* Mark that table was created earlier and thus should have been logged */
721 share->table_creation_was_logged= 1;
722
723 if (unlikely(share->error && !error_given))
724 {
725 share->open_errno= my_errno;
726 open_table_error(share, share->error, share->open_errno);
727 }
728
729 DBUG_RETURN(share->error);
730 }
731
create_key_infos(const uchar * strpos,const uchar * frm_image_end,uint keys,KEY * keyinfo,uint new_frm_ver,uint * ext_key_parts,TABLE_SHARE * share,uint len,KEY * first_keyinfo,LEX_STRING * keynames)732 static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
733 uint keys, KEY *keyinfo,
734 uint new_frm_ver, uint *ext_key_parts,
735 TABLE_SHARE *share, uint len,
736 KEY *first_keyinfo,
737 LEX_STRING *keynames)
738 {
739 uint i, j, n_length;
740 KEY_PART_INFO *key_part= NULL;
741 ulong *rec_per_key= NULL;
742 KEY_PART_INFO *first_key_part= NULL;
743 uint first_key_parts= 0;
744
745 if (!keys)
746 {
747 if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len)))
748 return 1;
749 bzero((char*) keyinfo, len);
750 key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo);
751 }
752
753 /*
754 If share->use_ext_keys is set to TRUE we assume that any key
755 can be extended by the components of the primary key whose
756 definition is read first from the frm file.
757 For each key only those fields of the assumed primary key are
758 added that are not included in the proper key definition.
759 If after all it turns out that there is no primary key the
760 added components are removed from each key.
761
762 When in the future we support others schemes of extending of
763 secondary keys with components of the primary key we'll have
764 to change the type of this flag for an enumeration type.
765 */
766
767 for (i=0 ; i < keys ; i++, keyinfo++)
768 {
769 if (new_frm_ver >= 3)
770 {
771 if (strpos + 8 >= frm_image_end)
772 return 1;
773 keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
774 keyinfo->key_length= (uint) uint2korr(strpos+2);
775 keyinfo->user_defined_key_parts= (uint) strpos[4];
776 keyinfo->algorithm= (enum ha_key_alg) strpos[5];
777 keyinfo->block_size= uint2korr(strpos+6);
778 strpos+=8;
779 }
780 else
781 {
782 if (strpos + 4 >= frm_image_end)
783 return 1;
784 keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
785 keyinfo->key_length= (uint) uint2korr(strpos+1);
786 keyinfo->user_defined_key_parts= (uint) strpos[3];
787 keyinfo->algorithm= HA_KEY_ALG_UNDEF;
788 strpos+=4;
789 }
790
791 if (i == 0)
792 {
793 (*ext_key_parts)+= (share->use_ext_keys ? first_keyinfo->user_defined_key_parts*(keys-1) : 0);
794 n_length=keys * sizeof(KEY) + *ext_key_parts * sizeof(KEY_PART_INFO);
795 if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
796 n_length + len)))
797 return 1;
798 bzero((char*) keyinfo,n_length);
799 share->key_info= keyinfo;
800 key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo + keys);
801
802 if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
803 sizeof(ulong) * *ext_key_parts)))
804 return 1;
805 first_key_part= key_part;
806 first_key_parts= first_keyinfo->user_defined_key_parts;
807 keyinfo->flags= first_keyinfo->flags;
808 keyinfo->key_length= first_keyinfo->key_length;
809 keyinfo->user_defined_key_parts= first_keyinfo->user_defined_key_parts;
810 keyinfo->algorithm= first_keyinfo->algorithm;
811 if (new_frm_ver >= 3)
812 keyinfo->block_size= first_keyinfo->block_size;
813 }
814
815 keyinfo->key_part= key_part;
816 keyinfo->rec_per_key= rec_per_key;
817 for (j=keyinfo->user_defined_key_parts ; j-- ; key_part++)
818 {
819 if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end)
820 return 1;
821 if (!(keyinfo->algorithm == HA_KEY_ALG_LONG_HASH))
822 *rec_per_key++=0;
823 key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
824 key_part->offset= (uint) uint2korr(strpos+2)-1;
825 key_part->key_type= (uint) uint2korr(strpos+5);
826 // key_part->field= (Field*) 0; // Will be fixed later
827 if (new_frm_ver >= 1)
828 {
829 key_part->key_part_flag= *(strpos+4);
830 key_part->length= (uint) uint2korr(strpos+7);
831 strpos+=9;
832 }
833 else
834 {
835 key_part->length= *(strpos+4);
836 key_part->key_part_flag=0;
837 if (key_part->length > 128)
838 {
839 key_part->length&=127; /* purecov: inspected */
840 key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
841 }
842 strpos+=7;
843 }
844 key_part->store_length=key_part->length;
845 }
846 if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
847 {
848 keyinfo->key_length= HA_HASH_KEY_LENGTH_WITHOUT_NULL;
849 key_part++; // reserved for the hash value
850 *rec_per_key++=0;
851 }
852
853 /*
854 Add primary key to end of extended keys for non unique keys for
855 storage engines that supports it.
856 */
857 keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
858 keyinfo->ext_key_flags= keyinfo->flags;
859 keyinfo->ext_key_part_map= 0;
860 if (share->use_ext_keys && i && !(keyinfo->flags & HA_NOSAME))
861 {
862 for (j= 0;
863 j < first_key_parts && keyinfo->ext_key_parts < MAX_REF_PARTS;
864 j++)
865 {
866 uint key_parts= keyinfo->user_defined_key_parts;
867 KEY_PART_INFO* curr_key_part= keyinfo->key_part;
868 KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts;
869 for ( ; curr_key_part < curr_key_part_end; curr_key_part++)
870 {
871 if (curr_key_part->fieldnr == first_key_part[j].fieldnr)
872 break;
873 }
874 if (curr_key_part == curr_key_part_end)
875 {
876 *key_part++= first_key_part[j];
877 *rec_per_key++= 0;
878 keyinfo->ext_key_parts++;
879 keyinfo->ext_key_part_map|= 1 << j;
880 }
881 }
882 if (j == first_key_parts)
883 keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME;
884 }
885 if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
886 share->ext_key_parts++;
887 share->ext_key_parts+= keyinfo->ext_key_parts;
888 }
889 keynames->str= (char*) key_part;
890 keynames->length= strnmov(keynames->str, (char *) strpos,
891 frm_image_end - strpos) - keynames->str;
892 strpos+= keynames->length;
893 if (*strpos++) // key names are \0-terminated
894 return 1;
895 keynames->length++; // Include '\0', to make fix_type_pointers() happy.
896
897 //reading index comments
898 for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
899 {
900 if (keyinfo->flags & HA_USES_COMMENT)
901 {
902 if (strpos + 2 >= frm_image_end)
903 return 1;
904 keyinfo->comment.length= uint2korr(strpos);
905 strpos+= 2;
906
907 if (strpos + keyinfo->comment.length >= frm_image_end)
908 return 1;
909 keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos,
910 keyinfo->comment.length);
911 strpos+= keyinfo->comment.length;
912 }
913 DBUG_ASSERT(MY_TEST(keyinfo->flags & HA_USES_COMMENT) ==
914 (keyinfo->comment.length > 0));
915 }
916
917 share->keys= keys; // do it *after* all key_info's are initialized
918
919 return 0;
920 }
921
922
923 /** ensures that the enum value (read from frm) is within limits
924
925 if not - issues a warning and resets the value to 0
926 (that is, 0 is assumed to be a default value)
927 */
928
enum_value_with_check(THD * thd,TABLE_SHARE * share,const char * name,uint value,uint limit)929 static uint enum_value_with_check(THD *thd, TABLE_SHARE *share,
930 const char *name, uint value, uint limit)
931 {
932 if (value < limit)
933 return value;
934
935 sql_print_warning("%s.frm: invalid value %d for the field %s",
936 share->normalized_path.str, value, name);
937 return 0;
938 }
939
940
941 /**
942 Check if a collation has changed number
943
944 @param mysql_version
945 @param current collation number
946
947 @retval new collation number (same as current collation number of no change)
948 */
949
upgrade_collation(ulong mysql_version,uint cs_number)950 static uint upgrade_collation(ulong mysql_version, uint cs_number)
951 {
952 if (mysql_version >= 50300 && mysql_version <= 50399)
953 {
954 switch (cs_number) {
955 case 149: return MY_PAGE2_COLLATION_ID_UCS2; // ucs2_crotian_ci
956 case 213: return MY_PAGE2_COLLATION_ID_UTF8; // utf8_crotian_ci
957 }
958 }
959 if ((mysql_version >= 50500 && mysql_version <= 50599) ||
960 (mysql_version >= 100000 && mysql_version <= 100005))
961 {
962 switch (cs_number) {
963 case 149: return MY_PAGE2_COLLATION_ID_UCS2; // ucs2_crotian_ci
964 case 213: return MY_PAGE2_COLLATION_ID_UTF8; // utf8_crotian_ci
965 case 214: return MY_PAGE2_COLLATION_ID_UTF32; // utf32_croatian_ci
966 case 215: return MY_PAGE2_COLLATION_ID_UTF16; // utf16_croatian_ci
967 case 245: return MY_PAGE2_COLLATION_ID_UTF8MB4;// utf8mb4_croatian_ci
968 }
969 }
970 return cs_number;
971 }
972
973
frm_pack_basic(uchar * buff) const974 void Column_definition_attributes::frm_pack_basic(uchar *buff) const
975 {
976 int2store(buff + 3, length);
977 int2store(buff + 8, pack_flag);
978 buff[10]= (uchar) unireg_check;
979 }
980
981
frm_unpack_basic(const uchar * buff)982 void Column_definition_attributes::frm_unpack_basic(const uchar *buff)
983 {
984 length= uint2korr(buff + 3);
985 pack_flag= uint2korr(buff + 8);
986 unireg_check= (Field::utype) MTYP_TYPENR((uint) buff[10]);
987 }
988
989
frm_pack_charset(uchar * buff) const990 void Column_definition_attributes::frm_pack_charset(uchar *buff) const
991 {
992 buff[11]= (uchar) (charset->number >> 8);
993 buff[14]= (uchar) charset->number;
994 }
995
996
frm_unpack_charset(TABLE_SHARE * share,const uchar * buff)997 bool Column_definition_attributes::frm_unpack_charset(TABLE_SHARE *share,
998 const uchar *buff)
999 {
1000 uint cs_org= buff[14] + (((uint) buff[11]) << 8);
1001 uint cs_new= upgrade_collation(share->mysql_version, cs_org);
1002 if (cs_org != cs_new)
1003 share->incompatible_version|= HA_CREATE_USED_CHARSET;
1004 if (cs_new && !(charset= get_charset(cs_new, MYF(0))))
1005 {
1006 const char *csname= get_charset_name((uint) cs_new);
1007 char tmp[10];
1008 if (!csname || csname[0] =='?')
1009 {
1010 my_snprintf(tmp, sizeof(tmp), "#%u", cs_new);
1011 csname= tmp;
1012 }
1013 my_printf_error(ER_UNKNOWN_COLLATION,
1014 "Unknown collation '%s' in table '%-.64s' definition",
1015 MYF(0), csname, share->table_name.str);
1016 return true;
1017 }
1018 return false;
1019 }
1020
1021
1022 /*
1023 In MySQL 5.7 the null bits for not stored virtual fields are last.
1024 Calculate the position for these bits
1025 */
1026
mysql57_calculate_null_position(TABLE_SHARE * share,uchar ** null_pos,uint * null_bit_pos,const uchar * strpos,const uchar * vcol_screen_pos)1027 static void mysql57_calculate_null_position(TABLE_SHARE *share,
1028 uchar **null_pos,
1029 uint *null_bit_pos,
1030 const uchar *strpos,
1031 const uchar *vcol_screen_pos)
1032 {
1033 uint field_pack_length= 17;
1034
1035 for (uint i=0 ; i < share->fields; i++, strpos+= field_pack_length)
1036 {
1037 uint field_length, pack_flag;
1038 enum_field_types field_type;
1039
1040 if ((strpos[10] & MYSQL57_GENERATED_FIELD))
1041 {
1042 /* Skip virtual (not stored) generated field */
1043 bool stored_in_db= vcol_screen_pos[3];
1044 vcol_screen_pos+= (uint2korr(vcol_screen_pos + 1) +
1045 MYSQL57_GCOL_HEADER_SIZE);
1046 if (! stored_in_db)
1047 continue;
1048 }
1049 field_length= uint2korr(strpos+3);
1050 pack_flag= uint2korr(strpos+8);
1051 field_type= (enum_field_types) (uint) strpos[13];
1052 if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
1053 {
1054 if (((*null_bit_pos)+= field_length & 7) > 7)
1055 {
1056 (*null_pos)++;
1057 (*null_bit_pos)-= 8;
1058 }
1059 }
1060 if (f_maybe_null(pack_flag))
1061 {
1062 if (!((*null_bit_pos)= ((*null_bit_pos) + 1) & 7))
1063 (*null_pos)++;
1064 }
1065 }
1066 }
1067
1068 static bool fix_and_check_vcol_expr(THD *thd, TABLE *table,
1069 Virtual_column_info *vcol);
1070
1071 /** Parse TABLE_SHARE::vcol_defs
1072
1073 unpack_vcol_info_from_frm
1074 5.7
1075 byte 1 = 1
1076 byte 2,3 = expr length
1077 byte 4 = stored_in_db
1078 expression
1079 10.1-
1080 byte 1 = 1 | 2
1081 byte 2 = sql_type ; but TABLE::init_from_binary_frm_image()
1082 byte 3 = stored_in_db ; has put expr_length here
1083 [byte 4] = optional interval_id for sql_type (if byte 1 == 2)
1084 expression
1085 10.2+
1086 byte 1 = type
1087 byte 2,3 = field_number
1088 byte 4,5 = length of expression
1089 byte 6 = length of name
1090 name
1091 expression
1092 */
parse_vcol_defs(THD * thd,MEM_ROOT * mem_root,TABLE * table,bool * error_reported,vcol_init_mode mode)1093 bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
1094 bool *error_reported, vcol_init_mode mode)
1095 {
1096 CHARSET_INFO *save_character_set_client= thd->variables.character_set_client;
1097 CHARSET_INFO *save_collation= thd->variables.collation_connection;
1098 Query_arena *backup_stmt_arena_ptr= thd->stmt_arena;
1099 const uchar *pos= table->s->vcol_defs.str;
1100 const uchar *end= pos + table->s->vcol_defs.length;
1101 Field **field_ptr= table->field - 1;
1102 Field **vfield_ptr= table->vfield;
1103 Field **dfield_ptr= table->default_field;
1104 Virtual_column_info **check_constraint_ptr= table->check_constraints;
1105 sql_mode_t saved_mode= thd->variables.sql_mode;
1106 Query_arena backup_arena;
1107 Virtual_column_info *vcol= 0;
1108 StringBuffer<MAX_FIELD_WIDTH> expr_str;
1109 bool res= 1;
1110 DBUG_ENTER("parse_vcol_defs");
1111
1112 if (check_constraint_ptr)
1113 memcpy(table->check_constraints + table->s->field_check_constraints,
1114 table->s->check_constraints,
1115 table->s->table_check_constraints * sizeof(Virtual_column_info*));
1116
1117 DBUG_ASSERT(table->expr_arena == NULL);
1118 /*
1119 We need to use CONVENTIONAL_EXECUTION here to ensure that
1120 any new items created by fix_fields() are not reverted.
1121 */
1122 table->expr_arena= new (alloc_root(mem_root, sizeof(Table_arena)))
1123 Table_arena(mem_root,
1124 Query_arena::STMT_CONVENTIONAL_EXECUTION);
1125 if (!table->expr_arena)
1126 DBUG_RETURN(1);
1127
1128 thd->set_n_backup_active_arena(table->expr_arena, &backup_arena);
1129 thd->stmt_arena= table->expr_arena;
1130 thd->update_charset(&my_charset_utf8mb4_general_ci, table->s->table_charset);
1131 expr_str.append(&parse_vcol_keyword);
1132 thd->variables.sql_mode &= ~(MODE_NO_BACKSLASH_ESCAPES | MODE_EMPTY_STRING_IS_NULL);
1133
1134 while (pos < end)
1135 {
1136 uint type, expr_length;
1137 if (table->s->frm_version >= FRM_VER_EXPRESSSIONS)
1138 {
1139 uint field_nr, name_length;
1140 /* see pack_expression() for how data is stored */
1141 type= pos[0];
1142 field_nr= uint2korr(pos+1);
1143 expr_length= uint2korr(pos+3);
1144 name_length= pos[5];
1145 pos+= FRM_VCOL_NEW_HEADER_SIZE + name_length;
1146 field_ptr= table->field + field_nr;
1147 }
1148 else
1149 {
1150 /*
1151 see below in ::init_from_binary_frm_image for how data is stored
1152 in versions below 10.2 (that includes 5.7 too)
1153 */
1154 while (*++field_ptr && !(*field_ptr)->vcol_info) /* no-op */;
1155 if (!*field_ptr)
1156 {
1157 open_table_error(table->s, OPEN_FRM_CORRUPTED, 1);
1158 goto end;
1159 }
1160 type= (*field_ptr)->vcol_info->stored_in_db
1161 ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL;
1162 expr_length= uint2korr(pos+1);
1163 if (table->s->mysql_version > 50700 && table->s->mysql_version < 100000)
1164 pos+= 4; // MySQL from 5.7
1165 else
1166 pos+= pos[0] == 2 ? 4 : 3; // MariaDB from 5.2 to 10.1
1167 }
1168
1169 expr_str.length(parse_vcol_keyword.length);
1170 expr_str.append((char*)pos, expr_length);
1171 thd->where= vcol_type_name(static_cast<enum_vcol_info_type>(type));
1172
1173 switch (type) {
1174 case VCOL_GENERATED_VIRTUAL:
1175 case VCOL_GENERATED_STORED:
1176 vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
1177 &((*field_ptr)->vcol_info), error_reported);
1178 *(vfield_ptr++)= *field_ptr;
1179 DBUG_ASSERT(table->map == 0);
1180 /*
1181 We need Item_field::const_item() to return false, so
1182 datetime_precision() and time_precision() do not try to calculate
1183 field values, e.g. val_str().
1184 Set table->map to non-zero temporarily.
1185 */
1186 table->map= 1;
1187 if (vcol && field_ptr[0]->check_vcol_sql_mode_dependency(thd, mode))
1188 {
1189 DBUG_ASSERT(thd->is_error());
1190 *error_reported= true;
1191 goto end;
1192 }
1193 table->map= 0;
1194 break;
1195 case VCOL_DEFAULT:
1196 vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
1197 &((*field_ptr)->default_value),
1198 error_reported);
1199 *(dfield_ptr++)= *field_ptr;
1200 if (vcol && (vcol->flags & (VCOL_NON_DETERMINISTIC | VCOL_SESSION_FUNC)))
1201 table->s->non_determinstic_insert= true;
1202 break;
1203 case VCOL_CHECK_FIELD:
1204 vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
1205 &((*field_ptr)->check_constraint),
1206 error_reported);
1207 *check_constraint_ptr++= (*field_ptr)->check_constraint;
1208 break;
1209 case VCOL_CHECK_TABLE:
1210 vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
1211 check_constraint_ptr, error_reported);
1212 check_constraint_ptr++;
1213 break;
1214 }
1215 if (!vcol)
1216 goto end;
1217 pos+= expr_length;
1218 }
1219
1220 /* Now, initialize CURRENT_TIMESTAMP and UNIQUE_INDEX_HASH_FIELD fields */
1221 for (field_ptr= table->field; *field_ptr; field_ptr++)
1222 {
1223 Field *field= *field_ptr;
1224 if (field->flags & LONG_UNIQUE_HASH_FIELD)
1225 {
1226 List<Item> *field_list= new (mem_root) List<Item>();
1227 Item *list_item;
1228 KEY *key= 0;
1229 uint key_index, parts= 0;
1230 for (key_index= 0; key_index < table->s->keys; key_index++)
1231 {
1232 key=table->key_info + key_index;
1233 parts= key->user_defined_key_parts;
1234 if (key->key_part[parts].fieldnr == field->field_index + 1)
1235 break;
1236 }
1237 if (!key || key->algorithm != HA_KEY_ALG_LONG_HASH)
1238 goto end;
1239 KEY_PART_INFO *keypart;
1240 for (uint i=0; i < parts; i++)
1241 {
1242 keypart= key->key_part + i;
1243 if (keypart->key_part_flag & HA_PART_KEY_SEG)
1244 {
1245 int length= keypart->length/keypart->field->charset()->mbmaxlen;
1246 list_item= new (mem_root) Item_func_left(thd,
1247 new (mem_root) Item_field(thd, keypart->field),
1248 new (mem_root) Item_int(thd, length));
1249 list_item->fix_fields(thd, NULL);
1250 keypart->field->vcol_info=
1251 table->field[keypart->field->field_index]->vcol_info;
1252 }
1253 else
1254 list_item= new (mem_root) Item_field(thd, keypart->field);
1255 field_list->push_back(list_item, mem_root);
1256 }
1257 Item_func_hash *hash_item= new(mem_root)Item_func_hash(thd, *field_list);
1258 Virtual_column_info *v= new (mem_root) Virtual_column_info();
1259 field->vcol_info= v;
1260 field->vcol_info->expr= hash_item;
1261 field->vcol_info->set_vcol_type(VCOL_USING_HASH);
1262 if (fix_and_check_vcol_expr(thd, table, v))
1263 goto end;
1264 key->user_defined_key_parts= key->ext_key_parts= key->usable_key_parts= 1;
1265 key->key_part+= parts;
1266
1267 if (key->flags & HA_NULL_PART_KEY)
1268 key->key_length= HA_HASH_KEY_LENGTH_WITH_NULL;
1269 else
1270 key->key_length= HA_HASH_KEY_LENGTH_WITHOUT_NULL;
1271
1272 *(vfield_ptr++)= *field_ptr;
1273 }
1274 if (field->has_default_now_unireg_check())
1275 {
1276 expr_str.length(parse_vcol_keyword.length);
1277 expr_str.append(STRING_WITH_LEN("current_timestamp("));
1278 expr_str.append_ulonglong(field->decimals());
1279 expr_str.append(')');
1280 vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
1281 &((*field_ptr)->default_value),
1282 error_reported);
1283 *(dfield_ptr++)= *field_ptr;
1284 if (!field->default_value->expr)
1285 goto end;
1286 }
1287 else if (field->has_update_default_function() && !field->default_value)
1288 *(dfield_ptr++)= *field_ptr;
1289 }
1290
1291 if (vfield_ptr)
1292 *vfield_ptr= 0;
1293
1294 if (dfield_ptr)
1295 *dfield_ptr= 0;
1296
1297 if (check_constraint_ptr)
1298 *check_constraint_ptr= 0;
1299
1300 /* Check that expressions aren't referring to not yet initialized fields */
1301 for (field_ptr= table->field; *field_ptr; field_ptr++)
1302 {
1303 Field *field= *field_ptr;
1304 if (check_vcol_forward_refs(field, field->vcol_info, 0) ||
1305 check_vcol_forward_refs(field, field->check_constraint, 1) ||
1306 check_vcol_forward_refs(field, field->default_value, 0))
1307 {
1308 *error_reported= true;
1309 goto end;
1310 }
1311 }
1312
1313 table->find_constraint_correlated_indexes();
1314
1315 res=0;
1316 end:
1317 thd->restore_active_arena(table->expr_arena, &backup_arena);
1318 thd->stmt_arena= backup_stmt_arena_ptr;
1319 if (save_character_set_client)
1320 thd->update_charset(save_character_set_client, save_collation);
1321 thd->variables.sql_mode= saved_mode;
1322 DBUG_RETURN(res);
1323 }
1324
1325
old_frm_type_handler(uint pack_flag,uint interval_nr)1326 static const Type_handler *old_frm_type_handler(uint pack_flag,
1327 uint interval_nr)
1328 {
1329 enum_field_types field_type= (enum_field_types) f_packtype(pack_flag);
1330 DBUG_ASSERT(field_type < 16);
1331
1332 if (!f_is_alpha(pack_flag))
1333 return Type_handler::get_handler_by_real_type(field_type);
1334
1335 if (!f_is_packed(pack_flag))
1336 {
1337 if (field_type == MYSQL_TYPE_DECIMAL) // 3.23 or 4.0 string
1338 return &type_handler_string;
1339 if (field_type == MYSQL_TYPE_VARCHAR) // Since mysql-5.0
1340 return &type_handler_varchar;
1341 return NULL; // Error (bad frm?)
1342 }
1343
1344 if (f_is_blob(pack_flag))
1345 return &type_handler_blob; // QQ: exact type??
1346
1347 if (interval_nr)
1348 {
1349 if (f_is_enum(pack_flag))
1350 return &type_handler_enum;
1351 return &type_handler_set;
1352 }
1353 return Type_handler::get_handler_by_real_type(field_type);
1354 }
1355
1356 /* Set overlapped bitmaps for each index */
1357
set_overlapped_keys()1358 void TABLE_SHARE::set_overlapped_keys()
1359 {
1360 KEY *key1= key_info;
1361 for (uint i= 0; i < keys; i++, key1++)
1362 {
1363 key1->overlapped.clear_all();
1364 key1->overlapped.set_bit(i);
1365 }
1366 key1= key_info;
1367 for (uint i= 0; i < keys; i++, key1++)
1368 {
1369 KEY *key2= key1 + 1;
1370 for (uint j= i+1; j < keys; j++, key2++)
1371 {
1372 KEY_PART_INFO *key_part1= key1->key_part;
1373 uint n1= key1->user_defined_key_parts;
1374 uint n2= key2->user_defined_key_parts;
1375 for (uint k= 0; k < n1; k++, key_part1++)
1376 {
1377 KEY_PART_INFO *key_part2= key2->key_part;
1378 for (uint l= 0; l < n2; l++, key_part2++)
1379 {
1380 if (key_part1->fieldnr == key_part2->fieldnr)
1381 {
1382 key1->overlapped.set_bit(j);
1383 key2->overlapped.set_bit(i);
1384 goto end_checking_overlap;
1385 }
1386 }
1387 }
1388 end_checking_overlap:
1389 ;
1390 }
1391 }
1392 }
1393
1394
check_index_dependence(void * arg)1395 bool Item_field::check_index_dependence(void *arg)
1396 {
1397 TABLE *table= (TABLE *)arg;
1398
1399 KEY *key= table->key_info;
1400 for (uint j= 0; j < table->s->keys; j++, key++)
1401 {
1402 if (table->constraint_dependent_keys.is_set(j))
1403 continue;
1404
1405 KEY_PART_INFO *key_part= key->key_part;
1406 uint n= key->user_defined_key_parts;
1407
1408 for (uint k= 0; k < n; k++, key_part++)
1409 {
1410 if (this->field == key_part->field)
1411 {
1412 table->constraint_dependent_keys.set_bit(j);
1413 break;
1414 }
1415 }
1416 }
1417 return false;
1418 }
1419
1420
1421 /**
1422 @brief
1423 Find keys that occur in the same constraint on this table
1424
1425 @details
1426 Constraints on this table are checked only.
1427
1428 The method goes through constraints list trying to find at
1429 least two keys which parts participate in some constraint.
1430 These keys are called constraint correlated.
1431
1432 Each key has its own key map with the information about with
1433 which keys it is constraint correlated. Bit in this map is set
1434 only if keys are constraint correlated.
1435 This method fills each keys constraint correlated key map.
1436 */
1437
find_constraint_correlated_indexes()1438 void TABLE::find_constraint_correlated_indexes()
1439 {
1440 if (s->keys == 0)
1441 return;
1442
1443 KEY *key= key_info;
1444 for (uint i= 0; i < s->keys; i++, key++)
1445 {
1446 key->constraint_correlated.clear_all();
1447 key->constraint_correlated.set_bit(i);
1448 }
1449
1450 if (!check_constraints)
1451 return;
1452
1453 for (Virtual_column_info **chk= check_constraints ; *chk ; chk++)
1454 {
1455 constraint_dependent_keys.clear_all();
1456 (*chk)->expr->walk(&Item::check_index_dependence, 0, this);
1457
1458 if (constraint_dependent_keys.bits_set() <= 1)
1459 continue;
1460
1461 uint key_no= 0;
1462 key_map::Iterator ki(constraint_dependent_keys);
1463 while ((key_no= ki++) != key_map::Iterator::BITMAP_END)
1464 key_info[key_no].constraint_correlated.merge(constraint_dependent_keys);
1465 }
1466 }
1467
1468
init_period_from_extra2(period_info_t * period,const uchar * data,const uchar * end)1469 bool TABLE_SHARE::init_period_from_extra2(period_info_t *period,
1470 const uchar *data, const uchar *end)
1471 {
1472 if (data + 2*frm_fieldno_size > end)
1473 return 1;
1474 period->start_fieldno= read_frm_fieldno(data);
1475 period->end_fieldno= read_frm_fieldno(data + frm_fieldno_size);
1476 return period->start_fieldno >= fields || period->end_fieldno >= fields;
1477 }
1478
1479
extra2_read_len(const uchar ** extra2,const uchar * extra2_end)1480 static size_t extra2_read_len(const uchar **extra2, const uchar *extra2_end)
1481 {
1482 size_t length= *(*extra2)++;
1483 if (length)
1484 return length;
1485
1486 if ((*extra2) + 2 >= extra2_end)
1487 return 0;
1488 length= uint2korr(*extra2);
1489 (*extra2)+= 2;
1490 if (length < 256 || *extra2 + length > extra2_end)
1491 return 0;
1492 return length;
1493 }
1494
1495
1496 static
read_extra2(const uchar * frm_image,size_t len,extra2_fields * fields)1497 bool read_extra2(const uchar *frm_image, size_t len, extra2_fields *fields)
1498 {
1499 const uchar *extra2= frm_image + 64;
1500
1501 DBUG_ENTER("read_extra2");
1502
1503 fields->reset();
1504
1505 if (*extra2 != '/') // old frm had '/' there
1506 {
1507 const uchar *e2end= extra2 + len;
1508 while (extra2 + 3 <= e2end)
1509 {
1510 extra2_frm_value_type type= (extra2_frm_value_type)*extra2++;
1511 size_t length= extra2_read_len(&extra2, e2end);
1512 if (!length)
1513 DBUG_RETURN(true);
1514 switch (type) {
1515 case EXTRA2_TABLEDEF_VERSION:
1516 if (fields->version.str) // see init_from_sql_statement_string()
1517 {
1518 if (length != fields->version.length)
1519 DBUG_RETURN(true);
1520 }
1521 else
1522 {
1523 fields->version.str= extra2;
1524 fields->version.length= length;
1525 }
1526 break;
1527 case EXTRA2_ENGINE_TABLEOPTS:
1528 if (fields->options.str)
1529 DBUG_RETURN(true);
1530 fields->options.str= extra2;
1531 fields->options.length= length;
1532 break;
1533 case EXTRA2_DEFAULT_PART_ENGINE:
1534 fields->engine.set((const char*)extra2, length);
1535 break;
1536 case EXTRA2_GIS:
1537 if (fields->gis.str)
1538 DBUG_RETURN(true);
1539 fields->gis.str= extra2;
1540 fields->gis.length= length;
1541 break;
1542 case EXTRA2_PERIOD_FOR_SYSTEM_TIME:
1543 if (fields->system_period.str || length != 2 * frm_fieldno_size)
1544 DBUG_RETURN(true);
1545 fields->system_period.str = extra2;
1546 fields->system_period.length= length;
1547 break;
1548 case EXTRA2_FIELD_FLAGS:
1549 if (fields->field_flags.str)
1550 DBUG_RETURN(true);
1551 fields->field_flags.str= extra2;
1552 fields->field_flags.length= length;
1553 break;
1554 case EXTRA2_APPLICATION_TIME_PERIOD:
1555 if (fields->application_period.str)
1556 DBUG_RETURN(true);
1557 fields->application_period.str= extra2;
1558 fields->application_period.length= length;
1559 break;
1560 default:
1561 /* abort frm parsing if it's an unknown but important extra2 value */
1562 if (type >= EXTRA2_ENGINE_IMPORTANT)
1563 DBUG_RETURN(true);
1564 }
1565 extra2+= length;
1566 }
1567 if (extra2 != e2end)
1568 DBUG_RETURN(true);
1569 }
1570 DBUG_RETURN(false);
1571 }
1572
1573
1574 /**
1575 Read data from a binary .frm file image into a TABLE_SHARE
1576
1577 @note
1578 frm bytes at the following offsets are unused in MariaDB 10.0:
1579
1580 8..9 (used to be the number of "form names")
1581 28..29 (used to be key_info_length)
1582
1583 They're still set, for compatibility reasons, but never read.
1584
1585 42..46 are unused since 5.0 (were for RAID support)
1586 Also, there're few unused bytes in forminfo.
1587
1588 */
1589
init_from_binary_frm_image(THD * thd,bool write,const uchar * frm_image,size_t frm_length)1590 int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
1591 const uchar *frm_image,
1592 size_t frm_length)
1593 {
1594 TABLE_SHARE *share= this;
1595 uint new_frm_ver, field_pack_length, new_field_pack_flag;
1596 uint interval_count, interval_parts, read_length, int_length;
1597 uint total_typelib_value_count;
1598 uint db_create_options, keys, key_parts, n_length;
1599 uint com_length, null_bit_pos, UNINIT_VAR(mysql57_vcol_null_bit_pos), bitmap_count;
1600 uint i, hash_fields= 0;
1601 bool use_hash, mysql57_null_bits= 0;
1602 LEX_STRING keynames= {NULL, 0};
1603 char *names, *comment_pos;
1604 const uchar *forminfo;
1605 const uchar *frm_image_end = frm_image + frm_length;
1606 uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos);
1607 const uchar *disk_buff, *strpos;
1608 ulong pos, record_offset;
1609 ulong rec_buff_length;
1610 handler *handler_file= 0;
1611 KEY *keyinfo;
1612 KEY_PART_INFO *key_part= NULL;
1613 Field **field_ptr, *reg_field;
1614 const char **interval_array;
1615 uint *typelib_value_lengths= NULL;
1616 enum legacy_db_type legacy_db_type;
1617 my_bitmap_map *bitmaps;
1618 bool null_bits_are_used;
1619 uint vcol_screen_length;
1620 uchar *vcol_screen_pos;
1621 LEX_CUSTRING options;
1622 KEY first_keyinfo;
1623 uint len;
1624 uint ext_key_parts= 0;
1625 plugin_ref se_plugin= 0;
1626 bool vers_can_native= false;
1627
1628 MEM_ROOT *old_root= thd->mem_root;
1629 Virtual_column_info **table_check_constraints;
1630 extra2_fields extra2;
1631
1632 DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
1633
1634 keyinfo= &first_keyinfo;
1635 thd->mem_root= &share->mem_root;
1636
1637 if (write && write_frm_image(frm_image, frm_length))
1638 goto err;
1639
1640 if (frm_length < FRM_HEADER_SIZE + FRM_FORMINFO_SIZE)
1641 goto err;
1642
1643 share->frm_version= frm_image[2];
1644 /*
1645 Check if .frm file created by MySQL 5.0. In this case we want to
1646 display CHAR fields as CHAR and not as VARCHAR.
1647 We do it this way as we want to keep the old frm version to enable
1648 MySQL 4.1 to read these files.
1649 */
1650 if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && frm_image[33] == 5)
1651 share->frm_version= FRM_VER_TRUE_VARCHAR;
1652
1653 new_field_pack_flag= frm_image[27];
1654 new_frm_ver= (frm_image[2] - FRM_VER);
1655 field_pack_length= new_frm_ver < 2 ? 11 : 17;
1656
1657 /* Length of the MariaDB extra2 segment in the form file. */
1658 len = uint2korr(frm_image+4);
1659
1660 if (read_extra2(frm_image, len, &extra2))
1661 goto err;
1662
1663 tabledef_version.length= extra2.version.length;
1664 tabledef_version.str= (uchar*)memdup_root(&mem_root, extra2.version.str,
1665 extra2.version.length);
1666 if (!tabledef_version.str)
1667 goto err;
1668
1669 /* remember but delay parsing until we have read fields and keys */
1670 options= extra2.options;
1671
1672 #ifdef WITH_PARTITION_STORAGE_ENGINE
1673 if (extra2.engine)
1674 {
1675 share->default_part_plugin= ha_resolve_by_name(NULL, &extra2.engine, false);
1676 if (!share->default_part_plugin)
1677 goto err;
1678 }
1679 #endif
1680
1681 if (frm_length < FRM_HEADER_SIZE + len ||
1682 !(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len)))
1683 goto err;
1684
1685 forminfo= frm_image + pos;
1686 if (forminfo + FRM_FORMINFO_SIZE >= frm_image_end)
1687 goto err;
1688
1689 #ifdef WITH_PARTITION_STORAGE_ENGINE
1690 if (frm_image[61] && !share->default_part_plugin)
1691 {
1692 enum legacy_db_type db_type= (enum legacy_db_type) (uint) frm_image[61];
1693 share->default_part_plugin= ha_lock_engine(NULL, ha_checktype(thd, db_type));
1694 if (!share->default_part_plugin)
1695 goto err;
1696 }
1697 #endif
1698 legacy_db_type= (enum legacy_db_type) (uint) frm_image[3];
1699 /*
1700 if the storage engine is dynamic, no point in resolving it by its
1701 dynamically allocated legacy_db_type. We will resolve it later by name.
1702 */
1703 if (legacy_db_type > DB_TYPE_UNKNOWN &&
1704 legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
1705 se_plugin= ha_lock_engine(NULL, ha_checktype(thd, legacy_db_type));
1706 share->db_create_options= db_create_options= uint2korr(frm_image+30);
1707 share->db_options_in_use= share->db_create_options;
1708 share->mysql_version= uint4korr(frm_image+51);
1709 share->table_type= TABLE_TYPE_NORMAL;
1710 share->null_field_first= 0;
1711 if (!frm_image[32]) // New frm file in 3.23
1712 {
1713 uint cs_org= (((uint) frm_image[41]) << 8) + (uint) frm_image[38];
1714 uint cs_new= upgrade_collation(share->mysql_version, cs_org);
1715 if (cs_org != cs_new)
1716 share->incompatible_version|= HA_CREATE_USED_CHARSET;
1717
1718 share->avg_row_length= uint4korr(frm_image+34);
1719 share->transactional= (ha_choice)
1720 enum_value_with_check(thd, share, "transactional", frm_image[39] & 3, HA_CHOICE_MAX);
1721 share->page_checksum= (ha_choice)
1722 enum_value_with_check(thd, share, "page_checksum", (frm_image[39] >> 2) & 3, HA_CHOICE_MAX);
1723 if (((ha_choice) enum_value_with_check(thd, share, "sequence",
1724 (frm_image[39] >> 4) & 3,
1725 HA_CHOICE_MAX)) == HA_CHOICE_YES)
1726 {
1727 share->table_type= TABLE_TYPE_SEQUENCE;
1728 share->sequence= new (&share->mem_root) SEQUENCE();
1729 share->non_determinstic_insert= true;
1730 }
1731 share->row_type= (enum row_type)
1732 enum_value_with_check(thd, share, "row_format", frm_image[40], ROW_TYPE_MAX);
1733
1734 if (cs_new && !(share->table_charset= get_charset(cs_new, MYF(MY_WME))))
1735 goto err;
1736 share->null_field_first= 1;
1737 share->stats_sample_pages= uint2korr(frm_image+42);
1738 share->stats_auto_recalc= (enum_stats_auto_recalc)(frm_image[44]);
1739 share->table_check_constraints= uint2korr(frm_image+45);
1740 }
1741 if (!share->table_charset)
1742 {
1743 const CHARSET_INFO *cs= thd->variables.collation_database;
1744 /* unknown charset in frm_image[38] or pre-3.23 frm */
1745 if (use_mb(cs))
1746 {
1747 /* Warn that we may be changing the size of character columns */
1748 sql_print_warning("'%s' had no or invalid character set, "
1749 "and default character set is multi-byte, "
1750 "so character column sizes may have changed",
1751 share->path.str);
1752 }
1753 share->table_charset= cs;
1754 }
1755
1756 share->db_record_offset= 1;
1757 share->max_rows= uint4korr(frm_image+18);
1758 share->min_rows= uint4korr(frm_image+22);
1759
1760 /* Read keyinformation */
1761 disk_buff= frm_image + uint2korr(frm_image+6);
1762
1763 if (disk_buff + 6 >= frm_image_end)
1764 goto err;
1765
1766 if (disk_buff[0] & 0x80)
1767 {
1768 keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
1769 share->key_parts= key_parts= uint2korr(disk_buff+2);
1770 }
1771 else
1772 {
1773 keys= disk_buff[0];
1774 share->key_parts= key_parts= disk_buff[1];
1775 }
1776 share->keys_for_keyread.init(0);
1777 share->keys_in_use.init(keys);
1778 ext_key_parts= key_parts;
1779
1780 len= (uint) uint2korr(disk_buff+4);
1781
1782 share->reclength = uint2korr(frm_image+16);
1783 share->stored_rec_length= share->reclength;
1784 if (frm_image[26] == 1)
1785 share->system= 1; /* one-record-database */
1786
1787 record_offset= (ulong) (uint2korr(frm_image+6)+
1788 ((uint2korr(frm_image+14) == 0xffff ?
1789 uint4korr(frm_image+47) : uint2korr(frm_image+14))));
1790
1791 if (record_offset + share->reclength >= frm_length)
1792 goto err;
1793
1794 if ((n_length= uint4korr(frm_image+55)))
1795 {
1796 /* Read extra data segment */
1797 const uchar *next_chunk, *buff_end;
1798 DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
1799 next_chunk= frm_image + record_offset + share->reclength;
1800 buff_end= next_chunk + n_length;
1801
1802 if (buff_end >= frm_image_end)
1803 goto err;
1804
1805 share->connect_string.length= uint2korr(next_chunk);
1806 if (!(share->connect_string.str= strmake_root(&share->mem_root,
1807 (char*) next_chunk + 2,
1808 share->connect_string.
1809 length)))
1810 {
1811 goto err;
1812 }
1813 next_chunk+= share->connect_string.length + 2;
1814 if (next_chunk + 2 < buff_end)
1815 {
1816 uint str_db_type_length= uint2korr(next_chunk);
1817 LEX_CSTRING name;
1818 name.str= (char*) next_chunk + 2;
1819 name.length= str_db_type_length;
1820
1821 plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name, false);
1822 if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, se_plugin))
1823 {
1824 if (se_plugin)
1825 {
1826 /* bad file, legacy_db_type did not match the name */
1827 sql_print_warning("%s.frm is inconsistent: engine typecode %d, engine name %s (%d)",
1828 share->normalized_path.str, legacy_db_type,
1829 plugin_name(tmp_plugin)->str,
1830 ha_legacy_type(plugin_data(tmp_plugin, handlerton *)));
1831 }
1832 /*
1833 tmp_plugin is locked with a local lock.
1834 we unlock the old value of se_plugin before
1835 replacing it with a globally locked version of tmp_plugin
1836 */
1837 plugin_unlock(NULL, se_plugin);
1838 se_plugin= plugin_lock(NULL, tmp_plugin);
1839 }
1840 #ifdef WITH_PARTITION_STORAGE_ENGINE
1841 else if (str_db_type_length == 9 &&
1842 !strncmp((char *) next_chunk + 2, "partition", 9))
1843 {
1844 /*
1845 Use partition handler
1846 tmp_plugin is locked with a local lock.
1847 we unlock the old value of se_plugin before
1848 replacing it with a globally locked version of tmp_plugin
1849 */
1850 /* Check if the partitioning engine is ready */
1851 if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
1852 {
1853 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
1854 "--skip-partition");
1855 goto err;
1856 }
1857 plugin_unlock(NULL, se_plugin);
1858 se_plugin= ha_lock_engine(NULL, partition_hton);
1859 }
1860 #endif
1861 else if (!tmp_plugin)
1862 {
1863 /* purecov: begin inspected */
1864 ((char*) name.str)[name.length]=0;
1865 my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
1866 goto err;
1867 /* purecov: end */
1868 }
1869 next_chunk+= str_db_type_length + 2;
1870 }
1871
1872 share->set_use_ext_keys_flag(plugin_hton(se_plugin)->flags & HTON_SUPPORTS_EXTENDED_KEYS);
1873
1874 if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
1875 new_frm_ver, &ext_key_parts,
1876 share, len, &first_keyinfo, &keynames))
1877 goto err;
1878
1879 if (next_chunk + 5 < buff_end)
1880 {
1881 uint32 partition_info_str_len = uint4korr(next_chunk);
1882 #ifdef WITH_PARTITION_STORAGE_ENGINE
1883 if ((share->partition_info_buffer_size=
1884 share->partition_info_str_len= partition_info_str_len))
1885 {
1886 if (!(share->partition_info_str= (char*)
1887 memdup_root(&share->mem_root, next_chunk + 4,
1888 partition_info_str_len + 1)))
1889 {
1890 goto err;
1891 }
1892 }
1893 #else
1894 if (partition_info_str_len)
1895 {
1896 DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
1897 goto err;
1898 }
1899 #endif
1900 next_chunk+= 5 + partition_info_str_len;
1901 }
1902 if (share->mysql_version >= 50110 && next_chunk < buff_end)
1903 {
1904 /* New auto_partitioned indicator introduced in 5.1.11 */
1905 #ifdef WITH_PARTITION_STORAGE_ENGINE
1906 share->auto_partitioned= *next_chunk;
1907 #endif
1908 next_chunk++;
1909 }
1910 keyinfo= share->key_info;
1911 for (i= 0; i < keys; i++, keyinfo++)
1912 {
1913 if (keyinfo->flags & HA_USES_PARSER)
1914 {
1915 LEX_CSTRING parser_name;
1916 if (next_chunk >= buff_end)
1917 {
1918 DBUG_PRINT("error",
1919 ("fulltext key uses parser that is not defined in .frm"));
1920 goto err;
1921 }
1922 parser_name.str= (char*) next_chunk;
1923 parser_name.length= strlen((char*) next_chunk);
1924 next_chunk+= parser_name.length + 1;
1925 keyinfo->parser= my_plugin_lock_by_name(NULL, &parser_name,
1926 MYSQL_FTPARSER_PLUGIN);
1927 if (! keyinfo->parser)
1928 {
1929 my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
1930 goto err;
1931 }
1932 }
1933 }
1934
1935 if (forminfo[46] == (uchar)255)
1936 {
1937 //reading long table comment
1938 if (next_chunk + 2 > buff_end)
1939 {
1940 DBUG_PRINT("error",
1941 ("long table comment is not defined in .frm"));
1942 goto err;
1943 }
1944 share->comment.length = uint2korr(next_chunk);
1945 if (! (share->comment.str= strmake_root(&share->mem_root,
1946 (char*)next_chunk + 2, share->comment.length)))
1947 {
1948 goto err;
1949 }
1950 next_chunk+= 2 + share->comment.length;
1951 }
1952
1953 DBUG_ASSERT(next_chunk <= buff_end);
1954
1955 if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS_legacy)
1956 {
1957 if (options.str)
1958 goto err;
1959 options.length= uint4korr(next_chunk);
1960 options.str= next_chunk + 4;
1961 next_chunk+= options.length + 4;
1962 }
1963 DBUG_ASSERT(next_chunk <= buff_end);
1964 }
1965 else
1966 {
1967 if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
1968 new_frm_ver, &ext_key_parts,
1969 share, len, &first_keyinfo, &keynames))
1970 goto err;
1971 }
1972 share->key_block_size= uint2korr(frm_image+62);
1973 keyinfo= share->key_info;
1974 for (uint i= 0; i < share->keys; i++, keyinfo++)
1975 if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
1976 hash_fields++;
1977
1978 if (share->db_plugin && !plugin_equals(share->db_plugin, se_plugin))
1979 goto err; // wrong engine (someone changed the frm under our feet?)
1980
1981 rec_buff_length= ALIGN_SIZE(share->reclength + 1);
1982 share->rec_buff_length= rec_buff_length;
1983 if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length)))
1984 goto err; /* purecov: inspected */
1985 /* Mark bytes after record as not accessable to catch overrun bugs */
1986 MEM_NOACCESS(record + share->reclength, rec_buff_length - share->reclength);
1987 share->default_values= record;
1988 memcpy(record, frm_image + record_offset, share->reclength);
1989
1990 disk_buff= frm_image + pos + FRM_FORMINFO_SIZE;
1991 share->fields= uint2korr(forminfo+258);
1992 if (extra2.field_flags.str && extra2.field_flags.length != share->fields)
1993 goto err;
1994 pos= uint2korr(forminfo+260); /* Length of all screens */
1995 n_length= uint2korr(forminfo+268);
1996 interval_count= uint2korr(forminfo+270);
1997 interval_parts= uint2korr(forminfo+272);
1998 int_length= uint2korr(forminfo+274);
1999 share->null_fields= uint2korr(forminfo+282);
2000 com_length= uint2korr(forminfo+284);
2001 vcol_screen_length= uint2korr(forminfo+286);
2002 share->virtual_fields= share->default_expressions=
2003 share->field_check_constraints= share->default_fields= 0;
2004 share->visible_fields= 0;
2005 share->stored_fields= share->fields;
2006 if (forminfo[46] != (uchar)255)
2007 {
2008 share->comment.length= (int) (forminfo[46]);
2009 share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
2010 share->comment.length);
2011 }
2012
2013 DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length));
2014
2015 /*
2016 We load the following things into TYPELIBs:
2017 - One TYPELIB for field names
2018 - interval_count TYPELIBs for ENUM/SET values
2019 - One TYPELIB for key names
2020 Every TYPELIB requires one extra value with a NULL pointer and zero length,
2021 which is the end-of-values marker.
2022 TODO-10.5+:
2023 Note, we should eventually reuse this total_typelib_value_count
2024 to allocate interval_array. The below code reserves less space
2025 than total_typelib_value_count pointers. So it seems `interval_array`
2026 and `names` overlap in the memory. Too dangerous to fix in 10.1.
2027 */
2028 total_typelib_value_count=
2029 (share->fields + 1/*end-of-values marker*/) +
2030 (interval_parts + interval_count/*end-of-values markers*/) +
2031 (keys + 1/*end-of-values marker*/);
2032
2033 if (!multi_alloc_root(&share->mem_root,
2034 &share->field, (uint)(share->fields+1)*sizeof(Field*),
2035 &share->intervals, (uint)interval_count*sizeof(TYPELIB),
2036 &share->check_constraints, (uint) share->table_check_constraints * sizeof(Virtual_column_info*),
2037 /*
2038 This looks wrong: shouldn't it be (+2+interval_count)
2039 instread of (+3) ?
2040 */
2041 &interval_array, (uint) (share->fields+interval_parts+ keys+3)*sizeof(char *),
2042 &typelib_value_lengths, total_typelib_value_count * sizeof(uint *),
2043 &names, (uint) (n_length+int_length),
2044 &comment_pos, (uint) com_length,
2045 &vcol_screen_pos, vcol_screen_length,
2046 NullS))
2047
2048 goto err;
2049
2050 field_ptr= share->field;
2051 table_check_constraints= share->check_constraints;
2052 read_length=(uint) (share->fields * field_pack_length +
2053 pos+ (uint) (n_length+int_length+com_length+
2054 vcol_screen_length));
2055 strpos= disk_buff+pos;
2056
2057 if (!interval_count)
2058 share->intervals= 0; // For better debugging
2059
2060 share->vcol_defs.str= vcol_screen_pos;
2061 share->vcol_defs.length= vcol_screen_length;
2062
2063 memcpy(names, strpos+(share->fields*field_pack_length), n_length+int_length);
2064 memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length,
2065 com_length);
2066 memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length,
2067 vcol_screen_length);
2068
2069 if (fix_type_pointers(&interval_array, &typelib_value_lengths,
2070 &share->fieldnames, 1, names, n_length) ||
2071 share->fieldnames.count != share->fields)
2072 goto err;
2073
2074 if (fix_type_pointers(&interval_array, &typelib_value_lengths,
2075 share->intervals, interval_count,
2076 names + n_length, int_length))
2077 goto err;
2078
2079 if (keynames.length &&
2080 (fix_type_pointers(&interval_array, &typelib_value_lengths,
2081 &share->keynames, 1, keynames.str, keynames.length) ||
2082 share->keynames.count != keys))
2083 goto err;
2084
2085 /* Allocate handler */
2086 if (!(handler_file= get_new_handler(share, thd->mem_root,
2087 plugin_hton(se_plugin))))
2088 goto err;
2089
2090 if (handler_file->set_ha_share_ref(&share->ha_share))
2091 goto err;
2092
2093 record= share->default_values-1; /* Fieldstart = 1 */
2094 null_bits_are_used= share->null_fields != 0;
2095 if (share->null_field_first)
2096 {
2097 null_flags= null_pos= record+1;
2098 null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
2099 /*
2100 null_bytes below is only correct under the condition that
2101 there are no bit fields. Correct values is set below after the
2102 table struct is initialized
2103 */
2104 share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
2105 }
2106 #ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES
2107 else
2108 {
2109 share->null_bytes= (share->null_fields+7)/8;
2110 null_flags= null_pos= record + 1 + share->reclength - share->null_bytes;
2111 null_bit_pos= 0;
2112 }
2113 #endif
2114
2115 use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
2116 if (use_hash)
2117 use_hash= !my_hash_init(&share->name_hash,
2118 system_charset_info,
2119 share->fields,0,0,
2120 (my_hash_get_key) get_field_name,0,0);
2121
2122 if (share->mysql_version >= 50700 && share->mysql_version < 100000 &&
2123 vcol_screen_length)
2124 {
2125 /*
2126 MySQL 5.7 stores the null bits for not stored fields last.
2127 Calculate the position for them.
2128 */
2129 mysql57_null_bits= 1;
2130 mysql57_vcol_null_pos= null_pos;
2131 mysql57_vcol_null_bit_pos= null_bit_pos;
2132 mysql57_calculate_null_position(share, &mysql57_vcol_null_pos,
2133 &mysql57_vcol_null_bit_pos,
2134 strpos, vcol_screen_pos);
2135 }
2136
2137 /* Set system versioning information. */
2138 vers.name= Lex_ident(STRING_WITH_LEN("SYSTEM_TIME"));
2139 if (extra2.system_period.str == NULL)
2140 {
2141 versioned= VERS_UNDEFINED;
2142 vers.start_fieldno= 0;
2143 vers.end_fieldno= 0;
2144 }
2145 else
2146 {
2147 DBUG_PRINT("info", ("Setting system versioning informations"));
2148 if (init_period_from_extra2(&vers, extra2.system_period.str,
2149 extra2.system_period.str + extra2.system_period.length))
2150 goto err;
2151 DBUG_PRINT("info", ("Columns with system versioning: [%d, %d]",
2152 vers.start_fieldno, vers.end_fieldno));
2153 versioned= VERS_TIMESTAMP;
2154 vers_can_native= handler_file->vers_can_native(thd);
2155 status_var_increment(thd->status_var.feature_system_versioning);
2156 } // if (system_period == NULL)
2157
2158 if (extra2.application_period.str)
2159 {
2160 const uchar *pos= extra2.application_period.str;
2161 const uchar *end= pos + extra2.application_period.length;
2162 period.name.length= extra2_read_len(&pos, end);
2163 period.name.str= strmake_root(&mem_root, (char*)pos, period.name.length);
2164 pos+= period.name.length;
2165
2166 period.constr_name.length= extra2_read_len(&pos, end);
2167 period.constr_name.str= strmake_root(&mem_root, (char*)pos,
2168 period.constr_name.length);
2169 pos+= period.constr_name.length;
2170
2171 if (init_period_from_extra2(&period, pos, end))
2172 goto err;
2173 status_var_increment(thd->status_var.feature_application_time_periods);
2174 }
2175
2176 for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
2177 {
2178 uint interval_nr= 0, recpos;
2179 LEX_CSTRING comment;
2180 LEX_CSTRING name;
2181 Virtual_column_info *vcol_info= 0;
2182 const Type_handler *handler;
2183 uint32 flags= 0;
2184 Column_definition_attributes attr;
2185
2186 if (new_frm_ver >= 3)
2187 {
2188 /* new frm file in 4.1 */
2189 recpos= uint3korr(strpos+5);
2190 uint comment_length=uint2korr(strpos+15);
2191
2192 if (!comment_length)
2193 {
2194 comment.str= (char*) "";
2195 comment.length=0;
2196 }
2197 else
2198 {
2199 comment.str= (char*) comment_pos;
2200 comment.length= comment_length;
2201 comment_pos+= comment_length;
2202 }
2203
2204 if ((uchar) strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL)
2205 {
2206 /*
2207 MariaDB version 10.0 version.
2208 The interval_id byte in the .frm file stores the length of the
2209 expression statement for a virtual column.
2210 */
2211 uint vcol_info_length= (uint) strpos[12];
2212
2213 if (!vcol_info_length) // Expect non-null expression
2214 goto err;
2215
2216 attr.frm_unpack_basic(strpos);
2217 if (attr.frm_unpack_charset(share, strpos))
2218 goto err;
2219 /*
2220 Old virtual field information before 10.2
2221
2222 Get virtual column data stored in the .frm file as follows:
2223 byte 1 = 1 | 2
2224 byte 2 = sql_type
2225 byte 3 = flags. 1 for stored_in_db
2226 [byte 4] = optional interval_id for sql_type (if byte 1 == 2)
2227 next byte ... = virtual column expression (text data)
2228 */
2229
2230 vcol_info= new (&share->mem_root) Virtual_column_info();
2231 bool opt_interval_id= (uint)vcol_screen_pos[0] == 2;
2232 enum_field_types ftype= (enum_field_types) (uchar) vcol_screen_pos[1];
2233 if (!(handler= Type_handler::get_handler_by_real_type(ftype)))
2234 goto err;
2235 if (opt_interval_id)
2236 interval_nr= (uint)vcol_screen_pos[3];
2237 else if ((uint)vcol_screen_pos[0] != 1)
2238 goto err;
2239 bool stored= vcol_screen_pos[2] & 1;
2240 vcol_info->stored_in_db= stored;
2241 vcol_info->set_vcol_type(stored ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL);
2242 uint vcol_expr_length= vcol_info_length -
2243 (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
2244 vcol_info->utf8= 0; // before 10.2.1 the charset was unknown
2245 int2store(vcol_screen_pos+1, vcol_expr_length); // for parse_vcol_defs()
2246 vcol_screen_pos+= vcol_info_length;
2247 share->virtual_fields++;
2248 }
2249 else
2250 {
2251 interval_nr= (uint) strpos[12];
2252 enum_field_types field_type= (enum_field_types) strpos[13];
2253 if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
2254 goto err; // Not supported field type
2255 if (handler->Column_definition_attributes_frm_unpack(&attr, share,
2256 strpos,
2257 &extra2.gis))
2258 goto err;
2259 }
2260
2261 if (((uint) strpos[10]) & MYSQL57_GENERATED_FIELD)
2262 {
2263 attr.unireg_check= Field::NONE;
2264
2265 /*
2266 MySQL 5.7 generated fields
2267
2268 byte 1 = 1
2269 byte 2,3 = expr length
2270 byte 4 = stored_in_db
2271 byte 5.. = expr
2272 */
2273 if ((uint)(vcol_screen_pos)[0] != 1)
2274 goto err;
2275 vcol_info= new (&share->mem_root) Virtual_column_info();
2276 uint vcol_info_length= uint2korr(vcol_screen_pos + 1);
2277 if (!vcol_info_length) // Expect non-empty expression
2278 goto err;
2279 vcol_info->stored_in_db= vcol_screen_pos[3];
2280 vcol_info->utf8= 0;
2281 vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;;
2282 share->virtual_fields++;
2283 }
2284 }
2285 else
2286 {
2287 attr.length= (uint) strpos[3];
2288 recpos= uint2korr(strpos+4),
2289 attr.pack_flag= uint2korr(strpos+6);
2290 attr.pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
2291 attr.unireg_check= (Field::utype) MTYP_TYPENR((uint) strpos[8]);
2292 interval_nr= (uint) strpos[10];
2293
2294 /* old frm file */
2295 enum_field_types ftype= (enum_field_types) f_packtype(attr.pack_flag);
2296 if (!(handler= Type_handler::get_handler_by_real_type(ftype)))
2297 goto err; // Not supported field type
2298
2299 if (f_is_binary(attr.pack_flag))
2300 {
2301 /*
2302 Try to choose the best 4.1 type:
2303 - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
2304 try to find a binary collation for character set.
2305 - for other types (e.g. BLOB) just use my_charset_bin.
2306 */
2307 if (!f_is_blob(attr.pack_flag))
2308 {
2309 // 3.23 or 4.0 string
2310 if (!(attr.charset= get_charset_by_csname(share->table_charset->csname,
2311 MY_CS_BINSORT, MYF(0))))
2312 attr.charset= &my_charset_bin;
2313 }
2314 }
2315 else
2316 attr.charset= share->table_charset;
2317 bzero((char*) &comment, sizeof(comment));
2318 if ((!(handler= old_frm_type_handler(attr.pack_flag, interval_nr))))
2319 goto err; // Not supported field type
2320 }
2321
2322 /* Remove >32 decimals from old files */
2323 if (share->mysql_version < 100200)
2324 attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
2325
2326 if (interval_nr && attr.charset->mbminlen > 1)
2327 {
2328 /* Unescape UCS2 intervals from HEX notation */
2329 TYPELIB *interval= share->intervals + interval_nr - 1;
2330 unhex_type2(interval);
2331 }
2332
2333 #ifndef TO_BE_DELETED_ON_PRODUCTION
2334 if (handler->real_field_type() == MYSQL_TYPE_NEWDECIMAL &&
2335 !share->mysql_version)
2336 {
2337 /*
2338 Fix pack length of old decimal values from 5.0.3 -> 5.0.4
2339 The difference is that in the old version we stored precision
2340 in the .frm table while we now store the display_length
2341 */
2342 uint decimals= f_decimals(attr.pack_flag);
2343 attr.length=
2344 my_decimal_precision_to_length((uint) attr.length, decimals,
2345 f_is_dec(attr.pack_flag) == 0);
2346 sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
2347 "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
2348 share->fieldnames.type_names[i], share->table_name.str,
2349 share->table_name.str);
2350 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
2351 ER_CRASHED_ON_USAGE,
2352 "Found incompatible DECIMAL field '%s' in %s; "
2353 "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
2354 share->fieldnames.type_names[i],
2355 share->table_name.str,
2356 share->table_name.str);
2357 share->crashed= 1; // Marker for CHECK TABLE
2358 }
2359 #endif
2360
2361 if (mysql57_null_bits && vcol_info && !vcol_info->stored_in_db)
2362 {
2363 swap_variables(uchar*, null_pos, mysql57_vcol_null_pos);
2364 swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos);
2365 }
2366
2367 if (versioned)
2368 {
2369 if (i == vers.start_fieldno)
2370 flags|= VERS_ROW_START;
2371 else if (i == vers.end_fieldno)
2372 flags|= VERS_ROW_END;
2373
2374 if (flags & VERS_SYSTEM_FIELD)
2375 {
2376 switch (handler->real_field_type())
2377 {
2378 case MYSQL_TYPE_TIMESTAMP2:
2379 break;
2380 case MYSQL_TYPE_LONGLONG:
2381 if (vers_can_native)
2382 {
2383 versioned= VERS_TRX_ID;
2384 break;
2385 }
2386 /* Fallthrough */
2387 default:
2388 my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), fieldnames.type_names[i],
2389 versioned == VERS_TIMESTAMP ? "TIMESTAMP(6)" : "BIGINT(20) UNSIGNED",
2390 table_name.str);
2391 goto err;
2392 }
2393 }
2394 }
2395
2396 /* Convert pre-10.2.2 timestamps to use Field::default_value */
2397 name.str= fieldnames.type_names[i];
2398 name.length= strlen(name.str);
2399 attr.interval= interval_nr ? share->intervals + interval_nr - 1 : NULL;
2400 Record_addr addr(record + recpos, null_pos, null_bit_pos);
2401 *field_ptr= reg_field=
2402 attr.make_field(share, &share->mem_root, &addr, handler, &name, flags);
2403 if (!reg_field) // Not supported field type
2404 goto err;
2405
2406 if (attr.unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
2407 attr.unireg_check == Field::TIMESTAMP_DN_FIELD)
2408 {
2409 reg_field->default_value= new (&share->mem_root) Virtual_column_info();
2410 reg_field->default_value->set_vcol_type(VCOL_DEFAULT);
2411 reg_field->default_value->stored_in_db= 1;
2412 share->default_expressions++;
2413 }
2414
2415 reg_field->field_index= i;
2416 reg_field->comment=comment;
2417 reg_field->vcol_info= vcol_info;
2418 reg_field->flags|= flags;
2419 if (extra2.field_flags.str)
2420 {
2421 uchar flags= *extra2.field_flags.str++;
2422 if (flags & VERS_OPTIMIZED_UPDATE)
2423 reg_field->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
2424
2425 reg_field->invisible= f_visibility(flags);
2426 }
2427 if (reg_field->invisible == INVISIBLE_USER)
2428 status_var_increment(thd->status_var.feature_invisible_columns);
2429 if (!reg_field->invisible)
2430 share->visible_fields++;
2431 if (handler->real_field_type() == MYSQL_TYPE_BIT &&
2432 !f_bit_as_char(attr.pack_flag))
2433 {
2434 null_bits_are_used= 1;
2435 if ((null_bit_pos+= (uint) (attr.length & 7)) > 7)
2436 {
2437 null_pos++;
2438 null_bit_pos-= 8;
2439 }
2440 }
2441 if (!(reg_field->flags & NOT_NULL_FLAG))
2442 {
2443 if (!(null_bit_pos= (null_bit_pos + 1) & 7))
2444 null_pos++;
2445 }
2446
2447 if (vcol_info)
2448 {
2449 vcol_info->name= reg_field->field_name;
2450 if (mysql57_null_bits && !vcol_info->stored_in_db)
2451 {
2452 /* MySQL 5.7 has null bits last */
2453 swap_variables(uchar*, null_pos, mysql57_vcol_null_pos);
2454 swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos);
2455 }
2456 }
2457
2458 if (f_no_default(attr.pack_flag))
2459 reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
2460
2461 if (reg_field->unireg_check == Field::NEXT_NUMBER)
2462 share->found_next_number_field= field_ptr;
2463
2464 if (use_hash && my_hash_insert(&share->name_hash, (uchar*) field_ptr))
2465 goto err;
2466 if (!reg_field->stored_in_db())
2467 {
2468 share->stored_fields--;
2469 if (share->stored_rec_length>=recpos)
2470 share->stored_rec_length= recpos-1;
2471 }
2472 if (reg_field->has_update_default_function())
2473 {
2474 has_update_default_function= 1;
2475 if (!reg_field->default_value)
2476 share->default_fields++;
2477 }
2478 }
2479 *field_ptr=0; // End marker
2480 /* Sanity checks: */
2481 DBUG_ASSERT(share->fields>=share->stored_fields);
2482 DBUG_ASSERT(share->reclength>=share->stored_rec_length);
2483
2484 if (mysql57_null_bits)
2485 {
2486 /* We want to store the value for the last bits */
2487 swap_variables(uchar*, null_pos, mysql57_vcol_null_pos);
2488 swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos);
2489 DBUG_ASSERT((null_pos + (null_bit_pos + 7) / 8) <= share->field[0]->ptr);
2490 }
2491
2492 /* Fix key->name and key_part->field */
2493 if (key_parts)
2494 {
2495 keyinfo= share->key_info;
2496 uint hash_field_used_no= share->fields - hash_fields;
2497 KEY_PART_INFO *hash_keypart;
2498 Field *hash_field;
2499 uint offset= share->reclength - HA_HASH_FIELD_LENGTH * hash_fields;
2500 for (uint i= 0; i < share->keys; i++, keyinfo++)
2501 {
2502 /* We need set value in hash key_part */
2503 if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
2504 {
2505 share->long_unique_table= 1;
2506 hash_keypart= keyinfo->key_part + keyinfo->user_defined_key_parts;
2507 hash_keypart->length= HA_HASH_KEY_LENGTH_WITHOUT_NULL;
2508 hash_keypart->store_length= hash_keypart->length;
2509 hash_keypart->type= HA_KEYTYPE_ULONGLONG;
2510 hash_keypart->key_part_flag= 0;
2511 hash_keypart->key_type= 32834;
2512 /* Last n fields are unique_index_hash fields*/
2513 hash_keypart->offset= offset;
2514 hash_keypart->fieldnr= hash_field_used_no + 1;
2515 hash_field= share->field[hash_field_used_no];
2516 hash_field->flags|= LONG_UNIQUE_HASH_FIELD;//Used in parse_vcol_defs
2517 keyinfo->flags|= HA_NOSAME;
2518 share->virtual_fields++;
2519 share->stored_fields--;
2520 if (record + share->stored_rec_length >= hash_field->ptr)
2521 share->stored_rec_length= (ulong)(hash_field->ptr - record - 1);
2522 hash_field_used_no++;
2523 offset+= HA_HASH_FIELD_LENGTH;
2524 }
2525 }
2526 uint add_first_key_parts= 0;
2527 longlong ha_option= handler_file->ha_table_flags();
2528 keyinfo= share->key_info;
2529 uint primary_key= my_strcasecmp(system_charset_info, share->keynames.type_names[0],
2530 primary_key_name) ? MAX_KEY : 0;
2531 KEY* key_first_info= NULL;
2532
2533 if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME &&
2534 keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
2535 {
2536 /*
2537 If the UNIQUE key doesn't have NULL columns and is not a part key
2538 declare this as a primary key.
2539 */
2540 primary_key= 0;
2541 key_part= keyinfo->key_part;
2542 for (i=0 ; i < keyinfo->user_defined_key_parts ;i++)
2543 {
2544 DBUG_ASSERT(key_part[i].fieldnr > 0);
2545 // Table field corresponding to the i'th key part.
2546 Field *table_field= share->field[key_part[i].fieldnr - 1];
2547
2548 /*
2549 If the key column is of NOT NULL BLOB type, then it
2550 will definitly have key prefix. And if key part prefix size
2551 is equal to the BLOB column max size, then we can promote
2552 it to primary key.
2553 */
2554 if (!table_field->real_maybe_null() &&
2555 table_field->type() == MYSQL_TYPE_BLOB &&
2556 table_field->field_length == key_part[i].length)
2557 continue;
2558
2559 if (table_field->real_maybe_null() ||
2560 table_field->key_length() != key_part[i].length)
2561 {
2562 primary_key= MAX_KEY; // Can't be used
2563 break;
2564 }
2565 }
2566 }
2567
2568 if (share->use_ext_keys)
2569 {
2570 if (primary_key >= MAX_KEY)
2571 {
2572 add_first_key_parts= 0;
2573 share->set_use_ext_keys_flag(FALSE);
2574 }
2575 else
2576 {
2577 add_first_key_parts= first_keyinfo.user_defined_key_parts;
2578 /*
2579 Do not add components of the primary key starting from
2580 the major component defined over the beginning of a field.
2581 */
2582 for (i= 0; i < first_keyinfo.user_defined_key_parts; i++)
2583 {
2584 uint fieldnr= keyinfo[0].key_part[i].fieldnr;
2585 if (share->field[fieldnr-1]->key_length() !=
2586 keyinfo[0].key_part[i].length)
2587 {
2588 add_first_key_parts= i;
2589 break;
2590 }
2591 }
2592 }
2593 }
2594
2595 key_first_info= keyinfo;
2596 for (uint key=0 ; key < keys ; key++,keyinfo++)
2597 {
2598 uint usable_parts= 0;
2599 keyinfo->name.str= share->keynames.type_names[key];
2600 keyinfo->name.length= strlen(keyinfo->name.str);
2601 keyinfo->cache_name=
2602 (uchar*) alloc_root(&share->mem_root,
2603 share->table_cache_key.length+
2604 keyinfo->name.length + 1);
2605 if (keyinfo->cache_name) // If not out of memory
2606 {
2607 uchar *pos= keyinfo->cache_name;
2608 memcpy(pos, share->table_cache_key.str, share->table_cache_key.length);
2609 memcpy(pos + share->table_cache_key.length, keyinfo->name.str,
2610 keyinfo->name.length+1);
2611 }
2612
2613 if (ext_key_parts > share->key_parts && key)
2614 {
2615 KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
2616 (keyinfo-1)->ext_key_parts;
2617 uint add_keyparts_for_this_key= add_first_key_parts;
2618 uint length_bytes= 0, len_null_byte= 0, ext_key_length= 0;
2619 Field *field;
2620
2621 if ((keyinfo-1)->algorithm == HA_KEY_ALG_LONG_HASH)
2622 new_key_part++; // reserved for the hash value
2623
2624 /*
2625 Do not extend the key that contains a component
2626 defined over the beginning of a field.
2627 */
2628 for (i= 0; i < keyinfo->user_defined_key_parts; i++)
2629 {
2630 uint fieldnr= keyinfo->key_part[i].fieldnr;
2631 field= share->field[fieldnr-1];
2632
2633 if (field->null_ptr)
2634 len_null_byte= HA_KEY_NULL_LENGTH;
2635
2636 if ((field->type() == MYSQL_TYPE_BLOB ||
2637 field->real_type() == MYSQL_TYPE_VARCHAR ||
2638 field->type() == MYSQL_TYPE_GEOMETRY) &&
2639 keyinfo->algorithm != HA_KEY_ALG_LONG_HASH )
2640 {
2641 length_bytes= HA_KEY_BLOB_LENGTH;
2642 }
2643
2644 ext_key_length+= keyinfo->key_part[i].length + len_null_byte
2645 + length_bytes;
2646 if (field->key_length() != keyinfo->key_part[i].length)
2647 {
2648 add_keyparts_for_this_key= 0;
2649 break;
2650 }
2651 }
2652
2653 if (add_keyparts_for_this_key)
2654 {
2655 for (i= 0; i < add_keyparts_for_this_key; i++)
2656 {
2657 uint pk_part_length= key_first_info->key_part[i].store_length;
2658 if (keyinfo->ext_key_part_map & 1<<i)
2659 {
2660 if (ext_key_length + pk_part_length > MAX_DATA_LENGTH_FOR_KEY)
2661 {
2662 add_keyparts_for_this_key= i;
2663 break;
2664 }
2665 ext_key_length+= pk_part_length;
2666 }
2667 }
2668 }
2669
2670 if (add_keyparts_for_this_key < keyinfo->ext_key_parts -
2671 keyinfo->user_defined_key_parts)
2672 {
2673 share->ext_key_parts-= keyinfo->ext_key_parts;
2674 key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
2675 keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
2676 keyinfo->ext_key_flags= keyinfo->flags;
2677 keyinfo->ext_key_part_map= 0;
2678 for (i= 0; i < add_keyparts_for_this_key; i++)
2679 {
2680 if (ext_key_part_map & 1<<i)
2681 {
2682 keyinfo->ext_key_part_map|= 1<<i;
2683 keyinfo->ext_key_parts++;
2684 }
2685 }
2686 share->ext_key_parts+= keyinfo->ext_key_parts;
2687 }
2688 if (new_key_part != keyinfo->key_part)
2689 {
2690 memmove(new_key_part, keyinfo->key_part,
2691 sizeof(KEY_PART_INFO) * keyinfo->ext_key_parts);
2692 keyinfo->key_part= new_key_part;
2693 }
2694 }
2695
2696 /* Fix fulltext keys for old .frm files */
2697 if (share->key_info[key].flags & HA_FULLTEXT)
2698 share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
2699
2700 key_part= keyinfo->key_part;
2701 uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
2702 keyinfo->user_defined_key_parts;
2703 if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
2704 key_parts++;
2705 for (i=0; i < key_parts; key_part++, i++)
2706 {
2707 Field *field;
2708 if (new_field_pack_flag <= 1)
2709 key_part->fieldnr= (uint16) find_field(share->field,
2710 share->default_values,
2711 (uint) key_part->offset,
2712 (uint) key_part->length);
2713 if (!key_part->fieldnr)
2714 goto err;
2715
2716 field= key_part->field= share->field[key_part->fieldnr-1];
2717 key_part->type= field->key_type();
2718
2719 if (field->invisible > INVISIBLE_USER && !field->vers_sys_field())
2720 if (keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
2721 keyinfo->flags |= HA_INVISIBLE_KEY;
2722 if (field->null_ptr)
2723 {
2724 key_part->null_offset=(uint) ((uchar*) field->null_ptr -
2725 share->default_values);
2726 key_part->null_bit= field->null_bit;
2727 key_part->store_length+=HA_KEY_NULL_LENGTH;
2728 keyinfo->flags|=HA_NULL_PART_KEY;
2729 keyinfo->key_length+= HA_KEY_NULL_LENGTH;
2730 }
2731 if (field->type() == MYSQL_TYPE_BLOB ||
2732 field->real_type() == MYSQL_TYPE_VARCHAR ||
2733 field->type() == MYSQL_TYPE_GEOMETRY)
2734 {
2735 if (field->type() == MYSQL_TYPE_BLOB ||
2736 field->type() == MYSQL_TYPE_GEOMETRY)
2737 key_part->key_part_flag|= HA_BLOB_PART;
2738 else
2739 key_part->key_part_flag|= HA_VAR_LENGTH_PART;
2740 key_part->store_length+=HA_KEY_BLOB_LENGTH;
2741 if (i < keyinfo->user_defined_key_parts)
2742 keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
2743 }
2744 if (field->type() == MYSQL_TYPE_BIT)
2745 key_part->key_part_flag|= HA_BIT_PART;
2746
2747 if (i == 0 && key != primary_key)
2748 field->flags |= (((keyinfo->flags & HA_NOSAME ||
2749 keyinfo->algorithm == HA_KEY_ALG_LONG_HASH) &&
2750 (keyinfo->user_defined_key_parts == 1)) ?
2751 UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
2752 if (i == 0)
2753 field->key_start.set_bit(key);
2754 if (field->key_length() == key_part->length &&
2755 !(field->flags & BLOB_FLAG) &&
2756 keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
2757 {
2758 if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
2759 {
2760 share->keys_for_keyread.set_bit(key);
2761 field->part_of_key.set_bit(key);
2762 if (i < keyinfo->user_defined_key_parts)
2763 field->part_of_key_not_clustered.set_bit(key);
2764 }
2765 if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
2766 field->part_of_sortkey.set_bit(key);
2767 }
2768 if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
2769 usable_parts == i)
2770 usable_parts++; // For FILESORT
2771 field->flags|= PART_KEY_FLAG;
2772 if (key == primary_key)
2773 {
2774 field->flags|= PRI_KEY_FLAG;
2775 /*
2776 If this field is part of the primary key and all keys contains
2777 the primary key, then we can use any key to find this column
2778 */
2779 if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
2780 {
2781 if (field->key_length() == key_part->length &&
2782 !(field->flags & BLOB_FLAG))
2783 field->part_of_key= share->keys_in_use;
2784 if (field->part_of_sortkey.is_set(key))
2785 field->part_of_sortkey= share->keys_in_use;
2786 }
2787 }
2788 if (field->key_length() != key_part->length)
2789 {
2790 #ifndef TO_BE_DELETED_ON_PRODUCTION
2791 if (field->type() == MYSQL_TYPE_NEWDECIMAL &&
2792 keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
2793 {
2794 /*
2795 Fix a fatal error in decimal key handling that causes crashes
2796 on Innodb. We fix it by reducing the key length so that
2797 InnoDB never gets a too big key when searching.
2798 This allows the end user to do an ALTER TABLE to fix the
2799 error.
2800 */
2801 keyinfo->key_length-= (key_part->length - field->key_length());
2802 key_part->store_length-= (uint16)(key_part->length -
2803 field->key_length());
2804 key_part->length= (uint16)field->key_length();
2805 sql_print_error("Found wrong key definition in %s; "
2806 "Please do \"ALTER TABLE '%s' FORCE \" to fix it!",
2807 share->table_name.str,
2808 share->table_name.str);
2809 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
2810 ER_CRASHED_ON_USAGE,
2811 "Found wrong key definition in %s; "
2812 "Please do \"ALTER TABLE '%s' FORCE\" to fix "
2813 "it!",
2814 share->table_name.str,
2815 share->table_name.str);
2816 share->crashed= 1; // Marker for CHECK TABLE
2817 continue;
2818 }
2819 #endif
2820 key_part->key_part_flag|= HA_PART_KEY_SEG;
2821 }
2822 if (field->real_maybe_null())
2823 key_part->key_part_flag|= HA_NULL_PART;
2824 /*
2825 Sometimes we can compare key parts for equality with memcmp.
2826 But not always.
2827 */
2828 if (!(key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART |
2829 HA_BIT_PART)) &&
2830 key_part->type != HA_KEYTYPE_FLOAT &&
2831 key_part->type == HA_KEYTYPE_DOUBLE &&
2832 keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
2833 key_part->key_part_flag|= HA_CAN_MEMCMP;
2834 }
2835 keyinfo->usable_key_parts= usable_parts; // Filesort
2836
2837 set_if_bigger(share->max_key_length,keyinfo->key_length+
2838 keyinfo->user_defined_key_parts);
2839 /*
2840 MERGE tables do not have unique indexes. But every key could be
2841 an unique index on the underlying MyISAM table. (Bug #10400)
2842 */
2843 if ((keyinfo->flags & HA_NOSAME) ||
2844 (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
2845 set_if_bigger(share->max_unique_length,keyinfo->key_length);
2846 }
2847 if (primary_key < MAX_KEY &&
2848 (share->keys_in_use.is_set(primary_key)))
2849 {
2850 share->primary_key= primary_key;
2851 /*
2852 If we are using an integer as the primary key then allow the user to
2853 refer to it as '_rowid'
2854 */
2855 if (share->key_info[primary_key].user_defined_key_parts == 1)
2856 {
2857 Field *field= share->key_info[primary_key].key_part[0].field;
2858 if (field && field->result_type() == INT_RESULT)
2859 {
2860 /* note that fieldnr here (and rowid_field_offset) starts from 1 */
2861 share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
2862 fieldnr);
2863 }
2864 }
2865 }
2866 else
2867 share->primary_key = MAX_KEY; // we do not have a primary key
2868 }
2869 else
2870 share->primary_key= MAX_KEY;
2871 if (new_field_pack_flag <= 1)
2872 {
2873 /* Old file format with default as not null */
2874 uint null_length= (share->null_fields+7)/8;
2875 bfill(share->default_values + (null_flags - (uchar*) record),
2876 null_length, 255);
2877 }
2878
2879 set_overlapped_keys();
2880
2881 /* Handle virtual expressions */
2882 if (vcol_screen_length && share->frm_version >= FRM_VER_EXPRESSSIONS)
2883 {
2884 uchar *vcol_screen_end= vcol_screen_pos + vcol_screen_length;
2885
2886 /* Skip header */
2887 vcol_screen_pos+= FRM_VCOL_NEW_BASE_SIZE;
2888 share->vcol_defs.str+= FRM_VCOL_NEW_BASE_SIZE;
2889 share->vcol_defs.length-= FRM_VCOL_NEW_BASE_SIZE;
2890
2891 /*
2892 Read virtual columns, default values and check constraints
2893 See pack_expression() for how data is stored
2894 */
2895 while (vcol_screen_pos < vcol_screen_end)
2896 {
2897 Virtual_column_info *vcol_info;
2898 uint type= (uint) vcol_screen_pos[0];
2899 uint field_nr= uint2korr(vcol_screen_pos+1);
2900 uint expr_length= uint2korr(vcol_screen_pos+3);
2901 uint name_length= (uint) vcol_screen_pos[5];
2902
2903 if (!(vcol_info= new (&share->mem_root) Virtual_column_info()))
2904 goto err;
2905
2906 /* The following can only be true for check_constraints */
2907
2908 if (field_nr != UINT_MAX16)
2909 {
2910 DBUG_ASSERT(field_nr < share->fields);
2911 reg_field= share->field[field_nr];
2912 }
2913 else
2914 {
2915 reg_field= 0;
2916 DBUG_ASSERT(name_length);
2917 }
2918
2919 vcol_screen_pos+= FRM_VCOL_NEW_HEADER_SIZE;
2920 vcol_info->set_vcol_type((enum_vcol_info_type) type);
2921 if (name_length)
2922 {
2923 vcol_info->name.str= strmake_root(&share->mem_root,
2924 (char*)vcol_screen_pos, name_length);
2925 vcol_info->name.length= name_length;
2926 }
2927 else
2928 vcol_info->name= reg_field->field_name;
2929 vcol_screen_pos+= name_length + expr_length;
2930
2931 switch (type) {
2932 case VCOL_GENERATED_VIRTUAL:
2933 {
2934 uint recpos;
2935 reg_field->vcol_info= vcol_info;
2936 share->virtual_fields++;
2937 share->stored_fields--;
2938 if (reg_field->flags & BLOB_FLAG)
2939 share->virtual_not_stored_blob_fields++;
2940 /* Correct stored_rec_length as non stored fields are last */
2941 recpos= (uint) (reg_field->ptr - record);
2942 if (share->stored_rec_length >= recpos)
2943 share->stored_rec_length= recpos-1;
2944 break;
2945 }
2946 case VCOL_GENERATED_STORED:
2947 vcol_info->stored_in_db= 1;
2948 DBUG_ASSERT(!reg_field->vcol_info);
2949 reg_field->vcol_info= vcol_info;
2950 share->virtual_fields++;
2951 break;
2952 case VCOL_DEFAULT:
2953 vcol_info->stored_in_db= 1;
2954 DBUG_ASSERT(!reg_field->default_value);
2955 reg_field->default_value= vcol_info;
2956 share->default_expressions++;
2957 break;
2958 case VCOL_CHECK_FIELD:
2959 DBUG_ASSERT(!reg_field->check_constraint);
2960 reg_field->check_constraint= vcol_info;
2961 share->field_check_constraints++;
2962 break;
2963 case VCOL_CHECK_TABLE:
2964 *(table_check_constraints++)= vcol_info;
2965 break;
2966 }
2967 }
2968 }
2969 DBUG_ASSERT((uint) (table_check_constraints - share->check_constraints) ==
2970 (uint) (share->table_check_constraints -
2971 share->field_check_constraints));
2972
2973 if (options.str)
2974 {
2975 DBUG_ASSERT(options.length);
2976 if (engine_table_options_frm_read(options.str, options.length, share))
2977 goto err;
2978 }
2979 if (parse_engine_table_options(thd, handler_file->partition_ht(), share))
2980 goto err;
2981
2982 if (share->found_next_number_field)
2983 {
2984 reg_field= *share->found_next_number_field;
2985 if ((int) (share->next_number_index= (uint)
2986 find_ref_key(share->key_info, keys,
2987 share->default_values, reg_field,
2988 &share->next_number_key_offset,
2989 &share->next_number_keypart)) < 0)
2990 goto err; // Wrong field definition
2991 reg_field->flags |= AUTO_INCREMENT_FLAG;
2992 }
2993
2994 if (share->blob_fields)
2995 {
2996 Field **ptr;
2997 uint k, *save;
2998
2999 /* Store offsets to blob fields to find them fast */
3000 if (!(share->blob_field= save=
3001 (uint*) alloc_root(&share->mem_root,
3002 (uint) (share->blob_fields* sizeof(uint)))))
3003 goto err;
3004 for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
3005 {
3006 if ((*ptr)->flags & BLOB_FLAG)
3007 (*save++)= k;
3008 }
3009 }
3010
3011 /*
3012 the correct null_bytes can now be set, since bitfields have been taken
3013 into account
3014 */
3015 share->null_bytes= (uint)(null_pos - (uchar*) null_flags +
3016 (null_bit_pos + 7) / 8);
3017 share->last_null_bit_pos= null_bit_pos;
3018 share->null_bytes_for_compare= null_bits_are_used ? share->null_bytes : 0;
3019 share->can_cmp_whole_record= (share->blob_fields == 0 &&
3020 share->varchar_fields == 0);
3021
3022 share->column_bitmap_size= bitmap_buffer_size(share->fields);
3023
3024 bitmap_count= 1;
3025 if (share->table_check_constraints)
3026 {
3027 feature_check_constraint++;
3028 if (!(share->check_set= (MY_BITMAP*)
3029 alloc_root(&share->mem_root, sizeof(*share->check_set))))
3030 goto err;
3031 bitmap_count++;
3032 }
3033 if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
3034 share->column_bitmap_size *
3035 bitmap_count)))
3036 goto err;
3037 my_bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
3038 bitmap_set_all(&share->all_set);
3039 if (share->check_set)
3040 {
3041 /*
3042 Bitmap for fields used by CHECK constraint. Will be filled up
3043 at first usage of table.
3044 */
3045 my_bitmap_init(share->check_set,
3046 (my_bitmap_map*) ((uchar*) bitmaps +
3047 share->column_bitmap_size),
3048 share->fields, FALSE);
3049 bitmap_clear_all(share->check_set);
3050 }
3051
3052 #ifndef DBUG_OFF
3053 if (use_hash)
3054 (void) my_hash_check(&share->name_hash);
3055 #endif
3056
3057 share->db_plugin= se_plugin;
3058 delete handler_file;
3059
3060 share->error= OPEN_FRM_OK;
3061 thd->status_var.opened_shares++;
3062 thd->mem_root= old_root;
3063 DBUG_RETURN(0);
3064
3065 err:
3066 share->db_plugin= NULL;
3067 share->error= OPEN_FRM_CORRUPTED;
3068 share->open_errno= my_errno;
3069 delete handler_file;
3070 plugin_unlock(0, se_plugin);
3071 my_hash_free(&share->name_hash);
3072
3073 if (!thd->is_error())
3074 open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
3075
3076 thd->mem_root= old_root;
3077 DBUG_RETURN(HA_ERR_NOT_A_TABLE);
3078 }
3079
3080
sql_unusable_for_discovery(THD * thd,handlerton * engine,const char * sql)3081 static bool sql_unusable_for_discovery(THD *thd, handlerton *engine,
3082 const char *sql)
3083 {
3084 LEX *lex= thd->lex;
3085 HA_CREATE_INFO *create_info= &lex->create_info;
3086
3087 // ... not CREATE TABLE
3088 if (lex->sql_command != SQLCOM_CREATE_TABLE &&
3089 lex->sql_command != SQLCOM_CREATE_SEQUENCE)
3090 return 1;
3091 // ... create like
3092 if (lex->create_info.like())
3093 return 1;
3094 // ... create select
3095 if (lex->first_select_lex()->item_list.elements)
3096 return 1;
3097 // ... temporary
3098 if (create_info->tmp_table())
3099 return 1;
3100 // ... if exists
3101 if (lex->create_info.if_not_exists())
3102 return 1;
3103
3104 // XXX error out or rather ignore the following:
3105 // ... partitioning
3106 if (lex->part_info)
3107 return 1;
3108 // ... union
3109 if (create_info->used_fields & HA_CREATE_USED_UNION)
3110 return 1;
3111 // ... index/data directory
3112 if (create_info->data_file_name || create_info->index_file_name)
3113 return 1;
3114 // ... engine
3115 DBUG_ASSERT(lex->m_sql_cmd);
3116 if (lex->create_info.used_fields & HA_CREATE_USED_ENGINE)
3117 {
3118 /*
3119 TODO: we could just compare engine names here, without resolving.
3120 But this optimization is too late for 10.1.
3121 */
3122 Storage_engine_name *opt= lex->m_sql_cmd->option_storage_engine_name();
3123 DBUG_ASSERT(opt); // lex->m_sql_cmd must be an Sql_cmd_create_table instance
3124 if (opt->resolve_storage_engine_with_error(thd, &create_info->db_type,
3125 false) ||
3126 (create_info->db_type && create_info->db_type != engine))
3127 return 1;
3128 }
3129 // ... WITH SYSTEM VERSIONING
3130 if (create_info->versioned())
3131 return 1;
3132
3133 return 0;
3134 }
3135
init_from_sql_statement_string(THD * thd,bool write,const char * sql,size_t sql_length)3136 int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
3137 const char *sql, size_t sql_length)
3138 {
3139 sql_mode_t saved_mode= thd->variables.sql_mode;
3140 CHARSET_INFO *old_cs= thd->variables.character_set_client;
3141 Parser_state parser_state;
3142 bool error;
3143 char *sql_copy;
3144 handler *file;
3145 LEX *old_lex;
3146 Query_arena *arena, backup;
3147 LEX tmp_lex;
3148 KEY *unused1;
3149 uint unused2;
3150 handlerton *hton= plugin_hton(db_plugin);
3151 LEX_CUSTRING frm= {0,0};
3152 LEX_CSTRING db_backup= thd->db;
3153 DBUG_ENTER("TABLE_SHARE::init_from_sql_statement_string");
3154
3155 /*
3156 Ouch. Parser may *change* the string it's working on.
3157 Currently (2013-02-26) it is used to permanently disable
3158 conditional comments.
3159 Anyway, let's copy the caller's string...
3160 */
3161 if (!(sql_copy= thd->strmake(sql, sql_length)))
3162 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
3163
3164 if (parser_state.init(thd, sql_copy, sql_length))
3165 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
3166
3167 thd->variables.sql_mode= MODE_NO_ENGINE_SUBSTITUTION | MODE_NO_DIR_IN_CREATE;
3168 thd->variables.character_set_client= system_charset_info;
3169 tmp_disable_binlog(thd);
3170 old_lex= thd->lex;
3171 thd->lex= &tmp_lex;
3172
3173 arena= thd->stmt_arena;
3174 if (arena->is_conventional())
3175 arena= 0;
3176 else
3177 thd->set_n_backup_active_arena(arena, &backup);
3178
3179 thd->reset_db(&db);
3180 lex_start(thd);
3181
3182 if (unlikely((error= parse_sql(thd, & parser_state, NULL) ||
3183 sql_unusable_for_discovery(thd, hton, sql_copy))))
3184 goto ret;
3185
3186 thd->lex->create_info.db_type= hton;
3187 #ifdef WITH_PARTITION_STORAGE_ENGINE
3188 thd->work_part_info= 0; // For partitioning
3189 #endif
3190
3191 if (tabledef_version.str)
3192 thd->lex->create_info.tabledef_version= tabledef_version;
3193
3194 promote_first_timestamp_column(&thd->lex->alter_info.create_list);
3195 file= mysql_create_frm_image(thd, db, table_name,
3196 &thd->lex->create_info, &thd->lex->alter_info,
3197 C_ORDINARY_CREATE, &unused1, &unused2, &frm);
3198 error|= file == 0;
3199 delete file;
3200
3201 if (frm.str)
3202 {
3203 option_list= 0; // cleanup existing options ...
3204 option_struct= 0; // ... if it's an assisted discovery
3205 error= init_from_binary_frm_image(thd, write, frm.str, frm.length);
3206 }
3207
3208 ret:
3209 my_free(const_cast<uchar*>(frm.str));
3210 lex_end(thd->lex);
3211 thd->reset_db(&db_backup);
3212 thd->lex= old_lex;
3213 if (arena)
3214 thd->restore_active_arena(arena, &backup);
3215 reenable_binlog(thd);
3216 thd->variables.sql_mode= saved_mode;
3217 thd->variables.character_set_client= old_cs;
3218 if (unlikely(thd->is_error() || error))
3219 {
3220 thd->clear_error();
3221 my_error(ER_SQL_DISCOVER_ERROR, MYF(0), hton_name(hton)->str,
3222 db.str, table_name.str, sql_copy);
3223 DBUG_RETURN(HA_ERR_GENERIC);
3224 }
3225 /* Treat the table as normal table from binary logging point of view */
3226 table_creation_was_logged= 1;
3227 DBUG_RETURN(0);
3228 }
3229
write_frm_image(const uchar * frm,size_t len)3230 bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len)
3231 {
3232 return writefrm(normalized_path.str, db.str, table_name.str, false, frm, len);
3233 }
3234
3235
read_frm_image(const uchar ** frm,size_t * len)3236 bool TABLE_SHARE::read_frm_image(const uchar **frm, size_t *len)
3237 {
3238 if (IF_PARTITIONING(partition_info_str, 0)) // cannot discover a partition
3239 {
3240 DBUG_ASSERT(db_type()->discover_table == 0);
3241 return 1;
3242 }
3243
3244 if (frm_image)
3245 {
3246 *frm= frm_image->str;
3247 *len= frm_image->length;
3248 frm_image->str= 0; // pass the ownership to the caller
3249 frm_image= 0;
3250 return 0;
3251 }
3252 return readfrm(normalized_path.str, frm, len);
3253 }
3254
3255
free_frm_image(const uchar * frm)3256 void TABLE_SHARE::free_frm_image(const uchar *frm)
3257 {
3258 if (frm)
3259 my_free(const_cast<uchar*>(frm));
3260 }
3261
3262
fix_vcol_expr(THD * thd,Virtual_column_info * vcol)3263 static bool fix_vcol_expr(THD *thd, Virtual_column_info *vcol)
3264 {
3265 DBUG_ENTER("fix_vcol_expr");
3266
3267 const enum enum_column_usage saved_column_usage= thd->column_usage;
3268 thd->column_usage= COLUMNS_WRITE;
3269
3270 int error= vcol->expr->fix_fields(thd, &vcol->expr);
3271
3272 thd->column_usage= saved_column_usage;
3273
3274 if (unlikely(error))
3275 {
3276 StringBuffer<MAX_FIELD_WIDTH> str;
3277 vcol->print(&str);
3278 my_error(ER_ERROR_EVALUATING_EXPRESSION, MYF(0), str.c_ptr_safe());
3279 DBUG_RETURN(1);
3280 }
3281
3282 DBUG_RETURN(0);
3283 }
3284
3285 /** rerun fix_fields for vcols that returns time- or session- dependent values
3286
3287 @note this is done for all vcols for INSERT/UPDATE/DELETE,
3288 and only as needed for SELECTs.
3289 */
fix_session_vcol_expr(THD * thd,Virtual_column_info * vcol)3290 bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol)
3291 {
3292 DBUG_ENTER("fix_session_vcol_expr");
3293 if (!(vcol->flags & (VCOL_TIME_FUNC|VCOL_SESSION_FUNC)))
3294 DBUG_RETURN(0);
3295
3296 vcol->expr->walk(&Item::cleanup_excluding_fields_processor, 0, 0);
3297 DBUG_ASSERT(!vcol->expr->is_fixed());
3298 DBUG_RETURN(fix_vcol_expr(thd, vcol));
3299 }
3300
3301
3302 /** invoke fix_session_vcol_expr for a vcol
3303
3304 @note this is called for generated column or a DEFAULT expression from
3305 their corresponding fix_fields on SELECT.
3306 */
fix_session_vcol_expr_for_read(THD * thd,Field * field,Virtual_column_info * vcol)3307 bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
3308 Virtual_column_info *vcol)
3309 {
3310 DBUG_ENTER("fix_session_vcol_expr_for_read");
3311 TABLE_LIST *tl= field->table->pos_in_table_list;
3312 if (!tl || tl->lock_type >= TL_WRITE_ALLOW_WRITE)
3313 DBUG_RETURN(0);
3314 Security_context *save_security_ctx= thd->security_ctx;
3315 if (tl->security_ctx)
3316 thd->security_ctx= tl->security_ctx;
3317 bool res= fix_session_vcol_expr(thd, vcol);
3318 thd->security_ctx= save_security_ctx;
3319 DBUG_RETURN(res);
3320 }
3321
3322
3323 /*
3324 @brief
3325 Perform semantic analysis of the defining expression for a virtual column
3326
3327 @param thd The thread object
3328 @param table The table containing the virtual column
3329 @param field Field if this is a DEFAULT or AS, otherwise NULL
3330 @param vcol The Virtual_column object
3331
3332
3333 @details
3334 The function performs semantic analysis of the defining expression for
3335 the virtual column vcol_field. The expression is used to compute the
3336 values of this column.
3337
3338 @retval
3339 TRUE An error occurred, something was wrong with the function
3340 @retval
3341 FALSE Otherwise
3342 */
3343
fix_and_check_vcol_expr(THD * thd,TABLE * table,Virtual_column_info * vcol)3344 static bool fix_and_check_vcol_expr(THD *thd, TABLE *table,
3345 Virtual_column_info *vcol)
3346 {
3347 Item* func_expr= vcol->expr;
3348 DBUG_ENTER("fix_and_check_vcol_expr");
3349 DBUG_PRINT("info", ("vcol: %p", vcol));
3350 DBUG_ASSERT(func_expr);
3351
3352 if (func_expr->is_fixed())
3353 DBUG_RETURN(0); // nothing to do
3354
3355 if (fix_vcol_expr(thd, vcol))
3356 DBUG_RETURN(1);
3357
3358 if (vcol->flags)
3359 DBUG_RETURN(0); // already checked, no need to do it again
3360
3361 /* fix_fields could've changed the expression */
3362 func_expr= vcol->expr;
3363
3364 /* this was checked in check_expression(), but the frm could be mangled... */
3365 if (unlikely(func_expr->result_type() == ROW_RESULT))
3366 {
3367 my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
3368 DBUG_RETURN(1);
3369 }
3370
3371 /*
3372 Walk through the Item tree checking if all items are valid
3373 to be part of the virtual column
3374 */
3375 Item::vcol_func_processor_result res;
3376 res.errors= 0;
3377
3378 int error= func_expr->walk(&Item::check_vcol_func_processor, 0, &res);
3379 if (unlikely(error || (res.errors & VCOL_IMPOSSIBLE)))
3380 {
3381 // this can only happen if the frm was corrupted
3382 my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name,
3383 vcol->get_vcol_type_name(), vcol->name.str);
3384 DBUG_RETURN(1);
3385 }
3386 else if (unlikely(res.errors & VCOL_AUTO_INC))
3387 {
3388 /*
3389 An auto_increment field may not be used in an expression for
3390 a check constraint, a default value or a generated column
3391
3392 Note that this error condition is not detected during parsing
3393 of the statement because the field item does not have a field
3394 pointer at that time
3395 */
3396 myf warn= table->s->frm_version < FRM_VER_EXPRESSSIONS ? ME_WARNING : 0;
3397 my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(warn),
3398 "AUTO_INCREMENT", vcol->get_vcol_type_name(), res.name);
3399 if (!warn)
3400 DBUG_RETURN(1);
3401 }
3402 vcol->flags= res.errors;
3403
3404 if (vcol->flags & VCOL_SESSION_FUNC)
3405 table->s->vcols_need_refixing= true;
3406
3407 DBUG_RETURN(0);
3408 }
3409
3410
3411 /*
3412 @brief
3413 Unpack the definition of a virtual column from its linear representation
3414
3415 @param thd The thread object
3416 @param mem_root Where to allocate memory
3417 @param table The table containing the virtual column
3418 @param field Field if this is a DEFAULT or AS, otherwise NULL
3419 @param vcol The Virtual_column object
3420 @param[out] error_reported Flag to inform the caller that no
3421 other error messages are to be generated
3422
3423 @details
3424
3425 The function takes string expression from the 'vcol' object of the
3426 table 'table' and parses it, building an item object for it. The
3427 pointer to this item is placed into in a Virtual_column_info object
3428 that is created. After this the function performs
3429 semantic analysis of the item by calling the the function
3430 fix_and_check_vcol_expr(). Since the defining expression is part of the table
3431 definition the item for it is created in table->memroot within the
3432 special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED
3433
3434 @note
3435 Before passing 'vcol_expr' to the parser the function wraps it in
3436 parentheses and prepends a special keyword.
3437
3438 @retval Virtual_column_info* Success
3439 @retval NULL Error
3440 */
3441
3442 static Virtual_column_info *
unpack_vcol_info_from_frm(THD * thd,MEM_ROOT * mem_root,TABLE * table,String * expr_str,Virtual_column_info ** vcol_ptr,bool * error_reported)3443 unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table,
3444 String *expr_str, Virtual_column_info **vcol_ptr,
3445 bool *error_reported)
3446 {
3447 Create_field vcol_storage; // placeholder for vcol_info
3448 Parser_state parser_state;
3449 Virtual_column_info *vcol= *vcol_ptr, *vcol_info= 0;
3450 LEX *old_lex= thd->lex;
3451 LEX lex;
3452 bool error;
3453 DBUG_ENTER("unpack_vcol_info_from_frm");
3454
3455 DBUG_ASSERT(vcol->expr == NULL);
3456
3457 if (parser_state.init(thd, expr_str->c_ptr_safe(), expr_str->length()))
3458 goto end;
3459
3460 if (init_lex_with_single_table(thd, table, &lex))
3461 goto end;
3462
3463 lex.parse_vcol_expr= true;
3464 lex.last_field= &vcol_storage;
3465
3466 error= parse_sql(thd, &parser_state, NULL);
3467 if (unlikely(error))
3468 goto end;
3469
3470 if (lex.current_select->table_list.first[0].next_global)
3471 {
3472 /* We are using NEXT VALUE FOR sequence. Remember table name for open */
3473 TABLE_LIST *sequence= lex.current_select->table_list.first[0].next_global;
3474 sequence->next_global= table->internal_tables;
3475 table->internal_tables= sequence;
3476 }
3477
3478 vcol_storage.vcol_info->set_vcol_type(vcol->get_vcol_type());
3479 vcol_storage.vcol_info->stored_in_db= vcol->stored_in_db;
3480 vcol_storage.vcol_info->name= vcol->name;
3481 vcol_storage.vcol_info->utf8= vcol->utf8;
3482 if (!fix_and_check_vcol_expr(thd, table, vcol_storage.vcol_info))
3483 {
3484 *vcol_ptr= vcol_info= vcol_storage.vcol_info; // Expression ok
3485 DBUG_ASSERT(vcol_info->expr);
3486 goto end;
3487 }
3488 *error_reported= TRUE;
3489
3490 end:
3491 end_lex_with_single_table(thd, table, old_lex);
3492
3493 DBUG_RETURN(vcol_info);
3494 }
3495
check_vcol_forward_refs(Field * field,Virtual_column_info * vcol,bool check_constraint)3496 static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol,
3497 bool check_constraint)
3498 {
3499 bool res;
3500 uint32 flags= field->flags;
3501 if (check_constraint)
3502 {
3503 /* Check constraints can refer it itself */
3504 field->flags|= NO_DEFAULT_VALUE_FLAG;
3505 }
3506 res= (vcol &&
3507 vcol->expr->walk(&Item::check_field_expression_processor, 0, field));
3508 field->flags= flags;
3509 return res;
3510 }
3511
3512 #ifndef DBUG_OFF
print_long_unique_table(TABLE * table)3513 static void print_long_unique_table(TABLE *table)
3514 {
3515 char buff[256];
3516 String str;
3517 KEY *key_info_table, *key_info_share;
3518 KEY_PART_INFO *key_part;
3519 Field *field;
3520 my_snprintf(buff, sizeof(buff), "Printing Table state, It will print table fields,"
3521 " fields->offset,field->null_bit, field->null_pos and key_info ... \n"
3522 "\nPrinting Table keyinfo\n");
3523 str.append(buff, strlen(buff));
3524 my_snprintf(buff, sizeof(buff), "\ntable->s->reclength %d\n"
3525 "table->s->fields %d\n",
3526 table->s->reclength, table->s->fields);
3527 str.append(buff, strlen(buff));
3528 for (uint i= 0; i < table->s->keys; i++)
3529 {
3530 key_info_table= table->key_info + i;
3531 key_info_share= table->s->key_info + i;
3532 my_snprintf(buff, sizeof(buff), "\ntable->key_info[%d] user_defined_key_parts = %d\n"
3533 "table->key_info[%d] algorithm == HA_KEY_ALG_LONG_HASH = %d\n"
3534 "table->key_info[%d] flags & HA_NOSAME = %d\n",
3535 i, key_info_table->user_defined_key_parts,
3536 i, key_info_table->algorithm == HA_KEY_ALG_LONG_HASH,
3537 i, key_info_table->flags & HA_NOSAME);
3538 str.append(buff, strlen(buff));
3539 my_snprintf(buff, sizeof(buff), "\ntable->s->key_info[%d] user_defined_key_parts = %d\n"
3540 "table->s->key_info[%d] algorithm == HA_KEY_ALG_LONG_HASH = %d\n"
3541 "table->s->key_info[%d] flags & HA_NOSAME = %d\n",
3542 i, key_info_share->user_defined_key_parts,
3543 i, key_info_share->algorithm == HA_KEY_ALG_LONG_HASH,
3544 i, key_info_share->flags & HA_NOSAME);
3545 str.append(buff, strlen(buff));
3546 key_part = key_info_table->key_part;
3547 my_snprintf(buff, sizeof(buff), "\nPrinting table->key_info[%d].key_part[0] info\n"
3548 "key_part->offset = %d\n"
3549 "key_part->field_name = %s\n"
3550 "key_part->length = %d\n"
3551 "key_part->null_bit = %d\n"
3552 "key_part->null_offset = %d\n",
3553 i, key_part->offset, key_part->field->field_name.str, key_part->length,
3554 key_part->null_bit, key_part->null_offset);
3555 str.append(buff, strlen(buff));
3556
3557 for (uint j= 0; j < key_info_share->user_defined_key_parts; j++)
3558 {
3559 key_part= key_info_share->key_part + j;
3560 my_snprintf(buff, sizeof(buff), "\nPrinting share->key_info[%d].key_part[%d] info\n"
3561 "key_part->offset = %d\n"
3562 "key_part->field_name = %s\n"
3563 "key_part->length = %d\n"
3564 "key_part->null_bit = %d\n"
3565 "key_part->null_offset = %d\n",
3566 i,j,key_part->offset, key_part->field->field_name.str, key_part->length,
3567 key_part->null_bit, key_part->null_offset);
3568 str.append(buff, strlen(buff));
3569 }
3570 }
3571 my_snprintf(buff, sizeof(buff), "\nPrinting table->fields\n");
3572 str.append(buff, strlen(buff));
3573 for(uint i= 0; i < table->s->fields; i++)
3574 {
3575 field= table->field[i];
3576 my_snprintf(buff, sizeof(buff), "\ntable->field[%d]->field_name %s\n"
3577 "table->field[%d]->offset = %d\n"
3578 "table->field[%d]->field_length = %d\n"
3579 "table->field[%d]->null_pos wrt to record 0 = %d\n"
3580 "table->field[%d]->null_bit_pos = %d\n",
3581 i, field->field_name.str,
3582 i, field->ptr- table->record[0],
3583 i, field->pack_length(),
3584 i, field->null_bit ? field->null_ptr - table->record[0] : -1,
3585 i, field->null_bit);
3586 str.append(buff, strlen(buff));
3587 }
3588 (*error_handler_hook)(1, str.ptr(), ME_NOTE);
3589 }
3590 #endif
3591
3592 /*
3593 Open a table based on a TABLE_SHARE
3594
3595 SYNOPSIS
3596 open_table_from_share()
3597 thd Thread handler
3598 share Table definition
3599 alias Alias for table
3600 db_stat open flags (for example HA_OPEN_KEYFILE|
3601 HA_OPEN_RNDFILE..) can be 0 (example in
3602 ha_example_table)
3603 prgflag READ_ALL etc..
3604 ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
3605 outparam result table
3606 partitions_to_open open only these partitions.
3607
3608 RETURN VALUES
3609 0 ok
3610 1 Error (see open_table_error)
3611 2 Error (see open_table_error)
3612 3 Wrong data in .frm file
3613 4 Error (see open_table_error)
3614 5 Error (see open_table_error: charset unavailable)
3615 7 Table definition has changed in engine
3616 */
3617
open_table_from_share(THD * thd,TABLE_SHARE * share,const LEX_CSTRING * alias,uint db_stat,uint prgflag,uint ha_open_flags,TABLE * outparam,bool is_create_table,List<String> * partitions_to_open)3618 enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
3619 const LEX_CSTRING *alias, uint db_stat, uint prgflag,
3620 uint ha_open_flags, TABLE *outparam,
3621 bool is_create_table, List<String> *partitions_to_open)
3622 {
3623 enum open_frm_error error;
3624 uint records, i, bitmap_size, bitmap_count;
3625 const char *tmp_alias;
3626 bool error_reported= FALSE;
3627 uchar *record, *bitmaps;
3628 Field **field_ptr;
3629 uint8 save_context_analysis_only= thd->lex->context_analysis_only;
3630 TABLE_SHARE::enum_v_keys check_set_initialized= share->check_set_initialized;
3631 DBUG_ENTER("open_table_from_share");
3632 DBUG_PRINT("enter",("name: '%s.%s' form: %p", share->db.str,
3633 share->table_name.str, outparam));
3634
3635 thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view
3636
3637 error= OPEN_FRM_ERROR_ALREADY_ISSUED; // for OOM errors below
3638 bzero((char*) outparam, sizeof(*outparam));
3639 outparam->in_use= thd;
3640 outparam->s= share;
3641 outparam->db_stat= db_stat;
3642 outparam->write_row_record= NULL;
3643
3644 if (share->incompatible_version &&
3645 !(ha_open_flags & (HA_OPEN_FOR_ALTER | HA_OPEN_FOR_REPAIR)))
3646 {
3647 /* one needs to run mysql_upgrade on the table */
3648 error= OPEN_FRM_NEEDS_REBUILD;
3649 goto err;
3650 }
3651 init_sql_alloc(&outparam->mem_root, "table", TABLE_ALLOC_BLOCK_SIZE, 0,
3652 MYF(0));
3653
3654 /*
3655 We have to store the original alias in mem_root as constraints and virtual
3656 functions may store pointers to it
3657 */
3658 if (!(tmp_alias= strmake_root(&outparam->mem_root, alias->str, alias->length)))
3659 goto err;
3660
3661 outparam->alias.set(tmp_alias, alias->length, table_alias_charset);
3662
3663 /* Allocate handler */
3664 outparam->file= 0;
3665 if (!(prgflag & OPEN_FRM_FILE_ONLY))
3666 {
3667 if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
3668 share->db_type())))
3669 goto err;
3670
3671 if (outparam->file->set_ha_share_ref(&share->ha_share))
3672 goto err;
3673 }
3674 else
3675 {
3676 DBUG_ASSERT(!db_stat);
3677 }
3678
3679 if (share->sequence && outparam->file)
3680 {
3681 ha_sequence *file;
3682 /* SEQUENCE table. Create a sequence handler over the original handler */
3683 if (!(file= (ha_sequence*) sql_sequence_hton->create(sql_sequence_hton, share,
3684 &outparam->mem_root)))
3685 goto err;
3686 file->register_original_handler(outparam->file);
3687 outparam->file= file;
3688 }
3689
3690 outparam->reginfo.lock_type= TL_UNLOCK;
3691 outparam->current_lock= F_UNLCK;
3692 records=0;
3693 if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
3694 records=1;
3695 if (prgflag & (READ_ALL + EXTRA_RECORD))
3696 {
3697 records++;
3698 if (share->versioned || share->period.name)
3699 records++;
3700 }
3701
3702 if (records == 0)
3703 {
3704 /* We are probably in hard repair, and the buffers should not be used */
3705 record= share->default_values;
3706 }
3707 else
3708 {
3709 if (!(record= (uchar*) alloc_root(&outparam->mem_root,
3710 share->rec_buff_length * records)))
3711 goto err; /* purecov: inspected */
3712 }
3713
3714 for (i= 0; i < 3;)
3715 {
3716 outparam->record[i]= record;
3717 if (++i < records)
3718 record+= share->rec_buff_length;
3719 }
3720 /* Mark bytes between records as not accessable to catch overrun bugs */
3721 for (i= 0; i < records; i++)
3722 MEM_NOACCESS(outparam->record[i] + share->reclength,
3723 share->rec_buff_length - share->reclength);
3724
3725 if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
3726 (uint) ((share->fields+1)*
3727 sizeof(Field*)))))
3728 goto err; /* purecov: inspected */
3729
3730 outparam->field= field_ptr;
3731
3732 record= (uchar*) outparam->record[0]-1; /* Fieldstart = 1 */
3733 if (share->null_field_first)
3734 outparam->null_flags= (uchar*) record+1;
3735 else
3736 outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
3737 share->null_bytes);
3738
3739 /* Setup copy of fields from share, but use the right alias and record */
3740 for (i=0 ; i < share->fields; i++, field_ptr++)
3741 {
3742 if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
3743 goto err;
3744 }
3745 (*field_ptr)= 0; // End marker
3746
3747 DEBUG_SYNC(thd, "TABLE_after_field_clone");
3748
3749 outparam->vers_write= share->versioned;
3750
3751 if (share->found_next_number_field)
3752 outparam->found_next_number_field=
3753 outparam->field[(uint) (share->found_next_number_field - share->field)];
3754
3755 /* Fix key->name and key_part->field */
3756 if (share->key_parts)
3757 {
3758 KEY *key_info, *key_info_end;
3759 KEY_PART_INFO *key_part;
3760 uint n_length;
3761 n_length= share->keys*sizeof(KEY) + share->ext_key_parts*sizeof(KEY_PART_INFO);
3762 if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
3763 goto err;
3764 outparam->key_info= key_info;
3765 key_part= (reinterpret_cast<KEY_PART_INFO*>(key_info+share->keys));
3766
3767 memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
3768 memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
3769 share->ext_key_parts));
3770
3771 for (key_info_end= key_info + share->keys ;
3772 key_info < key_info_end ;
3773 key_info++)
3774 {
3775 KEY_PART_INFO *key_part_end;
3776
3777 key_info->table= outparam;
3778 key_info->key_part= key_part;
3779
3780 key_part_end= key_part + (share->use_ext_keys ? key_info->ext_key_parts :
3781 key_info->user_defined_key_parts) ;
3782 if (key_info->algorithm == HA_KEY_ALG_LONG_HASH)
3783 {
3784 key_part_end++;
3785 key_info->flags&= ~HA_NOSAME;
3786 }
3787 for ( ; key_part < key_part_end; key_part++)
3788 {
3789 Field *field= key_part->field= outparam->field[key_part->fieldnr - 1];
3790 if (field->key_length() != key_part->length &&
3791 !(field->flags & BLOB_FLAG))
3792 {
3793 /*
3794 We are using only a prefix of the column as a key:
3795 Create a new field for the key part that matches the index
3796 */
3797 field= key_part->field=field->make_new_field(&outparam->mem_root,
3798 outparam, 0);
3799 const_cast<uint32_t&>(field->field_length)= key_part->length;
3800 }
3801 }
3802 if (!share->use_ext_keys)
3803 key_part+= key_info->ext_key_parts - key_info->user_defined_key_parts;
3804 }
3805 }
3806
3807 /*
3808 Process virtual and default columns, if any.
3809 */
3810 if (share->virtual_fields || share->default_fields ||
3811 share->default_expressions || share->table_check_constraints)
3812 {
3813 Field **vfield_ptr, **dfield_ptr;
3814 Virtual_column_info **check_constraint_ptr;
3815
3816 if (!multi_alloc_root(&outparam->mem_root,
3817 &vfield_ptr, (uint) ((share->virtual_fields + 1)*
3818 sizeof(Field*)),
3819 &dfield_ptr, (uint) ((share->default_fields +
3820 share->default_expressions +1)*
3821 sizeof(Field*)),
3822 &check_constraint_ptr,
3823 (uint) ((share->table_check_constraints +
3824 share->field_check_constraints + 1)*
3825 sizeof(Virtual_column_info*)),
3826 NullS))
3827 goto err;
3828 if (share->virtual_fields)
3829 outparam->vfield= vfield_ptr;
3830 if (share->default_fields + share->default_expressions)
3831 outparam->default_field= dfield_ptr;
3832 if (share->table_check_constraints || share->field_check_constraints)
3833 outparam->check_constraints= check_constraint_ptr;
3834
3835 vcol_init_mode mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_WARNING;
3836 #if MYSQL_VERSION_ID > 100500
3837 switch (thd->lex->sql_command)
3838 {
3839 case SQLCOM_CREATE_TABLE:
3840 mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR;
3841 break;
3842 case SQLCOM_ALTER_TABLE:
3843 case SQLCOM_CREATE_INDEX:
3844 case SQLCOM_DROP_INDEX:
3845 if ((ha_open_flags & HA_OPEN_FOR_ALTER) == 0)
3846 mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR;
3847 break;
3848 default:
3849 break;
3850 }
3851 #endif
3852
3853 if (parse_vcol_defs(thd, &outparam->mem_root, outparam,
3854 &error_reported, mode))
3855 {
3856 error= OPEN_FRM_CORRUPTED;
3857 goto err;
3858 }
3859
3860 /* Update to use trigger fields */
3861 switch_defaults_to_nullable_trigger_fields(outparam);
3862
3863 for (uint k= 0; k < share->keys; k++)
3864 {
3865 KEY &key_info= outparam->key_info[k];
3866 uint parts = (share->use_ext_keys ? key_info.ext_key_parts :
3867 key_info.user_defined_key_parts);
3868 for (uint p= 0; p < parts; p++)
3869 {
3870 KEY_PART_INFO &kp= key_info.key_part[p];
3871 if (kp.field != outparam->field[kp.fieldnr - 1])
3872 {
3873 kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info;
3874 }
3875 }
3876 }
3877 }
3878
3879 #ifdef WITH_PARTITION_STORAGE_ENGINE
3880 bool work_part_info_used;
3881 if (share->partition_info_str_len && outparam->file)
3882 {
3883 /*
3884 In this execution we must avoid calling thd->change_item_tree since
3885 we might release memory before statement is completed. We do this
3886 by changing to a new statement arena. As part of this arena we also
3887 set the memory root to be the memory root of the table since we
3888 call the parser and fix_fields which both can allocate memory for
3889 item objects. We keep the arena to ensure that we can release the
3890 free_list when closing the table object.
3891 SEE Bug #21658
3892 */
3893
3894 Query_arena *backup_stmt_arena_ptr= thd->stmt_arena;
3895 Query_arena backup_arena;
3896 Query_arena part_func_arena(&outparam->mem_root,
3897 Query_arena::STMT_INITIALIZED);
3898 thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
3899 thd->stmt_arena= &part_func_arena;
3900 bool tmp;
3901
3902 tmp= mysql_unpack_partition(thd, share->partition_info_str,
3903 share->partition_info_str_len,
3904 outparam, is_create_table,
3905 plugin_hton(share->default_part_plugin),
3906 &work_part_info_used);
3907 if (tmp)
3908 {
3909 thd->stmt_arena= backup_stmt_arena_ptr;
3910 thd->restore_active_arena(&part_func_arena, &backup_arena);
3911 goto partititon_err;
3912 }
3913 outparam->part_info->is_auto_partitioned= share->auto_partitioned;
3914 DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
3915 /*
3916 We should perform the fix_partition_func in either local or
3917 caller's arena depending on work_part_info_used value.
3918 */
3919 if (!work_part_info_used)
3920 tmp= fix_partition_func(thd, outparam, is_create_table);
3921 thd->stmt_arena= backup_stmt_arena_ptr;
3922 thd->restore_active_arena(&part_func_arena, &backup_arena);
3923 if (!tmp)
3924 {
3925 if (work_part_info_used)
3926 tmp= fix_partition_func(thd, outparam, is_create_table);
3927 }
3928 outparam->part_info->item_free_list= part_func_arena.free_list;
3929 partititon_err:
3930 if (tmp)
3931 {
3932 if (is_create_table)
3933 {
3934 /*
3935 During CREATE/ALTER TABLE it is ok to receive errors here.
3936 It is not ok if it happens during the opening of an frm
3937 file as part of a normal query.
3938 */
3939 error_reported= TRUE;
3940 }
3941 goto err;
3942 }
3943 }
3944 #endif
3945
3946 /* Check virtual columns against table's storage engine. */
3947 if (share->virtual_fields &&
3948 (outparam->file &&
3949 !(outparam->file->ha_table_flags() & HA_CAN_VIRTUAL_COLUMNS)))
3950 {
3951 my_error(ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS, MYF(0),
3952 plugin_name(share->db_plugin)->str);
3953 error_reported= TRUE;
3954 goto err;
3955 }
3956
3957 /* Allocate bitmaps */
3958
3959 bitmap_size= share->column_bitmap_size;
3960 bitmap_count= 7;
3961 if (share->virtual_fields)
3962 bitmap_count++;
3963
3964 if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root,
3965 bitmap_size * bitmap_count)))
3966 goto err;
3967
3968 my_bitmap_init(&outparam->def_read_set,
3969 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3970 bitmaps+= bitmap_size;
3971 my_bitmap_init(&outparam->def_write_set,
3972 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3973 bitmaps+= bitmap_size;
3974
3975 my_bitmap_init(&outparam->has_value_set,
3976 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3977 bitmaps+= bitmap_size;
3978 my_bitmap_init(&outparam->tmp_set,
3979 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3980 bitmaps+= bitmap_size;
3981 my_bitmap_init(&outparam->eq_join_set,
3982 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3983 bitmaps+= bitmap_size;
3984 my_bitmap_init(&outparam->cond_set,
3985 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3986 bitmaps+= bitmap_size;
3987 my_bitmap_init(&outparam->def_rpl_write_set,
3988 (my_bitmap_map*) bitmaps, share->fields, FALSE);
3989 outparam->default_column_bitmaps();
3990
3991 outparam->cond_selectivity= 1.0;
3992
3993 /* The table struct is now initialized; Open the table */
3994 if (db_stat)
3995 {
3996 if (specialflag & SPECIAL_WAIT_IF_LOCKED)
3997 ha_open_flags|= HA_OPEN_WAIT_IF_LOCKED;
3998 else
3999 ha_open_flags|= HA_OPEN_IGNORE_IF_LOCKED;
4000
4001 int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str,
4002 (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
4003 ha_open_flags, 0, partitions_to_open);
4004 if (ha_err)
4005 {
4006 share->open_errno= ha_err;
4007 /* Set a flag if the table is crashed and it can be auto. repaired */
4008 share->crashed= (outparam->file->auto_repair(ha_err) &&
4009 !(ha_open_flags & HA_OPEN_FOR_REPAIR));
4010 if (!thd->is_error())
4011 outparam->file->print_error(ha_err, MYF(0));
4012 error_reported= TRUE;
4013
4014 if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
4015 error= OPEN_FRM_DISCOVER;
4016
4017 /*
4018 We're here, because .frm file was successfully opened.
4019
4020 But if the table doesn't exist in the engine and the engine
4021 supports discovery, we force rediscover to discover
4022 the fact that table doesn't in fact exist and remove
4023 the stray .frm file.
4024 */
4025 if (share->db_type()->discover_table &&
4026 (ha_err == ENOENT || ha_err == HA_ERR_NO_SUCH_TABLE))
4027 error= OPEN_FRM_DISCOVER;
4028
4029 goto err;
4030 }
4031 }
4032
4033 outparam->mark_columns_used_by_virtual_fields();
4034 if (!check_set_initialized &&
4035 share->check_set_initialized == TABLE_SHARE::V_KEYS)
4036 {
4037 // copy PART_INDIRECT_KEY_FLAG that was set meanwhile by *some* thread
4038 for (uint i= 0 ; i < share->fields ; i++)
4039 {
4040 if (share->field[i]->flags & PART_INDIRECT_KEY_FLAG)
4041 outparam->field[i]->flags|= PART_INDIRECT_KEY_FLAG;
4042 }
4043 }
4044
4045 if (db_stat)
4046 {
4047 /* Set some flags in share on first open of the table */
4048 handler::Table_flags flags= outparam->file->ha_table_flags();
4049 if (! MY_TEST(flags & (HA_BINLOG_STMT_CAPABLE |
4050 HA_BINLOG_ROW_CAPABLE)) ||
4051 MY_TEST(flags & HA_HAS_OWN_BINLOGGING))
4052 share->no_replicate= TRUE;
4053 if (outparam->file->table_cache_type() & HA_CACHE_TBL_NOCACHE)
4054 share->not_usable_by_query_cache= TRUE;
4055 if (outparam->file->ha_table_flags() & HA_CAN_ONLINE_BACKUPS)
4056 share->online_backup= 1;
4057 }
4058
4059 if (share->no_replicate || !binlog_filter->db_ok(share->db.str))
4060 share->can_do_row_logging= 0; // No row based replication
4061
4062 /* Increment the opened_tables counter, only when open flags set. */
4063 if (db_stat)
4064 thd->status_var.opened_tables++;
4065
4066 thd->lex->context_analysis_only= save_context_analysis_only;
4067 DBUG_EXECUTE_IF("print_long_unique_internal_state",
4068 print_long_unique_table(outparam););
4069 DBUG_RETURN (OPEN_FRM_OK);
4070
4071 err:
4072 if (! error_reported)
4073 open_table_error(share, error, my_errno);
4074 delete outparam->file;
4075 #ifdef WITH_PARTITION_STORAGE_ENGINE
4076 if (outparam->part_info)
4077 free_items(outparam->part_info->item_free_list);
4078 #endif
4079 outparam->file= 0; // For easier error checking
4080 outparam->db_stat=0;
4081 thd->lex->context_analysis_only= save_context_analysis_only;
4082 if (outparam->expr_arena)
4083 outparam->expr_arena->free_items();
4084 free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root
4085 outparam->alias.free();
4086 DBUG_RETURN (error);
4087 }
4088
4089
4090 /*
4091 Free information allocated by openfrm
4092
4093 SYNOPSIS
4094 closefrm()
4095 table TABLE object to free
4096 */
4097
closefrm(TABLE * table)4098 int closefrm(TABLE *table)
4099 {
4100 int error=0;
4101 DBUG_ENTER("closefrm");
4102 DBUG_PRINT("enter", ("table: %p", table));
4103
4104 if (table->db_stat)
4105 error=table->file->ha_close();
4106 table->alias.free();
4107 if (table->expr_arena)
4108 table->expr_arena->free_items();
4109 if (table->field)
4110 {
4111 for (Field **ptr=table->field ; *ptr ; ptr++)
4112 {
4113 delete *ptr;
4114 }
4115 table->field= 0;
4116 }
4117 delete table->file;
4118 table->file= 0; /* For easier errorchecking */
4119 #ifdef WITH_PARTITION_STORAGE_ENGINE
4120 if (table->part_info)
4121 {
4122 /* Allocated through table->mem_root, freed below */
4123 free_items(table->part_info->item_free_list);
4124 table->part_info->item_free_list= 0;
4125 table->part_info= 0;
4126 }
4127 #endif
4128 free_root(&table->mem_root, MYF(0));
4129 DBUG_RETURN(error);
4130 }
4131
4132
4133 /* Deallocate temporary blob storage */
4134
free_blobs(TABLE * table)4135 void free_blobs(TABLE *table)
4136 {
4137 uint *ptr, *end;
4138 for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
4139 ptr != end ;
4140 ptr++)
4141 {
4142 /*
4143 Reduced TABLE objects which are used by row-based replication for
4144 type conversion might have some fields missing. Skip freeing BLOB
4145 buffers for such missing fields.
4146 */
4147 if (table->field[*ptr])
4148 ((Field_blob*) table->field[*ptr])->free();
4149 }
4150 }
4151
4152
4153 /**
4154 Reclaim temporary blob storage which is bigger than
4155 a threshold.
4156
4157 @param table A handle to the TABLE object containing blob fields
4158 @param size The threshold value.
4159
4160 */
4161
free_field_buffers_larger_than(TABLE * table,uint32 size)4162 void free_field_buffers_larger_than(TABLE *table, uint32 size)
4163 {
4164 uint *ptr, *end;
4165 for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
4166 ptr != end ;
4167 ptr++)
4168 {
4169 Field_blob *blob= (Field_blob*) table->field[*ptr];
4170 if (blob->get_field_buffer_size() > size)
4171 blob->free();
4172 }
4173 }
4174
4175 /* error message when opening a form file */
4176
open_table_error(TABLE_SHARE * share,enum open_frm_error error,int db_errno)4177 void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
4178 int db_errno)
4179 {
4180 char buff[FN_REFLEN];
4181 const myf errortype= ME_ERROR_LOG; // Write fatals error to log
4182 DBUG_ENTER("open_table_error");
4183 DBUG_PRINT("info", ("error: %d db_errno: %d", error, db_errno));
4184
4185 switch (error) {
4186 case OPEN_FRM_OPEN_ERROR:
4187 /*
4188 Test if file didn't exists. We have to also test for EINVAL as this
4189 may happen on windows when opening a file with a not legal file name
4190 */
4191 if (db_errno == ENOENT || db_errno == EINVAL)
4192 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
4193 else
4194 {
4195 strxmov(buff, share->normalized_path.str, reg_ext, NullS);
4196 my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
4197 errortype, buff, db_errno);
4198 }
4199 break;
4200 case OPEN_FRM_OK:
4201 DBUG_ASSERT(0); // open_table_error() is never called for this one
4202 break;
4203 case OPEN_FRM_ERROR_ALREADY_ISSUED:
4204 break;
4205 case OPEN_FRM_NOT_A_VIEW:
4206 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str,
4207 share->table_name.str, "VIEW");
4208 break;
4209 case OPEN_FRM_NOT_A_TABLE:
4210 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str,
4211 share->table_name.str, "TABLE");
4212 break;
4213 case OPEN_FRM_DISCOVER:
4214 DBUG_ASSERT(0); // open_table_error() is never called for this one
4215 break;
4216 case OPEN_FRM_CORRUPTED:
4217 strxmov(buff, share->normalized_path.str, reg_ext, NullS);
4218 my_error(ER_NOT_FORM_FILE, errortype, buff);
4219 break;
4220 case OPEN_FRM_READ_ERROR:
4221 strxmov(buff, share->normalized_path.str, reg_ext, NullS);
4222 my_error(ER_ERROR_ON_READ, errortype, buff, db_errno);
4223 break;
4224 case OPEN_FRM_NEEDS_REBUILD:
4225 strxnmov(buff, sizeof(buff)-1,
4226 share->db.str, ".", share->table_name.str, NullS);
4227 my_error(ER_TABLE_NEEDS_REBUILD, errortype, buff);
4228 break;
4229 }
4230 DBUG_VOID_RETURN;
4231 } /* open_table_error */
4232
4233
4234 /*
4235 ** fix a str_type to a array type
4236 ** typeparts separated with some char. differents types are separated
4237 ** with a '\0'
4238 */
4239
4240 static bool
fix_type_pointers(const char *** typelib_value_names,uint ** typelib_value_lengths,TYPELIB * point_to_type,uint types,char * ptr,size_t length)4241 fix_type_pointers(const char ***typelib_value_names,
4242 uint **typelib_value_lengths,
4243 TYPELIB *point_to_type, uint types,
4244 char *ptr, size_t length)
4245 {
4246 const char *end= ptr + length;
4247
4248 while (types--)
4249 {
4250 char sep;
4251 point_to_type->name=0;
4252 point_to_type->type_names= *typelib_value_names;
4253 point_to_type->type_lengths= *typelib_value_lengths;
4254
4255 /*
4256 Typelib can be encoded as:
4257 1) 0x00 - empty typelib
4258 2) 0xFF 0x00 - empty typelib (index names)
4259 3) sep (value sep)... 0x00 - non-empty typelib (where sep is a separator)
4260 */
4261 if (length == 2 && ptr[0] == (char) 0xFF && ptr[1] == '\0')
4262 {
4263 /*
4264 This is a special case #2.
4265 If there are no indexes at all, index names can be encoded
4266 as a two byte sequence: 0xFF 0x00
4267 TODO: Check if it's a bug in the FRM packing routine.
4268 It should probably write just 0x00 instead of 0xFF00.
4269 */
4270 ptr+= 2;
4271 }
4272 else if ((sep= *ptr++)) // A non-empty typelib
4273 {
4274 for ( ; ptr < end; )
4275 {
4276 // Now scan the next value+sep pair
4277 char *vend= (char*) memchr(ptr, sep, end - ptr);
4278 if (!vend)
4279 return true; // Bad format
4280 *((*typelib_value_names)++)= ptr;
4281 *((*typelib_value_lengths)++)= (uint) (vend - ptr);
4282 *vend= '\0'; // Change sep to '\0'
4283 ptr= vend + 1; // Shift from sep to the next byte
4284 /*
4285 Now we can have either:
4286 - the end-of-typelib marker (0x00)
4287 - more value+sep pairs
4288 */
4289 if (!*ptr)
4290 {
4291 /*
4292 We have an ambiguity here. 0x00 can be an end-of-typelib marker,
4293 but it can also be a part of the next value:
4294 CREATE TABLE t1 (a ENUM(0x61, 0x0062) CHARACTER SET BINARY);
4295 If this is the last ENUM/SET in the table and there is still more
4296 packed data left after 0x00, then we know for sure that 0x00
4297 is a part of the next value.
4298 TODO-10.5+: we should eventually introduce a new unambiguous
4299 typelib encoding for FRM.
4300 */
4301 if (!types && ptr + 1 < end)
4302 continue; // A binary value starting with 0x00
4303 ptr++; // Consume the end-of-typelib marker
4304 break; // End of the current typelib
4305 }
4306 }
4307 }
4308 point_to_type->count= (uint) (*typelib_value_names -
4309 point_to_type->type_names);
4310 point_to_type++;
4311 *((*typelib_value_names)++)= NullS; /* End of type */
4312 *((*typelib_value_lengths)++)= 0; /* End of type */
4313 }
4314 return ptr != end;
4315 } /* fix_type_pointers */
4316
4317
4318 /*
4319 Search after a field with given start & length
4320 If an exact field isn't found, return longest field with starts
4321 at right position.
4322
4323 NOTES
4324 This is needed because in some .frm fields 'fieldnr' was saved wrong
4325
4326 RETURN
4327 0 error
4328 # field number +1
4329 */
4330
find_field(Field ** fields,uchar * record,uint start,uint length)4331 static uint find_field(Field **fields, uchar *record, uint start, uint length)
4332 {
4333 Field **field;
4334 uint i, pos;
4335
4336 pos= 0;
4337 for (field= fields, i=1 ; *field ; i++,field++)
4338 {
4339 if ((*field)->offset(record) == start)
4340 {
4341 if ((*field)->key_length() == length)
4342 return (i);
4343 if (!pos || fields[pos-1]->pack_length() <
4344 (*field)->pack_length())
4345 pos= i;
4346 }
4347 }
4348 return (pos);
4349 }
4350
4351
4352 /*
4353 Store an SQL quoted string.
4354
4355 SYNOPSIS
4356 append_unescaped()
4357 res result String
4358 pos string to be quoted
4359 length it's length
4360
4361 NOTE
4362 This function works correctly with utf8 or single-byte charset strings.
4363 May fail with some multibyte charsets though.
4364 */
4365
append_unescaped(String * res,const char * pos,size_t length)4366 void append_unescaped(String *res, const char *pos, size_t length)
4367 {
4368 const char *end= pos+length;
4369 res->append('\'');
4370
4371 for (; pos != end ; pos++)
4372 {
4373 switch (*pos) {
4374 case 0: /* Must be escaped for 'mysql' */
4375 res->append('\\');
4376 res->append('0');
4377 break;
4378 case '\n': /* Must be escaped for logs */
4379 res->append('\\');
4380 res->append('n');
4381 break;
4382 case '\r':
4383 res->append('\\'); /* This gives better readability */
4384 res->append('r');
4385 break;
4386 case '\\':
4387 res->append('\\'); /* Because of the sql syntax */
4388 res->append('\\');
4389 break;
4390 case '\'':
4391 res->append('\''); /* Because of the sql syntax */
4392 res->append('\'');
4393 break;
4394 default:
4395 res->append(*pos);
4396 break;
4397 }
4398 }
4399 res->append('\'');
4400 }
4401
4402
prepare_frm_header(THD * thd,uint reclength,uchar * fileinfo,HA_CREATE_INFO * create_info,uint keys,KEY * key_info)4403 void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo,
4404 HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
4405 {
4406 size_t key_comment_total_bytes= 0;
4407 uint i;
4408 uchar frm_format= create_info->expression_length ? FRM_VER_EXPRESSSIONS
4409 : FRM_VER_TRUE_VARCHAR;
4410 DBUG_ENTER("prepare_frm_header");
4411
4412 /* Fix this when we have new .frm files; Current limit is 4G rows (TODO) */
4413 if (create_info->max_rows > UINT_MAX32)
4414 create_info->max_rows= UINT_MAX32;
4415 if (create_info->min_rows > UINT_MAX32)
4416 create_info->min_rows= UINT_MAX32;
4417
4418 /*
4419 Keep in sync with pack_keys() in unireg.cc
4420 For each key:
4421 8 bytes for the key header
4422 9 bytes for each key-part (MAX_REF_PARTS)
4423 NAME_LEN bytes for the name
4424 1 byte for the NAMES_SEP_CHAR (before the name)
4425 For all keys:
4426 6 bytes for the header
4427 1 byte for the NAMES_SEP_CHAR (after the last name)
4428 9 extra bytes (padding for safety? alignment?)
4429 */
4430 for (i= 0; i < keys; i++)
4431 {
4432 DBUG_ASSERT(MY_TEST(key_info[i].flags & HA_USES_COMMENT) ==
4433 (key_info[i].comment.length > 0));
4434 if (key_info[i].flags & HA_USES_COMMENT)
4435 key_comment_total_bytes += 2 + key_info[i].comment.length;
4436 if (key_info[i].algorithm == HA_KEY_ALG_LONG_HASH)
4437 frm_format= FRM_VER_EXPRESSSIONS;
4438 }
4439
4440 size_t key_length, tmp_key_length, tmp, csid;
4441 bzero((char*) fileinfo, FRM_HEADER_SIZE);
4442 /* header */
4443 fileinfo[0]=(uchar) 254;
4444 fileinfo[1]= 1;
4445 fileinfo[2]= frm_format;
4446
4447 DBUG_ASSERT(ha_storage_engine_is_enabled(create_info->db_type));
4448 fileinfo[3]= (uchar) ha_legacy_type(create_info->db_type);
4449
4450 key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16
4451 + key_comment_total_bytes;
4452
4453 int2store(fileinfo+8,1);
4454 tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
4455 int2store(fileinfo+14,tmp_key_length);
4456 int2store(fileinfo+16,reclength);
4457 int4store(fileinfo+18,create_info->max_rows);
4458 int4store(fileinfo+22,create_info->min_rows);
4459 /* fileinfo[26] is set in mysql_create_frm() */
4460 fileinfo[27]=2; // Use long pack-fields
4461 /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
4462 create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
4463 int2store(fileinfo+30,create_info->table_options);
4464 fileinfo[32]=0; // No filename anymore
4465 fileinfo[33]=5; // Mark for 5.0 frm file
4466 int4store(fileinfo+34,create_info->avg_row_length);
4467 csid= (create_info->default_table_charset ?
4468 create_info->default_table_charset->number : 0);
4469 fileinfo[38]= (uchar) csid;
4470 fileinfo[39]= (uchar) ((uint) create_info->transactional |
4471 ((uint) create_info->page_checksum << 2) |
4472 ((create_info->sequence ? HA_CHOICE_YES : 0) << 4));
4473 fileinfo[40]= (uchar) create_info->row_type;
4474 /* Bytes 41-46 were for RAID support; now reused for other purposes */
4475 fileinfo[41]= (uchar) (csid >> 8);
4476 int2store(fileinfo+42, create_info->stats_sample_pages & 0xffff);
4477 fileinfo[44]= (uchar) create_info->stats_auto_recalc;
4478 int2store(fileinfo+45, (create_info->check_constraint_list->elements+
4479 create_info->field_check_constraints));
4480 int4store(fileinfo+47, key_length);
4481 tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store
4482 int4store(fileinfo+51, tmp);
4483 int4store(fileinfo+55, create_info->extra_size);
4484 /*
4485 59-60 is unused since 10.2.4
4486 61 for default_part_db_type
4487 */
4488 int2store(fileinfo+62, create_info->key_block_size);
4489 DBUG_VOID_RETURN;
4490 } /* prepare_fileinfo */
4491
4492
update_create_info_from_table(HA_CREATE_INFO * create_info,TABLE * table)4493 void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
4494 {
4495 TABLE_SHARE *share= table->s;
4496 DBUG_ENTER("update_create_info_from_table");
4497
4498 create_info->max_rows= share->max_rows;
4499 create_info->min_rows= share->min_rows;
4500 create_info->table_options= share->db_create_options;
4501 create_info->avg_row_length= share->avg_row_length;
4502 create_info->row_type= share->row_type;
4503 create_info->key_block_size= share->key_block_size;
4504 create_info->default_table_charset= share->table_charset;
4505 create_info->alter_table_convert_to_charset= 0;
4506 create_info->comment= share->comment;
4507 create_info->transactional= share->transactional;
4508 create_info->page_checksum= share->page_checksum;
4509 create_info->option_list= share->option_list;
4510 create_info->sequence= MY_TEST(share->sequence);
4511
4512 DBUG_VOID_RETURN;
4513 }
4514
4515 int
rename_file_ext(const char * from,const char * to,const char * ext)4516 rename_file_ext(const char * from,const char * to,const char * ext)
4517 {
4518 char from_b[FN_REFLEN],to_b[FN_REFLEN];
4519 (void) strxmov(from_b,from,ext,NullS);
4520 (void) strxmov(to_b,to,ext,NullS);
4521 return mysql_file_rename(key_file_frm, from_b, to_b, MYF(0));
4522 }
4523
4524
4525 /*
4526 Allocate string field in MEM_ROOT and return it as String
4527
4528 SYNOPSIS
4529 get_field()
4530 mem MEM_ROOT for allocating
4531 field Field for retrieving of string
4532 res result String
4533
4534 RETURN VALUES
4535 1 string is empty
4536 0 all ok
4537 */
4538
get_field(MEM_ROOT * mem,Field * field,String * res)4539 bool get_field(MEM_ROOT *mem, Field *field, String *res)
4540 {
4541 char *to;
4542 StringBuffer<MAX_FIELD_WIDTH> str;
4543 bool rc;
4544 THD *thd= field->get_thd();
4545 sql_mode_t sql_mode_backup= thd->variables.sql_mode;
4546 thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
4547
4548 field->val_str(&str);
4549 if ((rc= !str.length() ||
4550 !(to= strmake_root(mem, str.ptr(), str.length()))))
4551 {
4552 res->length(0);
4553 goto ex;
4554 }
4555 res->set(to, str.length(), field->charset());
4556
4557 ex:
4558 thd->variables.sql_mode= sql_mode_backup;
4559 return rc;
4560 }
4561
4562
4563 /*
4564 Allocate string field in MEM_ROOT and return it as NULL-terminated string
4565
4566 SYNOPSIS
4567 get_field()
4568 mem MEM_ROOT for allocating
4569 field Field for retrieving of string
4570
4571 RETURN VALUES
4572 NullS string is empty
4573 # pointer to NULL-terminated string value of field
4574 */
4575
get_field(MEM_ROOT * mem,Field * field)4576 char *get_field(MEM_ROOT *mem, Field *field)
4577 {
4578 String str;
4579 bool rc= get_field(mem, field, &str);
4580 DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0');
4581 return rc ? NullS : (char *) str.ptr();
4582 }
4583
4584 /*
4585 DESCRIPTION
4586 given a buffer with a key value, and a map of keyparts
4587 that are present in this value, returns the length of the value
4588 */
calculate_key_len(TABLE * table,uint key,const uchar * buf,key_part_map keypart_map)4589 uint calculate_key_len(TABLE *table, uint key, const uchar *buf,
4590 key_part_map keypart_map)
4591 {
4592 /* works only with key prefixes */
4593 DBUG_ASSERT(((keypart_map + 1) & keypart_map) == 0);
4594
4595 KEY *key_info= table->key_info+key;
4596 KEY_PART_INFO *key_part= key_info->key_part;
4597 KEY_PART_INFO *end_key_part= key_part + table->actual_n_key_parts(key_info);
4598 uint length= 0;
4599
4600 while (key_part < end_key_part && keypart_map)
4601 {
4602 length+= key_part->store_length;
4603 keypart_map >>= 1;
4604 key_part++;
4605 }
4606 return length;
4607 }
4608
4609 #ifndef DBUG_OFF
4610 /**
4611 Verifies that database/table name is in lowercase, when it should be
4612
4613 This is supposed to be used only inside DBUG_ASSERT()
4614 */
ok_for_lower_case_names(const char * name)4615 bool ok_for_lower_case_names(const char *name)
4616 {
4617 if (!lower_case_table_names || !name)
4618 return true;
4619
4620 char buf[SAFE_NAME_LEN];
4621 strmake_buf(buf, name);
4622 my_casedn_str(files_charset_info, buf);
4623 return strcmp(name, buf) == 0;
4624 }
4625 #endif
4626
4627 /*
4628 Check if database name is valid
4629
4630 SYNPOSIS
4631 check_db_name()
4632 org_name Name of database
4633
4634 NOTES
4635 If lower_case_table_names is set to 1 then database name is converted
4636 to lower case
4637
4638 RETURN
4639 0 ok
4640 1 error
4641 */
4642
check_db_name(LEX_STRING * org_name)4643 bool check_db_name(LEX_STRING *org_name)
4644 {
4645 char *name= org_name->str;
4646 size_t name_length= org_name->length;
4647 bool check_for_path_chars;
4648
4649 if ((check_for_path_chars= check_mysql50_prefix(name)))
4650 {
4651 name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
4652 name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
4653 }
4654
4655 if (!name_length || name_length > NAME_LEN)
4656 return 1;
4657
4658 if (lower_case_table_names == 1 && name != any_db)
4659 {
4660 org_name->length= name_length= my_casedn_str(files_charset_info, name);
4661 if (check_for_path_chars)
4662 org_name->length+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
4663 }
4664 if (db_name_is_in_ignore_db_dirs_list(name))
4665 return 1;
4666
4667 return check_table_name(name, name_length, check_for_path_chars);
4668 }
4669
4670
4671 /*
4672 Allow anything as a table name, as long as it doesn't contain an
4673 ' ' at the end
4674 returns 1 on error
4675 */
4676
check_table_name(const char * name,size_t length,bool check_for_path_chars)4677 bool check_table_name(const char *name, size_t length, bool check_for_path_chars)
4678 {
4679 // name length in symbols
4680 size_t name_length= 0;
4681 const char *end= name+length;
4682
4683 if (!check_for_path_chars &&
4684 (check_for_path_chars= check_mysql50_prefix(name)))
4685 {
4686 name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
4687 length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
4688 }
4689
4690 if (!length || length > NAME_LEN)
4691 return 1;
4692 #if defined(USE_MB) && defined(USE_MB_IDENT)
4693 bool last_char_is_space= FALSE;
4694 #else
4695 if (name[length-1]==' ')
4696 return 1;
4697 #endif
4698
4699 while (name != end)
4700 {
4701 #if defined(USE_MB) && defined(USE_MB_IDENT)
4702 last_char_is_space= my_isspace(system_charset_info, *name);
4703 if (use_mb(system_charset_info))
4704 {
4705 int len=my_ismbchar(system_charset_info, name, end);
4706 if (len)
4707 {
4708 name+= len;
4709 name_length++;
4710 continue;
4711 }
4712 }
4713 #endif
4714 if (check_for_path_chars &&
4715 (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
4716 return 1;
4717 /*
4718 We don't allow zero byte in table/schema names:
4719 - Some code still uses NULL-terminated strings.
4720 Zero bytes will confuse this code.
4721 - There is a little practical use of zero bytes in names anyway.
4722 Note, if the string passed as "name" comes here
4723 from the parser as an identifier, it does not contain zero bytes,
4724 as the parser rejects zero bytes in identifiers.
4725 But "name" can also come here from queries like this:
4726 SELECT * FROM I_S.TABLES WHERE TABLE_NAME='str';
4727 In this case "name" is a general string expression
4728 and it can have any arbitrary bytes, including zero bytes.
4729 */
4730 if (*name == 0x00)
4731 return 1;
4732 name++;
4733 name_length++;
4734 }
4735 #if defined(USE_MB) && defined(USE_MB_IDENT)
4736 return last_char_is_space || (name_length > NAME_CHAR_LEN);
4737 #else
4738 return FALSE;
4739 #endif
4740 }
4741
4742
check_column_name(const char * name)4743 bool check_column_name(const char *name)
4744 {
4745 // name length in symbols
4746 size_t name_length= 0;
4747 bool last_char_is_space= TRUE;
4748
4749 while (*name)
4750 {
4751 #if defined(USE_MB) && defined(USE_MB_IDENT)
4752 last_char_is_space= my_isspace(system_charset_info, *name);
4753 if (use_mb(system_charset_info))
4754 {
4755 int len=my_ismbchar(system_charset_info, name,
4756 name+system_charset_info->mbmaxlen);
4757 if (len)
4758 {
4759 name += len;
4760 name_length++;
4761 continue;
4762 }
4763 }
4764 #else
4765 last_char_is_space= *name==' ';
4766 if (*name == '\377')
4767 return 1;
4768 #endif
4769 name++;
4770 name_length++;
4771 }
4772 /* Error if empty or too long column name */
4773 return last_char_is_space || (name_length > NAME_CHAR_LEN);
4774 }
4775
4776
4777 /**
4778 Checks whether a table is intact. Should be done *just* after the table has
4779 been opened.
4780
4781 @param[in] table The table to check
4782 @param[in] table_def Expected structure of the table (column name
4783 and type)
4784
4785 @retval FALSE OK
4786 @retval TRUE There was an error. An error message is output
4787 to the error log. We do not push an error
4788 message into the error stack because this
4789 function is currently only called at start up,
4790 and such errors never reach the user.
4791 */
4792
4793 bool
check(TABLE * table,const TABLE_FIELD_DEF * table_def)4794 Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
4795 {
4796 uint i;
4797 my_bool error= FALSE;
4798 const TABLE_FIELD_TYPE *field_def= table_def->field;
4799 DBUG_ENTER("table_check_intact");
4800 DBUG_PRINT("info",("table: %s expected_count: %d",
4801 table->alias.c_ptr(), table_def->count));
4802
4803 /* Whether the table definition has already been validated. */
4804 if (table->s->table_field_def_cache == table_def)
4805 goto end;
4806
4807 if (table->s->fields != table_def->count)
4808 {
4809 THD *thd= current_thd;
4810 DBUG_PRINT("info", ("Column count has changed, checking the definition"));
4811
4812 /* previous MySQL version */
4813 if (MYSQL_VERSION_ID > table->s->mysql_version)
4814 {
4815 report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE,
4816 ER_THD(thd, ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
4817 table->alias.c_ptr(), table_def->count, table->s->fields,
4818 static_cast<int>(table->s->mysql_version),
4819 MYSQL_VERSION_ID);
4820 DBUG_RETURN(TRUE);
4821 }
4822 else if (MYSQL_VERSION_ID == table->s->mysql_version)
4823 {
4824 report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2,
4825 ER_THD(thd, ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2),
4826 table->s->db.str, table->s->table_name.str,
4827 table_def->count, table->s->fields);
4828 DBUG_RETURN(TRUE);
4829 }
4830 /*
4831 Something has definitely changed, but we're running an older
4832 version of MySQL with new system tables.
4833 Let's check column definitions. If a column was added at
4834 the end of the table, then we don't care much since such change
4835 is backward compatible.
4836 */
4837 }
4838 else
4839 {
4840 StringBuffer<1024> sql_type(system_charset_info);
4841 sql_type.extra_allocation(256); // Allocate min 256 characters at once
4842 for (i=0 ; i < table_def->count; i++, field_def++)
4843 {
4844 sql_type.length(0);
4845 if (i < table->s->fields)
4846 {
4847 Field *field= table->field[i];
4848
4849 if (strncmp(field->field_name.str, field_def->name.str,
4850 field_def->name.length))
4851 {
4852 /*
4853 Name changes are not fatal, we use ordinal numbers to access columns.
4854 Still this can be a sign of a tampered table, output an error
4855 to the error log.
4856 */
4857 report_error(0, "Incorrect definition of table %s.%s: "
4858 "expected column '%s' at position %d, found '%s'.",
4859 table->s->db.str, table->alias.c_ptr(),
4860 field_def->name.str, i,
4861 field->field_name.str);
4862 }
4863 field->sql_type(sql_type);
4864 /*
4865 Generally, if column types don't match, then something is
4866 wrong.
4867
4868 However, we only compare column definitions up to the
4869 length of the original definition, since we consider the
4870 following definitions compatible:
4871
4872 1. DATETIME and DATETIM
4873 2. INT(11) and INT(11
4874 3. SET('one', 'two') and SET('one', 'two', 'more')
4875
4876 For SETs or ENUMs, if the same prefix is there it's OK to
4877 add more elements - they will get higher ordinal numbers and
4878 the new table definition is backward compatible with the
4879 original one.
4880 */
4881 if (strncmp(sql_type.c_ptr_safe(), field_def->type.str,
4882 field_def->type.length - 1))
4883 {
4884 report_error(0, "Incorrect definition of table %s.%s: "
4885 "expected column '%s' at position %d to have type "
4886 "%s, found type %s.", table->s->db.str,
4887 table->alias.c_ptr(),
4888 field_def->name.str, i, field_def->type.str,
4889 sql_type.c_ptr_safe());
4890 error= TRUE;
4891 }
4892 else if (field_def->cset.str && !field->has_charset())
4893 {
4894 report_error(0, "Incorrect definition of table %s.%s: "
4895 "expected the type of column '%s' at position %d "
4896 "to have character set '%s' but the type has no "
4897 "character set.", table->s->db.str,
4898 table->alias.c_ptr(),
4899 field_def->name.str, i, field_def->cset.str);
4900 error= TRUE;
4901 }
4902 else if (field_def->cset.str &&
4903 strcmp(field->charset()->csname, field_def->cset.str))
4904 {
4905 report_error(0, "Incorrect definition of table %s.%s: "
4906 "expected the type of column '%s' at position %d "
4907 "to have character set '%s' but found "
4908 "character set '%s'.", table->s->db.str,
4909 table->alias.c_ptr(),
4910 field_def->name.str, i, field_def->cset.str,
4911 field->charset()->csname);
4912 error= TRUE;
4913 }
4914 }
4915 else
4916 {
4917 report_error(0, "Incorrect definition of table %s.%s: "
4918 "expected column '%s' at position %d to have type %s "
4919 " but the column is not found.",
4920 table->s->db.str, table->alias.c_ptr(),
4921 field_def->name.str, i, field_def->type.str);
4922 error= TRUE;
4923 }
4924 }
4925 }
4926
4927 if (table_def->primary_key_parts)
4928 {
4929 if (table->s->primary_key == MAX_KEY)
4930 {
4931 report_error(0, "Incorrect definition of table %s.%s: "
4932 "missing primary key.", table->s->db.str,
4933 table->alias.c_ptr());
4934 error= TRUE;
4935 }
4936 else
4937 {
4938 KEY *pk= &table->s->key_info[table->s->primary_key];
4939 if (pk->user_defined_key_parts != table_def->primary_key_parts)
4940 {
4941 report_error(0, "Incorrect definition of table %s.%s: "
4942 "Expected primary key to have %u columns, but instead "
4943 "found %u columns.", table->s->db.str,
4944 table->alias.c_ptr(), table_def->primary_key_parts,
4945 pk->user_defined_key_parts);
4946 error= TRUE;
4947 }
4948 else
4949 {
4950 for (i= 0; i < pk->user_defined_key_parts; ++i)
4951 {
4952 if (table_def->primary_key_columns[i] + 1 != pk->key_part[i].fieldnr)
4953 {
4954 report_error(0, "Incorrect definition of table %s.%s: Expected "
4955 "primary key part %u to refer to column %u, but "
4956 "instead found column %u.", table->s->db.str,
4957 table->alias.c_ptr(), i + 1,
4958 table_def->primary_key_columns[i] + 1,
4959 pk->key_part[i].fieldnr);
4960 error= TRUE;
4961 }
4962 }
4963 }
4964 }
4965 }
4966
4967 if (likely(! error))
4968 table->s->table_field_def_cache= table_def;
4969
4970 end:
4971
4972 if (has_keys && !error && !table->key_info)
4973 {
4974 report_error(0, "Incorrect definition of table %s.%s: "
4975 "indexes are missing",
4976 table->s->db.str, table->alias.c_ptr());
4977 error= TRUE;
4978 }
4979
4980 DBUG_RETURN(error);
4981 }
4982
4983
report_error(uint,const char * fmt,...)4984 void Table_check_intact_log_error::report_error(uint, const char *fmt, ...)
4985 {
4986 va_list args;
4987 va_start(args, fmt);
4988 error_log_print(ERROR_LEVEL, fmt, args);
4989 va_end(args);
4990 }
4991
4992
4993 /**
4994 Traverse portion of wait-for graph which is reachable through edge
4995 represented by this flush ticket in search for deadlocks.
4996
4997 @retval TRUE A deadlock is found. A victim is remembered
4998 by the visitor.
4999 @retval FALSE Success, no deadlocks.
5000 */
5001
accept_visitor(MDL_wait_for_graph_visitor * gvisitor)5002 bool Wait_for_flush::accept_visitor(MDL_wait_for_graph_visitor *gvisitor)
5003 {
5004 return m_share->visit_subgraph(this, gvisitor);
5005 }
5006
5007
get_deadlock_weight() const5008 uint Wait_for_flush::get_deadlock_weight() const
5009 {
5010 return m_deadlock_weight;
5011 }
5012
5013
5014 /**
5015 Traverse portion of wait-for graph which is reachable through this
5016 table share in search for deadlocks.
5017
5018 @param waiting_ticket Ticket representing wait for this share.
5019 @param dvisitor Deadlock detection visitor.
5020
5021 @retval TRUE A deadlock is found. A victim is remembered
5022 by the visitor.
5023 @retval FALSE No deadlocks, it's OK to begin wait.
5024 */
5025
visit_subgraph(Wait_for_flush * wait_for_flush,MDL_wait_for_graph_visitor * gvisitor)5026 bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
5027 MDL_wait_for_graph_visitor *gvisitor)
5028 {
5029 TABLE *table;
5030 MDL_context *src_ctx= wait_for_flush->get_ctx();
5031 bool result= TRUE;
5032
5033 /*
5034 To protect all_tables list from being concurrently modified
5035 while we are iterating through it we increment tdc.all_tables_refs.
5036 This does not introduce deadlocks in the deadlock detector
5037 because we won't try to acquire tdc.LOCK_table_share while
5038 holding a write-lock on MDL_lock::m_rwlock.
5039 */
5040 mysql_mutex_lock(&tdc->LOCK_table_share);
5041 tdc->all_tables_refs++;
5042 mysql_mutex_unlock(&tdc->LOCK_table_share);
5043
5044 All_share_tables_list::Iterator tables_it(tdc->all_tables);
5045
5046 /*
5047 In case of multiple searches running in parallel, avoid going
5048 over the same loop twice and shortcut the search.
5049 Do it after taking the lock to weed out unnecessary races.
5050 */
5051 if (src_ctx->m_wait.get_status() != MDL_wait::EMPTY)
5052 {
5053 result= FALSE;
5054 goto end;
5055 }
5056
5057 if (gvisitor->enter_node(src_ctx))
5058 goto end;
5059
5060 while ((table= tables_it++))
5061 {
5062 DBUG_ASSERT(table->in_use && tdc->flushed);
5063 if (gvisitor->inspect_edge(&table->in_use->mdl_context))
5064 {
5065 goto end_leave_node;
5066 }
5067 }
5068
5069 tables_it.rewind();
5070 while ((table= tables_it++))
5071 {
5072 DBUG_ASSERT(table->in_use && tdc->flushed);
5073 if (table->in_use->mdl_context.visit_subgraph(gvisitor))
5074 {
5075 goto end_leave_node;
5076 }
5077 }
5078
5079 result= FALSE;
5080
5081 end_leave_node:
5082 gvisitor->leave_node(src_ctx);
5083
5084 end:
5085 mysql_mutex_lock(&tdc->LOCK_table_share);
5086 if (!--tdc->all_tables_refs)
5087 mysql_cond_broadcast(&tdc->COND_release);
5088 mysql_mutex_unlock(&tdc->LOCK_table_share);
5089
5090 return result;
5091 }
5092
5093
5094 /**
5095 Wait until the subject share is removed from the table
5096 definition cache and make sure it's destroyed.
5097
5098 @param mdl_context MDL context for thread which is going to wait.
5099 @param abstime Timeout for waiting as absolute time value.
5100 @param deadlock_weight Weight of this wait for deadlock detector.
5101
5102 @pre LOCK_table_share is locked, the share is marked for flush and
5103 this connection does not reference the share.
5104 LOCK_table_share will be unlocked temporarily during execution.
5105
5106 It may happen that another FLUSH TABLES thread marked this share
5107 for flush, but didn't yet purge it from table definition cache.
5108 In this case we may start waiting for a table share that has no
5109 references (ref_count == 0). We do this with assumption that this
5110 another FLUSH TABLES thread is about to purge this share.
5111
5112 @retval FALSE - Success.
5113 @retval TRUE - Error (OOM, deadlock, timeout, etc...).
5114 */
5115
wait_for_old_version(THD * thd,struct timespec * abstime,uint deadlock_weight)5116 bool TABLE_SHARE::wait_for_old_version(THD *thd, struct timespec *abstime,
5117 uint deadlock_weight)
5118 {
5119 MDL_context *mdl_context= &thd->mdl_context;
5120 Wait_for_flush ticket(mdl_context, this, deadlock_weight);
5121 MDL_wait::enum_wait_status wait_status;
5122
5123 mysql_mutex_assert_owner(&tdc->LOCK_table_share);
5124 DBUG_ASSERT(tdc->flushed);
5125
5126 tdc->m_flush_tickets.push_front(&ticket);
5127
5128 mdl_context->m_wait.reset_status();
5129
5130 mysql_mutex_unlock(&tdc->LOCK_table_share);
5131
5132 mdl_context->will_wait_for(&ticket);
5133
5134 mdl_context->find_deadlock();
5135
5136 wait_status= mdl_context->m_wait.timed_wait(thd, abstime, TRUE,
5137 &stage_waiting_for_table_flush);
5138
5139 mdl_context->done_waiting_for();
5140
5141 mysql_mutex_lock(&tdc->LOCK_table_share);
5142 tdc->m_flush_tickets.remove(&ticket);
5143 mysql_cond_broadcast(&tdc->COND_release);
5144 mysql_mutex_unlock(&tdc->LOCK_table_share);
5145
5146
5147 /*
5148 In cases when our wait was aborted by KILL statement,
5149 a deadlock or a timeout, the share might still be referenced,
5150 so we don't delete it. Note, that we can't determine this
5151 condition by checking wait_status alone, since, for example,
5152 a timeout can happen after all references to the table share
5153 were released, but before the share is removed from the
5154 cache and we receive the notification. This is why
5155 we first destroy the share, and then look at
5156 wait_status.
5157 */
5158 switch (wait_status)
5159 {
5160 case MDL_wait::GRANTED:
5161 return FALSE;
5162 case MDL_wait::VICTIM:
5163 my_error(ER_LOCK_DEADLOCK, MYF(0));
5164 return TRUE;
5165 case MDL_wait::TIMEOUT:
5166 my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
5167 return TRUE;
5168 case MDL_wait::KILLED:
5169 return TRUE;
5170 default:
5171 DBUG_ASSERT(0);
5172 return TRUE;
5173 }
5174 }
5175
5176
5177 /**
5178 Initialize TABLE instance (newly created, or coming either from table
5179 cache or THD::temporary_tables list) and prepare it for further use
5180 during statement execution. Set the 'alias' attribute from the specified
5181 TABLE_LIST element. Remember the TABLE_LIST element in the
5182 TABLE::pos_in_table_list member.
5183
5184 @param thd Thread context.
5185 @param tl TABLE_LIST element.
5186 */
5187
init(THD * thd,TABLE_LIST * tl)5188 void TABLE::init(THD *thd, TABLE_LIST *tl)
5189 {
5190 DBUG_ASSERT(s->tmp_table != NO_TMP_TABLE || s->tdc->ref_count > 0);
5191
5192 if (thd->lex->need_correct_ident())
5193 alias_name_used= my_strcasecmp(table_alias_charset,
5194 s->table_name.str,
5195 tl->alias.str);
5196 /* Fix alias if table name changes. */
5197 if (!alias.alloced_length() || strcmp(alias.c_ptr(), tl->alias.str))
5198 alias.copy(tl->alias.str, tl->alias.length, alias.charset());
5199
5200 tablenr= thd->current_tablenr++;
5201 used_fields= 0;
5202 const_table= 0;
5203 null_row= 0;
5204 maybe_null= 0;
5205 force_index= 0;
5206 force_index_order= 0;
5207 force_index_group= 0;
5208 status= STATUS_NO_RECORD;
5209 insert_values= 0;
5210 fulltext_searched= 0;
5211 file->ft_handler= 0;
5212 reginfo.impossible_range= 0;
5213 reginfo.join_tab= NULL;
5214 reginfo.not_exists_optimize= FALSE;
5215 created= TRUE;
5216 cond_selectivity= 1.0;
5217 cond_selectivity_sampling_explain= NULL;
5218 range_rowid_filter_cost_info_elems= 0;
5219 range_rowid_filter_cost_info_ptr= NULL;
5220 range_rowid_filter_cost_info= NULL;
5221 update_handler= NULL;
5222 check_unique_buf= NULL;
5223 vers_write= s->versioned;
5224 quick_condition_rows=0;
5225 no_cache= false;
5226 initialize_quick_structures();
5227 #ifdef HAVE_REPLICATION
5228 /* used in RBR Triggers */
5229 master_had_triggers= 0;
5230 #endif
5231
5232 /* Catch wrong handling of the auto_increment_field_not_null. */
5233 DBUG_ASSERT(!auto_increment_field_not_null);
5234 auto_increment_field_not_null= FALSE;
5235
5236 pos_in_table_list= tl;
5237
5238 clear_column_bitmaps();
5239 for (Field **f_ptr= field ; *f_ptr ; f_ptr++)
5240 {
5241 (*f_ptr)->next_equal_field= NULL;
5242 (*f_ptr)->cond_selectivity= 1.0;
5243 }
5244
5245 DBUG_ASSERT(!file->keyread_enabled());
5246
5247 restore_record(this, s->default_values);
5248
5249 /* Tables may be reused in a sub statement. */
5250 DBUG_ASSERT(!file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
5251 }
5252
5253
5254 /*
5255 Create Item_field for each column in the table.
5256
5257 SYNPOSIS
5258 TABLE::fill_item_list()
5259 item_list a pointer to an empty list used to store items
5260
5261 DESCRIPTION
5262 Create Item_field object for each column in the table and
5263 initialize it with the corresponding Field. New items are
5264 created in the current THD memory root.
5265
5266 RETURN VALUE
5267 0 success
5268 1 out of memory
5269 */
5270
fill_item_list(List<Item> * item_list) const5271 bool TABLE::fill_item_list(List<Item> *item_list) const
5272 {
5273 /*
5274 All Item_field's created using a direct pointer to a field
5275 are fixed in Item_field constructor.
5276 */
5277 for (Field **ptr= field; *ptr; ptr++)
5278 {
5279 Item_field *item= new (in_use->mem_root) Item_field(in_use, *ptr);
5280 if (!item || item_list->push_back(item))
5281 return TRUE;
5282 }
5283 return FALSE;
5284 }
5285
5286 /*
5287 Reset an existing list of Item_field items to point to the
5288 Fields of this table.
5289
5290 SYNPOSIS
5291 TABLE::fill_item_list()
5292 item_list a non-empty list with Item_fields
5293
5294 DESCRIPTION
5295 This is a counterpart of fill_item_list used to redirect
5296 Item_fields to the fields of a newly created table.
5297 The caller must ensure that number of items in the item_list
5298 is the same as the number of columns in the table.
5299 */
5300
reset_item_list(List<Item> * item_list,uint skip) const5301 void TABLE::reset_item_list(List<Item> *item_list, uint skip) const
5302 {
5303 List_iterator_fast<Item> it(*item_list);
5304 Field **ptr= field;
5305 for ( ; skip && *ptr; skip--)
5306 ptr++;
5307 for (; *ptr; ptr++)
5308 {
5309 Item_field *item_field= (Item_field*) it++;
5310 DBUG_ASSERT(item_field != 0);
5311 item_field->reset_field(*ptr);
5312 }
5313 }
5314
5315 /*
5316 calculate md5 of query
5317
5318 SYNOPSIS
5319 TABLE_LIST::calc_md5()
5320 buffer buffer for md5 writing
5321 */
5322
calc_md5(char * buffer)5323 void TABLE_LIST::calc_md5(char *buffer)
5324 {
5325 uchar digest[16];
5326 compute_md5_hash(digest, select_stmt.str,
5327 select_stmt.length);
5328 sprintf(buffer,
5329 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
5330 digest[0], digest[1], digest[2], digest[3],
5331 digest[4], digest[5], digest[6], digest[7],
5332 digest[8], digest[9], digest[10], digest[11],
5333 digest[12], digest[13], digest[14], digest[15]);
5334 }
5335
5336
5337 /**
5338 @brief
5339 Create field translation for mergeable derived table/view.
5340
5341 @param thd Thread handle
5342
5343 @details
5344 Create field translation for mergeable derived table/view.
5345
5346 @return FALSE ok.
5347 @return TRUE an error occur.
5348 */
5349
create_field_translation(THD * thd)5350 bool TABLE_LIST::create_field_translation(THD *thd)
5351 {
5352 Item *item;
5353 Field_translator *transl;
5354 SELECT_LEX *select= get_single_select();
5355 List_iterator_fast<Item> it(select->item_list);
5356 uint field_count= 0;
5357 Query_arena *arena, backup;
5358 bool res= FALSE;
5359 DBUG_ENTER("TABLE_LIST::create_field_translation");
5360 DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
5361 (alias.str ? alias.str : "<NULL>"),
5362 get_unit()));
5363
5364 if (thd->stmt_arena->is_conventional() ||
5365 thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
5366 {
5367 /* initialize lists */
5368 used_items.empty();
5369 persistent_used_items.empty();
5370 }
5371 else
5372 {
5373 /*
5374 Copy the list created by natural join procedure because the procedure
5375 will not be repeated.
5376 */
5377 used_items= persistent_used_items;
5378 }
5379
5380 if (field_translation)
5381 {
5382 /*
5383 Update items in the field translation after view have been prepared.
5384 It's needed because some items in the select list, like IN subselects,
5385 might be substituted for optimized ones.
5386 */
5387 if (is_view() && get_unit()->prepared && !field_translation_updated)
5388 {
5389 field_translation_updated= TRUE;
5390 if (static_cast<uint>(field_translation_end - field_translation) <
5391 select->item_list.elements)
5392 goto allocate;
5393 while ((item= it++))
5394 {
5395 field_translation[field_count++].item= item;
5396 }
5397 }
5398
5399 DBUG_RETURN(FALSE);
5400 }
5401
5402 allocate:
5403 arena= thd->activate_stmt_arena_if_needed(&backup);
5404
5405 /* Create view fields translation table */
5406
5407 if (!(transl=
5408 (Field_translator*)(thd->stmt_arena->
5409 alloc(select->item_list.elements *
5410 sizeof(Field_translator)))))
5411 {
5412 res= TRUE;
5413 goto exit;
5414 }
5415
5416 while ((item= it++))
5417 {
5418 DBUG_ASSERT(item->name.str && item->name.str[0]);
5419 transl[field_count].name.str= thd->strmake(item->name.str, item->name.length);
5420 transl[field_count].name.length= item->name.length;
5421 transl[field_count++].item= item;
5422 }
5423 field_translation= transl;
5424 field_translation_end= transl + field_count;
5425 /* It's safe to cache this table for prepared statements */
5426 cacheable_table= 1;
5427
5428 exit:
5429 if (arena)
5430 thd->restore_active_arena(arena, &backup);
5431
5432 DBUG_RETURN(res);
5433 }
5434
5435
5436 /**
5437 @brief
5438 Create field translation for mergeable derived table/view.
5439
5440 @param thd Thread handle
5441
5442 @details
5443 Create field translation for mergeable derived table/view.
5444
5445 @return FALSE ok.
5446 @return TRUE an error occur.
5447 */
5448
setup_underlying(THD * thd)5449 bool TABLE_LIST::setup_underlying(THD *thd)
5450 {
5451 DBUG_ENTER("TABLE_LIST::setup_underlying");
5452
5453 if (!view || (!field_translation && merge_underlying_list))
5454 {
5455 SELECT_LEX *select= get_single_select();
5456
5457 if (create_field_translation(thd))
5458 DBUG_RETURN(TRUE);
5459
5460 /* full text function moving to current select */
5461 if (select->ftfunc_list->elements)
5462 {
5463 Item_func_match *ifm;
5464 SELECT_LEX *current_select= thd->lex->current_select;
5465 List_iterator_fast<Item_func_match>
5466 li(*(select_lex->ftfunc_list));
5467 while ((ifm= li++))
5468 current_select->ftfunc_list->push_front(ifm);
5469 }
5470 }
5471 DBUG_RETURN(FALSE);
5472 }
5473
5474
5475 /*
5476 Prepare where expression of derived table/view
5477
5478 SYNOPSIS
5479 TABLE_LIST::prep_where()
5480 thd - thread handler
5481 conds - condition of this JOIN
5482 no_where_clause - do not build WHERE or ON outer qwery do not need it
5483 (it is INSERT), we do not need conds if this flag is set
5484
5485 NOTE: have to be called befor CHECK OPTION preparation, because it makes
5486 fix_fields for view WHERE clause
5487
5488 RETURN
5489 FALSE - OK
5490 TRUE - error
5491 */
5492
prep_where(THD * thd,Item ** conds,bool no_where_clause)5493 bool TABLE_LIST::prep_where(THD *thd, Item **conds,
5494 bool no_where_clause)
5495 {
5496 DBUG_ENTER("TABLE_LIST::prep_where");
5497 bool res= FALSE;
5498
5499 for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
5500 {
5501 if (tbl->is_view_or_derived() &&
5502 tbl->prep_where(thd, conds, no_where_clause))
5503 {
5504 DBUG_RETURN(TRUE);
5505 }
5506 }
5507
5508 if (where)
5509 {
5510 if (where->is_fixed())
5511 where->update_used_tables();
5512 else if (where->fix_fields(thd, &where))
5513 DBUG_RETURN(TRUE);
5514
5515 /*
5516 check that it is not VIEW in which we insert with INSERT SELECT
5517 (in this case we can't add view WHERE condition to main SELECT_LEX)
5518 */
5519 if (!no_where_clause && !where_processed)
5520 {
5521 TABLE_LIST *tbl= this;
5522 Query_arena *arena= thd->stmt_arena, backup;
5523 arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
5524
5525 /* Go up to join tree and try to find left join */
5526 for (; tbl; tbl= tbl->embedding)
5527 {
5528 if (tbl->outer_join)
5529 {
5530 /*
5531 Store WHERE condition to ON expression for outer join, because
5532 we can't use WHERE to correctly execute left joins on VIEWs and
5533 this expression will not be moved to WHERE condition (i.e. will
5534 be clean correctly for PS/SP)
5535 */
5536 tbl->on_expr= and_conds(thd, tbl->on_expr,
5537 where->copy_andor_structure(thd));
5538 break;
5539 }
5540 }
5541 if (tbl == 0)
5542 {
5543 if (*conds)
5544 res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
5545 if (!res)
5546 *conds= and_conds(thd, *conds, where->copy_andor_structure(thd));
5547 if (*conds && !res)
5548 res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
5549 }
5550 if (arena)
5551 thd->restore_active_arena(arena, &backup);
5552 where_processed= TRUE;
5553 }
5554 }
5555
5556 DBUG_RETURN(res);
5557 }
5558
5559 /**
5560 Check that table/view is updatable and if it has single
5561 underlying tables/views it is also updatable
5562
5563 @return Result of the check.
5564 */
5565
single_table_updatable()5566 bool TABLE_LIST::single_table_updatable()
5567 {
5568 if (!updatable)
5569 return false;
5570 if (view && view->first_select_lex()->table_list.elements == 1)
5571 {
5572 /*
5573 We need to check deeply only single table views. Multi-table views
5574 will be turned to multi-table updates and then checked by leaf tables
5575 */
5576 return (((TABLE_LIST *)view->first_select_lex()->table_list.first)->
5577 single_table_updatable());
5578 }
5579 return true;
5580 }
5581
5582
5583 /*
5584 Merge ON expressions for a view
5585
5586 SYNOPSIS
5587 merge_on_conds()
5588 thd thread handle
5589 table table for the VIEW
5590 is_cascaded TRUE <=> merge ON expressions from underlying views
5591
5592 DESCRIPTION
5593 This function returns the result of ANDing the ON expressions
5594 of the given view and all underlying views. The ON expressions
5595 of the underlying views are added only if is_cascaded is TRUE.
5596
5597 RETURN
5598 Pointer to the built expression if there is any.
5599 Otherwise and in the case of a failure NULL is returned.
5600 */
5601
5602 static Item *
merge_on_conds(THD * thd,TABLE_LIST * table,bool is_cascaded)5603 merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
5604 {
5605 DBUG_ENTER("merge_on_conds");
5606
5607 Item *cond= NULL;
5608 DBUG_PRINT("info", ("alias: %s", table->alias.str));
5609 if (table->on_expr)
5610 cond= table->on_expr->copy_andor_structure(thd);
5611 if (!table->view)
5612 DBUG_RETURN(cond);
5613 for (TABLE_LIST *tbl=
5614 (TABLE_LIST*)table->view->first_select_lex()->table_list.first;
5615 tbl;
5616 tbl= tbl->next_local)
5617 {
5618 if (tbl->view && !is_cascaded)
5619 continue;
5620 cond= and_conds(thd, cond, merge_on_conds(thd, tbl, is_cascaded));
5621 }
5622 DBUG_RETURN(cond);
5623 }
5624
5625
5626 /*
5627 Prepare check option expression of table
5628
5629 SYNOPSIS
5630 TABLE_LIST::prep_check_option()
5631 thd - thread handler
5632 check_opt_type - WITH CHECK OPTION type (VIEW_CHECK_NONE,
5633 VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
5634 we use this parameter instead of direct check of
5635 effective_with_check to change type of underlying
5636 views to VIEW_CHECK_CASCADED if outer view have
5637 such option and prevent processing of underlying
5638 view check options if outer view have just
5639 VIEW_CHECK_LOCAL option.
5640
5641 NOTE
5642 This method builds check option condition to use it later on
5643 every call (usual execution or every SP/PS call).
5644 This method have to be called after WHERE preparation
5645 (TABLE_LIST::prep_where)
5646
5647 RETURN
5648 FALSE - OK
5649 TRUE - error
5650 */
5651
prep_check_option(THD * thd,uint8 check_opt_type)5652 bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
5653 {
5654 DBUG_ENTER("TABLE_LIST::prep_check_option");
5655 bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
5656 TABLE_LIST *merge_underlying_list= view->first_select_lex()->get_table_list();
5657 for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
5658 {
5659 /* see comment of check_opt_type parameter */
5660 if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
5661 VIEW_CHECK_CASCADED :
5662 VIEW_CHECK_NONE)))
5663 DBUG_RETURN(TRUE);
5664 }
5665
5666 if (check_opt_type && !check_option_processed)
5667 {
5668 Query_arena *arena= thd->stmt_arena, backup;
5669 arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
5670
5671 if (where)
5672 {
5673 check_option= where->copy_andor_structure(thd);
5674 }
5675 if (is_cascaded)
5676 {
5677 for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
5678 {
5679 if (tbl->check_option)
5680 check_option= and_conds(thd, check_option, tbl->check_option);
5681 }
5682 }
5683 check_option= and_conds(thd, check_option,
5684 merge_on_conds(thd, this, is_cascaded));
5685
5686 if (arena)
5687 thd->restore_active_arena(arena, &backup);
5688 check_option_processed= TRUE;
5689
5690 }
5691
5692 if (check_option)
5693 {
5694 const char *save_where= thd->where;
5695 thd->where= "check option";
5696 if (check_option->fix_fields_if_needed_for_bool(thd, &check_option))
5697 DBUG_RETURN(TRUE);
5698 thd->where= save_where;
5699 }
5700 DBUG_RETURN(FALSE);
5701 }
5702
5703
5704 /**
5705 Hide errors which show view underlying table information.
5706 There are currently two mechanisms at work that handle errors for views,
5707 this one and a more general mechanism based on an Internal_error_handler,
5708 see Show_create_error_handler. The latter handles errors encountered during
5709 execution of SHOW CREATE VIEW, while the mechanism using this method is
5710 handles SELECT from views. The two methods should not clash.
5711
5712 @param[in,out] thd thread handler
5713
5714 @pre This method can be called only if there is an error.
5715 */
5716
hide_view_error(THD * thd)5717 void TABLE_LIST::hide_view_error(THD *thd)
5718 {
5719 if ((thd->killed && !thd->is_error())|| thd->get_internal_handler())
5720 return;
5721 /* Hide "Unknown column" or "Unknown function" error */
5722 DBUG_ASSERT(thd->is_error());
5723 switch (thd->get_stmt_da()->sql_errno()) {
5724 case ER_BAD_FIELD_ERROR:
5725 case ER_SP_DOES_NOT_EXIST:
5726 case ER_FUNC_INEXISTENT_NAME_COLLISION:
5727 case ER_PROCACCESS_DENIED_ERROR:
5728 case ER_COLUMNACCESS_DENIED_ERROR:
5729 case ER_TABLEACCESS_DENIED_ERROR:
5730 case ER_TABLE_NOT_LOCKED:
5731 case ER_NO_SUCH_TABLE:
5732 {
5733 TABLE_LIST *top= top_table();
5734 thd->clear_error();
5735 my_error(ER_VIEW_INVALID, MYF(0),
5736 top->view_db.str, top->view_name.str);
5737 break;
5738 }
5739
5740 case ER_NO_DEFAULT_FOR_FIELD:
5741 {
5742 TABLE_LIST *top= top_table();
5743 thd->clear_error();
5744 // TODO: make correct error message
5745 my_error(ER_NO_DEFAULT_FOR_VIEW_FIELD, MYF(0),
5746 top->view_db.str, top->view_name.str);
5747 break;
5748 }
5749 }
5750 }
5751
5752
5753 /*
5754 Find underlying base tables (TABLE_LIST) which represent given
5755 table_to_find (TABLE)
5756
5757 SYNOPSIS
5758 TABLE_LIST::find_underlying_table()
5759 table_to_find table to find
5760
5761 RETURN
5762 0 table is not found
5763 found table reference
5764 */
5765
find_underlying_table(TABLE * table_to_find)5766 TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
5767 {
5768 /* is this real table and table which we are looking for? */
5769 if (table == table_to_find && view == 0)
5770 return this;
5771 if (!view)
5772 return 0;
5773
5774 for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list();
5775 tbl;
5776 tbl= tbl->next_local)
5777 {
5778 TABLE_LIST *result;
5779 if ((result= tbl->find_underlying_table(table_to_find)))
5780 return result;
5781 }
5782 return 0;
5783 }
5784
5785 /*
5786 cleanup items belonged to view fields translation table
5787
5788 SYNOPSIS
5789 TABLE_LIST::cleanup_items()
5790 */
5791
cleanup_items()5792 void TABLE_LIST::cleanup_items()
5793 {
5794 if (!field_translation)
5795 return;
5796
5797 for (Field_translator *transl= field_translation;
5798 transl < field_translation_end;
5799 transl++)
5800 transl->item->walk(&Item::cleanup_processor, 0, 0);
5801 }
5802
5803
5804 /*
5805 check CHECK OPTION condition both for view and underlying table
5806
5807 SYNOPSIS
5808 TABLE_LIST::view_check_option()
5809 ignore_failure ignore check option fail
5810
5811 RETURN
5812 VIEW_CHECK_OK OK
5813 VIEW_CHECK_ERROR FAILED
5814 VIEW_CHECK_SKIP FAILED, but continue
5815 */
5816
5817
view_check_option(THD * thd,bool ignore_failure)5818 int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure)
5819 {
5820 if (check_option)
5821 {
5822 /* VIEW's CHECK OPTION CLAUSE */
5823 Counting_error_handler ceh;
5824 thd->push_internal_handler(&ceh);
5825 bool res= check_option->val_int() == 0;
5826 thd->pop_internal_handler();
5827 if (ceh.errors)
5828 return(VIEW_CHECK_ERROR);
5829 if (res)
5830 {
5831 TABLE_LIST *main_view= top_table();
5832 const char *name_db= (main_view->view ? main_view->view_db.str :
5833 main_view->db.str);
5834 const char *name_table= (main_view->view ? main_view->view_name.str :
5835 main_view->table_name.str);
5836 my_error(ER_VIEW_CHECK_FAILED, MYF(ignore_failure ? ME_WARNING : 0),
5837 name_db, name_table);
5838 return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR;
5839 }
5840 }
5841 return table->verify_constraints(ignore_failure);
5842 }
5843
5844
verify_constraints(bool ignore_failure)5845 int TABLE::verify_constraints(bool ignore_failure)
5846 {
5847 /*
5848 We have to check is_error() first as we are checking it for each
5849 constraint to catch fatal warnings.
5850 */
5851 if (in_use->is_error())
5852 return (VIEW_CHECK_ERROR);
5853
5854 /* go trough check option clauses for fields and table */
5855 if (check_constraints &&
5856 !(in_use->variables.option_bits & OPTION_NO_CHECK_CONSTRAINT_CHECKS))
5857 {
5858 if (versioned() && !vers_end_field()->is_max())
5859 return VIEW_CHECK_OK;
5860 for (Virtual_column_info **chk= check_constraints ; *chk ; chk++)
5861 {
5862 /*
5863 yes! NULL is ok.
5864 see 4.23.3.4 Table check constraints, part 2, SQL:2016
5865 */
5866 if (((*chk)->expr->val_int() == 0 && !(*chk)->expr->null_value) ||
5867 in_use->is_error())
5868 {
5869 StringBuffer<MAX_FIELD_WIDTH> field_error(system_charset_info);
5870 enum_vcol_info_type vcol_type= (*chk)->get_vcol_type();
5871 DBUG_ASSERT(vcol_type == VCOL_CHECK_TABLE ||
5872 vcol_type == VCOL_CHECK_FIELD);
5873 if (vcol_type == VCOL_CHECK_FIELD)
5874 {
5875 field_error.append(s->table_name.str);
5876 field_error.append(".");
5877 }
5878 field_error.append((*chk)->name.str);
5879 my_error(ER_CONSTRAINT_FAILED,
5880 MYF(ignore_failure ? ME_WARNING : 0), field_error.c_ptr(),
5881 s->db.str, s->table_name.str);
5882 return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR;
5883 }
5884 }
5885 }
5886 /*
5887 We have to check in_use() as checking constraints may have generated
5888 warnings that should be treated as errors
5889 */
5890 return(!in_use->is_error() ? VIEW_CHECK_OK : VIEW_CHECK_ERROR);
5891 }
5892
5893 /*
5894 Find table in underlying tables by mask and check that only this
5895 table belong to given mask
5896
5897 SYNOPSIS
5898 TABLE_LIST::check_single_table()
5899 table_arg reference on variable where to store found table
5900 (should be 0 on call, to find table, or point to table for
5901 unique test)
5902 map bit mask of tables
5903 view_arg view for which we are looking table
5904
5905 RETURN
5906 FALSE table not found or found only one
5907 TRUE found several tables
5908 */
5909
check_single_table(TABLE_LIST ** table_arg,table_map map,TABLE_LIST * view_arg)5910 bool TABLE_LIST::check_single_table(TABLE_LIST **table_arg,
5911 table_map map,
5912 TABLE_LIST *view_arg)
5913 {
5914 if (!select_lex)
5915 return FALSE;
5916 DBUG_ASSERT(is_merged_derived());
5917 for (TABLE_LIST *tbl= get_single_select()->get_table_list();
5918 tbl;
5919 tbl= tbl->next_local)
5920 {
5921 /*
5922 Merged view has also temporary table attached (in 5.2 if it has table
5923 then it was real table), so we have filter such temporary tables out
5924 by checking that it is not merged view
5925 */
5926 if (tbl->table &&
5927 !(tbl->is_view() &&
5928 tbl->is_merged_derived()))
5929 {
5930 if (tbl->table->map & map)
5931 {
5932 if (*table_arg)
5933 return TRUE;
5934 *table_arg= tbl;
5935 tbl->check_option= view_arg->check_option;
5936 }
5937 }
5938 else if (tbl->check_single_table(table_arg, map, view_arg))
5939 return TRUE;
5940 }
5941 return FALSE;
5942 }
5943
5944
5945 /*
5946 Set insert_values buffer
5947
5948 SYNOPSIS
5949 set_insert_values()
5950 mem_root memory pool for allocating
5951
5952 RETURN
5953 FALSE - OK
5954 TRUE - out of memory
5955 */
5956
set_insert_values(MEM_ROOT * mem_root)5957 bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
5958 {
5959 DBUG_ENTER("set_insert_values");
5960 if (table)
5961 {
5962 DBUG_PRINT("info", ("setting insert_value for table"));
5963 if (!table->insert_values &&
5964 !(table->insert_values= (uchar *)alloc_root(mem_root,
5965 table->s->rec_buff_length)))
5966 DBUG_RETURN(TRUE);
5967 }
5968 else
5969 {
5970 DBUG_PRINT("info", ("setting insert_value for view"));
5971 DBUG_ASSERT(is_view_or_derived() && is_merged_derived());
5972 for (TABLE_LIST *tbl=
5973 (TABLE_LIST*)view->first_select_lex()->table_list.first;
5974 tbl;
5975 tbl= tbl->next_local)
5976 if (tbl->set_insert_values(mem_root))
5977 DBUG_RETURN(TRUE);
5978 }
5979 DBUG_RETURN(FALSE);
5980 }
5981
5982
5983 /*
5984 Test if this is a leaf with respect to name resolution.
5985
5986 SYNOPSIS
5987 TABLE_LIST::is_leaf_for_name_resolution()
5988
5989 DESCRIPTION
5990 A table reference is a leaf with respect to name resolution if
5991 it is either a leaf node in a nested join tree (table, view,
5992 schema table, subquery), or an inner node that represents a
5993 NATURAL/USING join, or a nested join with materialized join
5994 columns.
5995
5996 RETURN
5997 TRUE if a leaf, FALSE otherwise.
5998 */
is_leaf_for_name_resolution()5999 bool TABLE_LIST::is_leaf_for_name_resolution()
6000 {
6001 return (is_merged_derived() || is_natural_join || is_join_columns_complete ||
6002 !nested_join);
6003 }
6004
6005
6006 /*
6007 Retrieve the first (left-most) leaf in a nested join tree with
6008 respect to name resolution.
6009
6010 SYNOPSIS
6011 TABLE_LIST::first_leaf_for_name_resolution()
6012
6013 DESCRIPTION
6014 Given that 'this' is a nested table reference, recursively walk
6015 down the left-most children of 'this' until we reach a leaf
6016 table reference with respect to name resolution.
6017
6018 IMPLEMENTATION
6019 The left-most child of a nested table reference is the last element
6020 in the list of children because the children are inserted in
6021 reverse order.
6022
6023 RETURN
6024 If 'this' is a nested table reference - the left-most child of
6025 the tree rooted in 'this',
6026 else return 'this'
6027 */
6028
first_leaf_for_name_resolution()6029 TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
6030 {
6031 TABLE_LIST *UNINIT_VAR(cur_table_ref);
6032 NESTED_JOIN *cur_nested_join;
6033
6034 if (is_leaf_for_name_resolution())
6035 return this;
6036 DBUG_ASSERT(nested_join);
6037
6038 for (cur_nested_join= nested_join;
6039 cur_nested_join;
6040 cur_nested_join= cur_table_ref->nested_join)
6041 {
6042 List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
6043 cur_table_ref= it++;
6044 /*
6045 If the current nested join is a RIGHT JOIN, the operands in
6046 'join_list' are in reverse order, thus the first operand is
6047 already at the front of the list. Otherwise the first operand
6048 is in the end of the list of join operands.
6049 */
6050 if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
6051 {
6052 TABLE_LIST *next;
6053 while ((next= it++))
6054 cur_table_ref= next;
6055 }
6056 if (cur_table_ref->is_leaf_for_name_resolution())
6057 break;
6058 }
6059 return cur_table_ref;
6060 }
6061
6062
6063 /*
6064 Retrieve the last (right-most) leaf in a nested join tree with
6065 respect to name resolution.
6066
6067 SYNOPSIS
6068 TABLE_LIST::last_leaf_for_name_resolution()
6069
6070 DESCRIPTION
6071 Given that 'this' is a nested table reference, recursively walk
6072 down the right-most children of 'this' until we reach a leaf
6073 table reference with respect to name resolution.
6074
6075 IMPLEMENTATION
6076 The right-most child of a nested table reference is the first
6077 element in the list of children because the children are inserted
6078 in reverse order.
6079
6080 RETURN
6081 - If 'this' is a nested table reference - the right-most child of
6082 the tree rooted in 'this',
6083 - else - 'this'
6084 */
6085
last_leaf_for_name_resolution()6086 TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
6087 {
6088 TABLE_LIST *cur_table_ref= this;
6089 NESTED_JOIN *cur_nested_join;
6090
6091 if (is_leaf_for_name_resolution())
6092 return this;
6093 DBUG_ASSERT(nested_join);
6094
6095 for (cur_nested_join= nested_join;
6096 cur_nested_join;
6097 cur_nested_join= cur_table_ref->nested_join)
6098 {
6099 cur_table_ref= cur_nested_join->join_list.head();
6100 /*
6101 If the current nested is a RIGHT JOIN, the operands in
6102 'join_list' are in reverse order, thus the last operand is in the
6103 end of the list.
6104 */
6105 if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
6106 {
6107 List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
6108 TABLE_LIST *next;
6109 cur_table_ref= it++;
6110 while ((next= it++))
6111 cur_table_ref= next;
6112 }
6113 if (cur_table_ref->is_leaf_for_name_resolution())
6114 break;
6115 }
6116 return cur_table_ref;
6117 }
6118
6119
6120 /*
6121 Register access mode which we need for underlying tables
6122
6123 SYNOPSIS
6124 register_want_access()
6125 want_access Acess which we require
6126 */
6127
register_want_access(ulong want_access)6128 void TABLE_LIST::register_want_access(ulong want_access)
6129 {
6130 /* Remove SHOW_VIEW_ACL, because it will be checked during making view */
6131 want_access&= ~SHOW_VIEW_ACL;
6132 if (belong_to_view)
6133 {
6134 grant.want_privilege= want_access;
6135 if (table)
6136 table->grant.want_privilege= want_access;
6137 }
6138 if (!view)
6139 return;
6140 for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list();
6141 tbl;
6142 tbl= tbl->next_local)
6143 tbl->register_want_access(want_access);
6144 }
6145
6146
6147 /*
6148 Load security context information for this view
6149
6150 SYNOPSIS
6151 TABLE_LIST::prepare_view_security_context()
6152 thd [in] thread handler
6153
6154 RETURN
6155 FALSE OK
6156 TRUE Error
6157 */
6158
6159 #ifndef NO_EMBEDDED_ACCESS_CHECKS
prepare_view_security_context(THD * thd)6160 bool TABLE_LIST::prepare_view_security_context(THD *thd)
6161 {
6162 DBUG_ENTER("TABLE_LIST::prepare_view_security_context");
6163 DBUG_PRINT("enter", ("table: %s", alias.str));
6164
6165 DBUG_ASSERT(!prelocking_placeholder && view);
6166 if (view_suid)
6167 {
6168 DBUG_PRINT("info", ("This table is suid view => load contest"));
6169 DBUG_ASSERT(view && view_sctx);
6170 if (acl_getroot(view_sctx, definer.user.str, definer.host.str,
6171 definer.host.str, thd->db.str))
6172 {
6173 if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
6174 (thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
6175 {
6176 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
6177 ER_NO_SUCH_USER,
6178 ER_THD(thd, ER_NO_SUCH_USER),
6179 definer.user.str, definer.host.str);
6180 }
6181 else
6182 {
6183 if (thd->security_ctx->master_access & SUPER_ACL)
6184 {
6185 my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
6186
6187 }
6188 else
6189 {
6190 if (thd->password == 2)
6191 my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
6192 thd->security_ctx->priv_user,
6193 thd->security_ctx->priv_host);
6194 else
6195 my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
6196 thd->security_ctx->priv_user,
6197 thd->security_ctx->priv_host,
6198 (thd->password ? ER_THD(thd, ER_YES) :
6199 ER_THD(thd, ER_NO)));
6200 }
6201 DBUG_RETURN(TRUE);
6202 }
6203 }
6204 }
6205 DBUG_RETURN(FALSE);
6206
6207 }
6208 #endif
6209
6210
6211 /*
6212 Find security context of current view
6213
6214 SYNOPSIS
6215 TABLE_LIST::find_view_security_context()
6216 thd [in] thread handler
6217
6218 */
6219
6220 #ifndef NO_EMBEDDED_ACCESS_CHECKS
find_view_security_context(THD * thd)6221 Security_context *TABLE_LIST::find_view_security_context(THD *thd)
6222 {
6223 Security_context *sctx;
6224 TABLE_LIST *upper_view= this;
6225 DBUG_ENTER("TABLE_LIST::find_view_security_context");
6226
6227 DBUG_ASSERT(view);
6228 while (upper_view && !upper_view->view_suid)
6229 {
6230 DBUG_ASSERT(!upper_view->prelocking_placeholder);
6231 upper_view= upper_view->referencing_view;
6232 }
6233 if (upper_view)
6234 {
6235 DBUG_PRINT("info", ("Securety context of view %s will be used",
6236 upper_view->alias.str));
6237 sctx= upper_view->view_sctx;
6238 DBUG_ASSERT(sctx);
6239 }
6240 else
6241 {
6242 DBUG_PRINT("info", ("Current global context will be used"));
6243 sctx= thd->security_ctx;
6244 }
6245 DBUG_RETURN(sctx);
6246 }
6247 #endif
6248
6249
6250 /*
6251 Prepare security context and load underlying tables priveleges for view
6252
6253 SYNOPSIS
6254 TABLE_LIST::prepare_security()
6255 thd [in] thread handler
6256
6257 RETURN
6258 FALSE OK
6259 TRUE Error
6260 */
6261
prepare_security(THD * thd)6262 bool TABLE_LIST::prepare_security(THD *thd)
6263 {
6264 List_iterator_fast<TABLE_LIST> tb(*view_tables);
6265 TABLE_LIST *tbl;
6266 DBUG_ENTER("TABLE_LIST::prepare_security");
6267 #ifndef NO_EMBEDDED_ACCESS_CHECKS
6268 Security_context *save_security_ctx= thd->security_ctx;
6269
6270 DBUG_ASSERT(!prelocking_placeholder);
6271 if (prepare_view_security_context(thd))
6272 DBUG_RETURN(TRUE);
6273 thd->security_ctx= find_view_security_context(thd);
6274 opt_trace_disable_if_no_security_context_access(thd);
6275 while ((tbl= tb++))
6276 {
6277 DBUG_ASSERT(tbl->referencing_view);
6278 const char *local_db, *local_table_name;
6279 if (tbl->view)
6280 {
6281 local_db= tbl->view_db.str;
6282 local_table_name= tbl->view_name.str;
6283 }
6284 else
6285 {
6286 local_db= tbl->db.str;
6287 local_table_name= tbl->table_name.str;
6288 }
6289 fill_effective_table_privileges(thd, &tbl->grant, local_db,
6290 local_table_name);
6291 if (tbl->table)
6292 tbl->table->grant= grant;
6293 }
6294 thd->security_ctx= save_security_ctx;
6295 #else
6296 while ((tbl= tb++))
6297 tbl->grant.privilege= ~NO_ACCESS;
6298 #endif
6299 DBUG_RETURN(FALSE);
6300 }
6301
6302 #ifndef DBUG_OFF
set_check_merged()6303 void TABLE_LIST::set_check_merged()
6304 {
6305 DBUG_ASSERT(derived);
6306 /*
6307 It is not simple to check all, but at least this should be checked:
6308 this select is not excluded or the exclusion came from above.
6309 */
6310 DBUG_ASSERT(derived->is_excluded() ||
6311 !derived->first_select()->exclude_from_table_unique_test ||
6312 derived->outer_select()->
6313 exclude_from_table_unique_test);
6314 }
6315 #endif
6316
set_check_materialized()6317 void TABLE_LIST::set_check_materialized()
6318 {
6319 DBUG_ENTER("TABLE_LIST::set_check_materialized");
6320 SELECT_LEX_UNIT *derived= this->derived;
6321 if (view)
6322 derived= &view->unit;
6323 DBUG_ASSERT(derived);
6324 DBUG_ASSERT(!derived->is_excluded());
6325 if (!derived->first_select()->exclude_from_table_unique_test)
6326 derived->set_unique_exclude();
6327 else
6328 {
6329 /*
6330 The subtree should be already excluded
6331 */
6332 DBUG_ASSERT(!derived->first_select()->first_inner_unit() ||
6333 derived->first_select()->first_inner_unit()->with_element ||
6334 derived->first_select()->first_inner_unit()->first_select()->
6335 exclude_from_table_unique_test);
6336 }
6337 DBUG_VOID_RETURN;
6338 }
6339
get_real_join_table()6340 TABLE *TABLE_LIST::get_real_join_table()
6341 {
6342 TABLE_LIST *tbl= this;
6343 while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL)
6344 {
6345 if ((tbl->view == NULL && tbl->derived == NULL) ||
6346 tbl->is_materialized_derived())
6347 break;
6348 /* we do not support merging of union yet */
6349 DBUG_ASSERT(tbl->view == NULL ||
6350 tbl->view->first_select_lex()->next_select() == NULL);
6351 DBUG_ASSERT(tbl->derived == NULL ||
6352 tbl->derived->first_select()->next_select() == NULL);
6353
6354 {
6355 List_iterator_fast<TABLE_LIST>
6356 ti(tbl->view != NULL ?
6357 tbl->view->first_select_lex()->top_join_list :
6358 tbl->derived->first_select()->top_join_list);
6359 for (;;)
6360 {
6361 tbl= NULL;
6362 /*
6363 Find left table in outer join on this level
6364 (the list is reverted).
6365 */
6366 for (TABLE_LIST *t= ti++; t; t= ti++)
6367 tbl= t;
6368 if (!tbl)
6369 return NULL; // view/derived with no tables
6370 if (!tbl->nested_join)
6371 break;
6372 /* go deeper if we've found nested join */
6373 ti= tbl->nested_join->join_list;
6374 }
6375 }
6376 }
6377
6378 return tbl->table;
6379 }
6380
6381
Natural_join_column(Field_translator * field_param,TABLE_LIST * tab)6382 Natural_join_column::Natural_join_column(Field_translator *field_param,
6383 TABLE_LIST *tab)
6384 {
6385 DBUG_ASSERT(tab->field_translation);
6386 view_field= field_param;
6387 table_field= NULL;
6388 table_ref= tab;
6389 is_common= FALSE;
6390 }
6391
6392
Natural_join_column(Item_field * field_param,TABLE_LIST * tab)6393 Natural_join_column::Natural_join_column(Item_field *field_param,
6394 TABLE_LIST *tab)
6395 {
6396 DBUG_ASSERT(tab->table == field_param->field->table);
6397 table_field= field_param;
6398 view_field= NULL;
6399 table_ref= tab;
6400 is_common= FALSE;
6401 }
6402
6403
name()6404 LEX_CSTRING *Natural_join_column::name()
6405 {
6406 if (view_field)
6407 {
6408 DBUG_ASSERT(table_field == NULL);
6409 return &view_field->name;
6410 }
6411
6412 return &table_field->field_name;
6413 }
6414
6415
create_item(THD * thd)6416 Item *Natural_join_column::create_item(THD *thd)
6417 {
6418 if (view_field)
6419 {
6420 DBUG_ASSERT(table_field == NULL);
6421 return create_view_field(thd, table_ref, &view_field->item,
6422 &view_field->name);
6423 }
6424 return table_field;
6425 }
6426
6427
field()6428 Field *Natural_join_column::field()
6429 {
6430 if (view_field)
6431 {
6432 DBUG_ASSERT(table_field == NULL);
6433 return NULL;
6434 }
6435 return table_field->field;
6436 }
6437
6438
safe_table_name()6439 const char *Natural_join_column::safe_table_name()
6440 {
6441 DBUG_ASSERT(table_ref);
6442 return table_ref->alias.str ? table_ref->alias.str : "";
6443 }
6444
6445
safe_db_name()6446 const char *Natural_join_column::safe_db_name()
6447 {
6448 if (view_field)
6449 return table_ref->view_db.str ? table_ref->view_db.str : "";
6450
6451 /*
6452 Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
6453 ensure consistency. An exception are I_S schema tables, which
6454 are inconsistent in this respect.
6455 */
6456 DBUG_ASSERT(!cmp(&table_ref->db,
6457 &table_ref->table->s->db) ||
6458 (table_ref->schema_table &&
6459 is_infoschema_db(&table_ref->table->s->db)) ||
6460 table_ref->is_materialized_derived());
6461 return table_ref->db.str ? table_ref->db.str : "";
6462 }
6463
6464
grant()6465 GRANT_INFO *Natural_join_column::grant()
6466 {
6467 /* if (view_field)
6468 return &(table_ref->grant);
6469 return &(table_ref->table->grant);*/
6470 /*
6471 Have to check algorithm because merged derived also has
6472 field_translation.
6473 */
6474 //if (table_ref->effective_algorithm == DTYPE_ALGORITHM_MERGE)
6475 if (table_ref->is_merged_derived())
6476 return &(table_ref->grant);
6477 return &(table_ref->table->grant);
6478 }
6479
6480
set(TABLE_LIST * table)6481 void Field_iterator_view::set(TABLE_LIST *table)
6482 {
6483 DBUG_ASSERT(table->field_translation);
6484 view= table;
6485 ptr= table->field_translation;
6486 array_end= table->field_translation_end;
6487 }
6488
6489
name()6490 LEX_CSTRING *Field_iterator_table::name()
6491 {
6492 return &(*ptr)->field_name;
6493 }
6494
6495
create_item(THD * thd)6496 Item *Field_iterator_table::create_item(THD *thd)
6497 {
6498 SELECT_LEX *select= thd->lex->current_select;
6499
6500 Item_field *item= new (thd->mem_root) Item_field(thd, &select->context, *ptr);
6501 DBUG_ASSERT(strlen(item->name.str) == item->name.length);
6502 if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
6503 !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS &&
6504 select->join)
6505 {
6506 select->join->non_agg_fields.push_back(item);
6507 item->marker= select->cur_pos_in_select_list;
6508 select->set_non_agg_field_used(true);
6509 }
6510 return item;
6511 }
6512
6513
name()6514 LEX_CSTRING *Field_iterator_view::name()
6515 {
6516 return &ptr->name;
6517 }
6518
6519
create_item(THD * thd)6520 Item *Field_iterator_view::create_item(THD *thd)
6521 {
6522 return create_view_field(thd, view, &ptr->item, &ptr->name);
6523 }
6524
create_view_field(THD * thd,TABLE_LIST * view,Item ** field_ref,LEX_CSTRING * name)6525 Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
6526 LEX_CSTRING *name)
6527 {
6528 bool save_wrapper= thd->lex->first_select_lex()->no_wrap_view_item;
6529 Item *field= *field_ref;
6530 DBUG_ENTER("create_view_field");
6531
6532 if (view->schema_table_reformed)
6533 {
6534 /*
6535 Translation table items are always Item_fields and already fixed
6536 ('mysql_schema_table' function). So we can return directly the
6537 field. This case happens only for 'show & where' commands.
6538 */
6539 DBUG_ASSERT(field && field->is_fixed());
6540 DBUG_RETURN(field);
6541 }
6542
6543 DBUG_ASSERT(field);
6544 thd->lex->current_select->no_wrap_view_item= TRUE;
6545 if (!field->is_fixed())
6546 {
6547 if (field->fix_fields(thd, field_ref))
6548 {
6549 thd->lex->current_select->no_wrap_view_item= save_wrapper;
6550 DBUG_RETURN(0);
6551 }
6552 field= *field_ref;
6553 }
6554 thd->lex->current_select->no_wrap_view_item= save_wrapper;
6555 if (save_wrapper)
6556 {
6557 DBUG_RETURN(field);
6558 }
6559 Name_resolution_context *context= (view->view ?
6560 &view->view->first_select_lex()->context:
6561 &thd->lex->first_select_lex()->context);
6562 Item *item= (new (thd->mem_root)
6563 Item_direct_view_ref(thd, context, field_ref, view->alias.str,
6564 name, view));
6565 if (!item)
6566 return NULL;
6567 /*
6568 Force creation of nullable item for the result tmp table for outer joined
6569 views/derived tables.
6570 */
6571 if (view->table && view->table->maybe_null)
6572 item->maybe_null= TRUE;
6573 /* Save item in case we will need to fall back to materialization. */
6574 view->used_items.push_front(item, thd->mem_root);
6575 /*
6576 If we create this reference on persistent memory then it should be
6577 present in persistent list
6578 */
6579 if (thd->mem_root == thd->stmt_arena->mem_root)
6580 view->persistent_used_items.push_front(item, thd->mem_root);
6581 DBUG_RETURN(item);
6582 }
6583
6584
set(TABLE_LIST * table_ref)6585 void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
6586 {
6587 DBUG_ASSERT(table_ref->join_columns);
6588 column_ref_it.init(*(table_ref->join_columns));
6589 cur_column_ref= column_ref_it++;
6590 }
6591
6592
next()6593 void Field_iterator_natural_join::next()
6594 {
6595 cur_column_ref= column_ref_it++;
6596 DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
6597 cur_column_ref->table_ref->table ==
6598 cur_column_ref->table_field->field->table);
6599 }
6600
6601
set_field_iterator()6602 void Field_iterator_table_ref::set_field_iterator()
6603 {
6604 DBUG_ENTER("Field_iterator_table_ref::set_field_iterator");
6605 /*
6606 If the table reference we are iterating over is a natural join, or it is
6607 an operand of a natural join, and TABLE_LIST::join_columns contains all
6608 the columns of the join operand, then we pick the columns from
6609 TABLE_LIST::join_columns, instead of the orginial container of the
6610 columns of the join operator.
6611 */
6612 if (table_ref->is_join_columns_complete)
6613 {
6614 /* Necesary, but insufficient conditions. */
6615 DBUG_ASSERT(table_ref->is_natural_join ||
6616 table_ref->nested_join ||
6617 (table_ref->join_columns &&
6618 /* This is a merge view. */
6619 ((table_ref->field_translation &&
6620 table_ref->join_columns->elements ==
6621 (ulong)(table_ref->field_translation_end -
6622 table_ref->field_translation)) ||
6623 /* This is stored table or a tmptable view. */
6624 (!table_ref->field_translation &&
6625 table_ref->join_columns->elements ==
6626 table_ref->table->s->fields))));
6627 field_it= &natural_join_it;
6628 DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
6629 table_ref->alias.str));
6630 }
6631 /* This is a merge view, so use field_translation. */
6632 else if (table_ref->field_translation)
6633 {
6634 DBUG_ASSERT(table_ref->is_merged_derived());
6635 field_it= &view_field_it;
6636 DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
6637 table_ref->alias.str));
6638 }
6639 /* This is a base table or stored view. */
6640 else
6641 {
6642 DBUG_ASSERT(table_ref->table || table_ref->view);
6643 field_it= &table_field_it;
6644 DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_table",
6645 table_ref->alias.str));
6646 }
6647 field_it->set(table_ref);
6648 DBUG_VOID_RETURN;
6649 }
6650
6651
set(TABLE_LIST * table)6652 void Field_iterator_table_ref::set(TABLE_LIST *table)
6653 {
6654 DBUG_ASSERT(table);
6655 first_leaf= table->first_leaf_for_name_resolution();
6656 last_leaf= table->last_leaf_for_name_resolution();
6657 DBUG_ASSERT(first_leaf && last_leaf);
6658 table_ref= first_leaf;
6659 set_field_iterator();
6660 }
6661
6662
next()6663 void Field_iterator_table_ref::next()
6664 {
6665 /* Move to the next field in the current table reference. */
6666 field_it->next();
6667 /*
6668 If all fields of the current table reference are exhausted, move to
6669 the next leaf table reference.
6670 */
6671 if (field_it->end_of_fields() && table_ref != last_leaf)
6672 {
6673 table_ref= table_ref->next_name_resolution_table;
6674 DBUG_ASSERT(table_ref);
6675 set_field_iterator();
6676 }
6677 }
6678
6679
get_table_name()6680 const char *Field_iterator_table_ref::get_table_name()
6681 {
6682 if (table_ref->view)
6683 return table_ref->view_name.str;
6684 if (table_ref->is_derived())
6685 return table_ref->table->s->table_name.str;
6686 else if (table_ref->is_natural_join)
6687 return natural_join_it.column_ref()->safe_table_name();
6688
6689 DBUG_ASSERT(!strcmp(table_ref->table_name.str,
6690 table_ref->table->s->table_name.str) ||
6691 table_ref->schema_table);
6692 return table_ref->table_name.str;
6693 }
6694
6695
get_db_name()6696 const char *Field_iterator_table_ref::get_db_name()
6697 {
6698 if (table_ref->view)
6699 return table_ref->view_db.str;
6700 else if (table_ref->is_natural_join)
6701 return natural_join_it.column_ref()->safe_db_name();
6702
6703 /*
6704 Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
6705 ensure consistency. An exception are I_S schema tables, which
6706 are inconsistent in this respect.
6707 */
6708 DBUG_ASSERT(!cmp(&table_ref->db, &table_ref->table->s->db) ||
6709 (table_ref->schema_table &&
6710 is_infoschema_db(&table_ref->table->s->db)));
6711
6712 return table_ref->db.str;
6713 }
6714
6715
grant()6716 GRANT_INFO *Field_iterator_table_ref::grant()
6717 {
6718 if (table_ref->view)
6719 return &(table_ref->grant);
6720 else if (table_ref->is_natural_join)
6721 return natural_join_it.column_ref()->grant();
6722 return &(table_ref->table->grant);
6723 }
6724
6725
6726 /*
6727 Create new or return existing column reference to a column of a
6728 natural/using join.
6729
6730 SYNOPSIS
6731 Field_iterator_table_ref::get_or_create_column_ref()
6732 parent_table_ref the parent table reference over which the
6733 iterator is iterating
6734
6735 DESCRIPTION
6736 Create a new natural join column for the current field of the
6737 iterator if no such column was created, or return an already
6738 created natural join column. The former happens for base tables or
6739 views, and the latter for natural/using joins. If a new field is
6740 created, then the field is added to 'parent_table_ref' if it is
6741 given, or to the original table referene of the field if
6742 parent_table_ref == NULL.
6743
6744 NOTES
6745 This method is designed so that when a Field_iterator_table_ref
6746 walks through the fields of a table reference, all its fields
6747 are created and stored as follows:
6748 - If the table reference being iterated is a stored table, view or
6749 natural/using join, store all natural join columns in a list
6750 attached to that table reference.
6751 - If the table reference being iterated is a nested join that is
6752 not natural/using join, then do not materialize its result
6753 fields. This is OK because for such table references
6754 Field_iterator_table_ref iterates over the fields of the nested
6755 table references (recursively). In this way we avoid the storage
6756 of unnecessay copies of result columns of nested joins.
6757
6758 RETURN
6759 # Pointer to a column of a natural join (or its operand)
6760 NULL No memory to allocate the column
6761 */
6762
6763 Natural_join_column *
get_or_create_column_ref(THD * thd,TABLE_LIST * parent_table_ref)6764 Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref)
6765 {
6766 Natural_join_column *nj_col;
6767 bool is_created= TRUE;
6768 uint UNINIT_VAR(field_count);
6769 TABLE_LIST *add_table_ref= parent_table_ref ?
6770 parent_table_ref : table_ref;
6771
6772 if (field_it == &table_field_it)
6773 {
6774 /* The field belongs to a stored table. */
6775 Field *tmp_field= table_field_it.field();
6776 Item_field *tmp_item=
6777 new (thd->mem_root) Item_field(thd, &thd->lex->current_select->context, tmp_field);
6778 if (!tmp_item)
6779 return NULL;
6780 nj_col= new Natural_join_column(tmp_item, table_ref);
6781 field_count= table_ref->table->s->fields;
6782 }
6783 else if (field_it == &view_field_it)
6784 {
6785 /* The field belongs to a merge view or information schema table. */
6786 Field_translator *translated_field= view_field_it.field_translator();
6787 nj_col= new Natural_join_column(translated_field, table_ref);
6788 field_count= (uint)(table_ref->field_translation_end -
6789 table_ref->field_translation);
6790 }
6791 else
6792 {
6793 /*
6794 The field belongs to a NATURAL join, therefore the column reference was
6795 already created via one of the two constructor calls above. In this case
6796 we just return the already created column reference.
6797 */
6798 DBUG_ASSERT(table_ref->is_join_columns_complete);
6799 is_created= FALSE;
6800 nj_col= natural_join_it.column_ref();
6801 DBUG_ASSERT(nj_col);
6802 }
6803 DBUG_ASSERT(!nj_col->table_field || !nj_col->table_field->field ||
6804 nj_col->table_ref->table == nj_col->table_field->field->table);
6805
6806 /*
6807 If the natural join column was just created add it to the list of
6808 natural join columns of either 'parent_table_ref' or to the table
6809 reference that directly contains the original field.
6810 */
6811 if (is_created)
6812 {
6813 /* Make sure not all columns were materialized. */
6814 DBUG_ASSERT(!add_table_ref->is_join_columns_complete);
6815 if (!add_table_ref->join_columns)
6816 {
6817 /* Create a list of natural join columns on demand. */
6818 if (!(add_table_ref->join_columns= new List<Natural_join_column>))
6819 return NULL;
6820 add_table_ref->is_join_columns_complete= FALSE;
6821 }
6822 add_table_ref->join_columns->push_back(nj_col);
6823 /*
6824 If new fields are added to their original table reference, mark if
6825 all fields were added. We do it here as the caller has no easy way
6826 of knowing when to do it.
6827 If the fields are being added to parent_table_ref, then the caller
6828 must take care to mark when all fields are created/added.
6829 */
6830 if (!parent_table_ref &&
6831 add_table_ref->join_columns->elements == field_count)
6832 add_table_ref->is_join_columns_complete= TRUE;
6833 }
6834
6835 return nj_col;
6836 }
6837
6838
6839 /*
6840 Return an existing reference to a column of a natural/using join.
6841
6842 SYNOPSIS
6843 Field_iterator_table_ref::get_natural_column_ref()
6844
6845 DESCRIPTION
6846 The method should be called in contexts where it is expected that
6847 all natural join columns are already created, and that the column
6848 being retrieved is a Natural_join_column.
6849
6850 RETURN
6851 # Pointer to a column of a natural join (or its operand)
6852 NULL We didn't originally have memory to allocate the column
6853 */
6854
6855 Natural_join_column *
get_natural_column_ref()6856 Field_iterator_table_ref::get_natural_column_ref()
6857 {
6858 Natural_join_column *nj_col;
6859
6860 DBUG_ASSERT(field_it == &natural_join_it);
6861 /*
6862 The field belongs to a NATURAL join, therefore the column reference was
6863 already created via one of the two constructor calls above. In this case
6864 we just return the already created column reference.
6865 */
6866 nj_col= natural_join_it.column_ref();
6867 DBUG_ASSERT(nj_col &&
6868 (!nj_col->table_field || !nj_col->table_field->field ||
6869 nj_col->table_ref->table == nj_col->table_field->field->table));
6870 return nj_col;
6871 }
6872
6873 /*****************************************************************************
6874 Functions to handle column usage bitmaps (read_set, write_set etc...)
6875 *****************************************************************************/
6876
6877 /* Reset all columns bitmaps */
6878
clear_column_bitmaps()6879 void TABLE::clear_column_bitmaps()
6880 {
6881 /*
6882 Reset column read/write usage. It's identical to:
6883 bitmap_clear_all(&table->def_read_set);
6884 bitmap_clear_all(&table->def_write_set);
6885 The code assumes that the bitmaps are allocated after each other, as
6886 guaranteed by open_table_from_share()
6887 */
6888 bzero((char*) def_read_set.bitmap,
6889 s->column_bitmap_size * (s->virtual_fields ? 3 : 2));
6890 column_bitmaps_set(&def_read_set, &def_write_set);
6891 rpl_write_set= 0; // Safety
6892 }
6893
6894
6895 /*
6896 Tell handler we are going to call position() and rnd_pos() later.
6897
6898 NOTES:
6899 This is needed for handlers that uses the primary key to find the
6900 row. In this case we have to extend the read bitmap with the primary
6901 key fields.
6902 */
6903
prepare_for_position()6904 void TABLE::prepare_for_position()
6905 {
6906 DBUG_ENTER("TABLE::prepare_for_position");
6907
6908 if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
6909 s->primary_key < MAX_KEY)
6910 {
6911 mark_index_columns_for_read(s->primary_key);
6912 /* signal change */
6913 file->column_bitmaps_signal();
6914 }
6915 DBUG_VOID_RETURN;
6916 }
6917
6918
prepare_for_keyread(uint index,MY_BITMAP * map)6919 MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map)
6920 {
6921 MY_BITMAP *backup= read_set;
6922 DBUG_ENTER("TABLE::prepare_for_keyread");
6923 if (!no_keyread)
6924 file->ha_start_keyread(index);
6925 if (map != read_set || !(file->index_flags(index, 0, 1) & HA_CLUSTERED_INDEX))
6926 {
6927 mark_index_columns(index, map);
6928 column_bitmaps_set(map);
6929 }
6930 DBUG_RETURN(backup);
6931 }
6932
6933
6934 /*
6935 Mark that only fields from one key is used. Useful before keyread.
6936 */
6937
mark_index_columns(uint index,MY_BITMAP * bitmap)6938 void TABLE::mark_index_columns(uint index, MY_BITMAP *bitmap)
6939 {
6940 DBUG_ENTER("TABLE::mark_index_columns");
6941
6942 bitmap_clear_all(bitmap);
6943 mark_index_columns_no_reset(index, bitmap);
6944 DBUG_VOID_RETURN;
6945 }
6946
6947 /*
6948 Restore to use normal column maps after key read
6949
6950 NOTES
6951 This reverse the change done by mark_columns_used_by_index
6952
6953 WARNING
6954 For this to work, one must have the normal table maps in place
6955 when calling mark_columns_used_by_index
6956 */
6957
restore_column_maps_after_keyread(MY_BITMAP * backup)6958 void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup)
6959 {
6960 DBUG_ENTER("TABLE::restore_column_maps_after_mark_index");
6961 file->ha_end_keyread();
6962 read_set= backup;
6963 file->column_bitmaps_signal();
6964 DBUG_VOID_RETURN;
6965 }
6966
do_mark_index_columns(TABLE * table,uint index,MY_BITMAP * bitmap,bool read)6967 static void do_mark_index_columns(TABLE *table, uint index,
6968 MY_BITMAP *bitmap, bool read)
6969 {
6970 KEY_PART_INFO *key_part= table->key_info[index].key_part;
6971 uint key_parts= table->key_info[index].user_defined_key_parts;
6972 for (uint k= 0; k < key_parts; k++)
6973 if (read)
6974 key_part[k].field->register_field_in_read_map();
6975 else
6976 bitmap_set_bit(bitmap, key_part[k].fieldnr-1);
6977 if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
6978 table->s->primary_key != MAX_KEY && table->s->primary_key != index)
6979 do_mark_index_columns(table, table->s->primary_key, bitmap, read);
6980
6981 }
6982 /*
6983 mark columns used by key, but don't reset other fields
6984 */
6985
mark_index_columns_no_reset(uint index,MY_BITMAP * bitmap)6986 inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap)
6987 {
6988 do_mark_index_columns(this, index, bitmap, false);
6989 }
6990
6991
mark_index_columns_for_read(uint index)6992 inline void TABLE::mark_index_columns_for_read(uint index)
6993 {
6994 do_mark_index_columns(this, index, read_set, true);
6995 }
6996
6997 /*
6998 Mark auto-increment fields as used fields in both read and write maps
6999
7000 NOTES
7001 This is needed in insert & update as the auto-increment field is
7002 always set and sometimes read.
7003 */
7004
mark_auto_increment_column()7005 void TABLE::mark_auto_increment_column()
7006 {
7007 DBUG_ASSERT(found_next_number_field);
7008 /*
7009 We must set bit in read set as update_auto_increment() is using the
7010 store() to check overflow of auto_increment values
7011 */
7012 bitmap_set_bit(read_set, found_next_number_field->field_index);
7013 bitmap_set_bit(write_set, found_next_number_field->field_index);
7014 if (s->next_number_keypart)
7015 mark_index_columns_for_read(s->next_number_index);
7016 file->column_bitmaps_signal();
7017 }
7018
7019
7020 /*
7021 Mark columns needed for doing an delete of a row
7022
7023 DESCRIPTON
7024 Some table engines don't have a cursor on the retrieve rows
7025 so they need either to use the primary key or all columns to
7026 be able to delete a row.
7027
7028 If the engine needs this, the function works as follows:
7029 - If primary key exits, mark the primary key columns to be read.
7030 - If not, mark all columns to be read
7031
7032 If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
7033 mark all key columns as 'to-be-read'. This allows the engine to
7034 loop over the given record to find all keys and doesn't have to
7035 retrieve the row again.
7036 */
7037
mark_columns_needed_for_delete()7038 void TABLE::mark_columns_needed_for_delete()
7039 {
7040 bool need_signal= false;
7041 mark_columns_per_binlog_row_image();
7042
7043 if (triggers)
7044 triggers->mark_fields_used(TRG_EVENT_DELETE);
7045 if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
7046 {
7047 Field **reg_field;
7048 for (reg_field= field ; *reg_field ; reg_field++)
7049 {
7050 if ((*reg_field)->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG))
7051 mark_column_with_deps(*reg_field);
7052 }
7053 need_signal= true;
7054 }
7055 if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
7056 {
7057 /*
7058 If the handler has no cursor capabilites, we have to read either
7059 the primary key, the hidden primary key or all columns to be
7060 able to do an delete
7061 */
7062 if (s->primary_key == MAX_KEY)
7063 file->use_hidden_primary_key();
7064 else
7065 {
7066 mark_index_columns_for_read(s->primary_key);
7067 need_signal= true;
7068 }
7069 }
7070
7071 if (s->versioned)
7072 {
7073 bitmap_set_bit(read_set, s->vers.start_fieldno);
7074 bitmap_set_bit(read_set, s->vers.end_fieldno);
7075 bitmap_set_bit(write_set, s->vers.end_fieldno);
7076 need_signal= true;
7077 }
7078
7079 if (need_signal)
7080 file->column_bitmaps_signal();
7081 }
7082
7083
7084 /*
7085 Mark columns needed for doing an update of a row
7086
7087 DESCRIPTON
7088 Some engines needs to have all columns in an update (to be able to
7089 build a complete row). If this is the case, we mark all not
7090 updated columns to be read.
7091
7092 If this is no the case, we do like in the delete case and mark
7093 if needed, either the primary key column or all columns to be read.
7094 (see mark_columns_needed_for_delete() for details)
7095
7096 If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
7097 mark all USED key columns as 'to-be-read'. This allows the engine to
7098 loop over the given record to find all changed keys and doesn't have to
7099 retrieve the row again.
7100 */
7101
mark_columns_needed_for_update()7102 void TABLE::mark_columns_needed_for_update()
7103 {
7104 DBUG_ENTER("TABLE::mark_columns_needed_for_update");
7105 bool need_signal= false;
7106
7107
7108 if (triggers)
7109 triggers->mark_fields_used(TRG_EVENT_UPDATE);
7110 if (default_field)
7111 mark_default_fields_for_write(FALSE);
7112 if (vfield)
7113 need_signal|= mark_virtual_columns_for_write(FALSE);
7114 if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
7115 {
7116 KEY *end= key_info + s->keys;
7117 for (KEY *k= key_info; k < end; k++)
7118 {
7119 KEY_PART_INFO *kpend= k->key_part + k->ext_key_parts;
7120 int any_written= 0, all_read= 1;
7121 for (KEY_PART_INFO *kp= k->key_part; kp < kpend; kp++)
7122 {
7123 int idx= kp->fieldnr - 1;
7124 any_written|= bitmap_is_set(write_set, idx);
7125 all_read&= bitmap_is_set(read_set, idx);
7126 }
7127 if (any_written && !all_read)
7128 {
7129 for (KEY_PART_INFO *kp= k->key_part; kp < kpend; kp++)
7130 mark_column_with_deps(field[kp->fieldnr - 1]);
7131 }
7132 }
7133 need_signal= true;
7134 }
7135 else
7136 {
7137 if (found_next_number_field)
7138 mark_auto_increment_column();
7139 }
7140
7141 if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
7142 {
7143 /*
7144 If the handler has no cursor capabilites, we have to read either
7145 the primary key, the hidden primary key or all columns to be
7146 able to do an update
7147 */
7148 if (s->primary_key == MAX_KEY)
7149 file->use_hidden_primary_key();
7150 else
7151 {
7152 mark_index_columns_for_read(s->primary_key);
7153 need_signal= true;
7154 }
7155 }
7156 if (s->versioned)
7157 {
7158 /*
7159 For System Versioning we have to read all columns since we store
7160 a copy of previous row with modified row_end back to a table.
7161 */
7162 bitmap_union(read_set, &s->all_set);
7163 need_signal= true;
7164 }
7165 if (check_constraints)
7166 {
7167 mark_check_constraint_columns_for_read();
7168 need_signal= true;
7169 }
7170
7171 /*
7172 If a timestamp field settable on UPDATE is present then to avoid wrong
7173 update force the table handler to retrieve write-only fields to be able
7174 to compare records and detect data change.
7175 */
7176 if ((file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
7177 default_field && s->has_update_default_function)
7178 {
7179 bitmap_union(read_set, write_set);
7180 need_signal= true;
7181 }
7182 mark_columns_per_binlog_row_image();
7183 if (need_signal)
7184 file->column_bitmaps_signal();
7185 DBUG_VOID_RETURN;
7186 }
7187
7188
7189 /*
7190 Mark columns the handler needs for doing an insert
7191
7192 For now, this is used to mark fields used by the trigger
7193 as changed.
7194 */
7195
mark_columns_needed_for_insert()7196 void TABLE::mark_columns_needed_for_insert()
7197 {
7198 DBUG_ENTER("mark_columns_needed_for_insert");
7199
7200 if (triggers)
7201 {
7202 /*
7203 We don't need to mark columns which are used by ON DELETE and
7204 ON UPDATE triggers, which may be invoked in case of REPLACE or
7205 INSERT ... ON DUPLICATE KEY UPDATE, since before doing actual
7206 row replacement or update write_record() will mark all table
7207 fields as used.
7208 */
7209 triggers->mark_fields_used(TRG_EVENT_INSERT);
7210 }
7211 if (found_next_number_field)
7212 mark_auto_increment_column();
7213 if (default_field)
7214 mark_default_fields_for_write(TRUE);
7215 /* Mark virtual columns for insert */
7216 if (vfield)
7217 mark_virtual_columns_for_write(TRUE);
7218 mark_columns_per_binlog_row_image();
7219 if (check_constraints)
7220 mark_check_constraint_columns_for_read();
7221 DBUG_VOID_RETURN;
7222 }
7223
7224 /*
7225 Mark columns according the binlog row image option.
7226
7227 Columns to be written are stored in 'rpl_write_set'
7228
7229 When logging in RBR, the user can select whether to
7230 log partial or full rows, depending on the table
7231 definition, and the value of binlog_row_image.
7232
7233 Semantics of the binlog_row_image are the following
7234 (PKE - primary key equivalent, ie, PK fields if PK
7235 exists, all fields otherwise):
7236
7237 binlog_row_image= MINIMAL
7238 - This marks the PKE fields in the read_set
7239 - This marks all fields where a value was specified
7240 in the rpl_write_set
7241
7242 binlog_row_image= NOBLOB
7243 - This marks PKE + all non-blob fields in the read_set
7244 - This marks all fields where a value was specified
7245 and all non-blob fields in the rpl_write_set
7246
7247 binlog_row_image= FULL
7248 - all columns in the read_set
7249 - all columns in the rpl_write_set
7250
7251 This marking is done without resetting the original
7252 bitmaps. This means that we will strip extra fields in
7253 the read_set at binlogging time (for those cases that
7254 we only want to log a PK and we needed other fields for
7255 execution).
7256 */
7257
mark_columns_per_binlog_row_image()7258 void TABLE::mark_columns_per_binlog_row_image()
7259 {
7260 THD *thd= in_use;
7261 DBUG_ENTER("mark_columns_per_binlog_row_image");
7262 DBUG_ASSERT(read_set->bitmap);
7263 DBUG_ASSERT(write_set->bitmap);
7264
7265 /* If not using row format */
7266 rpl_write_set= write_set;
7267
7268 /**
7269 If in RBR we may need to mark some extra columns,
7270 depending on the binlog-row-image command line argument.
7271 */
7272 if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
7273 thd->is_current_stmt_binlog_format_row() &&
7274 !ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT))
7275 {
7276 /* if there is no PK, then mark all columns for the BI. */
7277 if (s->primary_key >= MAX_KEY)
7278 {
7279 bitmap_set_all(read_set);
7280 rpl_write_set= read_set;
7281 }
7282 else
7283 {
7284 switch (thd->variables.binlog_row_image) {
7285 case BINLOG_ROW_IMAGE_FULL:
7286 bitmap_set_all(read_set);
7287 /* Set of columns that should be written (all) */
7288 rpl_write_set= read_set;
7289 break;
7290 case BINLOG_ROW_IMAGE_NOBLOB:
7291 /* Only write changed columns + not blobs */
7292 rpl_write_set= &def_rpl_write_set;
7293 bitmap_copy(rpl_write_set, write_set);
7294
7295 /*
7296 for every field that is not set, mark it unless it is a blob or
7297 part of a primary key
7298 */
7299 for (Field **ptr=field ; *ptr ; ptr++)
7300 {
7301 Field *my_field= *ptr;
7302 /*
7303 bypass blob fields. These can be set or not set, we don't care.
7304 Later, at binlogging time, if we don't need them in the before
7305 image, we will discard them.
7306
7307 If set in the AI, then the blob is really needed, there is
7308 nothing we can do about it.
7309 */
7310 if ((my_field->flags & PRI_KEY_FLAG) ||
7311 (my_field->type() != MYSQL_TYPE_BLOB))
7312 {
7313 my_field->register_field_in_read_map();
7314 bitmap_set_bit(rpl_write_set, my_field->field_index);
7315 }
7316 }
7317 break;
7318 case BINLOG_ROW_IMAGE_MINIMAL:
7319 /*
7320 mark the primary key in the read set so that we can find the row
7321 that is updated / deleted.
7322 We don't need to mark the primary key in the rpl_write_set as the
7323 binary log will include all columns read anyway.
7324 */
7325 mark_index_columns_for_read(s->primary_key);
7326 if (versioned())
7327 {
7328 // TODO: After MDEV-18432 we don't pass history rows, so remove this:
7329 rpl_write_set= &s->all_set;
7330 }
7331 else
7332 {
7333 /* Only write columns that have changed */
7334 rpl_write_set= write_set;
7335 }
7336 break;
7337
7338 default:
7339 DBUG_ASSERT(FALSE);
7340 }
7341 }
7342 file->column_bitmaps_signal();
7343 }
7344
7345 DBUG_VOID_RETURN;
7346 }
7347
7348
7349 /*
7350 @brief Mark virtual columns for update/insert commands
7351
7352 @param insert_fl true if virtual columns are marked for insert command
7353 For the moment this is not used, may be used in future.
7354
7355 @details
7356 The function marks virtual columns used in a update/insert commands
7357 in the vcol_set bitmap.
7358 For an insert command a virtual column is always marked in write_set if
7359 it is a stored column.
7360 If a virtual column is from write_set it is always marked in vcol_set.
7361 If a stored virtual column is not from write_set but it is computed
7362 through columns from write_set it is also marked in vcol_set, and,
7363 besides, it is added to write_set.
7364
7365 @return whether a bitmap was updated
7366
7367 @note
7368 Let table t1 have columns a,b,c and let column c be a stored virtual
7369 column computed through columns a and b. Then for the query
7370 UPDATE t1 SET a=1
7371 column c will be placed into vcol_set and into write_set while
7372 column b will be placed into read_set.
7373 If column c was a virtual column, but not a stored virtual column
7374 then it would not be added to any of the sets. Column b would not
7375 be added to read_set either.
7376 */
7377
mark_virtual_columns_for_write(bool insert_fl)7378 bool TABLE::mark_virtual_columns_for_write(bool insert_fl
7379 __attribute__((unused)))
7380 {
7381 Field **vfield_ptr, *tmp_vfield;
7382 bool bitmap_updated= false;
7383 DBUG_ENTER("mark_virtual_columns_for_write");
7384
7385 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7386 {
7387 tmp_vfield= *vfield_ptr;
7388 if (bitmap_is_set(write_set, tmp_vfield->field_index))
7389 bitmap_updated|= mark_virtual_column_with_deps(tmp_vfield);
7390 else if (tmp_vfield->vcol_info->stored_in_db ||
7391 (tmp_vfield->flags & (PART_KEY_FLAG | FIELD_IN_PART_FUNC_FLAG |
7392 PART_INDIRECT_KEY_FLAG)))
7393 {
7394 bitmap_set_bit(write_set, tmp_vfield->field_index);
7395 mark_virtual_column_with_deps(tmp_vfield);
7396 bitmap_updated= true;
7397 }
7398 }
7399 if (bitmap_updated)
7400 file->column_bitmaps_signal();
7401 DBUG_RETURN(bitmap_updated);
7402 }
7403
7404
7405 /**
7406 Check if a virtual not stored column field is in read set
7407
7408 @retval FALSE No virtual not stored column is used
7409 @retval TRUE At least one virtual not stored column is used
7410 */
7411
check_virtual_columns_marked_for_read()7412 bool TABLE::check_virtual_columns_marked_for_read()
7413 {
7414 if (vfield)
7415 {
7416 Field **vfield_ptr;
7417 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7418 {
7419 Field *tmp_vfield= *vfield_ptr;
7420 if (bitmap_is_set(read_set, tmp_vfield->field_index) &&
7421 !tmp_vfield->vcol_info->stored_in_db)
7422 return TRUE;
7423 }
7424 }
7425 return FALSE;
7426 }
7427
7428
7429 /**
7430 Check if a stored virtual column field is marked for write
7431
7432 This can be used to check if any column that is part of a virtual
7433 stored column is changed
7434
7435 @retval FALSE No stored virtual column is used
7436 @retval TRUE At least one stored virtual column is used
7437 */
7438
check_virtual_columns_marked_for_write()7439 bool TABLE::check_virtual_columns_marked_for_write()
7440 {
7441 if (vfield)
7442 {
7443 Field **vfield_ptr;
7444 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7445 {
7446 Field *tmp_vfield= *vfield_ptr;
7447 if (bitmap_is_set(write_set, tmp_vfield->field_index) &&
7448 tmp_vfield->vcol_info->stored_in_db)
7449 return TRUE;
7450 }
7451 }
7452 return FALSE;
7453 }
7454
7455
7456 /*
7457 Mark fields used by check constraints into s->check_set.
7458 Mark all fields used in an expression that is part of an index
7459 with PART_INDIRECT_KEY_FLAG
7460
7461 This is done once for the TABLE_SHARE the first time the table is opened.
7462 The marking must be done non-destructively to handle the case when
7463 this could be run in parallely by two threads
7464 */
7465
mark_columns_used_by_virtual_fields(void)7466 void TABLE::mark_columns_used_by_virtual_fields(void)
7467 {
7468 MY_BITMAP *save_read_set;
7469 Field **vfield_ptr;
7470 TABLE_SHARE::enum_v_keys v_keys= TABLE_SHARE::NO_V_KEYS;
7471
7472 /* If there is virtual fields are already initialized */
7473 if (s->check_set_initialized)
7474 return;
7475
7476 if (s->tmp_table == NO_TMP_TABLE)
7477 mysql_mutex_lock(&s->LOCK_share);
7478 if (s->check_set)
7479 {
7480 /* Mark fields used by check constraint */
7481 save_read_set= read_set;
7482 read_set= s->check_set;
7483
7484 for (Virtual_column_info **chk= check_constraints ; *chk ; chk++)
7485 (*chk)->expr->walk(&Item::register_field_in_read_map, 1, 0);
7486 read_set= save_read_set;
7487 }
7488
7489 /*
7490 mark all fields that part of a virtual indexed field with
7491 PART_INDIRECT_KEY_FLAG. This is used to ensure that all fields
7492 that are part of an index exits before write/delete/update.
7493
7494 As this code is only executed once per open share, it's reusing
7495 existing functionality instead of adding an extra argument to
7496 add_field_to_set_processor or adding another processor.
7497 */
7498 if (vfield)
7499 {
7500 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7501 {
7502 if ((*vfield_ptr)->flags & PART_KEY_FLAG)
7503 (*vfield_ptr)->vcol_info->expr->walk(&Item::add_field_to_set_processor,
7504 1, this);
7505 }
7506 for (uint i= 0 ; i < s->fields ; i++)
7507 {
7508 if (bitmap_is_set(&tmp_set, i))
7509 {
7510 s->field[i]->flags|= PART_INDIRECT_KEY_FLAG;
7511 v_keys= TABLE_SHARE::V_KEYS;
7512 }
7513 }
7514 bitmap_clear_all(&tmp_set);
7515 }
7516 s->check_set_initialized= v_keys;
7517 if (s->tmp_table == NO_TMP_TABLE)
7518 mysql_mutex_unlock(&s->LOCK_share);
7519 }
7520
7521 /* Add fields used by CHECK CONSTRAINT to read map */
7522
mark_check_constraint_columns_for_read(void)7523 void TABLE::mark_check_constraint_columns_for_read(void)
7524 {
7525 bitmap_union(read_set, s->check_set);
7526 }
7527
7528
7529 /**
7530 Add all fields that have a default function to the table write set.
7531 */
7532
mark_default_fields_for_write(bool is_insert)7533 void TABLE::mark_default_fields_for_write(bool is_insert)
7534 {
7535 DBUG_ENTER("mark_default_fields_for_write");
7536 Field **field_ptr, *field;
7537 for (field_ptr= default_field; *field_ptr; field_ptr++)
7538 {
7539 field= (*field_ptr);
7540 if (is_insert && field->default_value)
7541 {
7542 bitmap_set_bit(write_set, field->field_index);
7543 field->default_value->expr->
7544 walk(&Item::register_field_in_read_map, 1, 0);
7545 }
7546 else if (!is_insert && field->has_update_default_function())
7547 bitmap_set_bit(write_set, field->field_index);
7548 }
7549 DBUG_VOID_RETURN;
7550 }
7551
7552
move_fields(Field ** ptr,const uchar * to,const uchar * from)7553 void TABLE::move_fields(Field **ptr, const uchar *to, const uchar *from)
7554 {
7555 my_ptrdiff_t diff= to - from;
7556 if (diff)
7557 {
7558 do
7559 {
7560 (*ptr)->move_field_offset(diff);
7561 } while (*(++ptr));
7562 }
7563 }
7564
7565
7566 /*
7567 Store all allocated virtual fields blob values
7568 Used by InnoDB when calculating virtual fields for it's own internal
7569 records
7570 */
7571
remember_blob_values(String * blob_storage)7572 void TABLE::remember_blob_values(String *blob_storage)
7573 {
7574 Field **vfield_ptr;
7575 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7576 {
7577 if ((*vfield_ptr)->type() == MYSQL_TYPE_BLOB &&
7578 !(*vfield_ptr)->vcol_info->stored_in_db)
7579 {
7580 Field_blob *blob= ((Field_blob*) *vfield_ptr);
7581 memcpy((void*) blob_storage, (void*) &blob->value, sizeof(blob->value));
7582 blob_storage++;
7583 blob->value.release();
7584 }
7585 }
7586 }
7587
7588
7589 /*
7590 Restore all allocated virtual fields blob values
7591 Used by InnoDB when calculating virtual fields for it's own internal
7592 records
7593 */
7594
restore_blob_values(String * blob_storage)7595 void TABLE::restore_blob_values(String *blob_storage)
7596 {
7597 Field **vfield_ptr;
7598 for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
7599 {
7600 if ((*vfield_ptr)->type() == MYSQL_TYPE_BLOB &&
7601 !(*vfield_ptr)->vcol_info->stored_in_db)
7602 {
7603 Field_blob *blob= ((Field_blob*) *vfield_ptr);
7604 blob->value.free();
7605 memcpy((void*) &blob->value, (void*) blob_storage, sizeof(blob->value));
7606 blob_storage++;
7607 }
7608 }
7609 }
7610
7611
7612 /**
7613 @brief
7614 Allocate space for keys
7615
7616 @param key_count number of keys to allocate additionally
7617
7618 @details
7619 The function allocates memory to fit additionally 'key_count' keys
7620 for this table.
7621
7622 @return FALSE space was successfully allocated
7623 @return TRUE an error occur
7624 */
7625
alloc_keys(uint key_count)7626 bool TABLE::alloc_keys(uint key_count)
7627 {
7628 key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*(s->keys+key_count));
7629 if (s->keys)
7630 memmove(key_info, s->key_info, sizeof(KEY)*s->keys);
7631 s->key_info= key_info;
7632 max_keys= s->keys+key_count;
7633 return !(key_info);
7634 }
7635
7636
7637 /**
7638 @brief
7639 Populate a KEY_PART_INFO structure with the data related to a field entry.
7640
7641 @param key_part_info The structure to fill.
7642 @param field The field entry that represents the key part.
7643 @param fleldnr The number of the field, count starting from 1.
7644
7645 TODO: This method does not make use of any table specific fields. It
7646 could be refactored to act as a constructor for KEY_PART_INFO instead.
7647 */
7648
create_key_part_by_field(KEY_PART_INFO * key_part_info,Field * field,uint fieldnr)7649 void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info,
7650 Field *field, uint fieldnr)
7651 {
7652 DBUG_ASSERT(field->field_index + 1 == (int)fieldnr);
7653 key_part_info->null_bit= field->null_bit;
7654 key_part_info->null_offset= (uint) (field->null_ptr -
7655 (uchar*) record[0]);
7656 key_part_info->field= field;
7657 key_part_info->fieldnr= fieldnr;
7658 key_part_info->offset= field->offset(record[0]);
7659 /*
7660 field->key_length() accounts for the raw length of the field, excluding
7661 any metadata such as length of field or the NULL flag.
7662 */
7663 key_part_info->length= (uint16) field->key_length();
7664 key_part_info->key_part_flag= 0;
7665 /* TODO:
7666 The below method of computing the key format length of the
7667 key part is a copy/paste from opt_range.cc, and table.cc.
7668 This should be factored out, e.g. as a method of Field.
7669 In addition it is not clear if any of the Field::*_length
7670 methods is supposed to compute the same length. If so, it
7671 might be reused.
7672 */
7673 key_part_info->store_length= key_part_info->length;
7674 /*
7675 For BIT fields null_bit is not set to 0 even if the field is defined
7676 as NOT NULL, look at Field_bit::Field_bit
7677 */
7678 if (!field->real_maybe_null())
7679 {
7680 key_part_info->null_bit= 0;
7681 }
7682
7683 /*
7684 The total store length of the key part is the raw length of the field +
7685 any metadata information, such as its length for strings and/or the null
7686 flag.
7687 */
7688 if (field->real_maybe_null())
7689 {
7690 key_part_info->store_length+= HA_KEY_NULL_LENGTH;
7691 }
7692 if (field->type() == MYSQL_TYPE_BLOB ||
7693 field->type() == MYSQL_TYPE_GEOMETRY ||
7694 field->real_type() == MYSQL_TYPE_VARCHAR)
7695 {
7696 key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
7697 key_part_info->key_part_flag|=
7698 field->type() == MYSQL_TYPE_BLOB ? HA_BLOB_PART: HA_VAR_LENGTH_PART;
7699 }
7700
7701 key_part_info->type= (uint8) field->key_type();
7702 key_part_info->key_type =
7703 ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
7704 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
7705 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
7706 0 : FIELDFLAG_BINARY;
7707 }
7708
7709
7710 /**
7711 @brief
7712 Check validity of a possible key for the derived table
7713
7714 @param key the number of the key
7715 @param key_parts number of components of the key
7716 @param next_field_no the call-back function that returns the number of
7717 the field used as the next component of the key
7718 @param arg the argument for the above function
7719
7720 @details
7721 The function checks whether a possible key satisfies the constraints
7722 imposed on the keys of any temporary table.
7723
7724 We need to filter out BLOB columns here, because ref access optimizer creates
7725 KEYUSE objects for equalities for non-key columns for two puproses:
7726 1. To discover possible keys for derived_with_keys optimization
7727 2. To do hash joins
7728 For the purpose of #1, KEYUSE objects are not created for "blob_column=..." .
7729 However, they might be created for #2. In order to catch that case, we filter
7730 them out here.
7731
7732 @return TRUE if the key is valid
7733 @return FALSE otherwise
7734 */
7735
check_tmp_key(uint key,uint key_parts,uint (* next_field_no)(uchar *),uchar * arg)7736 bool TABLE::check_tmp_key(uint key, uint key_parts,
7737 uint (*next_field_no) (uchar *), uchar *arg)
7738 {
7739 Field **reg_field;
7740 uint i;
7741 uint key_len= 0;
7742
7743 for (i= 0; i < key_parts; i++)
7744 {
7745 uint fld_idx= next_field_no(arg);
7746 reg_field= field + fld_idx;
7747 if ((*reg_field)->type() == MYSQL_TYPE_BLOB)
7748 return FALSE;
7749 uint fld_store_len= (uint16) (*reg_field)->key_length();
7750 if ((*reg_field)->real_maybe_null())
7751 fld_store_len+= HA_KEY_NULL_LENGTH;
7752 if ((*reg_field)->real_type() == MYSQL_TYPE_VARCHAR ||
7753 (*reg_field)->type() == MYSQL_TYPE_GEOMETRY)
7754 fld_store_len+= HA_KEY_BLOB_LENGTH;
7755 key_len+= fld_store_len;
7756 }
7757 /*
7758 We use MI_MAX_KEY_LENGTH (myisam's default) below because it is
7759 smaller than MAX_KEY_LENGTH (heap's default) and it's unknown whether
7760 myisam or heap will be used for the temporary table.
7761 */
7762 return key_len <= MI_MAX_KEY_LENGTH;
7763 }
7764
7765 /**
7766 @brief
7767 Add one key to a temporary table
7768
7769 @param key the number of the key
7770 @param key_parts number of components of the key
7771 @param next_field_no the call-back function that returns the number of
7772 the field used as the next component of the key
7773 @param arg the argument for the above function
7774 @param unique TRUE <=> it is a unique index
7775
7776 @details
7777 The function adds a new key to the table that is assumed to be a temporary
7778 table. At each its invocation the call-back function must return
7779 the number of the field that is used as the next component of this key.
7780
7781 @return FALSE is a success
7782 @return TRUE if a failure
7783
7784 */
7785
add_tmp_key(uint key,uint key_parts,uint (* next_field_no)(uchar *),uchar * arg,bool unique)7786 bool TABLE::add_tmp_key(uint key, uint key_parts,
7787 uint (*next_field_no) (uchar *), uchar *arg,
7788 bool unique)
7789 {
7790 DBUG_ASSERT(key < max_keys);
7791
7792 char buf[NAME_CHAR_LEN];
7793 KEY* keyinfo;
7794 Field **reg_field;
7795 uint i;
7796
7797 bool key_start= TRUE;
7798 KEY_PART_INFO* key_part_info=
7799 (KEY_PART_INFO*) alloc_root(&mem_root, sizeof(KEY_PART_INFO)*key_parts);
7800 if (!key_part_info)
7801 return TRUE;
7802 keyinfo= key_info + key;
7803 keyinfo->key_part= key_part_info;
7804 keyinfo->usable_key_parts= keyinfo->user_defined_key_parts = key_parts;
7805 keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
7806 keyinfo->key_length=0;
7807 keyinfo->algorithm= HA_KEY_ALG_UNDEF;
7808 keyinfo->flags= HA_GENERATED_KEY;
7809 keyinfo->ext_key_flags= keyinfo->flags;
7810 keyinfo->is_statistics_from_stat_tables= FALSE;
7811 if (unique)
7812 keyinfo->flags|= HA_NOSAME;
7813 sprintf(buf, "key%i", key);
7814 keyinfo->name.length= strlen(buf);
7815 if (!(keyinfo->name.str= strmake_root(&mem_root, buf, keyinfo->name.length)))
7816 return TRUE;
7817 keyinfo->rec_per_key= (ulong*) alloc_root(&mem_root,
7818 sizeof(ulong)*key_parts);
7819 if (!keyinfo->rec_per_key)
7820 return TRUE;
7821 bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
7822 keyinfo->read_stats= NULL;
7823 keyinfo->collected_stats= NULL;
7824
7825 for (i= 0; i < key_parts; i++)
7826 {
7827 uint fld_idx= next_field_no(arg);
7828 reg_field= field + fld_idx;
7829 if (key_start)
7830 (*reg_field)->key_start.set_bit(key);
7831 (*reg_field)->part_of_key.set_bit(key);
7832 create_key_part_by_field(key_part_info, *reg_field, fld_idx+1);
7833 keyinfo->key_length += key_part_info->store_length;
7834 (*reg_field)->flags|= PART_KEY_FLAG;
7835 key_start= FALSE;
7836 key_part_info++;
7837 }
7838
7839 /*
7840 For the case when there is a derived table that would give distinct rows,
7841 the index statistics are passed to the join optimizer to tell that a ref
7842 access to all the fields of the derived table will produce only one row.
7843 */
7844
7845 st_select_lex_unit* derived= pos_in_table_list ?
7846 pos_in_table_list->derived: NULL;
7847 if (derived)
7848 {
7849 st_select_lex* first= derived->first_select();
7850 uint select_list_items= first->get_item_list()->elements;
7851 if (key_parts == select_list_items)
7852 {
7853 if ((!first->is_part_of_union() && (first->options & SELECT_DISTINCT)) ||
7854 derived->check_distinct_in_union())
7855 keyinfo->rec_per_key[key_parts - 1]= 1;
7856 }
7857 }
7858
7859 set_if_bigger(s->max_key_length, keyinfo->key_length);
7860 s->keys++;
7861 return FALSE;
7862 }
7863
7864 /*
7865 @brief
7866 Drop all indexes except specified one.
7867
7868 @param key_to_save the key to save
7869
7870 @details
7871 Drop all indexes on this table except 'key_to_save'. The saved key becomes
7872 key #0. Memory occupied by key parts of dropped keys are freed.
7873 If the 'key_to_save' is negative then all keys are freed.
7874 */
7875
use_index(int key_to_save)7876 void TABLE::use_index(int key_to_save)
7877 {
7878 uint i= 1;
7879 DBUG_ASSERT(!created && key_to_save < (int)s->keys);
7880 if (key_to_save >= 0)
7881 /* Save the given key. */
7882 memmove(key_info, key_info + key_to_save, sizeof(KEY));
7883 else
7884 /* Drop all keys; */
7885 i= 0;
7886
7887 s->keys= i;
7888 }
7889
7890 /*
7891 Return TRUE if the table is filled at execution phase
7892
7893 (and so, the optimizer must not do anything that depends on the contents of
7894 the table, like range analysis or constant table detection)
7895 */
7896
is_filled_at_execution()7897 bool TABLE::is_filled_at_execution()
7898 {
7899 /*
7900 pos_in_table_list == NULL for internal temporary tables because they
7901 do not have a corresponding table reference. Such tables are filled
7902 during execution.
7903 */
7904 return MY_TEST(!pos_in_table_list ||
7905 pos_in_table_list->jtbm_subselect ||
7906 pos_in_table_list->is_active_sjm());
7907 }
7908
7909
7910 /**
7911 @brief
7912 Get actual number of key components
7913
7914 @param keyinfo
7915
7916 @details
7917 The function calculates actual number of key components, possibly including
7918 components of extended keys, taken into consideration by the optimizer for the
7919 key described by the parameter keyinfo.
7920
7921 @return number of considered key components
7922 */
7923
actual_n_key_parts(KEY * keyinfo)7924 uint TABLE::actual_n_key_parts(KEY *keyinfo)
7925 {
7926 return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
7927 keyinfo->ext_key_parts : keyinfo->user_defined_key_parts;
7928 }
7929
7930
7931 /**
7932 @brief
7933 Get actual key flags for a table key
7934
7935 @param keyinfo
7936
7937 @details
7938 The function finds out actual key flags taken into consideration by the
7939 optimizer for the key described by the parameter keyinfo.
7940
7941 @return actual key flags
7942 */
7943
actual_key_flags(KEY * keyinfo)7944 ulong TABLE::actual_key_flags(KEY *keyinfo)
7945 {
7946 return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
7947 keyinfo->ext_key_flags : keyinfo->flags;
7948 }
7949
7950
7951 /*
7952 Cleanup this table for re-execution.
7953
7954 SYNOPSIS
7955 TABLE_LIST::reinit_before_use()
7956 */
7957
reinit_before_use(THD * thd)7958 void TABLE_LIST::reinit_before_use(THD *thd)
7959 {
7960 /*
7961 Reset old pointers to TABLEs: they are not valid since the tables
7962 were closed in the end of previous prepare or execute call.
7963 */
7964 table= 0;
7965 /* Reset is_schema_table_processed value(needed for I_S tables */
7966 schema_table_state= NOT_PROCESSED;
7967
7968 TABLE_LIST *embedded; /* The table at the current level of nesting. */
7969 TABLE_LIST *parent_embedding= this; /* The parent nested table reference. */
7970 do
7971 {
7972 embedded= parent_embedding;
7973 if (embedded->prep_on_expr)
7974 embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
7975 parent_embedding= embedded->embedding;
7976 }
7977 while (parent_embedding &&
7978 parent_embedding->nested_join->join_list.head() == embedded);
7979
7980 mdl_request.ticket= NULL;
7981 }
7982
7983
7984 /*
7985 Return subselect that contains the FROM list this table is taken from
7986
7987 SYNOPSIS
7988 TABLE_LIST::containing_subselect()
7989
7990 RETURN
7991 Subselect item for the subquery that contains the FROM list
7992 this table is taken from if there is any
7993 0 - otherwise
7994
7995 */
7996
containing_subselect()7997 Item_subselect *TABLE_LIST::containing_subselect()
7998 {
7999 return (select_lex ? select_lex->master_unit()->item : 0);
8000 }
8001
8002 /*
8003 Compiles the tagged hints list and fills up the bitmasks.
8004
8005 SYNOPSIS
8006 process_index_hints()
8007 table the TABLE to operate on.
8008
8009 DESCRIPTION
8010 The parser collects the index hints for each table in a "tagged list"
8011 (TABLE_LIST::index_hints). Using the information in this tagged list
8012 this function sets the members TABLE::keys_in_use_for_query,
8013 TABLE::keys_in_use_for_group_by, TABLE::keys_in_use_for_order_by,
8014 TABLE::force_index, TABLE::force_index_order,
8015 TABLE::force_index_group and TABLE::covering_keys.
8016
8017 Current implementation of the runtime does not allow mixing FORCE INDEX
8018 and USE INDEX, so this is checked here. Then the FORCE INDEX list
8019 (if non-empty) is appended to the USE INDEX list and a flag is set.
8020
8021 Multiple hints of the same kind are processed so that each clause
8022 is applied to what is computed in the previous clause.
8023 For example:
8024 USE INDEX (i1) USE INDEX (i2)
8025 is equivalent to
8026 USE INDEX (i1,i2)
8027 and means "consider only i1 and i2".
8028
8029 Similarly
8030 USE INDEX () USE INDEX (i1)
8031 is equivalent to
8032 USE INDEX (i1)
8033 and means "consider only the index i1"
8034
8035 It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
8036 not an error.
8037
8038 Different kind of hints (USE/FORCE/IGNORE) are processed in the following
8039 order:
8040 1. All indexes in USE (or FORCE) INDEX are added to the mask.
8041 2. All IGNORE INDEX
8042
8043 e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
8044 as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
8045
8046 As an optimization if there is a covering index, and we have
8047 IGNORE INDEX FOR GROUP/ORDER, and this index is used for the JOIN part,
8048 then we have to ignore the IGNORE INDEX FROM GROUP/ORDER.
8049
8050 RETURN VALUE
8051 FALSE no errors found
8052 TRUE found and reported an error.
8053 */
process_index_hints(TABLE * tbl)8054 bool TABLE_LIST::process_index_hints(TABLE *tbl)
8055 {
8056 /* initialize the result variables */
8057 tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
8058 tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
8059
8060 /* index hint list processing */
8061 if (index_hints)
8062 {
8063 key_map index_join[INDEX_HINT_FORCE + 1];
8064 key_map index_order[INDEX_HINT_FORCE + 1];
8065 key_map index_group[INDEX_HINT_FORCE + 1];
8066 Index_hint *hint;
8067 int type;
8068 bool have_empty_use_join= FALSE, have_empty_use_order= FALSE,
8069 have_empty_use_group= FALSE;
8070 List_iterator <Index_hint> iter(*index_hints);
8071
8072 /* initialize temporary variables used to collect hints of each kind */
8073 for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
8074 {
8075 index_join[type].clear_all();
8076 index_order[type].clear_all();
8077 index_group[type].clear_all();
8078 }
8079
8080 /* iterate over the hints list */
8081 while ((hint= iter++))
8082 {
8083 uint pos;
8084
8085 /* process empty USE INDEX () */
8086 if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
8087 {
8088 if (hint->clause & INDEX_HINT_MASK_JOIN)
8089 {
8090 index_join[hint->type].clear_all();
8091 have_empty_use_join= TRUE;
8092 }
8093 if (hint->clause & INDEX_HINT_MASK_ORDER)
8094 {
8095 index_order[hint->type].clear_all();
8096 have_empty_use_order= TRUE;
8097 }
8098 if (hint->clause & INDEX_HINT_MASK_GROUP)
8099 {
8100 index_group[hint->type].clear_all();
8101 have_empty_use_group= TRUE;
8102 }
8103 continue;
8104 }
8105
8106 /*
8107 Check if an index with the given name exists and get his offset in
8108 the keys bitmask for the table
8109 */
8110 if (tbl->s->keynames.type_names == 0 ||
8111 (pos= find_type(&tbl->s->keynames, hint->key_name.str,
8112 hint->key_name.length, 1)) <= 0)
8113 {
8114 my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias.str);
8115 return 1;
8116 }
8117
8118 pos--;
8119
8120 /* add to the appropriate clause mask */
8121 if (hint->clause & INDEX_HINT_MASK_JOIN)
8122 index_join[hint->type].set_bit (pos);
8123 if (hint->clause & INDEX_HINT_MASK_ORDER)
8124 index_order[hint->type].set_bit (pos);
8125 if (hint->clause & INDEX_HINT_MASK_GROUP)
8126 index_group[hint->type].set_bit (pos);
8127 }
8128
8129 /* cannot mix USE INDEX and FORCE INDEX */
8130 if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
8131 !index_order[INDEX_HINT_FORCE].is_clear_all() ||
8132 !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
8133 (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join ||
8134 !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
8135 !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
8136 {
8137 my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
8138 index_hint_type_name[INDEX_HINT_FORCE]);
8139 return 1;
8140 }
8141
8142 /* process FORCE INDEX as USE INDEX with a flag */
8143 if (!index_order[INDEX_HINT_FORCE].is_clear_all())
8144 {
8145 tbl->force_index_order= TRUE;
8146 index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
8147 }
8148
8149 if (!index_group[INDEX_HINT_FORCE].is_clear_all())
8150 {
8151 tbl->force_index_group= TRUE;
8152 index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
8153 }
8154
8155 /*
8156 TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified)
8157 and create tbl->force_index_join instead.
8158 Then use the correct force_index_XX instead of the global one.
8159 */
8160 if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
8161 tbl->force_index_group || tbl->force_index_order)
8162 {
8163 tbl->force_index= TRUE;
8164 index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
8165 }
8166
8167 /* apply USE INDEX */
8168 if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
8169 tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
8170 if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
8171 tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
8172 if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
8173 tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
8174
8175 /* apply IGNORE INDEX */
8176 tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
8177 tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
8178 tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
8179 }
8180
8181 /* make sure covering_keys don't include indexes disabled with a hint */
8182 tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
8183 return 0;
8184 }
8185
8186
max_row_length(TABLE * table,MY_BITMAP const * cols,const uchar * data)8187 size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data)
8188 {
8189 TABLE_SHARE *table_s= table->s;
8190 size_t length= table_s->reclength + 2 * table_s->fields;
8191 uint *const beg= table_s->blob_field;
8192 uint *const end= beg + table_s->blob_fields;
8193 my_ptrdiff_t const rec_offset= (my_ptrdiff_t) (data - table->record[0]);
8194 DBUG_ENTER("max_row_length");
8195
8196 for (uint *ptr= beg ; ptr != end ; ++ptr)
8197 {
8198 Field * const field= table->field[*ptr];
8199 if (bitmap_is_set(cols, field->field_index) &&
8200 !field->is_null(rec_offset))
8201 {
8202 Field_blob * const blob= (Field_blob*) field;
8203 length+= blob->get_length(rec_offset) + 8; /* max blob store length */
8204 }
8205 }
8206 DBUG_PRINT("exit", ("length: %lld", (longlong) length));
8207 DBUG_RETURN(length);
8208 }
8209
8210
8211 /**
8212 Helper function which allows to allocate metadata lock request
8213 objects for all elements of table list.
8214 */
8215
init_mdl_requests(TABLE_LIST * table_list)8216 void init_mdl_requests(TABLE_LIST *table_list)
8217 {
8218 for ( ; table_list ; table_list= table_list->next_global)
8219 table_list->mdl_request.init(MDL_key::TABLE,
8220 table_list->db.str, table_list->table_name.str,
8221 table_list->lock_type >= TL_WRITE_ALLOW_WRITE ?
8222 MDL_SHARED_WRITE : MDL_SHARED_READ,
8223 MDL_TRANSACTION);
8224 }
8225
8226
8227 /**
8228 Update TABLE::const_key_parts for single table UPDATE/DELETE query
8229
8230 @param conds WHERE clause expression
8231
8232 @retval TRUE error (OOM)
8233 @retval FALSE success
8234
8235 @note
8236 Set const_key_parts bits if key fields are equal to constants in
8237 the WHERE expression.
8238 */
8239
update_const_key_parts(COND * conds)8240 bool TABLE::update_const_key_parts(COND *conds)
8241 {
8242 bzero((char*) const_key_parts, sizeof(key_part_map) * s->keys);
8243
8244 if (conds == NULL)
8245 return FALSE;
8246
8247 for (uint index= 0; index < s->keys; index++)
8248 {
8249 KEY_PART_INFO *keyinfo= key_info[index].key_part;
8250 KEY_PART_INFO *keyinfo_end= keyinfo + key_info[index].user_defined_key_parts;
8251
8252 for (key_part_map part_map= (key_part_map)1;
8253 keyinfo < keyinfo_end;
8254 keyinfo++, part_map<<= 1)
8255 {
8256 if (const_expression_in_where(conds, NULL, keyinfo->field))
8257 const_key_parts[index]|= part_map;
8258 }
8259 }
8260 return FALSE;
8261 }
8262
8263 /**
8264 Test if the order list consists of simple field expressions
8265
8266 @param order Linked list of ORDER BY arguments
8267
8268 @return TRUE if @a order is empty or consist of simple field expressions
8269 */
8270
is_simple_order(ORDER * order)8271 bool is_simple_order(ORDER *order)
8272 {
8273 for (ORDER *ord= order; ord; ord= ord->next)
8274 {
8275 if (ord->item[0]->real_item()->type() != Item::FIELD_ITEM)
8276 return FALSE;
8277 }
8278 return TRUE;
8279 }
8280
8281 class Turn_errors_to_warnings_handler : public Internal_error_handler
8282 {
8283 public:
Turn_errors_to_warnings_handler()8284 Turn_errors_to_warnings_handler() {}
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_warning_level * level,const char * msg,Sql_condition ** cond_hdl)8285 bool handle_condition(THD *thd,
8286 uint sql_errno,
8287 const char* sqlstate,
8288 Sql_condition::enum_warning_level *level,
8289 const char* msg,
8290 Sql_condition ** cond_hdl)
8291 {
8292 *cond_hdl= NULL;
8293 if (*level == Sql_condition::WARN_LEVEL_ERROR)
8294 *level= Sql_condition::WARN_LEVEL_WARN;
8295 return(0);
8296 }
8297 };
8298
8299
8300 /*
8301 to satisfy marked_for_write_or_computed() Field's assert we temporarily
8302 mark field for write before storing the generated value in it
8303 */
8304 #ifdef DBUG_ASSERT_EXISTS
8305 #define DBUG_FIX_WRITE_SET(f) bool _write_set_fixed= !bitmap_fast_test_and_set(write_set, (f)->field_index)
8306 #define DBUG_RESTORE_WRITE_SET(f) if (_write_set_fixed) bitmap_clear_bit(write_set, (f)->field_index)
8307 #else
8308 #define DBUG_FIX_WRITE_SET(f)
8309 #define DBUG_RESTORE_WRITE_SET(f)
8310 #endif
8311
8312
8313 /*
8314 @brief Compute values for virtual columns used in query
8315
8316 @param update_mode Specifies what virtual column are computed
8317
8318 @details
8319 The function computes the values of the virtual columns of the table and
8320 stores them in the table record buffer.
8321 This will be done even if is_error() is set either when function was called
8322 or by calculating the virtual function, as most calls to this
8323 function doesn't check the result. We also want to ensure that as many
8324 fields as possible has the right value so that we can optionally
8325 return the partly-faulty-row from a storage engine with a virtual
8326 field that gives an error on storage for an existing row.
8327
8328 @todo
8329 Ensure that all caller checks the value of this function and
8330 either properly ignores it (and resets the error) or sends the
8331 error forward to the caller.
8332
8333 @retval
8334 0 Success
8335 @retval
8336 >0 Error occurred when storing a virtual field value or potentially
8337 is_error() was set when function was called.
8338 */
8339
update_virtual_fields(handler * h,enum_vcol_update_mode update_mode)8340 int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
8341 {
8342 DBUG_ENTER("TABLE::update_virtual_fields");
8343 DBUG_PRINT("enter", ("update_mode: %d is_error: %d", update_mode,
8344 in_use->is_error()));
8345 Field **vfield_ptr, *vf;
8346 Query_arena backup_arena;
8347 Turn_errors_to_warnings_handler Suppress_errors;
8348 bool handler_pushed= 0, update_all_columns= 1;
8349 DBUG_ASSERT(vfield);
8350
8351 if (h->keyread_enabled())
8352 DBUG_RETURN(0);
8353
8354 in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
8355
8356 /* When reading or deleting row, ignore errors from virtual columns */
8357 if (update_mode == VCOL_UPDATE_FOR_READ ||
8358 update_mode == VCOL_UPDATE_FOR_DELETE ||
8359 update_mode == VCOL_UPDATE_INDEXED)
8360 {
8361 in_use->push_internal_handler(&Suppress_errors);
8362 handler_pushed= 1;
8363 }
8364 else if (update_mode == VCOL_UPDATE_FOR_REPLACE &&
8365 in_use->is_current_stmt_binlog_format_row() &&
8366 in_use->variables.binlog_row_image != BINLOG_ROW_IMAGE_MINIMAL)
8367 {
8368 /*
8369 If we are doing a replace with not minimal binary logging, we have to
8370 calculate all virtual columns.
8371 */
8372 update_all_columns= 1;
8373 }
8374
8375 /* Iterate over virtual fields in the table */
8376 for (vfield_ptr= vfield; *vfield_ptr ; vfield_ptr++)
8377 {
8378 vf= (*vfield_ptr);
8379 Virtual_column_info *vcol_info= vf->vcol_info;
8380 DBUG_ASSERT(vcol_info);
8381 DBUG_ASSERT(vcol_info->expr);
8382
8383 bool update= 0, swap_values= 0;
8384 switch (update_mode) {
8385 case VCOL_UPDATE_FOR_READ:
8386 update= (!vcol_info->stored_in_db &&
8387 bitmap_is_set(read_set, vf->field_index));
8388 swap_values= 1;
8389 break;
8390 case VCOL_UPDATE_FOR_DELETE:
8391 case VCOL_UPDATE_FOR_WRITE:
8392 update= bitmap_is_set(read_set, vf->field_index);
8393 break;
8394 case VCOL_UPDATE_FOR_REPLACE:
8395 update= ((!vcol_info->stored_in_db &&
8396 (vf->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG)) &&
8397 bitmap_is_set(read_set, vf->field_index)) ||
8398 update_all_columns);
8399 if (update && (vf->flags & BLOB_FLAG))
8400 {
8401 /*
8402 The row has been read into record[1] and Field_blob::value
8403 contains the value for record[0]. Swap value and read_value
8404 to ensure that the virtual column data for the read row will
8405 be in read_value at the end of this function
8406 */
8407 ((Field_blob*) vf)->swap_value_and_read_value();
8408 /* Ensure we call swap_value_and_read_value() after update */
8409 swap_values= 1;
8410 }
8411 break;
8412 case VCOL_UPDATE_INDEXED:
8413 case VCOL_UPDATE_INDEXED_FOR_UPDATE:
8414 /* Read indexed fields that was not updated in VCOL_UPDATE_FOR_READ */
8415 update= (!vcol_info->stored_in_db &&
8416 (vf->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG)) &&
8417 !bitmap_is_set(read_set, vf->field_index));
8418 swap_values= 1;
8419 break;
8420 }
8421
8422 if (update)
8423 {
8424 int field_error __attribute__((unused)) = 0;
8425 /* Compute the actual value of the virtual fields */
8426 DBUG_FIX_WRITE_SET(vf);
8427 field_error= vcol_info->expr->save_in_field(vf, 0);
8428 DBUG_RESTORE_WRITE_SET(vf);
8429 DBUG_PRINT("info", ("field '%s' - updated error: %d",
8430 vf->field_name.str, field_error));
8431 if (swap_values && (vf->flags & BLOB_FLAG))
8432 {
8433 /*
8434 Remember the read value to allow other update_virtual_field() calls
8435 for the same blob field for the row to be updated.
8436 Field_blob->read_value always contains the virtual column data for
8437 any read row.
8438 */
8439 ((Field_blob*) vf)->swap_value_and_read_value();
8440 }
8441 }
8442 else
8443 {
8444 DBUG_PRINT("info", ("field '%s' - skipped", vf->field_name.str));
8445 }
8446 }
8447 if (handler_pushed)
8448 in_use->pop_internal_handler();
8449 in_use->restore_active_arena(expr_arena, &backup_arena);
8450
8451 /* Return 1 only of we got a fatal error, not a warning */
8452 DBUG_RETURN(in_use->is_error());
8453 }
8454
update_virtual_field(Field * vf)8455 int TABLE::update_virtual_field(Field *vf)
8456 {
8457 DBUG_ENTER("TABLE::update_virtual_field");
8458 Query_arena backup_arena;
8459 Counting_error_handler count_errors;
8460 in_use->push_internal_handler(&count_errors);
8461 in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
8462 bitmap_clear_all(&tmp_set);
8463 vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set);
8464 DBUG_FIX_WRITE_SET(vf);
8465 vf->vcol_info->expr->save_in_field(vf, 0);
8466 DBUG_RESTORE_WRITE_SET(vf);
8467 in_use->restore_active_arena(expr_arena, &backup_arena);
8468 in_use->pop_internal_handler();
8469 DBUG_RETURN(count_errors.errors);
8470 }
8471
8472
8473 /**
8474 Update all DEFAULT and/or ON INSERT fields.
8475
8476 @details
8477 Compute and set the default value of all fields with a default function.
8478 There are two kinds of default functions - one is used for INSERT-like
8479 operations, the other for UPDATE-like operations. Depending on the field
8480 definition and the current operation one or the other kind of update
8481 function is evaluated.
8482
8483 @param update_command True if command was an update else insert
8484 @param ignore_errors True if we should ignore errors
8485
8486 @retval
8487 0 Success
8488 @retval
8489 >0 Error occurred when storing a virtual field value and
8490 ignore_errors == 0. If set then an error was generated.
8491 */
8492
update_default_fields(bool ignore_errors)8493 int TABLE::update_default_fields(bool ignore_errors)
8494 {
8495 Query_arena backup_arena;
8496 Field **field_ptr;
8497 int res= 0;
8498 DBUG_ENTER("TABLE::update_default_fields");
8499 DBUG_ASSERT(default_field);
8500
8501 in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
8502
8503 /* Iterate over fields with default functions in the table */
8504 for (field_ptr= default_field; *field_ptr ; field_ptr++)
8505 {
8506 Field *field= (*field_ptr);
8507 /*
8508 If an explicit default value for a field overrides the default,
8509 do not update the field with its automatic default value.
8510 */
8511 if (!field->has_explicit_value())
8512 {
8513 if (field->default_value &&
8514 (field->default_value->flags || field->flags & BLOB_FLAG))
8515 res|= (field->default_value->expr->save_in_field(field, 0) < 0);
8516 if (!ignore_errors && res)
8517 {
8518 my_error(ER_CALCULATING_DEFAULT_VALUE, MYF(0), field->field_name.str);
8519 break;
8520 }
8521 res= 0;
8522 }
8523 }
8524 in_use->restore_active_arena(expr_arena, &backup_arena);
8525 DBUG_RETURN(res);
8526 }
8527
update_generated_fields()8528 int TABLE::update_generated_fields()
8529 {
8530 int res= 0;
8531 if (found_next_number_field)
8532 {
8533 next_number_field= found_next_number_field;
8534 res= found_next_number_field->set_default();
8535 if (likely(!res))
8536 res= file->update_auto_increment();
8537 }
8538
8539 if (likely(!res) && vfield)
8540 res= update_virtual_fields(file, VCOL_UPDATE_FOR_WRITE);
8541 if (likely(!res) && versioned())
8542 vers_update_fields();
8543 if (likely(!res))
8544 res= verify_constraints(false) == VIEW_CHECK_ERROR;
8545 return res;
8546 }
8547
period_make_insert(Item * src,Field * dst)8548 int TABLE::period_make_insert(Item *src, Field *dst)
8549 {
8550 THD *thd= in_use;
8551
8552 ulonglong prev_insert_id= file->next_insert_id;
8553 store_record(this, record[1]);
8554 int res= src->save_in_field(dst, true);
8555
8556 if (likely(!res))
8557 res= update_generated_fields();
8558
8559 if (likely(!res) && triggers)
8560 res= triggers->process_triggers(thd, TRG_EVENT_INSERT,
8561 TRG_ACTION_BEFORE, true);
8562
8563 if (likely(!res))
8564 res = file->ha_write_row(record[0]);
8565
8566 if (likely(!res) && triggers)
8567 res= triggers->process_triggers(thd, TRG_EVENT_INSERT,
8568 TRG_ACTION_AFTER, true);
8569
8570 restore_record(this, record[1]);
8571 if (res)
8572 file->restore_auto_increment(prev_insert_id);
8573 return res;
8574 }
8575
insert_portion_of_time(THD * thd,const vers_select_conds_t & period_conds,ha_rows * rows_inserted)8576 int TABLE::insert_portion_of_time(THD *thd,
8577 const vers_select_conds_t &period_conds,
8578 ha_rows *rows_inserted)
8579 {
8580 bool lcond= period_conds.field_start->val_datetime_packed(thd)
8581 < period_conds.start.item->val_datetime_packed(thd);
8582 bool rcond= period_conds.field_end->val_datetime_packed(thd)
8583 > period_conds.end.item->val_datetime_packed(thd);
8584
8585 int res= 0;
8586 if (lcond)
8587 {
8588 res= period_make_insert(period_conds.start.item,
8589 field[s->period.end_fieldno]);
8590 if (likely(!res))
8591 ++*rows_inserted;
8592 }
8593 if (likely(!res) && rcond)
8594 {
8595 res= period_make_insert(period_conds.end.item,
8596 field[s->period.start_fieldno]);
8597 if (likely(!res))
8598 ++*rows_inserted;
8599 }
8600
8601 return res;
8602 }
8603
evaluate_update_default_function()8604 void TABLE::evaluate_update_default_function()
8605 {
8606 DBUG_ENTER("TABLE::evaluate_update_default_function");
8607
8608 if (s->has_update_default_function)
8609 for (Field **field_ptr= default_field; *field_ptr ; field_ptr++)
8610 {
8611 Field *field= (*field_ptr);
8612 if (!field->has_explicit_value() && field->has_update_default_function())
8613 field->set_time();
8614 }
8615 DBUG_VOID_RETURN;
8616 }
8617
8618
vers_update_fields()8619 void TABLE::vers_update_fields()
8620 {
8621 bitmap_set_bit(write_set, vers_start_field()->field_index);
8622 bitmap_set_bit(write_set, vers_end_field()->field_index);
8623
8624 if (!vers_write)
8625 {
8626 file->column_bitmaps_signal();
8627 return;
8628 }
8629
8630 if (versioned(VERS_TIMESTAMP))
8631 {
8632 if (vers_start_field()->store_timestamp(in_use->query_start(),
8633 in_use->query_start_sec_part()))
8634 {
8635 DBUG_ASSERT(0);
8636 }
8637 vers_start_field()->set_has_explicit_value();
8638 }
8639
8640 vers_end_field()->set_max();
8641 vers_end_field()->set_has_explicit_value();
8642 bitmap_set_bit(read_set, vers_end_field()->field_index);
8643 file->column_bitmaps_signal();
8644 if (vfield)
8645 update_virtual_fields(file, VCOL_UPDATE_FOR_READ);
8646 }
8647
8648
vers_update_end()8649 void TABLE::vers_update_end()
8650 {
8651 if (vers_end_field()->store_timestamp(in_use->query_start(),
8652 in_use->query_start_sec_part()))
8653 DBUG_ASSERT(0);
8654 vers_end_field()->set_has_explicit_value();
8655 }
8656
8657 /**
8658 Reset markers that fields are being updated
8659 */
8660
reset_default_fields()8661 void TABLE::reset_default_fields()
8662 {
8663 DBUG_ENTER("reset_default_fields");
8664 bitmap_clear_all(&has_value_set);
8665 DBUG_VOID_RETURN;
8666 }
8667
8668 /*
8669 Prepare triggers for INSERT-like statement.
8670
8671 SYNOPSIS
8672 prepare_triggers_for_insert_stmt_or_event()
8673
8674 NOTE
8675 Prepare triggers for INSERT-like statement by marking fields
8676 used by triggers and inform handlers that batching of UPDATE/DELETE
8677 cannot be done if there are BEFORE UPDATE/DELETE triggers.
8678 */
8679
prepare_triggers_for_insert_stmt_or_event()8680 void TABLE::prepare_triggers_for_insert_stmt_or_event()
8681 {
8682 if (triggers)
8683 {
8684 if (triggers->has_triggers(TRG_EVENT_DELETE,
8685 TRG_ACTION_AFTER))
8686 {
8687 /*
8688 The table has AFTER DELETE triggers that might access to
8689 subject table and therefore might need delete to be done
8690 immediately. So we turn-off the batching.
8691 */
8692 (void) file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
8693 }
8694 if (triggers->has_triggers(TRG_EVENT_UPDATE,
8695 TRG_ACTION_AFTER))
8696 {
8697 /*
8698 The table has AFTER UPDATE triggers that might access to subject
8699 table and therefore might need update to be done immediately.
8700 So we turn-off the batching.
8701 */
8702 (void) file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH);
8703 }
8704 }
8705 }
8706
8707
prepare_triggers_for_delete_stmt_or_event()8708 bool TABLE::prepare_triggers_for_delete_stmt_or_event()
8709 {
8710 if (triggers &&
8711 triggers->has_triggers(TRG_EVENT_DELETE,
8712 TRG_ACTION_AFTER))
8713 {
8714 /*
8715 The table has AFTER DELETE triggers that might access to subject table
8716 and therefore might need delete to be done immediately. So we turn-off
8717 the batching.
8718 */
8719 (void) file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
8720 return TRUE;
8721 }
8722 return FALSE;
8723 }
8724
8725
prepare_triggers_for_update_stmt_or_event()8726 bool TABLE::prepare_triggers_for_update_stmt_or_event()
8727 {
8728 if (triggers &&
8729 triggers->has_triggers(TRG_EVENT_UPDATE,
8730 TRG_ACTION_AFTER))
8731 {
8732 /*
8733 The table has AFTER UPDATE triggers that might access to subject
8734 table and therefore might need update to be done immediately.
8735 So we turn-off the batching.
8736 */
8737 (void) file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH);
8738 return TRUE;
8739 }
8740 return FALSE;
8741 }
8742
8743
8744 /**
8745 Validates default value of fields which are not specified in
8746 the column list of INSERT/LOAD statement.
8747
8748 @Note s->default_values should be properly populated
8749 before calling this function.
8750
8751 @param thd thread context
8752 @param record the record to check values in
8753
8754 @return
8755 @retval false Success.
8756 @retval true Failure.
8757 */
8758
validate_default_values_of_unset_fields(THD * thd) const8759 bool TABLE::validate_default_values_of_unset_fields(THD *thd) const
8760 {
8761 DBUG_ENTER("TABLE::validate_default_values_of_unset_fields");
8762 for (Field **fld= field; *fld; fld++)
8763 {
8764 if (!bitmap_is_set(write_set, (*fld)->field_index) &&
8765 !((*fld)->flags & (NO_DEFAULT_VALUE_FLAG | VERS_SYSTEM_FIELD)))
8766 {
8767 if (!(*fld)->is_null_in_record(s->default_values) &&
8768 (*fld)->validate_value_in_record_with_warn(thd, s->default_values) &&
8769 thd->is_error())
8770 {
8771 /*
8772 We're here if:
8773 - validate_value_in_record_with_warn() failed and
8774 strict mo validate_default_values_of_unset_fieldsde converted WARN to ERROR
8775 - or the connection was killed, or closed unexpectedly
8776 */
8777 DBUG_RETURN(true);
8778 }
8779 }
8780 }
8781 DBUG_RETURN(false);
8782 }
8783
8784
insert_all_rows_into_tmp_table(THD * thd,TABLE * tmp_table,TMP_TABLE_PARAM * tmp_table_param,bool with_cleanup)8785 bool TABLE::insert_all_rows_into_tmp_table(THD *thd,
8786 TABLE *tmp_table,
8787 TMP_TABLE_PARAM *tmp_table_param,
8788 bool with_cleanup)
8789 {
8790 int write_err= 0;
8791
8792 DBUG_ENTER("TABLE::insert_all_rows_into_tmp_table");
8793
8794 if (with_cleanup)
8795 {
8796 if ((write_err= tmp_table->file->ha_delete_all_rows()))
8797 goto err;
8798 }
8799
8800 if (file->indexes_are_disabled())
8801 tmp_table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
8802 file->ha_index_or_rnd_end();
8803
8804 if (unlikely(file->ha_rnd_init_with_error(1)))
8805 DBUG_RETURN(1);
8806
8807 if (tmp_table->no_rows)
8808 tmp_table->file->extra(HA_EXTRA_NO_ROWS);
8809 else
8810 {
8811 /* update table->file->stats.records */
8812 file->info(HA_STATUS_VARIABLE);
8813 tmp_table->file->ha_start_bulk_insert(file->stats.records);
8814 }
8815
8816 while (likely(!file->ha_rnd_next(tmp_table->record[0])))
8817 {
8818 write_err= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]);
8819 if (unlikely(write_err))
8820 {
8821 bool is_duplicate;
8822 if (tmp_table->file->is_fatal_error(write_err, HA_CHECK_DUP) &&
8823 create_internal_tmp_table_from_heap(thd, tmp_table,
8824 tmp_table_param->start_recinfo,
8825 &tmp_table_param->recinfo,
8826 write_err, 1, &is_duplicate))
8827 DBUG_RETURN(1);
8828
8829 }
8830 if (unlikely(thd->check_killed()))
8831 goto err_killed;
8832 }
8833 if (!tmp_table->no_rows && tmp_table->file->ha_end_bulk_insert())
8834 goto err;
8835 DBUG_RETURN(0);
8836
8837 err:
8838 DBUG_PRINT("error",("Got error: %d",write_err));
8839 file->print_error(write_err, MYF(0));
8840 err_killed:
8841 (void) file->ha_rnd_end();
8842 DBUG_RETURN(1);
8843 }
8844
8845
8846
8847 /*
8848 @brief Reset const_table flag
8849
8850 @detail
8851 Reset const_table flag for this table. If this table is a merged derived
8852 table/view the flag is recursively reseted for all tables of the underlying
8853 select.
8854 */
8855
reset_const_table()8856 void TABLE_LIST::reset_const_table()
8857 {
8858 table->const_table= 0;
8859 if (is_merged_derived())
8860 {
8861 SELECT_LEX *select_lex= get_unit()->first_select();
8862 TABLE_LIST *tl;
8863 List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
8864 while ((tl= ti++))
8865 tl->reset_const_table();
8866 }
8867 }
8868
8869
8870 /*
8871 @brief Run derived tables/view handling phases on underlying select_lex.
8872
8873 @param lex LEX for this thread
8874 @param phases derived tables/views handling phases to run
8875 (set of DT_XXX constants)
8876 @details
8877 This function runs this derived table through specified 'phases'.
8878 Underlying tables of this select are handled prior to this derived.
8879 'lex' is passed as an argument to called functions.
8880
8881 @return TRUE on error
8882 @return FALSE ok
8883 */
8884
handle_derived(LEX * lex,uint phases)8885 bool TABLE_LIST::handle_derived(LEX *lex, uint phases)
8886 {
8887 SELECT_LEX_UNIT *unit= get_unit();
8888 DBUG_ENTER("handle_derived");
8889 DBUG_PRINT("enter", ("phases: 0x%x", phases));
8890
8891 if (unit)
8892 {
8893 if (!is_with_table_recursive_reference())
8894 {
8895 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
8896 if (sl->handle_derived(lex, phases))
8897 DBUG_RETURN(TRUE);
8898 }
8899 if (mysql_handle_single_derived(lex, this, phases))
8900 DBUG_RETURN(TRUE);
8901 }
8902 DBUG_RETURN(FALSE);
8903 }
8904
8905 /**
8906 @brief
8907 Return unit of this derived table/view
8908
8909 @return reference to a unit if it's a derived table/view.
8910 @return 0 when it's not a derived table/view.
8911 */
8912
get_unit()8913 st_select_lex_unit *TABLE_LIST::get_unit()
8914 {
8915 return (view ? &view->unit : derived);
8916 }
8917
8918
8919 /**
8920 @brief
8921 Return select_lex of this derived table/view
8922
8923 @return select_lex of this derived table/view.
8924 @return 0 when it's not a derived table.
8925 */
8926
get_single_select()8927 st_select_lex *TABLE_LIST::get_single_select()
8928 {
8929 SELECT_LEX_UNIT *unit= get_unit();
8930 return (unit ? unit->first_select() : 0);
8931 }
8932
8933
8934 /**
8935 @brief
8936 Attach a join table list as a nested join to this TABLE_LIST.
8937
8938 @param join_list join table list to attach
8939
8940 @details
8941 This function wraps 'join_list' into a nested_join of this table, thus
8942 turning it to a nested join leaf.
8943 */
8944
wrap_into_nested_join(List<TABLE_LIST> & join_list)8945 void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
8946 {
8947 TABLE_LIST *tl;
8948 /*
8949 Walk through derived table top list and set 'embedding' to point to
8950 the nesting table.
8951 */
8952 nested_join->join_list.empty();
8953 List_iterator_fast<TABLE_LIST> li(join_list);
8954 nested_join->join_list= join_list;
8955 while ((tl= li++))
8956 {
8957 tl->embedding= this;
8958 tl->join_list= &nested_join->join_list;
8959 }
8960 }
8961
8962
8963 /**
8964 Check whether optimization has been performed and a derived table either
8965 been merged to upper select level or materialized.
8966
8967 @param table a TABLE_LIST object containing a derived table
8968
8969 @return true in case the derived table has been merged to surrounding select,
8970 false otherwise
8971 */
8972
derived_table_optimization_done(TABLE_LIST * table)8973 static inline bool derived_table_optimization_done(TABLE_LIST *table)
8974 {
8975 return table->derived &&
8976 (table->derived->is_excluded() ||
8977 table->is_materialized_derived());
8978 }
8979
8980
8981 /**
8982 @brief
8983 Initialize this derived table/view
8984
8985 @param thd Thread handle
8986
8987 @details
8988 This function makes initial preparations of this derived table/view for
8989 further processing:
8990 if it's a derived table this function marks it either as mergeable or
8991 materializable
8992 creates temporary table for name resolution purposes
8993 creates field translation for mergeable derived table/view
8994
8995 @return TRUE an error occur
8996 @return FALSE ok
8997 */
8998
init_derived(THD * thd,bool init_view)8999 bool TABLE_LIST::init_derived(THD *thd, bool init_view)
9000 {
9001 SELECT_LEX *first_select= get_single_select();
9002 SELECT_LEX_UNIT *unit= get_unit();
9003
9004 if (!unit)
9005 return FALSE;
9006 /*
9007 Check whether we can merge this derived table into main select.
9008 Depending on the result field translation will or will not
9009 be created.
9010 */
9011 TABLE_LIST *first_table= (TABLE_LIST *) first_select->table_list.first;
9012 if (first_select->table_list.elements > 1 ||
9013 (first_table && first_table->is_multitable()))
9014 set_multitable();
9015
9016 if (!unit->derived)
9017 unit->derived= this;
9018 else if (!is_with_table_recursive_reference() && unit->derived != this)
9019 {
9020 if (unit->derived->is_with_table_recursive_reference())
9021 unit->derived= this;
9022 else if (vers_conditions.eq(unit->derived->vers_conditions))
9023 vers_conditions.empty();
9024 else
9025 {
9026 my_error(ER_CONFLICTING_FOR_SYSTEM_TIME, MYF(0));
9027 return TRUE;
9028 }
9029 }
9030
9031 if (init_view && !view &&
9032 !derived_table_optimization_done(this))
9033 {
9034 /* This is all what we can do for a derived table for now. */
9035 set_derived();
9036 }
9037
9038 if (!is_view() &&
9039 !derived_table_optimization_done(this))
9040 {
9041 /* A subquery might be forced to be materialized due to a side-effect. */
9042 if (!is_materialized_derived() && first_select->is_mergeable() &&
9043 optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE) &&
9044 !thd->lex->can_not_use_merged() &&
9045 !(thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
9046 thd->lex->sql_command == SQLCOM_DELETE_MULTI) &&
9047 !is_recursive_with_table())
9048 set_merged_derived();
9049 else
9050 set_materialized_derived();
9051 }
9052 /*
9053 Derived tables/view are materialized prior to UPDATE, thus we can skip
9054 them from table uniqueness check
9055 */
9056 if (is_materialized_derived())
9057 {
9058 set_check_materialized();
9059 }
9060
9061 /*
9062 Create field translation for mergeable derived tables/views.
9063 For derived tables field translation can be created only after
9064 unit is prepared so all '*' are get unrolled.
9065 */
9066 if (is_merged_derived())
9067 {
9068 if (is_view() ||
9069 (unit->prepared &&
9070 !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
9071 create_field_translation(thd);
9072 }
9073
9074 return FALSE;
9075 }
9076
9077
9078 /**
9079 @brief
9080 Retrieve number of rows in the table
9081
9082 @details
9083 Retrieve number of rows in the table referred by this TABLE_LIST and
9084 store it in the table's stats.records variable. If this TABLE_LIST refers
9085 to a materialized derived table/view then the estimated number of rows of
9086 the derived table/view is used instead.
9087
9088 @return 0 ok
9089 @return non zero error
9090 */
9091
fetch_number_of_rows()9092 int TABLE_LIST::fetch_number_of_rows()
9093 {
9094 int error= 0;
9095 if (jtbm_subselect)
9096 {
9097 if (jtbm_subselect->is_jtbm_merged)
9098 {
9099 table->file->stats.records= (ha_rows)jtbm_subselect->jtbm_record_count;
9100 set_if_bigger(table->file->stats.records, 2);
9101 table->used_stat_records= table->file->stats.records;
9102 }
9103 return 0;
9104 }
9105 if (is_materialized_derived() && !fill_me)
9106 {
9107 table->file->stats.records= get_unit()->result->est_records;
9108 set_if_bigger(table->file->stats.records, 2);
9109 table->used_stat_records= table->file->stats.records;
9110 }
9111 else
9112 error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
9113 return error;
9114 }
9115
9116 /*
9117 Procedure of keys generation for result tables of materialized derived
9118 tables/views.
9119
9120 A key is generated for each equi-join pair derived table-another table.
9121 Each generated key consists of fields of derived table used in equi-join.
9122 Example:
9123
9124 SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
9125 t1 ON tt.f1=t1.f3 and tt.f2.=t1.f4;
9126 In this case for the derived table tt one key will be generated. It will
9127 consist of two parts f1 and f2.
9128 Example:
9129
9130 SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
9131 t1 ON tt.f1=t1.f3 JOIN
9132 t2 ON tt.f2=t2.f4;
9133 In this case for the derived table tt two keys will be generated.
9134 One key over f1 field, and another key over f2 field.
9135 Currently optimizer may choose to use only one such key, thus the second
9136 one will be dropped after range optimizer is finished.
9137 See also JOIN::drop_unused_derived_keys function.
9138 Example:
9139
9140 SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
9141 t1 ON tt.f1=a_function(t1.f3);
9142 In this case for the derived table tt one key will be generated. It will
9143 consist of one field - f1.
9144 */
9145
9146
9147
9148 /*
9149 @brief
9150 Change references to underlying items of a merged derived table/view
9151 for fields in derived table's result table.
9152
9153 @return FALSE ok
9154 @return TRUE Out of memory
9155 */
change_refs_to_fields()9156 bool TABLE_LIST::change_refs_to_fields()
9157 {
9158 List_iterator<Item> li(used_items);
9159 Item_direct_ref *ref;
9160 Field_iterator_view field_it;
9161 THD *thd= table->in_use;
9162 DBUG_ASSERT(is_merged_derived());
9163
9164 if (!used_items.elements)
9165 return FALSE;
9166
9167 Item **materialized_items=
9168 (Item **)thd->calloc(sizeof(void *) * table->s->fields);
9169 if (!materialized_items)
9170 return TRUE;
9171
9172 while ((ref= (Item_direct_ref*)li++))
9173 {
9174 uint idx;
9175 Item *orig_item= *ref->ref;
9176 field_it.set(this);
9177 for (idx= 0; !field_it.end_of_fields(); field_it.next(), idx++)
9178 {
9179 if (field_it.item() == orig_item)
9180 break;
9181 }
9182 DBUG_ASSERT(!field_it.end_of_fields());
9183 if (!materialized_items[idx])
9184 {
9185 materialized_items[idx]= new (thd->mem_root) Item_field(thd, table->field[idx]);
9186 if (!materialized_items[idx])
9187 return TRUE;
9188 }
9189 /*
9190 We need to restore the pointers after the execution of the
9191 prepared statement.
9192 */
9193 thd->change_item_tree((Item **)&ref->ref,
9194 (Item*)(materialized_items + idx));
9195 }
9196
9197 return FALSE;
9198 }
9199
9200
set_lock_type(THD * thd,enum thr_lock_type lock)9201 void TABLE_LIST::set_lock_type(THD *thd, enum thr_lock_type lock)
9202 {
9203 if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar *)&lock))
9204 return;
9205 /* we call it only when table is opened and it is "leaf" table*/
9206 DBUG_ASSERT(table);
9207 lock_type= lock;
9208 /* table->file->get_table() can be 0 for derived tables */
9209 if (table->file && table->file->get_table())
9210 table->file->set_lock_type(lock);
9211 if (is_merged_derived())
9212 {
9213 for (TABLE_LIST *table= get_single_select()->get_table_list();
9214 table;
9215 table= table->next_local)
9216 {
9217 table->set_lock_type(thd, lock);
9218 }
9219 }
9220 }
9221
is_with_table()9222 bool TABLE_LIST::is_with_table()
9223 {
9224 return derived && derived->with_element;
9225 }
9226
actual_n_key_parts(THD * thd)9227 uint TABLE_SHARE::actual_n_key_parts(THD *thd)
9228 {
9229 return use_ext_keys &&
9230 optimizer_flag(thd, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
9231 ext_key_parts : key_parts;
9232 }
9233
9234
actual_rec_per_key(uint i)9235 double KEY::actual_rec_per_key(uint i)
9236 {
9237 if (rec_per_key == 0)
9238 return 0;
9239 return (is_statistics_from_stat_tables ?
9240 read_stats->get_avg_frequency(i) : (double) rec_per_key[i]);
9241 }
9242
9243 /*
9244 find total number of field in hash expr
9245 */
fields_in_hash_keyinfo(KEY * keyinfo)9246 int fields_in_hash_keyinfo(KEY *keyinfo)
9247 {
9248 Item_func_hash * temp= (Item_func_hash *)
9249 keyinfo->key_part->field->vcol_info->expr;
9250 return temp->argument_count();
9251 }
9252 /*
9253 setup_keyinfo_hash changes the key_info->key_part
9254 to be same as defined by user
9255 */
setup_keyinfo_hash(KEY * key_info)9256 void setup_keyinfo_hash(KEY *key_info)
9257 {
9258 DBUG_ASSERT(key_info->algorithm == HA_KEY_ALG_LONG_HASH);
9259 DBUG_ASSERT(key_info->key_part->field->flags & LONG_UNIQUE_HASH_FIELD);
9260 uint no_of_keyparts= fields_in_hash_keyinfo(key_info);
9261 key_info->key_part-= no_of_keyparts;
9262 key_info->user_defined_key_parts= key_info->usable_key_parts=
9263 key_info->ext_key_parts= no_of_keyparts;
9264 key_info->flags|= HA_NOSAME;
9265 }
9266 /*
9267 re_setup_keyinfo_hash reverts th setup_keyinfo_hash and this type of
9268 arrangement is expected by storage engine
9269 */
9270
re_setup_keyinfo_hash(KEY * key_info)9271 void re_setup_keyinfo_hash(KEY *key_info)
9272 {
9273 DBUG_ASSERT(key_info->algorithm == HA_KEY_ALG_LONG_HASH);
9274 DBUG_ASSERT(!(key_info->key_part->field->flags & LONG_UNIQUE_HASH_FIELD));
9275 while(!(key_info->key_part->field->flags & LONG_UNIQUE_HASH_FIELD))
9276 key_info->key_part++;
9277 key_info->user_defined_key_parts= key_info->usable_key_parts=
9278 key_info->ext_key_parts= 1;
9279 key_info->flags&= ~HA_NOSAME;
9280 }
9281 /**
9282 @brief clone of current handler.
9283 Creates a clone of handler used in update for
9284 unique hash key.
9285 */
clone_handler_for_update()9286 void TABLE::clone_handler_for_update()
9287 {
9288 if (this->update_handler)
9289 return;
9290 handler *update_handler= NULL;
9291 if (!s->long_unique_table)
9292 return;
9293 update_handler= file->clone(s->normalized_path.str,
9294 in_use->mem_root);
9295 update_handler->ha_external_lock(in_use, F_RDLCK);
9296 this->update_handler= update_handler;
9297 return;
9298 }
9299
9300 /**
9301 @brief Deletes update handler object
9302 */
delete_update_handler()9303 void TABLE::delete_update_handler()
9304 {
9305 update_handler->ha_external_lock(in_use, F_UNLCK);
9306 update_handler->ha_close();
9307 delete update_handler;
9308 this->update_handler= NULL;
9309 }
9310
fk_option_name(enum_fk_option opt)9311 LEX_CSTRING *fk_option_name(enum_fk_option opt)
9312 {
9313 static LEX_CSTRING names[]=
9314 {
9315 { STRING_WITH_LEN("???") },
9316 { STRING_WITH_LEN("RESTRICT") },
9317 { STRING_WITH_LEN("CASCADE") },
9318 { STRING_WITH_LEN("SET NULL") },
9319 { STRING_WITH_LEN("NO ACTION") },
9320 { STRING_WITH_LEN("SET DEFAULT") }
9321 };
9322 return names + opt;
9323 }
9324
fk_modifies_child(enum_fk_option opt)9325 bool fk_modifies_child(enum_fk_option opt)
9326 {
9327 static bool can_write[]= { false, false, true, true, false, true };
9328 return can_write[opt];
9329 }
9330
9331 enum TR_table::enabled TR_table::use_transaction_registry= TR_table::MAYBE;
9332
TR_table(THD * _thd,bool rw)9333 TR_table::TR_table(THD* _thd, bool rw) :
9334 thd(_thd), open_tables_backup(NULL)
9335 {
9336 init_one_table(&MYSQL_SCHEMA_NAME, &TRANSACTION_REG_NAME,
9337 NULL, rw ? TL_WRITE : TL_READ);
9338 }
9339
open()9340 bool TR_table::open()
9341 {
9342 DBUG_ASSERT(!table);
9343 open_tables_backup= new Open_tables_backup;
9344 if (!open_tables_backup)
9345 {
9346 my_error(ER_OUT_OF_RESOURCES, MYF(0));
9347 return true;
9348 }
9349
9350 All_tmp_tables_list *temporary_tables= thd->temporary_tables;
9351 bool error= !open_log_table(thd, this, open_tables_backup);
9352 thd->temporary_tables= temporary_tables;
9353
9354 if (use_transaction_registry == MAYBE)
9355 error= check(error);
9356
9357 use_transaction_registry= error ? NO : YES;
9358
9359 return error;
9360 }
9361
~TR_table()9362 TR_table::~TR_table()
9363 {
9364 if (table)
9365 {
9366 thd->temporary_tables= NULL;
9367 close_log_table(thd, open_tables_backup);
9368 }
9369 delete open_tables_backup;
9370 }
9371
store(uint field_id,ulonglong val)9372 void TR_table::store(uint field_id, ulonglong val)
9373 {
9374 table->field[field_id]->store(val, true);
9375 table->field[field_id]->set_notnull();
9376 }
9377
store(uint field_id,timeval ts)9378 void TR_table::store(uint field_id, timeval ts)
9379 {
9380 table->field[field_id]->store_timestamp(ts.tv_sec, ts.tv_usec);
9381 table->field[field_id]->set_notnull();
9382 }
9383
iso_level() const9384 enum_tx_isolation TR_table::iso_level() const
9385 {
9386 enum_tx_isolation res= (enum_tx_isolation) ((*this)[FLD_ISO_LEVEL]->val_int() - 1);
9387 DBUG_ASSERT(res <= ISO_SERIALIZABLE);
9388 return res;
9389 }
9390
update(ulonglong start_id,ulonglong end_id)9391 bool TR_table::update(ulonglong start_id, ulonglong end_id)
9392 {
9393 if (!table && open())
9394 return true;
9395
9396 store(FLD_BEGIN_TS, thd->transaction_time());
9397 thd->set_time();
9398 timeval end_time= {thd->query_start(), int(thd->query_start_sec_part())};
9399 store(FLD_TRX_ID, start_id);
9400 store(FLD_COMMIT_ID, end_id);
9401 store(FLD_COMMIT_TS, end_time);
9402 store_iso_level(thd->tx_isolation);
9403
9404 int error= table->file->ha_write_row(table->record[0]);
9405 if (unlikely(error))
9406 table->file->print_error(error, MYF(0));
9407 return error;
9408 }
9409
9410 #define newx new (thd->mem_root)
query(ulonglong trx_id)9411 bool TR_table::query(ulonglong trx_id)
9412 {
9413 if (!table && open())
9414 return false;
9415 SQL_SELECT_auto select;
9416 READ_RECORD info;
9417 int error;
9418 List<TABLE_LIST> dummy;
9419 SELECT_LEX &slex= *(thd->lex->first_select_lex());
9420 Name_resolution_context_backup backup(slex.context, *this);
9421 Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_TRX_ID]);
9422 Item *value= newx Item_int(thd, trx_id);
9423 COND *conds= newx Item_func_eq(thd, field, value);
9424 if (unlikely((error= setup_conds(thd, this, dummy, &conds))))
9425 return false;
9426 select= make_select(table, 0, 0, conds, NULL, 0, &error);
9427 if (unlikely(error || !select))
9428 {
9429 my_error(ER_OUT_OF_RESOURCES, MYF(0));
9430 return false;
9431 }
9432 // FIXME: (performance) force index 'transaction_id'
9433 error= init_read_record(&info, thd, table, select, NULL,
9434 1 /* use_record_cache */, true /* print_error */,
9435 false /* disable_rr_cache */);
9436 while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
9437 {
9438 if (select->skip_record(thd) > 0)
9439 return true;
9440 }
9441 my_error(ER_VERS_NO_TRX_ID, MYF(0), (longlong) trx_id);
9442 return false;
9443 }
9444
query(MYSQL_TIME & commit_time,bool backwards)9445 bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
9446 {
9447 if (!table && open())
9448 return false;
9449 SQL_SELECT_auto select;
9450 READ_RECORD info;
9451 int error;
9452 List<TABLE_LIST> dummy;
9453 SELECT_LEX &slex= *(thd->lex->first_select_lex());
9454 Name_resolution_context_backup backup(slex.context, *this);
9455 Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_COMMIT_TS]);
9456 Datetime dt(&commit_time);
9457 Item *value= newx Item_datetime_literal(thd, &dt, 6);
9458 COND *conds;
9459 if (backwards)
9460 conds= newx Item_func_ge(thd, field, value);
9461 else
9462 conds= newx Item_func_le(thd, field, value);
9463 if (unlikely((error= setup_conds(thd, this, dummy, &conds))))
9464 return false;
9465 // FIXME: (performance) force index 'commit_timestamp'
9466 select= make_select(table, 0, 0, conds, NULL, 0, &error);
9467 if (unlikely(error || !select))
9468 return false;
9469 error= init_read_record(&info, thd, table, select, NULL,
9470 1 /* use_record_cache */, true /* print_error */,
9471 false /* disable_rr_cache */);
9472
9473 // With PK by transaction_id the records are ordered by PK, so we have to
9474 // scan TRT fully and collect min (backwards == true)
9475 // or max (backwards == false) stats.
9476 bool found= false;
9477 MYSQL_TIME found_ts;
9478 while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
9479 {
9480 int res= select->skip_record(thd);
9481 if (res > 0)
9482 {
9483 MYSQL_TIME commit_ts;
9484 if ((*this)[FLD_COMMIT_TS]->get_date(&commit_ts, date_mode_t(0)))
9485 {
9486 found= false;
9487 break;
9488 }
9489 int c;
9490 if (!found || ((c= my_time_compare(&commit_ts, &found_ts)) &&
9491 (backwards ? c < 0 : c > 0)))
9492 {
9493 found_ts= commit_ts;
9494 found= true;
9495 // TODO: (performance) make ORDER DESC and break after first found.
9496 // Otherwise it is O(n) scan (+copy)!
9497 store_record(table, record[1]);
9498 }
9499 }
9500 else if (res < 0)
9501 {
9502 found= false;
9503 break;
9504 }
9505 }
9506 if (found)
9507 restore_record(table, record[1]);
9508 return found;
9509 }
9510 #undef newx
9511
query_sees(bool & result,ulonglong trx_id1,ulonglong trx_id0,ulonglong commit_id1,enum_tx_isolation iso_level1,ulonglong commit_id0)9512 bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
9513 ulonglong commit_id1, enum_tx_isolation iso_level1,
9514 ulonglong commit_id0)
9515 {
9516 if (trx_id1 == trx_id0)
9517 {
9518 return false;
9519 }
9520
9521 if (trx_id1 == ULONGLONG_MAX || trx_id0 == 0)
9522 {
9523 result= true;
9524 return false;
9525 }
9526
9527 if (trx_id0 == ULONGLONG_MAX || trx_id1 == 0)
9528 {
9529 result= false;
9530 return false;
9531 }
9532
9533 if (!commit_id1)
9534 {
9535 if (!query(trx_id1))
9536 return true;
9537
9538 commit_id1= (*this)[FLD_COMMIT_ID]->val_int();
9539 iso_level1= iso_level();
9540 }
9541
9542 if (!commit_id0)
9543 {
9544 if (!query(trx_id0))
9545 return true;
9546
9547 commit_id0= (*this)[FLD_COMMIT_ID]->val_int();
9548 }
9549
9550 // Trivial case: TX1 started after TX0 committed
9551 if (trx_id1 > commit_id0
9552 // Concurrent transactions: TX1 committed after TX0 and TX1 is read (un)committed
9553 || (commit_id1 > commit_id0 && iso_level1 < ISO_REPEATABLE_READ))
9554 {
9555 result= true;
9556 }
9557 else // All other cases: TX1 does not see TX0
9558 {
9559 result= false;
9560 }
9561
9562 return false;
9563 }
9564
warn_schema_incorrect(const char * reason)9565 void TR_table::warn_schema_incorrect(const char *reason)
9566 {
9567 if (MYSQL_VERSION_ID == table->s->mysql_version)
9568 {
9569 sql_print_error("%`s.%`s schema is incorrect: %s.",
9570 db.str, table_name.str, reason);
9571 }
9572 else
9573 {
9574 sql_print_error("%`s.%`s schema is incorrect: %s. Created with MariaDB %d, "
9575 "now running %d.",
9576 db.str, table_name.str, reason, MYSQL_VERSION_ID,
9577 static_cast<int>(table->s->mysql_version));
9578 }
9579 }
9580
check(bool error)9581 bool TR_table::check(bool error)
9582 {
9583 if (error)
9584 {
9585 sql_print_warning("%`s.%`s does not exist (open failed).", db.str,
9586 table_name.str);
9587 return true;
9588 }
9589
9590 if (table->file->ht->db_type != DB_TYPE_INNODB)
9591 {
9592 warn_schema_incorrect("Wrong table engine (expected InnoDB)");
9593 return true;
9594 }
9595
9596 #define WARN_SCHEMA(...) \
9597 char reason[128]; \
9598 snprintf(reason, 128, __VA_ARGS__); \
9599 warn_schema_incorrect(reason);
9600
9601 if (table->s->fields != FIELD_COUNT)
9602 {
9603 WARN_SCHEMA("Wrong field count (expected %d)", FIELD_COUNT);
9604 return true;
9605 }
9606
9607 if (table->field[FLD_TRX_ID]->type() != MYSQL_TYPE_LONGLONG)
9608 {
9609 WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_TRX_ID);
9610 return true;
9611 }
9612
9613 if (table->field[FLD_COMMIT_ID]->type() != MYSQL_TYPE_LONGLONG)
9614 {
9615 WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_COMMIT_ID);
9616 return true;
9617 }
9618
9619 if (table->field[FLD_BEGIN_TS]->type() != MYSQL_TYPE_TIMESTAMP)
9620 {
9621 WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_BEGIN_TS);
9622 return true;
9623 }
9624
9625 if (table->field[FLD_COMMIT_TS]->type() != MYSQL_TYPE_TIMESTAMP)
9626 {
9627 WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_COMMIT_TS);
9628 return true;
9629 }
9630
9631 if (table->field[FLD_ISO_LEVEL]->type() != MYSQL_TYPE_STRING ||
9632 !(table->field[FLD_ISO_LEVEL]->flags & ENUM_FLAG))
9633 {
9634 wrong_enum:
9635 WARN_SCHEMA("Wrong field %d type (expected ENUM('READ-UNCOMMITTED', "
9636 "'READ-COMMITTED', 'REPEATABLE-READ', 'SERIALIZABLE'))",
9637 FLD_ISO_LEVEL);
9638 return true;
9639 }
9640
9641 Field_enum *iso_level= static_cast<Field_enum *>(table->field[FLD_ISO_LEVEL]);
9642 st_typelib *typelib= iso_level->typelib;
9643
9644 if (typelib->count != 4)
9645 goto wrong_enum;
9646
9647 if (strcmp(typelib->type_names[0], "READ-UNCOMMITTED") ||
9648 strcmp(typelib->type_names[1], "READ-COMMITTED") ||
9649 strcmp(typelib->type_names[2], "REPEATABLE-READ") ||
9650 strcmp(typelib->type_names[3], "SERIALIZABLE"))
9651 {
9652 goto wrong_enum;
9653 }
9654
9655 if (!table->key_info || !table->key_info->key_part)
9656 goto wrong_pk;
9657
9658 if (strcmp(table->key_info->key_part->field->field_name.str, "transaction_id"))
9659 {
9660 wrong_pk:
9661 WARN_SCHEMA("Wrong PRIMARY KEY (expected `transaction_id`)");
9662 return true;
9663 }
9664
9665 return false;
9666 }
9667
resolve_units(THD * thd)9668 bool vers_select_conds_t::resolve_units(THD *thd)
9669 {
9670 DBUG_ASSERT(type != SYSTEM_TIME_UNSPECIFIED);
9671 DBUG_ASSERT(start.item);
9672 return start.resolve_unit(thd) ||
9673 end.resolve_unit(thd);
9674 }
9675
eq(const vers_select_conds_t & conds) const9676 bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const
9677 {
9678 if (type != conds.type)
9679 return false;
9680 switch (type) {
9681 case SYSTEM_TIME_UNSPECIFIED:
9682 case SYSTEM_TIME_ALL:
9683 return true;
9684 case SYSTEM_TIME_BEFORE:
9685 break;
9686 case SYSTEM_TIME_HISTORY:
9687 break;
9688 case SYSTEM_TIME_AS_OF:
9689 return start.eq(conds.start);
9690 case SYSTEM_TIME_FROM_TO:
9691 case SYSTEM_TIME_BETWEEN:
9692 return start.eq(conds.start) && end.eq(conds.end);
9693 }
9694 DBUG_ASSERT(0);
9695 return false;
9696 }
9697
9698
resolve_unit(THD * thd)9699 bool Vers_history_point::resolve_unit(THD *thd)
9700 {
9701 if (!item)
9702 return false;
9703 if (item->fix_fields_if_needed(thd, &item))
9704 return true;
9705 return item->this_item()->real_type_handler()->
9706 type_handler_for_system_time()->
9707 Vers_history_point_resolve_unit(thd, this);
9708 }
9709
9710
bad_expression_data_type_error(const char * type) const9711 void Vers_history_point::bad_expression_data_type_error(const char *type) const
9712 {
9713 my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
9714 type, "FOR SYSTEM_TIME");
9715 }
9716
9717
fix_item()9718 void Vers_history_point::fix_item()
9719 {
9720 if (item && item->decimals == 0 && item->type() == Item::FUNC_ITEM &&
9721 ((Item_func*)item)->functype() == Item_func::NOW_FUNC)
9722 item->decimals= 6;
9723 }
9724
9725
eq(const vers_history_point_t & point) const9726 bool Vers_history_point::eq(const vers_history_point_t &point) const
9727 {
9728 return unit == point.unit && item->eq(point.item, false);
9729 }
9730
print(String * str,enum_query_type query_type,const char * prefix,size_t plen) const9731 void Vers_history_point::print(String *str, enum_query_type query_type,
9732 const char *prefix, size_t plen) const
9733 {
9734 const static LEX_CSTRING unit_type[]=
9735 {
9736 { STRING_WITH_LEN("") },
9737 { STRING_WITH_LEN("TIMESTAMP ") },
9738 { STRING_WITH_LEN("TRANSACTION ") }
9739 };
9740 str->append(prefix, plen);
9741 str->append(unit_type + unit);
9742 item->print(str, query_type);
9743 }
9744
find_field_by_name(LEX_CSTRING * str) const9745 Field *TABLE::find_field_by_name(LEX_CSTRING *str) const
9746 {
9747 Field **tmp;
9748 size_t length= str->length;
9749 if (s->name_hash.records)
9750 {
9751 tmp= (Field**) my_hash_search(&s->name_hash, (uchar*) str->str, length);
9752 return tmp ? field[tmp - s->field] : NULL;
9753 }
9754 else
9755 {
9756 for (tmp= field; *tmp; tmp++)
9757 {
9758 if ((*tmp)->field_name.length == length &&
9759 !lex_string_cmp(system_charset_info, &(*tmp)->field_name, str))
9760 return *tmp;
9761 }
9762 }
9763 return NULL;
9764 }
9765
9766
export_structure(THD * thd,Row_definition_list * defs)9767 bool TABLE::export_structure(THD *thd, Row_definition_list *defs)
9768 {
9769 for (Field **src= field; *src; src++)
9770 {
9771 uint offs;
9772 if (defs->find_row_field_by_name(&src[0]->field_name, &offs))
9773 {
9774 my_error(ER_DUP_FIELDNAME, MYF(0), src[0]->field_name.str);
9775 return true;
9776 }
9777 Spvar_definition *def= new (thd->mem_root) Spvar_definition(thd, *src);
9778 if (!def)
9779 return true;
9780 def->flags&= (uint) ~NOT_NULL_FLAG;
9781 if ((def->sp_prepare_create_field(thd, thd->mem_root)) ||
9782 (defs->push_back(def, thd->mem_root)))
9783 return true;
9784 }
9785 return false;
9786 }
9787
9788 /*
9789 @brief
9790 Initialize all the quick structures that are used to stored the
9791 estimates when the range optimizer is run.
9792 @details
9793 This is specifically needed when we read the TABLE structure from the
9794 table cache. There can be some garbage data from previous queries
9795 that need to be reset here.
9796 */
9797
initialize_quick_structures()9798 void TABLE::initialize_quick_structures()
9799 {
9800 TRASH_ALLOC(quick_rows, sizeof(quick_rows));
9801 TRASH_ALLOC(quick_key_parts, sizeof(quick_key_parts));
9802 TRASH_ALLOC(quick_costs, sizeof(quick_costs));
9803 TRASH_ALLOC(quick_n_ranges, sizeof(quick_n_ranges));
9804 }
9805
9806 /*
9807 Mark table to be reopened after query
9808 */
9809
mark_table_for_reopen()9810 void TABLE::mark_table_for_reopen()
9811 {
9812 THD *thd= in_use;
9813 DBUG_ASSERT(thd);
9814 thd->locked_tables_list.mark_table_for_reopen(thd, this);
9815 }
9816