summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc26
-rw-r--r--sql/field.h6
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item.h10
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_insert.cc19
-rw-r--r--sql/sql_insert.h1
-rw-r--r--sql/sql_prepare.cc14
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_update.cc6
-rw-r--r--sql/table.cc10
-rw-r--r--sql/table.h13
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> &not_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,