Commit 098dff10 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-11359 Implement IGNORE for bulk operation

parent d9c03c43
...@@ -21,7 +21,8 @@ enum enum_indicator_type ...@@ -21,7 +21,8 @@ enum enum_indicator_type
{ {
STMT_INDICATOR_NONE= 0, STMT_INDICATOR_NONE= 0,
STMT_INDICATOR_NULL, STMT_INDICATOR_NULL,
STMT_INDICATOR_DEFAULT STMT_INDICATOR_DEFAULT,
STMT_INDICATOR_IGNORE
}; };
struct st_vio; struct st_vio;
typedef struct st_vio Vio; typedef struct st_vio Vio;
......
...@@ -130,7 +130,8 @@ enum enum_indicator_type ...@@ -130,7 +130,8 @@ enum enum_indicator_type
{ {
STMT_INDICATOR_NONE= 0, STMT_INDICATOR_NONE= 0,
STMT_INDICATOR_NULL, STMT_INDICATOR_NULL,
STMT_INDICATOR_DEFAULT STMT_INDICATOR_DEFAULT,
STMT_INDICATOR_IGNORE
}; };
/* sql type stored in .frm files for virtual fields */ /* sql type stored in .frm files for virtual fields */
......
...@@ -3080,3 +3080,153 @@ t3 CREATE TABLE `t3` ( ...@@ -3080,3 +3080,153 @@ t3 CREATE TABLE `t3` (
`max(c)` int(11) DEFAULT NULL `max(c)` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3; 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
...@@ -4668,41 +4668,41 @@ a b ...@@ -4668,41 +4668,41 @@ a b
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT DEFAULT 10); CREATE TABLE t1 (a INT DEFAULT 10);
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING DEFAULT; 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'; 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; DROP TABLE t1;
CREATE TABLE t1 (a INT DEFAULT 10); CREATE TABLE t1 (a INT DEFAULT 10);
INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (20);
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING DEFAULT; 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'; 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; DROP TABLE t1;
EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING DEFAULT; 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; 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; 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; 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; 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; 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; 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; 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'; 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; 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); CREATE TABLE t1 (a INT DEFAULT 10);
INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (1),(2),(3);
EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING DEFAULT; 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; DROP TABLE t1;
# The output of this query in 'Note' is a syntactically incorrect query. # 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. # But as it's never logged, it's ok. It should be human readable only.
...@@ -4714,5 +4714,5 @@ Note 1003 select default AS `?` ...@@ -4714,5 +4714,5 @@ Note 1003 select default AS `?`
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (1),(2),(3);
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT; 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; DROP TABLE t1;
...@@ -1836,3 +1836,141 @@ create table t3 as select max(a), max(b), max(c) from t1; ...@@ -1836,3 +1836,141 @@ create table t3 as select max(a), max(b), max(c) from t1;
show create table t2; show create table t2;
show create table t3; show create table t3;
drop table t1, t2, 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
...@@ -10861,3 +10861,15 @@ bool Field::save_in_field_default_value(bool view_error_processing) ...@@ -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]) && validate_value_in_record_with_warn(thd, table->record[0]) &&
thd->is_error() ? -1 : 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
}
...@@ -1453,6 +1453,7 @@ class Field: public Value_source ...@@ -1453,6 +1453,7 @@ class Field: public Value_source
} }
bool save_in_field_default_value(bool view_eror_processing); 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, friend int cre_myisam(char * name, register TABLE *form, uint options,
ulonglong auto_increment_value); ulonglong auto_increment_value);
......
...@@ -3611,6 +3611,10 @@ int Item_param::save_in_field(Field *field, bool no_conversions) ...@@ -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-> return field->save_in_field_default_value(field->table->pos_in_table_list->
top_table() != top_table() !=
field->table->pos_in_table_list); 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: case NO_VALUE:
DBUG_ASSERT(0); // Should not be possible DBUG_ASSERT(0); // Should not be possible
return true; return true;
...@@ -3663,6 +3667,7 @@ double Item_param::val_real() ...@@ -3663,6 +3667,7 @@ double Item_param::val_real()
time value for the placeholder. time value for the placeholder.
*/ */
return TIME_to_double(&value.time); return TIME_to_double(&value.time);
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
// fall through // fall through
...@@ -3698,6 +3703,7 @@ longlong Item_param::val_int() ...@@ -3698,6 +3703,7 @@ longlong Item_param::val_int()
} }
case TIME_VALUE: case TIME_VALUE:
return (longlong) TIME_to_ulonglong(&value.time); return (longlong) TIME_to_ulonglong(&value.time);
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
// fall through // fall through
...@@ -3731,6 +3737,7 @@ my_decimal *Item_param::val_decimal(my_decimal *dec) ...@@ -3731,6 +3737,7 @@ my_decimal *Item_param::val_decimal(my_decimal *dec)
{ {
return TIME_to_my_decimal(&value.time, dec); return TIME_to_my_decimal(&value.time, dec);
} }
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
// fall through // fall through
...@@ -3772,6 +3779,7 @@ String *Item_param::val_str(String* str) ...@@ -3772,6 +3779,7 @@ String *Item_param::val_str(String* str)
str->set_charset(&my_charset_bin); str->set_charset(&my_charset_bin);
return str; return str;
} }
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
// fall through // fall through
...@@ -3856,6 +3864,7 @@ const String *Item_param::query_val_str(THD *thd, String* str) const ...@@ -3856,6 +3864,7 @@ const String *Item_param::query_val_str(THD *thd, String* str) const
thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES); thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES);
return str; return str;
} }
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
return &my_default_string; return &my_default_string;
case NULL_VALUE: case NULL_VALUE:
...@@ -3911,6 +3920,7 @@ Item_param::clone_item(THD *thd) ...@@ -3911,6 +3920,7 @@ Item_param::clone_item(THD *thd)
MEM_ROOT *mem_root= thd->mem_root; MEM_ROOT *mem_root= thd->mem_root;
// There's no "default". See comments in Item_param::save_in_field(). // There's no "default". See comments in Item_param::save_in_field().
switch (state) { switch (state) {
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
// fall through // fall through
...@@ -3949,6 +3959,7 @@ Item_param::eq(const Item *item, bool binary_cmp) const ...@@ -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(). // There's no "default". See comments in Item_param::save_in_field().
switch (state) { switch (state) {
case IGNORE_VALUE:
case DEFAULT_VALUE: case DEFAULT_VALUE:
invalid_default_param(); invalid_default_param();
return false; return false;
...@@ -3982,6 +3993,10 @@ void Item_param::print(String *str, enum_query_type query_type) ...@@ -3982,6 +3993,10 @@ void Item_param::print(String *str, enum_query_type query_type)
{ {
str->append("default"); str->append("default");
} }
else if (state == IGNORE_VALUE)
{
str->append("ignore");
}
else else
{ {
char buffer[STRING_BUFFER_USUAL_SIZE]; char buffer[STRING_BUFFER_USUAL_SIZE];
...@@ -4047,6 +4062,12 @@ void Item_param::set_default() ...@@ -4047,6 +4062,12 @@ void Item_param::set_default()
null_value= true; 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 This operation is intended to store some item value in Item_param to be
used later. used later.
...@@ -8703,6 +8724,57 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer, ...@@ -8703,6 +8724,57 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer,
return (this->*transformer)(thd, args); 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 bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{ {
......
...@@ -2806,7 +2806,7 @@ class Item_param :public Item_basic_value, ...@@ -2806,7 +2806,7 @@ class Item_param :public Item_basic_value,
{ {
NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE, NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE, STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE,
DECIMAL_VALUE, DEFAULT_VALUE DECIMAL_VALUE, DEFAULT_VALUE, IGNORE_VALUE
} state; } state;
struct CONVERSION_INFO struct CONVERSION_INFO
...@@ -2898,6 +2898,7 @@ class Item_param :public Item_basic_value, ...@@ -2898,6 +2898,7 @@ class Item_param :public Item_basic_value,
int save_in_field(Field *field, bool no_conversions); int save_in_field(Field *field, bool no_conversions);
void set_default(); void set_default();
void set_ignore();
void set_null(); void set_null();
void set_int(longlong i, uint32 max_length_arg); void set_int(longlong i, uint32 max_length_arg);
void set_double(double i); void set_double(double i);
...@@ -5166,6 +5167,37 @@ class Item_default_value : public Item_field ...@@ -5166,6 +5167,37 @@ class Item_default_value : public Item_field
Item *transform(THD *thd, Item_transformer transformer, uchar *args); 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. Item_insert_value -- an implementation of VALUES() function.
You can use the VALUES(col_name) function in the UPDATE clause You can use the VALUES(col_name) function in the UPDATE clause
......
...@@ -7233,8 +7233,8 @@ ER_PARTITION_DEFAULT_ERROR ...@@ -7233,8 +7233,8 @@ ER_PARTITION_DEFAULT_ERROR
ER_REFERENCED_TRG_DOES_NOT_EXIST ER_REFERENCED_TRG_DOES_NOT_EXIST
eng "Referenced trigger '%s' for the given action time and event type does not exist" eng "Referenced trigger '%s' for the given action time and event type does not exist"
ER_INVALID_DEFAULT_PARAM ER_INVALID_DEFAULT_PARAM
eng "Default value is not supported for such parameter usage" eng "Default/ignore value is not supported for such parameter usage"
ukr "Значення за замовчуванням не підтримано для цього випадку використання параьетра" ukr "Значення за замовчуванням або ігнороване значення не підтримано для цього випадку використання параьетра"
ER_BINLOG_NON_SUPPORTED_BULK ER_BINLOG_NON_SUPPORTED_BULK
eng "Only row based replication supported for bulk operations" eng "Only row based replication supported for bulk operations"
ER_BINLOG_UNCOMPRESS_ERROR ER_BINLOG_UNCOMPRESS_ERROR
......
...@@ -1012,6 +1012,9 @@ static bool insert_bulk_params(Prepared_statement *stmt, ...@@ -1012,6 +1012,9 @@ static bool insert_bulk_params(Prepared_statement *stmt,
case STMT_INDICATOR_DEFAULT: case STMT_INDICATOR_DEFAULT:
param->set_default(); param->set_default();
break; break;
case STMT_INDICATOR_IGNORE:
param->set_ignore();
break;
} }
} }
else else
......
...@@ -12500,6 +12500,12 @@ expr_or_default: ...@@ -12500,6 +12500,12 @@ expr_or_default:
if ($$ == NULL) if ($$ == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| IGNORE_SYM
{
$$= new (thd->mem_root) Item_ignore_value(thd, Lex->current_context());
if ($$ == NULL)
MYSQL_YYABORT;
}
; ;
opt_insert_update: opt_insert_update:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment