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