diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 184 |
1 files changed, 114 insertions, 70 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5ce6a6b001c..f89fbc59b14 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -199,8 +199,8 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) from key used by MDL subsystem. */ DBUG_ASSERT(!strcmp(table_list->get_db_name(), - table_list->mdl_request.key.db_name()) && - !strcmp(table_list->get_table_name(), + table_list->mdl_request.key.db_name())); + DBUG_ASSERT(!strcmp(table_list->get_table_name(), table_list->mdl_request.key.name())); *key= (const char*)table_list->mdl_request.key.ptr() + 1; @@ -484,7 +484,7 @@ err_with_reopen: old locks. This should always succeed (unless some external process has removed the tables) */ - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) result= true; /* Since downgrade_lock() won't do anything with shared @@ -951,7 +951,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, @param thd thread handle @param table table which should be checked @param table_list list of tables - @param check_alias whether to check tables' aliases + @param check_flag whether to check tables' aliases + Currently this is only used by INSERT NOTE: to exclude derived tables from check we use following mechanism: a) during derived table processing set THD::derived_tables_processing @@ -980,9 +981,9 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, static TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { - TABLE_LIST *res; + TABLE_LIST *res= 0; LEX_CSTRING *d_name, *t_name, *t_alias; DBUG_ENTER("find_dup_table"); DBUG_PRINT("enter", ("table alias: %s", table->alias.str)); @@ -1015,17 +1016,15 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, retry: DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str)); - for (TABLE_LIST *tl= table_list;;) + for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0) { - if (tl && - tl->select_lex && tl->select_lex->master_unit() && + if (tl->select_lex && tl->select_lex->master_unit() && tl->select_lex->master_unit()->executed) { /* There is no sense to check tables of already executed parts of the query */ - tl= tl->next_global; continue; } /* @@ -1034,21 +1033,29 @@ retry: */ if (! (res= find_table_in_global_list(tl, d_name, t_name))) break; + tl= res; // We can continue search after this table /* Skip if same underlying table. */ if (res->table && (res->table == table->table)) - goto next; + continue; + + if (check_flag & CHECK_DUP_FOR_CREATE) + DBUG_RETURN(res); /* Skip if table alias does not match. */ - if (check_alias) + if (check_flag & CHECK_DUP_ALLOW_DIFFERENT_ALIAS) { if (my_strcasecmp(table_alias_charset, t_alias->str, res->alias.str)) - goto next; + continue; } /* - Skip if marked to be excluded (could be a derived table) or if - entry is a prelocking placeholder. + If table is not excluded (could be a derived table) and table is not + a prelocking placeholder then we found either a duplicate entry + or a table that is part of a derived table (handled below). + Examples are: + INSERT INTO t1 SELECT * FROM t1; + INSERT INTO t1 SELECT * FROM view_containing_t1; */ if (res->select_lex && !res->select_lex->exclude_from_table_unique_test && @@ -1060,14 +1067,17 @@ retry: processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test) or prelocking placeholder. */ -next: - tl= res->next_global; DBUG_PRINT("info", ("found same copy of table or table which we should skip")); } if (res && res->belong_to_derived) { - /* Try to fix */ + /* + We come here for queries of type: + INSERT INTO t1 (SELECT tmp.a FROM (select * FROM t1) as tmp); + + Try to fix by materializing the derived table + */ TABLE_LIST *derived= res->belong_to_derived; if (derived->is_merged_derived() && !derived->derived->is_excluded()) { @@ -1099,7 +1109,7 @@ next: TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { TABLE_LIST *dup; @@ -1131,12 +1141,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, if (!tmp_parent) break; - if ((dup= find_dup_table(thd, child, child->next_global, check_alias))) + if ((dup= find_dup_table(thd, child, child->next_global, check_flag))) break; } } else - dup= find_dup_table(thd, table, table_list, check_alias); + dup= find_dup_table(thd, table, table_list, check_flag); return dup; } @@ -1782,7 +1792,7 @@ retry_share: share= tdc_acquire_share(thd, table_list, gts_flags, &table); - if (!share) + if (unlikely(!share)) { /* Hide "Table doesn't exist" errors if the table belongs to a view. @@ -1924,7 +1934,7 @@ retry_share: thd->open_options, table, FALSE, IF_PARTITIONING(table_list->partition_names,0)); - if (error) + if (unlikely(error)) { my_free(table); @@ -1969,7 +1979,7 @@ retry_share: table_list->table= table; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (table->part_info) + if (unlikely(table->part_info)) { /* Partitions specified were incorrect.*/ if (part_names_error) @@ -2054,7 +2064,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, { TABLE *tab= find_locked_table(thd->open_tables, db, table_name); - if (!tab) + if (unlikely(!tab)) { if (!no_error) my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_name); @@ -2067,8 +2077,8 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, cases don't take a global IX lock in order to be compatible with global read lock. */ - if (!thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", - MDL_INTENTION_EXCLUSIVE)) + if (unlikely(!thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE))) { if (!no_error) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); @@ -2080,7 +2090,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, (tab= find_locked_table(tab->next, db, table_name))) continue; - if (!tab && !no_error) + if (unlikely(!tab && !no_error)) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); return tab; @@ -2298,7 +2308,8 @@ void Locked_tables_list::unlink_from_list(THD *thd, If mode is not LTM_LOCK_TABLES, we needn't do anything. Moreover, outside this mode pos_in_locked_tables value is not trustworthy. */ - if (thd->locked_tables_mode != LTM_LOCK_TABLES) + if (thd->locked_tables_mode != LTM_LOCK_TABLES && + thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES) return; /* @@ -2402,7 +2413,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) */ bool -Locked_tables_list::reopen_tables(THD *thd) +Locked_tables_list::reopen_tables(THD *thd, bool need_reopen) { Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); uint reopen_count= 0; @@ -2413,8 +2424,20 @@ Locked_tables_list::reopen_tables(THD *thd) for (TABLE_LIST *table_list= m_locked_tables; table_list; table_list= table_list->next_global) { - if (table_list->table) /* The table was not closed */ - continue; + if (need_reopen) + { + if (!table_list->table || !table_list->table->needs_reopen()) + continue; + /* no need to remove the table from the TDC here, thus (TABLE*)1 */ + close_all_tables_for_name(thd, table_list->table->s, + HA_EXTRA_NOT_USED, (TABLE*)1); + DBUG_ASSERT(table_list->table == NULL); + } + else + { + if (table_list->table) /* The table was not closed */ + continue; + } /* Links into thd->open_tables upon success */ if (open_table(thd, table_list, &ot_ctx)) @@ -3513,7 +3536,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, error= open_table(thd, tables, ot_ctx); } - if (error) + if (unlikely(error)) { if (! ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table) { @@ -3593,7 +3616,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, if (need_prelocking && ! lex->requires_prelocking()) lex->mark_as_requiring_prelocking(save_query_tables_last); - if (error) + if (unlikely(error)) goto end; } @@ -3603,7 +3626,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, /* Check and update metadata version of a base table. */ error= check_and_update_table_version(thd, tables, tables->table->s); - if (error) + if (unlikely(error)) goto end; /* After opening a MERGE table add the children to the query list of @@ -3663,7 +3686,7 @@ process_view_routines: if (need_prelocking && ! lex->requires_prelocking()) lex->mark_as_requiring_prelocking(save_query_tables_last); - if (error) + if (unlikely(error)) goto end; } @@ -4032,7 +4055,7 @@ restart: flags, prelocking_strategy, has_prelocking_list, &ot_ctx); - if (error) + if (unlikely(error)) { if (ot_ctx.can_recover_from_failed_open()) { @@ -4114,7 +4137,7 @@ restart: if (need_prelocking && ! *start) *start= thd->lex->query_tables; - if (error) + if (unlikely(error)) { if (ot_ctx.can_recover_from_failed_open()) { @@ -4210,7 +4233,7 @@ error: THD_STAGE_INFO(thd, stage_after_opening_tables); thd_proc_info(thd, 0); - if (error && *table_to_open) + if (unlikely(error) && *table_to_open) { (*table_to_open)->table= NULL; } @@ -4388,7 +4411,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, arena= thd->activate_stmt_arena_if_needed(&backup); table->file->get_parent_foreign_key_list(thd, &fk_list); - if (thd->is_error()) + if (unlikely(thd->is_error())) { if (arena) thd->restore_active_arena(arena, &backup); @@ -4439,7 +4462,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, table->internal_tables); if (arena) thd->restore_active_arena(arena, &backup); - if (error) + if (unlikely(error)) { *need_prelocking= TRUE; return TRUE; @@ -4680,7 +4703,7 @@ static bool check_lock_and_start_stmt(THD *thd, table_list->table->alias.c_ptr()); DBUG_RETURN(1); } - if ((error= table_list->table->file->start_stmt(thd, lock_type))) + if (unlikely((error= table_list->table->file->start_stmt(thd, lock_type)))) { table_list->table->file->print_error(error, MYF(0)); DBUG_RETURN(1); @@ -4820,7 +4843,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, break; } - if (!error) + if (likely(!error)) { /* We can't have a view or some special "open_strategy" in this function @@ -5864,7 +5887,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (check_privileges && - check_column_grant_in_table_ref(thd, *actual_table, name, length)) + check_column_grant_in_table_ref(thd, *actual_table, name, length, fld)) fld= WRONG_GRANT; else #endif @@ -6041,7 +6064,7 @@ find_field_in_tables(THD *thd, Item_ident *item, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (found && check_privileges && - check_column_grant_in_table_ref(thd, table_ref, name, length)) + check_column_grant_in_table_ref(thd, table_ref, name, length, found)) found= WRONG_GRANT; #endif } @@ -6162,7 +6185,7 @@ find_field_in_tables(THD *thd, Item_ident *item, if (db) return cur_field; - if (found) + if (unlikely(found)) { if (report_error == REPORT_ALL_ERRORS || report_error == IGNORE_EXCEPT_NON_UNIQUE) @@ -6174,7 +6197,7 @@ find_field_in_tables(THD *thd, Item_ident *item, } } - if (found) + if (likely(found)) return found; /* @@ -6293,7 +6316,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, (if this field created from expression argument of group_concat()), => we have to check presence of name before compare */ - if (!item_field->name.str) + if (unlikely(!item_field->name.str)) continue; if (table_name) @@ -6411,24 +6434,27 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, } } } - if (!found) + + if (likely(found)) + return found; + + if (unlikely(found_unaliased_non_uniq)) { - if (found_unaliased_non_uniq) - { - if (report_error != IGNORE_ERRORS) - my_error(ER_NON_UNIQ_ERROR, MYF(0), - find->full_name(), current_thd->where); - return (Item **) 0; - } - if (found_unaliased) - { - found= found_unaliased; - *counter= unaliased_counter; - *resolution= RESOLVED_BEHIND_ALIAS; - } + if (report_error != IGNORE_ERRORS) + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); + return (Item **) 0; + } + if (found_unaliased) + { + found= found_unaliased; + *counter= unaliased_counter; + *resolution= RESOLVED_BEHIND_ALIAS; } + if (found) return found; + if (report_error != REPORT_EXCEPT_NOT_FOUND) { if (report_error == REPORT_ALL_ERRORS) @@ -6548,7 +6574,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, Query_arena *arena, backup; bool result= TRUE; bool first_outer_loop= TRUE; - Field *field_1, *field_2; + Field *field_1; field_visibility_t field_1_invisible, field_2_invisible; /* Leaf table references to which new natural join columns are added @@ -6572,6 +6598,8 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, { bool found= FALSE; const LEX_CSTRING *field_name_1; + Field *field_2= 0; + /* true if field_name_1 is a member of using_fields */ bool is_using_column_1; if (!(nj_col_1= it_1.get_or_create_column_ref(thd, leaf_1))) @@ -7160,7 +7188,7 @@ static bool setup_natural_join_row_types(THD *thd, int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, - uint wild_num) + uint wild_num, uint *hidden_bit_fields) { if (!wild_num) return(0); @@ -7200,7 +7228,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, else if (insert_fields(thd, ((Item_field*) item)->context, ((Item_field*) item)->db_name, ((Item_field*) item)->table_name, &it, - any_privileges)) + any_privileges, hidden_bit_fields)) { if (arena) thd->restore_active_arena(arena, &backup); @@ -7251,7 +7279,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> *sum_func_list, List<Item> *pre_fix, bool allow_sum_func) { - reg2 Item *item; + Item *item; enum_column_usage saved_column_usage= thd->column_usage; nesting_map save_allow_sum_func= thd->lex->allow_sum_func; List_iterator<Item> it(fields); @@ -7665,7 +7693,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator<Item> *it, - bool any_privileges) + bool any_privileges, uint *hidden_bit_fields) { Field_iterator_table_ref field_iterator; bool found; @@ -7793,6 +7821,9 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, else it->after(item); /* Add 'item' to the SELECT list. */ + if (item->type() == Item::FIELD_ITEM && item->field_type() == MYSQL_TYPE_BIT) + (*hidden_bit_fields)++; + #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Set privilege information for the fields of newly created views. @@ -8169,7 +8200,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, if (rfield->stored_in_db()) { - if (value->save_in_field(rfield, 0) < 0 && !ignore_errors) + if (unlikely(value->save_in_field(rfield, 0) < 0) && !ignore_errors) { my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0)); goto err; @@ -8424,7 +8455,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, /* Ensure that all fields are from the same table */ DBUG_ASSERT(field->table == table); - if (field->invisible) + if (unlikely(field->invisible)) { all_fields_have_values= false; continue; @@ -8436,7 +8467,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, if (field->field_index == autoinc_index) table->auto_increment_field_not_null= TRUE; - if (field->vcol_info || (vers_sys_field && !ignore_errors)) + if (unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors)) { Item::Type type= value->type(); if (type != Item::DEFAULT_VALUE_ITEM && @@ -8621,6 +8652,19 @@ int setup_ftfuncs(SELECT_LEX *select_lex) } +void cleanup_ftfuncs(SELECT_LEX *select_lex) +{ + List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)), + lj(*(select_lex->ftfunc_list)); + Item_func_match *ftf; + + while ((ftf=li++)) + { + ftf->cleanup(); + } +} + + int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) { if (select_lex->ftfunc_list->elements) |