diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0874ee16127..c0b69ac7b54 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -22,6 +22,7 @@ #include "sp_head.h" #include "sp.h" #include "sql_trigger.h" +#include "sql_handler.h" #include <m_ctype.h> #include <my_dir.h> #include <hash.h> @@ -1381,10 +1382,10 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) bool found_old_table= 0; TABLE *table= *table_ptr; DBUG_ENTER("close_thread_table"); - DBUG_ASSERT(table->key_read == 0); - DBUG_ASSERT(!table->file || table->file->inited == handler::NONE); DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str, table->s->table_name.str, (long) table)); + DBUG_ASSERT(table->key_read == 0); + DBUG_ASSERT(!table->file || table->file->inited == handler::NONE); if (table->file) { @@ -3032,13 +3033,19 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->pos_in_table_list= table_list; table_list->updatable= 1; // It is not derived table nor non-updatable VIEW table->clear_column_bitmaps(); -#if !defined(DBUG_OFF) && !defined(HAVE_valgrind) /* Fill record with random values to find bugs where we access fields without first reading them. */ - bfill(table->record[0], table->s->reclength, 254); -#endif + TRASH(table->record[0], table->s->reclength); + /* + Initialize the null marker bits, to ensure that if we are doing a read + of only selected columns (like in keyread), all null markers are + initialized. + */ + bfill(table->record[0], table->s->null_bytes, 255); + bfill(table->record[1], table->s->null_bytes, 255); + DBUG_ASSERT(table->key_read == 0); DBUG_RETURN(table); } @@ -6427,12 +6434,21 @@ find_field_in_tables(THD *thd, Item_ident *item, sub query as dependent on the outer query */ if (current_sel != last_select) + { mark_select_range_as_dependent(thd, last_select, current_sel, found, *ref, item); + if (item->can_be_depended) + { + DBUG_ASSERT((*ref) == (Item*)item); + current_sel->register_dependency_item(last_select, ref); + } + } } return found; } } + else + item->can_be_depended= TRUE; if (db && lower_case_table_names) { @@ -7496,13 +7512,11 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num) { - if (!wild_num) - return(0); - Item *item; List_iterator<Item> it(fields); Query_arena *arena, backup; DBUG_ENTER("setup_wild"); + DBUG_ASSERT(wild_num != 0); /* Don't use arena if we are not in prepared statements or stored procedures @@ -7591,6 +7605,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, List_iterator<Item> it(fields); bool save_is_item_list_lookup; DBUG_ENTER("setup_fields"); + DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array)); thd->mark_used_columns= mark_used_columns; DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); @@ -7825,10 +7840,11 @@ bool setup_tables_and_check_access(THD *thd, { TABLE_LIST *leaves_tmp= NULL; bool first_table= true; + DBUG_ENTER("setup_tables_and_check_access"); if (setup_tables(thd, context, from_clause, tables, &leaves_tmp, select_insert)) - return TRUE; + DBUG_RETURN(TRUE); if (leaves) *leaves= leaves_tmp; @@ -7840,11 +7856,11 @@ bool setup_tables_and_check_access(THD *thd, want_access, leaves_tmp, FALSE)) { tables->hide_view_error(thd); - return TRUE; + DBUG_RETURN(TRUE); } first_table= 0; } - return FALSE; + DBUG_RETURN(FALSE); } @@ -8147,6 +8163,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, SELECT_LEX *select_lex= thd->lex->current_select; Query_arena *arena= thd->stmt_arena, backup; TABLE_LIST *table= NULL; // For HP compilers + TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest; /* it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX which belong to LEX, i.e. most up SELECT) will be updated by @@ -8177,13 +8194,19 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, goto err_no_arena; } + thd->thd_marker.emb_on_expr_nest= (TABLE_LIST*)1; if (*conds) { thd->where="where clause"; + DBUG_EXECUTE("where", + print_where(*conds, + "WHERE in setup_conds", + QT_ORDINARY);); if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) || (*conds)->check_cols(1)) goto err_no_arena; } + thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest; /* Apply fix_fields() to all ON clauses at all levels of nesting, @@ -8199,6 +8222,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, if (embedded->on_expr) { /* Make a join an a expression */ + thd->thd_marker.emb_on_expr_nest= embedded; thd->where="on clause"; if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(thd, &embedded->on_expr)) || @@ -8223,6 +8247,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, } } } + thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest; if (!thd->stmt_arena->is_conventional()) { @@ -8421,6 +8446,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields, ptr pointer on pointer to record values list of fields ignore_errors TRUE if we should ignore errors + use_value forces usage of value of the items instead of result NOTE fill_record() may set table->auto_increment_field_not_null and a @@ -8433,7 +8459,8 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields, */ bool -fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors) +fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors, + bool use_value) { List_iterator_fast<Item> v(values); List<TABLE> tbl_list; @@ -8480,8 +8507,12 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors) field->field_name, table->s->table_name.str); thd->abort_on_warning= abort_on_warning_saved; } - if (value->save_in_field(field, 0) < 0) - goto err; + + if (use_value) + value->save_val(field); + else + if (value->save_in_field(field, 0) < 0) + goto err; } /* Update virtual fields*/ thd->abort_on_warning= FALSE; @@ -8527,7 +8558,7 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr, enum trg_event_type event) { bool result; - result= (fill_record(thd, ptr, values, ignore_errors) || + result= (fill_record(thd, ptr, values, ignore_errors, FALSE) || (triggers && triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE))); /* |