Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions mysql-test/main/func_analyse.result
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,105 @@ DROP TABLE t;
#
# End of 10.5 tests
#
#
# MDEV-28374 UBSAN signed integer overflow PROCEDURE ANALYSE
#
SET sql_mode='';
CREATE TABLE t (a BIGINT);
INSERT INTO t VALUES ('10000000000000'),('10000000000000');
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.a 10000000000000 10000000000000 14 14 0 0 10000000000000.0000 0.0000 ENUM('10000000000000') NOT NULL
DROP TABLE t;
CREATE TABLE t (a BIGINT UNSIGNED);
INSERT INTO t VALUES ('18446744073709551615'),('18446744073709551615');
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.a 18446744073709551615 18446744073709551615 20 20 0 0 18446744073709552000.0000 0.0000 ENUM('18446744073709551615') NOT NULL
DROP TABLE t;
CREATE TABLE t (a BIGINT,KEY a USING BTREE (a));
INSERT INTO t VALUES (0),('1'),('1'),('1'),('1'),('00010101'),('99991231'),('00101000000'),('691231000000'),('700101000000'),('991231235959'),('10000101000000'),('99991231235959'),('20030100000000'),('20030000000000');
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.a 0 99991231235959 1 14 1 0 10162279764883.6000 24971351159406.2300 ENUM('0','1','10101','99991231','101000000','691231000000','700101000000','991231235959','10000101000000','20030000000000','20030100000000','99991231235959') NOT NULL
DROP TABLE t;
CREATE TABLE t (c BIGINT,c2 DATE,c3 BLOB,KEY(c)) ENGINE=InnoDB;
INSERT INTO t VALUES (-1.e+308,1,1);
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
Warning 1265 Data truncated for column 'c2' at row 1
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.c -9223372036854775808 -9223372036854775808 20 20 0 0 -9223372036854776000.0000 0.0000 ENUM('-9223372036854775808') NOT NULL
test.t.c2 0000-00-00 0000-00-00 10 10 0 0 10.0000 NULL ENUM('0000-00-00') NOT NULL
test.t.c3 1 1 1 1 0 0 1.0000 NULL ENUM('1') NOT NULL
DROP TABLE t;
CREATE TABLE t (c INT) ENGINE=InnoDB UNION=(t,t2) INSERT_METHOD=LAST;
CREATE TABLE t3 LIKE t;
INSERT INTO t VALUES (1),(2),(-685113344),(0);
INSERT INTO t3 SELECT * FROM t;
INSERT INTO t SELECT * FROM t;
INSERT INTO t SELECT * FROM t;
INSERT INTO t3 SELECT * FROM t;
SELECT * FROM t3 PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t3.c -685113344 2 1 10 5 0 -171278335.2500 296662780.6209 ENUM('-685113344','0','1','2') NOT NULL
DROP TABLE t, t3;
CREATE TABLE t (c INT) ENGINE=InnoDB UNION=(t,t2) INSERT_METHOD=LAST;
INSERT INTO t VALUES (1);
INSERT INTO t VALUES (0xA9BD);
INSERT INTO t (c) VALUES (ADDTIME(NOW(),1));
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
CREATE TABLE c AS SELECT 1 A;
SELECT * FROM t a,c,t b PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.a.c 1 2147483647 1 10 0 0 715842367.0000 1012323257.4700 ENUM('1','43453','2147483647') NOT NULL
test.c.A 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.b.c 1 2147483647 1 10 0 0 715842367.0000 1012323257.4700 ENUM('1','43453','2147483647') NOT NULL
DROP TABLE t, c;
CREATE TABLE t (c BIGINT);
INSERT INTO t VALUES (1000000000000000);
SELECT * FROM t PROCEDURE ANALYSE(0,0);
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.c 1000000000000000 1000000000000000 16 16 0 0 1000000000000000.0000 0.0000 BIGINT(16) UNSIGNED NOT NULL
DROP TABLE t;
CREATE SEQUENCE t CACHE=1 MAXVALUE=0 INCREMENT=-1;
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.next_not_cached_value 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
test.t.minimum_value -9223372036854775807 -9223372036854775807 20 20 0 0 -9223372036854776000.0000 0.0000 ENUM('-9223372036854775807') NOT NULL
test.t.maximum_value 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
test.t.start_value 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
test.t.increment -1 -1 2 2 0 0 -1.0000 0.0000 ENUM('-1') NOT NULL
test.t.cache_size 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.cycle_option 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
test.t.cycle_count 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
DROP SEQUENCE t;
CREATE SEQUENCE t CACHE+1;
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.next_not_cached_value 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.minimum_value 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.maximum_value 9223372036854775806 9223372036854775806 19 19 0 0 9223372036854776000.0000 0.0000 ENUM('9223372036854775806') NOT NULL
test.t.start_value 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.increment 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.cache_size 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
test.t.cycle_option 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
test.t.cycle_count 0 0 1 1 1 0 0.0000 0.0000 ENUM('0') NOT NULL
DROP SEQUENCE t;
CREATE TABLE t (c INT) ENGINE=InnoDB;
INSERT INTO t VALUES (0x31313131),(0x32323232);
INSERT INTO t VALUES (0x31313131),(0x32323232);
SELECT * FROM t LIMIT 1 PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.c 825307441 842150450 9 9 0 0 833728945.5000 8421504.5000 ENUM('825307441','842150450') NOT NULL
DROP TABLE t;
CREATE TABLE t (f BIGINT) ENGINE=InnoDB;
INSERT INTO t VALUES (1),(+1),(1),(1),(+1),(1),(1),(1),(1),(+1),(1),(1),(1),(20030000000000);
SELECT * FROM t PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.f 1 20030000000000 1 14 0 0 1430714285715.2144 5158513717681.4360 ENUM('1','20030000000000') NOT NULL
DROP TABLE t;
SET sql_mode=DEFAULT;
# End of 10.11 tests
83 changes: 83 additions & 0 deletions mysql-test/main/func_analyse.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Test of procedure analyse
#
-- source include/have_innodb.inc
--source include/have_sequence.inc

