Commit c1885d22 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-13273 Confusion between table alias and ROW type variable

parent 9e53a6bd
...@@ -129,15 +129,17 @@ CALL p1(); ...@@ -129,15 +129,17 @@ CALL p1();
ERROR 21000: Operand should contain 2 column(s) ERROR 21000: Operand should contain 2 column(s)
DROP PROCEDURE p1; DROP PROCEDURE p1;
# #
# Bad usage of a scalar variable as a row # Scalar variable vs table alias cause no ambiguity
# #
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
BEGIN BEGIN
DECLARE a INT; DECLARE a INT;
SELECT a.x FROM t1; -- a.x is a table column here (not a row variable field)
SELECT a.x FROM a;
SELECT a.x FROM t1 a;
END; END;
$$ $$
ERROR HY000: 'a' is not a row variable DROP PROCEDURE p1;
# #
# Using the entire ROW variable in select list # Using the entire ROW variable in select list
# #
...@@ -2166,3 +2168,81 @@ rec1.a rec1.b ...@@ -2166,3 +2168,81 @@ rec1.a rec1.b
10 b10 10 b10
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
#
# MDEV-13273 Confusion between table alias and ROW type variable
#
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1()
BEGIN
DECLARE a INT;
DECLARE b INT;
-- a.c1 is a table column
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 0;
SELECT b;
END;
$$
CALL p1;
b
0
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1()
BEGIN
DECLARE a ROW (c1 INT, c2 INT) DEFAULT ROW(101,102);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 102;
SELECT b;
END;
$$
CALL p1;
b
101
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1()
BEGIN
DECLARE a ROW TYPE OF t1 DEFAULT ROW (10,20);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
CALL p1;
b
10
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1()
BEGIN
DECLARE cur1 CURSOR FOR SELECT * FROM t1;
BEGIN
DECLARE a ROW TYPE OF cur1 DEFAULT ROW (10,20);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
END;
$$
CALL p1;
b
10
DROP PROCEDURE p1;
DROP TABLE t1;
...@@ -143,16 +143,18 @@ CALL p1(); ...@@ -143,16 +143,18 @@ CALL p1();
ERROR 21000: Operand should contain 2 column(s) ERROR 21000: Operand should contain 2 column(s)
DROP PROCEDURE p1; DROP PROCEDURE p1;
# #
# Bad usage of a scalar variable as a row # Scalar variable vs table alias cause no ambiguity
# #
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
AS AS
a INT; a INT;
BEGIN BEGIN
SELECT a.x FROM t1; -- a.x is a table column here (not a row variable field)
SELECT a.x FROM a;
SELECT a.x FROM t1 a;
END; END;
$$ $$
ERROR HY000: 'a' is not a row variable DROP PROCEDURE p1;
# #
# Using the entire ROW variable in select list # Using the entire ROW variable in select list
# #
...@@ -2988,3 +2990,83 @@ rec.b ...@@ -2988,3 +2990,83 @@ rec.b
b0 b0
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
#
# MDEV-13273 Confusion between table alias and ROW type variable
#
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1
AS
a INT;
b INT;
BEGIN
-- a.c1 is a table column
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 0;
SELECT b;
END;
$$
CALL p1;
b
0
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1
AS
a ROW (c1 INT, c2 INT) := ROW(101,102);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 102;
SELECT b;
END;
$$
CALL p1;
b
101
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1
AS
a t1%ROWTYPE := ROW (10,20);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
CALL p1;
b
10
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
CREATE PROCEDURE p1
AS
CURSOR cur1 IS SELECT * FROM t1;
a cur1%ROWTYPE := ROW (10,20);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
CALL p1;
b
10
DROP PROCEDURE p1;
DROP TABLE t1;
...@@ -175,20 +175,21 @@ DROP PROCEDURE p1; ...@@ -175,20 +175,21 @@ DROP PROCEDURE p1;
--echo # --echo #
--echo # Bad usage of a scalar variable as a row --echo # Scalar variable vs table alias cause no ambiguity
--echo # --echo #
DELIMITER $$; DELIMITER $$;
--error ER_UNKNOWN_ERROR
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
AS AS
a INT; a INT;
BEGIN BEGIN
SELECT a.x FROM t1; -- a.x is a table column here (not a row variable field)
SELECT a.x FROM a;
SELECT a.x FROM t1 a;
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
DROP PROCEDURE p1;
--echo # --echo #
--echo # Using the entire ROW variable in select list --echo # Using the entire ROW variable in select list
...@@ -2288,3 +2289,89 @@ DELIMITER ;$$ ...@@ -2288,3 +2289,89 @@ DELIMITER ;$$
CALL p1(); CALL p1();
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo #
--echo # MDEV-13273 Confusion between table alias and ROW type variable
--echo #
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1
AS
a INT;
b INT;
BEGIN
-- a.c1 is a table column
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 0;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1
AS
a ROW (c1 INT, c2 INT) := ROW(101,102);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 102;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1
AS
a t1%ROWTYPE := ROW (10,20);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1
AS
CURSOR cur1 IS SELECT * FROM t1;
a cur1%ROWTYPE := ROW (10,20);
b INT;
BEGIN
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
...@@ -161,18 +161,20 @@ DROP PROCEDURE p1; ...@@ -161,18 +161,20 @@ DROP PROCEDURE p1;
--echo # --echo #
--echo # Bad usage of a scalar variable as a row --echo # Scalar variable vs table alias cause no ambiguity
--echo # --echo #
DELIMITER $$; DELIMITER $$;
--error ER_UNKNOWN_ERROR
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
BEGIN BEGIN
DECLARE a INT; DECLARE a INT;
SELECT a.x FROM t1; -- a.x is a table column here (not a row variable field)
SELECT a.x FROM a;
SELECT a.x FROM t1 a;
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
DROP PROCEDURE p1;
--echo # --echo #
...@@ -1385,3 +1387,87 @@ DELIMITER ;$$ ...@@ -1385,3 +1387,87 @@ DELIMITER ;$$
CALL p1(); CALL p1();
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo #
--echo # MDEV-13273 Confusion between table alias and ROW type variable
--echo #
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE a INT;
DECLARE b INT;
-- a.c1 is a table column
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 0;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE a ROW (c1 INT, c2 INT) DEFAULT ROW(101,102);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 102;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE a ROW TYPE OF t1 DEFAULT ROW (10,20);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (0,0);
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE cur1 CURSOR FOR SELECT * FROM t1;
BEGIN
DECLARE a ROW TYPE OF cur1 DEFAULT ROW (10,20);
DECLARE b INT;
-- a.c1 is a ROW variable field
SELECT a.c1 INTO b
FROM t1 a
WHERE a.c2 = 20;
SELECT b;
END;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
...@@ -6452,7 +6452,10 @@ Item *LEX::create_item_ident(THD *thd, ...@@ -6452,7 +6452,10 @@ Item *LEX::create_item_ident(THD *thd,
uint pos_in_q, uint length_in_q) uint pos_in_q, uint length_in_q)
{ {
sp_variable *spv; sp_variable *spv;
if (spcont && (spv= spcont->find_variable(a, false))) if (spcont && (spv= spcont->find_variable(a, false)) &&
(spv->field_def.is_row() ||
spv->field_def.is_table_rowtype_ref() ||
spv->field_def.is_cursor_rowtype_ref()))
return create_item_spvar_row_field(thd, a, b, spv, pos_in_q, length_in_q); return create_item_spvar_row_field(thd, a, b, spv, pos_in_q, length_in_q);
if ((thd->variables.sql_mode & MODE_ORACLE) && b->length == 7) if ((thd->variables.sql_mode & MODE_ORACLE) && b->length == 7)
......
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