diff --git a/include/mysql.h.pp b/include/mysql.h.pp index aa9a0aaa266..9d93b9ad325 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -21,7 +21,8 @@ enum enum_indicator_type { STMT_INDICATOR_NONE= 0, STMT_INDICATOR_NULL, - STMT_INDICATOR_DEFAULT + STMT_INDICATOR_DEFAULT, + STMT_INDICATOR_IGNORE }; struct st_vio; typedef struct st_vio Vio; diff --git a/include/mysql_com.h b/include/mysql_com.h index eb28d8b5092..c399520022d 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -130,7 +130,8 @@ enum enum_indicator_type { STMT_INDICATOR_NONE= 0, STMT_INDICATOR_NULL, - STMT_INDICATOR_DEFAULT + STMT_INDICATOR_DEFAULT, + STMT_INDICATOR_IGNORE }; /* sql type stored in .frm files for virtual fields */ diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index 386837a84bb..03a444e6075 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -3080,3 +3080,153 @@ t3 CREATE TABLE `t3` ( `max(c)` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2, t3; +# MDEV-11359: Implement IGNORE for bulk operation +create table t1 (a int primary key default 0, b int default 3); +insert into t1 values (1, ignore); +insert into t1 values (2, ignore); +replace into t1 values (2, ignore); +replace into t1 values (3, ignore); +replace into t1 values (4, 6); +replace into t1 values (5, 7); +update t1 set a=6,b=ignore where a=5; +insert into t1 values (ignore, ignore); +insert into t1 values (ignore, ignore); +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select * from t1 order by a; +a b +0 3 +1 3 +2 3 +3 3 +4 6 +6 7 +delete from t1 where a < 4; +# actually insert default instead of ignoring +# (but REPLACE is non standard operator) +replace into t1 values (4, ignore); +select * from t1 order by a; +a b +4 3 +6 7 +drop table t1; +create table t1 (a int default 100, b int, c varchar(60) default 'x'); +load data infile '../../std_data/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=ignore; +select * from t1; +a b c +NULL 20 x +NULL 25 x +drop table t1; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2),(3),(2); +INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=DEFAULT; +SELECT * FROM t1 order by a; +a +0 +1 +3 +truncate table t1; +INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=IGNORE; +SELECT * FROM t1 order by a; +a +0 +1 +3 +DROP TABLE t1,t2; +create table t1 (a int primary key default 0, b int default 3); +prepare insstmt from "insert into t1 values (?, ?)"; +prepare repstmt from "replace into t1 values (?, ?)"; +prepare updstmt from "update t1 set a=6,b=? where a=5"; +execute insstmt using 1, ignore; +execute insstmt using 2, ignore; +execute repstmt using 2, ignore; +execute repstmt using 3, ignore; +execute repstmt using 4, 6; +execute repstmt using 5, 7; +execute updstmt using ignore; +execute insstmt using ignore, ignore; +execute insstmt using ignore, ignore; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select * from t1 order by a; +a b +0 3 +1 3 +2 3 +3 3 +4 6 +6 7 +delete from t1 where a < 4; +execute repstmt using 4, ignore; +select * from t1 order by a; +a b +4 3 +6 7 +drop table t1; +# +# DEVAULT & PS adoption +# +CREATE TABLE t1 (a INT DEFAULT 10, b INT DEFAULT NULL); +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?,?)' USING IGNORE, IGNORE; +SELECT * FROM t1; +a b +10 NULL +UPDATE t1 SET a=20, b=30; +SELECT * FROM t1; +a b +20 30 +EXECUTE IMMEDIATE 'UPDATE t1 SET a=?,b=?' USING IGNORE, IGNORE; +SELECT * FROM t1; +a b +20 30 +DROP TABLE t1; +CREATE TABLE t1 (a INT DEFAULT 10); +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING IGNORE, 'test'; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t1; +CREATE TABLE t1 (a INT DEFAULT 10); +INSERT INTO t1 VALUES (20); +EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING IGNORE, 'test'; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t1; +EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT ?+1' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING IGNORE,'test'; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +CREATE TABLE t1 (a INT DEFAULT 10); +INSERT INTO t1 VALUES (1),(2),(3); +EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t1; +# The output of this query in 'Note' is a syntactically incorrect query. +# But as it's never logged, it's ok. It should be human readable only. +EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT ?' USING IGNORE; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select ignore AS `?` +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t1; +# end of 10.2 test diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index a9211ee8130..faefd0805c8 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4668,41 +4668,41 @@ a b DROP TABLE t1; CREATE TABLE t1 (a INT DEFAULT 10); EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING DEFAULT, 'test'; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage DROP TABLE t1; CREATE TABLE t1 (a INT DEFAULT 10); INSERT INTO t1 VALUES (20); EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING DEFAULT, 'test'; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage DROP TABLE t1; EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT ?+1' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING DEFAULT,'test'; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage CREATE TABLE t1 (a INT DEFAULT 10); INSERT INTO t1 VALUES (1),(2),(3); EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage DROP TABLE t1; # The output of this query in 'Note' is a syntactically incorrect query. # But as it's never logged, it's ok. It should be human readable only. @@ -4714,5 +4714,5 @@ Note 1003 select default AS `?` CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT; -ERROR HY000: Default value is not supported for such parameter usage +ERROR HY000: Default/ignore value is not supported for such parameter usage DROP TABLE t1; diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test index 6c871527212..5f00debbc3a 100644 --- a/mysql-test/t/default.test +++ b/mysql-test/t/default.test @@ -1836,3 +1836,141 @@ create table t3 as select max(a), max(b), max(c) from t1; show create table t2; show create table t3; drop table t1, t2, t3; + +--echo # MDEV-11359: Implement IGNORE for bulk operation +create table t1 (a int primary key default 0, b int default 3); +insert into t1 values (1, ignore); +insert into t1 values (2, ignore); +replace into t1 values (2, ignore); +replace into t1 values (3, ignore); +replace into t1 values (4, 6); +replace into t1 values (5, 7); +update t1 set a=6,b=ignore where a=5; +insert into t1 values (ignore, ignore); +--error ER_DUP_ENTRY +insert into t1 values (ignore, ignore); +select * from t1 order by a; +delete from t1 where a < 4; +--echo # actually insert default instead of ignoring +--echo # (but REPLACE is non standard operator) +replace into t1 values (4, ignore); +select * from t1 order by a; +drop table t1; + +#using in load +create table t1 (a int default 100, b int, c varchar(60) default 'x'); +load data infile '../../std_data/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=ignore; +select * from t1; +drop table t1; + +#using in duplicate +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2),(3),(2); +INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=DEFAULT; +SELECT * FROM t1 order by a; +truncate table t1; +# efectively it is DEFALT +INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=IGNORE; +SELECT * FROM t1 order by a; +DROP TABLE t1,t2; + +create table t1 (a int primary key default 0, b int default 3); +prepare insstmt from "insert into t1 values (?, ?)"; +prepare repstmt from "replace into t1 values (?, ?)"; +prepare updstmt from "update t1 set a=6,b=? where a=5"; +execute insstmt using 1, ignore; +execute insstmt using 2, ignore; +execute repstmt using 2, ignore; +execute repstmt using 3, ignore; +execute repstmt using 4, 6; +execute repstmt using 5, 7; +execute updstmt using ignore; +execute insstmt using ignore, ignore; +--error ER_DUP_ENTRY +execute insstmt using ignore, ignore; +select * from t1 order by a; +delete from t1 where a < 4; +execute repstmt using 4, ignore; +select * from t1 order by a; +drop table t1; + +--echo # +--echo # DEVAULT & PS adoption +--echo # + + +# Correct usage +CREATE TABLE t1 (a INT DEFAULT 10, b INT DEFAULT NULL); +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?,?)' USING IGNORE, IGNORE; +SELECT * FROM t1; +UPDATE t1 SET a=20, b=30; +SELECT * FROM t1; +EXECUTE IMMEDIATE 'UPDATE t1 SET a=?,b=?' USING IGNORE, IGNORE; +SELECT * FROM t1; +DROP TABLE t1; + +# Incorrect usage in a expression in INSERT..VALUES +CREATE TABLE t1 (a INT DEFAULT 10); +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING IGNORE, 'test'; +DROP TABLE t1; + +# Incorrect usage in UPDATE..SET +CREATE TABLE t1 (a INT DEFAULT 10); +INSERT INTO t1 VALUES (20); +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING IGNORE, 'test'; +DROP TABLE t1; + + +# Incorrect usage in not an UPDATE/INSERT query at all +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING IGNORE; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT ?+1' USING IGNORE; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING IGNORE,'test'; + + +# Incorrect usage in the LIMIT clause +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING IGNORE; +CREATE TABLE t1 (a INT DEFAULT 10); +INSERT INTO t1 VALUES (1),(2),(3); +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING IGNORE; +DROP TABLE t1; + + +--echo # The output of this query in 'Note' is a syntactically incorrect query. +--echo # But as it's never logged, it's ok. It should be human readable only. +EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT ?' USING IGNORE; + + +# This tests Item_param::eq() for IGNORE as a bound value +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT; +DROP TABLE t1; + + +--echo # end of 10.2 test diff --git a/sql/field.cc b/sql/field.cc index 609d44f4856..751df5725b5 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10861,3 +10861,15 @@ bool Field::save_in_field_default_value(bool view_error_processing) validate_value_in_record_with_warn(thd, table->record[0]) && thd->is_error() ? -1 : 0; } + + +bool Field::save_in_field_ignore_value(bool view_error_processing) +{ + enum_sql_command com= table->in_use->lex->sql_command; + // All insert-like commands + if (com == SQLCOM_INSERT || com == SQLCOM_REPLACE || + com == SQLCOM_INSERT_SELECT || com == SQLCOM_REPLACE_SELECT || + com == SQLCOM_LOAD) + return save_in_field_default_value(view_error_processing); + return 0; // ignore +} diff --git a/sql/field.h b/sql/field.h index c9d7509618a..65c4843be82 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1453,6 +1453,7 @@ public: } bool save_in_field_default_value(bool view_eror_processing); + bool save_in_field_ignore_value(bool view_error_processing); friend int cre_myisam(char * name, register TABLE *form, uint options, ulonglong auto_increment_value); diff --git a/sql/item.cc b/sql/item.cc index 24b877bd5d8..009662252d8 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3611,6 +3611,10 @@ int Item_param::save_in_field(Field *field, bool no_conversions) return field->save_in_field_default_value(field->table->pos_in_table_list-> top_table() != field->table->pos_in_table_list); + case IGNORE_VALUE: + return field->save_in_field_ignore_value(field->table->pos_in_table_list-> + top_table() != + field->table->pos_in_table_list); case NO_VALUE: DBUG_ASSERT(0); // Should not be possible return true; @@ -3663,6 +3667,7 @@ double Item_param::val_real() time value for the placeholder. */ return TIME_to_double(&value.time); + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); // fall through @@ -3698,6 +3703,7 @@ longlong Item_param::val_int() } case TIME_VALUE: return (longlong) TIME_to_ulonglong(&value.time); + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); // fall through @@ -3731,6 +3737,7 @@ my_decimal *Item_param::val_decimal(my_decimal *dec) { return TIME_to_my_decimal(&value.time, dec); } + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); // fall through @@ -3772,6 +3779,7 @@ String *Item_param::val_str(String* str) str->set_charset(&my_charset_bin); return str; } + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); // fall through @@ -3856,6 +3864,7 @@ const String *Item_param::query_val_str(THD *thd, String* str) const thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES); return str; } + case IGNORE_VALUE: case DEFAULT_VALUE: return &my_default_string; case NULL_VALUE: @@ -3911,6 +3920,7 @@ Item_param::clone_item(THD *thd) MEM_ROOT *mem_root= thd->mem_root; // There's no "default". See comments in Item_param::save_in_field(). switch (state) { + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); // fall through @@ -3949,6 +3959,7 @@ Item_param::eq(const Item *item, bool binary_cmp) const // There's no "default". See comments in Item_param::save_in_field(). switch (state) { + case IGNORE_VALUE: case DEFAULT_VALUE: invalid_default_param(); return false; @@ -3982,6 +3993,10 @@ void Item_param::print(String *str, enum_query_type query_type) { str->append("default"); } + else if (state == IGNORE_VALUE) + { + str->append("ignore"); + } else { char buffer[STRING_BUFFER_USUAL_SIZE]; @@ -4047,6 +4062,12 @@ void Item_param::set_default() null_value= true; } +void Item_param::set_ignore() +{ + state= IGNORE_VALUE; + null_value= true; +} + /** This operation is intended to store some item value in Item_param to be used later. @@ -8703,6 +8724,57 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer, return (this->*transformer)(thd, args); } +void Item_ignore_value::print(String *str, enum_query_type query_type) +{ + str->append(STRING_WITH_LEN("ignore")); +} + +int Item_ignore_value::save_in_field(Field *field_arg, bool no_conversions) +{ + return field_arg->save_in_field_ignore_value(context->error_processor == + &view_error_processor); +} + +String *Item_ignore_value::val_str(String *str) +{ + DBUG_ASSERT(0); // never should be called + null_value= 1; + return 0; +} + +double Item_ignore_value::val_real() +{ + DBUG_ASSERT(0); // never should be called + null_value= 1; + return 0.0; +} + +longlong Item_ignore_value::val_int() +{ + DBUG_ASSERT(0); // never should be called + null_value= 1; + return 0; +} + +my_decimal *Item_ignore_value::val_decimal(my_decimal *decimal_value) +{ + DBUG_ASSERT(0); // never should be called + null_value= 1; + return 0; +} + +bool Item_ignore_value::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + DBUG_ASSERT(0); // never should be called + null_value= 1; + return TRUE; +} + +bool Item_ignore_value::send(Protocol *protocol, String *buffer) +{ + DBUG_ASSERT(0); // never should be called + return TRUE; +} bool Item_insert_value::eq(const Item *item, bool binary_cmp) const { diff --git a/sql/item.h b/sql/item.h index ab77b3f7035..a7f625dd9f9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2806,7 +2806,7 @@ public: { NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE, STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE, - DECIMAL_VALUE, DEFAULT_VALUE + DECIMAL_VALUE, DEFAULT_VALUE, IGNORE_VALUE } state; struct CONVERSION_INFO @@ -2898,6 +2898,7 @@ public: int save_in_field(Field *field, bool no_conversions); void set_default(); + void set_ignore(); void set_null(); void set_int(longlong i, uint32 max_length_arg); void set_double(double i); @@ -5166,6 +5167,37 @@ public: Item *transform(THD *thd, Item_transformer transformer, uchar *args); }; +/** + This class is used as bulk parameter INGNORE representation. + + It just do nothing when assigned to a field + +*/ + +class Item_ignore_value : public Item_default_value +{ +public: + Item_ignore_value(THD *thd, Name_resolution_context *context_arg) + :Item_default_value(thd, context_arg) + {}; + + void print(String *str, enum_query_type query_type); + int save_in_field(Field *field_arg, bool no_conversions); + bool save_in_param(THD *thd, Item_param *param) + { + param->set_ignore(); + return false; + } + + String *val_str(String *str); + double val_real(); + longlong val_int(); + my_decimal *val_decimal(my_decimal *decimal_value); + bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate); + bool send(Protocol *protocol, String *buffer); +}; + + /* Item_insert_value -- an implementation of VALUES() function. You can use the VALUES(col_name) function in the UPDATE clause diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 75eb8931c35..20f87eb912b 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7233,8 +7233,8 @@ ER_PARTITION_DEFAULT_ERROR ER_REFERENCED_TRG_DOES_NOT_EXIST eng "Referenced trigger '%s' for the given action time and event type does not exist" ER_INVALID_DEFAULT_PARAM - eng "Default value is not supported for such parameter usage" - ukr "Значення за замовчуванням не підтримано для цього випадку використання параьетра" + eng "Default/ignore value is not supported for such parameter usage" + ukr "Значення за замовчуванням або ігнороване значення не підтримано для цього випадку використання параьетра" ER_BINLOG_NON_SUPPORTED_BULK eng "Only row based replication supported for bulk operations" ER_BINLOG_UNCOMPRESS_ERROR diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1e943cad62f..fcd778d556c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1012,6 +1012,9 @@ static bool insert_bulk_params(Prepared_statement *stmt, case STMT_INDICATOR_DEFAULT: param->set_default(); break; + case STMT_INDICATOR_IGNORE: + param->set_ignore(); + break; } } else diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e0e0f6e0377..d45c7431e82 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -12500,6 +12500,12 @@ expr_or_default: if ($$ == NULL) MYSQL_YYABORT; } + | IGNORE_SYM + { + $$= new (thd->mem_root) Item_ignore_value(thd, Lex->current_context()); + if ($$ == NULL) + MYSQL_YYABORT; + } ; opt_insert_update: