Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.local:/opt/local/work/mysql-5.0-runtime-merge
This commit is contained in:
commit
b471ea50f7
@ -65,6 +65,8 @@ my_bool hash_check(HASH *hash); /* Only in debug library */
|
|||||||
|
|
||||||
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
|
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
|
||||||
#define hash_inited(H) ((H)->array.buffer != 0)
|
#define hash_inited(H) ((H)->array.buffer != 0)
|
||||||
|
#define hash_init_opt(A,B,C,D,E,F,G,H) \
|
||||||
|
(!hash_inited(A) && _hash_init(A,B,C,D,E,F,G, H CALLER_INFO))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -119,4 +119,13 @@ END|
|
|||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
|
||||||
|
BEGIN
|
||||||
|
DECLARE div_zero INTEGER;
|
||||||
|
SELECT 1/0 INTO div_zero;
|
||||||
|
RETURN div_zero;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
delimiter ;|
|
delimiter ;|
|
||||||
|
@ -1268,6 +1268,9 @@ sub environment_setup () {
|
|||||||
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
|
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
|
||||||
$ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
|
$ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
|
||||||
$ENV{'IM_PORT'}= $instance_manager->{port};
|
$ENV{'IM_PORT'}= $instance_manager->{port};
|
||||||
|
$ENV{'IM_PATH_SOCK'}= $instance_manager->{path_sock};
|
||||||
|
$ENV{'IM_USERNAME'}= $instance_manager->{admin_login};
|
||||||
|
$ENV{'IM_PASSWORD'}= $instance_manager->{admin_password};
|
||||||
|
|
||||||
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
|
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
|
||||||
$ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port};
|
$ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port};
|
||||||
@ -1276,6 +1279,9 @@ sub environment_setup () {
|
|||||||
$ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port};
|
$ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port};
|
||||||
$ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid};
|
$ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid};
|
||||||
|
|
||||||
|
$ENV{'EXE_MYSQL'}= $exe_mysql;
|
||||||
|
|
||||||
|
|
||||||
$ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
|
$ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
|
||||||
|
|
||||||
# We are nice and report a bit about our settings
|
# We are nice and report a bit about our settings
|
||||||
|
@ -8,6 +8,7 @@ mysqld2 offline
|
|||||||
Killing the process...
|
Killing the process...
|
||||||
Sleeping...
|
Sleeping...
|
||||||
Success: the process was restarted.
|
Success: the process was restarted.
|
||||||
|
Success: server is ready to accept connection on socket.
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
-- Test for BUG#12751
|
-- Test for BUG#12751
|
||||||
|
@ -295,6 +295,22 @@ b
|
|||||||
c
|
c
|
||||||
d
|
d
|
||||||
drop table t1,t4;
|
drop table t1,t4;
|
||||||
|
DROP TABLE IF EXISTS t2, t1;
|
||||||
|
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
i INT NOT NULL,
|
||||||
|
FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
|
||||||
|
) ENGINE= InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
DELETE IGNORE FROM t1 WHERE i = 1;
|
||||||
|
Warnings:
|
||||||
|
Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
|
||||||
|
SELECT * FROM t1, t2;
|
||||||
|
i i
|
||||||
|
1 1
|
||||||
|
DROP TABLE t2, t1;
|
||||||
|
End of 4.1 tests.
|
||||||
create table t1 (
|
create table t1 (
|
||||||
a varchar(30), b varchar(30), primary key(a), key(b)
|
a varchar(30), b varchar(30), primary key(a), key(b)
|
||||||
) engine=innodb;
|
) engine=innodb;
|
||||||
|
@ -956,7 +956,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';
|
||||||
@ -1379,4 +1475,5 @@ 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.
|
||||||
|
@ -1226,3 +1226,27 @@ 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;
|
||||||
|
@ -4,6 +4,7 @@ DROP FUNCTION IF EXISTS sp_vars_check_ret1;
|
|||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
|
||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
|
||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION IF EXISTS sp_vars_div_zero;
|
||||||
SET @@sql_mode = 'ansi';
|
SET @@sql_mode = 'ansi';
|
||||||
CREATE PROCEDURE sp_vars_check_dflt()
|
CREATE PROCEDURE sp_vars_check_dflt()
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -88,6 +89,12 @@ CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2)
|
|||||||
BEGIN
|
BEGIN
|
||||||
RETURN 12 * 10 + 34 + 0.1234;
|
RETURN 12 * 10 + 34 + 0.1234;
|
||||||
END|
|
END|
|
||||||
|
CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
|
||||||
|
BEGIN
|
||||||
|
DECLARE div_zero INTEGER;
|
||||||
|
SELECT 1/0 INTO div_zero;
|
||||||
|
RETURN div_zero;
|
||||||
|
END|
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Calling the routines, created in ANSI mode.
|
Calling the routines, created in ANSI mode.
|
||||||
@ -172,6 +179,9 @@ sp_vars_check_ret4()
|
|||||||
154.12
|
154.12
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
sp_vars_div_zero()
|
||||||
|
NULL
|
||||||
SET @@sql_mode = 'traditional';
|
SET @@sql_mode = 'traditional';
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
@ -257,12 +267,16 @@ sp_vars_check_ret4()
|
|||||||
154.12
|
154.12
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
sp_vars_div_zero()
|
||||||
|
NULL
|
||||||
DROP PROCEDURE sp_vars_check_dflt;
|
DROP PROCEDURE sp_vars_check_dflt;
|
||||||
DROP PROCEDURE sp_vars_check_assignment;
|
DROP PROCEDURE sp_vars_check_assignment;
|
||||||
DROP FUNCTION sp_vars_check_ret1;
|
DROP FUNCTION sp_vars_check_ret1;
|
||||||
DROP FUNCTION sp_vars_check_ret2;
|
DROP FUNCTION sp_vars_check_ret2;
|
||||||
DROP FUNCTION sp_vars_check_ret3;
|
DROP FUNCTION sp_vars_check_ret3;
|
||||||
DROP FUNCTION sp_vars_check_ret4;
|
DROP FUNCTION sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION sp_vars_div_zero;
|
||||||
CREATE PROCEDURE sp_vars_check_dflt()
|
CREATE PROCEDURE sp_vars_check_dflt()
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE v1 TINYINT DEFAULT 1e200;
|
DECLARE v1 TINYINT DEFAULT 1e200;
|
||||||
@ -346,6 +360,12 @@ CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2)
|
|||||||
BEGIN
|
BEGIN
|
||||||
RETURN 12 * 10 + 34 + 0.1234;
|
RETURN 12 * 10 + 34 + 0.1234;
|
||||||
END|
|
END|
|
||||||
|
CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
|
||||||
|
BEGIN
|
||||||
|
DECLARE div_zero INTEGER;
|
||||||
|
SELECT 1/0 INTO div_zero;
|
||||||
|
RETURN div_zero;
|
||||||
|
END|
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Calling the routines, created in TRADITIONAL mode.
|
Calling the routines, created in TRADITIONAL mode.
|
||||||
@ -366,6 +386,8 @@ sp_vars_check_ret4()
|
|||||||
154.12
|
154.12
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
ERROR 22012: Division by 0
|
||||||
SET @@sql_mode = 'ansi';
|
SET @@sql_mode = 'ansi';
|
||||||
DROP PROCEDURE sp_vars_check_dflt;
|
DROP PROCEDURE sp_vars_check_dflt;
|
||||||
DROP PROCEDURE sp_vars_check_assignment;
|
DROP PROCEDURE sp_vars_check_assignment;
|
||||||
@ -373,6 +395,7 @@ DROP FUNCTION sp_vars_check_ret1;
|
|||||||
DROP FUNCTION sp_vars_check_ret2;
|
DROP FUNCTION sp_vars_check_ret2;
|
||||||
DROP FUNCTION sp_vars_check_ret3;
|
DROP FUNCTION sp_vars_check_ret3;
|
||||||
DROP FUNCTION sp_vars_check_ret4;
|
DROP FUNCTION sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION sp_vars_div_zero;
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
BIT data type tests
|
BIT data type tests
|
||||||
|
@ -5470,5 +5470,161 @@ CAD
|
|||||||
CHF
|
CHF
|
||||||
DROP FUNCTION bug21493|
|
DROP FUNCTION bug21493|
|
||||||
DROP TABLE t3,t4|
|
DROP TABLE t3,t4|
|
||||||
|
drop function if exists func_20028_a|
|
||||||
|
drop function if exists func_20028_b|
|
||||||
|
drop function if exists func_20028_c|
|
||||||
|
drop procedure if exists proc_20028_a|
|
||||||
|
drop procedure if exists proc_20028_b|
|
||||||
|
drop procedure if exists proc_20028_c|
|
||||||
|
drop table if exists table_20028|
|
||||||
|
create table table_20028 (i int)|
|
||||||
|
SET @save_sql_mode=@@sql_mode|
|
||||||
|
SET sql_mode=''|
|
||||||
|
create function func_20028_a() returns integer
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
return ifnull(temp, 0);
|
||||||
|
end|
|
||||||
|
create function func_20028_b() returns integer
|
||||||
|
begin
|
||||||
|
return func_20028_a();
|
||||||
|
end|
|
||||||
|
create function func_20028_c() returns integer
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='TRADITIONAL';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
return div_zero;
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_a()
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_b()
|
||||||
|
begin
|
||||||
|
call proc_20028_a();
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_c()
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='TRADITIONAL';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
end|
|
||||||
|
select func_20028_a()|
|
||||||
|
func_20028_a()
|
||||||
|
0
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
select func_20028_b()|
|
||||||
|
func_20028_b()
|
||||||
|
0
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
select func_20028_c()|
|
||||||
|
ERROR 22012: Division by 0
|
||||||
|
call proc_20028_a()|
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
call proc_20028_b()|
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
call proc_20028_c()|
|
||||||
|
ERROR 22012: Division by 0
|
||||||
|
SET sql_mode='TRADITIONAL'|
|
||||||
|
drop function func_20028_a|
|
||||||
|
drop function func_20028_b|
|
||||||
|
drop function func_20028_c|
|
||||||
|
drop procedure proc_20028_a|
|
||||||
|
drop procedure proc_20028_b|
|
||||||
|
drop procedure proc_20028_c|
|
||||||
|
create function func_20028_a() returns integer
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
return ifnull(temp, 0);
|
||||||
|
end|
|
||||||
|
create function func_20028_b() returns integer
|
||||||
|
begin
|
||||||
|
return func_20028_a();
|
||||||
|
end|
|
||||||
|
create function func_20028_c() returns integer
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
return div_zero;
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_a()
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_b()
|
||||||
|
begin
|
||||||
|
call proc_20028_a();
|
||||||
|
end|
|
||||||
|
create procedure proc_20028_c()
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
end|
|
||||||
|
select func_20028_a()|
|
||||||
|
func_20028_a()
|
||||||
|
0
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
select func_20028_b()|
|
||||||
|
func_20028_b()
|
||||||
|
0
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
select func_20028_c()|
|
||||||
|
func_20028_c()
|
||||||
|
NULL
|
||||||
|
call proc_20028_a()|
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
call proc_20028_b()|
|
||||||
|
Warnings:
|
||||||
|
Warning 1329 No data - zero rows fetched, selected, or processed
|
||||||
|
call proc_20028_c()|
|
||||||
|
SET @@sql_mode=@save_sql_mode|
|
||||||
|
drop function func_20028_a|
|
||||||
|
drop function func_20028_b|
|
||||||
|
drop function func_20028_c|
|
||||||
|
drop procedure proc_20028_a|
|
||||||
|
drop procedure proc_20028_b|
|
||||||
|
drop procedure proc_20028_c|
|
||||||
|
drop table table_20028|
|
||||||
|
drop procedure if exists proc_21462_a|
|
||||||
|
drop procedure if exists proc_21462_b|
|
||||||
|
create procedure proc_21462_a()
|
||||||
|
begin
|
||||||
|
select "Called A";
|
||||||
|
end|
|
||||||
|
create procedure proc_21462_b(x int)
|
||||||
|
begin
|
||||||
|
select "Called B";
|
||||||
|
end|
|
||||||
|
call proc_21462_a|
|
||||||
|
Called A
|
||||||
|
Called A
|
||||||
|
call proc_21462_a()|
|
||||||
|
Called A
|
||||||
|
Called A
|
||||||
|
call proc_21462_a(1)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_a; expected 0, got 1
|
||||||
|
call proc_21462_b|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_b; expected 1, got 0
|
||||||
|
call proc_21462_b()|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_b; expected 1, got 0
|
||||||
|
call proc_21462_b(1)|
|
||||||
|
Called B
|
||||||
|
Called B
|
||||||
|
drop procedure proc_21462_a|
|
||||||
|
drop procedure proc_21462_b|
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
@ -1073,10 +1073,11 @@ SELECT @x;
|
|||||||
NULL
|
NULL
|
||||||
SET @x=2;
|
SET @x=2;
|
||||||
UPDATE t1 SET i1 = @x;
|
UPDATE t1 SET i1 = @x;
|
||||||
ERROR 22012: Division by 0
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
SELECT @x;
|
SELECT @x;
|
||||||
@x
|
@x
|
||||||
2
|
NULL
|
||||||
SET SQL_MODE='';
|
SET SQL_MODE='';
|
||||||
SET @x=3;
|
SET @x=3;
|
||||||
INSERT INTO t1 VALUES (@x);
|
INSERT INTO t1 VALUES (@x);
|
||||||
@ -1085,10 +1086,12 @@ SELECT @x;
|
|||||||
NULL
|
NULL
|
||||||
SET @x=4;
|
SET @x=4;
|
||||||
UPDATE t1 SET i1 = @x;
|
UPDATE t1 SET i1 = @x;
|
||||||
ERROR 22012: Division by 0
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
|
Error 1365 Division by 0
|
||||||
SELECT @x;
|
SELECT @x;
|
||||||
@x
|
@x
|
||||||
4
|
NULL
|
||||||
SET @@sql_mode=@save_sql_mode;
|
SET @@sql_mode=@save_sql_mode;
|
||||||
DROP TRIGGER t1_ai;
|
DROP TRIGGER t1_ai;
|
||||||
DROP TRIGGER t1_au;
|
DROP TRIGGER t1_au;
|
||||||
@ -1174,6 +1177,59 @@ ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghi
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
drop table if exists t2;
|
||||||
|
drop table if exists t3;
|
||||||
|
drop table if exists t4;
|
||||||
|
SET @save_sql_mode=@@sql_mode;
|
||||||
|
SET sql_mode='TRADITIONAL'|
|
||||||
|
create table t1 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t2 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t3 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t4 (c int)|
|
||||||
|
create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
|
||||||
|
create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
|
||||||
|
insert into t1 values(10, 10)|
|
||||||
|
set @a:=1/0|
|
||||||
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
|
select 1/0 from t1|
|
||||||
|
1/0
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
|
create trigger t1_bi before insert on t1 for each row set @a:=1/0|
|
||||||
|
insert into t1 values(20, 20)|
|
||||||
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
|
drop trigger t1_bi|
|
||||||
|
create trigger t1_bi before insert on t1 for each row
|
||||||
|
begin
|
||||||
|
insert into t2 values (new.id, new.v);
|
||||||
|
update t2 set v=v+1 where id= new.id;
|
||||||
|
replace t3 values (new.id, 0);
|
||||||
|
update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
|
||||||
|
create temporary table t5 select * from t1;
|
||||||
|
delete from t5;
|
||||||
|
insert into t5 select * from t1;
|
||||||
|
insert into t4 values (0);
|
||||||
|
set @check= (select count(*) from t5);
|
||||||
|
update t4 set c= @check;
|
||||||
|
drop temporary table t5;
|
||||||
|
set @a:=1/0;
|
||||||
|
end|
|
||||||
|
set @check=0, @t4_bi_called=0, @t4_bu_called=0|
|
||||||
|
insert into t1 values(30, 30)|
|
||||||
|
Warnings:
|
||||||
|
Error 1365 Division by 0
|
||||||
|
select @check, @t4_bi_called, @t4_bu_called|
|
||||||
|
@check @t4_bi_called @t4_bu_called
|
||||||
|
2 1 1
|
||||||
|
SET @@sql_mode=@save_sql_mode;
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
||||||
|
drop table t3;
|
||||||
|
drop table t4;
|
||||||
|
drop table if exists t1;
|
||||||
create table t1 (i int, j int key);
|
create table t1 (i int, j int key);
|
||||||
insert into t1 values (1,1), (2,2), (3,3);
|
insert into t1 values (1,1), (2,2), (3,3);
|
||||||
create trigger t1_bu before update on t1 for each row
|
create trigger t1_bu before update on t1 for each row
|
||||||
|
@ -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,20 @@ 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;
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
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);
|
||||||
@ -2966,4 +2980,38 @@ UPDATE v1 SET val=6 WHERE id=2;
|
|||||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP VIEW IF EXISTS v1, v2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
|
||||||
|
CREATE VIEW v1 AS SELECT j FROM t1;
|
||||||
|
CREATE VIEW v2 AS SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (j) VALUES (1);
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
LAST_INSERT_ID()
|
||||||
|
1
|
||||||
|
INSERT INTO v1 (j) VALUES (2);
|
||||||
|
# LAST_INSERT_ID() should not change.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
LAST_INSERT_ID()
|
||||||
|
1
|
||||||
|
INSERT INTO v2 (j) VALUES (3);
|
||||||
|
# LAST_INSERT_ID() should be updated.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
LAST_INSERT_ID()
|
||||||
|
3
|
||||||
|
INSERT INTO v1 (j) SELECT j FROM t1;
|
||||||
|
# LAST_INSERT_ID() should not change.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
LAST_INSERT_ID()
|
||||||
|
3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i j
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 1
|
||||||
|
5 2
|
||||||
|
6 3
|
||||||
|
DROP VIEW v1, v2;
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -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);
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
|
# Wait for IM to start accepting connections.
|
||||||
|
|
||||||
|
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#12751: Instance Manager: client hangs
|
# BUG#12751: Instance Manager: client hangs
|
||||||
#
|
#
|
||||||
|
@ -246,6 +246,36 @@ select distinct a1 from t4 where pk_col not in (1,2,3,4);
|
|||||||
|
|
||||||
drop table t1,t4;
|
drop table t1,t4;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#18819: DELETE IGNORE hangs on foreign key parent delete
|
||||||
|
#
|
||||||
|
# The bug itself does not relate to InnoDB, but we have to use foreign
|
||||||
|
# keys to reproduce it.
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t2, t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
i INT NOT NULL,
|
||||||
|
FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
|
||||||
|
) ENGINE= InnoDB;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
|
||||||
|
DELETE IGNORE FROM t1 WHERE i = 1;
|
||||||
|
|
||||||
|
SELECT * FROM t1, t2;
|
||||||
|
|
||||||
|
DROP TABLE t2, t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 4.1 tests.
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #6142: a problem with the empty innodb table
|
# Bug #6142: a problem with the empty innodb table
|
||||||
# (was part of group_min_max.test)
|
# (was part of group_min_max.test)
|
||||||
|
@ -988,6 +988,7 @@ execute stmt;
|
|||||||
drop temporary table t1;
|
drop temporary table t1;
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#22085: Crash on the execution of a prepared statement that
|
# BUG#22085: Crash on the execution of a prepared statement that
|
||||||
# uses an IN subquery with aggregate functions in HAVING
|
# uses an IN subquery with aggregate functions in HAVING
|
||||||
@ -1040,7 +1041,82 @@ 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,4 +1513,24 @@ 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.
|
||||||
|
@ -1767,6 +1767,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;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
@ -15,6 +15,7 @@ DROP FUNCTION IF EXISTS sp_vars_check_ret1;
|
|||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
|
||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
|
||||||
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
|
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION IF EXISTS sp_vars_div_zero;
|
||||||
|
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
@ -49,6 +50,8 @@ SELECT sp_vars_check_ret3();
|
|||||||
|
|
||||||
SELECT sp_vars_check_ret4();
|
SELECT sp_vars_check_ret4();
|
||||||
|
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
|
||||||
# Check that changing sql_mode after creating a store procedure does not
|
# Check that changing sql_mode after creating a store procedure does not
|
||||||
# matter.
|
# matter.
|
||||||
|
|
||||||
@ -72,6 +75,8 @@ SELECT sp_vars_check_ret3();
|
|||||||
|
|
||||||
SELECT sp_vars_check_ret4();
|
SELECT sp_vars_check_ret4();
|
||||||
|
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
|
||||||
# Create the procedure in TRADITIONAL mode. Check that error will be thrown on
|
# Create the procedure in TRADITIONAL mode. Check that error will be thrown on
|
||||||
# execution.
|
# execution.
|
||||||
|
|
||||||
@ -81,6 +86,7 @@ DROP FUNCTION sp_vars_check_ret1;
|
|||||||
DROP FUNCTION sp_vars_check_ret2;
|
DROP FUNCTION sp_vars_check_ret2;
|
||||||
DROP FUNCTION sp_vars_check_ret3;
|
DROP FUNCTION sp_vars_check_ret3;
|
||||||
DROP FUNCTION sp_vars_check_ret4;
|
DROP FUNCTION sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION sp_vars_div_zero;
|
||||||
|
|
||||||
--source include/sp-vars.inc
|
--source include/sp-vars.inc
|
||||||
|
|
||||||
@ -110,6 +116,9 @@ SELECT sp_vars_check_ret3();
|
|||||||
|
|
||||||
SELECT sp_vars_check_ret4();
|
SELECT sp_vars_check_ret4();
|
||||||
|
|
||||||
|
--error ER_DIVISION_BY_ZERO
|
||||||
|
SELECT sp_vars_div_zero();
|
||||||
|
|
||||||
SET @@sql_mode = 'ansi';
|
SET @@sql_mode = 'ansi';
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -122,6 +131,7 @@ DROP FUNCTION sp_vars_check_ret1;
|
|||||||
DROP FUNCTION sp_vars_check_ret2;
|
DROP FUNCTION sp_vars_check_ret2;
|
||||||
DROP FUNCTION sp_vars_check_ret3;
|
DROP FUNCTION sp_vars_check_ret3;
|
||||||
DROP FUNCTION sp_vars_check_ret4;
|
DROP FUNCTION sp_vars_check_ret4;
|
||||||
|
DROP FUNCTION sp_vars_div_zero;
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
#
|
#
|
||||||
|
@ -6420,6 +6420,170 @@ SELECT bug21493(Member_ID) FROM t3|
|
|||||||
DROP FUNCTION bug21493|
|
DROP FUNCTION bug21493|
|
||||||
DROP TABLE t3,t4|
|
DROP TABLE t3,t4|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#20028 Function with select return no data
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop function if exists func_20028_a|
|
||||||
|
drop function if exists func_20028_b|
|
||||||
|
drop function if exists func_20028_c|
|
||||||
|
drop procedure if exists proc_20028_a|
|
||||||
|
drop procedure if exists proc_20028_b|
|
||||||
|
drop procedure if exists proc_20028_c|
|
||||||
|
drop table if exists table_20028|
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table table_20028 (i int)|
|
||||||
|
|
||||||
|
SET @save_sql_mode=@@sql_mode|
|
||||||
|
|
||||||
|
SET sql_mode=''|
|
||||||
|
|
||||||
|
create function func_20028_a() returns integer
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
return ifnull(temp, 0);
|
||||||
|
end|
|
||||||
|
|
||||||
|
create function func_20028_b() returns integer
|
||||||
|
begin
|
||||||
|
return func_20028_a();
|
||||||
|
end|
|
||||||
|
|
||||||
|
create function func_20028_c() returns integer
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='TRADITIONAL';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
return div_zero;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_a()
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_b()
|
||||||
|
begin
|
||||||
|
call proc_20028_a();
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_c()
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='TRADITIONAL';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
end|
|
||||||
|
|
||||||
|
select func_20028_a()|
|
||||||
|
select func_20028_b()|
|
||||||
|
--error ER_DIVISION_BY_ZERO
|
||||||
|
select func_20028_c()|
|
||||||
|
call proc_20028_a()|
|
||||||
|
call proc_20028_b()|
|
||||||
|
--error ER_DIVISION_BY_ZERO
|
||||||
|
call proc_20028_c()|
|
||||||
|
|
||||||
|
SET sql_mode='TRADITIONAL'|
|
||||||
|
|
||||||
|
drop function func_20028_a|
|
||||||
|
drop function func_20028_b|
|
||||||
|
drop function func_20028_c|
|
||||||
|
drop procedure proc_20028_a|
|
||||||
|
drop procedure proc_20028_b|
|
||||||
|
drop procedure proc_20028_c|
|
||||||
|
|
||||||
|
create function func_20028_a() returns integer
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
return ifnull(temp, 0);
|
||||||
|
end|
|
||||||
|
|
||||||
|
create function func_20028_b() returns integer
|
||||||
|
begin
|
||||||
|
return func_20028_a();
|
||||||
|
end|
|
||||||
|
|
||||||
|
create function func_20028_c() returns integer
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
return div_zero;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_a()
|
||||||
|
begin
|
||||||
|
declare temp integer;
|
||||||
|
select i into temp from table_20028 limit 1;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_b()
|
||||||
|
begin
|
||||||
|
call proc_20028_a();
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_20028_c()
|
||||||
|
begin
|
||||||
|
declare div_zero integer;
|
||||||
|
set SQL_MODE='';
|
||||||
|
select 1/0 into div_zero;
|
||||||
|
end|
|
||||||
|
|
||||||
|
select func_20028_a()|
|
||||||
|
select func_20028_b()|
|
||||||
|
select func_20028_c()|
|
||||||
|
call proc_20028_a()|
|
||||||
|
call proc_20028_b()|
|
||||||
|
call proc_20028_c()|
|
||||||
|
|
||||||
|
SET @@sql_mode=@save_sql_mode|
|
||||||
|
|
||||||
|
drop function func_20028_a|
|
||||||
|
drop function func_20028_b|
|
||||||
|
drop function func_20028_c|
|
||||||
|
drop procedure proc_20028_a|
|
||||||
|
drop procedure proc_20028_b|
|
||||||
|
drop procedure proc_20028_c|
|
||||||
|
drop table table_20028|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#21462 Stored procedures with no arguments require parenthesis
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists proc_21462_a|
|
||||||
|
drop procedure if exists proc_21462_b|
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create procedure proc_21462_a()
|
||||||
|
begin
|
||||||
|
select "Called A";
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure proc_21462_b(x int)
|
||||||
|
begin
|
||||||
|
select "Called B";
|
||||||
|
end|
|
||||||
|
|
||||||
|
call proc_21462_a|
|
||||||
|
call proc_21462_a()|
|
||||||
|
-- error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call proc_21462_a(1)|
|
||||||
|
|
||||||
|
-- error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call proc_21462_b|
|
||||||
|
-- error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call proc_21462_b()|
|
||||||
|
call proc_21462_b(1)|
|
||||||
|
|
||||||
|
drop procedure proc_21462_a|
|
||||||
|
drop procedure proc_21462_b|
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
|
||||||
|
@ -1274,7 +1274,6 @@ INSERT INTO t1 VALUES (@x);
|
|||||||
SELECT @x;
|
SELECT @x;
|
||||||
|
|
||||||
SET @x=2;
|
SET @x=2;
|
||||||
--error ER_DIVISION_BY_ZERO
|
|
||||||
UPDATE t1 SET i1 = @x;
|
UPDATE t1 SET i1 = @x;
|
||||||
SELECT @x;
|
SELECT @x;
|
||||||
|
|
||||||
@ -1285,7 +1284,6 @@ INSERT INTO t1 VALUES (@x);
|
|||||||
SELECT @x;
|
SELECT @x;
|
||||||
|
|
||||||
SET @x=4;
|
SET @x=4;
|
||||||
--error ER_DIVISION_BY_ZERO
|
|
||||||
UPDATE t1 SET i1 = @x;
|
UPDATE t1 SET i1 = @x;
|
||||||
SELECT @x;
|
SELECT @x;
|
||||||
|
|
||||||
@ -1420,6 +1418,67 @@ CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#20028 Function with select return no data
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
drop table if exists t2;
|
||||||
|
drop table if exists t3;
|
||||||
|
drop table if exists t4;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
SET @save_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
SET sql_mode='TRADITIONAL'|
|
||||||
|
create table t1 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t2 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t3 (id int(10) not null primary key, v int(10) )|
|
||||||
|
create table t4 (c int)|
|
||||||
|
|
||||||
|
create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
|
||||||
|
create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
|
||||||
|
|
||||||
|
insert into t1 values(10, 10)|
|
||||||
|
set @a:=1/0|
|
||||||
|
select 1/0 from t1|
|
||||||
|
|
||||||
|
create trigger t1_bi before insert on t1 for each row set @a:=1/0|
|
||||||
|
|
||||||
|
insert into t1 values(20, 20)|
|
||||||
|
|
||||||
|
drop trigger t1_bi|
|
||||||
|
create trigger t1_bi before insert on t1 for each row
|
||||||
|
begin
|
||||||
|
insert into t2 values (new.id, new.v);
|
||||||
|
update t2 set v=v+1 where id= new.id;
|
||||||
|
replace t3 values (new.id, 0);
|
||||||
|
update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
|
||||||
|
create temporary table t5 select * from t1;
|
||||||
|
delete from t5;
|
||||||
|
insert into t5 select * from t1;
|
||||||
|
insert into t4 values (0);
|
||||||
|
set @check= (select count(*) from t5);
|
||||||
|
update t4 set c= @check;
|
||||||
|
drop temporary table t5;
|
||||||
|
|
||||||
|
set @a:=1/0;
|
||||||
|
end|
|
||||||
|
|
||||||
|
set @check=0, @t4_bi_called=0, @t4_bu_called=0|
|
||||||
|
insert into t1 values(30, 30)|
|
||||||
|
select @check, @t4_bi_called, @t4_bu_called|
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
SET @@sql_mode=@save_sql_mode;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
||||||
|
drop table t3;
|
||||||
|
drop table t4;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#20670 "UPDATE using key and invoking trigger that modifies
|
# Bug#20670 "UPDATE using key and invoking trigger that modifies
|
||||||
|
@ -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;
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -2597,6 +2589,7 @@ SELECT * FROM t2;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#16110: insert permitted into view col w/o default value
|
# Bug#16110: insert permitted into view col w/o default value
|
||||||
#
|
#
|
||||||
@ -2880,6 +2873,40 @@ SHOW CREATE VIEW v1;
|
|||||||
DROP VIEW v1;
|
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)
|
||||||
#
|
#
|
||||||
@ -2894,4 +2921,43 @@ UPDATE v1 SET val=6 WHERE id=2;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#22584: last_insert_id not updated after inserting a record
|
||||||
|
# through a updatable view
|
||||||
|
#
|
||||||
|
# We still do not update LAST_INSERT_ID if AUTO_INCREMENT column is
|
||||||
|
# not accessible through a view. However, we do not reset the value
|
||||||
|
# of LAST_INSERT_ID, but keep it unchanged.
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP VIEW IF EXISTS v1, v2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
|
||||||
|
CREATE VIEW v1 AS SELECT j FROM t1;
|
||||||
|
CREATE VIEW v2 AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
INSERT INTO t1 (j) VALUES (1);
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
|
||||||
|
INSERT INTO v1 (j) VALUES (2);
|
||||||
|
--echo # LAST_INSERT_ID() should not change.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
|
||||||
|
INSERT INTO v2 (j) VALUES (3);
|
||||||
|
--echo # LAST_INSERT_ID() should be updated.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
|
||||||
|
INSERT INTO v1 (j) SELECT j FROM t1;
|
||||||
|
--echo # LAST_INSERT_ID() should not change.
|
||||||
|
SELECT LAST_INSERT_ID();
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
DROP VIEW v1, v2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
62
mysql-test/t/wait_for_socket.sh
Executable file
62
mysql-test/t/wait_for_socket.sh
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
if [ $# -ne 6 ]; then
|
||||||
|
echo "Usage: wait_for_socket.sh <executable path> <socket path> <username> <password> <db> <timeout>"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
client_exe="$1"
|
||||||
|
socket_path="$2"
|
||||||
|
username="$3"
|
||||||
|
password="$4"
|
||||||
|
db="$5"
|
||||||
|
total_timeout="$6"
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
if [ -z "$client_exe" ]; then
|
||||||
|
echo "Error: invalid path to client executable ($client_exe)."
|
||||||
|
exit 0;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$client_exe" ]; then
|
||||||
|
echo "Error: client by path '$client_exe' is not available."
|
||||||
|
exit 0;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$socket_path" ]; then
|
||||||
|
echo "Error: invalid socket patch."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
client_args="--silent --socket=$socket_path "
|
||||||
|
|
||||||
|
[ -n "$username" ] && client_args="$client_args --user=$username "
|
||||||
|
[ -n "$password" ] && client_args="$client_args --password=$password "
|
||||||
|
[ -n "$db" ] && client_args="$client_args $db"
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
cur_attempt=1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
if ( echo 'quit' | "$client_exe" $client_args >/dev/null 2>&1 ); then
|
||||||
|
echo "Success: server is ready to accept connection on socket."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ $cur_attempt -ge $total_timeout ] && break
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
cur_attempt=`expr $cur_attempt + 1`
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Error: server does not accept connections after $total_timeout seconds."
|
||||||
|
exit 0
|
@ -66,11 +66,11 @@ Guardian_thread::~Guardian_thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Guardian_thread::request_shutdown(bool stop_instances_arg)
|
void Guardian_thread::request_shutdown()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_guardian);
|
pthread_mutex_lock(&LOCK_guardian);
|
||||||
/* stop instances or just clean up Guardian repository */
|
/* stop instances or just clean up Guardian repository */
|
||||||
stop_instances(stop_instances_arg);
|
stop_instances();
|
||||||
shutdown_requested= TRUE;
|
shutdown_requested= TRUE;
|
||||||
pthread_mutex_unlock(&LOCK_guardian);
|
pthread_mutex_unlock(&LOCK_guardian);
|
||||||
}
|
}
|
||||||
@ -118,11 +118,11 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||||||
{
|
{
|
||||||
/* Pid file not created yet, don't go to STARTED state yet */
|
/* Pid file not created yet, don't go to STARTED state yet */
|
||||||
}
|
}
|
||||||
else
|
else if (current_node->state != STARTED)
|
||||||
{
|
{
|
||||||
/* clear status fields */
|
/* clear status fields */
|
||||||
log_info("guardian: instance %s is running, set state to STARTED",
|
log_info("guardian: instance '%s' is running, set state to STARTED.",
|
||||||
instance->options.instance_name);
|
(const char *) instance->options.instance_name);
|
||||||
current_node->restart_counter= 0;
|
current_node->restart_counter= 0;
|
||||||
current_node->crash_moment= 0;
|
current_node->crash_moment= 0;
|
||||||
current_node->state= STARTED;
|
current_node->state= STARTED;
|
||||||
@ -132,8 +132,8 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||||||
{
|
{
|
||||||
switch (current_node->state) {
|
switch (current_node->state) {
|
||||||
case NOT_STARTED:
|
case NOT_STARTED:
|
||||||
log_info("guardian: starting instance %s",
|
log_info("guardian: starting instance '%s'...",
|
||||||
instance->options.instance_name);
|
(const char *) instance->options.instance_name);
|
||||||
|
|
||||||
/* NOTE, set state to STARTING _before_ start() is called */
|
/* NOTE, set state to STARTING _before_ start() is called */
|
||||||
current_node->state= STARTING;
|
current_node->state= STARTING;
|
||||||
@ -157,8 +157,8 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||||||
if (instance->is_crashed())
|
if (instance->is_crashed())
|
||||||
{
|
{
|
||||||
instance->start();
|
instance->start();
|
||||||
log_info("guardian: starting instance %s",
|
log_info("guardian: starting instance '%s'...",
|
||||||
instance->options.instance_name);
|
(const char *) instance->options.instance_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -175,8 +175,8 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||||||
instance->start();
|
instance->start();
|
||||||
current_node->last_checked= current_time;
|
current_node->last_checked= current_time;
|
||||||
current_node->restart_counter++;
|
current_node->restart_counter++;
|
||||||
log_info("guardian: restarting instance %s",
|
log_info("guardian: restarting instance '%s'...",
|
||||||
instance->options.instance_name);
|
(const char *) instance->options.instance_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -382,12 +382,11 @@ int Guardian_thread::stop_guard(Instance *instance)
|
|||||||
|
|
||||||
SYNOPSYS
|
SYNOPSYS
|
||||||
stop_instances()
|
stop_instances()
|
||||||
stop_instances_arg whether we should stop instances at shutdown
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Loops through the guarded_instances list and prepares them for shutdown.
|
Loops through the guarded_instances list and prepares them for shutdown.
|
||||||
If stop_instances was requested, we need to issue a stop command and change
|
For each instance we issue a stop command and change the state
|
||||||
the state accordingly. Otherwise we simply delete an entry.
|
accordingly.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
Guardian object should be locked by the calling function.
|
Guardian object should be locked by the calling function.
|
||||||
@ -397,42 +396,29 @@ int Guardian_thread::stop_guard(Instance *instance)
|
|||||||
1 - error occured
|
1 - error occured
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Guardian_thread::stop_instances(bool stop_instances_arg)
|
int Guardian_thread::stop_instances()
|
||||||
{
|
{
|
||||||
LIST *node;
|
LIST *node;
|
||||||
node= guarded_instances;
|
node= guarded_instances;
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
if (!stop_instances_arg)
|
GUARD_NODE *current_node= (GUARD_NODE *) node->data;
|
||||||
|
/*
|
||||||
|
If instance is running or was running (and now probably hanging),
|
||||||
|
request stop.
|
||||||
|
*/
|
||||||
|
if (current_node->instance->is_running() ||
|
||||||
|
(current_node->state == STARTED))
|
||||||
{
|
{
|
||||||
/* just forget about an instance */
|
current_node->state= STOPPING;
|
||||||
guarded_instances= list_delete(guarded_instances, node);
|
current_node->last_checked= time(NULL);
|
||||||
/*
|
|
||||||
This should still work fine, as we have only removed the
|
|
||||||
node from the list. The pointer to the next one is still valid
|
|
||||||
*/
|
|
||||||
node= node->next;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
/* otherwise remove it from the list */
|
||||||
GUARD_NODE *current_node= (GUARD_NODE *) node->data;
|
guarded_instances= list_delete(guarded_instances, node);
|
||||||
/*
|
/* But try to kill it anyway. Just in case */
|
||||||
If instance is running or was running (and now probably hanging),
|
current_node->instance->kill_instance(SIGTERM);
|
||||||
request stop.
|
node= node->next;
|
||||||
*/
|
|
||||||
if (current_node->instance->is_running() ||
|
|
||||||
(current_node->state == STARTED))
|
|
||||||
{
|
|
||||||
current_node->state= STOPPING;
|
|
||||||
current_node->last_checked= time(NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* otherwise remove it from the list */
|
|
||||||
guarded_instances= list_delete(guarded_instances, node);
|
|
||||||
/* But try to kill it anyway. Just in case */
|
|
||||||
current_node->instance->kill_instance(SIGTERM);
|
|
||||||
node= node->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ public:
|
|||||||
/* Initialize or refresh the list of guarded instances */
|
/* Initialize or refresh the list of guarded instances */
|
||||||
int init();
|
int init();
|
||||||
/* Request guardian shutdown. Stop instances if needed */
|
/* Request guardian shutdown. Stop instances if needed */
|
||||||
void request_shutdown(bool stop_instances);
|
void request_shutdown();
|
||||||
/* Start instance protection */
|
/* Start instance protection */
|
||||||
int guard(Instance *instance, bool nolock= FALSE);
|
int guard(Instance *instance, bool nolock= FALSE);
|
||||||
/* Stop instance protection */
|
/* Stop instance protection */
|
||||||
@ -104,7 +104,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/* Prepares Guardian shutdown. Stops instances is needed */
|
/* Prepares Guardian shutdown. Stops instances is needed */
|
||||||
int stop_instances(bool stop_instances_arg);
|
int stop_instances();
|
||||||
/* check instance state and act accordingly */
|
/* check instance state and act accordingly */
|
||||||
void process_instance(Instance *instance, GUARD_NODE *current_node,
|
void process_instance(Instance *instance, GUARD_NODE *current_node,
|
||||||
LIST **guarded_instances, LIST *elem);
|
LIST **guarded_instances, LIST *elem);
|
||||||
|
@ -156,8 +156,8 @@ static int start_process(Instance_options *instance_options,
|
|||||||
/* exec never returns */
|
/* exec never returns */
|
||||||
exit(1);
|
exit(1);
|
||||||
case -1:
|
case -1:
|
||||||
log_info("cannot create a new process to start instance %s",
|
log_info("cannot create a new process to start instance '%s'.",
|
||||||
instance_options->instance_name);
|
(const char *) instance_options->instance_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -252,7 +252,8 @@ static void start_and_monitor_instance(Instance_options *old_instance_options,
|
|||||||
MAX_INSTANCE_NAME_LEN - 1);
|
MAX_INSTANCE_NAME_LEN - 1);
|
||||||
instance_name_len= old_instance_options->instance_name_len;
|
instance_name_len= old_instance_options->instance_name_len;
|
||||||
|
|
||||||
log_info("starting instance %s", instance_name_buff);
|
log_info("starting instance '%s'...",
|
||||||
|
(const char *) instance_name_buff);
|
||||||
|
|
||||||
if (start_process(old_instance_options, &process_info))
|
if (start_process(old_instance_options, &process_info))
|
||||||
{
|
{
|
||||||
@ -286,9 +287,9 @@ void Instance::remove_pid()
|
|||||||
int pid;
|
int pid;
|
||||||
if ((pid= options.get_pid()) != 0) /* check the pidfile */
|
if ((pid= options.get_pid()) != 0) /* check the pidfile */
|
||||||
if (options.unlink_pidfile()) /* remove stalled pidfile */
|
if (options.unlink_pidfile()) /* remove stalled pidfile */
|
||||||
log_error("cannot remove pidfile for instance %i, this might be \
|
log_error("cannot remove pidfile for instance '%s', this might be \
|
||||||
since IM lacks permmissions or hasn't found the pidifle",
|
since IM lacks permmissions or hasn't found the pidifle",
|
||||||
options.instance_name);
|
(const char *) options.instance_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -435,9 +436,9 @@ bool Instance::is_running()
|
|||||||
We have successfully connected to the server using fake
|
We have successfully connected to the server using fake
|
||||||
username/password. Write a warning to the logfile.
|
username/password. Write a warning to the logfile.
|
||||||
*/
|
*/
|
||||||
log_info("The Instance Manager was able to log into you server \
|
log_info("The Instance Manager was able to log into you server "
|
||||||
with faked compiled-in password while checking server status. \
|
"with faked compiled-in password while checking server status. "
|
||||||
Looks like something is wrong.");
|
"Looks like something is wrong.");
|
||||||
pthread_mutex_unlock(&LOCK_instance);
|
pthread_mutex_unlock(&LOCK_instance);
|
||||||
return_val= TRUE; /* server is alive */
|
return_val= TRUE; /* server is alive */
|
||||||
}
|
}
|
||||||
@ -577,10 +578,10 @@ void Instance::kill_instance(int signum)
|
|||||||
/* Kill suceeded */
|
/* Kill suceeded */
|
||||||
if (signum == SIGKILL) /* really killed instance with SIGKILL */
|
if (signum == SIGKILL) /* really killed instance with SIGKILL */
|
||||||
{
|
{
|
||||||
log_error("The instance %s is being stopped forcibly. Normally" \
|
log_error("The instance '%s' is being stopped forcibly. Normally"
|
||||||
"it should not happen. Probably the instance has been" \
|
"it should not happen. Probably the instance has been"
|
||||||
"hanging. You should also check your IM setup",
|
"hanging. You should also check your IM setup",
|
||||||
options.instance_name);
|
(const char *) options.instance_name);
|
||||||
/* After sucessful hard kill the pidfile need to be removed */
|
/* After sucessful hard kill the pidfile need to be removed */
|
||||||
options.unlink_pidfile();
|
options.unlink_pidfile();
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,9 @@ int Instance_map::flush_instances()
|
|||||||
hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||||
get_instance_key, delete_instance, 0);
|
get_instance_key, delete_instance, 0);
|
||||||
rc= load();
|
rc= load();
|
||||||
guardian->init(); // TODO: check error status.
|
/* don't init guardian if we failed to load instances */
|
||||||
|
if (!rc)
|
||||||
|
guardian->init(); // TODO: check error status.
|
||||||
pthread_mutex_unlock(&LOCK_instance_map);
|
pthread_mutex_unlock(&LOCK_instance_map);
|
||||||
guardian->unlock();
|
guardian->unlock();
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -280,7 +280,7 @@ int Listener_thread::create_tcp_socket()
|
|||||||
|
|
||||||
FD_SET(ip_socket, &read_fds);
|
FD_SET(ip_socket, &read_fds);
|
||||||
sockets[num_sockets++]= ip_socket;
|
sockets[num_sockets++]= ip_socket;
|
||||||
log_info("accepting connections on ip socket");
|
log_info("accepting connections on ip socket (port: %d)", (int) im_port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
|
|||||||
/* make sure that instances won't be listening our sockets */
|
/* make sure that instances won't be listening our sockets */
|
||||||
set_no_inherit(unix_socket);
|
set_no_inherit(unix_socket);
|
||||||
|
|
||||||
log_info("accepting connections on unix socket %s",
|
log_info("accepting connections on unix socket '%s'",
|
||||||
unix_socket_address.sun_path);
|
unix_socket_address.sun_path);
|
||||||
sockets[num_sockets++]= unix_socket;
|
sockets[num_sockets++]= unix_socket;
|
||||||
FD_SET(unix_socket, &read_fds);
|
FD_SET(unix_socket, &read_fds);
|
||||||
|
@ -104,6 +104,19 @@ int my_sigwait(const sigset_t *set, int *sig)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Let guardian thread know that it should break it's processing cycle,
|
||||||
|
once it wakes up.
|
||||||
|
*/
|
||||||
|
guardian->request_shutdown();
|
||||||
|
/* wake guardian */
|
||||||
|
pthread_cond_signal(&guardian->COND_guardian);
|
||||||
|
/* stop all threads */
|
||||||
|
registry->deliver_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
manager - entry point to the main instance manager process: start
|
manager - entry point to the main instance manager process: start
|
||||||
listener thread, write pid file and enter into signal handling.
|
listener thread, write pid file and enter into signal handling.
|
||||||
@ -210,7 +223,8 @@ void manager(const Options &options)
|
|||||||
log_error("Cannot init instances repository. This might be caused by "
|
log_error("Cannot init instances repository. This might be caused by "
|
||||||
"the wrong config file options. For instance, missing mysqld "
|
"the wrong config file options. For instance, missing mysqld "
|
||||||
"binary. Aborting.");
|
"binary. Aborting.");
|
||||||
return;
|
stop_all(&guardian_thread, &thread_registry);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the listener */
|
/* create the listener */
|
||||||
@ -227,6 +241,7 @@ void manager(const Options &options)
|
|||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
|
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
|
||||||
|
stop_all(&guardian_thread, &thread_registry);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +260,7 @@ void manager(const Options &options)
|
|||||||
if ((status= my_sigwait(&mask, &signo)) != 0)
|
if ((status= my_sigwait(&mask, &signo)) != 0)
|
||||||
{
|
{
|
||||||
log_error("sigwait() failed");
|
log_error("sigwait() failed");
|
||||||
|
stop_all(&guardian_thread, &thread_registry);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +282,7 @@ void manager(const Options &options)
|
|||||||
{
|
{
|
||||||
if (!guardian_thread.is_stopped())
|
if (!guardian_thread.is_stopped())
|
||||||
{
|
{
|
||||||
bool stop_instances= true;
|
guardian_thread.request_shutdown();
|
||||||
guardian_thread.request_shutdown(stop_instances);
|
|
||||||
pthread_cond_signal(&guardian_thread.COND_guardian);
|
pthread_cond_signal(&guardian_thread.COND_guardian);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -45,10 +45,10 @@ const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
|
|||||||
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
|
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
|
||||||
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
|
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
|
||||||
const char *Options::angel_pid_file_name= NULL;
|
const char *Options::angel_pid_file_name= NULL;
|
||||||
|
const char *Options::socket_file_name= QUOTE(DEFAULT_SOCKET_FILE_NAME);
|
||||||
#endif
|
#endif
|
||||||
const char *Options::log_file_name= default_log_file_name;
|
const char *Options::log_file_name= default_log_file_name;
|
||||||
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
|
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
|
||||||
const char *Options::socket_file_name= QUOTE(DEFAULT_SOCKET_FILE_NAME);
|
|
||||||
const char *Options::password_file_name= default_password_file_name;
|
const char *Options::password_file_name= default_password_file_name;
|
||||||
const char *Options::default_mysqld_path= QUOTE(DEFAULT_MYSQLD_PATH);
|
const char *Options::default_mysqld_path= QUOTE(DEFAULT_MYSQLD_PATH);
|
||||||
const char *Options::bind_address= 0; /* No default value */
|
const char *Options::bind_address= 0; /* No default value */
|
||||||
@ -106,11 +106,11 @@ static struct my_option my_long_options[] =
|
|||||||
(gptr *) &Options::angel_pid_file_name,
|
(gptr *) &Options::angel_pid_file_name,
|
||||||
(gptr *) &Options::angel_pid_file_name,
|
(gptr *) &Options::angel_pid_file_name,
|
||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
#endif
|
|
||||||
|
|
||||||
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
|
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
|
||||||
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
|
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
|
||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
|
#endif
|
||||||
|
|
||||||
{ "passwd", 'P', "Prepare entry for passwd file and exit.", 0, 0, 0,
|
{ "passwd", 'P', "Prepare entry for passwd file and exit.", 0, 0, 0,
|
||||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
|
@ -36,11 +36,11 @@ struct Options
|
|||||||
static char run_as_service; /* handle_options doesn't support bool */
|
static char run_as_service; /* handle_options doesn't support bool */
|
||||||
static const char *user;
|
static const char *user;
|
||||||
static const char *angel_pid_file_name;
|
static const char *angel_pid_file_name;
|
||||||
|
static const char *socket_file_name;
|
||||||
#endif
|
#endif
|
||||||
static bool is_forced_default_file;
|
static bool is_forced_default_file;
|
||||||
static const char *log_file_name;
|
static const char *log_file_name;
|
||||||
static const char *pid_file_name;
|
static const char *pid_file_name;
|
||||||
static const char *socket_file_name;
|
|
||||||
static const char *password_file_name;
|
static const char *password_file_name;
|
||||||
static const char *default_mysqld_path;
|
static const char *default_mysqld_path;
|
||||||
/* the option which should be passed to process_default_option_files */
|
/* the option which should be passed to process_default_option_files */
|
||||||
|
@ -1055,6 +1055,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");
|
||||||
|
count= 0;
|
||||||
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()
|
||||||
|
{
|
||||||
|
count= 0;
|
||||||
|
Item_sum_sum::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_sum_variance;
|
class Item_sum_variance;
|
||||||
@ -689,6 +725,12 @@ 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()
|
||||||
|
{
|
||||||
|
cur_dec= 0;
|
||||||
|
count= 0;
|
||||||
|
Item_sum_num::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_sum_std;
|
class Item_sum_std;
|
||||||
@ -819,6 +861,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()
|
||||||
|
{
|
||||||
|
bits= reset_bits;
|
||||||
|
Item_sum_int::cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,6 +131,8 @@ MY_LOCALE *my_locale_by_name(const char *name);
|
|||||||
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
|
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
|
||||||
#define MAX_FIELDS_BEFORE_HASH 32
|
#define MAX_FIELDS_BEFORE_HASH 32
|
||||||
#define USER_VARS_HASH_SIZE 16
|
#define USER_VARS_HASH_SIZE 16
|
||||||
|
#define TABLE_OPEN_CACHE_MIN 64
|
||||||
|
#define TABLE_OPEN_CACHE_DEFAULT 64
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
|
Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
|
||||||
|
@ -2641,19 +2641,43 @@ static int init_common_variables(const char *conf_file_name, int argc,
|
|||||||
|
|
||||||
/* connections and databases needs lots of files */
|
/* connections and databases needs lots of files */
|
||||||
{
|
{
|
||||||
uint files, wanted_files;
|
uint files, wanted_files, max_open_files;
|
||||||
|
|
||||||
wanted_files= 10+(uint) max(max_connections*5,
|
/* MyISAM requires two file handles per table. */
|
||||||
max_connections+table_cache_size*2);
|
wanted_files= 10+max_connections+table_cache_size*2;
|
||||||
set_if_bigger(wanted_files, open_files_limit);
|
/*
|
||||||
files= my_set_max_open_files(wanted_files);
|
We are trying to allocate no less than max_connections*5 file
|
||||||
|
handles (i.e. we are trying to set the limit so that they will
|
||||||
|
be available). In addition, we allocate no less than how much
|
||||||
|
was already allocated. However below we report a warning and
|
||||||
|
recompute values only if we got less file handles than were
|
||||||
|
explicitly requested. No warning and re-computation occur if we
|
||||||
|
can't get max_connections*5 but still got no less than was
|
||||||
|
requested (value of wanted_files).
|
||||||
|
*/
|
||||||
|
max_open_files= max(max(wanted_files, max_connections*5),
|
||||||
|
open_files_limit);
|
||||||
|
files= my_set_max_open_files(max_open_files);
|
||||||
|
|
||||||
if (files < wanted_files)
|
if (files < wanted_files)
|
||||||
{
|
{
|
||||||
if (!open_files_limit)
|
if (!open_files_limit)
|
||||||
{
|
{
|
||||||
max_connections= (ulong) min((files-10),max_connections);
|
/*
|
||||||
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
|
If we have requested too much file handles than we bring
|
||||||
|
max_connections in supported bounds.
|
||||||
|
*/
|
||||||
|
max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
|
||||||
|
max_connections);
|
||||||
|
/*
|
||||||
|
Decrease table_cache_size according to max_connections, but
|
||||||
|
not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
|
||||||
|
never increase table_cache_size automatically (that could
|
||||||
|
happen if max_connections is decreased above).
|
||||||
|
*/
|
||||||
|
table_cache_size= (ulong) min(max((files-10-max_connections)/2,
|
||||||
|
TABLE_OPEN_CACHE_MIN),
|
||||||
|
table_cache_size);
|
||||||
DBUG_PRINT("warning",
|
DBUG_PRINT("warning",
|
||||||
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
|
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
|
||||||
files, max_connections, table_cache_size));
|
files, max_connections, table_cache_size));
|
||||||
@ -5943,8 +5967,8 @@ The minimum value for this variable is 4096.",
|
|||||||
0, 0, 0, 0},
|
0, 0, 0, 0},
|
||||||
{"table_cache", OPT_TABLE_CACHE,
|
{"table_cache", OPT_TABLE_CACHE,
|
||||||
"The number of open tables for all threads.", (gptr*) &table_cache_size,
|
"The number of open tables for all threads.", (gptr*) &table_cache_size,
|
||||||
(gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L,
|
(gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG,
|
||||||
0, 1, 0},
|
TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
|
||||||
{"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT, "Timeout in "
|
{"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT, "Timeout in "
|
||||||
"seconds to wait for a table level lock before returning an error. Used"
|
"seconds to wait for a table level lock before returning an error. Used"
|
||||||
" only if the connection has active cursors.",
|
" only if the connection has active cursors.",
|
||||||
|
@ -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_ */
|
||||||
|
@ -1369,6 +1369,10 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
|
|||||||
const LEX_STRING *key,
|
const LEX_STRING *key,
|
||||||
TABLE_LIST *belong_to_view)
|
TABLE_LIST *belong_to_view)
|
||||||
{
|
{
|
||||||
|
hash_init_opt(&lex->sroutines, system_charset_info,
|
||||||
|
Query_tables_list::START_SROUTINES_HASH_SIZE,
|
||||||
|
0, 0, sp_sroutine_key, 0, 0);
|
||||||
|
|
||||||
if (!hash_search(&lex->sroutines, (byte *)key->str, key->length))
|
if (!hash_search(&lex->sroutines, (byte *)key->str, key->length))
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry *rn=
|
Sroutine_hash_entry *rn=
|
||||||
|
@ -991,8 +991,7 @@ sp_head::execute(THD *thd)
|
|||||||
save_sql_mode= thd->variables.sql_mode;
|
save_sql_mode= thd->variables.sql_mode;
|
||||||
thd->variables.sql_mode= m_sql_mode;
|
thd->variables.sql_mode= m_sql_mode;
|
||||||
save_abort_on_warning= thd->abort_on_warning;
|
save_abort_on_warning= thd->abort_on_warning;
|
||||||
thd->abort_on_warning=
|
thd->abort_on_warning= 0;
|
||||||
(m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
It is also more efficient to save/restore current thd->lex once when
|
It is also more efficient to save/restore current thd->lex once when
|
||||||
|
@ -806,6 +806,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
|
||||||
|
|
||||||
@ -852,12 +856,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",
|
||||||
|
@ -322,7 +322,7 @@ cleanup:
|
|||||||
mysql_unlock_tables(thd, thd->lock);
|
mysql_unlock_tables(thd, thd->lock);
|
||||||
thd->lock=0;
|
thd->lock=0;
|
||||||
}
|
}
|
||||||
if (error < 0)
|
if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
|
||||||
{
|
{
|
||||||
thd->row_count_func= deleted;
|
thd->row_count_func= deleted;
|
||||||
send_ok(thd,deleted);
|
send_ok(thd,deleted);
|
||||||
|
@ -150,7 +150,6 @@ void lex_start(THD *thd, 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;
|
||||||
@ -1635,9 +1634,18 @@ void Query_tables_list::reset_query_tables_list(bool init)
|
|||||||
query_tables_last= &query_tables;
|
query_tables_last= &query_tables;
|
||||||
query_tables_own_last= 0;
|
query_tables_own_last= 0;
|
||||||
if (init)
|
if (init)
|
||||||
hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
|
{
|
||||||
|
/*
|
||||||
|
We delay real initialization of hash (and therefore related
|
||||||
|
memory allocation) until first insertion into this hash.
|
||||||
|
*/
|
||||||
|
hash_clear(&sroutines);
|
||||||
|
}
|
||||||
else if (sroutines.records)
|
else if (sroutines.records)
|
||||||
|
{
|
||||||
|
/* Non-zero sroutines.records means that hash was initialized. */
|
||||||
my_hash_reset(&sroutines);
|
my_hash_reset(&sroutines);
|
||||||
|
}
|
||||||
sroutines_list.empty();
|
sroutines_list.empty();
|
||||||
sroutines_list_own_last= sroutines_list.next;
|
sroutines_list_own_last= sroutines_list.next;
|
||||||
sroutines_list_own_elements= 0;
|
sroutines_list_own_elements= 0;
|
||||||
|
@ -743,7 +743,11 @@ public:
|
|||||||
0 - indicates that this query does not need prelocking.
|
0 - indicates that this query does not need prelocking.
|
||||||
*/
|
*/
|
||||||
TABLE_LIST **query_tables_own_last;
|
TABLE_LIST **query_tables_own_last;
|
||||||
/* Set of stored routines called by statement. */
|
/*
|
||||||
|
Set of stored routines called by statement.
|
||||||
|
(Note that we use lazy-initialization for this hash).
|
||||||
|
*/
|
||||||
|
enum { START_SROUTINES_HASH_SIZE= 16 };
|
||||||
HASH sroutines;
|
HASH sroutines;
|
||||||
/*
|
/*
|
||||||
List linking elements of 'sroutines' set. Allows you to add new elements
|
List linking elements of 'sroutines' set. Allows you to add new elements
|
||||||
@ -808,6 +812,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
|
||||||
@ -951,7 +974,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) */
|
||||||
|
@ -3045,11 +3045,6 @@ end_with_restore_list:
|
|||||||
|
|
||||||
case SQLCOM_ALTER_TABLE:
|
case SQLCOM_ALTER_TABLE:
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
|
||||||
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
|
|
||||||
MYF(0)); /* purecov: inspected */
|
|
||||||
goto error;
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
ulong priv=0;
|
ulong priv=0;
|
||||||
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
|
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
|
||||||
@ -3115,7 +3110,6 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /*DONT_ALLOW_SHOW_COMMANDS*/
|
|
||||||
case SQLCOM_RENAME_TABLE:
|
case SQLCOM_RENAME_TABLE:
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
@ -3369,8 +3363,16 @@ end_with_restore_list:
|
|||||||
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
|
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
|
||||||
lex->update_list, lex->value_list,
|
lex->update_list, lex->value_list,
|
||||||
lex->duplicates, lex->ignore);
|
lex->duplicates, lex->ignore);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If we have inserted into a VIEW, and the base table has
|
||||||
|
AUTO_INCREMENT column, but this column is not accessible through
|
||||||
|
a view, then we should restore LAST_INSERT_ID to the value it
|
||||||
|
had before the statement.
|
||||||
|
*/
|
||||||
if (first_table->view && !first_table->contain_auto_increment)
|
if (first_table->view && !first_table->contain_auto_increment)
|
||||||
thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
|
thd->last_insert_id= thd->current_insert_id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_REPLACE_SELECT:
|
case SQLCOM_REPLACE_SELECT:
|
||||||
@ -3431,8 +3433,15 @@ end_with_restore_list:
|
|||||||
select_lex->table_list.first= (byte*) first_table;
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If we have inserted into a VIEW, and the base table has
|
||||||
|
AUTO_INCREMENT column, but this column is not accessible through
|
||||||
|
a view, then we should restore LAST_INSERT_ID to the value it
|
||||||
|
had before the statement.
|
||||||
|
*/
|
||||||
if (first_table->view && !first_table->contain_auto_increment)
|
if (first_table->view && !first_table->contain_auto_increment)
|
||||||
thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
|
thd->last_insert_id= thd->current_insert_id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_TRUNCATE:
|
case SQLCOM_TRUNCATE:
|
||||||
@ -5878,14 +5887,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 (thd->lex->sphead)
|
if (thd->lex->sphead)
|
||||||
{
|
{
|
||||||
/* Clean up after failed stored procedure/function */
|
/* Clean up after failed stored procedure/function */
|
||||||
delete thd->lex->sphead;
|
delete thd->lex->sphead;
|
||||||
thd->lex->sphead= NULL;
|
thd->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();
|
||||||
|
@ -2773,6 +2773,16 @@ 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;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
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
|
||||||
@ -2798,6 +2808,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;
|
||||||
|
202
sql/sql_table.cc
202
sql/sql_table.cc
@ -2934,208 +2934,6 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/*
|
|
||||||
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
|
|
||||||
the proper arguments. This isn't very fast but it should work for most
|
|
||||||
cases.
|
|
||||||
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
|
||||||
{
|
|
||||||
List<create_field> fields;
|
|
||||||
List<Alter_drop> drop;
|
|
||||||
List<Alter_column> alter;
|
|
||||||
HA_CREATE_INFO create_info;
|
|
||||||
int rc;
|
|
||||||
uint idx;
|
|
||||||
uint db_options;
|
|
||||||
uint key_count;
|
|
||||||
TABLE *table;
|
|
||||||
Field **f_ptr;
|
|
||||||
KEY *key_info_buffer;
|
|
||||||
char path[FN_REFLEN+1];
|
|
||||||
DBUG_ENTER("mysql_create_index");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Try to use online generation of index.
|
|
||||||
This requires that all indexes can be created online.
|
|
||||||
Otherwise, the old alter table procedure is executed.
|
|
||||||
|
|
||||||
Open the table to have access to the correct table handler.
|
|
||||||
*/
|
|
||||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The add_index method takes an array of KEY structs for the new indexes.
|
|
||||||
Preparing a new table structure generates this array.
|
|
||||||
It needs a list with all fields of the table, which does not need to
|
|
||||||
be correct in every respect. The field names are important.
|
|
||||||
*/
|
|
||||||
for (f_ptr= table->field; *f_ptr; f_ptr++)
|
|
||||||
{
|
|
||||||
create_field *c_fld= new create_field(*f_ptr, *f_ptr);
|
|
||||||
c_fld->unireg_check= Field::NONE; /*avoid multiple auto_increments*/
|
|
||||||
fields.push_back(c_fld);
|
|
||||||
}
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
|
||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
|
||||||
create_info.default_table_charset= thd->variables.collation_database;
|
|
||||||
db_options= 0;
|
|
||||||
if (mysql_prepare_table(thd, &create_info, &fields,
|
|
||||||
&keys, /*tmp_table*/ 0, &db_options, table->file,
|
|
||||||
&key_info_buffer, key_count,
|
|
||||||
/*select_field_count*/ 0))
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check if all keys can be generated with the add_index method.
|
|
||||||
If anyone cannot, then take the old way.
|
|
||||||
*/
|
|
||||||
for (idx=0; idx< key_count; idx++)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name));
|
|
||||||
if (!(table->file->index_ddl_flags(key_info_buffer+idx)&
|
|
||||||
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ((idx < key_count)|| !key_count)
|
|
||||||
{
|
|
||||||
/* Re-initialize the create_info, which was changed by prepare table. */
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
|
||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
|
||||||
create_info.default_table_charset= thd->variables.collation_database;
|
|
||||||
/* Cleanup the fields list. We do not want to create existing fields. */
|
|
||||||
fields.delete_elements();
|
|
||||||
if (real_alter_table(thd, table_list->db, table_list->table_name,
|
|
||||||
&create_info, table_list, table,
|
|
||||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
|
||||||
ALTER_ADD_INDEX, DUP_ERROR))
|
|
||||||
/* Don't need to free((gptr) key_info_buffer);*/
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (table->file->add_index(table, key_info_buffer, key_count)||
|
|
||||||
build_table_path(path, sizeof(path), table_list->db,
|
|
||||||
(lower_case_table_names == 2) ?
|
|
||||||
table_list->alias : table_list->table_name,
|
|
||||||
reg_ext) == 0 ||
|
|
||||||
mysql_create_frm(thd, path, &create_info,
|
|
||||||
fields, key_count, key_info_buffer, table->file))
|
|
||||||
/* don't need to free((gptr) key_info_buffer);*/
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
/* don't need to free((gptr) key_info_buffer);*/
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
|
|
||||||
List<Alter_drop> &drop)
|
|
||||||
{
|
|
||||||
List<create_field> fields;
|
|
||||||
List<Key> keys;
|
|
||||||
List<Alter_column> alter;
|
|
||||||
HA_CREATE_INFO create_info;
|
|
||||||
uint idx;
|
|
||||||
uint db_options;
|
|
||||||
uint key_count;
|
|
||||||
uint *key_numbers;
|
|
||||||
TABLE *table;
|
|
||||||
Field **f_ptr;
|
|
||||||
KEY *key_info;
|
|
||||||
KEY *key_info_buffer;
|
|
||||||
char path[FN_REFLEN];
|
|
||||||
DBUG_ENTER("mysql_drop_index");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Try to use online generation of index.
|
|
||||||
This requires that all indexes can be created online.
|
|
||||||
Otherwise, the old alter table procedure is executed.
|
|
||||||
|
|
||||||
Open the table to have access to the correct table handler.
|
|
||||||
*/
|
|
||||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The drop_index method takes an array of key numbers.
|
|
||||||
It cannot get more entries than keys in the table.
|
|
||||||
*/
|
|
||||||
key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys);
|
|
||||||
key_count= 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the number of each key and check if it can be created online.
|
|
||||||
*/
|
|
||||||
List_iterator<Alter_drop> drop_it(drop);
|
|
||||||
Alter_drop *drop_key;
|
|
||||||
while ((drop_key= drop_it++))
|
|
||||||
{
|
|
||||||
/* Find the key in the table. */
|
|
||||||
key_info=table->key_info;
|
|
||||||
for (idx=0; idx< table->keys; idx++, key_info++)
|
|
||||||
{
|
|
||||||
if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (idx>= table->keys)
|
|
||||||
{
|
|
||||||
my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name);
|
|
||||||
/*don't need to free((gptr) key_numbers);*/
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Check if the key can be generated with the add_index method.
|
|
||||||
If anyone cannot, then take the old way.
|
|
||||||
*/
|
|
||||||
DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name));
|
|
||||||
if (!(table->file->index_ddl_flags(table->key_info+idx)&
|
|
||||||
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
|
|
||||||
break ;
|
|
||||||
key_numbers[key_count++]= idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
|
||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
|
||||||
create_info.default_table_charset= thd->variables.collation_database;
|
|
||||||
|
|
||||||
if ((drop_key)|| (drop.elements<= 0))
|
|
||||||
{
|
|
||||||
if (real_alter_table(thd, table_list->db, table_list->table_name,
|
|
||||||
&create_info, table_list, table,
|
|
||||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
|
||||||
ALTER_DROP_INDEX, DUP_ERROR))
|
|
||||||
/*don't need to free((gptr) key_numbers);*/
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
db_options= 0;
|
|
||||||
if (table->file->drop_index(table, key_numbers, key_count)||
|
|
||||||
mysql_prepare_table(thd, &create_info, &fields,
|
|
||||||
&keys, /*tmp_table*/ 0, &db_options, table->file,
|
|
||||||
&key_info_buffer, key_count,
|
|
||||||
/*select_field_count*/ 0)||
|
|
||||||
build_table_path(path, sizeof(path), table_list->db,
|
|
||||||
(lower_case_table_names == 2) ?
|
|
||||||
table_list->alias : table_list->table_name,
|
|
||||||
reg_ext) == 0 ||
|
|
||||||
mysql_create_frm(thd, path, &create_info,
|
|
||||||
fields, key_count, key_info_buffer, table->file))
|
|
||||||
/*don't need to free((gptr) key_numbers);*/
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*don't need to free((gptr) key_numbers);*/
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
#endif /* NOT_USED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Alter table
|
Alter table
|
||||||
*/
|
*/
|
||||||
|
@ -36,17 +36,17 @@ static File_option triggers_file_parameters[]=
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
{(char *) STRING_WITH_LEN("triggers") },
|
{(char *) 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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{(char *) STRING_WITH_LEN("sql_modes") },
|
{(char *) 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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{(char *) STRING_WITH_LEN("definers") },
|
{(char *) 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=
|
||||||
{
|
{
|
||||||
{(char*) STRING_WITH_LEN("sql_modes") },
|
{(char*) 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[]=
|
||||||
{{{(char*) STRING_WITH_LEN("query")},
|
{{{(char*) STRING_WITH_LEN("query")},
|
||||||
offsetof(TABLE_LIST, query),
|
my_offsetof(TABLE_LIST, query),
|
||||||
FILE_OPTIONS_ESTRING},
|
FILE_OPTIONS_ESTRING},
|
||||||
{{(char*) STRING_WITH_LEN("md5")},
|
{{(char*) STRING_WITH_LEN("md5")},
|
||||||
offsetof(TABLE_LIST, md5),
|
my_offsetof(TABLE_LIST, md5),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{(char*) STRING_WITH_LEN("updatable")},
|
{{(char*) STRING_WITH_LEN("updatable")},
|
||||||
offsetof(TABLE_LIST, updatable_view),
|
my_offsetof(TABLE_LIST, updatable_view),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{(char*) STRING_WITH_LEN("algorithm")},
|
{{(char*) STRING_WITH_LEN("algorithm")},
|
||||||
offsetof(TABLE_LIST, algorithm),
|
my_offsetof(TABLE_LIST, algorithm),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{(char*) STRING_WITH_LEN("definer_user")},
|
{{(char*) STRING_WITH_LEN("definer_user")},
|
||||||
offsetof(TABLE_LIST, definer.user),
|
my_offsetof(TABLE_LIST, definer.user),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{(char*) STRING_WITH_LEN("definer_host")},
|
{{(char*) STRING_WITH_LEN("definer_host")},
|
||||||
offsetof(TABLE_LIST, definer.host),
|
my_offsetof(TABLE_LIST, definer.host),
|
||||||
FILE_OPTIONS_STRING},
|
FILE_OPTIONS_STRING},
|
||||||
{{(char*) STRING_WITH_LEN("suid")},
|
{{(char*) STRING_WITH_LEN("suid")},
|
||||||
offsetof(TABLE_LIST, view_suid),
|
my_offsetof(TABLE_LIST, view_suid),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{(char*) STRING_WITH_LEN("with_check_option")},
|
{{(char*) STRING_WITH_LEN("with_check_option")},
|
||||||
offsetof(TABLE_LIST, with_check),
|
my_offsetof(TABLE_LIST, with_check),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{(char*) STRING_WITH_LEN("revision")},
|
{{(char*) STRING_WITH_LEN("revision")},
|
||||||
offsetof(TABLE_LIST, revision),
|
my_offsetof(TABLE_LIST, revision),
|
||||||
FILE_OPTIONS_REV},
|
FILE_OPTIONS_REV},
|
||||||
{{(char*) STRING_WITH_LEN("timestamp")},
|
{{(char*) STRING_WITH_LEN("timestamp")},
|
||||||
offsetof(TABLE_LIST, timestamp),
|
my_offsetof(TABLE_LIST, timestamp),
|
||||||
FILE_OPTIONS_TIMESTAMP},
|
FILE_OPTIONS_TIMESTAMP},
|
||||||
{{(char*)STRING_WITH_LEN("create-version")},
|
{{(char*)STRING_WITH_LEN("create-version")},
|
||||||
offsetof(TABLE_LIST, file_version),
|
my_offsetof(TABLE_LIST, file_version),
|
||||||
FILE_OPTIONS_ULONGLONG},
|
FILE_OPTIONS_ULONGLONG},
|
||||||
{{(char*) STRING_WITH_LEN("source")},
|
{{(char*) 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}
|
||||||
|
159
sql/sql_yacc.yy
159
sql/sql_yacc.yy
@ -650,11 +650,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token UNIX_TIMESTAMP
|
%token UNIX_TIMESTAMP
|
||||||
%token UNKNOWN_SYM
|
%token UNKNOWN_SYM
|
||||||
%token UNLOCK_SYM
|
%token UNLOCK_SYM
|
||||||
%token UNLOCK_SYM
|
|
||||||
%token UNSIGNED
|
%token UNSIGNED
|
||||||
%token UNTIL_SYM
|
%token UNTIL_SYM
|
||||||
%token UNTIL_SYM
|
|
||||||
%token UPDATE_SYM
|
|
||||||
%token UPDATE_SYM
|
%token UPDATE_SYM
|
||||||
%token UPGRADE_SYM
|
%token UPGRADE_SYM
|
||||||
%token USAGE
|
%token USAGE
|
||||||
@ -749,7 +746,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
|
||||||
@ -1447,15 +1444,20 @@ call:
|
|||||||
lex->value_list.empty();
|
lex->value_list.empty();
|
||||||
sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
|
sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
|
||||||
}
|
}
|
||||||
'(' sp_cparam_list ')' {}
|
opt_sp_cparam_list {}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* CALL parameters */
|
/* CALL parameters */
|
||||||
sp_cparam_list:
|
opt_sp_cparam_list:
|
||||||
/* Empty */
|
/* Empty */
|
||||||
| sp_cparams
|
| '(' opt_sp_cparams ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_sp_cparams:
|
||||||
|
/* Empty */
|
||||||
|
| sp_cparams
|
||||||
|
;
|
||||||
|
|
||||||
sp_cparams:
|
sp_cparams:
|
||||||
sp_cparams ',' expr
|
sp_cparams ',' expr
|
||||||
{
|
{
|
||||||
@ -4325,32 +4327,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); }
|
||||||
@ -5060,6 +5037,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; };
|
||||||
@ -5166,7 +5183,7 @@ when_list2:
|
|||||||
/* Warning - may return NULL in case of incomplete SELECT */
|
/* Warning - may return NULL in case of incomplete SELECT */
|
||||||
table_ref:
|
table_ref:
|
||||||
table_factor { $$=$1; }
|
table_factor { $$=$1; }
|
||||||
| join_table { $$=$1; }
|
| join_table
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
if (!($$= lex->current_select->nest_last_join(lex->thd)))
|
if (!($$= lex->current_select->nest_last_join(lex->thd)))
|
||||||
@ -5208,7 +5225,7 @@ join_table:
|
|||||||
| table_ref normal_join table_ref
|
| table_ref normal_join table_ref
|
||||||
ON
|
ON
|
||||||
{
|
{
|
||||||
YYERROR_UNLESS($1 && ($$=$3));
|
YYERROR_UNLESS($1 && $3);
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -5223,7 +5240,7 @@ join_table:
|
|||||||
| table_ref STRAIGHT_JOIN table_factor
|
| table_ref STRAIGHT_JOIN table_factor
|
||||||
ON
|
ON
|
||||||
{
|
{
|
||||||
YYERROR_UNLESS($1 && ($$=$3));
|
YYERROR_UNLESS($1 && $3);
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -5490,6 +5507,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))
|
||||||
@ -5849,6 +5873,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");
|
||||||
@ -5948,28 +5979,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);
|
||||||
}
|
}
|
||||||
@ -7129,8 +7172,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));
|
||||||
@ -7250,6 +7298,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 -
|
||||||
@ -7259,7 +7313,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
|
||||||
@ -9107,6 +9160,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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user