Skip to content

Commit 098dff1

Browse files
committed
MDEV-11359 Implement IGNORE for bulk operation
1 parent d9c03c4 commit 098dff1

File tree

12 files changed

+437
-21
lines changed

12 files changed

+437
-21
lines changed

include/mysql.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
{
2222
STMT_INDICATOR_NONE= 0,
2323
STMT_INDICATOR_NULL,
24-
STMT_INDICATOR_DEFAULT
24+
STMT_INDICATOR_DEFAULT,
25+
STMT_INDICATOR_IGNORE
2526
};
2627
struct st_vio;
2728
typedef struct st_vio Vio;

include/mysql_com.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ enum enum_indicator_type
130130
{
131131
STMT_INDICATOR_NONE= 0,
132132
STMT_INDICATOR_NULL,
133-
STMT_INDICATOR_DEFAULT
133+
STMT_INDICATOR_DEFAULT,
134+
STMT_INDICATOR_IGNORE
134135
};
135136

136137
/* sql type stored in .frm files for virtual fields */

mysql-test/r/default.result

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,3 +3080,153 @@ t3 CREATE TABLE `t3` (
30803080
`max(c)` int(11) DEFAULT NULL
30813081
) ENGINE=MyISAM DEFAULT CHARSET=latin1
30823082
drop table t1, t2, t3;
3083+
# MDEV-11359: Implement IGNORE for bulk operation
3084+
create table t1 (a int primary key default 0, b int default 3);
3085+
insert into t1 values (1, ignore);
3086+
insert into t1 values (2, ignore);
3087+
replace into t1 values (2, ignore);
3088+
replace into t1 values (3, ignore);
3089+
replace into t1 values (4, 6);
3090+
replace into t1 values (5, 7);
3091+
update t1 set a=6,b=ignore where a=5;
3092+
insert into t1 values (ignore, ignore);
3093+
insert into t1 values (ignore, ignore);
3094+
ERROR 23000: Duplicate entry '0' for key 'PRIMARY'
3095+
select * from t1 order by a;
3096+
a b
3097+
0 3
3098+
1 3
3099+
2 3
3100+
3 3
3101+
4 6
3102+
6 7
3103+
delete from t1 where a < 4;
3104+
# actually insert default instead of ignoring
3105+
# (but REPLACE is non standard operator)
3106+
replace into t1 values (4, ignore);
3107+
select * from t1 order by a;
3108+
a b
3109+
4 3
3110+
6 7
3111+
drop table t1;
3112+
create table t1 (a int default 100, b int, c varchar(60) default 'x');
3113+
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=ignore;
3114+
select * from t1;
3115+
a b c
3116+
NULL 20 x
3117+
NULL 25 x
3118+
drop table t1;
3119+
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT);
3120+
CREATE TABLE t2 (a INT);
3121+
INSERT INTO t2 VALUES (1),(2),(3),(2);
3122+
INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=DEFAULT;
3123+
SELECT * FROM t1 order by a;
3124+
a
3125+
0
3126+
1
3127+
3
3128+
truncate table t1;
3129+
INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=IGNORE;
3130+
SELECT * FROM t1 order by a;
3131+
a
3132+
0
3133+
1
3134+
3
3135+
DROP TABLE t1,t2;
3136+
create table t1 (a int primary key default 0, b int default 3);
3137+
prepare insstmt from "insert into t1 values (?, ?)";
3138+
prepare repstmt from "replace into t1 values (?, ?)";
3139+
prepare updstmt from "update t1 set a=6,b=? where a=5";
3140+
execute insstmt using 1, ignore;
3141+
execute insstmt using 2, ignore;
3142+
execute repstmt using 2, ignore;
3143+
execute repstmt using 3, ignore;
3144+
execute repstmt using 4, 6;
3145+
execute repstmt using 5, 7;
3146+
execute updstmt using ignore;
3147+
execute insstmt using ignore, ignore;
3148+
execute insstmt using ignore, ignore;
3149+
ERROR 23000: Duplicate entry '0' for key 'PRIMARY'
3150+
select * from t1 order by a;
3151+
a b
3152+
0 3
3153+
1 3
3154+
2 3
3155+
3 3
3156+
4 6
3157+
6 7
3158+
delete from t1 where a < 4;
3159+
execute repstmt using 4, ignore;
3160+
select * from t1 order by a;
3161+
a b
3162+
4 3
3163+
6 7
3164+
drop table t1;
3165+
#
3166+
# DEVAULT & PS adoption
3167+
#
3168+
CREATE TABLE t1 (a INT DEFAULT 10, b INT DEFAULT NULL);
3169+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?,?)' USING IGNORE, IGNORE;
3170+
SELECT * FROM t1;
3171+
a b
3172+
10 NULL
3173+
UPDATE t1 SET a=20, b=30;
3174+
SELECT * FROM t1;
3175+
a b
3176+
20 30
3177+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?,b=?' USING IGNORE, IGNORE;
3178+
SELECT * FROM t1;
3179+
a b
3180+
20 30
3181+
DROP TABLE t1;
3182+
CREATE TABLE t1 (a INT DEFAULT 10);
3183+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING IGNORE;
3184+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3185+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING IGNORE, 'test';
3186+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3187+
DROP TABLE t1;
3188+
CREATE TABLE t1 (a INT DEFAULT 10);
3189+
INSERT INTO t1 VALUES (20);
3190+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING IGNORE;
3191+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3192+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING IGNORE, 'test';
3193+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3194+
DROP TABLE t1;
3195+
EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING IGNORE;
3196+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3197+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING IGNORE;
3198+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3199+
EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING IGNORE;
3200+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3201+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING IGNORE;
3202+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3203+
EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING IGNORE;
3204+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3205+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING IGNORE;
3206+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3207+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING IGNORE;
3208+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3209+
EXECUTE IMMEDIATE 'SELECT ?+1' USING IGNORE;
3210+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3211+
EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING IGNORE,'test';
3212+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3213+
EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING IGNORE;
3214+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3215+
CREATE TABLE t1 (a INT DEFAULT 10);
3216+
INSERT INTO t1 VALUES (1),(2),(3);
3217+
EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING IGNORE;
3218+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3219+
DROP TABLE t1;
3220+
# The output of this query in 'Note' is a syntactically incorrect query.
3221+
# But as it's never logged, it's ok. It should be human readable only.
3222+
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT ?' USING IGNORE;
3223+
id select_type table type possible_keys key key_len ref rows filtered Extra
3224+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3225+
Warnings:
3226+
Note 1003 select ignore AS `?`
3227+
CREATE TABLE t1 (a INT);
3228+
INSERT INTO t1 VALUES (1),(2),(3);
3229+
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
3230+
ERROR HY000: Default/ignore value is not supported for such parameter usage
3231+
DROP TABLE t1;
3232+
# end of 10.2 test