--disable_warnings
drop table if exists t1,t2;
Expand Down Expand Up @@ -267,3 +268,85 @@ DROP TABLE t;
--echo #
--echo # End of 10.5 tests
--echo #

--echo #
--echo # MDEV-28374 UBSAN signed integer overflow PROCEDURE ANALYSE
--echo #

SET sql_mode='';

CREATE TABLE t (a BIGINT);
INSERT INTO t VALUES ('10000000000000'),('10000000000000');
SELECT * FROM t PROCEDURE ANALYSE();

DROP TABLE t;

CREATE TABLE t (a BIGINT UNSIGNED);
INSERT INTO t VALUES ('18446744073709551615'),('18446744073709551615');
SELECT * FROM t PROCEDURE ANALYSE();

DROP TABLE t;

CREATE TABLE t (a BIGINT,KEY a USING BTREE (a));
INSERT INTO t VALUES (0),('1'),('1'),('1'),('1'),('00010101'),('99991231'),('00101000000'),('691231000000'),('700101000000'),('991231235959'),('10000101000000'),('99991231235959'),('20030100000000'),('20030000000000');
SELECT * FROM t PROCEDURE ANALYSE();

DROP TABLE t;

CREATE TABLE t (c BIGINT,c2 DATE,c3 BLOB,KEY(c)) ENGINE=InnoDB;
INSERT INTO t VALUES (-1.e+308,1,1);
SELECT * FROM t PROCEDURE ANALYSE();

DROP TABLE t;

CREATE TABLE t (c INT) ENGINE=InnoDB UNION=(t,t2) INSERT_METHOD=LAST;
CREATE TABLE t3 LIKE t;
INSERT INTO t VALUES (1),(2),(-685113344),(0);
INSERT INTO t3 SELECT * FROM t;
INSERT INTO t SELECT * FROM t;
INSERT INTO t SELECT * FROM t;
INSERT INTO t3 SELECT * FROM t;
SELECT * FROM t3 PROCEDURE ANALYSE();

DROP TABLE t, t3;

CREATE TABLE t (c INT) ENGINE=InnoDB UNION=(t,t2) INSERT_METHOD=LAST;
INSERT INTO t VALUES (1);
INSERT INTO t VALUES (0xA9BD);
INSERT INTO t (c) VALUES (ADDTIME(NOW(),1));
CREATE TABLE c AS SELECT 1 A;
SELECT * FROM t a,c,t b PROCEDURE ANALYSE();

DROP TABLE t, c;

CREATE TABLE t (c BIGINT);
INSERT INTO t VALUES (1000000000000000);
SELECT * FROM t PROCEDURE ANALYSE(0,0);

DROP TABLE t;

CREATE SEQUENCE t CACHE=1 MAXVALUE=0 INCREMENT=-1;
SELECT * FROM t PROCEDURE ANALYSE();

DROP SEQUENCE t;

CREATE SEQUENCE t CACHE+1;
SELECT * FROM t PROCEDURE ANALYSE();

DROP SEQUENCE t;

CREATE TABLE t (c INT) ENGINE=InnoDB;
INSERT INTO t VALUES (0x31313131),(0x32323232);
INSERT INTO t VALUES (0x31313131),(0x32323232);
SELECT * FROM t LIMIT 1 PROCEDURE ANALYSE();

DROP TABLE t;

CREATE TABLE t (f BIGINT) ENGINE=InnoDB;
INSERT INTO t VALUES (1),(+1),(1),(1),(+1),(1),(1),(1),(1),(+1),(1),(1),(1),(20030000000000);
SELECT * FROM t PROCEDURE ANALYSE();

DROP TABLE t;
SET sql_mode=DEFAULT;

