diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 3 | ||||
-rw-r--r-- | sql/item_create.cc | 16 | ||||
-rw-r--r-- | sql/item_create.h | 3 | ||||
-rw-r--r-- | sql/item_func.cc | 45 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 6 | ||||
-rw-r--r-- | sql/my_decimal.h | 20 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 5 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.h | 7 | ||||
-rw-r--r-- | sql/sql_update.cc | 5 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 |
13 files changed, 102 insertions, 27 deletions
diff --git a/sql/field.cc b/sql/field.cc index b2def4ca8d2..d2e72371bc1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8426,8 +8426,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, case FIELD_TYPE_NULL: break; case FIELD_TYPE_NEWDECIMAL: - if (!fld_length && !decimals) - length= 10; + my_decimal_trim(&length, &decimals); if (length > DECIMAL_MAX_PRECISION) { my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name, diff --git a/sql/item_create.cc b/sql/item_create.cc index c1a81da0285..c4008d36aae 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -445,11 +445,13 @@ Item *create_load_file(Item* a) } -Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, +Item *create_func_cast(Item *a, Cast_target cast_type, + const char *c_len, const char *c_dec, CHARSET_INFO *cs) { Item *res; - int tmp_len; + ulong len; + uint dec; LINT_INIT(res); switch (cast_type) { @@ -460,15 +462,18 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, case ITEM_CAST_TIME: res= new Item_time_typecast(a); break; case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break; case ITEM_CAST_DECIMAL: - tmp_len= (len>0) ? len : 10; - if (tmp_len < dec) + len= c_len ? atoi(c_len) : 0; + dec= c_dec ? atoi(c_dec) : 0; + my_decimal_trim(&len, &dec); + if (len < dec) { my_error(ER_M_BIGGER_THAN_D, MYF(0), ""); return 0; } - res= new Item_decimal_typecast(a, tmp_len, dec ? dec : 2); + res= new Item_decimal_typecast(a, len, dec); break; case ITEM_CAST_CHAR: + len= c_len ? atoi(c_len) : -1; res= new Item_char_typecast(a, len, cs ? cs : current_thd->variables.collation_connection); break; @@ -476,6 +481,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, return res; } + Item *create_func_is_free_lock(Item* a) { current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); diff --git a/sql/item_create.h b/sql/item_create.h index 2ff849263c6..46b209b3e49 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -27,7 +27,8 @@ Item *create_func_bit_length(Item* a); Item *create_func_coercibility(Item* a); Item *create_func_ceiling(Item* a); Item *create_func_char_length(Item* a); -Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, +Item *create_func_cast(Item *a, Cast_target cast_type, + const char *len, const char *dec, CHARSET_INFO *cs); Item *create_func_connection_id(void); Item *create_func_conv(Item* a, Item *b, Item *c); diff --git a/sql/item_func.cc b/sql/item_func.cc index 7a31b564502..c0a9647e382 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1050,18 +1050,61 @@ longlong Item_decimal_typecast::val_int() my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec) { my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf); + bool sign; + uint precision; + if ((null_value= args[0]->null_value)) return NULL; my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec); + sign= dec->sign(); + if (unsigned_flag) + { + if (sign) + { + my_decimal_set_zero(dec); + goto err; + } + } + precision= my_decimal_length_to_precision(max_length, + decimals, unsigned_flag); + if (precision - decimals < (uint) my_decimal_intg(dec)) + { + max_my_decimal(dec, precision, decimals); + dec->sign(sign); + goto err; + } + return dec; + +err: + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_WARN_DATA_OUT_OF_RANGE, + ER(ER_WARN_DATA_OUT_OF_RANGE), + name, 1); return dec; } void Item_decimal_typecast::print(String *str) { + char len_buf[20*3 + 1]; + char *end; + + uint precision= my_decimal_length_to_precision(max_length, decimals, + unsigned_flag); str->append(STRING_WITH_LEN("cast(")); args[0]->print(str); - str->append(STRING_WITH_LEN(" as decimal)")); + str->append(STRING_WITH_LEN(" as decimal(")); + + end=int10_to_str(precision, len_buf,10); + str->append(len_buf, (uint32) (end - len_buf)); + + str->append(','); + + end=int10_to_str(decimals, len_buf,10); + str->append(len_buf, (uint32) (end - len_buf)); + + str->append(')'); + str->append(')'); } diff --git a/sql/item_func.h b/sql/item_func.h index 0443e394585..7ec3c0b00c4 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -331,8 +331,8 @@ class Item_decimal_typecast :public Item_func public: Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a) { - max_length= len + 2; decimals= dec; + max_length= my_decimal_precision_to_length(len, dec, unsigned_flag); } String *val_str(String *str); double val_real(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ccd361dba99..48b82e3cde6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1829,6 +1829,8 @@ int subselect_single_select_engine::exec() if (cond_guard && !*cond_guard) { /* Change the access method to full table scan */ + tab->save_read_first_record= tab->read_first_record; + tab->save_read_record= tab->read_record.read_record; tab->read_first_record= init_read_record_seq; tab->read_record.record= tab->table->record[0]; tab->read_record.thd= join->thd; @@ -1849,8 +1851,8 @@ int subselect_single_select_engine::exec() JOIN_TAB *tab= *ptab; tab->read_record.record= 0; tab->read_record.ref_length= 0; - tab->read_first_record= join_read_always_key_or_null; - tab->read_record.read_record= join_read_next_same_or_null; + tab->read_first_record= tab->save_read_first_record; + tab->read_record.read_record= tab->save_read_record; } executed= 1; thd->where= save_where; diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 45270150d22..9558b00f0cf 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -387,5 +387,25 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) return decimal_cmp((decimal_t*) a, (decimal_t*) b); } + +inline +int my_decimal_intg(const my_decimal *a) +{ + return decimal_intg((decimal_t*) a); +} + + +inline +void my_decimal_trim(ulong *precision, uint *scale) +{ + if (!(*precision) && !(*scale)) + { + *precision= 10; + *scale= 0; + return; + } +} + + #endif /*my_decimal_h*/ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f1d86224adb..5f54bc2b43b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1258,7 +1258,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) DBUG_ASSERT(info->update_fields->elements == info->update_values->elements); if (fill_record_n_invoke_before_triggers(thd, *info->update_fields, - *info->update_values, 0, + *info->update_values, + info->ignore, table->triggers, TRG_EVENT_UPDATE)) goto before_trg_err; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1ec65743b0f..90361f8ff0d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1164,8 +1164,9 @@ static int mysql_test_update(Prepared_statement *stmt, goto error; #ifndef NO_EMBEDDED_ACCESS_CHECKS - /* TABLE_LIST contain right privilages request */ - want_privilege= table_list->grant.want_privilege; + /* Force privilege re-checking for views after they have been opened. */ + want_privilege= (table_list->view ? UPDATE_ACL : + table_list->grant.want_privilege); #endif if (mysql_prepare_update(thd, table_list, &select->where, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3a480c01ac1..967322600a7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4189,7 +4189,7 @@ best_access_path(JOIN *join, !(s->quick && best_key && s->quick->index == best_key->key && // (2) best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2) !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) - ! s->table->used_keys.is_clear_all() && best_key) && // (3) + ! s->table->used_keys.is_clear_all() && best_key && !s->quick) &&// (3) !(s->table->force_index && best_key && !s->quick)) // (4) { // Check full join ha_rows rnd_records= s->found_records; diff --git a/sql/sql_select.h b/sql/sql_select.h index 5081366c10b..3cdd265df9a 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -159,6 +159,13 @@ typedef struct st_join_table { Read_record_func read_first_record; Next_select_func next_select; READ_RECORD read_record; + /* + Currently the following two fields are used only for a [NOT] IN subquery + if it is executed by an alternative full table scan when the left operand of + the subquery predicate is evaluated to NULL. + */ + Read_record_func save_read_first_record;/* to save read_first_record */ + int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */ double worst_seeks; key_map const_keys; /* Keys with constant part */ key_map checked_keys; /* Keys checked in find_best */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e17c71ae541..222e33345cc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -173,8 +173,9 @@ int mysql_update(THD *thd, table->quick_keys.clear_all(); #ifndef NO_EMBEDDED_ACCESS_CHECKS - /* TABLE_LIST contain right privilages request */ - want_privilege= table_list->grant.want_privilege; + /* Force privilege re-checking for views after they have been opened. */ + want_privilege= (table_list->view ? UPDATE_ACL : + table_list->grant.want_privilege); #endif if (mysql_prepare_update(thd, table_list, &conds, order_num, order)) DBUG_RETURN(1); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4a50a602121..0bb5f6a5e25 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4699,15 +4699,12 @@ simple_expr: | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } | BINARY simple_expr %prec NEG { - $$= create_func_cast($2, ITEM_CAST_CHAR, -1, 0, &my_charset_bin); + $$= create_func_cast($2, ITEM_CAST_CHAR, NULL, NULL, &my_charset_bin); } | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_cast($3, $5, - lex->length ? atoi(lex->length) : -1, - lex->dec ? atoi(lex->dec) : 0, - lex->charset); + $$= create_func_cast($3, $5, lex->length, lex->dec, lex->charset); if (!$$) MYSQL_YYABORT; } @@ -4715,10 +4712,7 @@ simple_expr: { $$= new Item_func_case(* $3, $2, $4 ); } | CONVERT_SYM '(' expr ',' cast_type ')' { - $$= create_func_cast($3, $5, - Lex->length ? atoi(Lex->length) : -1, - Lex->dec ? atoi(Lex->dec) : 0, - Lex->charset); + $$= create_func_cast($3, $5, Lex->length, Lex->dec, Lex->charset); if (!$$) MYSQL_YYABORT; } |