summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc61
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)));
/*