summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-12-07 15:54:27 +0400
committerAlexander Barkov <bar@mariadb.org>2017-12-07 15:54:27 +0400
commit08dae447118b49b99499ccc456c9a72afa651f24 (patch)
treef77698fa7b5a4978f0efbe98a28667771a5d4d99
parent6d4b0958dc5a6a2d44dcccf083ec9e136bb4a38e (diff)
downloadmariadb-git-08dae447118b49b99499ccc456c9a72afa651f24.tar.gz
MDEV-14228 MariaDB crashes with function
-rw-r--r--mysql-test/r/sp-row.result4
-rw-r--r--mysql-test/r/sp.result57
-rw-r--r--mysql-test/r/subselect.result12
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result12
-rw-r--r--mysql-test/r/subselect_no_mat.result12
-rw-r--r--mysql-test/r/subselect_no_opts.result12
-rw-r--r--mysql-test/r/subselect_no_scache.result12
-rw-r--r--mysql-test/r/subselect_no_semijoin.result12
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-row.result4
-rw-r--r--mysql-test/suite/compat/oracle/r/sp.result63
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-row.test4
-rw-r--r--mysql-test/suite/compat/oracle/t/sp.test87
-rw-r--r--mysql-test/t/sp-row.test4
-rw-r--r--mysql-test/t/sp.test80
-rw-r--r--mysql-test/t/subselect.test12
-rw-r--r--sql/item.cc10
-rw-r--r--sql/item_func.cc13
17 files changed, 357 insertions, 53 deletions
diff --git a/mysql-test/r/sp-row.result b/mysql-test/r/sp-row.result
index adb67030feb..d3be7c2a9b9 100644
--- a/mysql-test/r/sp-row.result
+++ b/mysql-test/r/sp-row.result
@@ -210,7 +210,7 @@ SELECT a=1;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
BEGIN
@@ -219,7 +219,7 @@ SELECT 1=a;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
DROP PROCEDURE p1;
#
# Passing the entire ROW to a stored function
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 9fad95421cf..f40e6033b9f 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -8291,3 +8291,60 @@ rec=(10)
c
rec=(20)
DROP PROCEDURE p1;
+#
+# MDEV-14228 MariaDB crashes with function
+#
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v VARCHAR(16);
+FOR v IN (SELECT DISTINCT c FROM t1)
+DO
+IF (v = 'bar') THEN
+SELECT 1 INTO @a;
+END IF;
+END FOR;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v ROW TYPE OF t1;
+IF v = 'bar' THEN
+RETURN 'eq';
+END IF;
+RETURN 'ne';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v ROW(a INT);
+IF v = 'bar' THEN
+RETURN 'eq';
+END IF;
+RETURN 'ne';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT v IN ('a','b');
+END $$
+ERROR HY000: Illegal parameter data types row and varchar for operation 'in'
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT 'a' IN (v,'b');
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT 'a' IN ('b',v);
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 7ba8b545e6a..1e0d5f31a7a 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -384,10 +384,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2865,13 +2865,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index c09f3c94710..ac02ec71920 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -388,10 +388,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2868,13 +2868,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 0aefeaf44d9..dd89f2f2776 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -391,10 +391,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2871,13 +2871,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 92defb3c36d..c5c4019768c 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -387,10 +387,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2867,13 +2867,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index b47dab2e79e..1af56e5b683 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -390,10 +390,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2871,13 +2871,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 9d04ddd9829..4276e5ef638 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -387,10 +387,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -2867,13 +2867,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result
index f95817420f1..9557a24a1da 100644
--- a/mysql-test/suite/compat/oracle/r/sp-row.result
+++ b/mysql-test/suite/compat/oracle/r/sp-row.result
@@ -232,7 +232,7 @@ SELECT a=1;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
AS
@@ -242,7 +242,7 @@ SELECT 1=a;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
DROP PROCEDURE p1;
#
# Passing the entire ROW to a stored function
diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result
index 2bf4f50e6d5..2f565b0a183 100644
--- a/mysql-test/suite/compat/oracle/r/sp.result
+++ b/mysql-test/suite/compat/oracle/r/sp.result
@@ -2432,3 +2432,66 @@ a b
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
+#
+# MDEV-14228 MariaDB crashes with function
+#
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v VARCHAR2(16);
+BEGIN
+FOR v IN (SELECT DISTINCT c FROM t1)
+LOOP
+IF (v = 'bar') THEN
+SELECT 1 INTO @a;
+END IF;
+END LOOP;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v t1%ROWTYPE;
+BEGIN
+IF v = 'bar' THEN
+NULL;
+END IF;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v ROW(a INT);
+BEGIN
+IF v = 'bar' THEN
+NULL;
+END IF;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+DROP TABLE t1;
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT v IN ('a','b');
+END $$
+ERROR HY000: Illegal parameter data types row and varchar for operation 'in'
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT 'a' IN (v,'b');
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT 'a' IN ('b',v);
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
diff --git a/mysql-test/suite/compat/oracle/t/sp-row.test b/mysql-test/suite/compat/oracle/t/sp-row.test
index b26cae5a5c6..469494ad228 100644
--- a/mysql-test/suite/compat/oracle/t/sp-row.test
+++ b/mysql-test/suite/compat/oracle/t/sp-row.test
@@ -295,7 +295,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
@@ -309,7 +309,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test
index e7adbb5403a..693569d184c 100644
--- a/mysql-test/suite/compat/oracle/t/sp.test
+++ b/mysql-test/suite/compat/oracle/t/sp.test
@@ -2260,3 +2260,90 @@ CALL p1();
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-14228 MariaDB crashes with function
+--echo #
+
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v VARCHAR2(16);
+BEGIN
+ FOR v IN (SELECT DISTINCT c FROM t1)
+ LOOP
+ IF (v = 'bar') THEN
+ SELECT 1 INTO @a;
+ END IF;
+ END LOOP;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v t1%ROWTYPE;
+BEGIN
+ IF v = 'bar' THEN
+ NULL;
+ END IF;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v ROW(a INT);
+BEGIN
+ IF v = 'bar' THEN
+ NULL;
+ END IF;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DROP TABLE t1;
+
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT v IN ('a','b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT 'a' IN (v,'b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT 'a' IN ('b',v);
+END $$
+DELIMITER ;$$
+
diff --git a/mysql-test/t/sp-row.test b/mysql-test/t/sp-row.test
index 5928c8cb76d..837e24c89c0 100644
--- a/mysql-test/t/sp-row.test
+++ b/mysql-test/t/sp-row.test
@@ -274,7 +274,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
@@ -287,7 +287,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 08aa70df03e..82ad655593a 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9771,3 +9771,83 @@ $$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
+
+
+--echo #
+--echo # MDEV-14228 MariaDB crashes with function
+--echo #
+
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v VARCHAR(16);
+ FOR v IN (SELECT DISTINCT c FROM t1)
+ DO
+ IF (v = 'bar') THEN
+ SELECT 1 INTO @a;
+ END IF;
+ END FOR;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v ROW TYPE OF t1;
+ IF v = 'bar' THEN
+ RETURN 'eq';
+ END IF;
+ RETURN 'ne';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v ROW(a INT);
+ IF v = 'bar' THEN
+ RETURN 'eq';
+ END IF;
+ RETURN 'ne';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DROP TABLE t1;
+
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+ DECLARE v ROW(a INT);
+ SELECT v IN ('a','b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+ SELECT 'a' IN (v,'b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+ DECLARE v ROW(a INT);
+ SELECT 'a' IN ('b',v);
+END $$
+DELIMITER ;$$
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 5e1e1494fee..ce0b949fcac 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -188,10 +188,10 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
@@ -1834,13 +1834,13 @@ drop table t1, t2;
#
create table t1 (a int, b int);
insert into t1 values (1,2);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select 1 = (select * from t1);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (select * from t1) = 1;
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (1,2) = (select a from t1);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (select a from t1) = (1,2);
-- error ER_OPERAND_COLUMNS
select (1,2,3) = (select * from t1);
diff --git a/sql/item.cc b/sql/item.cc
index c9f5462cca9..6fdcd29af29 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1148,6 +1148,16 @@ bool Item::check_type_can_return_text(const char *opname) const
bool Item::check_type_scalar(const char *opname) const
{
+ /*
+ fixed==true usually means than the Item has an initialized
+ and reliable data type handler and attributes.
+ Item_outer_ref is an exception. It copies the data type and the attributes
+ from the referenced Item in the constructor, but then sets "fixed" to false,
+ and re-fixes itself again in fix_inner_refs().
+ This hack in Item_outer_ref should probably be refactored eventually.
+ Discuss with Sanja.
+ */
+ DBUG_ASSERT(fixed || type() == REF_ITEM);
const Type_handler *handler= type_handler();
if (handler->is_scalar_type())
return false;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index be5e5064d60..a6134c009d5 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -153,12 +153,19 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
bool Item_func::check_argument_types_like_args0() const
{
- uint cols;
- if (arg_count == 0)
+ if (arg_count < 2)
return false;
- cols= args[0]->cols();
+ uint cols= args[0]->cols();
+ bool is_scalar= args[0]->type_handler()->is_scalar_type();
for (uint i= 1; i < arg_count; i++)
{
+ if (is_scalar != args[i]->type_handler()->is_scalar_type())
+ {
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
+ args[0]->type_handler()->name().ptr(),
+ args[i]->type_handler()->name().ptr(), func_name());
+ return true;
+ }
if (args[i]->check_cols(cols))
return true;
}