mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge ramayana.hindu.god:/home/tsmith/m/bk/50
into ramayana.hindu.god:/home/tsmith/m/bk/maint/50 sql/sql_select.cc: Auto merged
This commit is contained in:
@ -1177,4 +1177,40 @@ id c1 c2
|
|||||||
4 2 3
|
4 2 3
|
||||||
1 5 1
|
1 5 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ( a INT, b INT );
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
c (SELECT a FROM t1 WHERE b = c)
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
c (SELECT a FROM t1 WHERE b = c)
|
||||||
|
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
ERROR 42S22: Reference 'c' not supported (reference to group function)
|
||||||
|
SET @old_sql_mode = @@sql_mode;
|
||||||
|
SET @@sql_mode='ONLY_FULL_GROUP_BY';
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
c (SELECT a FROM t1 WHERE b = c)
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
ERROR 42000: non-grouping field 'b' is used in HAVING clause
|
||||||
|
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
ERROR 42S22: Reference 'c' not supported (reference to group function)
|
||||||
|
INSERT INTO t1 VALUES (1, 1);
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
c (SELECT a FROM t1 WHERE b = c)
|
||||||
|
1 1
|
||||||
|
INSERT INTO t1 VALUES (2, 1);
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@sql_mode = @old_sql_mode;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -733,4 +733,113 @@ optimizer: keep hreturn
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
drop procedure proc_26977_broken;
|
drop procedure proc_26977_broken;
|
||||||
drop procedure proc_26977_works;
|
drop procedure proc_26977_works;
|
||||||
|
drop procedure if exists proc_33618_h;
|
||||||
|
drop procedure if exists proc_33618_c;
|
||||||
|
create procedure proc_33618_h(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare exit handler for 1062 begin end;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
## should generate a hpop instruction here
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
create procedure proc_33618_c(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare cur2 cursor for select `b` from t_33618;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
## should generate a cpop instruction here
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
show procedure code proc_33618_h;
|
||||||
|
Pos Instruction
|
||||||
|
0 set count1@1 _latin1'0'
|
||||||
|
1 set vb@2 NULL
|
||||||
|
2 set last_row@3 NULL
|
||||||
|
3 jump_if_not 24(24) (num@0 >= 1)
|
||||||
|
4 set num@0 (num@0 - 1)
|
||||||
|
5 cpush cur1@0
|
||||||
|
6 hpush_jump 9 4 CONTINUE
|
||||||
|
7 set last_row@3 1
|
||||||
|
8 hreturn 4
|
||||||
|
9 set last_row@3 0
|
||||||
|
10 copen cur1@0
|
||||||
|
11 hpush_jump 13 4 EXIT
|
||||||
|
12 hreturn 0 17
|
||||||
|
13 cfetch cur1@0 vb@2
|
||||||
|
14 jump_if_not 17(17) (last_row@3 = 1)
|
||||||
|
15 hpop 1
|
||||||
|
16 jump 19
|
||||||
|
17 hpop 1
|
||||||
|
18 jump_if_not 11(19) (last_row@3 = 1)
|
||||||
|
19 cclose cur1@0
|
||||||
|
20 hpop 1
|
||||||
|
21 cpop 1
|
||||||
|
22 jump 3
|
||||||
|
show procedure code proc_33618_c;
|
||||||
|
Pos Instruction
|
||||||
|
0 set count1@1 _latin1'0'
|
||||||
|
1 set vb@2 NULL
|
||||||
|
2 set last_row@3 NULL
|
||||||
|
3 jump_if_not 23(23) (num@0 >= 1)
|
||||||
|
4 set num@0 (num@0 - 1)
|
||||||
|
5 cpush cur1@0
|
||||||
|
6 hpush_jump 9 4 CONTINUE
|
||||||
|
7 set last_row@3 1
|
||||||
|
8 hreturn 4
|
||||||
|
9 set last_row@3 0
|
||||||
|
10 copen cur1@0
|
||||||
|
11 cpush cur2@1
|
||||||
|
12 cfetch cur1@0 vb@2
|
||||||
|
13 jump_if_not 16(16) (last_row@3 = 1)
|
||||||
|
14 cpop 1
|
||||||
|
15 jump 18
|
||||||
|
16 cpop 1
|
||||||
|
17 jump_if_not 11(18) (last_row@3 = 1)
|
||||||
|
18 cclose cur1@0
|
||||||
|
19 hpop 1
|
||||||
|
20 cpop 1
|
||||||
|
21 jump 3
|
||||||
|
drop procedure proc_33618_h;
|
||||||
|
drop procedure proc_33618_c;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -1465,3 +1465,51 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
|
|||||||
SELECT ..inexistent();
|
SELECT ..inexistent();
|
||||||
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 '.inexistent()' at line 1
|
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 '.inexistent()' at line 1
|
||||||
USE test;
|
USE test;
|
||||||
|
drop procedure if exists proc_33983_a;
|
||||||
|
drop procedure if exists proc_33983_b;
|
||||||
|
drop procedure if exists proc_33983_c;
|
||||||
|
drop procedure if exists proc_33983_d;
|
||||||
|
create procedure proc_33983_a()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
begin
|
||||||
|
label2:
|
||||||
|
begin
|
||||||
|
select 1;
|
||||||
|
end label1;
|
||||||
|
end;
|
||||||
|
end|
|
||||||
|
ERROR 42000: End-label label1 without match
|
||||||
|
create procedure proc_33983_b()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
repeat
|
||||||
|
label2:
|
||||||
|
repeat
|
||||||
|
select 1;
|
||||||
|
until FALSE end repeat label1;
|
||||||
|
until FALSE end repeat;
|
||||||
|
end|
|
||||||
|
ERROR 42000: End-label label1 without match
|
||||||
|
create procedure proc_33983_c()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
while TRUE do
|
||||||
|
label2:
|
||||||
|
while TRUE do
|
||||||
|
select 1;
|
||||||
|
end while label1;
|
||||||
|
end while;
|
||||||
|
end|
|
||||||
|
ERROR 42000: End-label label1 without match
|
||||||
|
create procedure proc_33983_d()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
loop
|
||||||
|
label2:
|
||||||
|
loop
|
||||||
|
select 1;
|
||||||
|
end loop label1;
|
||||||
|
end loop;
|
||||||
|
end|
|
||||||
|
ERROR 42000: End-label label1 without match
|
||||||
|
@ -6578,6 +6578,57 @@ DROP PROCEDURE db28318_a.t1;
|
|||||||
DROP PROCEDURE db28318_b.t2;
|
DROP PROCEDURE db28318_b.t2;
|
||||||
DROP DATABASE db28318_a;
|
DROP DATABASE db28318_a;
|
||||||
DROP DATABASE db28318_b;
|
DROP DATABASE db28318_b;
|
||||||
|
USE test;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP PROCEDURE IF EXISTS bug29770;
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
CREATE PROCEDURE bug29770()
|
||||||
|
BEGIN
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
|
||||||
|
SELECT x FROM t1;
|
||||||
|
END|
|
||||||
|
CALL bug29770();
|
||||||
|
SELECT @state, @exception;
|
||||||
|
@state @exception
|
||||||
|
run NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP PROCEDURE bug29770;
|
||||||
|
use test;
|
||||||
|
drop table if exists t_33618;
|
||||||
|
drop procedure if exists proc_33618;
|
||||||
|
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
|
||||||
|
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
|
||||||
|
create procedure proc_33618(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare exit handler for 1062 begin end;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
call proc_33618(20);
|
||||||
|
drop table t_33618;
|
||||||
|
drop procedure proc_33618;
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# -- End of 5.0 tests
|
# -- End of 5.0 tests
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
@ -4392,4 +4392,52 @@ select count(*) from t1 where f12 =
|
|||||||
count(*)
|
count(*)
|
||||||
3
|
3
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
CREATE TABLE t4 (
|
||||||
|
f7 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f10 varchar(32) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f7)
|
||||||
|
);
|
||||||
|
INSERT INTO t4 VALUES(1,1), (2,null);
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
f4 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f2 varchar(50) collate utf8_bin default NULL,
|
||||||
|
f3 varchar(10) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f4),
|
||||||
|
UNIQUE KEY uk1 (f2)
|
||||||
|
);
|
||||||
|
INSERT INTO t2 VALUES(1,1,null), (2,2,null);
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
f8 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f1 varchar(10) collate utf8_bin default NULL,
|
||||||
|
f9 varchar(32) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f8)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
|
||||||
|
CREATE TABLE t3 (
|
||||||
|
f6 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f5 varchar(50) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f6)
|
||||||
|
);
|
||||||
|
INSERT INTO t3 VALUES (1,null), (2,null);
|
||||||
|
SELECT
|
||||||
|
IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
|
||||||
|
IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
|
||||||
|
SUM(
|
||||||
|
IF(
|
||||||
|
(SELECT VPC.f2
|
||||||
|
FROM t2 VPC, t4 a2, t2 a3
|
||||||
|
WHERE
|
||||||
|
VPC.f4 = a2.f10 AND a3.f2 = a4
|
||||||
|
LIMIT 1) IS NULL,
|
||||||
|
0,
|
||||||
|
t3.f5
|
||||||
|
)
|
||||||
|
) AS a6
|
||||||
|
FROM
|
||||||
|
t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
|
||||||
|
GROUP BY a4;
|
||||||
|
a4 f3 a6
|
||||||
|
1 NULL NULL
|
||||||
|
2 NULL NULL
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -794,7 +794,7 @@ dps tinyint(3) unsigned default NULL
|
|||||||
INSERT INTO t1 VALUES (1.1325,3);
|
INSERT INTO t1 VALUES (1.1325,3);
|
||||||
SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
|
SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
|
||||||
ROUND(qty,3) dps ROUND(qty,dps)
|
ROUND(qty,3) dps ROUND(qty,dps)
|
||||||
1.133 3 1.133
|
1.133 3 1.133000
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
|
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
|
||||||
%
|
%
|
||||||
@ -885,4 +885,65 @@ c
|
|||||||
1000
|
1000
|
||||||
1234567890
|
1234567890
|
||||||
DROP TABLE t1, t2, t3, t4;
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
CREATE TABLE t1( a DECIMAL(4, 3), b INT );
|
||||||
|
INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
|
||||||
|
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
|
||||||
|
a b c
|
||||||
|
1.000 5 1.000
|
||||||
|
2.000 4 2.000
|
||||||
|
3.000 3 3.000
|
||||||
|
4.000 2 4.000
|
||||||
|
5.000 1 5.000
|
||||||
|
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
|
||||||
|
a b c
|
||||||
|
5.000 1 5.000
|
||||||
|
4.000 2 4.000
|
||||||
|
3.000 3 3.000
|
||||||
|
2.000 4 2.000
|
||||||
|
1.000 5 1.000
|
||||||
|
CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
|
||||||
|
INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
|
||||||
|
( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
|
||||||
|
SELECT a, b, MAX(ROUND(c, a))
|
||||||
|
FROM t2
|
||||||
|
GROUP BY a, b
|
||||||
|
ORDER BY b;
|
||||||
|
a b MAX(ROUND(c, a))
|
||||||
|
0 1 1.0000
|
||||||
|
1 2 1.2000
|
||||||
|
3 3 1.2350
|
||||||
|
2 4 1.2300
|
||||||
|
SELECT a, b, ROUND(c, a)
|
||||||
|
FROM t2;
|
||||||
|
a b ROUND(c, a)
|
||||||
|
0 1 1.0000
|
||||||
|
1 2 1.2000
|
||||||
|
3 3 1.2350
|
||||||
|
2 4 1.2300
|
||||||
|
CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
|
||||||
|
INSERT INTO t3 VALUES( 0, 1.5 );
|
||||||
|
SELECT ROUND( b, a ) FROM t3;
|
||||||
|
ROUND( b, a )
|
||||||
|
2.000
|
||||||
|
CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
|
||||||
|
INSERT INTO t4 VALUES( -9, 1.5e9 );
|
||||||
|
SELECT ROUND( b, a ) FROM t4;
|
||||||
|
ROUND( b, a )
|
||||||
|
2000000000
|
||||||
|
CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
|
||||||
|
INSERT INTO t5 VALUES( 0, 1.5 );
|
||||||
|
INSERT INTO t5 VALUES( 9, 1.5e-9 );
|
||||||
|
SELECT ROUND( b, a ) FROM t5;
|
||||||
|
ROUND( b, a )
|
||||||
|
2.000000000000
|
||||||
|
0.000000002000
|
||||||
|
CREATE TABLE t6( a INT );
|
||||||
|
INSERT INTO t6 VALUES( 6 / 8 );
|
||||||
|
SELECT * FROM t6;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
SELECT ROUND(20061108085411.000002);
|
||||||
|
ROUND(20061108085411.000002)
|
||||||
|
20061108085411
|
||||||
|
DROP TABLE t1, t2, t3, t4, t5, t6;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -3602,4 +3602,20 @@ DROP VIEW v1;
|
|||||||
DROP VIEW v2;
|
DROP VIEW v2;
|
||||||
DROP VIEW v3;
|
DROP VIEW v3;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#29477: Not all fields of the target table were checked to have
|
||||||
|
# a default value when inserting into a view.
|
||||||
|
#
|
||||||
|
create table t1(f1 int, f2 int not null);
|
||||||
|
create view v1 as select f1 from t1;
|
||||||
|
insert into v1 values(1);
|
||||||
|
Warnings:
|
||||||
|
Warning 1423 Field of view 'test.v1' underlying table doesn't have a default value
|
||||||
|
set @old_mode=@@sql_mode;
|
||||||
|
set @@sql_mode=traditional;
|
||||||
|
insert into v1 values(1);
|
||||||
|
ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
|
||||||
|
set @@sql_mode=@old_mode;
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -849,4 +849,48 @@ SELECT * FROM t1 GROUP BY c2 ORDER BY c2 DESC, c1 DESC;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# Bug #31797: error while parsing subqueries -- WHERE is parsed as HAVING
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( a INT, b INT );
|
||||||
|
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
|
||||||
|
--error ER_ILLEGAL_REFERENCE
|
||||||
|
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
|
||||||
|
SET @old_sql_mode = @@sql_mode;
|
||||||
|
SET @@sql_mode='ONLY_FULL_GROUP_BY';
|
||||||
|
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
|
||||||
|
--error ER_NON_GROUPING_FIELD_USED
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
|
||||||
|
--error ER_ILLEGAL_REFERENCE
|
||||||
|
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1
|
||||||
|
HAVING b = 10;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1, 1);
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (2, 1);
|
||||||
|
--error ER_SUBQUERY_NO_1_ROW
|
||||||
|
SELECT b c, (SELECT a FROM t1 WHERE b = c)
|
||||||
|
FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@sql_mode = @old_sql_mode;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -520,5 +520,82 @@ drop table t1;
|
|||||||
drop procedure proc_26977_broken;
|
drop procedure proc_26977_broken;
|
||||||
drop procedure proc_26977_works;
|
drop procedure proc_26977_works;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#33618 Crash in sp_rcontext
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists proc_33618_h;
|
||||||
|
drop procedure if exists proc_33618_c;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter //;
|
||||||
|
|
||||||
|
create procedure proc_33618_h(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare exit handler for 1062 begin end;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
## should generate a hpop instruction here
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
|
||||||
|
create procedure proc_33618_c(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare cur2 cursor for select `b` from t_33618;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
## should generate a cpop instruction here
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
delimiter ;//
|
||||||
|
|
||||||
|
show procedure code proc_33618_h;
|
||||||
|
show procedure code proc_33618_c;
|
||||||
|
|
||||||
|
drop procedure proc_33618_h;
|
||||||
|
drop procedure proc_33618_c;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
@ -2112,6 +2112,69 @@ SELECT .inexistent();
|
|||||||
SELECT ..inexistent();
|
SELECT ..inexistent();
|
||||||
USE test;
|
USE test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted)
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists proc_33983_a;
|
||||||
|
drop procedure if exists proc_33983_b;
|
||||||
|
drop procedure if exists proc_33983_c;
|
||||||
|
drop procedure if exists proc_33983_d;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
--error ER_SP_LABEL_MISMATCH
|
||||||
|
create procedure proc_33983_a()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
begin
|
||||||
|
label2:
|
||||||
|
begin
|
||||||
|
select 1;
|
||||||
|
end label1;
|
||||||
|
end;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_SP_LABEL_MISMATCH
|
||||||
|
create procedure proc_33983_b()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
repeat
|
||||||
|
label2:
|
||||||
|
repeat
|
||||||
|
select 1;
|
||||||
|
until FALSE end repeat label1;
|
||||||
|
until FALSE end repeat;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_SP_LABEL_MISMATCH
|
||||||
|
create procedure proc_33983_c()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
while TRUE do
|
||||||
|
label2:
|
||||||
|
while TRUE do
|
||||||
|
select 1;
|
||||||
|
end while label1;
|
||||||
|
end while;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_SP_LABEL_MISMATCH
|
||||||
|
create procedure proc_33983_d()
|
||||||
|
begin
|
||||||
|
label1:
|
||||||
|
loop
|
||||||
|
label2:
|
||||||
|
loop
|
||||||
|
select 1;
|
||||||
|
end loop label1;
|
||||||
|
end loop;
|
||||||
|
end|
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
@ -7698,7 +7698,82 @@ DROP PROCEDURE db28318_a.t1;
|
|||||||
DROP PROCEDURE db28318_b.t2;
|
DROP PROCEDURE db28318_b.t2;
|
||||||
DROP DATABASE db28318_a;
|
DROP DATABASE db28318_a;
|
||||||
DROP DATABASE db28318_b;
|
DROP DATABASE db28318_b;
|
||||||
|
USE test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#29770 Two handlers are allowed to catch an error in an stored procedure.
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP PROCEDURE IF EXISTS bug29770;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE bug29770()
|
||||||
|
BEGIN
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
|
||||||
|
SELECT x FROM t1;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
CALL bug29770();
|
||||||
|
SELECT @state, @exception;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP PROCEDURE bug29770;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#33618 Crash in sp_rcontext
|
||||||
|
#
|
||||||
|
|
||||||
|
use test;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t_33618;
|
||||||
|
drop procedure if exists proc_33618;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
|
||||||
|
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
|
||||||
|
|
||||||
|
delimiter //;
|
||||||
|
|
||||||
|
create procedure proc_33618(num int)
|
||||||
|
begin
|
||||||
|
declare count1 int default '0';
|
||||||
|
declare vb varchar(30);
|
||||||
|
declare last_row int;
|
||||||
|
|
||||||
|
while(num>=1) do
|
||||||
|
set num=num-1;
|
||||||
|
begin
|
||||||
|
declare cur1 cursor for select `a` from t_33618;
|
||||||
|
declare continue handler for not found set last_row = 1;
|
||||||
|
set last_row:=0;
|
||||||
|
open cur1;
|
||||||
|
rep1:
|
||||||
|
repeat
|
||||||
|
begin
|
||||||
|
declare exit handler for 1062 begin end;
|
||||||
|
fetch cur1 into vb;
|
||||||
|
if (last_row = 1) then
|
||||||
|
leave rep1;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
until last_row=1
|
||||||
|
end repeat;
|
||||||
|
close cur1;
|
||||||
|
end;
|
||||||
|
end while;
|
||||||
|
end//
|
||||||
|
|
||||||
|
delimiter ;//
|
||||||
|
|
||||||
|
call proc_33618(20);
|
||||||
|
|
||||||
|
drop table t_33618;
|
||||||
|
drop procedure proc_33618;
|
||||||
|
|
||||||
--echo # ------------------------------------------------------------------
|
--echo # ------------------------------------------------------------------
|
||||||
--echo # -- End of 5.0 tests
|
--echo # -- End of 5.0 tests
|
||||||
|
@ -3252,4 +3252,60 @@ select count(*) from t1 where f12 =
|
|||||||
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
|
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
|
||||||
|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#33794 "MySQL crashes executing specific query on specific dump"
|
||||||
|
#
|
||||||
|
CREATE TABLE t4 (
|
||||||
|
f7 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f10 varchar(32) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f7)
|
||||||
|
);
|
||||||
|
INSERT INTO t4 VALUES(1,1), (2,null);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
f4 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f2 varchar(50) collate utf8_bin default NULL,
|
||||||
|
f3 varchar(10) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f4),
|
||||||
|
UNIQUE KEY uk1 (f2)
|
||||||
|
);
|
||||||
|
INSERT INTO t2 VALUES(1,1,null), (2,2,null);
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
f8 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f1 varchar(10) collate utf8_bin default NULL,
|
||||||
|
f9 varchar(32) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f8)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (
|
||||||
|
f6 varchar(32) collate utf8_bin NOT NULL default '',
|
||||||
|
f5 varchar(50) collate utf8_bin default NULL,
|
||||||
|
PRIMARY KEY (f6)
|
||||||
|
);
|
||||||
|
INSERT INTO t3 VALUES (1,null), (2,null);
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
|
||||||
|
IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
|
||||||
|
SUM(
|
||||||
|
IF(
|
||||||
|
(SELECT VPC.f2
|
||||||
|
FROM t2 VPC, t4 a2, t2 a3
|
||||||
|
WHERE
|
||||||
|
VPC.f4 = a2.f10 AND a3.f2 = a4
|
||||||
|
LIMIT 1) IS NULL,
|
||||||
|
0,
|
||||||
|
t3.f5
|
||||||
|
)
|
||||||
|
) AS a6
|
||||||
|
FROM
|
||||||
|
t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
|
||||||
|
GROUP BY a4;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
@ -478,4 +478,47 @@ select round(a,b) as c from t1 order by c;
|
|||||||
|
|
||||||
DROP TABLE t1, t2, t3, t4;
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #33143: Incorrect ORDER BY for ROUND()/TRUNCATE() result
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1( a DECIMAL(4, 3), b INT );
|
||||||
|
INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
|
||||||
|
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
|
||||||
|
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
|
||||||
|
|
||||||
|
CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
|
||||||
|
( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
|
||||||
|
|
||||||
|
SELECT a, b, MAX(ROUND(c, a))
|
||||||
|
FROM t2
|
||||||
|
GROUP BY a, b
|
||||||
|
ORDER BY b;
|
||||||
|
|
||||||
|
SELECT a, b, ROUND(c, a)
|
||||||
|
FROM t2;
|
||||||
|
|
||||||
|
CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
|
||||||
|
INSERT INTO t3 VALUES( 0, 1.5 );
|
||||||
|
SELECT ROUND( b, a ) FROM t3;
|
||||||
|
|
||||||
|
CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
|
||||||
|
INSERT INTO t4 VALUES( -9, 1.5e9 );
|
||||||
|
SELECT ROUND( b, a ) FROM t4;
|
||||||
|
|
||||||
|
CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
|
||||||
|
INSERT INTO t5 VALUES( 0, 1.5 );
|
||||||
|
INSERT INTO t5 VALUES( 9, 1.5e-9 );
|
||||||
|
SELECT ROUND( b, a ) FROM t5;
|
||||||
|
|
||||||
|
CREATE TABLE t6( a INT );
|
||||||
|
INSERT INTO t6 VALUES( 6 / 8 );
|
||||||
|
SELECT * FROM t6;
|
||||||
|
|
||||||
|
SELECT ROUND(20061108085411.000002);
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3, t4, t5, t6;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -3456,5 +3456,19 @@ DROP VIEW v2;
|
|||||||
DROP VIEW v3;
|
DROP VIEW v3;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#29477: Not all fields of the target table were checked to have
|
||||||
|
--echo # a default value when inserting into a view.
|
||||||
|
--echo #
|
||||||
|
create table t1(f1 int, f2 int not null);
|
||||||
|
create view v1 as select f1 from t1;
|
||||||
|
insert into v1 values(1);
|
||||||
|
set @old_mode=@@sql_mode;
|
||||||
|
set @@sql_mode=traditional;
|
||||||
|
--error ER_NO_DEFAULT_FOR_VIEW_FIELD
|
||||||
|
insert into v1 values(1);
|
||||||
|
set @@sql_mode=@old_mode;
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
@ -3366,7 +3366,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
|
|||||||
resolve_ref_in_select_and_group()
|
resolve_ref_in_select_and_group()
|
||||||
thd current thread
|
thd current thread
|
||||||
ref column reference being resolved
|
ref column reference being resolved
|
||||||
select the sub-select that ref is resolved against
|
select the select that ref is resolved against
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Resolve a column reference (usually inside a HAVING clause) against the
|
Resolve a column reference (usually inside a HAVING clause) against the
|
||||||
@ -3437,6 +3437,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
|
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
|
||||||
|
select->having_fix_field &&
|
||||||
select_ref != not_found_item && !group_by_ref)
|
select_ref != not_found_item && !group_by_ref)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -2009,7 +2009,7 @@ void Item_func_round::fix_length_and_dec()
|
|||||||
int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
|
int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
|
||||||
|
|
||||||
precision-= decimals_delta - length_increase;
|
precision-= decimals_delta - length_increase;
|
||||||
decimals= decimals_to_set;
|
decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
break;
|
break;
|
||||||
@ -2108,18 +2108,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
|
|||||||
{
|
{
|
||||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||||
longlong dec= args[1]->val_int();
|
longlong dec= args[1]->val_int();
|
||||||
if (dec > 0 || (dec < 0 && args[1]->unsigned_flag))
|
if (dec >= 0 || args[1]->unsigned_flag)
|
||||||
{
|
|
||||||
dec= min((ulonglong) dec, decimals);
|
dec= min((ulonglong) dec, decimals);
|
||||||
decimals= (uint8) dec; // to get correct output
|
|
||||||
}
|
|
||||||
else if (dec < INT_MIN)
|
else if (dec < INT_MIN)
|
||||||
dec= INT_MIN;
|
dec= INT_MIN;
|
||||||
|
|
||||||
if (!(null_value= (args[0]->null_value || args[1]->null_value ||
|
if (!(null_value= (args[0]->null_value || args[1]->null_value ||
|
||||||
my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
|
my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
|
||||||
truncate, decimal_value) > 1)))
|
truncate, decimal_value) > 1)))
|
||||||
|
{
|
||||||
|
decimal_value->frac= decimals;
|
||||||
return decimal_value;
|
return decimal_value;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1933,11 +1933,17 @@ sp_head::backpatch(sp_label_t *lab)
|
|||||||
uint dest= instructions();
|
uint dest= instructions();
|
||||||
List_iterator_fast<bp_t> li(m_backpatch);
|
List_iterator_fast<bp_t> li(m_backpatch);
|
||||||
|
|
||||||
|
DBUG_ENTER("sp_head::backpatch");
|
||||||
while ((bp= li++))
|
while ((bp= li++))
|
||||||
{
|
{
|
||||||
if (bp->lab == lab)
|
if (bp->lab == lab)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d",
|
||||||
|
bp->instr->m_ip, (ulong) lab, lab->name, dest));
|
||||||
bp->instr->backpatch(dest, lab->ctx);
|
bp->instr->backpatch(dest, lab->ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -779,8 +779,9 @@ public:
|
|||||||
|
|
||||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||||
{
|
{
|
||||||
if (m_dest == 0) // Don't reset
|
/* Calling backpatch twice is a logic flaw in jump resolution. */
|
||||||
m_dest= dest;
|
DBUG_ASSERT(m_dest == 0);
|
||||||
|
m_dest= dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -334,17 +334,91 @@ sp_rcontext::handle_error(uint sql_errno,
|
|||||||
void
|
void
|
||||||
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
|
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::push_cursor");
|
||||||
|
DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index());
|
||||||
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
|
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
|
||||||
|
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sp_rcontext::pop_cursors(uint count)
|
sp_rcontext::pop_cursors(uint count)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::pop_cursors");
|
||||||
|
DBUG_ASSERT(m_ccount >= count);
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
delete m_cstack[--m_ccount];
|
delete m_cstack[--m_ccount];
|
||||||
}
|
}
|
||||||
|
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::push_handler");
|
||||||
|
DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index());
|
||||||
|
|
||||||
|
m_handler[m_hcount].cond= cond;
|
||||||
|
m_handler[m_hcount].handler= h;
|
||||||
|
m_handler[m_hcount].type= type;
|
||||||
|
m_handler[m_hcount].foffset= f;
|
||||||
|
m_hcount+= 1;
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_rcontext::pop_handlers(uint count)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::pop_handlers");
|
||||||
|
DBUG_ASSERT(m_hcount >= count);
|
||||||
|
m_hcount-= count;
|
||||||
|
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_rcontext::push_hstack(uint h)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::push_hstack");
|
||||||
|
DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index());
|
||||||
|
m_hstack[m_hsp++]= h;
|
||||||
|
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
sp_rcontext::pop_hstack()
|
||||||
|
{
|
||||||
|
uint handler;
|
||||||
|
DBUG_ENTER("sp_rcontext::pop_hstack");
|
||||||
|
DBUG_ASSERT(m_hsp);
|
||||||
|
handler= m_hstack[--m_hsp];
|
||||||
|
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
|
||||||
|
DBUG_RETURN(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_rcontext::enter_handler(int hid)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::enter_handler");
|
||||||
|
DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index());
|
||||||
|
m_in_handler[m_ihsp++]= hid;
|
||||||
|
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_rcontext::exit_handler()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("sp_rcontext::exit_handler");
|
||||||
|
DBUG_ASSERT(m_ihsp);
|
||||||
|
m_ihsp-= 1;
|
||||||
|
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc
|
|||||||
return m_return_value_set;
|
return m_return_value_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
void push_handler(struct sp_cond_type *cond, uint h, int type, uint f);
|
||||||
push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
|
|
||||||
{
|
|
||||||
m_handler[m_hcount].cond= cond;
|
|
||||||
m_handler[m_hcount].handler= h;
|
|
||||||
m_handler[m_hcount].type= type;
|
|
||||||
m_handler[m_hcount].foffset= f;
|
|
||||||
m_hcount+= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
void pop_handlers(uint count);
|
||||||
pop_handlers(uint count)
|
|
||||||
{
|
|
||||||
m_hcount-= count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns 1 if a handler was found, 0 otherwise.
|
// Returns 1 if a handler was found, 0 otherwise.
|
||||||
bool
|
bool
|
||||||
@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc
|
|||||||
m_hfound= -1;
|
m_hfound= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
void push_hstack(uint h);
|
||||||
push_hstack(uint h)
|
|
||||||
{
|
|
||||||
m_hstack[m_hsp++]= h;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint
|
uint pop_hstack();
|
||||||
pop_hstack()
|
|
||||||
{
|
|
||||||
return m_hstack[--m_hsp];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
void enter_handler(int hid);
|
||||||
enter_handler(int hid)
|
|
||||||
{
|
|
||||||
m_in_handler[m_ihsp++]= hid;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
void exit_handler();
|
||||||
exit_handler()
|
|
||||||
{
|
|
||||||
m_ihsp-= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
|
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
|
||||||
|
@ -630,7 +630,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
if (mysql_prepare_insert(thd, table_list, table, fields, values,
|
if (mysql_prepare_insert(thd, table_list, table, fields, values,
|
||||||
update_fields, update_values, duplic, &unused_conds,
|
update_fields, update_values, duplic, &unused_conds,
|
||||||
FALSE,
|
FALSE,
|
||||||
(fields.elements || !value_count),
|
(fields.elements || !value_count ||
|
||||||
|
table_list->view != 0),
|
||||||
!ignore && (thd->variables.sql_mode &
|
!ignore && (thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
MODE_STRICT_ALL_TABLES))))
|
MODE_STRICT_ALL_TABLES))))
|
||||||
|
@ -5379,7 +5379,8 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
|
|||||||
(keyuse->val->type() == Item::REF_ITEM &&
|
(keyuse->val->type() == Item::REF_ITEM &&
|
||||||
((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
|
((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
|
||||||
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
|
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
|
||||||
Item_ref::DIRECT_REF) )
|
Item_ref::DIRECT_REF &&
|
||||||
|
keyuse->val->real_item()->type() == Item::FIELD_ITEM))
|
||||||
return new store_key_field(thd,
|
return new store_key_field(thd,
|
||||||
key_part->field,
|
key_part->field,
|
||||||
key_buff + maybe_null,
|
key_buff + maybe_null,
|
||||||
|
@ -2214,6 +2214,10 @@ sp_proc_stmt:
|
|||||||
|
|
||||||
lex->sphead->backpatch(lex->spcont->pop_label());
|
lex->sphead->backpatch(lex->spcont->pop_label());
|
||||||
}
|
}
|
||||||
|
| sp_labeled_block
|
||||||
|
{}
|
||||||
|
| sp_unlabeled_block
|
||||||
|
{}
|
||||||
| LEAVE_SYM label_ident
|
| LEAVE_SYM label_ident
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
@ -2231,9 +2235,17 @@ sp_proc_stmt:
|
|||||||
sp_instr_jump *i;
|
sp_instr_jump *i;
|
||||||
uint ip= sp->instructions();
|
uint ip= sp->instructions();
|
||||||
uint n;
|
uint n;
|
||||||
|
/*
|
||||||
|
When jumping to a BEGIN-END block end, the target jump
|
||||||
|
points to the block hpop/cpop cleanup instructions,
|
||||||
|
so we should exclude the block context here.
|
||||||
|
When jumping to something else (i.e., SP_LAB_ITER),
|
||||||
|
there are no hpop/cpop at the jump destination,
|
||||||
|
so we should include the block context here for cleanup.
|
||||||
|
*/
|
||||||
|
bool exclusive= (lab->type == SP_LAB_BEGIN);
|
||||||
|
|
||||||
n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
|
n= ctx->diff_handlers(lab->ctx, exclusive);
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
|
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
|
||||||
@ -2241,10 +2253,12 @@ sp_proc_stmt:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
sp->add_instr(hpop);
|
sp->add_instr(hpop);
|
||||||
}
|
}
|
||||||
n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
|
n= ctx->diff_cursors(lab->ctx, exclusive);
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
|
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
|
||||||
|
if (cpop == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
sp->add_instr(cpop);
|
sp->add_instr(cpop);
|
||||||
}
|
}
|
||||||
i= new sp_instr_jump(ip, ctx);
|
i= new sp_instr_jump(ip, ctx);
|
||||||
@ -2276,12 +2290,16 @@ sp_proc_stmt:
|
|||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
|
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
|
||||||
|
if (hpop == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
sp->add_instr(hpop);
|
sp->add_instr(hpop);
|
||||||
}
|
}
|
||||||
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
|
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
|
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
|
||||||
|
if (cpop == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
sp->add_instr(cpop);
|
sp->add_instr(cpop);
|
||||||
}
|
}
|
||||||
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
||||||
@ -2577,19 +2595,17 @@ sp_labeled_control:
|
|||||||
sp_unlabeled_control sp_opt_label
|
sp_unlabeled_control sp_opt_label
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
sp_label_t *lab= lex->spcont->pop_label();
|
||||||
|
|
||||||
if ($5.str)
|
if ($5.str)
|
||||||
{
|
{
|
||||||
sp_label_t *lab= lex->spcont->find_label($5.str);
|
if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
|
||||||
|
|
||||||
if (!lab ||
|
|
||||||
my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
|
|
||||||
{
|
{
|
||||||
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
|
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lex->sphead->backpatch(lex->spcont->pop_label());
|
lex->sphead->backpatch(lab);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2598,15 +2614,59 @@ sp_opt_label:
|
|||||||
| label_ident { $$= $1; }
|
| label_ident { $$= $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_unlabeled_control:
|
sp_labeled_block:
|
||||||
|
label_ident ':'
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
sp_pcontext *ctx= lex->spcont;
|
||||||
|
sp_label_t *lab= ctx->find_label($1.str);
|
||||||
|
|
||||||
|
if (lab)
|
||||||
|
{
|
||||||
|
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
lab= lex->spcont->push_label($1.str,
|
||||||
|
lex->sphead->instructions());
|
||||||
|
lab->type= SP_LAB_BEGIN;
|
||||||
|
}
|
||||||
|
sp_block_content sp_opt_label
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
sp_label_t *lab= lex->spcont->pop_label();
|
||||||
|
|
||||||
|
if ($5.str)
|
||||||
|
{
|
||||||
|
if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
|
||||||
|
{
|
||||||
|
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
sp_unlabeled_block:
|
||||||
|
{ /* Unlabeled blocks get a secret label. */
|
||||||
|
LEX *lex= Lex;
|
||||||
|
uint ip= lex->sphead->instructions();
|
||||||
|
sp_label_t *lab= lex->spcont->push_label((char *)"", ip);
|
||||||
|
lab->type= SP_LAB_BEGIN;
|
||||||
|
}
|
||||||
|
sp_block_content
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->spcont->pop_label();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
sp_block_content:
|
||||||
BEGIN_SYM
|
BEGIN_SYM
|
||||||
{ /* QQ This is just a dummy for grouping declarations and statements
|
{ /* QQ This is just a dummy for grouping declarations and statements
|
||||||
together. No [[NOT] ATOMIC] yet, and we need to figure out how
|
together. No [[NOT] ATOMIC] yet, and we need to figure out how
|
||||||
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
|
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_label_t *lab= lex->spcont->last_label();
|
|
||||||
|
|
||||||
lab->type= SP_LAB_BEGIN;
|
|
||||||
lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
|
lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
|
||||||
}
|
}
|
||||||
sp_decls
|
sp_decls
|
||||||
@ -2636,7 +2696,10 @@ sp_unlabeled_control:
|
|||||||
}
|
}
|
||||||
lex->spcont= ctx->pop_context();
|
lex->spcont= ctx->pop_context();
|
||||||
}
|
}
|
||||||
| LOOP_SYM
|
;
|
||||||
|
|
||||||
|
sp_unlabeled_control:
|
||||||
|
LOOP_SYM
|
||||||
sp_proc_stmts1 END LOOP_SYM
|
sp_proc_stmts1 END LOOP_SYM
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
@ -1595,9 +1595,21 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
|
|||||||
x+=10;
|
x+=10;
|
||||||
*buf1=powers10[pos]*(x-y);
|
*buf1=powers10[pos]*(x-y);
|
||||||
}
|
}
|
||||||
if (frac0 < 0)
|
/*
|
||||||
|
In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
|
||||||
|
the buffer are as follows.
|
||||||
|
|
||||||
|
Before <1, 5e8>
|
||||||
|
After <2, 5e8>
|
||||||
|
|
||||||
|
Hence we need to set the 2nd field to 0.
|
||||||
|
The same holds if we round 1.5e-9 to 2e-9.
|
||||||
|
*/
|
||||||
|
if (frac0 < frac1)
|
||||||
{
|
{
|
||||||
dec1 *end=to->buf+intg0, *buf=buf1+1;
|
dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
|
||||||
|
dec1 *end= to->buf + len;
|
||||||
|
|
||||||
while (buf < end)
|
while (buf < end)
|
||||||
*buf++=0;
|
*buf++=0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user