diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-12-15 15:57:26 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-12-15 15:57:26 +0100 |
commit | 6bf10fac445d73fb796d4863612c87bff5f28b66 (patch) | |
tree | 4d51e193684163c21e47e9de6536cd8dae0613eb /sql | |
parent | 8efaff4959efe32ff9bc47c1bf1710cfe9ab21b5 (diff) | |
parent | 39a8d7965d912d8fb32436735449ce04e85583d1 (diff) | |
download | mariadb-git-6bf10fac445d73fb796d4863612c87bff5f28b66.tar.gz |
5.5 merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 7 | ||||
-rw-r--r-- | sql/item_func.h | 5 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/opt_table_elimination.cc | 15 | ||||
-rw-r--r-- | sql/sql_base.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 5 | ||||
-rw-r--r-- | sql/sql_time.cc | 19 | ||||
-rw-r--r-- | sql/sql_time.h | 1 | ||||
-rw-r--r-- | sql/sql_union.cc | 18 | ||||
-rw-r--r-- | sql/table.cc | 6 |
12 files changed, 72 insertions, 16 deletions
diff --git a/sql/item.h b/sql/item.h index ea17668d47d..113e8bdcb9c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3307,13 +3307,16 @@ class Item_direct_view_ref :public Item_direct_ref TABLE_LIST *view; TABLE *null_ref_table; +#define NO_NULL_TABLE (reinterpret_cast<TABLE *>(0x1)) + bool check_null_ref() { if (null_ref_table == NULL) { - null_ref_table= view->get_real_join_table(); + if (!(null_ref_table= view->get_real_join_table())) + null_ref_table= NO_NULL_TABLE; } - if (null_ref_table->null_row) + if (null_ref_table != NO_NULL_TABLE && null_ref_table->null_row) { null_value= 1; return TRUE; diff --git a/sql/item_func.h b/sql/item_func.h index f4be9a14fe3..384a6b535df 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -166,7 +166,10 @@ public: Item **item, uint nitems); inline bool get_arg0_time(MYSQL_TIME *ltime) { - return (null_value=args[0]->get_time(ltime)); + null_value= args[0]->get_time(ltime); + DBUG_ASSERT(null_value || + ltime->time_type != MYSQL_TIMESTAMP_TIME || ltime->day == 0); + return null_value; } bool is_null() { update_null_value(); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 425008ab43b..a3652ebf16e 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2142,6 +2142,10 @@ longlong Item_extract::val_int() return 0; neg= ltime.neg ? -1 : 1; + DBUG_ASSERT(ltime.time_type != MYSQL_TIMESTAMP_TIME || ltime.day == 0); + if (ltime.time_type == MYSQL_TIMESTAMP_TIME) + time_to_daytime_interval(<ime); + switch (int_type) { case INTERVAL_YEAR: return ltime.year; case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1d4002df60f..4e6646feead 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1914,7 +1914,9 @@ void clean_up(bool print_message) delete binlog_filter; delete global_rpl_filter; end_ssl(); +#ifndef EMBEDDED_LIBRARY vio_end(); +#endif /*!EMBEDDED_LIBRARY*/ #if defined(ENABLED_DEBUG_SYNC) /* End the debug sync facility. See debug_sync.cc. */ debug_sync_end(); diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 4a10d402fac..9f304ad043b 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -609,6 +609,21 @@ void eliminate_tables(JOIN *join) /* Find the tables that are referred to from WHERE/HAVING */ used_tables= (join->conds? join->conds->used_tables() : 0) | (join->having? join->having->used_tables() : 0); + + /* + For "INSERT ... SELECT ... ON DUPLICATE KEY UPDATE column = val" + we should also take into account tables mentioned in "val". + */ + if (join->thd->lex->sql_command == SQLCOM_INSERT_SELECT && + join->select_lex == &thd->lex->select_lex) + { + List_iterator<Item> val_it(thd->lex->value_list); + while ((item= val_it++)) + { + DBUG_ASSERT(item->fixed); + used_tables |= item->used_tables(); + } + } /* Add tables referred to from the select list */ List_iterator<Item> it(join->fields_list); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3f4be0da25d..6e0a852601c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6635,9 +6635,9 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, else { if (thd->mark_used_columns == MARK_COLUMNS_READ) - it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); + it->walk(&Item::register_field_in_read_map, 0, (uchar *) 0); else - it->walk(&Item::register_field_in_write_map, 1, (uchar *) 0); + it->walk(&Item::register_field_in_write_map, 0, (uchar *) 0); } } else diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 77b03f32105..4ce9c3828d7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -721,7 +721,7 @@ public: void print(String *str, enum_query_type query_type); bool add_fake_select_lex(THD *thd); - void init_prepare_fake_select_lex(THD *thd); + void init_prepare_fake_select_lex(THD *thd, bool first_execution); inline bool is_prepared() { return prepared; } bool change_result(select_result_interceptor *result, select_result_interceptor *old_result); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 77f79783db0..54f9881fe45 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11444,17 +11444,18 @@ void JOIN::cleanup(bool full) tabs_kind= WALK_EXECUTION_TABS; if (table_count) { - for (tab= first_breadth_first_tab(this, tabs_kind); tab; + for (tab= first_breadth_first_tab(this, tabs_kind); tab; tab= next_breadth_first_tab(this, tabs_kind, tab)) { tab->cleanup(); } } cleaned= true; + } else { - for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab; + for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) { if (tab->table) diff --git a/sql/sql_time.cc b/sql/sql_time.cc index e9fda9be0b1..cf3cdd61000 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -1085,3 +1085,22 @@ int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b) return 0; } + +/* + Convert a TIME value to DAY-TIME interval, e.g. for extraction: + EXTRACT(DAY FROM x), EXTRACT(HOUR FROM x), etc. + Moves full days from ltime->hour to ltime->day. + Note, time_type is set to MYSQL_TIMESTAMP_NONE, to make sure that + the structure is not used for anything else other than extraction: + non-extraction TIME functions expect zero day value! +*/ +void time_to_daytime_interval(MYSQL_TIME *ltime) +{ + DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_TIME); + DBUG_ASSERT(ltime->year == 0); + DBUG_ASSERT(ltime->month == 0); + DBUG_ASSERT(ltime->day == 0); + ltime->day= ltime->hour / 24; + ltime->hour%= 24; + ltime->time_type= MYSQL_TIMESTAMP_NONE; +} diff --git a/sql/sql_time.h b/sql/sql_time.h index f8b1e950b14..ab8f0e0b962 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -33,6 +33,7 @@ typedef struct st_known_date_time_format KNOWN_DATE_TIME_FORMAT; ulong convert_period_to_month(ulong period); ulong convert_month_to_period(ulong month); +void time_to_daytime_interval(MYSQL_TIME *l_time); bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code); bool str_to_time_with_warn(CHARSET_INFO *cs, const char *str, uint length, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 864f5a8d91a..76857b58234 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -193,13 +193,15 @@ void select_union::cleanup() SYNOPSIS st_select_lex_unit::init_prepare_fake_select_lex() thd - thread handler + first_execution - TRUE at the first execution of the union RETURN options of SELECT */ void -st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) +st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg, + bool first_execution) { thd_arg->lex->current_select= fake_select_lex; fake_select_lex->table_list.link_in_list(&result_table_list, @@ -207,7 +209,13 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) fake_select_lex->context.table_list= fake_select_lex->context.first_name_resolution_table= fake_select_lex->get_table_list(); - if (!fake_select_lex->first_execution) + /* + The flag fake_select_lex->first_execution indicates whether this is + called at the first execution of the statement, while first_execution + shows whether this is called at the first execution of the union that + may form just a subselect. + */ + if (!fake_select_lex->first_execution && first_execution) { for (ORDER *order= global_parameters->order_list.first; order; @@ -481,7 +489,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { /* Validate the global parameters of this union */ - init_prepare_fake_select_lex(thd); + init_prepare_fake_select_lex(thd, TRUE); /* Should be done only once (the only item_list per statement) */ DBUG_ASSERT(fake_select_lex->join == 0); if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->variables.option_bits, @@ -622,6 +630,7 @@ bool st_select_lex_unit::exec() SELECT_LEX *select_cursor=first_select(); ulonglong add_rows=0; ha_rows examined_rows= 0; + bool first_execution= !executed; DBUG_ENTER("st_select_lex_unit::exec"); bool was_executed= executed; @@ -644,6 +653,7 @@ bool st_select_lex_unit::exec() { ha_rows records_at_start= 0; thd->lex->current_select= sl; + fake_select_lex->uncacheable|= sl->uncacheable; { set_limit(sl); @@ -750,7 +760,7 @@ bool st_select_lex_unit::exec() if (!thd->is_fatal_error) // Check if EOM { set_limit(global_parameters); - init_prepare_fake_select_lex(thd); + init_prepare_fake_select_lex(thd, first_execution); JOIN *join= fake_select_lex->join; if (!join) { diff --git a/sql/table.cc b/sql/table.cc index 7adf4f4831b..f6bea7221ce 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5016,10 +5016,8 @@ TABLE *TABLE_LIST::get_real_join_table() */ for (TABLE_LIST *t= ti++; t; t= ti++) tbl= t; - /* - It is impossible that the list is empty - so tbl can't be NULL after above loop. - */ + if (!tbl) + return NULL; // view/derived with no tables if (!tbl->nested_join) break; /* go deeper if we've found nested join */ |