Auto-merge from mysql-5.1.
This commit is contained in:
commit
3e2c9aac11
@ -48,6 +48,16 @@ DROP TABLE IF EXISTS tmp2, t;
|
|||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
SELECT GET_LOCK("a",10);
|
SELECT GET_LOCK("a",10);
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG48216 Replication fails on all slaves after upgrade to 5.0.86 on master
|
||||||
|
#
|
||||||
|
# When the session is closed, any temporary tables of the session are dropped
|
||||||
|
# and are binlogged. But it will be binlogged with a wrong database name when
|
||||||
|
# the length of the database name('drop-temp-table-test') is greater than the
|
||||||
|
# current database name('test').
|
||||||
|
#
|
||||||
|
USE test;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
|
|
||||||
connection con2;
|
connection con2;
|
||||||
|
@ -895,3 +895,72 @@ t1.a < (select t4.a+10
|
|||||||
from t4, t5 limit 2));
|
from t4, t5 limit 2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
drop table t0, t1, t2, t3, t4, t5;
|
drop table t0, t1, t2, t3, t4, t5;
|
||||||
|
#
|
||||||
|
# BUG#48177 - SELECTs with NOT IN subqueries containing NULL
|
||||||
|
# values return too many records
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
i1 int DEFAULT NULL,
|
||||||
|
i2 int DEFAULT NULL
|
||||||
|
) ;
|
||||||
|
INSERT INTO t1 VALUES (1, NULL);
|
||||||
|
INSERT INTO t1 VALUES (2, 3);
|
||||||
|
INSERT INTO t1 VALUES (4, NULL);
|
||||||
|
INSERT INTO t1 VALUES (4, 0);
|
||||||
|
INSERT INTO t1 VALUES (NULL, NULL);
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
i1 int DEFAULT NULL,
|
||||||
|
i2 int DEFAULT NULL
|
||||||
|
) ;
|
||||||
|
INSERT INTO t2 VALUES (4, NULL);
|
||||||
|
INSERT INTO t2 VALUES (5, 0);
|
||||||
|
|
||||||
|
Data in t1
|
||||||
|
SELECT i1, i2 FROM t1;
|
||||||
|
i1 i2
|
||||||
|
1 NULL
|
||||||
|
2 3
|
||||||
|
4 NULL
|
||||||
|
4 0
|
||||||
|
NULL NULL
|
||||||
|
|
||||||
|
Data in subquery (should be filtered out)
|
||||||
|
SELECT i1, i2 FROM t2 ORDER BY i1;
|
||||||
|
i1 i2
|
||||||
|
4 NULL
|
||||||
|
5 0
|
||||||
|
FLUSH STATUS;
|
||||||
|
|
||||||
|
SELECT i1, i2
|
||||||
|
FROM t1
|
||||||
|
WHERE (i1, i2)
|
||||||
|
NOT IN (SELECT i1, i2 FROM t2);
|
||||||
|
i1 i2
|
||||||
|
1 NULL
|
||||||
|
2 3
|
||||||
|
|
||||||
|
# Check that the subquery only has to be evaluated once
|
||||||
|
# for all-NULL values even though there are two (NULL,NULL) records
|
||||||
|
# Baseline:
|
||||||
|
SHOW STATUS LIKE '%Handler_read_rnd_next';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_rnd_next 17
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (NULL, NULL);
|
||||||
|
FLUSH STATUS;
|
||||||
|
|
||||||
|
SELECT i1, i2
|
||||||
|
FROM t1
|
||||||
|
WHERE (i1, i2)
|
||||||
|
NOT IN (SELECT i1, i2 FROM t2);
|
||||||
|
i1 i2
|
||||||
|
1 NULL
|
||||||
|
2 3
|
||||||
|
|
||||||
|
# Handler_read_rnd_next should be one more than baseline
|
||||||
|
# (read record from t1, but do not read from t2)
|
||||||
|
SHOW STATUS LIKE '%Handler_read_rnd_next';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_rnd_next 18
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
End of 5.1 tests
|
||||||
|
@ -1495,9 +1495,9 @@ CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
|
|||||||
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
|
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
|
||||||
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
||||||
aa SUM(b)
|
aa SUM(b)
|
||||||
2.00000000000000000000000000000 10
|
2.000000000000000000000000000000 10
|
||||||
3.00000000000000000000000000000 10
|
3.000000000000000000000000000000 10
|
||||||
4.00000000000000000000000000000 30
|
4.000000000000000000000000000000 30
|
||||||
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
|
||||||
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
|
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@ -1521,13 +1521,13 @@ f1
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
|
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1265 Data truncated for column 'f1' at row 1
|
Warning 1264 Out of range value for column 'f1' at row 1
|
||||||
DESC t1;
|
DESC t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
f1 decimal(65,20) NO 0.00000000000000000000
|
f1 decimal(65,30) NO 0.000000000000000000000000000000
|
||||||
SELECT f1 FROM t1;
|
SELECT f1 FROM t1;
|
||||||
f1
|
f1
|
||||||
123451234512345123451234512345123451234512345.67890678906789067891
|
99999999999999999999999999999999999.999999999999999999999999999999
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
||||||
1.01500000 * 1.01500000 * 0.99500000);
|
1.01500000 * 1.01500000 * 0.99500000);
|
||||||
@ -1595,7 +1595,7 @@ Warnings:
|
|||||||
Note 1265 Data truncated for column 'my_col' at row 1
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
my_col decimal(32,30) NO 0.000000000000000000000000000000
|
my_col decimal(65,30) NO 0.000000000000000000000000000000
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
my_col
|
my_col
|
||||||
1.123456789123456789123456789123
|
1.123456789123456789123456789123
|
||||||
@ -1625,212 +1625,8 @@ Warnings:
|
|||||||
Note 1265 Data truncated for column 'my_col' at row 1
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
my_col decimal(30,30) YES NULL
|
my_col decimal(65,30) YES NULL
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
my_col
|
my_col
|
||||||
0.012345687012345687012345687012
|
0.012345687012345687012345687012
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
|
||||||
# Bug#45261: Crash, stored procedure + decimal
|
|
||||||
#
|
|
||||||
DROP TABLE IF EXISTS t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Warning 1264 Out of range value for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
99999999999999999999999999999999999999999999999999999999999999999
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Warning 1264 Out of range value for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
99999999999999999999999999999999999999999999999999999999999999999
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Warning 1264 Out of range value for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
99999999999999999999999999999999999999999999999999999999999999999
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
99999999999999999999999999999999999999999999999999999999999999999
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,25) NO 0.0000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
1000000000000000000000000000000000000001.1000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(31,30) NO 0.000000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
1.100000000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(31,30) NO 0.000000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
1.100000000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(30,30) NO 0.000000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
0.100000000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,20) NO 0.00000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
123456789012345678901234567890123456789012345.12345678901234567890
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
12345678901234567890123456789012345678901234567890123456789012345
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Warning 1264 Out of range value for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,0) NO 0
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
99999999999999999999999999999999999999999999999999999999999999999
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
|
|
||||||
AS c1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(30,30) NO 0.000000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
0.123456789012345678901234567890
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(33,30) NO 0.000000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
123.123456789012345678901234567890
|
|
||||||
DROP TABLE t1;
|
|
||||||
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,29) NO 0.00000000000000000000000000000
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
2.10000000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
#
|
|
||||||
# Test that the integer and decimal parts are properly calculated.
|
|
||||||
#
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 3
|
|
||||||
DESC t2;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(32,30) YES NULL
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 2
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 3
|
|
||||||
DESC t2;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(32,30) YES NULL
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
|
|
||||||
Warnings:
|
|
||||||
Note 1265 Data truncated for column 'c1' at row 1
|
|
||||||
DESC t2;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(31,30) YES NULL
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
#
|
|
||||||
# Test that variables get maximum precision.
|
|
||||||
#
|
|
||||||
SET @decimal= 1.1;
|
|
||||||
CREATE TABLE t1 SELECT @decimal AS c1;
|
|
||||||
DESC t1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
c1 decimal(65,30) YES NULL
|
|
||||||
SELECT * FROM t1;
|
|
||||||
c1
|
|
||||||
1.100000000000000000000000000000
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t;
|
|||||||
SELECT GET_LOCK("a",10);
|
SELECT GET_LOCK("a",10);
|
||||||
GET_LOCK("a",10)
|
GET_LOCK("a",10)
|
||||||
1
|
1
|
||||||
|
USE test;
|
||||||
SELECT GET_LOCK("a",10);
|
SELECT GET_LOCK("a",10);
|
||||||
GET_LOCK("a",10)
|
GET_LOCK("a",10)
|
||||||
1
|
1
|
||||||
|
@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t;
|
|||||||
SELECT GET_LOCK("a",10);
|
SELECT GET_LOCK("a",10);
|
||||||
GET_LOCK("a",10)
|
GET_LOCK("a",10)
|
||||||
1
|
1
|
||||||
|
USE test;
|
||||||
SELECT GET_LOCK("a",10);
|
SELECT GET_LOCK("a",10);
|
||||||
GET_LOCK("a",10)
|
GET_LOCK("a",10)
|
||||||
1
|
1
|
||||||
|
@ -728,3 +728,69 @@ where
|
|||||||
from t4, t5 limit 2));
|
from t4, t5 limit 2));
|
||||||
|
|
||||||
drop table t0, t1, t2, t3, t4, t5;
|
drop table t0, t1, t2, t3, t4, t5;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#48177 - SELECTs with NOT IN subqueries containing NULL
|
||||||
|
--echo # values return too many records
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
i1 int DEFAULT NULL,
|
||||||
|
i2 int DEFAULT NULL
|
||||||
|
) ;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1, NULL);
|
||||||
|
INSERT INTO t1 VALUES (2, 3);
|
||||||
|
INSERT INTO t1 VALUES (4, NULL);
|
||||||
|
INSERT INTO t1 VALUES (4, 0);
|
||||||
|
INSERT INTO t1 VALUES (NULL, NULL);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
i1 int DEFAULT NULL,
|
||||||
|
i2 int DEFAULT NULL
|
||||||
|
) ;
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES (4, NULL);
|
||||||
|
INSERT INTO t2 VALUES (5, 0);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo Data in t1
|
||||||
|
SELECT i1, i2 FROM t1;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo Data in subquery (should be filtered out)
|
||||||
|
SELECT i1, i2 FROM t2 ORDER BY i1;
|
||||||
|
|
||||||
|
FLUSH STATUS;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SELECT i1, i2
|
||||||
|
FROM t1
|
||||||
|
WHERE (i1, i2)
|
||||||
|
NOT IN (SELECT i1, i2 FROM t2);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Check that the subquery only has to be evaluated once
|
||||||
|
--echo # for all-NULL values even though there are two (NULL,NULL) records
|
||||||
|
--echo # Baseline:
|
||||||
|
SHOW STATUS LIKE '%Handler_read_rnd_next';
|
||||||
|
|
||||||
|
--echo
|
||||||
|
INSERT INTO t1 VALUES (NULL, NULL);
|
||||||
|
FLUSH STATUS;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SELECT i1, i2
|
||||||
|
FROM t1
|
||||||
|
WHERE (i1, i2)
|
||||||
|
NOT IN (SELECT i1, i2 FROM t2);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Handler_read_rnd_next should be one more than baseline
|
||||||
|
--echo # (read record from t1, but do not read from t2)
|
||||||
|
SHOW STATUS LIKE '%Handler_read_rnd_next';
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
@ -1286,137 +1286,3 @@ CREATE TABLE t1 SELECT 1 % .1234567891234567891234567891234567891234567891234567
|
|||||||
DESCRIBE t1;
|
DESCRIBE t1;
|
||||||
SELECT my_col FROM t1;
|
SELECT my_col FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
|
||||||
--echo # Bug#45261: Crash, stored procedure + decimal
|
|
||||||
--echo #
|
|
||||||
|
|
||||||
--disable_warnings
|
|
||||||
DROP TABLE IF EXISTS t1;
|
|
||||||
--enable_warnings
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT
|
|
||||||
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
|
|
||||||
AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
--echo #
|
|
||||||
--echo # Test that the integer and decimal parts are properly calculated.
|
|
||||||
--echo #
|
|
||||||
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
|
|
||||||
DESC t2;
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
|
|
||||||
DESC t2;
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
|
|
||||||
CREATE TABLE t1 (a DECIMAL(30,30));
|
|
||||||
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
|
|
||||||
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
|
|
||||||
DESC t2;
|
|
||||||
DROP TABLE t1,t2;
|
|
||||||
|
|
||||||
--echo #
|
|
||||||
--echo # Test that variables get maximum precision.
|
|
||||||
--echo #
|
|
||||||
|
|
||||||
SET @decimal= 1.1;
|
|
||||||
CREATE TABLE t1 SELECT @decimal AS c1;
|
|
||||||
DESC t1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
85
sql/field.cc
85
sql/field.cc
@ -2480,97 +2480,12 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
|
|||||||
{
|
{
|
||||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||||
DBUG_ASSERT(precision >= dec);
|
|
||||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
||||||
(dec <= DECIMAL_MAX_SCALE));
|
(dec <= DECIMAL_MAX_SCALE));
|
||||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a field to hold a decimal value from an item.
|
|
||||||
|
|
||||||
@remark The MySQL DECIMAL data type has a characteristic that needs to be
|
|
||||||
taken into account when deducing the type from a Item_decimal.
|
|
||||||
|
|
||||||
But first, let's briefly recap what is the new MySQL DECIMAL type:
|
|
||||||
|
|
||||||
The declaration syntax for a decimal is DECIMAL(M,D), where:
|
|
||||||
|
|
||||||
* M is the maximum number of digits (the precision).
|
|
||||||
It has a range of 1 to 65.
|
|
||||||
* D is the number of digits to the right of the decimal separator (the scale).
|
|
||||||
It has a range of 0 to 30 and must be no larger than M.
|
|
||||||
|
|
||||||
D and M are used to determine the storage requirements for the integer
|
|
||||||
and fractional parts of each value. The integer part is to the left of
|
|
||||||
the decimal separator and to the right is the fractional part. Hence:
|
|
||||||
|
|
||||||
M is the number of digits for the integer and fractional part.
|
|
||||||
D is the number of digits for the fractional part.
|
|
||||||
|
|
||||||
Consequently, M - D is the number of digits for the integer part. For
|
|
||||||
example, a DECIMAL(20,10) column has ten digits on either side of
|
|
||||||
the decimal separator.
|
|
||||||
|
|
||||||
The characteristic that needs to be taken into account is that the
|
|
||||||
backing type for Item_decimal is a my_decimal that has a higher
|
|
||||||
precision (DECIMAL_MAX_POSSIBLE_PRECISION, see my_decimal.h) than
|
|
||||||
DECIMAL.
|
|
||||||
|
|
||||||
Drawing a comparison between my_decimal and DECIMAL:
|
|
||||||
|
|
||||||
* M has a range of 1 to 81.
|
|
||||||
* D has a range of 0 to 81.
|
|
||||||
|
|
||||||
There can be a difference in range if the decimal contains a integer
|
|
||||||
part. This is because the fractional part must always be on a group
|
|
||||||
boundary, leaving at least one group for the integer part. Since each
|
|
||||||
group is 9 (DIG_PER_DEC1) digits and there are 9 (DECIMAL_BUFF_LENGTH)
|
|
||||||
groups, the fractional part is limited to 72 digits if there is at
|
|
||||||
least one digit in the integral part.
|
|
||||||
|
|
||||||
Although the backing type for a DECIMAL is also my_decimal, every
|
|
||||||
time a my_decimal is stored in a DECIMAL field, the precision and
|
|
||||||
scale are explicitly capped at 65 (DECIMAL_MAX_PRECISION) and 30
|
|
||||||
(DECIMAL_MAX_SCALE) digits, following my_decimal truncation procedure
|
|
||||||
(FIX_INTG_FRAC_ERROR).
|
|
||||||
*/
|
|
||||||
|
|
||||||
Field_new_decimal *
|
|
||||||
Field_new_decimal::new_decimal_field(const Item *item)
|
|
||||||
{
|
|
||||||
uint32 len;
|
|
||||||
uint intg= item->decimal_int_part(), scale= item->decimals;
|
|
||||||
|
|
||||||
DBUG_ASSERT(item->decimal_precision() >= item->decimals);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Employ a procedure along the lines of the my_decimal truncation process:
|
|
||||||
- If the integer part is equal to or bigger than the maximum precision:
|
|
||||||
Truncate integer part to fit and the fractional becomes zero.
|
|
||||||
- Otherwise:
|
|
||||||
Truncate fractional part to fit.
|
|
||||||
*/
|
|
||||||
if (intg >= DECIMAL_MAX_PRECISION)
|
|
||||||
{
|
|
||||||
intg= DECIMAL_MAX_PRECISION;
|
|
||||||
scale= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint room= min(DECIMAL_MAX_PRECISION - intg, DECIMAL_MAX_SCALE);
|
|
||||||
if (scale > room)
|
|
||||||
scale= room;
|
|
||||||
}
|
|
||||||
|
|
||||||
len= my_decimal_precision_to_length(intg + scale, scale, item->unsigned_flag);
|
|
||||||
|
|
||||||
return new Field_new_decimal(len, item->maybe_null, item->name, scale,
|
|
||||||
item->unsigned_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Field_new_decimal::reset(void)
|
int Field_new_decimal::reset(void)
|
||||||
{
|
{
|
||||||
store_value(&decimal_zero);
|
store_value(&decimal_zero);
|
||||||
|
@ -621,10 +621,6 @@ protected:
|
|||||||
|
|
||||||
class Field_num :public Field {
|
class Field_num :public Field {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
The scale of the Field's value, i.e. the number of digits to the right
|
|
||||||
of the decimal point.
|
|
||||||
*/
|
|
||||||
const uint8 dec;
|
const uint8 dec;
|
||||||
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
|
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
|
||||||
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||||
@ -782,11 +778,6 @@ public:
|
|||||||
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
|
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
|
||||||
const char *field_name_arg, uint8 dec_arg,
|
const char *field_name_arg, uint8 dec_arg,
|
||||||
bool unsigned_arg);
|
bool unsigned_arg);
|
||||||
/*
|
|
||||||
Create a field to hold a decimal value from an item.
|
|
||||||
Truncates the precision and/or scale if necessary.
|
|
||||||
*/
|
|
||||||
static Field_new_decimal *new_decimal_field(const Item *item);
|
|
||||||
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
|
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||||
Item_result result_type () const { return DECIMAL_RESULT; }
|
Item_result result_type () const { return DECIMAL_RESULT; }
|
||||||
|
25
sql/item.cc
25
sql/item.cc
@ -435,26 +435,17 @@ Item::Item(THD *thd, Item *item):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Decimal precision of the item.
|
|
||||||
|
|
||||||
@remark The precision must not be capped as it can be used in conjunction
|
|
||||||
with Item::decimals to determine the size of the integer part when
|
|
||||||
constructing a decimal data type.
|
|
||||||
|
|
||||||
@see Item::decimal_int_part()
|
|
||||||
@see Item::decimals
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint Item::decimal_precision() const
|
uint Item::decimal_precision() const
|
||||||
{
|
{
|
||||||
uint precision= max_length;
|
|
||||||
Item_result restype= result_type();
|
Item_result restype= result_type();
|
||||||
|
|
||||||
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
||||||
precision= my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
|
{
|
||||||
|
uint prec=
|
||||||
return precision;
|
my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
|
||||||
|
return min(prec, DECIMAL_MAX_PRECISION);
|
||||||
|
}
|
||||||
|
return min(max_length, DECIMAL_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4908,7 +4899,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
|
|||||||
switch (field_type()) {
|
switch (field_type()) {
|
||||||
case MYSQL_TYPE_DECIMAL:
|
case MYSQL_TYPE_DECIMAL:
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
field= Field_new_decimal::new_decimal_field(this);
|
field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
|
||||||
|
Field::NONE, name, decimals, 0,
|
||||||
|
unsigned_flag);
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
|
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
|
||||||
|
@ -762,10 +762,9 @@ public:
|
|||||||
virtual cond_result eq_cmp_result() const { return COND_OK; }
|
virtual cond_result eq_cmp_result() const { return COND_OK; }
|
||||||
inline uint float_length(uint decimals_par) const
|
inline uint float_length(uint decimals_par) const
|
||||||
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
|
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
|
||||||
/** Returns the uncapped decimal precision of this item. */
|
|
||||||
virtual uint decimal_precision() const;
|
virtual uint decimal_precision() const;
|
||||||
inline int decimal_int_part() const
|
inline int decimal_int_part() const
|
||||||
{ return decimal_precision() - decimals; }
|
{ return my_decimal_int_part(decimal_precision(), decimals); }
|
||||||
/*
|
/*
|
||||||
Returns true if this is constant (during query execution, i.e. its value
|
Returns true if this is constant (during query execution, i.e. its value
|
||||||
will not change until next fix_fields) and its value is known.
|
will not change until next fix_fields) and its value is known.
|
||||||
|
@ -1585,61 +1585,73 @@ longlong Item_in_optimizer::val_int()
|
|||||||
|
|
||||||
if (cache->null_value)
|
if (cache->null_value)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
We're evaluating
|
||||||
|
"<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)"
|
||||||
|
where one or more of the outer values is NULL.
|
||||||
|
*/
|
||||||
if (((Item_in_subselect*)args[1])->is_top_level_item())
|
if (((Item_in_subselect*)args[1])->is_top_level_item())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
|
We're evaluating a top level item, e.g.
|
||||||
FALSE, and we can return one instead of another. Just return NULL.
|
"<outer_value_list> IN (SELECT <inner_value_list>...)",
|
||||||
|
and in this case a NULL value in the outer_value_list means
|
||||||
|
that the result shall be NULL/FALSE (makes no difference for
|
||||||
|
top level items). The cached value is NULL, so just return
|
||||||
|
NULL.
|
||||||
*/
|
*/
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!((Item_in_subselect*)args[1])->is_correlated &&
|
/*
|
||||||
result_for_null_param != UNKNOWN)
|
We're evaluating an item where a NULL value in either the
|
||||||
|
outer or inner value list does not automatically mean that we
|
||||||
|
can return NULL/FALSE. An example of such a query is
|
||||||
|
"<outer_value_list> NOT IN (SELECT <inner_value_list>...)"
|
||||||
|
The result when there is at least one NULL value is: NULL if the
|
||||||
|
SELECT evaluated over the non-NULL values produces at least
|
||||||
|
one row, FALSE otherwise
|
||||||
|
*/
|
||||||
|
Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
|
||||||
|
bool all_left_cols_null= true;
|
||||||
|
const uint ncols= cache->cols();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Turn off the predicates that are based on column compares for
|
||||||
|
which the left part is currently NULL
|
||||||
|
*/
|
||||||
|
for (uint i= 0; i < ncols; i++)
|
||||||
{
|
{
|
||||||
/* Use cached value from previous execution */
|
if (cache->element_index(i)->null_value)
|
||||||
null_value= result_for_null_param;
|
item_subs->set_cond_guard_var(i, FALSE);
|
||||||
|
else
|
||||||
|
all_left_cols_null= false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!((Item_in_subselect*)args[1])->is_correlated &&
|
||||||
|
all_left_cols_null && result_for_null_param != UNKNOWN)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We're evaluating "NULL IN (SELECT ...)". The result is:
|
This is a non-correlated subquery, all values in the outer
|
||||||
FALSE if SELECT produces an empty set, or
|
value list are NULL, and we have already evaluated the
|
||||||
NULL otherwise.
|
subquery for all NULL values: Return the same result we
|
||||||
We disable the predicates we've pushed down into subselect, run the
|
did last time without evaluating the subquery.
|
||||||
subselect and see if it has produced any rows.
|
|
||||||
*/
|
*/
|
||||||
Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
|
null_value= result_for_null_param;
|
||||||
if (cache->cols() == 1)
|
}
|
||||||
{
|
else
|
||||||
item_subs->set_cond_guard_var(0, FALSE);
|
{
|
||||||
(void) args[1]->val_bool_result();
|
/* The subquery has to be evaluated */
|
||||||
result_for_null_param= null_value= !item_subs->engine->no_rows();
|
(void) args[1]->val_bool_result();
|
||||||
item_subs->set_cond_guard_var(0, TRUE);
|
null_value= !item_subs->engine->no_rows();
|
||||||
}
|
if (all_left_cols_null)
|
||||||
else
|
result_for_null_param= null_value;
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
uint ncols= cache->cols();
|
|
||||||
/*
|
|
||||||
Turn off the predicates that are based on column compares for
|
|
||||||
which the left part is currently NULL
|
|
||||||
*/
|
|
||||||
for (i= 0; i < ncols; i++)
|
|
||||||
{
|
|
||||||
if (cache->element_index(i)->null_value)
|
|
||||||
item_subs->set_cond_guard_var(i, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) args[1]->val_bool_result();
|
|
||||||
result_for_null_param= null_value= !item_subs->engine->no_rows();
|
|
||||||
|
|
||||||
/* Turn all predicates back on */
|
|
||||||
for (i= 0; i < ncols; i++)
|
|
||||||
item_subs->set_cond_guard_var(i, TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Turn all predicates back on */
|
||||||
|
for (uint i= 0; i < ncols; i++)
|
||||||
|
item_subs->set_cond_guard_var(i, TRUE);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2217,7 +2229,7 @@ uint Item_func_ifnull::decimal_precision() const
|
|||||||
int arg1_int_part= args[1]->decimal_int_part();
|
int arg1_int_part= args[1]->decimal_int_part();
|
||||||
int max_int_part= max(arg0_int_part, arg1_int_part);
|
int max_int_part= max(arg0_int_part, arg1_int_part);
|
||||||
int precision= max_int_part + decimals;
|
int precision= max_int_part + decimals;
|
||||||
return precision;
|
return min(precision, DECIMAL_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2401,7 +2413,7 @@ uint Item_func_if::decimal_precision() const
|
|||||||
int arg1_prec= args[1]->decimal_int_part();
|
int arg1_prec= args[1]->decimal_int_part();
|
||||||
int arg2_prec= args[2]->decimal_int_part();
|
int arg2_prec= args[2]->decimal_int_part();
|
||||||
int precision=max(arg1_prec,arg2_prec) + decimals;
|
int precision=max(arg1_prec,arg2_prec) + decimals;
|
||||||
return precision;
|
return min(precision, DECIMAL_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2809,7 +2821,7 @@ uint Item_func_case::decimal_precision() const
|
|||||||
|
|
||||||
if (else_expr_num != -1)
|
if (else_expr_num != -1)
|
||||||
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
|
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
|
||||||
return max_int_part + decimals;
|
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -451,8 +451,45 @@ Field *Item_func::tmp_table_field(TABLE *table)
|
|||||||
return make_string_field(table);
|
return make_string_field(table);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
field= Field_new_decimal::new_decimal_field(this);
|
{
|
||||||
|
uint8 dec= decimals;
|
||||||
|
uint8 intg= decimal_precision() - dec;
|
||||||
|
uint32 len= max_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
||||||
|
will always throw a warning. We must limit dec to
|
||||||
|
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dec > 0)
|
||||||
|
{
|
||||||
|
int overflow;
|
||||||
|
|
||||||
|
dec= min(dec, DECIMAL_MAX_SCALE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the value still overflows the field with the corrected dec,
|
||||||
|
we'll throw out decimals rather than integers. This is still
|
||||||
|
bad and of course throws a truncation warning.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int required_length=
|
||||||
|
my_decimal_precision_to_length(intg + dec, dec,
|
||||||
|
unsigned_flag);
|
||||||
|
|
||||||
|
overflow= required_length - len;
|
||||||
|
|
||||||
|
if (overflow > 0)
|
||||||
|
dec= max(0, dec - overflow); // too long, discard fract
|
||||||
|
else
|
||||||
|
/* Corrected value fits. */
|
||||||
|
len= required_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
// This case should never be chosen
|
// This case should never be chosen
|
||||||
@ -4739,19 +4776,6 @@ void Item_func_get_user_var::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Item_func_get_user_var::decimal_precision() const
|
|
||||||
{
|
|
||||||
uint precision= max_length;
|
|
||||||
Item_result restype= result_type();
|
|
||||||
|
|
||||||
/* Default to maximum as the precision is unknown a priori. */
|
|
||||||
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
|
||||||
precision= DECIMAL_MAX_PRECISION;
|
|
||||||
|
|
||||||
return precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_get_user_var::const_item() const
|
bool Item_func_get_user_var::const_item() const
|
||||||
{
|
{
|
||||||
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
|
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
|
||||||
|
@ -1393,7 +1393,6 @@ public:
|
|||||||
table_map used_tables() const
|
table_map used_tables() const
|
||||||
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
uint decimal_precision() const;
|
|
||||||
private:
|
private:
|
||||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||||
|
|
||||||
|
@ -517,7 +517,8 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
|
|||||||
name, table->s, collation.collation);
|
name, table->s, collation.collation);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
field= Field_new_decimal::new_decimal_field(this);
|
field= new Field_new_decimal(max_length, maybe_null, name,
|
||||||
|
decimals, unsigned_flag);
|
||||||
break;
|
break;
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
|
@ -48,12 +48,10 @@ C_MODE_END
|
|||||||
digits * number of decimal digits in one our big digit - number of decimal
|
digits * number of decimal digits in one our big digit - number of decimal
|
||||||
digits in one our big digit decreased by 1 (because we always put decimal
|
digits in one our big digit decreased by 1 (because we always put decimal
|
||||||
point on the border of our big digits))
|
point on the border of our big digits))
|
||||||
|
|
||||||
This value is 65 due to historical reasons partly due to it being used
|
|
||||||
as the maximum allowed precision and not the actual maximum precision.
|
|
||||||
*/
|
*/
|
||||||
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
|
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
|
||||||
#define DECIMAL_MAX_SCALE 30
|
#define DECIMAL_MAX_SCALE 30
|
||||||
|
#define DECIMAL_NOT_SPECIFIED 31
|
||||||
|
|
||||||
/**
|
/**
|
||||||
maximum length of string representation (number of maximum decimal
|
maximum length of string representation (number of maximum decimal
|
||||||
@ -77,6 +75,12 @@ inline uint my_decimal_size(uint precision, uint scale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int my_decimal_int_part(uint precision, uint decimals)
|
||||||
|
{
|
||||||
|
return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
||||||
|
|
||||||
@ -180,7 +184,7 @@ inline uint my_decimal_length_to_precision(uint length, uint scale,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
||||||
uint scale,
|
uint8 scale,
|
||||||
bool unsigned_flag)
|
bool unsigned_flag)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -192,7 +196,7 @@ inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
|||||||
(unsigned_flag || !precision ? 0 : 1));
|
(unsigned_flag || !precision ? 0 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 my_decimal_precision_to_length(uint precision, uint scale,
|
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
|
||||||
bool unsigned_flag)
|
bool unsigned_flag)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -1548,6 +1548,7 @@ void close_temporary_tables(THD *thd)
|
|||||||
s_query.length() - 1 /* to remove trailing ',' */,
|
s_query.length() - 1 /* to remove trailing ',' */,
|
||||||
0, FALSE, 0);
|
0, FALSE, 0);
|
||||||
qinfo.db= db.ptr();
|
qinfo.db= db.ptr();
|
||||||
|
qinfo.db_len= db.length();
|
||||||
thd->variables.character_set_client= cs_save;
|
thd->variables.character_set_client= cs_save;
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
|
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
|
||||||
|
@ -9436,8 +9436,47 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
|||||||
new_field->set_derivation(item->collation.derivation);
|
new_field->set_derivation(item->collation.derivation);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
new_field= Field_new_decimal::new_decimal_field(item);
|
{
|
||||||
|
uint8 dec= item->decimals;
|
||||||
|
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
|
||||||
|
uint32 len= item->max_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
||||||
|
will always throw a warning. We must limit dec to
|
||||||
|
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dec > 0)
|
||||||
|
{
|
||||||
|
signed int overflow;
|
||||||
|
|
||||||
|
dec= min(dec, DECIMAL_MAX_SCALE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the value still overflows the field with the corrected dec,
|
||||||
|
we'll throw out decimals rather than integers. This is still
|
||||||
|
bad and of course throws a truncation warning.
|
||||||
|
+1: for decimal point
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int required_length=
|
||||||
|
my_decimal_precision_to_length(intg + dec, dec,
|
||||||
|
item->unsigned_flag);
|
||||||
|
|
||||||
|
overflow= required_length - len;
|
||||||
|
|
||||||
|
if (overflow > 0)
|
||||||
|
dec= max(0, dec - overflow); // too long, discard fract
|
||||||
|
else
|
||||||
|
/* Corrected value fits. */
|
||||||
|
len= required_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_field= new Field_new_decimal(len, maybe_null, item->name,
|
||||||
|
dec, item->unsigned_flag);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
// This case should never be choosen
|
// This case should never be choosen
|
||||||
|
Loading…
x
Reference in New Issue
Block a user