diff options
author | Igor Babaev <igor@askmonty.org> | 2012-09-08 22:36:55 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2012-09-08 22:36:55 -0700 |
commit | 8c131f1262099d4088f3c83642bd09cd83aab148 (patch) | |
tree | 9d8351d4eb6bc7603b5225016747078038d506aa /sql | |
parent | 92eadf641590560cbc29ece9c37c7ed493a89468 (diff) | |
parent | 22de18ddcb97640f8f90c1c88d1dcd795ba1070f (diff) | |
download | mariadb-git-8c131f1262099d4088f3c83642bd09cd83aab148.tar.gz |
Merge 5.5 -> mwl248
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 12 | ||||
-rw-r--r-- | sql/item.h | 106 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 3 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 37 | ||||
-rw-r--r-- | sql/log.cc | 10 | ||||
-rw-r--r-- | sql/mysqld.cc | 12 | ||||
-rw-r--r-- | sql/opt_sum.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 38 | ||||
-rw-r--r-- | sql/sql_join_cache.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 38 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | sql/sql_time.cc | 69 | ||||
-rw-r--r-- | sql/sql_time.h | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 8 | ||||
-rw-r--r-- | sql/table.cc | 22 | ||||
-rw-r--r-- | sql/table.h | 1 |
18 files changed, 221 insertions, 152 deletions
diff --git a/sql/field.cc b/sql/field.cc index 610d56ce37a..db3854aa340 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5710,7 +5710,7 @@ bool Field_newdate::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) if (!tmp) return fuzzydate & TIME_NO_ZERO_DATE; if (!ltime->month || !ltime->day) - return !(fuzzydate & TIME_FUZZY_DATE); + return fuzzydate & TIME_NO_ZERO_IN_DATE; return 0; } diff --git a/sql/item.cc b/sql/item.cc index ac54e1925b7..4d80a153785 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -503,8 +503,8 @@ Item::Item(THD *thd, Item *item): orig_name(item->orig_name), max_length(item->max_length), name_length(item->name_length), - marker(item->marker), decimals(item->decimals), + marker(item->marker), maybe_null(item->maybe_null), in_rollup(item->in_rollup), null_value(item->null_value), @@ -7759,6 +7759,13 @@ Item* Item_cache_wrapper::get_tmp_table_item(THD *thd_arg) } +bool Item_direct_view_ref::send(Protocol *protocol, String *buffer) +{ + if (check_null_ref()) + return protocol->store_null(); + return Item_direct_ref::send(protocol, buffer); +} + /** Prepare referenced field then call usual Item_direct_ref::fix_fields . @@ -7773,6 +7780,7 @@ Item* Item_cache_wrapper::get_tmp_table_item(THD *thd_arg) bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference) { + DBUG_ASSERT(1); /* view fild reference must be defined */ DBUG_ASSERT(*ref); /* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */ @@ -9285,7 +9293,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) item->max_length, item->decimals)); fld_type= Field::field_type_merge(fld_type, get_real_type(item)); { - int item_decimals= item->decimals; + uint item_decimals= item->decimals; /* fix variable decimals which always is NOT_FIXED_DEC */ if (Field::result_merge_type(fld_type) == INT_RESULT) item_decimals= 0; diff --git a/sql/item.h b/sql/item.h index 8855996b76c..3136bb00394 100644 --- a/sql/item.h +++ b/sql/item.h @@ -618,8 +618,8 @@ public: calls. */ uint name_length; /* Length of name */ + uint decimals; int8 marker; - uint8 decimals; bool maybe_null; /* If item may be null */ bool in_rollup; /* If used in GROUP BY list of a query with ROLLUP */ @@ -3161,20 +3161,29 @@ class Item_direct_view_ref :public Item_direct_ref { Item_equal *item_equal; TABLE_LIST *view; + TABLE *null_ref_table; + + bool check_null_ref() + { + if (null_ref_table == NULL) + { + null_ref_table= view->get_real_join_table(); + } + if (null_ref_table->null_row) + { + null_value= 1; + return TRUE; + } + return FALSE; + } public: Item_direct_view_ref(Name_resolution_context *context_arg, Item **item, const char *table_name_arg, const char *field_name_arg, TABLE_LIST *view_arg) :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg), - item_equal(0), view(view_arg) {} - /* Constructor need to process subselect with temporary tables (see Item) */ - Item_direct_view_ref(THD *thd, Item_direct_ref *item) - :Item_direct_ref(thd, item), item_equal(0) {} - Item_direct_view_ref(TABLE_LIST *view_arg, Item **item, - const char *field_name_arg) - :Item_direct_ref(view_arg, item, field_name_arg), item_equal(0) - {} + item_equal(0), view(view_arg), + null_ref_table(NULL) {} bool fix_fields(THD *, Item **); bool eq(const Item *item, bool binary_cmp) const; @@ -3205,6 +3214,85 @@ public: view_arg->view_used_tables|= (*ref)->used_tables(); return 0; } + void save_val(Field *to) + { + if (check_null_ref()) + to->set_null(); + else + Item_direct_ref::save_val(to); + } + double val_real() + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_real(); + } + longlong val_int() + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_int(); + } + String *val_str(String* tmp) + { + if (check_null_ref()) + return NULL; + else + return Item_direct_ref::val_str(tmp); + } + my_decimal *val_decimal(my_decimal *tmp) + { + if (check_null_ref()) + return NULL; + else + return Item_direct_ref::val_decimal(tmp); + } + bool val_bool() + { + if (check_null_ref()) + return 0; + else + return Item_direct_ref::val_bool(); + } + bool is_null() + { + if (check_null_ref()) + return 1; + else + return Item_direct_ref::is_null(); + } + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { + if (check_null_ref()) + { + bzero((char*) ltime,sizeof(*ltime)); + return 1; + } + return Item_direct_ref::get_date(ltime, fuzzydate); + } + bool send(Protocol *protocol, String *buffer); + void save_org_in_field(Field *field) + { + if (check_null_ref()) + field->set_null(); + else + Item_direct_ref::save_val(field); + } + void save_in_result_field(bool no_conversions) + { + if (check_null_ref()) + result_field->set_null(); + else + Item_direct_ref::save_in_result_field(no_conversions); + } + + void cleanup() + { + null_ref_table= NULL; + Item_direct_ref::cleanup(); + } }; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 3648b10af3f..bc89a6c14b3 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1695,7 +1695,8 @@ count_distance: for (dist_point= collector.get_first(); dist_point; dist_point= dist_point->get_next()) { /* We only check vertices of object 2 */ - if (dist_point->shape < obj2_si) + if (dist_point->type != Gcalc_heap::nt_shape_node || + dist_point->shape < obj2_si) continue; /* if we have an edge to check */ diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 857d9bc2080..117276e488b 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -361,9 +361,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, { uint days; days= calc_daynr(l_time->year,1,1) + yearday - 1; - if (days <= 0 || days > MAX_DAY_NUMBER) + if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day)) goto err; - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (week_number >= 0 && weekday) @@ -408,9 +407,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, (weekday - 1); } - if (days <= 0 || days > MAX_DAY_NUMBER) + if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day)) goto err; - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || @@ -768,7 +766,7 @@ longlong Item_func_to_days::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day); } @@ -808,7 +806,7 @@ longlong Item_func_to_seconds::val_int() MYSQL_TIME ltime; longlong seconds; longlong days; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; seconds= ltime.hour * 3600L + ltime.minute * 60 + ltime.second; seconds=ltime.neg ? -seconds : seconds; @@ -1501,10 +1499,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) if ((fuzzy_date & TIME_NO_ZERO_DATE) && value == 0) return (null_value= 1); bzero(ltime, sizeof(MYSQL_TIME)); - get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); + if (get_date_from_daynr((long) value, <ime->year, <ime->month, + <ime->day)) + return (null_value= 1); - if ((fuzzy_date & TIME_NO_ZERO_DATE) && - (ltime->year == 0 || ltime->month == 0 || ltime->day == 0)) + if ((fuzzy_date & TIME_NO_ZERO_DATE) && ltime->year == 0) return (null_value= 1); ltime->time_type= MYSQL_TIMESTAMP_DATE; @@ -2043,7 +2042,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { INTERVAL interval; - if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE) || + if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE | TIME_NO_ZERO_IN_DATE) || get_interval_value(args[1], int_type, &interval)) return (null_value=1); @@ -2514,14 +2513,12 @@ bool Item_func_makedate::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) year= year_2000_handling(year); days= calc_daynr(year,1,1) + daynr - 1; - /* Day number from year 0 to 9999-12-31 */ - if (days >= 0 && days <= MAX_DAY_NUMBER) - { - bzero(ltime, sizeof(*ltime)); - ltime->time_type= MYSQL_TIMESTAMP_DATE; - get_date_from_daynr(days, <ime->year, <ime->month, <ime->day); - return (null_value= 0); - } + if (get_date_from_daynr(days, <ime->year, <ime->month, <ime->day)) + goto err; + ltime->time_type= MYSQL_TIMESTAMP_DATE; + ltime->neg= 0; + ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; + return (null_value= 0); err: return (null_value= 1); @@ -2615,8 +2612,8 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) if (!is_time) { - get_date_from_daynr(days,<ime->year,<ime->month,<ime->day); - if (!ltime->day) + if (get_date_from_daynr(days,<ime->year,<ime->month,<ime->day) || + !ltime->day) return (null_value= 1); return (null_value= 0); } diff --git a/sql/log.cc b/sql/log.cc index 56c07f81c9e..bcca0012a56 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3182,7 +3182,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, bytes_written+= description_event_for_queue->data_written; } if (flush_io_cache(&log_file) || - mysql_file_sync(log_file.file, MYF(MY_WME))) + mysql_file_sync(log_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; mysql_mutex_lock(&LOCK_commit_ordered); strmake(last_commit_pos_file, log_file_name, @@ -3212,7 +3212,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, strlen(log_file_name)) || my_b_write(&index_file, (uchar*) "\n", 1) || flush_io_cache(&index_file) || - mysql_file_sync(index_file.file, MYF(MY_WME))) + mysql_file_sync(index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; #ifdef HAVE_REPLICATION @@ -3302,7 +3302,7 @@ static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset) } /* The following will either truncate the file or fill the end with \n' */ if (mysql_file_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) || - mysql_file_sync(file, MYF(MY_WME))) + mysql_file_sync(file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; /* Reset data in old index cache */ @@ -3939,7 +3939,7 @@ int MYSQL_BIN_LOG::sync_purge_index_file() DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file"); if ((error= flush_io_cache(&purge_index_file)) || - (error= my_sync(purge_index_file.file, MYF(MY_WME)))) + (error= my_sync(purge_index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE)))) DBUG_RETURN(error); DBUG_RETURN(error); @@ -4556,7 +4556,7 @@ bool MYSQL_BIN_LOG::flush_and_sync(bool *synced) if (sync_period && ++sync_counter >= sync_period) { sync_counter= 0; - err= mysql_file_sync(fd, MYF(MY_WME)); + err= mysql_file_sync(fd, MYF(MY_WME|MY_SYNC_FILESIZE)); if (synced) *synced= 1; #ifndef DBUG_OFF diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1947d42fca5..a6dbb083709 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2028,13 +2028,19 @@ static struct passwd *check_user(const char *user) if (!(tmp_user_info= getpwuid(atoi(user)))) goto err; } + return tmp_user_info; /* purecov: end */ err: sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); unireg_abort(1); +#endif + return NULL; +} +static inline void allow_coredumps() +{ #ifdef PR_SET_DUMPABLE if (test_flags & TEST_CORE_ON_SIGNAL) { @@ -2042,11 +2048,9 @@ err: (void) prctl(PR_SET_DUMPABLE, 1); } #endif - -#endif - return NULL; } + static void set_user(const char *user, struct passwd *user_info_arg) { /* purecov: begin tested */ @@ -2073,6 +2077,7 @@ static void set_user(const char *user, struct passwd *user_info_arg) sql_perror("setuid"); unireg_abort(1); } + allow_coredumps(); #endif /* purecov: end */ } @@ -2092,6 +2097,7 @@ static void set_effective_user(struct passwd *user_info_arg) sql_perror("setreuid"); unireg_abort(1); } + allow_coredumps(); #endif } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index cbec039b3e4..fa3a07b72c5 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -791,7 +791,7 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, { /* Update endpoints for MAX/MIN, see function comment. */ Item *value= args[between && max_fl ? 2 : 1]; - store_val_in_field(part->field, value, CHECK_FIELD_IGNORE); + value->save_in_field_no_warnings(part->field, 1); if (part->null_bit) *key_ptr++= (uchar) test(part->field->is_null()); part->field->get_key_image(key_ptr, part->length, Field::itRAW); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f3e180553f0..f753a67ea38 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3903,34 +3903,22 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry) { char query_buf[2*FN_REFLEN + 21]; String query(query_buf, sizeof(query_buf), system_charset_info); + query.length(0); - if (query.ptr()) - { - /* this DELETE FROM is needed even with row-based binlogging */ - query.append("DELETE FROM "); - append_identifier(thd, &query, share->db.str, share->db.length); - query.append("."); - append_identifier(thd, &query, share->table_name.str, + query.append("DELETE FROM "); + append_identifier(thd, &query, share->db.str, share->db.length); + query.append("."); + append_identifier(thd, &query, share->table_name.str, share->table_name.length); - int errcode= query_error_code(thd, TRUE); - if (thd->binlog_query(THD::STMT_QUERY_TYPE, - query.ptr(), query.length(), - FALSE, FALSE, FALSE, errcode)) - return TRUE; - } - else - { - /* - As replication is maybe going to be corrupted, we need to warn the - DBA on top of warning the client (which will automatically be done - because of MYF(MY_WME) in my_malloc() above). - */ - sql_print_error("When opening HEAP table, could not allocate memory " - "to write 'DELETE FROM %`s.%`s' to the binary log", - share->db.str, share->table_name.str); - delete entry->triggers; + + /* + we bypass thd->binlog_query() here, + as it does a lot of extra work, that is simply wrong in this case + */ + Query_log_event qinfo(thd, query.ptr(), query.length(), + FALSE, TRUE, TRUE, 0); + if (mysql_bin_log.write(&qinfo)) return TRUE; - } } } return FALSE; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index f6fc2ebfd1e..50d3bbfea26 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -3876,8 +3876,9 @@ int JOIN_TAB_SCAN_MRR::next() If a record in in an incremental cache contains no fields then the association for the last record in cache will be equal to cache->end_pos */ - DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) && - (uchar *) (*ptr) <= cache->end_pos); + DBUG_ASSERT((!(mrr_mode & HA_MRR_NO_ASSOCIATION))? + (cache->buff <= (uchar *) (*ptr) && + (uchar *) (*ptr) <= cache->end_pos): TRUE); if (join_tab->table->vfield) update_virtual_fields(join->thd, join_tab->table); } @@ -4543,7 +4544,7 @@ bool JOIN_CACHE_BKAH::prepare_look_for_matches(bool skip_last) { last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0; if (no_association && - (curr_matching_chain= get_matching_chain_by_join_key())) + !(curr_matching_chain= get_matching_chain_by_join_key())) return 1; last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain); return 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 33991851218..8865705feb9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8031,37 +8031,6 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, } /** - This function is only called for const items on fields which are keys. - - @return - returns 1 if there was some conversion made when the field was stored. -*/ - -bool -store_val_in_field(Field *field, Item *item, enum_check_fields check_flag) -{ - bool error; - TABLE *table= field->table; - THD *thd= table->in_use; - ha_rows cuted_fields=thd->cuted_fields; - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, - table->write_set); - - /* - we should restore old value of count_cuted_fields because - store_val_in_field can be called from mysql_insert - with select_insert, which make count_cuted_fields= 1 - */ - enum_check_fields old_count_cuted_fields= thd->count_cuted_fields; - thd->count_cuted_fields= check_flag; - error= item->save_in_field(field, 1); - thd->count_cuted_fields= old_count_cuted_fields; - dbug_tmp_restore_column_map(table->write_set, old_map); - return error || cuted_fields != thd->cuted_fields; -} - - -/** @details Initialize a JOIN as a query execution plan that accesses a single table via a table scan. @@ -17707,7 +17676,7 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item) field->real_type() != MYSQL_TYPE_VARCHAR && (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0)) { - return !store_val_in_field(field, right_item, CHECK_FIELD_WARN); + return !right_item->save_in_field_no_warnings(field, 1); } } } @@ -21589,11 +21558,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, length= (longlong10_to_str(key_len, keylen_str_buf, 10) - keylen_str_buf); tmp3.append(keylen_str_buf, length, cs); -/*<<<<<<< TREE - } - if ((is_hj || tab->type==JT_RANGE || tab->type == JT_INDEX_MERGE) && - tab->select && tab->select->quick) -=======*/ } if (tab->type != JT_CONST && tab->select && tab->select->quick) tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3); diff --git a/sql/sql_select.h b/sql/sql_select.h index be5f523a7e2..118a684ab62 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1430,7 +1430,6 @@ typedef struct st_select_check { extern const char *join_type_str[]; /* Extern functions in sql_select.cc */ -bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag); void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, List<Item> &fields, bool reset_with_sum_func); bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, @@ -1504,6 +1503,7 @@ public: enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields; ulonglong sql_mode= thd->variables.sql_mode; thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); + thd->variables.sql_mode|= MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 5972c8918ba..5c0471fdfaa 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -25,9 +25,9 @@ #include <m_ctype.h> - /* Some functions to calculate dates */ +#define MAX_DAY_NUMBER 3652424L -#ifndef TESTTIME + /* Some functions to calculate dates */ /* Name description of interval names used in statements. @@ -147,46 +147,42 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) /* Change a daynr to year, month and day */ /* Daynr 0 is returned as date 00.00.00 */ -void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month, +bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month, uint *ret_day) { uint year,temp,leap_day,day_of_year,days_in_year; uchar *month_pos; DBUG_ENTER("get_date_from_daynr"); - if (daynr <= 365L || daynr >= 3652500) - { /* Fix if wrong daynr */ - *ret_year= *ret_month = *ret_day =0; + if (daynr < 365 || daynr > MAX_DAY_NUMBER) + DBUG_RETURN(1); + + year= (uint) (daynr*100 / 36525L); + temp=(((year-1)/100+1)*3)/4; + day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp; + while (day_of_year > (days_in_year= calc_days_in_year(year))) + { + day_of_year-=days_in_year; + (year)++; } - else + leap_day=0; + if (days_in_year == 366) { - year= (uint) (daynr*100 / 36525L); - temp=(((year-1)/100+1)*3)/4; - day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp; - while (day_of_year > (days_in_year= calc_days_in_year(year))) + if (day_of_year > 31+28) { - day_of_year-=days_in_year; - (year)++; + day_of_year--; + if (day_of_year == 31+28) + leap_day=1; /* Handle leapyears leapday */ } - leap_day=0; - if (days_in_year == 366) - { - if (day_of_year > 31+28) - { - day_of_year--; - if (day_of_year == 31+28) - leap_day=1; /* Handle leapyears leapday */ - } - } - *ret_month=1; - for (month_pos= days_in_month ; - day_of_year > (uint) *month_pos ; - day_of_year-= *(month_pos++), (*ret_month)++) - ; - *ret_year=year; - *ret_day=day_of_year+leap_day; } - DBUG_VOID_RETURN; + *ret_month=1; + for (month_pos= days_in_month ; + day_of_year > (uint) *month_pos ; + day_of_year-= *(month_pos++), (*ret_month)++) + ; + *ret_year=year; + *ret_day=day_of_year+leap_day; + DBUG_RETURN(0); } /* Functions to handle periods */ @@ -842,7 +838,6 @@ void make_truncated_value_warning(THD *thd, /* Daynumber from year 0 to 9999-12-31 */ -#define MAX_DAY_NUMBER 3652424L #define COMBINE(X) \ (((((X)->day * 24LL + (X)->hour) * 60LL + \ (X)->minute) * 60LL + (X)->second)*1000000LL + \ @@ -909,19 +904,18 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, daynr= usec; /* Day number from year 0 to 9999-12-31 */ - if ((ulonglong) daynr > MAX_DAY_NUMBER) + if (get_date_from_daynr((long) daynr, <ime->year, <ime->month, + <ime->day)) goto invalid_date; - get_date_from_daynr((long) daynr, <ime->year, <ime->month, - <ime->day); break; } case INTERVAL_WEEK: period= (calc_daynr(ltime->year,ltime->month,ltime->day) + sign * (long) interval.day); /* Daynumber from year 0 to 9999-12-31 */ - if ((ulong) period > MAX_DAY_NUMBER) + if (get_date_from_daynr((long) period,<ime->year,<ime->month, + <ime->day)) goto invalid_date; - get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day); break; case INTERVAL_YEAR: ltime->year+= sign * (long) interval.year; @@ -1071,4 +1065,3 @@ int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b) return 0; } -#endif diff --git a/sql/sql_time.h b/sql/sql_time.h index 026a15cb796..c1a75bb2ad3 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -33,7 +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 get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); +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, MYSQL_TIME *l_time, ulonglong fuzzydate); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f2b6c5c9f92..d8254c9dbdb 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -406,7 +406,7 @@ int mysql_update(THD *thd, table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); select= make_select(table, 0, 0, conds, 0, &error); - if (error || !limit || + if (error || !limit || thd->is_error() || (select && select->check_quick(thd, safe_update, limit))) { delete select; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 48d2406c559..add400c37b3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5877,9 +5877,9 @@ attribute: NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; } | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; } | DEFAULT now_or_signed_literal { Lex->default_value=$2; } - | ON UPDATE_SYM NOW_SYM opt_time_precision + | ON UPDATE_SYM NOW_SYM optional_braces { - Item *item= new (YYTHD->mem_root) Item_func_now_local($4); + Item *item= new (YYTHD->mem_root) Item_func_now_local(6); if (item == NULL) MYSQL_YYABORT; Lex->on_update_value= item; @@ -5971,9 +5971,9 @@ type_with_opt_collate: now_or_signed_literal: - NOW_SYM opt_time_precision + NOW_SYM optional_braces { - $$= new (YYTHD->mem_root) Item_func_now_local($2); + $$= new (YYTHD->mem_root) Item_func_now_local(6); if ($$ == NULL) MYSQL_YYABORT; } diff --git a/sql/table.cc b/sql/table.cc index 1fa5069a07e..9fcf5879703 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4956,6 +4956,28 @@ void TABLE_LIST::set_check_materialized() } } +TABLE *TABLE_LIST::get_real_join_table() +{ + TABLE_LIST *tbl= this; + while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL) + { + if (tbl->view == NULL && tbl->derived == NULL) + break; + /* we do not support merging of union yet */ + DBUG_ASSERT(tbl->view == NULL || + tbl->view->select_lex.next_select() == NULL); + DBUG_ASSERT(tbl->derived == NULL || + tbl->derived->first_select()->next_select() == NULL); + + if (tbl->table) + table= tbl->table; + tbl= (tbl->view != NULL ? + tbl->view->select_lex.get_table_list() : + tbl->derived->first_select()->get_table_list()); + } + return tbl->table; +} + Natural_join_column::Natural_join_column(Field_translator *field_param, TABLE_LIST *tab) diff --git a/sql/table.h b/sql/table.h index e52a1858916..8e18f065d79 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1949,6 +1949,7 @@ struct TABLE_LIST TABLE_LIST *find_underlying_table(TABLE *table); TABLE_LIST *first_leaf_for_name_resolution(); TABLE_LIST *last_leaf_for_name_resolution(); + TABLE *get_real_join_table(); bool is_leaf_for_name_resolution(); inline TABLE_LIST *top_table() { return belong_to_view ? belong_to_view : this; } |