mysql-test/r/ps.result

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4668,41 +4668,41 @@ a b
46684668
DROP TABLE t1;
46694669
CREATE TABLE t1 (a INT DEFAULT 10);
46704670
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING DEFAULT;
4671-
ERROR HY000: Default value is not supported for such parameter usage
4671+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46724672
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING DEFAULT, 'test';
4673-
ERROR HY000: Default value is not supported for such parameter usage
4673+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46744674
DROP TABLE t1;
46754675
CREATE TABLE t1 (a INT DEFAULT 10);
46764676
INSERT INTO t1 VALUES (20);
46774677
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING DEFAULT;
4678-
ERROR HY000: Default value is not supported for such parameter usage
4678+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46794679
EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING DEFAULT, 'test';
4680-
ERROR HY000: Default value is not supported for such parameter usage
4680+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46814681
DROP TABLE t1;
46824682
EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING DEFAULT;
4683-
ERROR HY000: Default value is not supported for such parameter usage
4683+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46844684
EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING DEFAULT;
4685-
ERROR HY000: Default value is not supported for such parameter usage
4685+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46864686
EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING DEFAULT;
4687-
ERROR HY000: Default value is not supported for such parameter usage
4687+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46884688
EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING DEFAULT;
4689-
ERROR HY000: Default value is not supported for such parameter usage
4689+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46904690
EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING DEFAULT;
4691-
ERROR HY000: Default value is not supported for such parameter usage
4691+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46924692
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING DEFAULT;
4693-
ERROR HY000: Default value is not supported for such parameter usage
4693+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46944694
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING DEFAULT;
4695-
ERROR HY000: Default value is not supported for such parameter usage
4695+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46964696
EXECUTE IMMEDIATE 'SELECT ?+1' USING DEFAULT;
4697-
ERROR HY000: Default value is not supported for such parameter usage
4697+
ERROR HY000: Default/ignore value is not supported for such parameter usage
46984698
EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING DEFAULT,'test';
4699-
ERROR HY000: Default value is not supported for such parameter usage
4699+
ERROR HY000: Default/ignore value is not supported for such parameter usage
47004700
EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING DEFAULT;
4701-
ERROR HY000: Default value is not supported for such parameter usage
4701+
ERROR HY000: Default/ignore value is not supported for such parameter usage
47024702
CREATE TABLE t1 (a INT DEFAULT 10);
47034703
INSERT INTO t1 VALUES (1),(2),(3);
47044704
EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING DEFAULT;
4705-
ERROR HY000: Default value is not supported for such parameter usage
4705+
ERROR HY000: Default/ignore value is not supported for such parameter usage
47064706
DROP TABLE t1;
47074707
# The output of this query in 'Note' is a syntactically incorrect query.
47084708
# But as it's never logged, it's ok. It should be human readable only.
@@ -4714,5 +4714,5 @@ Note 1003 select default AS `?`
47144714
CREATE TABLE t1 (a INT);
47154715
INSERT INTO t1 VALUES (1),(2),(3);
47164716
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
4717-
ERROR HY000: Default value is not supported for such parameter usage
4717+
ERROR HY000: Default/ignore value is not supported for such parameter usage
47184718
DROP TABLE t1;

