mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-13273 Confusion between table alias and ROW type variable
This commit is contained in:
@ -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
|
|||||||
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();
|
|||||||
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
|
|||||||
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;
|
|||||||
|
|
||||||
|
|
||||||
--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 ;$$
|
|||||||
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;
|
|||||||
|
|
||||||
|
|
||||||
--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 ;$$
|
|||||||
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,
|
|||||||
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)
|
||||||
|
Reference in New Issue
Block a user