--echo # End of 10.11 tests
17 changes: 16 additions & 1 deletion mysql-test/suite/federated/federatedx.result
Original file line number Diff line number Diff line change
Expand Up @@ -2356,11 +2356,26 @@ pk
3
DROP TABLE t2_fed, t1, t2;
set @@optimizer_switch=@save_optimizer_switch;
DROP SERVER s;
# End of 10.5 tests
#
# MDEV-28374 UBSAN signed integer overflow PROCEDURE ANALYSE
#
CREATE TABLE t (a BIGINT);
INSERT INTO t VALUES ('-9223372036854775808');
INSERT INTO t SELECT * FROM t;
SELECT * FROM t PROCEDURE ANALYSE(2);
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t.a -9223372036854775808 -9223372036854775808 20 20 0 0 -9223372036854776000.0000 0.0000 BIGINT(20) NOT NULL
CREATE TABLE t_fed ENGINE=FEDERATED CONNECTION='s/t';
SELECT * FROM t_fed PROCEDURE ANALYSE(2);
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t_fed.a -9223372036854775808 -9223372036854775808 20 20 0 0 -9223372036854776000.0000 0.0000 BIGINT(20) NOT NULL
DROP TABLE t, t_fed;
DROP SERVER s;
connection master;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
connection slave;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
# End of 10.11 tests
19 changes: 17 additions & 2 deletions mysql-test/suite/federated/federatedx.test
Original file line number Diff line number Diff line change
Expand Up @@ -2086,8 +2086,23 @@ SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
DROP TABLE t2_fed, t1, t2;
set @@optimizer_switch=@save_optimizer_switch;

DROP SERVER s;

--echo # End of 10.5 tests

--echo #
--echo # MDEV-28374 UBSAN signed integer overflow PROCEDURE ANALYSE
--echo #

CREATE TABLE t (a BIGINT);
INSERT INTO t VALUES ('-9223372036854775808');
INSERT INTO t SELECT * FROM t;
SELECT * FROM t PROCEDURE ANALYSE(2);

CREATE TABLE t_fed ENGINE=FEDERATED CONNECTION='s/t';
SELECT * FROM t_fed PROCEDURE ANALYSE(2);

DROP TABLE t, t_fed;

DROP SERVER s;
source include/federated_cleanup.inc;

--echo # End of 10.11 tests
39 changes: 21 additions & 18 deletions sql/sql_analyse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -555,25 +555,25 @@ void field_decimal::add()
}
}


void field_longlong::add()
{
char buff[MAX_FIELD_WIDTH];
longlong num = item->val_int();
uint length = (uint) (longlong10_to_str(num, buff, -10) - buff);
longlong numlong = item->val_int();
double num = (double) numlong;
uint length = (uint) (longlong10_to_str(numlong, buff, -10) - buff);
TREE_ELEMENT *element;

if (item->null_value)
{
nulls++;
return;
}
if (num == 0)
if (num == 0.0)
empty++;

if (room_in_tree)
{
if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
if (!(element = tree_insert(&tree, (void*) &numlong, 0, tree.custom_arg)))
{
room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree, 0);
Expand All @@ -592,7 +592,8 @@ void field_longlong::add()
if (!found)
{
found = 1;
min_arg = max_arg = sum = num;
min_arg = max_arg = numlong;
sum = num;
sum_sqr = num * num;
min_length = max_length = length;
}
Expand All @@ -604,19 +605,20 @@ void field_longlong::add()
min_length = length;
if (length > max_length)
max_length = length;
if (compare_longlong(&num, &min_arg) < 0)
min_arg = num;
if (compare_longlong(&num, &max_arg) > 0)
max_arg = num;
if (compare_longlong(&numlong, &min_arg) < 0)
min_arg = numlong;
if (compare_longlong(&numlong, &max_arg) > 0)
max_arg = numlong;
}
} // field_longlong::add


void field_ulonglong::add()
{
char buff[MAX_FIELD_WIDTH];
longlong num = item->val_int();
uint length = (uint) (longlong10_to_str(num, buff, 10) - buff);
ulonglong numlong = item->val_int();
double num= (double) numlong;
uint length = (uint) (longlong10_to_str(numlong, buff, 10) - buff);
TREE_ELEMENT *element;

if (item->null_value)
Expand All @@ -629,7 +631,7 @@ void field_ulonglong::add()

if (room_in_tree)
{
if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
if (!(element = tree_insert(&tree, (void*) &numlong, 0, tree.custom_arg)))
{
room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree, 0);
Expand All @@ -648,7 +650,8 @@ void field_ulonglong::add()
if (!found)
{
found = 1;
min_arg = max_arg = sum = num;
min_arg = max_arg = numlong;
sum = num;
sum_sqr = num * num;
min_length = max_length = length;
}
Expand All @@ -660,10 +663,10 @@ void field_ulonglong::add()
min_length = length;
if (length > max_length)
max_length = length;
if (compare_ulonglong((ulonglong*) &num, &min_arg) < 0)
min_arg = num;
if (compare_ulonglong((ulonglong*) &num, &max_arg) > 0)
max_arg = num;
if (compare_ulonglong(&numlong, &min_arg) < 0)
min_arg = numlong;
if (compare_ulonglong(&numlong, &max_arg) > 0)
max_arg = numlong;
}
} // field_ulonglong::add

Expand Down
Loading