diff options
Diffstat (limited to 'sql/table.h')
-rw-r--r-- | sql/table.h | 528 |
1 files changed, 341 insertions, 187 deletions
diff --git a/sql/table.h b/sql/table.h index 66a51b9d4f5..eab8b8743fd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -29,6 +29,7 @@ #include "handler.h" /* row_type, ha_choice, handler */ #include "mysql_com.h" /* enum_field_types */ #include "thr_lock.h" /* thr_lock_type */ +#include "filesort_utils.h" /* Structs that defines the TABLE */ @@ -46,6 +47,7 @@ struct TABLE_LIST; class ACL_internal_schema_access; class ACL_internal_table_access; class Field; +class Table_statistics; struct Name_resolution_context; /* @@ -194,10 +196,20 @@ private: /* Order clause list element */ +typedef int (*fast_field_copier)(Field *to, Field *from); + + typedef struct st_order { struct st_order *next; Item **item; /* Point at item in select fields */ Item *item_ptr; /* Storage for initial item */ + /* + Reference to the function we are trying to optimize copy to + a temporary table + */ + fast_field_copier fast_field_copier_func; + /* Field for which above optimizer function setup */ + Field *fast_field_copier_setup; int counter; /* position in SELECT list, correct only if counter_used is true*/ bool asc; /* true if ascending */ @@ -251,7 +263,8 @@ typedef struct st_grant_info @details The version of this copy is found in GRANT_INFO::version. */ - GRANT_TABLE *grant_table; + GRANT_TABLE *grant_table_user; + GRANT_TABLE *grant_table_role; /** @brief Used for cache invalidation when caching privilege information. @@ -307,11 +320,13 @@ enum enum_vcol_update_mode VCOL_UPDATE_FOR_WRITE }; -typedef struct st_filesort_info +class Filesort_info { + /// Buffer for sorting keys. + Filesort_buffer filesort_buffer; + +public: IO_CACHE *io_cache; /* If sorted through filesort */ - uchar **sort_keys; /* Buffer for sorting keys */ - uint keys; /* Number of key pointers in buffer */ uchar *buffpek; /* Buffer for buffpek structures */ uint buffpek_len; /* Max number of buffpeks in the buffer */ uchar *addon_buf; /* Pointer to a buffer if sorted with fields */ @@ -320,28 +335,40 @@ typedef struct st_filesort_info void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); /* To unpack back */ uchar *record_pointers; /* If sorted in memory */ ha_rows found_records; /* How many records in sort */ -} FILESORT_INFO; + /** Sort filesort_buffer */ + void sort_buffer(Sort_param *param, uint count) + { filesort_buffer.sort_buffer(param, count); } -/* - Values in this enum are used to indicate how a tables TIMESTAMP field - should be treated. It can be set to the current timestamp on insert or - update or both. - WARNING: The values are used for bit operations. If you change the - enum, you must keep the bitwise relation of the values. For example: - (int) TIMESTAMP_AUTO_SET_ON_BOTH must be equal to - (int) TIMESTAMP_AUTO_SET_ON_INSERT | (int) TIMESTAMP_AUTO_SET_ON_UPDATE. - We use an enum here so that the debugger can display the value names. -*/ -enum timestamp_auto_set_type -{ - TIMESTAMP_NO_AUTO_SET= 0, TIMESTAMP_AUTO_SET_ON_INSERT= 1, - TIMESTAMP_AUTO_SET_ON_UPDATE= 2, TIMESTAMP_AUTO_SET_ON_BOTH= 3 + /** + Accessors for Filesort_buffer (which @c). + */ + uchar *get_record_buffer(uint idx) + { return filesort_buffer.get_record_buffer(idx); } + + uchar **get_sort_keys() + { return filesort_buffer.get_sort_keys(); } + + uchar **alloc_sort_buffer(uint num_records, uint record_length) + { return filesort_buffer.alloc_sort_buffer(num_records, record_length); } + + bool check_sort_buffer_properties(uint num_records, uint record_length) + { + return filesort_buffer.check_sort_buffer_properties(num_records, + record_length); + } + + void free_sort_buffer() + { filesort_buffer.free_sort_buffer(); } + + void init_record_pointers() + { filesort_buffer.init_record_pointers(); } + + size_t sort_buffer_size() const + { return filesort_buffer.sort_buffer_size(); } }; -#define clear_timestamp_auto_bits(_target_, _bits_) \ - (_target_)= (enum timestamp_auto_set_type)((int)(_target_) & ~(int)(_bits_)) -class Field_timestamp; + class Field_blob; class Table_triggers_list; @@ -463,8 +490,7 @@ TABLE_CATEGORY get_table_category(const LEX_STRING *db, struct TABLE_share; - -extern ulong refresh_version; +struct All_share_tables; typedef struct st_table_field_type { @@ -478,22 +504,11 @@ typedef struct st_table_field_def { uint count; const TABLE_FIELD_TYPE *field; + uint primary_key_parts; + const uint *primary_key_columns; } TABLE_FIELD_DEF; -#ifdef WITH_PARTITION_STORAGE_ENGINE -/** - Partition specific ha_data struct. -*/ -typedef struct st_ha_data_partition -{ - bool auto_inc_initialized; - mysql_mutex_t LOCK_auto_inc; /**< protecting auto_inc val */ - ulonglong next_auto_inc_val; /**< first non reserved value */ -} HA_DATA_PARTITION; -#endif - - class Table_check_intact { protected: @@ -548,6 +563,35 @@ typedef I_P_List <Wait_for_flush, Wait_for_flush_list; +enum open_frm_error { + OPEN_FRM_OK = 0, + OPEN_FRM_OPEN_ERROR, + OPEN_FRM_READ_ERROR, + OPEN_FRM_CORRUPTED, + OPEN_FRM_DISCOVER, + OPEN_FRM_ERROR_ALREADY_ISSUED, + OPEN_FRM_NOT_A_VIEW, + OPEN_FRM_NOT_A_TABLE, + OPEN_FRM_NEEDS_REBUILD +}; + +/** + Control block to access table statistics loaded + from persistent statistical tables +*/ + +struct TABLE_STATISTICS_CB +{ + MEM_ROOT mem_root; /* MEM_ROOT to allocate statistical data for the table */ + Table_statistics *table_stats; /* Structure to access the statistical data */ + bool stats_can_be_read; /* Memory for statistical data is allocated */ + bool stats_is_read; /* Statistical data for table has been read + from statistical tables */ + bool histograms_can_be_read; + bool histograms_are_read; +}; + + /** This structure is shared between different table objects. There is one instance of table share per one table in the database. @@ -567,14 +611,36 @@ struct TABLE_SHARE TYPELIB fieldnames; /* Pointer to fieldnames */ TYPELIB *intervals; /* pointer to interval info */ mysql_mutex_t LOCK_ha_data; /* To protect access to ha_data */ - TABLE_SHARE *next, **prev; /* Link to unused shares */ + mysql_mutex_t LOCK_share; /* To protect TABLE_SHARE */ - /* - Doubly-linked (back-linked) lists of used and unused TABLE objects - for this share. - */ - I_P_List <TABLE, TABLE_share> used_tables; - I_P_List <TABLE, TABLE_share> free_tables; + typedef I_P_List <TABLE, TABLE_share> TABLE_list; + typedef I_P_List <TABLE, All_share_tables> All_share_tables_list; + struct + { + /** + Protects ref_count, m_flush_tickets, all_tables, free_tables, flushed, + all_tables_refs. + */ + mysql_mutex_t LOCK_table_share; + mysql_cond_t COND_release; + TABLE_SHARE *next, **prev; /* Link to unused shares */ + uint ref_count; /* How many TABLE objects uses this */ + uint all_tables_refs; /* Number of refs to all_tables */ + /** + List of tickets representing threads waiting for the share to be flushed. + */ + Wait_for_flush_list m_flush_tickets; + /* + Doubly-linked (back-linked) lists of used and unused TABLE objects + for this share. + */ + All_share_tables_list all_tables; + TABLE_list free_tables; + ulong version; + bool flushed; + } tdc; + + LEX_CUSTRING tabledef_version; engine_option_value *option_list; /* text options for table */ ha_table_option_struct *option_struct; /* structure with parsed options */ @@ -582,10 +648,11 @@ struct TABLE_SHARE /* The following is copied to each TABLE on OPEN */ Field **field; Field **found_next_number_field; - Field *timestamp_field; /* Used only during open */ KEY *key_info; /* data of keys in database */ uint *blob_field; /* Index to blobs in Field arrray*/ + TABLE_STATISTICS_CB stats_cb; + uchar *default_values; /* row with default values */ LEX_STRING comment; /* Comment about table */ CHARSET_INFO *table_charset; /* Default charset of string fields */ @@ -616,7 +683,7 @@ struct TABLE_SHARE key_map keys_for_keyread; ha_rows min_rows, max_rows; /* create information */ ulong avg_row_length; /* create information */ - ulong version, mysql_version; + ulong mysql_version; /* 0 if .frm is created before 5.0 */ ulong reclength; /* Recordlength */ /* Stored record length. No generated-only virtual fields are included */ ulong stored_rec_length; @@ -624,8 +691,8 @@ struct TABLE_SHARE plugin_ref db_plugin; /* storage engine plugin */ inline handlerton *db_type() const /* table_type for handler */ { - // DBUG_ASSERT(db_plugin); - return db_plugin ? plugin_data(db_plugin, handlerton*) : NULL; + return is_view ? view_pseudo_hton : + db_plugin ? plugin_hton(db_plugin) : NULL; } enum row_type row_type; /* How rows are stored */ enum tmp_table_type tmp_table; @@ -635,9 +702,10 @@ struct TABLE_SHARE /** Per-page checksums or not. */ enum ha_choice page_checksum; - uint ref_count; /* How many TABLE objects uses this */ - uint blob_ptr_size; /* 4 or 8 */ uint key_block_size; /* create key_block_size, if used */ + uint stats_sample_pages; /* number of pages to sample during + stats estimation, if used, otherwise 0. */ + enum_stats_auto_recalc stats_auto_recalc; /* Automatic recalc of stats. */ uint null_bytes, last_null_bit_pos; /* Same as null_bytes, except that if there is only a 'delete-marker' in @@ -654,7 +722,6 @@ struct TABLE_SHARE uint uniques; /* Number of UNIQUE index */ uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ - uint timestamp_field_offset; /* Field number for timestamp field */ uint varchar_fields; /* number of varchar fields */ uint db_create_options; /* Create options from database */ uint db_options_in_use; /* Options in use */ @@ -665,10 +732,12 @@ struct TABLE_SHARE uint next_number_index; /* autoincrement key number */ uint next_number_key_offset; /* autoinc keypart offset in a key */ uint next_number_keypart; /* autoinc keypart number in a key */ - uint error, open_errno, errarg; /* error from open_table_def() */ + enum open_frm_error error; /* error from open_table_def() */ + uint open_errno; /* error from open_table_def() */ uint column_bitmap_size; uchar frm_version; uint vfields; /* Number of computed (virtual) fields */ + uint default_fields; /* Number of default fields */ bool use_ext_keys; /* Extended keys can be used */ bool null_field_first; bool system; /* Set if system table (one record) */ @@ -677,9 +746,17 @@ struct TABLE_SHARE bool is_view; bool deleting; /* going to delete this table */ bool can_cmp_whole_record; + bool table_creation_was_logged; ulong table_map_id; /* for row-based replication */ /* + Things that are incompatible between the stored version and the + current version. This is a set of HA_CREATE... bits that can be used + to modify create_info->used_fields for ALTER TABLE. + */ + ulong incompatible_version; + + /* Cache for row-based replication table share checks that does not need to be repeated. Possible values are: -1 when cache value is not calculated yet, 0 when table *shall not* be replicated, 1 when @@ -687,13 +764,16 @@ struct TABLE_SHARE */ int cached_row_logging_check; + /* Name of the tablespace used for this table */ + char *tablespace; + #ifdef WITH_PARTITION_STORAGE_ENGINE /* filled in when reading from frm */ bool auto_partitioned; char *partition_info_str; uint partition_info_str_len; uint partition_info_buffer_size; - handlerton *default_part_db_type; + plugin_ref default_part_plugin; #endif /** @@ -708,25 +788,12 @@ struct TABLE_SHARE */ const TABLE_FIELD_DEF *table_field_def_cache; - /** place to store storage engine specific data */ - void *ha_data; - void (*ha_data_destroy)(void *); /* An optional destructor for ha_data */ - -#ifdef WITH_PARTITION_STORAGE_ENGINE - /** place to store partition specific data, LOCK_ha_data hold while init. */ - HA_DATA_PARTITION *ha_part_data; - /* Destructor for ha_part_data */ - void (*ha_part_data_destroy)(HA_DATA_PARTITION *); -#endif + /** Main handler's share */ + Handler_share *ha_share; /** Instrumentation for this table share. */ PSI_table_share *m_psi; - /** - List of tickets representing threads waiting for the share to be flushed. - */ - Wait_for_flush_list m_flush_tickets; - /* Set share's table cache key and update its db and table name appropriately. @@ -795,42 +862,6 @@ struct TABLE_SHARE return table_map_id; } - /** Is this table share being expelled from the table definition cache? */ - inline bool has_old_version() const - { - return version != refresh_version; - } - inline bool protected_against_usage() const - { - return version == 0; - } - inline void protect_against_usage() - { - version= 0; - } - /* - This is used only for the case of locked tables, as we want to - allow one to do SHOW commands on them even after ALTER or REPAIR - */ - inline void allow_access_to_protected_table() - { - DBUG_ASSERT(version == 0); - version= 1; - } - /* - Remove from table definition cache at close. - Table can still be opened by SHOW - */ - inline void remove_from_cache_at_close() - { - if (version != 0) /* Don't remove protection */ - version= 1; - } - inline void set_refresh_version() - { - version= refresh_version; - } - /** Convert unrelated members of TABLE_SHARE to one enum representing its type. @@ -852,7 +883,7 @@ struct TABLE_SHARE } /** Return a table metadata version. - * for base tables, we return table_map_id. + * for base tables and views, we return table_map_id. It is assigned from a global counter incremented for each new table loaded into the table definition cache (TDC). * for temporary tables it's table_map_id again. But for @@ -861,7 +892,7 @@ struct TABLE_SHARE counter incremented for every new SQL statement. Since temporary tables are thread-local, each temporary table gets a unique id. - * for everything else (views, information schema tables), + * for everything else (e.g. information schema tables), the version id is zero. This choice of version id is a large compromise @@ -876,8 +907,8 @@ struct TABLE_SHARE version id of a temporary table is never compared with a version id of a view, and vice versa. - Secondly, for base tables, we know that each DDL flushes the - respective share from the TDC. This ensures that whenever + Secondly, for base tables and views, we know that each DDL flushes + the respective share from the TDC. This ensures that whenever a table is altered or dropped and recreated, it gets a new version id. Unfortunately, since elements of the TDC are also flushed on @@ -898,26 +929,6 @@ struct TABLE_SHARE Metadata of information schema tables never changes. Thus we can safely assume 0 for a good enough version id. - Views are a special and tricky case. A view is always inlined - into the parse tree of a prepared statement at prepare. - Thus, when we execute a prepared statement, the parse tree - will not get modified even if the view is replaced with another - view. Therefore, we can safely choose 0 for version id of - views and effectively never invalidate a prepared statement - when a view definition is altered. Note, that this leads to - wrong binary log in statement-based replication, since we log - prepared statement execution in form Query_log_events - containing conventional statements. But since there is no - metadata locking for views, the very same problem exists for - conventional statements alone, as reported in Bug#25144. The only - difference between prepared and conventional execution is, - effectively, that for prepared statements the race condition - window is much wider. - In 6.0 we plan to support view metadata locking (WL#3726) and - extend table definition cache to cache views (WL#4298). - When this is done, views will be handled in the same fashion - as the base tables. - Finally, by taking into account table type, we always track that a change has taken place when a view is replaced with a base table, a base table is replaced with a temporary @@ -927,7 +938,7 @@ struct TABLE_SHARE */ ulong get_table_ref_version() const { - return (tmp_table == SYSTEM_TMP_TABLE || is_view) ? 0 : table_map_id; + return (tmp_table == SYSTEM_TMP_TABLE) ? 0 : table_map_id; } bool visit_subgraph(Wait_for_flush *waiting_ticket, @@ -944,6 +955,43 @@ struct TABLE_SHARE } uint actual_n_key_parts(THD *thd); + + LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table) + + /* + populates TABLE_SHARE from the table description in the binary frm image. + if 'write' is true, this frm image is also written into a corresponding + frm file, that serves as a persistent metadata cache to avoid + discovering the table over and over again + */ + int init_from_binary_frm_image(THD *thd, bool write, + const uchar *frm_image, size_t frm_length); + + /* + populates TABLE_SHARE from the table description, specified as the + complete CREATE TABLE sql statement. + if 'write' is true, this frm image is also written into a corresponding + frm file, that serves as a persistent metadata cache to avoid + discovering the table over and over again + */ + int init_from_sql_statement_string(THD *thd, bool write, + const char *sql, size_t sql_length); + /* + writes the frm image to an frm file, corresponding to this table + */ + bool write_frm_image(const uchar *frm_image, size_t frm_length); + + bool write_frm_image(void) + { return frm_image ? write_frm_image(frm_image->str, frm_image->length) : 0; } + + /* + returns an frm image for this table. + the memory is allocated and must be freed later + */ + bool read_frm_image(const uchar **frm_image, size_t *frm_length); + + /* frees the memory allocated in read_frm_image */ + void free_frm_image(const uchar *frm); }; @@ -955,6 +1003,7 @@ enum index_hint_type INDEX_HINT_FORCE }; +struct st_cond_statistic; #define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0) #define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1) @@ -972,17 +1021,18 @@ struct TABLE private: /** - Links for the lists of used/unused TABLE objects for this share. + Links for the list of all TABLE objects for this share. Declared as private to avoid direct manipulation with those objects. One should use methods of I_P_List template instead. */ - TABLE *share_next, **share_prev; - - friend struct TABLE_share; + TABLE *share_all_next, **share_all_prev; + friend struct All_share_tables; public: THD *in_use; /* Which thread uses this */ + /* Time when table was released to table cache. Valid for unused tables. */ + ulonglong tc_time; Field **field; /* Pointer to fields */ uchar *record[2]; /* Pointer to records */ @@ -1015,8 +1065,9 @@ public: Field *next_number_field; /* Set if next_number is activated */ Field *found_next_number_field; /* Set on open */ - Field_timestamp *timestamp_field; Field **vfield; /* Pointer to virtual fields*/ + /* Fields that are updated automatically on INSERT or UPDATE. */ + Field **default_field; /* Table's triggers, 0 if there are no of them */ Table_triggers_list *triggers; @@ -1026,9 +1077,9 @@ public: ORDER *group; String alias; /* alias or table name */ uchar *null_flags; - my_bitmap_map *bitmap_init_value; MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set; MY_BITMAP eq_join_set; /* used to mark equi-joined fields */ + MY_BITMAP cond_set; /* used to mark fields from sargable conditions*/ MY_BITMAP *read_set, *write_set, *vcol_set; /* Active column sets */ /* The ID of the query that opened and is using this table. Has different @@ -1050,13 +1101,26 @@ public: */ query_id_t query_id; + /* + This structure is used for statistical data on the table that + is collected by the function collect_statistics_for_table + */ + Table_statistics *collected_stats; + + /* The estimate of the number of records in the table used by optimizer */ + ha_rows used_stat_records; + /* For each key that has quick_keys.is_set(key) == TRUE: estimate of #records and max #key parts that range access would use. */ ha_rows quick_rows[MAX_KEY]; - /* Bitmaps of key parts that =const for the entire join. */ + /* + Bitmaps of key parts that =const for the duration of join execution. If + we're in a subquery, then the constant may be different across subquery + re-executions. + */ key_part_map const_key_parts[MAX_KEY]; uint quick_key_parts[MAX_KEY]; @@ -1072,19 +1136,9 @@ public: */ ha_rows quick_condition_rows; - /* - If this table has TIMESTAMP field with auto-set property (pointed by - timestamp_field member) then this variable indicates during which - operations (insert only/on update/in both cases) we should set this - field to current timestamp. If there are no such field in this table - or we should not automatically set its value during execution of current - statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0). - - Value of this variable is set for each statement in open_table() and - if needed cleared later in statement processing code (see mysql_update() - as example). - */ - timestamp_auto_set_type timestamp_field_type; + double cond_selectivity; + List<st_cond_statistic> *cond_selectivity_sampling_explain; + table_map map; /* ID bit of table (1,2,4,8,16...) */ uint lock_position; /* Position in MYSQL_LOCK.table */ @@ -1154,7 +1208,12 @@ public: See TABLE_LIST::process_index_hints(). */ bool force_index_group; - bool distinct,const_table,no_rows, used_for_duplicate_elimination; + /* + TRUE<=> this table was created with create_tmp_table(... distinct=TRUE..) + call + */ + bool distinct; + bool const_table,no_rows, used_for_duplicate_elimination; /** Forces DYNAMIC Aria row format for internal temporary tables. */ @@ -1166,6 +1225,9 @@ public: */ bool key_read; bool no_keyread; + /** + If set, indicate that the table is not replicated by the server. + */ bool locked_by_logger; bool no_replicate; bool locked_by_name; @@ -1184,11 +1246,15 @@ public: bool get_fields_in_item_tree; /* Signal to fix_field */ bool m_needs_reopen; bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/ +#ifdef HAVE_REPLICATION + /* used in RBR Triggers */ + bool master_had_triggers; +#endif REGINFO reginfo; /* field connections */ MEM_ROOT mem_root; GRANT_INFO grant; - FILESORT_INFO sort; + Filesort_info sort; /* The arena which the items for expressions from the table definition are associated with. @@ -1199,9 +1265,12 @@ public: Query_arena *expr_arena; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info; /* Partition related information */ - bool no_partitions_used; /* If true, all partitions have been pruned away */ + /* If true, all partitions have been pruned away */ + bool all_partitions_pruned_away; #endif uint max_keys; /* Size of allocated key_info array. */ + bool stats_is_read; /* Persistent statistics is read for the table */ + bool histograms_are_read; MDL_ticket *mdl_ticket; void init(THD *thd, TABLE_LIST *tl); @@ -1219,6 +1288,8 @@ public: void mark_columns_needed_for_insert(void); bool mark_virtual_col(Field *field); void mark_virtual_columns_for_write(bool insert_fl); + void mark_default_fields_for_write(); + bool has_default_function(bool is_update); inline void column_bitmaps_set(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg) { @@ -1305,8 +1376,19 @@ public: } bool update_const_key_parts(COND *conds); + + my_ptrdiff_t default_values_offset() const + { return (my_ptrdiff_t) (s->default_values - record[0]); } + uint actual_n_key_parts(KEY *keyinfo); ulong actual_key_flags(KEY *keyinfo); + int update_default_fields(); + void reset_default_fields(); + inline ha_rows stat_records() { return used_stat_records; } + + void prepare_triggers_for_insert_stmt_or_event(); + bool prepare_triggers_for_delete_stmt_or_event(); + bool prepare_triggers_for_update_stmt_or_event(); }; @@ -1319,11 +1401,24 @@ struct TABLE_share { static inline TABLE **next_ptr(TABLE *l) { - return &l->share_next; + return &l->next; } static inline TABLE ***prev_ptr(TABLE *l) { - return &l->share_prev; + return (TABLE ***) &l->prev; + } +}; + + +struct All_share_tables +{ + static inline TABLE **next_ptr(TABLE *l) + { + return &l->share_all_next; + } + static inline TABLE ***prev_ptr(TABLE *l) + { + return &l->share_all_prev; } }; @@ -1335,6 +1430,9 @@ enum enum_schema_table_state PROCESSED_BY_JOIN_EXEC }; +enum enum_fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, + FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_SET_DEFAULT}; + typedef struct st_foreign_key_info { LEX_STRING *foreign_id; @@ -1342,13 +1440,16 @@ typedef struct st_foreign_key_info LEX_STRING *foreign_table; LEX_STRING *referenced_db; LEX_STRING *referenced_table; - LEX_STRING *update_method; - LEX_STRING *delete_method; + enum_fk_option update_method; + enum_fk_option delete_method; LEX_STRING *referenced_key_name; List<LEX_STRING> foreign_fields; List<LEX_STRING> referenced_fields; } FOREIGN_KEY_INFO; +LEX_CSTRING *fk_option_name(enum_fk_option opt); +bool fk_modifies_child(enum_fk_option opt); + #define MY_I_S_MAYBE_NULL 1 #define MY_I_S_UNSIGNED 2 @@ -1586,7 +1687,7 @@ struct TABLE_LIST /** Prepare TABLE_LIST that consists of one table instance to use in - simple_open_and_lock_tables + open_and_lock_tables */ inline void init_one_table(const char *db_name_arg, size_t db_length_arg, @@ -1595,6 +1696,14 @@ struct TABLE_LIST const char *alias_arg, enum thr_lock_type lock_type_arg) { + enum enum_mdl_type mdl_type; + if (lock_type_arg >= TL_WRITE_ALLOW_WRITE) + mdl_type= MDL_SHARED_WRITE; + else if (lock_type_arg == TL_READ_NO_INSERT) + mdl_type= MDL_SHARED_NO_WRITE; + else + mdl_type= MDL_SHARED_READ; + bzero((char*) this, sizeof(*this)); db= (char*) db_name_arg; db_length= db_length_arg; @@ -1602,10 +1711,32 @@ struct TABLE_LIST table_name_length= table_name_length_arg; alias= (char*) (alias_arg ? alias_arg : table_name_arg); lock_type= lock_type_arg; - mdl_request.init(MDL_key::TABLE, db, table_name, - (lock_type >= TL_WRITE_ALLOW_WRITE) ? - MDL_SHARED_WRITE : MDL_SHARED_READ, - MDL_TRANSACTION); + updating= lock_type >= TL_WRITE_ALLOW_WRITE; + mdl_request.init(MDL_key::TABLE, db, table_name, mdl_type, MDL_TRANSACTION); + } + + inline void init_one_table_for_prelocking(const char *db_name_arg, + size_t db_length_arg, + const char *table_name_arg, + size_t table_name_length_arg, + const char *alias_arg, + enum thr_lock_type lock_type_arg, + bool routine, + TABLE_LIST *belong_to_view_arg, + uint8 trg_event_map_arg, + TABLE_LIST ***last_ptr) + { + init_one_table(db_name_arg, db_length_arg, table_name_arg, + table_name_length_arg, alias_arg, lock_type_arg); + cacheable_table= 1; + prelocking_placeholder= routine ? ROUTINE : FK; + open_type= routine ? OT_TEMPORARY_OR_BASE : OT_BASE_ONLY; + belong_to_view= belong_to_view_arg; + trg_event_map= trg_event_map_arg; + + **last_ptr= this; + prev_global= *last_ptr; + *last_ptr= &next_global; } /* @@ -1688,7 +1819,7 @@ struct TABLE_LIST /* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */ List<Index_hint> *index_hints; TABLE *table; /* opened table */ - uint table_id; /* table id (from binlog) for opened table */ + ulonglong table_id; /* table id (from binlog) for opened table */ /* select_result for derived table to pass it from table creation to table filling procedure @@ -1884,12 +2015,12 @@ struct TABLE_LIST This TABLE_LIST object is just placeholder for prelocking, it will be used for implicit LOCK TABLES only and won't be used in real statement. */ - bool prelocking_placeholder; + enum { USER, ROUTINE, FK } prelocking_placeholder; /** Indicates that if TABLE_LIST object corresponds to the table/view which requires special handling. */ - enum + enum enum_open_strategy { /* Normal open. */ OPEN_NORMAL= 0, @@ -1901,7 +2032,6 @@ struct TABLE_LIST /* For transactional locking. */ int lock_timeout; /* NOWAIT or WAIT [X] */ bool lock_transactional; /* If transactional lock requested. */ - bool internal_tmp_table; /** TRUE if an alias for this table was specified in the SQL. */ bool is_alias; /** TRUE if the table is referred to in the statement using a fully @@ -1971,6 +2101,11 @@ struct TABLE_LIST MDL_request mdl_request; +#ifdef WITH_PARTITION_STORAGE_ENGINE + /* List to carry partition names from PARTITION (...) clause in statement */ + List<String> *partition_names; +#endif /* WITH_PARTITION_STORAGE_ENGINE */ + void calc_md5(char *buffer); int view_check_option(THD *thd, bool ignore_failure); bool create_field_translation(THD *thd); @@ -2030,7 +2165,7 @@ struct TABLE_LIST bool prepare_security(THD *thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *find_view_security_context(THD *thd); - bool prepare_view_securety_context(THD *thd); + bool prepare_view_security_context(THD *thd); #endif /* Cleanup for re-execution in a prepared statement or a stored @@ -2155,7 +2290,7 @@ struct TABLE_LIST @brief Returns the name of the database that the referenced table belongs to. */ - char *get_db_name() { return view != NULL ? view_db.str : db; } + char *get_db_name() const { return view != NULL ? view_db.str : db; } /** @brief Returns the name of the table that this TABLE_LIST represents. @@ -2163,9 +2298,9 @@ struct TABLE_LIST @details The unqualified table name or view name for a table or view, respectively. */ - char *get_table_name() { return view != NULL ? view_name.str : table_name; } + char *get_table_name() const { return view != NULL ? view_name.str : table_name; } bool is_active_sjm(); - bool is_jtbm() { return test(jtbm_subselect!=NULL); } + bool is_jtbm() { return MY_TEST(jtbm_subselect != NULL); } st_select_lex_unit *get_unit(); st_select_lex *get_single_select(); void wrap_into_nested_join(List<TABLE_LIST> &join_list); @@ -2205,9 +2340,9 @@ private: #else inline void set_check_merged() {} #endif - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ enum enum_table_ref_type m_table_ref_type; - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ ulong m_table_ref_version; }; @@ -2483,26 +2618,38 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, #endif } +bool ok_for_lower_case_names(const char *names); -size_t max_row_length(TABLE *table, const uchar *data); +enum get_table_share_flags { + GTS_TABLE = 1, + GTS_VIEW = 2, + GTS_NOLOCK = 4, + GTS_USE_DISCOVERY = 8, + GTS_FORCE_DISCOVERY = 16 +}; +size_t max_row_length(TABLE *table, const uchar *data); void init_mdl_requests(TABLE_LIST *table_list); -int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, - uint db_stat, uint prgflag, uint ha_open_flags, - TABLE *outparam, bool is_create_table); +enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, + const char *alias, uint db_stat, uint prgflag, + uint ha_open_flags, TABLE *outparam, + bool is_create_table); bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table, Field *field, LEX_STRING *vcol_expr, bool *error_reported); -TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, - uint key_length); +TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, + const char *key, uint key_length); void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, uint key_length, const char *table_name, const char *path); void free_table_share(TABLE_SHARE *share); -int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags); -void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg); +enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, + uint flags = GTS_TABLE); + +void open_table_error(TABLE_SHARE *share, enum open_frm_error error, + int db_errno); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase); bool check_db_name(LEX_STRING *db); @@ -2512,21 +2659,28 @@ int rename_file_ext(const char * from,const char * to,const char * ext); char *get_field(MEM_ROOT *mem, Field *field); bool get_field(MEM_ROOT *mem, Field *field, class String *res); +bool validate_comment_length(THD *thd, LEX_STRING *comment, size_t max_len, + uint err_code, const char *name); + int closefrm(TABLE *table, bool free_share); -int read_string(File file, uchar* *to, size_t length); void free_blobs(TABLE *table); void free_field_buffers_larger_than(TABLE *table, uint32 size); -int set_zone(int nr,int min_zone,int max_zone); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); -ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, - const char *newname); -ulong next_io_size(ulong pos); void append_unescaped(String *res, const char *pos, uint length); -File create_frm(THD *thd, const char *name, const char *db, - const char *table, uint reclength, uchar *fileinfo, - HA_CREATE_INFO *create_info, uint keys, KEY *key_info); +void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, + HA_CREATE_INFO *create_info, uint keys, KEY *key_info); char *fn_rext(char *name); +/* Check that the integer is in the internal */ +static inline int set_zone(int nr,int min_zone,int max_zone) +{ + if (nr <= min_zone) + return min_zone; + if (nr >= max_zone) + return max_zone; + return nr; +} + /* performance schema */ extern LEX_STRING PERFORMANCE_SCHEMA_DB_NAME; |