mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into bodhi.local:/opt/local/work/mysql-5.1-runtime-merge mysql-test/r/ps.result: Auto merged mysql-test/t/func_gconcat.test: Auto merged mysql-test/t/ps.test: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/log_event.cc: Auto merged sql/mysql_priv.h: Auto merged sql/set_var.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_view.cc: Auto merged sql/sql_yacc.yy: Auto merged tests/mysql_client_test.c: Auto merged mysql-test/r/view.result: Manual merge. mysql-test/t/view.test: Manual merge.
This commit is contained in:
@ -100,6 +100,8 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
|
|||||||
/*
|
/*
|
||||||
The following must be sorted so that simple intervals comes first.
|
The following must be sorted so that simple intervals comes first.
|
||||||
(get_interval_value() depends on this)
|
(get_interval_value() depends on this)
|
||||||
|
When updating this enum please update
|
||||||
|
LEX_STRING interval_type_to_name[] in sql/time.cc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum interval_type
|
enum interval_type
|
||||||
|
@ -546,7 +546,103 @@ GROUP_CONCAT(Track SEPARATOR ', ')
|
|||||||
CAD
|
CAD
|
||||||
DEALLOCATE PREPARE STMT;
|
DEALLOCATE PREPARE STMT;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 4.1 tests
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (i INT, INDEX(i));
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(COUNT(i) = 1) COUNT(i)
|
||||||
|
0 0
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(COUNT(i) = 1) COUNT(i)
|
||||||
|
1 1
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(COUNT(i) = 1) COUNT(i)
|
||||||
|
0 0
|
||||||
|
PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(AVG(i) = 1) AVG(i)
|
||||||
|
NULL NULL
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(AVG(i) = 1) AVG(i)
|
||||||
|
1 1.0000
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(AVG(i) = 1) AVG(i)
|
||||||
|
NULL NULL
|
||||||
|
PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(VARIANCE(i) = 1) VARIANCE(i)
|
||||||
|
NULL NULL
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(VARIANCE(i) = 1) VARIANCE(i)
|
||||||
|
0 0.0000
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(VARIANCE(i) = 1) VARIANCE(i)
|
||||||
|
NULL NULL
|
||||||
|
PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(STDDEV(i) = 1) STDDEV(i)
|
||||||
|
NULL NULL
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(STDDEV(i) = 1) STDDEV(i)
|
||||||
|
0 0.0000
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(STDDEV(i) = 1) STDDEV(i)
|
||||||
|
NULL NULL
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_OR(i) = 1) BIT_OR(i)
|
||||||
|
0 0
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_OR(i) = 1) BIT_OR(i)
|
||||||
|
1 1
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_OR(i) = 1) BIT_OR(i)
|
||||||
|
0 0
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_AND(i) = 1) BIT_AND(i)
|
||||||
|
0 18446744073709551615
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_AND(i) = 1) BIT_AND(i)
|
||||||
|
1 1
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_AND(i) = 1) BIT_AND(i)
|
||||||
|
0 18446744073709551615
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_XOR(i) = 1) BIT_XOR(i)
|
||||||
|
0 0
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_XOR(i) = 1) BIT_XOR(i)
|
||||||
|
1 1
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
(BIT_XOR(i) = 1) BIT_XOR(i)
|
||||||
|
0 0
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
End of 4.1 tests.
|
||||||
create table t1 (a varchar(20));
|
create table t1 (a varchar(20));
|
||||||
insert into t1 values ('foo');
|
insert into t1 values ('foo');
|
||||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||||
@ -1360,6 +1456,7 @@ i
|
|||||||
1
|
1
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
create procedure proc_1() reset query cache;
|
create procedure proc_1() reset query cache;
|
||||||
call proc_1();
|
call proc_1();
|
||||||
|
@ -1226,6 +1226,30 @@ END;
|
|||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS bug14702()
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS bug14702()
|
||||||
BEGIN
|
BEGIN
|
||||||
END' at line 1
|
END' at line 1
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
|
||||||
|
ERROR HY000: View's SELECT contains a 'INTO' clause
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
|
||||||
|
ERROR HY000: View's SELECT contains a 'INTO' clause
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
|
||||||
|
ERROR HY000: View's SELECT contains a 'INTO' clause
|
||||||
|
CREATE PROCEDURE bug20953()
|
||||||
|
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
|
||||||
|
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
|
||||||
|
ERROR HY000: View's SELECT contains a subquery in the FROM clause
|
||||||
|
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
|
||||||
|
ERROR HY000: View's SELECT contains a variable or parameter
|
||||||
|
CREATE PROCEDURE bug20953()
|
||||||
|
BEGIN
|
||||||
|
DECLARE i INT;
|
||||||
|
CREATE VIEW v AS SELECT i;
|
||||||
|
END |
|
||||||
|
ERROR HY000: View's SELECT contains a variable or parameter
|
||||||
|
PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
|
||||||
|
ERROR HY000: View's SELECT contains a variable or parameter
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
drop function if exists bug16164;
|
drop function if exists bug16164;
|
||||||
create function bug16164() returns int
|
create function bug16164() returns int
|
||||||
@ -1234,9 +1258,9 @@ show authors;
|
|||||||
return 42;
|
return 42;
|
||||||
end|
|
end|
|
||||||
ERROR 0A000: Not allowed to return a result set from a function
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
drop function if exists bug20701|
|
drop function if exists bug20701;
|
||||||
create function bug20701() returns varchar(25) binary return "test"|
|
create function bug20701() returns varchar(25) binary return "test";
|
||||||
ERROR 42000: This version of MySQL doesn't yet support 'return value collation'
|
ERROR 42000: This version of MySQL doesn't yet support 'return value collation'
|
||||||
create function bug20701() returns varchar(25) return "test"|
|
create function bug20701() returns varchar(25) return "test";
|
||||||
drop function bug20701|
|
drop function bug20701;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -12,6 +12,9 @@ create table t1 (a int, b int);
|
|||||||
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
||||||
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
|
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
|
||||||
ERROR HY000: View's SELECT contains a variable or parameter
|
ERROR HY000: View's SELECT contains a variable or parameter
|
||||||
|
create view v1 (c,d) as select a,b from t1
|
||||||
|
where a = @@global.max_user_connections;
|
||||||
|
ERROR HY000: View's SELECT contains a variable or parameter
|
||||||
create view v1 (c) as select b+1 from t1;
|
create view v1 (c) as select b+1 from t1;
|
||||||
select c from v1;
|
select c from v1;
|
||||||
c
|
c
|
||||||
@ -596,11 +599,6 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function
|
|||||||
drop view v1;
|
drop view v1;
|
||||||
create view v1 (a,a) as select 'a','a';
|
create view v1 (a,a) as select 'a','a';
|
||||||
ERROR 42S21: Duplicate column name 'a'
|
ERROR 42S21: Duplicate column name 'a'
|
||||||
drop procedure if exists p1;
|
|
||||||
create procedure p1 () begin declare v int; create view v1 as select v; end;//
|
|
||||||
call p1();
|
|
||||||
ERROR HY000: View's SELECT contains a variable or parameter
|
|
||||||
drop procedure p1;
|
|
||||||
create table t1 (col1 int,col2 char(22));
|
create table t1 (col1 int,col2 char(22));
|
||||||
insert into t1 values(5,'Hello, world of views');
|
insert into t1 values(5,'Hello, world of views');
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
@ -886,6 +884,8 @@ ERROR HY000: View's SELECT contains a 'INTO' clause
|
|||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
create view v1 as select a from t1 procedure analyse();
|
create view v1 as select a from t1 procedure analyse();
|
||||||
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
|
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
|
||||||
|
create view v1 as select 1 from (select 1) as d1;
|
||||||
|
ERROR HY000: View's SELECT contains a subquery in the FROM clause
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (s1 int, primary key (s1));
|
create table t1 (s1 int, primary key (s1));
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
@ -2956,6 +2956,18 @@ View Create View
|
|||||||
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
|
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP VIEW IF EXISTS v1;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
CREATE VIEW v1 AS SELECT MAX(i) FROM t1;
|
||||||
|
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
SET NEW.i = (SELECT * FROM v1) + 1;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1);
|
||||||
|
UPDATE t1 SET i= f1();
|
||||||
|
DROP FUNCTION f1;
|
||||||
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
||||||
CREATE VIEW v1 AS SELECT id, val FROM t1 WHERE val >= 1 AND val <= 5 WITH CHECK OPTION;
|
CREATE VIEW v1 AS SELECT id, val FROM t1 WHERE val >= 1 AND val <= 5 WITH CHECK OPTION;
|
||||||
INSERT INTO v1 (val) VALUES (2);
|
INSERT INTO v1 (val) VALUES (2);
|
||||||
|
@ -98,7 +98,7 @@ select ifnull(group_concat(concat(t1.id, ':', t1.name)), 'shortname') as 'withou
|
|||||||
select distinct ifnull(group_concat(concat(t1.id, ':', t1.name)), 'shortname') as 'with distinct: cutoff at length of shortname' from t1;
|
select distinct ifnull(group_concat(concat(t1.id, ':', t1.name)), 'shortname') as 'with distinct: cutoff at length of shortname' from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# check zero rows
|
# check zero rows (bug#836)
|
||||||
create table t1(id int);
|
create table t1(id int);
|
||||||
create table t2(id int);
|
create table t2(id int);
|
||||||
insert into t1 values(0),(1);
|
insert into t1 values(0),(1);
|
||||||
|
@ -1040,7 +1040,80 @@ EXECUTE STMT USING @id,@id;
|
|||||||
DEALLOCATE PREPARE STMT;
|
DEALLOCATE PREPARE STMT;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 4.1 tests
|
#
|
||||||
|
# BUG#21354: (COUNT(*) = 1) not working in SELECT inside prepared
|
||||||
|
# statement
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT, INDEX(i));
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 1;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
SET @a = 0;
|
||||||
|
EXECUTE stmt USING @a;
|
||||||
|
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 4.1 tests.
|
||||||
|
|
||||||
|
|
||||||
############################# 5.0 tests start ################################
|
############################# 5.0 tests start ################################
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@ -1437,6 +1510,26 @@ DEALLOCATE PREPARE stmt;
|
|||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#21856: Prepared Statments: crash if bad create
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
let $iterations= 100;
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
while ($iterations > 0)
|
||||||
|
{
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
PREPARE stmt FROM "CREATE PROCEDURE p1()";
|
||||||
|
dec $iterations;
|
||||||
|
}
|
||||||
|
--enable_query_log
|
||||||
|
--enable_result_log
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1769,6 +1769,47 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#20953: create proc with a create view that uses local
|
||||||
|
# vars/params should fail to create
|
||||||
|
#
|
||||||
|
# See test case for what syntax is forbidden in a view.
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
|
||||||
|
# We do not have to drop this procedure and view because they won't be
|
||||||
|
# created.
|
||||||
|
--error ER_VIEW_SELECT_CLAUSE
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
|
||||||
|
--error ER_VIEW_SELECT_CLAUSE
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
|
||||||
|
--error ER_VIEW_SELECT_CLAUSE
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
|
||||||
|
--error ER_VIEW_SELECT_CLAUSE
|
||||||
|
CREATE PROCEDURE bug20953()
|
||||||
|
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
|
||||||
|
--error ER_VIEW_SELECT_DERIVED
|
||||||
|
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
|
||||||
|
--error ER_VIEW_SELECT_VARIABLE
|
||||||
|
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
|
||||||
|
delimiter |;
|
||||||
|
--error ER_VIEW_SELECT_VARIABLE
|
||||||
|
CREATE PROCEDURE bug20953()
|
||||||
|
BEGIN
|
||||||
|
DECLARE i INT;
|
||||||
|
CREATE VIEW v AS SELECT i;
|
||||||
|
END |
|
||||||
|
delimiter ;|
|
||||||
|
--error ER_VIEW_SELECT_VARIABLE
|
||||||
|
PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
#
|
#
|
||||||
@ -1788,12 +1829,14 @@ begin
|
|||||||
show authors;
|
show authors;
|
||||||
return 42;
|
return 42;
|
||||||
end|
|
end|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#20701: BINARY keyword should be forbidden in stored routines
|
# BUG#20701: BINARY keyword should be forbidden in stored routines
|
||||||
#
|
#
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop function if exists bug20701|
|
drop function if exists bug20701;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
#
|
#
|
||||||
# This was disabled in 5.1.12. See bug #20701
|
# This was disabled in 5.1.12. See bug #20701
|
||||||
@ -1801,17 +1844,19 @@ drop function if exists bug20701|
|
|||||||
# be removed.
|
# be removed.
|
||||||
#
|
#
|
||||||
--error ER_NOT_SUPPORTED_YET
|
--error ER_NOT_SUPPORTED_YET
|
||||||
create function bug20701() returns varchar(25) binary return "test"|
|
create function bug20701() returns varchar(25) binary return "test";
|
||||||
create function bug20701() returns varchar(25) return "test"|
|
create function bug20701() returns varchar(25) return "test";
|
||||||
drop function bug20701|
|
drop function bug20701;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
#--disable_warnings
|
#--disable_warnings
|
||||||
#drop procedure if exists bugNNNN|
|
#drop procedure if exists bugNNNN;
|
||||||
#drop function if exists bugNNNN|
|
#drop function if exists bugNNNN;
|
||||||
#--enable_warnings
|
#--enable_warnings
|
||||||
#create procedure bugNNNN...
|
#create procedure bugNNNN...
|
||||||
#create function bugNNNN...
|
#create function bugNNNN...
|
||||||
|
@ -23,8 +23,11 @@ create table t1 (a int, b int);
|
|||||||
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
||||||
|
|
||||||
# view with variable
|
# view with variable
|
||||||
-- error 1351
|
-- error ER_VIEW_SELECT_VARIABLE
|
||||||
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
|
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
|
||||||
|
-- error ER_VIEW_SELECT_VARIABLE
|
||||||
|
create view v1 (c,d) as select a,b from t1
|
||||||
|
where a = @@global.max_user_connections;
|
||||||
|
|
||||||
# simple view
|
# simple view
|
||||||
create view v1 (c) as select b+1 from t1;
|
create view v1 (c) as select b+1 from t1;
|
||||||
@ -486,19 +489,6 @@ drop view v1;
|
|||||||
-- error 1060
|
-- error 1060
|
||||||
create view v1 (a,a) as select 'a','a';
|
create view v1 (a,a) as select 'a','a';
|
||||||
|
|
||||||
#
|
|
||||||
# SP variables inside view test
|
|
||||||
#
|
|
||||||
--disable_warnings
|
|
||||||
drop procedure if exists p1;
|
|
||||||
--enable_warnings
|
|
||||||
delimiter //;
|
|
||||||
create procedure p1 () begin declare v int; create view v1 as select v; end;//
|
|
||||||
delimiter ;//
|
|
||||||
-- error 1351
|
|
||||||
call p1();
|
|
||||||
drop procedure p1;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# updatablity should be transitive
|
# updatablity should be transitive
|
||||||
#
|
#
|
||||||
@ -820,6 +810,8 @@ create view v1 as select 5 into outfile 'ttt';
|
|||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
-- error 1350
|
-- error 1350
|
||||||
create view v1 as select a from t1 procedure analyse();
|
create view v1 as select a from t1 procedure analyse();
|
||||||
|
-- error ER_VIEW_SELECT_DERIVED
|
||||||
|
create view v1 as select 1 from (select 1) as d1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -2886,6 +2878,38 @@ DROP VIEW v1;
|
|||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# Bug#19111: TRIGGERs selecting from a VIEW on the firing base table
|
||||||
|
# fail
|
||||||
|
#
|
||||||
|
# Allow to select from a view on a table being modified in a trigger
|
||||||
|
# and stored function, since plain select is allowed there.
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP VIEW IF EXISTS v1;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS SELECT MAX(i) FROM t1;
|
||||||
|
|
||||||
|
# Plain 'SET NEW.i = (SELECT MAX(i) FROM t1) + 1' works, so select
|
||||||
|
# from a view should work too.
|
||||||
|
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
SET NEW.i = (SELECT * FROM v1) + 1;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
# Plain 'RETURN (SELECT MAX(i) FROM t1)' works in INSERT, so select
|
||||||
|
# from a view should work too.
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1);
|
||||||
|
UPDATE t1 SET i= f1();
|
||||||
|
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
|
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
|
||||||
#
|
#
|
||||||
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
||||||
|
@ -886,14 +886,29 @@ Event_queue_element::load_from_row(TABLE *table)
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In DB the values start from 1 but enum interval_type starts
|
We load the interval type from disk as string and then map it to
|
||||||
from 0
|
an integer. This decouples the values of enum interval_type
|
||||||
|
and values actually stored on disk. Therefore the type can be
|
||||||
|
reordered without risking incompatibilities of data between versions.
|
||||||
*/
|
*/
|
||||||
if (!table->field[ET_FIELD_TRANSIENT_INTERVAL]->is_null())
|
if (!table->field[ET_FIELD_TRANSIENT_INTERVAL]->is_null())
|
||||||
interval= (interval_type) ((ulonglong)
|
{
|
||||||
table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_int() - 1);
|
int i;
|
||||||
else
|
char buff[MAX_FIELD_WIDTH];
|
||||||
interval= (interval_type) 0;
|
String str(buff, sizeof(buff), &my_charset_bin);
|
||||||
|
LEX_STRING tmp;
|
||||||
|
|
||||||
|
table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_str(&str);
|
||||||
|
if (!(tmp.length= str.length()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
tmp.str= str.c_ptr_safe();
|
||||||
|
|
||||||
|
i= find_string_in_array(interval_type_to_name, &tmp, system_charset_info);
|
||||||
|
if (i < 0)
|
||||||
|
goto error;
|
||||||
|
interval= (interval_type) i;
|
||||||
|
}
|
||||||
|
|
||||||
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&last_executed,
|
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&last_executed,
|
||||||
TIME_NO_ZERO_DATE);
|
TIME_NO_ZERO_DATE);
|
||||||
|
@ -188,11 +188,11 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
|
|||||||
fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
|
fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
|
||||||
|
|
||||||
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
|
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
|
||||||
/*
|
|
||||||
In the enum (C) intervals start from 0 but in mysql enum valid values
|
fields[ET_FIELD_TRANSIENT_INTERVAL]->
|
||||||
start from 1. Thus +1 offset is needed!
|
store(interval_type_to_name[et->interval].str,
|
||||||
*/
|
interval_type_to_name[et->interval].length,
|
||||||
fields[ET_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1, TRUE);
|
scs);
|
||||||
|
|
||||||
fields[ET_FIELD_EXECUTE_AT]->set_null();
|
fields[ET_FIELD_EXECUTE_AT]->set_null();
|
||||||
|
|
||||||
|
@ -1065,6 +1065,7 @@ longlong Item_sum_count::val_int()
|
|||||||
void Item_sum_count::cleanup()
|
void Item_sum_count::cleanup()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_sum_count::cleanup");
|
DBUG_ENTER("Item_sum_count::cleanup");
|
||||||
|
clear();
|
||||||
Item_sum_int::cleanup();
|
Item_sum_int::cleanup();
|
||||||
used_table_cache= ~(table_map) 0;
|
used_table_cache= ~(table_map) 0;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -260,9 +260,30 @@ public:
|
|||||||
Item_sum(THD *thd, Item_sum *item);
|
Item_sum(THD *thd, Item_sum *item);
|
||||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||||
virtual enum Sumfunctype sum_func () const=0;
|
virtual enum Sumfunctype sum_func () const=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is similar to add(), but it is called when the current
|
||||||
|
aggregation group changes. Thus it performs a combination of
|
||||||
|
clear() and add().
|
||||||
|
*/
|
||||||
inline bool reset() { clear(); return add(); };
|
inline bool reset() { clear(); return add(); };
|
||||||
|
|
||||||
|
/*
|
||||||
|
Prepare this item for evaluation of an aggregate value. This is
|
||||||
|
called by reset() when a group changes, or, for correlated
|
||||||
|
subqueries, between subquery executions. E.g. for COUNT(), this
|
||||||
|
method should set count= 0;
|
||||||
|
*/
|
||||||
virtual void clear()= 0;
|
virtual void clear()= 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called for the next row in the same group. Its
|
||||||
|
purpose is to aggregate the new value to the previous values in
|
||||||
|
the group (i.e. since clear() was called last time). For example,
|
||||||
|
for COUNT(), do count++.
|
||||||
|
*/
|
||||||
virtual bool add()=0;
|
virtual bool add()=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Called when new group is started and results are being saved in
|
Called when new group is started and results are being saved in
|
||||||
a temporary table. Similar to reset(), but must also store value in
|
a temporary table. Similar to reset(), but must also store value in
|
||||||
@ -306,7 +327,17 @@ public:
|
|||||||
void make_field(Send_field *field);
|
void make_field(Send_field *field);
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
void fix_num_length_and_dec();
|
void fix_num_length_and_dec();
|
||||||
void no_rows_in_result() { reset(); }
|
|
||||||
|
/*
|
||||||
|
This function is called by the execution engine to assign 'NO ROWS
|
||||||
|
FOUND' value to an aggregate item, when the underlying result set
|
||||||
|
has no rows. Such value, in a general case, may be different from
|
||||||
|
the default value of the item after 'clear()': e.g. a numeric item
|
||||||
|
may be initialized to 0 by clear() and to NULL by
|
||||||
|
no_rows_in_result().
|
||||||
|
*/
|
||||||
|
void no_rows_in_result() { clear(); }
|
||||||
|
|
||||||
virtual bool setup(THD *thd) {return 0;}
|
virtual bool setup(THD *thd) {return 0;}
|
||||||
virtual void make_unique() {}
|
virtual void make_unique() {}
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
@ -610,6 +641,11 @@ public:
|
|||||||
const char *func_name() const { return "avg("; }
|
const char *func_name() const { return "avg("; }
|
||||||
Item *copy_or_same(THD* thd);
|
Item *copy_or_same(THD* thd);
|
||||||
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
|
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
|
||||||
|
void cleanup()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
Item_sum_num::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_sum_variance;
|
class Item_sum_variance;
|
||||||
@ -689,6 +725,11 @@ public:
|
|||||||
Item *copy_or_same(THD* thd);
|
Item *copy_or_same(THD* thd);
|
||||||
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
|
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
|
||||||
enum Item_result result_type () const { return REAL_RESULT; }
|
enum Item_result result_type () const { return REAL_RESULT; }
|
||||||
|
void cleanup()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
Item_sum_num::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_sum_std;
|
class Item_sum_std;
|
||||||
@ -819,6 +860,11 @@ public:
|
|||||||
void update_field();
|
void update_field();
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{ decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
|
{ decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
|
||||||
|
void cleanup()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
Item_sum_int::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1485,6 +1485,8 @@ uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
|
|||||||
void unhex_type2(TYPELIB *lib);
|
void unhex_type2(TYPELIB *lib);
|
||||||
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||||
const char **end_of_word);
|
const char **end_of_word);
|
||||||
|
int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
|
||||||
|
CHARSET_INFO * const cs);
|
||||||
|
|
||||||
|
|
||||||
bool is_keyword(const char *name, uint len);
|
bool is_keyword(const char *name, uint len);
|
||||||
|
@ -107,4 +107,20 @@ public:
|
|||||||
bool bad_format_errors);
|
bool bad_format_errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Custom version of standard offsetof() macro which can be used to get
|
||||||
|
offsets of members in class for non-POD types (according to the current
|
||||||
|
version of C++ standard offsetof() macro can't be used in such cases and
|
||||||
|
attempt to do so causes warnings to be emitted, OTOH in many cases it is
|
||||||
|
still OK to assume that all instances of the class has the same offsets
|
||||||
|
for the same members).
|
||||||
|
|
||||||
|
This is temporary solution which should be removed once File_parser class
|
||||||
|
and related routines are refactored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define my_offsetof(TYPE, MEMBER) \
|
||||||
|
((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
|
||||||
|
|
||||||
#endif /* _PARSE_FILE_H_ */
|
#endif /* _PARSE_FILE_H_ */
|
||||||
|
@ -1365,6 +1365,10 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
|||||||
Also SELECT::exclude_from_table_unique_test used to exclude from check
|
Also SELECT::exclude_from_table_unique_test used to exclude from check
|
||||||
tables of main SELECT of multi-delete and multi-update
|
tables of main SELECT of multi-delete and multi-update
|
||||||
|
|
||||||
|
We also skip tables with TABLE_LIST::prelocking_placeholder set,
|
||||||
|
because we want to allow SELECTs from them, and their modification
|
||||||
|
will rise the error anyway.
|
||||||
|
|
||||||
TODO: when we will have table/view change detection we can do this check
|
TODO: when we will have table/view change detection we can do this check
|
||||||
only once for PS/SP
|
only once for PS/SP
|
||||||
|
|
||||||
@ -1411,12 +1415,13 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list)
|
|||||||
if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
|
if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
|
||||||
(! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
|
(! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
|
||||||
((!res->table || res->table != table->table) &&
|
((!res->table || res->table != table->table) &&
|
||||||
res->select_lex && !res->select_lex->exclude_from_table_unique_test))
|
res->select_lex && !res->select_lex->exclude_from_table_unique_test &&
|
||||||
|
!res->prelocking_placeholder))
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
If we found entry of this table or or table of SELECT which already
|
If we found entry of this table or table of SELECT which already
|
||||||
processed in derived table or top select of multi-update/multi-delete
|
processed in derived table or top select of multi-update/multi-delete
|
||||||
(exclude_from_table_unique_test).
|
(exclude_from_table_unique_test) or prelocking placeholder.
|
||||||
*/
|
*/
|
||||||
table_list= res->next_global;
|
table_list= res->next_global;
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
|
@ -151,7 +151,6 @@ void lex_start(THD *thd, const uchar *buf, uint length)
|
|||||||
lex->safe_to_cache_query= 1;
|
lex->safe_to_cache_query= 1;
|
||||||
lex->time_zone_tables_used= 0;
|
lex->time_zone_tables_used= 0;
|
||||||
lex->leaf_tables_insert= 0;
|
lex->leaf_tables_insert= 0;
|
||||||
lex->variables_used= 0;
|
|
||||||
lex->empty_field_list_on_rset= 0;
|
lex->empty_field_list_on_rset= 0;
|
||||||
lex->select_lex.select_number= 1;
|
lex->select_lex.select_number= 1;
|
||||||
lex->next_state=MY_LEX_START;
|
lex->next_state=MY_LEX_START;
|
||||||
|
@ -867,6 +867,25 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
st_parsing_options contains the flags for constructions that are
|
||||||
|
allowed in the current statement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct st_parsing_options
|
||||||
|
{
|
||||||
|
bool allows_variable;
|
||||||
|
bool allows_select_into;
|
||||||
|
bool allows_select_procedure;
|
||||||
|
bool allows_derived;
|
||||||
|
|
||||||
|
st_parsing_options()
|
||||||
|
: allows_variable(TRUE), allows_select_into(TRUE),
|
||||||
|
allows_select_procedure(TRUE), allows_derived(TRUE)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* The state of the lex parsing. This is saved in the THD struct */
|
/* The state of the lex parsing. This is saved in the THD struct */
|
||||||
|
|
||||||
typedef struct st_lex : public Query_tables_list
|
typedef struct st_lex : public Query_tables_list
|
||||||
@ -1023,7 +1042,7 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
bool stmt_prepare_mode;
|
bool stmt_prepare_mode;
|
||||||
bool safe_to_cache_query;
|
bool safe_to_cache_query;
|
||||||
bool subqueries, ignore;
|
bool subqueries, ignore;
|
||||||
bool variables_used;
|
st_parsing_options parsing_options;
|
||||||
ALTER_INFO alter_info;
|
ALTER_INFO alter_info;
|
||||||
/* Prepared statements SQL syntax:*/
|
/* Prepared statements SQL syntax:*/
|
||||||
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
||||||
|
@ -6088,14 +6088,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||||||
DBUG_ASSERT(thd->net.report_error);
|
DBUG_ASSERT(thd->net.report_error);
|
||||||
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
|
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
|
||||||
thd->is_fatal_error));
|
thd->is_fatal_error));
|
||||||
query_cache_abort(&thd->net);
|
|
||||||
lex->unit.cleanup();
|
/*
|
||||||
|
The first thing we do after parse error is freeing sp_head to
|
||||||
|
ensure that we have restored original memroot.
|
||||||
|
*/
|
||||||
if (lex->sphead)
|
if (lex->sphead)
|
||||||
{
|
{
|
||||||
/* Clean up after failed stored procedure/function */
|
/* Clean up after failed stored procedure/function */
|
||||||
delete lex->sphead;
|
delete lex->sphead;
|
||||||
lex->sphead= NULL;
|
lex->sphead= NULL;
|
||||||
}
|
}
|
||||||
|
query_cache_abort(&thd->net);
|
||||||
|
lex->unit.cleanup();
|
||||||
}
|
}
|
||||||
thd->proc_info="freeing items";
|
thd->proc_info="freeing items";
|
||||||
thd->end_statement();
|
thd->end_statement();
|
||||||
|
@ -2811,7 +2811,19 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
|
|
||||||
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
|
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
|
||||||
thd->net.report_error || init_param_array(this);
|
thd->net.report_error || init_param_array(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
The first thing we do after parse error is freeing sp_head to
|
||||||
|
ensure that we have restored original memroot.
|
||||||
|
*/
|
||||||
|
if (error && lex->sphead)
|
||||||
|
{
|
||||||
|
delete lex->sphead;
|
||||||
|
lex->sphead= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
lex->safe_to_cache_query= FALSE;
|
lex->safe_to_cache_query= FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
While doing context analysis of the query (in check_prepared_statement)
|
While doing context analysis of the query (in check_prepared_statement)
|
||||||
we allocate a lot of additional memory: for open tables, JOINs, derived
|
we allocate a lot of additional memory: for open tables, JOINs, derived
|
||||||
@ -2837,6 +2849,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
if (error == 0)
|
if (error == 0)
|
||||||
error= check_prepared_statement(this, name.str != 0);
|
error= check_prepared_statement(this, name.str != 0);
|
||||||
|
|
||||||
|
/* Free sp_head if check_prepared_statement() failed. */
|
||||||
if (error && lex->sphead)
|
if (error && lex->sphead)
|
||||||
{
|
{
|
||||||
delete lex->sphead;
|
delete lex->sphead;
|
||||||
|
@ -36,17 +36,17 @@ static File_option triggers_file_parameters[]=
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ C_STRING_WITH_LEN("triggers") },
|
{ C_STRING_WITH_LEN("triggers") },
|
||||||
offsetof(class Table_triggers_list, definitions_list),
|
my_offsetof(class Table_triggers_list, definitions_list),
|
||||||
FILE_OPTIONS_STRLIST
|
FILE_OPTIONS_STRLIST
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ C_STRING_WITH_LEN("sql_modes") },
|
{ C_STRING_WITH_LEN("sql_modes") },
|
||||||
offsetof(class Table_triggers_list, definition_modes_list),
|
my_offsetof(class Table_triggers_list, definition_modes_list),
|
||||||
FILE_OPTIONS_ULLLIST
|
FILE_OPTIONS_ULLLIST
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ C_STRING_WITH_LEN("definers") },
|
{ C_STRING_WITH_LEN("definers") },
|
||||||
offsetof(class Table_triggers_list, definers_list),
|
my_offsetof(class Table_triggers_list, definers_list),
|
||||||
FILE_OPTIONS_STRLIST
|
FILE_OPTIONS_STRLIST
|
||||||
},
|
},
|
||||||
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
|
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
|
||||||
@ -55,7 +55,7 @@ static File_option triggers_file_parameters[]=
|
|||||||
File_option sql_modes_parameters=
|
File_option sql_modes_parameters=
|
||||||
{
|
{
|
||||||
{ C_STRING_WITH_LEN("sql_modes") },
|
{ C_STRING_WITH_LEN("sql_modes") },
|
||||||
offsetof(class Table_triggers_list, definition_modes_list),
|
my_offsetof(class Table_triggers_list, definition_modes_list),
|
||||||
FILE_OPTIONS_ULLLIST
|
FILE_OPTIONS_ULLLIST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -236,25 +236,9 @@ bool mysql_create_view(THD *thd,
|
|||||||
bool res= FALSE;
|
bool res= FALSE;
|
||||||
DBUG_ENTER("mysql_create_view");
|
DBUG_ENTER("mysql_create_view");
|
||||||
|
|
||||||
if (lex->proc_list.first ||
|
/* This is ensured in the parser. */
|
||||||
lex->result)
|
DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
|
||||||
{
|
!lex->param_list.elements && !lex->derived_tables);
|
||||||
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ?
|
|
||||||
"INTO" :
|
|
||||||
"PROCEDURE"));
|
|
||||||
res= TRUE;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (lex->derived_tables ||
|
|
||||||
lex->variables_used || lex->param_list.elements)
|
|
||||||
{
|
|
||||||
int err= (lex->derived_tables ?
|
|
||||||
ER_VIEW_SELECT_DERIVED :
|
|
||||||
ER_VIEW_SELECT_VARIABLE);
|
|
||||||
my_message(err, ER(err), MYF(0));
|
|
||||||
res= TRUE;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != VIEW_CREATE_NEW)
|
if (mode != VIEW_CREATE_NEW)
|
||||||
{
|
{
|
||||||
@ -582,40 +566,40 @@ static const int num_view_backups= 3;
|
|||||||
*/
|
*/
|
||||||
static File_option view_parameters[]=
|
static File_option view_parameters[]=
|
||||||
{{{ C_STRING_WITH_LEN("query")},
|
{{{ C_STRING_WITH_LEN("query")},
|
||||||
offsetof(TABLE_LIST, query),
|
my_offsetof(TABLE_LIST, query),
|
||||||
FILE_OPTIONS_ESTRING},
|
FILE_OPTIONS_ESTRING},
|
||||||
{{ C_STRING_WITH_LEN("md5")},
|
{{ C_STRING_WITH_LEN("md5")},
|
||||||
offsetof(TABLE_LIST, md5),
|
my_offsetof(TABLE_LIST, md5),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{ C_STRING_WITH_LEN("updatable")},
|
{{ C_STRING_WITH_LEN("updatable")},
|
||||||
offsetof(TABLE_LIST, updatable_view),
|
my_offsetof(TABLE_LIST, updatable_view),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{ C_STRING_WITH_LEN("algorithm")},
|
{{ C_STRING_WITH_LEN("algorithm")},
|
||||||
offsetof(TABLE_LIST, algorithm),
|
my_offsetof(TABLE_LIST, algorithm),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{ C_STRING_WITH_LEN("definer_user")},
|
{{ C_STRING_WITH_LEN("definer_user")},
|
||||||
offsetof(TABLE_LIST, definer.user),
|
my_offsetof(TABLE_LIST, definer.user),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{ C_STRING_WITH_LEN("definer_host")},
|
{{ C_STRING_WITH_LEN("definer_host")},
|
||||||
offsetof(TABLE_LIST, definer.host),
|
my_offsetof(TABLE_LIST, definer.host),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{ C_STRING_WITH_LEN("suid")},
|
{{ C_STRING_WITH_LEN("suid")},
|
||||||
offsetof(TABLE_LIST, view_suid),
|
my_offsetof(TABLE_LIST, view_suid),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{ C_STRING_WITH_LEN("with_check_option")},
|
{{ C_STRING_WITH_LEN("with_check_option")},
|
||||||
offsetof(TABLE_LIST, with_check),
|
my_offsetof(TABLE_LIST, with_check),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{ C_STRING_WITH_LEN("revision")},
|
{{ C_STRING_WITH_LEN("revision")},
|
||||||
offsetof(TABLE_LIST, revision),
|
my_offsetof(TABLE_LIST, revision),
|
||||||
FILE_OPTIONS_REV},
|
FILE_OPTIONS_REV},
|
||||||
{{ C_STRING_WITH_LEN("timestamp")},
|
{{ C_STRING_WITH_LEN("timestamp")},
|
||||||
offsetof(TABLE_LIST, timestamp),
|
my_offsetof(TABLE_LIST, timestamp),
|
||||||
FILE_OPTIONS_TIMESTAMP},
|
FILE_OPTIONS_TIMESTAMP},
|
||||||
{{ C_STRING_WITH_LEN("create-version")},
|
{{ C_STRING_WITH_LEN("create-version")},
|
||||||
offsetof(TABLE_LIST, file_version),
|
my_offsetof(TABLE_LIST, file_version),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{ C_STRING_WITH_LEN("source")},
|
{{ C_STRING_WITH_LEN("source")},
|
||||||
offsetof(TABLE_LIST, source),
|
my_offsetof(TABLE_LIST, source),
|
||||||
FILE_OPTIONS_ESTRING},
|
FILE_OPTIONS_ESTRING},
|
||||||
{{NullS, 0}, 0,
|
{{NullS, 0}, 0,
|
||||||
FILE_OPTIONS_STRING}
|
FILE_OPTIONS_STRING}
|
||||||
|
139
sql/sql_yacc.yy
139
sql/sql_yacc.yy
@ -793,7 +793,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <item>
|
%type <item>
|
||||||
literal text_literal insert_ident order_ident
|
literal text_literal insert_ident order_ident
|
||||||
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
|
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
|
||||||
bool_term bool_factor bool_test bool_pri
|
variable variable_aux bool_term bool_factor bool_test bool_pri
|
||||||
predicate bit_expr bit_term bit_factor value_expr term factor
|
predicate bit_expr bit_term bit_factor value_expr term factor
|
||||||
table_wild simple_expr udf_expr
|
table_wild simple_expr udf_expr
|
||||||
expr_or_default set_expr_or_default interval_expr
|
expr_or_default set_expr_or_default interval_expr
|
||||||
@ -5953,32 +5953,7 @@ simple_expr:
|
|||||||
}
|
}
|
||||||
| literal
|
| literal
|
||||||
| param_marker
|
| param_marker
|
||||||
| '@' ident_or_text SET_VAR expr
|
| variable
|
||||||
{
|
|
||||||
$$= new Item_func_set_user_var($2,$4);
|
|
||||||
LEX *lex= Lex;
|
|
||||||
lex->uncacheable(UNCACHEABLE_RAND);
|
|
||||||
lex->variables_used= 1;
|
|
||||||
}
|
|
||||||
| '@' ident_or_text
|
|
||||||
{
|
|
||||||
$$= new Item_func_get_user_var($2);
|
|
||||||
LEX *lex= Lex;
|
|
||||||
lex->uncacheable(UNCACHEABLE_RAND);
|
|
||||||
lex->variables_used= 1;
|
|
||||||
}
|
|
||||||
| '@' '@' opt_var_ident_type ident_or_text opt_component
|
|
||||||
{
|
|
||||||
|
|
||||||
if ($4.str && $5.str && check_reserved_words(&$4))
|
|
||||||
{
|
|
||||||
yyerror(ER(ER_SYNTAX_ERROR));
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
if (!($$= get_system_var(YYTHD, $3, $4, $5)))
|
|
||||||
YYABORT;
|
|
||||||
Lex->variables_used= 1;
|
|
||||||
}
|
|
||||||
| sum_expr
|
| sum_expr
|
||||||
| simple_expr OR_OR_SYM simple_expr
|
| simple_expr OR_OR_SYM simple_expr
|
||||||
{ $$= new Item_func_concat($1, $3); }
|
{ $$= new Item_func_concat($1, $3); }
|
||||||
@ -6701,6 +6676,46 @@ sum_expr:
|
|||||||
$5->empty();
|
$5->empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
variable:
|
||||||
|
'@'
|
||||||
|
{
|
||||||
|
if (! Lex->parsing_options.allows_variable)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variable_aux
|
||||||
|
{
|
||||||
|
$$= $3;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
variable_aux:
|
||||||
|
ident_or_text SET_VAR expr
|
||||||
|
{
|
||||||
|
$$= new Item_func_set_user_var($1, $3);
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->uncacheable(UNCACHEABLE_RAND);
|
||||||
|
}
|
||||||
|
| ident_or_text
|
||||||
|
{
|
||||||
|
$$= new Item_func_get_user_var($1);
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->uncacheable(UNCACHEABLE_RAND);
|
||||||
|
}
|
||||||
|
| '@' opt_var_ident_type ident_or_text opt_component
|
||||||
|
{
|
||||||
|
if ($3.str && $4.str && check_reserved_words(&$3))
|
||||||
|
{
|
||||||
|
yyerror(ER(ER_SYNTAX_ERROR));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
if (!($$= get_system_var(YYTHD, $2, $3, $4)))
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
opt_distinct:
|
opt_distinct:
|
||||||
/* empty */ { $$ = 0; }
|
/* empty */ { $$ = 0; }
|
||||||
|DISTINCT { $$ = 1; };
|
|DISTINCT { $$ = 1; };
|
||||||
@ -7130,6 +7145,13 @@ select_derived_init:
|
|||||||
SELECT_SYM
|
SELECT_SYM
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
|
||||||
|
if (! lex->parsing_options.allows_derived)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
SELECT_LEX *sel= lex->current_select;
|
SELECT_LEX *sel= lex->current_select;
|
||||||
TABLE_LIST *embedding;
|
TABLE_LIST *embedding;
|
||||||
if (!sel->embedding || sel->end_nested_join(lex->thd))
|
if (!sel->embedding || sel->end_nested_join(lex->thd))
|
||||||
@ -7514,6 +7536,13 @@ procedure_clause:
|
|||||||
| PROCEDURE ident /* Procedure name */
|
| PROCEDURE ident /* Procedure name */
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
|
||||||
|
if (! lex->parsing_options.allows_select_procedure)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
if (&lex->select_lex != lex->current_select)
|
if (&lex->select_lex != lex->current_select)
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
|
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
|
||||||
@ -7613,28 +7642,40 @@ select_var_ident:
|
|||||||
;
|
;
|
||||||
|
|
||||||
into:
|
into:
|
||||||
INTO OUTFILE TEXT_STRING_filesystem
|
INTO
|
||||||
|
{
|
||||||
|
if (! Lex->parsing_options.allows_select_into)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
into_destination
|
||||||
|
;
|
||||||
|
|
||||||
|
into_destination:
|
||||||
|
OUTFILE TEXT_STRING_filesystem
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
if (!(lex->exchange= new sql_exchange($3.str, 0)) ||
|
if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
|
||||||
!(lex->result= new select_export(lex->exchange)))
|
!(lex->result= new select_export(lex->exchange)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
opt_field_term opt_line_term
|
opt_field_term opt_line_term
|
||||||
| INTO DUMPFILE TEXT_STRING_filesystem
|
| DUMPFILE TEXT_STRING_filesystem
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
if (!lex->describe)
|
if (!lex->describe)
|
||||||
{
|
{
|
||||||
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
if (!(lex->exchange= new sql_exchange($3.str,1)))
|
if (!(lex->exchange= new sql_exchange($2.str,1)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
if (!(lex->result= new select_dump(lex->exchange)))
|
if (!(lex->result= new select_dump(lex->exchange)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| INTO select_var_list_init
|
| select_var_list_init
|
||||||
{
|
{
|
||||||
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
}
|
}
|
||||||
@ -8843,8 +8884,13 @@ param_marker:
|
|||||||
{
|
{
|
||||||
THD *thd=YYTHD;
|
THD *thd=YYTHD;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
Item_param *item= new Item_param((uint) (lex->tok_start -
|
Item_param *item;
|
||||||
(uchar *) thd->query));
|
if (! lex->parsing_options.allows_variable)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query));
|
||||||
if (!($$= item) || lex->param_list.push_back(item))
|
if (!($$= item) || lex->param_list.push_back(item))
|
||||||
{
|
{
|
||||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||||
@ -8964,6 +9010,12 @@ simple_ident:
|
|||||||
if (spc && (spv = spc->find_variable(&$1)))
|
if (spc && (spv = spc->find_variable(&$1)))
|
||||||
{
|
{
|
||||||
/* We're compiling a stored procedure and found a variable */
|
/* We're compiling a stored procedure and found a variable */
|
||||||
|
if (! lex->parsing_options.allows_variable)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
Item_splocal *splocal;
|
Item_splocal *splocal;
|
||||||
splocal= new Item_splocal($1, spv->offset, spv->type,
|
splocal= new Item_splocal($1, spv->offset, spv->type,
|
||||||
lex->tok_start_prev -
|
lex->tok_start_prev -
|
||||||
@ -8973,7 +9025,6 @@ simple_ident:
|
|||||||
splocal->m_sp= lex->sphead;
|
splocal->m_sp= lex->sphead;
|
||||||
#endif
|
#endif
|
||||||
$$ = (Item*) splocal;
|
$$ = (Item*) splocal;
|
||||||
lex->variables_used= 1;
|
|
||||||
lex->safe_to_cache_query=0;
|
lex->safe_to_cache_query=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -10872,6 +10923,24 @@ view_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
view_select:
|
view_select:
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->parsing_options.allows_variable= FALSE;
|
||||||
|
lex->parsing_options.allows_select_into= FALSE;
|
||||||
|
lex->parsing_options.allows_select_procedure= FALSE;
|
||||||
|
lex->parsing_options.allows_derived= FALSE;
|
||||||
|
}
|
||||||
|
view_select_aux
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->parsing_options.allows_variable= TRUE;
|
||||||
|
lex->parsing_options.allows_select_into= TRUE;
|
||||||
|
lex->parsing_options.allows_select_procedure= TRUE;
|
||||||
|
lex->parsing_options.allows_derived= TRUE;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
view_select_aux:
|
||||||
SELECT_SYM remember_name select_init2
|
SELECT_SYM remember_name select_init2
|
||||||
{
|
{
|
||||||
THD *thd=YYTHD;
|
THD *thd=YYTHD;
|
||||||
|
@ -312,3 +312,33 @@ outp:
|
|||||||
return (uint32) (to - to_start);
|
return (uint32) (to - to_start);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Searches for a LEX_STRING in an LEX_STRING array.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_string_in_array()
|
||||||
|
heap The array
|
||||||
|
needle The string to search for
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
The last LEX_STRING in the array should have str member set to NULL
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
-1 Not found
|
||||||
|
>=0 Ordinal position
|
||||||
|
*/
|
||||||
|
|
||||||
|
int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
|
||||||
|
CHARSET_INFO * const cs)
|
||||||
|
{
|
||||||
|
const LEX_STRING *pos;
|
||||||
|
for (pos= haystack; pos->str; pos++)
|
||||||
|
if (!cs->coll->strnncollsp(cs, (uchar *) pos->str, pos->length,
|
||||||
|
(uchar *) needle->str, needle->length, 0))
|
||||||
|
{
|
||||||
|
return (pos - haystack);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user