diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 26 | ||||
-rw-r--r-- | sql/field.h | 6 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item.h | 10 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 19 | ||||
-rw-r--r-- | sql/sql_insert.h | 1 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 14 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 6 | ||||
-rw-r--r-- | sql/table.cc | 10 | ||||
-rw-r--r-- | sql/table.h | 13 |
12 files changed, 73 insertions, 40 deletions
diff --git a/sql/field.cc b/sql/field.cc index 7d269ab004b..777312a15c4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -964,7 +964,8 @@ Type_handler::aggregate_for_result_traditional(const Type_handler *a, } -bool Field::check_assignability_from(const Type_handler *from) const +bool Field::check_assignability_from(const Type_handler *from, + bool ignore) const { /* Using type_handler_for_item_field() here to get the data type handler @@ -982,9 +983,26 @@ bool Field::check_assignability_from(const Type_handler *from) const type_handler_for_item_field()); if (th.aggregate_for_result(from->type_handler_for_item_field())) { - my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), - type_handler()->name().ptr(), from->name().ptr(), "SET"); - return true; + bool error= !ignore && get_thd()->is_strict_mode(); + /* + Display fully qualified column name for table columns. + Display non-qualified names for other things, + e.g. SP variables, SP return values, SP and CURSOR parameters. + */ + if (table->s->db.str && table->s->table_name.str) + my_printf_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, + "Cannot cast '%s' as '%s' in assignment of %`s.%`s.%`s", + MYF(error ? 0 : ME_WARNING), + from->name().ptr(), type_handler()->name().ptr(), + table->s->db.str, table->s->table_name.str, + field_name.str); + else + my_printf_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, + "Cannot cast '%s' as '%s' in assignment of %`s", + MYF(error ? 0 : ME_WARNING), + from->name().ptr(), type_handler()->name().ptr(), + field_name.str); + return error; } return false; } diff --git a/sql/field.h b/sql/field.h index e18d08ac6e2..fe85b615915 100644 --- a/sql/field.h +++ b/sql/field.h @@ -905,10 +905,10 @@ public: bool is_unsigned() const { return flags & UNSIGNED_FLAG; } - bool check_assignability_from(const Type_handler *from) const; - bool check_assignability_from(const Field *from) const + bool check_assignability_from(const Type_handler *from, bool ignore) const; + bool check_assignability_from(const Field *from, bool ignore) const { - return check_assignability_from(from->type_handler()); + return check_assignability_from(from->type_handler(), ignore); } /** diff --git a/sql/item.cc b/sql/item.cc index af3cd527709..7099296bee0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4509,13 +4509,13 @@ bool Item_param::is_evaluable_expression() const } -bool Item_param::check_assignability_to(const Field *to) const +bool Item_param::check_assignability_to(const Field *to, bool ignore) const { switch (state) { case SHORT_DATA_VALUE: case LONG_DATA_VALUE: case NULL_VALUE: - return to->check_assignability_from(type_handler()); + return to->check_assignability_from(type_handler(), ignore); case NO_VALUE: case IGNORE_VALUE: case DEFAULT_VALUE: diff --git a/sql/item.h b/sql/item.h index 4b71109ef8d..a1bc4ebb61e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1819,14 +1819,14 @@ public: */ virtual bool is_evaluable_expression() const { return true; } - virtual bool check_assignability_to(const Field *to) const + virtual bool check_assignability_to(const Field *to, bool ignore) const { /* "this" must be neither DEFAULT/IGNORE, nor Item_param bound to DEFAULT/IGNORE. */ DBUG_ASSERT(is_evaluable_expression()); - return to->check_assignability_from(type_handler()); + return to->check_assignability_from(type_handler(), ignore); } /** @@ -4101,7 +4101,7 @@ class Item_param :public Item_basic_value, const String *value_query_val_str(THD *thd, String* str) const; Item *value_clone_item(THD *thd); bool is_evaluable_expression() const override; - bool check_assignability_to(const Field *field) const override; + bool check_assignability_to(const Field *field, bool ignore) const override; bool can_return_value() const; public: @@ -6777,7 +6777,7 @@ public: { str->append(STRING_WITH_LEN("default")); } - bool check_assignability_to(const Field *to) const override + bool check_assignability_to(const Field *to, bool ignore) const override { return false; } @@ -6814,7 +6814,7 @@ public: { str->append(STRING_WITH_LEN("ignore")); } - bool check_assignability_to(const Field *to) const override + bool check_assignability_to(const Field *to, bool ignore) const override { return false; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3557e21d53b..340aca29c03 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -424,7 +424,7 @@ Item *THD::sp_fix_func_item_for_assignment(const Field *to, Item **it_addr) { DBUG_ENTER("THD::sp_fix_func_item_for_assignment"); Item *res= sp_fix_func_item(it_addr); - if (res && (!res->check_assignability_to(to))) + if (res && (!res->check_assignability_to(to, false))) DBUG_RETURN(res); DBUG_RETURN(NULL); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f73ef97b875..a5944751a4f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -767,7 +767,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, value_count= values->elements; if ((res= mysql_prepare_insert(thd, table_list, fields, values, - update_fields, update_values, duplic, + update_fields, update_values, duplic, ignore, &unused_conds, FALSE))) { retval= thd->is_error(); @@ -838,7 +838,8 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, behaviour for non-transactional tables. */ if (values->elements && - table_list->table->check_assignability_opt_fields(fields, *values)) + table_list->table->check_assignability_opt_fields(fields, *values, + ignore)) goto abort; while ((values= its++)) @@ -1630,7 +1631,8 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables) int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, List<Item> &fields, List_item *values, List<Item> &update_fields, List<Item> &update_values, - enum_duplicates duplic, COND **where, + enum_duplicates duplic, bool ignore, + COND **where, bool select_insert) { SELECT_LEX *select_lex= thd->lex->first_select_lex(); @@ -1705,7 +1707,8 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ON DUPLICATE KEY UPDATE col=expr [, col=expr]; */ TABLE::check_assignability_explicit_fields(update_fields, - update_values); + update_values, + ignore); select_lex->no_wrap_view_item= FALSE; } @@ -3804,7 +3807,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res) if ((res= mysql_prepare_insert(thd, lex->query_tables, lex->field_list, 0, lex->update_list, lex->value_list, - lex->duplicates, + lex->duplicates, lex->ignore, &select_lex->where, TRUE))) DBUG_RETURN(res); @@ -3905,7 +3908,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) INSERT INTO t1 (col1, col2) VALUES (expr1, expr2); INSERT INTO t1 SET col1=expr1, col2=expr2; */ - res= table_list->table->check_assignability_opt_fields(*fields, values); + res= table_list->table->check_assignability_opt_fields(*fields, values, + lex->ignore); } if (!res && fields->elements) @@ -3968,7 +3972,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ON DUPLICATE KEY UPDATE col=expr [, col=expr] */ TABLE::check_assignability_explicit_fields(*info.update_fields, - *info.update_values); + *info.update_values, + lex->ignore); if (!res) { /* diff --git a/sql/sql_insert.h b/sql/sql_insert.h index 80666a81c50..8b034c25877 100644 --- a/sql/sql_insert.h +++ b/sql/sql_insert.h @@ -27,6 +27,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, List<Item> &fields, List_item *values, List<Item> &update_fields, List<Item> &update_values, enum_duplicates duplic, + bool ignore, COND **where, bool select_insert); bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, List<List_item> &values, List<Item> &update_fields, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5fca48f403f..5aa7e98cc1a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1287,7 +1287,8 @@ static bool mysql_test_insert_common(Prepared_statement *stmt, List<List_item> &values_list, List<Item> &update_fields, List<Item> &update_values, - enum_duplicates duplic) + enum_duplicates duplic, + bool ignore) { THD *thd= stmt->thd; List_iterator_fast<List_item> its(values_list); @@ -1324,7 +1325,8 @@ static bool mysql_test_insert_common(Prepared_statement *stmt, } if (mysql_prepare_insert(thd, table_list, fields, values, update_fields, - update_values, duplic, &unused_conds, FALSE)) + update_values, duplic, ignore, + &unused_conds, FALSE)) goto error; value_count= values->elements; @@ -1377,7 +1379,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, List<List_item> &values_list, List<Item> &update_fields, List<Item> &update_values, - enum_duplicates duplic) + enum_duplicates duplic, bool ignore) { THD *thd= stmt->thd; @@ -1393,7 +1395,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, } return mysql_test_insert_common(stmt, table_list, fields, values_list, - update_fields, update_values, duplic); + update_fields, update_values, duplic, ignore); } @@ -2471,14 +2473,14 @@ static bool check_prepared_statement(Prepared_statement *stmt) res= mysql_test_insert(stmt, tables, lex->field_list, lex->many_values, lex->update_list, lex->value_list, - lex->duplicates); + lex->duplicates, lex->ignore); break; case SQLCOM_LOAD: res= mysql_test_insert_common(stmt, tables, lex->field_list, lex->many_values, lex->update_list, lex->value_list, - lex->duplicates); + lex->duplicates, lex->ignore); break; case SQLCOM_UPDATE: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 15e8d950467..7626e0a2a56 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10990,7 +10990,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, if (!(*ptr)->vcol_info) { bitmap_set_bit(from->read_set, def->field->field_index); - if ((*ptr)->check_assignability_from(def->field)) + if ((*ptr)->check_assignability_from(def->field, ignore)) goto err; (copy_end++)->set(*ptr,def->field,0); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 24ba59a5bfd..fdec4014521 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -523,7 +523,8 @@ int mysql_update(THD *thd, DBUG_RETURN(1); /* purecov: inspected */ } - if (table_list->table->check_assignability_explicit_fields(fields, values)) + if (table_list->table->check_assignability_explicit_fields(fields, values, + ignore)) DBUG_RETURN(true); if (check_unique_table(thd, table_list)) @@ -2085,7 +2086,8 @@ int multi_update::prepare(List<Item> ¬_used_values, int error= setup_fields(thd, Ref_ptr_array(), *values, MARK_COLUMNS_READ, 0, NULL, 0) || - TABLE::check_assignability_explicit_fields(*fields, *values); + TABLE::check_assignability_explicit_fields(*fields, *values, + ignore); ti.rewind(); while ((table_ref= ti++)) diff --git a/sql/table.cc b/sql/table.cc index 85f69a1fbb8..3eda105f79a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9250,7 +9250,8 @@ bool TABLE::validate_default_values_of_unset_fields(THD *thd) const INSERT INTO t1 (a,b) VALUES (1,2); */ bool TABLE::check_assignability_explicit_fields(List<Item> fields, - List<Item> values) + List<Item> values, + bool ignore) { DBUG_ENTER("TABLE::check_assignability_explicit_fields"); DBUG_ASSERT(fields.elements == values.elements); @@ -9270,7 +9271,7 @@ bool TABLE::check_assignability_explicit_fields(List<Item> fields, */ continue; } - if (value->check_assignability_to(item_field->field)) + if (value->check_assignability_to(item_field->field, ignore)) DBUG_RETURN(true); } DBUG_RETURN(false); @@ -9282,7 +9283,8 @@ bool TABLE::check_assignability_explicit_fields(List<Item> fields, all visible fields of the table, e.g. INSERT INTO t1 VALUES (1,2); */ -bool TABLE::check_assignability_all_visible_fields(List<Item> &values) const +bool TABLE::check_assignability_all_visible_fields(List<Item> &values, + bool ignore) const { DBUG_ENTER("TABLE::check_assignability_all_visible_fields"); DBUG_ASSERT(s->visible_fields == values.elements); @@ -9291,7 +9293,7 @@ bool TABLE::check_assignability_all_visible_fields(List<Item> &values) const for (uint i= 0; i < s->fields; i++) { if (!field[i]->invisible && - (vi++)->check_assignability_to(field[i])) + (vi++)->check_assignability_to(field[i], ignore)) DBUG_RETURN(true); } DBUG_RETURN(false); diff --git a/sql/table.h b/sql/table.h index ddb0b183cf2..bf0d4f530a0 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1688,9 +1688,11 @@ public: // Check if the value list is assignable to the explicit field list static bool check_assignability_explicit_fields(List<Item> fields, - List<Item> values); + List<Item> values, + bool ignore); // Check if the value list is assignable to all visible fields - bool check_assignability_all_visible_fields(List<Item> &values) const; + bool check_assignability_all_visible_fields(List<Item> &values, + bool ignore) const; /* Check if the value list is assignable to: - The explicit field list if fields.elements > 0, e.g. @@ -1699,12 +1701,13 @@ public: INSERT INTO t1 VALUES (1,2); */ bool check_assignability_opt_fields(List<Item> fields, - List<Item> values) const + List<Item> values, + bool ignore) const { DBUG_ASSERT(values.elements); return fields.elements ? - check_assignability_explicit_fields(fields, values) : - check_assignability_all_visible_fields(values); + check_assignability_explicit_fields(fields, values, ignore) : + check_assignability_all_visible_fields(values, ignore); } bool insert_all_rows_into_tmp_table(THD *thd, |