mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-11359 Implement IGNORE for bulk operation
This commit is contained in:
@@ -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
|
|||||||
{
|
{
|
||||||
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` (
|
|||||||
`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
|
|||||||
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 `?`
|
|||||||
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;
|
|||||||
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
|
||||||
|
12
sql/field.cc
12
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]) &&
|
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 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
72
sql/item.cc
72
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->
|
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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
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
|
|||||||
|
|
||||||
// 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)
|
|||||||
{
|
{
|
||||||
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()
|
|||||||
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,
|
|||||||
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
|
||||||
{
|
{
|
||||||
|
34
sql/item.h
34
sql/item.h
@@ -2806,7 +2806,7 @@ public:
|
|||||||
{
|
{
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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
|
|||||||
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,
|
|||||||
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:
|
|||||||
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:
|
||||||
|
Reference in New Issue
Block a user