mysql-test/t/default.test

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,3 +1836,141 @@ create table t3 as select max(a), max(b), max(c) from t1;
18361836
show create table t2;
18371837
show create table t3;
18381838
drop table t1, t2, t3;
1839+
1840+
--echo # MDEV-11359: Implement IGNORE for bulk operation
1841+
create table t1 (a int primary key default 0, b int default 3);
1842+
insert into t1 values (1, ignore);
1843+
insert into t1 values (2, ignore);
1844+
replace into t1 values (2, ignore);
1845+
replace into t1 values (3, ignore);
1846+
replace into t1 values (4, 6);
1847+
replace into t1 values (5, 7);
1848+
update t1 set a=6,b=ignore where a=5;
1849+
insert into t1 values (ignore, ignore);
1850+
--error ER_DUP_ENTRY
1851+
insert into t1 values (ignore, ignore);
1852+
select * from t1 order by a;
1853+
delete from t1 where a < 4;
1854+
--echo # actually insert default instead of ignoring
1855+
--echo # (but REPLACE is non standard operator)
1856+
replace into t1 values (4, ignore);
1857+
select * from t1 order by a;
1858+
drop table t1;
1859+
1860+
#using in load
1861+
create table t1 (a int default 100, b int, c varchar(60) default 'x');
1862+
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=ignore;
1863+
select * from t1;
1864+
drop table t1;
1865+
1866+
#using in duplicate
1867+
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT);
1868+
CREATE TABLE t2 (a INT);
1869+
INSERT INTO t2 VALUES (1),(2),(3),(2);
1870+
INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=DEFAULT;
1871+
SELECT * FROM t1 order by a;
1872+
truncate table t1;
1873+
# efectively it is DEFALT
1874+
INSERT INTO t1 SELECT a FROM t2 ON DUPLICATE KEY UPDATE a=IGNORE;
1875+
SELECT * FROM t1 order by a;
1876+
DROP TABLE t1,t2;
1877+
1878+
create table t1 (a int primary key default 0, b int default 3);
1879+
prepare insstmt from "insert into t1 values (?, ?)";
1880+
prepare repstmt from "replace into t1 values (?, ?)";
1881+
prepare updstmt from "update t1 set a=6,b=? where a=5";
1882+
execute insstmt using 1, ignore;
1883+
execute insstmt using 2, ignore;
1884+
execute repstmt using 2, ignore;
1885+
execute repstmt using 3, ignore;
1886+
execute repstmt using 4, 6;
1887+
execute repstmt using 5, 7;
1888+
execute updstmt using ignore;
1889+
execute insstmt using ignore, ignore;
1890+
--error ER_DUP_ENTRY
1891+
execute insstmt using ignore, ignore;
1892+
select * from t1 order by a;
1893+
delete from t1 where a < 4;
1894+
execute repstmt using 4, ignore;
1895+
select * from t1 order by a;
1896+
drop table t1;
1897+
1898+
--echo #
1899+
--echo # DEVAULT & PS adoption
1900+
--echo #
1901+
1902+
1903+
# Correct usage
1904+
CREATE TABLE t1 (a INT DEFAULT 10, b INT DEFAULT NULL);
1905+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?,?)' USING IGNORE, IGNORE;
1906+
SELECT * FROM t1;
1907+
UPDATE t1 SET a=20, b=30;
1908+
SELECT * FROM t1;
1909+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?,b=?' USING IGNORE, IGNORE;
1910+
SELECT * FROM t1;
1911+
DROP TABLE t1;
1912+
1913+
# Incorrect usage in a expression in INSERT..VALUES
1914+
CREATE TABLE t1 (a INT DEFAULT 10);
1915+
--error ER_INVALID_DEFAULT_PARAM
1916+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?+1)' USING IGNORE;
1917+
--error ER_INVALID_DEFAULT_PARAM
1918+
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (CONCAT(?,?))' USING IGNORE, 'test';
1919+
DROP TABLE t1;
1920+
1921+
# Incorrect usage in UPDATE..SET
1922+
CREATE TABLE t1 (a INT DEFAULT 10);
1923+
INSERT INTO t1 VALUES (20);
1924+
--error ER_INVALID_DEFAULT_PARAM
1925+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=?+1' USING IGNORE;
1926+
--error ER_INVALID_DEFAULT_PARAM
1927+
EXECUTE IMMEDIATE 'UPDATE t1 SET a=CONCAT(?,?)' USING IGNORE, 'test';
1928+
DROP TABLE t1;
1929+
1930+
1931+
# Incorrect usage in not an UPDATE/INSERT query at all
1932+
--error ER_INVALID_DEFAULT_PARAM
1933+
EXECUTE IMMEDIATE 'SELECT CAST(? AS SIGNED)' USING IGNORE;
1934+
--error ER_INVALID_DEFAULT_PARAM
1935+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DOUBLE)' USING IGNORE;
1936+
--error ER_INVALID_DEFAULT_PARAM
1937+
EXECUTE IMMEDIATE 'SELECT CAST(? AS CHAR)' USING IGNORE;
1938+
--error ER_INVALID_DEFAULT_PARAM
1939+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DECIMAL(10,1))' USING IGNORE;
1940+
--error ER_INVALID_DEFAULT_PARAM
1941+
EXECUTE IMMEDIATE 'SELECT CAST(? AS TIME)' USING IGNORE;
1942+
--error ER_INVALID_DEFAULT_PARAM
1943+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATE)' USING IGNORE;
1944+
--error ER_INVALID_DEFAULT_PARAM
1945+
EXECUTE IMMEDIATE 'SELECT CAST(? AS DATETIME)' USING IGNORE;
1946+
1947+
--error ER_INVALID_DEFAULT_PARAM
1948+
EXECUTE IMMEDIATE 'SELECT ?+1' USING IGNORE;
1949+
--error ER_INVALID_DEFAULT_PARAM
1950+
EXECUTE IMMEDIATE 'SELECT CONCAT(?,?)' USING IGNORE,'test';
1951+
1952+
1953+
# Incorrect usage in the LIMIT clause
1954+
--error ER_INVALID_DEFAULT_PARAM
1955+
EXECUTE IMMEDIATE 'SELECT 1 LIMIT ?' USING IGNORE;
1956+
CREATE TABLE t1 (a INT DEFAULT 10);
1957+
INSERT INTO t1 VALUES (1),(2),(3);
1958+
--error ER_INVALID_DEFAULT_PARAM
1959+
EXECUTE IMMEDIATE 'SELECT * FROM t1 LIMIT ?' USING IGNORE;
1960+
DROP TABLE t1;
1961+
1962+
1963+
--echo # The output of this query in 'Note' is a syntactically incorrect query.
1964+
--echo # But as it's never logged, it's ok. It should be human readable only.
1965+
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT ?' USING IGNORE;
1966+
1967+
1968+
# This tests Item_param::eq() for IGNORE as a bound value
1969+
CREATE TABLE t1 (a INT);
1970+
INSERT INTO t1 VALUES (1),(2),(3);
1971+
--error ER_INVALID_DEFAULT_PARAM
1972+
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
1973+
DROP TABLE t1;
1974+
1975+
1976+
--echo # end of 10.2 test

sql/field.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10861,3 +10861,15 @@ bool Field::save_in_field_default_value(bool view_error_processing)
1086110861
validate_value_in_record_with_warn(thd, table->record[0]) &&
1086210862
thd->is_error() ? -1 : 0;
1086310863
}
10864+
10865+
10866+
bool Field::save_in_field_ignore_value(bool view_error_processing)
10867+
{
10868+
enum_sql_command com= table->in_use->lex->sql_command;
10869+
// All insert-like commands
10870+
if (com == SQLCOM_INSERT || com == SQLCOM_REPLACE ||
10871+
com == SQLCOM_INSERT_SELECT || com == SQLCOM_REPLACE_SELECT ||
10872+
com == SQLCOM_LOAD)
10873+
return save_in_field_default_value(view_error_processing);
10874+
return 0; // ignore
10875+
}

0 commit comments

Comments
 (0)