diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 172 |
1 files changed, 96 insertions, 76 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 77d2b165881..aa571497683 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -947,8 +947,13 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table) { for (; table ; table= table->next) + { if (table->query_id == thd->query_id) + { table->query_id= 0; + table->file->ha_reset(); + } + } } @@ -1028,21 +1033,13 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) */ ha_commit_stmt(thd); - /* We are under simple LOCK TABLES so should not do anything else. */ - if (!prelocked_mode) - DBUG_VOID_RETURN; + /* Ensure we are calling ha_reset() for all used tables */ + mark_used_tables_as_free_for_reuse(thd, thd->open_tables); - if (!thd->lex->requires_prelocking()) - { - /* - If we are executing one of substatements we have to mark - all tables which it used as free for reuse. - */ - mark_used_tables_as_free_for_reuse(thd, thd->open_tables); + /* We are under simple LOCK TABLES so should not do anything else. */ + if (!prelocked_mode || !thd->lex->requires_prelocking()) DBUG_VOID_RETURN; - } - DBUG_ASSERT(prelocked_mode); /* We are in prelocked mode, so we have to leave it now with doing implicit UNLOCK TABLES if need. @@ -1094,7 +1091,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) found_old_table= 0; while (thd->open_tables) - found_old_table|=close_thread_table(thd, &thd->open_tables); + found_old_table|= close_thread_table(thd, &thd->open_tables); thd->some_tables_deleted=0; /* Free tables to hold down open files */ @@ -1123,6 +1120,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) DBUG_VOID_RETURN; } + /* move one table to free list */ bool close_thread_table(THD *thd, TABLE **table_ptr) @@ -1147,11 +1145,8 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) table->s->flush_version= flush_version; table->file->extra(HA_EXTRA_FLUSH); } - else - { - // Free memory and reset for next loop - table->file->ha_reset(); - } + // Free memory and reset for next loop + table->file->ha_reset(); table->in_use=0; if (unused_tables) { @@ -1181,10 +1176,8 @@ static inline uint tmpkeyval(THD *thd, TABLE *table) void close_temporary_tables(THD *thd) { - TABLE *next, - *prev_table /* prev link is not maintained in TABLE's double-linked list */, - *table; - char *query= (gptr) 0, *end; + TABLE *next, *prev_table, *table; + char *query= 0, *end; uint query_buf_size, max_names_len; bool found_user_tables; @@ -2085,6 +2078,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (table->timestamp_field) table->timestamp_field_type= table->timestamp_field->get_auto_set_type(); table_list->updatable= 1; // It is not derived table nor non-updatable VIEW + table->clear_column_bitmaps(); DBUG_ASSERT(table->key_read == 0); DBUG_RETURN(table); } @@ -2182,6 +2176,7 @@ static bool reopen_table(TABLE *table) VOID(closefrm(table, 1)); // close file, free everything *table= tmp; + table->default_column_bitmaps(); table->file->change_table_ptr(table, table->s); DBUG_ASSERT(table->alias != 0); @@ -3549,22 +3544,50 @@ Field *view_ref_found= (Field*) 0x2; static void update_field_dependencies(THD *thd, Field *field, TABLE *table) { - if (thd->set_query_id) + DBUG_ENTER("update_field_dependencies"); + if (thd->mark_used_columns != MARK_COLUMNS_NONE) { - table->file->ha_set_bit_in_rw_set(field->fieldnr, - (bool)(thd->set_query_id-1)); - if (field->query_id != thd->query_id) + MY_BITMAP *current_bitmap, *other_bitmap; + + /* + We always want to register the used keys, as the column bitmap may have + been set for all fields (for example for view). + */ + + table->used_keys.intersect(field->part_of_key); + table->merge_keys.merge(field->part_of_key); + + if (thd->mark_used_columns == MARK_COLUMNS_READ) { - if (table->get_fields_in_item_tree) - field->flags|= GET_FIXED_FIELDS_FLAG; - field->query_id= thd->query_id; - table->used_fields++; - table->used_keys.intersect(field->part_of_key); + current_bitmap= table->read_set; + other_bitmap= table->write_set; } else - thd->dupp_field= field; - } else if (table->get_fields_in_item_tree) + { + current_bitmap= table->write_set; + other_bitmap= table->read_set; + } + + if (bitmap_fast_test_and_set(current_bitmap, field->field_index)) + { + if (thd->mark_used_columns == MARK_COLUMNS_WRITE) + { + DBUG_PRINT("warning", ("Found duplicated field")); + thd->dup_field= field; + } + else + { + DBUG_PRINT("note", ("Field found before")); + } + DBUG_VOID_RETURN; + } + if (table->get_fields_in_item_tree) + field->flags|= GET_FIXED_FIELDS_FLAG; + table->used_fields++; + } + else if (table->get_fields_in_item_tree) field->flags|= GET_FIXED_FIELDS_FLAG; + DBUG_VOID_RETURN; } @@ -3973,12 +3996,12 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, fld= WRONG_GRANT; else #endif - if (thd->set_query_id) + if (thd->mark_used_columns != MARK_COLUMNS_NONE) { /* - * get rw_set correct for this field so that the handler - * knows that this field is involved in the query and gets - * retrieved/updated + Get rw_set correct for this field so that the handler + knows that this field is involved in the query and gets + retrieved/updated */ Field *field_to_set= NULL; if (fld == view_ref_found) @@ -3986,13 +4009,22 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, Item *it= (*ref)->real_item(); if (it->type() == Item::FIELD_ITEM) field_to_set= ((Item_field*)it)->field; + else + { + if (thd->mark_used_columns == MARK_COLUMNS_READ) + it->walk(&Item::register_field_in_read_map, 1, (byte *) 0); + } } else field_to_set= fld; if (field_to_set) - field_to_set->table->file-> - ha_set_bit_in_rw_set(field_to_set->fieldnr, - (bool)(thd->set_query_id-1)); + { + TABLE *table= field_to_set->table; + if (thd->mark_used_columns == MARK_COLUMNS_READ) + bitmap_set_bit(table->read_set, field_to_set->field_index); + else + bitmap_set_bit(table->write_set, field_to_set->field_index); + } } } DBUG_RETURN(fld); @@ -4685,17 +4717,17 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, { TABLE *table_1= nj_col_1->table_ref->table; /* Mark field_1 used for table cache. */ - field_1->query_id= thd->query_id; - table_1->file->ha_set_bit_in_read_set(field_1->fieldnr); + bitmap_set_bit(table_1->read_set, field_1->field_index); table_1->used_keys.intersect(field_1->part_of_key); + table_1->merge_keys.merge(field_1->part_of_key); } if (field_2) { TABLE *table_2= nj_col_2->table_ref->table; /* Mark field_2 used for table cache. */ - field_2->query_id= thd->query_id; - table_2->file->ha_set_bit_in_read_set(field_2->fieldnr); + bitmap_set_bit(table_2->read_set, field_2->field_index); table_2->used_keys.intersect(field_2->part_of_key); + table_2->merge_keys.merge(field_2->part_of_key); } if (using_fields != NULL) @@ -5163,17 +5195,17 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, ****************************************************************************/ bool setup_fields(THD *thd, Item **ref_pointer_array, - List<Item> &fields, ulong set_query_id, + List<Item> &fields, enum_mark_columns mark_used_columns, List<Item> *sum_func_list, bool allow_sum_func) { reg2 Item *item; - ulong save_set_query_id= thd->set_query_id; + enum_mark_columns save_mark_used_columns= thd->mark_used_columns; nesting_map save_allow_sum_func= thd->lex->allow_sum_func; List_iterator<Item> it(fields); DBUG_ENTER("setup_fields"); - thd->set_query_id=set_query_id; - DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id)); + thd->mark_used_columns= mark_used_columns; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); if (allow_sum_func) thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; thd->where= THD::DEFAULT_WHERE; @@ -5199,8 +5231,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, (item= *(it.ref()))->check_cols(1)) { thd->lex->allow_sum_func= save_allow_sum_func; - thd->set_query_id= save_set_query_id; - DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id)); + thd->mark_used_columns= save_mark_used_columns; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); DBUG_RETURN(TRUE); /* purecov: inspected */ } if (ref) @@ -5211,8 +5243,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, thd->used_tables|= item->used_tables(); } thd->lex->allow_sum_func= save_allow_sum_func; - thd->set_query_id= save_set_query_id; - DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id)); + thd->mark_used_columns= save_mark_used_columns; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); DBUG_RETURN(test(thd->net.report_error)); } @@ -5256,7 +5288,6 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables) context name resolution contest to setup table list there from_clause Top-level list of table references in the FROM clause tables Table list (select_lex->table_list) - conds Condition of current SELECT (can be changed by VIEW) leaves List of join table leaves list (select_lex->leaf_tables) refresh It is onle refresh for subquery select_insert It is SELECT ... INSERT command @@ -5278,7 +5309,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables) bool setup_tables(THD *thd, Name_resolution_context *context, List<TABLE_LIST> *from_clause, TABLE_LIST *tables, - Item **conds, TABLE_LIST **leaves, bool select_insert) + TABLE_LIST **leaves, bool select_insert) { uint tablenr= 0; DBUG_ENTER("setup_tables"); @@ -5310,6 +5341,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, } setup_table_map(table, table_list, tablenr); table->used_keys= table->s->keys_for_keyread; + table->merge_keys.clear_all(); if (table_list->use_index) { key_map map; @@ -5483,7 +5515,6 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, } #endif - /* Update the tables used in the query based on the referenced fields. For views and natural joins this update is performed inside the loop below. @@ -5549,18 +5580,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, if ((field= field_iterator.field())) { - /* - Mark if field used before in this select. - Used by 'insert' to verify if a field name is used twice. - */ - if (field->query_id == thd->query_id) - thd->dupp_field= field; - field->query_id= thd->query_id; - field->table->file->ha_set_bit_in_read_set(field->fieldnr); - + /* Mark fields as used to allow storage engine to optimze access */ + bitmap_set_bit(field->table->read_set, field->field_index); if (table) + { table->used_keys.intersect(field->part_of_key); - + table->merge_keys.merge(field->part_of_key); + } if (tables->is_natural_join) { TABLE *field_table; @@ -5577,16 +5603,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, { thd->used_tables|= field_table->map; field_table->used_keys.intersect(field->part_of_key); + field_table->merge_keys.merge(field->part_of_key); field_table->used_fields++; } } } else - { thd->used_tables|= item->used_tables(); - item->walk(&Item::reset_query_id_processor, - (byte *)(&thd->query_id)); - } } /* In case of stored tables, all fields are considered as used, @@ -5595,10 +5618,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, For NATURAL joins, used_tables is updated in the IF above. */ if (table) - { table->used_fields= table->s->fields; - table->file->ha_set_all_bits_in_read_set(); - } } if (found) DBUG_RETURN(FALSE); @@ -5657,8 +5677,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, arena->is_conventional()) arena= 0; // For easier test - thd->set_query_id=1; - DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id)); + thd->mark_used_columns= MARK_COLUMNS_READ; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); select_lex->cond_count= 0; for (table= tables; table; table= table->next_local) @@ -5913,7 +5933,7 @@ static void mysql_rm_tmp_tables(void) if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) { - sprintf(filePath,"%s%s",tmpdir,file->name); + sprintf(filePath,"%s%c%s",tmpdir,FN_LIBCHAR,file->name); VOID(my_delete(filePath,MYF(MY_WME))); } } @@ -6159,7 +6179,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) alias alias for table db database table_name name of table - db_stat open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..) + db_stat open flags (for example ->OPEN_KEYFILE|HA_OPEN_RNDFILE..) can be 0 (example in ha_example_table) prgflag READ_ALL etc.. ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc.. |