diff options
author | unknown <tsmith@sita.local> | 2007-07-09 01:22:54 -0600 |
---|---|---|
committer | unknown <tsmith@sita.local> | 2007-07-09 01:22:54 -0600 |
commit | 8b1b980df9706193051f12855bc660354f17db8e (patch) | |
tree | a9b663b47d9f01f6013ca523bc5111ddc7229754 | |
parent | dabd3c97244b5d403889ba845157fb4177921e51 (diff) | |
parent | f045039d861bbadfe82266460aa95f9b6d89760f (diff) | |
download | mariadb-git-8b1b980df9706193051f12855bc660354f17db8e.tar.gz |
Merge sita.local:/Users/tsmith/m/bk/50
into sita.local:/Users/tsmith/m/bk/maint/50
sql/log.cc:
Auto merged
-rwxr-xr-x | BUILD/compile-pentium-gcov | 5 | ||||
-rw-r--r-- | mysql-test/r/gis.result | 3 | ||||
-rw-r--r-- | mysql-test/r/innodb_mysql.result | 53 | ||||
-rw-r--r-- | mysql-test/r/loaddata.result | 68 | ||||
-rw-r--r-- | mysql-test/r/type_newdecimal.result | 28 | ||||
-rw-r--r-- | mysql-test/r/view.result | 47 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 20 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql.test | 59 | ||||
-rw-r--r-- | mysql-test/t/loaddata.test | 60 | ||||
-rw-r--r-- | mysql-test/t/type_newdecimal.test | 35 | ||||
-rw-r--r-- | mysql-test/t/view.test | 55 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/filesort.cc | 18 | ||||
-rw-r--r-- | sql/item.h | 6 | ||||
-rw-r--r-- | sql/item_create.cc | 12 | ||||
-rw-r--r-- | sql/log.cc | 10 | ||||
-rw-r--r-- | sql/spatial.cc | 23 | ||||
-rw-r--r-- | sql/sql_class.cc | 9 | ||||
-rw-r--r-- | sql/sql_class.h | 21 | ||||
-rw-r--r-- | sql/sql_load.cc | 1 | ||||
-rw-r--r-- | sql/sql_show.cc | 6 | ||||
-rw-r--r-- | sql/sql_sort.h | 9 | ||||
-rw-r--r-- | sql/stacktrace.c | 9 | ||||
-rw-r--r-- | sql/uniques.cc | 13 |
24 files changed, 545 insertions, 27 deletions
diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov index 26475824570..0d561d5b147 100755 --- a/BUILD/compile-pentium-gcov +++ b/BUILD/compile-pentium-gcov @@ -13,8 +13,9 @@ export LDFLAGS="-fprofile-arcs -ftest-coverage" # The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the # code with profiling information used by gcov. -# the -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl. -extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM $debug_cflags $max_cflags -DMYSQL_SERVER_SUFFIX=-gcov" +# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl. +# The -DHAVE_gcov enables code to write out coverage info even when crashing. +extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM $debug_cflags $max_cflags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs --disable-shared $static_link" diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index d1f292cda0c..edf017f24d4 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -885,4 +885,7 @@ AsText(a) POINT(1 1) LINESTRING(0 0,1 1,2 2) drop table t1, t2; +SELECT 1; +1 +1 End of 5.0 tests diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index c766560f078..4535710c905 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2; +drop table if exists t1,t2,t3,t4; create table t1 ( c_id int(11) not null default '0', org_id int(11) default null, @@ -684,4 +684,55 @@ INSERT INTO t1 VALUES (1); switch to connection default SET AUTOCOMMIT=default; DROP TABLE t1,t2; +CREATE TABLE t1 ( +id int NOT NULL auto_increment PRIMARY KEY, +b int NOT NULL, +c datetime NOT NULL, +INDEX idx_b(b), +INDEX idx_c(c) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +b int NOT NULL auto_increment PRIMARY KEY, +c datetime NOT NULL +) ENGINE= MyISAM; +INSERT INTO t2(c) VALUES ('2007-01-01'); +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-02'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-03'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +set @@sort_buffer_size=8192; +SELECT COUNT(*) FROM t1; +COUNT(*) +3072 +EXPLAIN +SELECT COUNT(*) FROM t1 +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL idx_b,idx_c NULL NULL NULL # Using where +SELECT COUNT(*) FROM t1 +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +COUNT(*) +3072 +EXPLAIN +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge idx_b,idx_c idx_c,idx_b 8,4 NULL # Using sort_union(idx_c,idx_b); Using where +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +COUNT(*) +3072 +set @@sort_buffer_size=default; +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index a02aaccf8f6..7fff2700779 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -86,6 +86,60 @@ field1 field2 a"b cd"ef a"b c"d"e drop table t1; +CREATE TABLE t1 ( +id INT AUTO_INCREMENT PRIMARY KEY, +c1 VARCHAR(255) +); +CREATE TABLE t2 ( +id INT, +c2 VARCHAR(255) +); +INSERT INTO t1 (c1) VALUES +('r'), ('rr'), ('rrr'), ('rrrr'), +('.r'), ('.rr'), ('.rrr'), ('.rrrr'), +('r.'), ('rr.'), ('rrr.'), ('rrrr.'), +('.r.'), ('.rr.'), ('.rrr.'), ('.rrrr.'); +SELECT * FROM t1; +id c1 +1 r +2 rr +3 rrr +4 rrrr +5 .r +6 .rr +7 .rrr +8 .rrrr +9 r. +10 rr. +11 rrr. +12 rrrr. +13 .r. +14 .rr. +15 .rrr. +16 .rrrr. +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY 'r' FROM t1; +r1r rrrr +r2r rrrrrr +r3r rrrrrrrr +r4r rrrrrrrrrr +r5r r.rrr +r6r r.rrrrr +r7r r.rrrrrrr +r8r r.rrrrrrrrr +r9r rrr.r +r10r rrrrr.r +r11r rrrrrrr.r +r12r rrrrrrrrr.r +r13r r.rr.r +r14r r.rrrr.r +r15r r.rrrrrr.r +r16r r.rrrrrrrr.r +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t2 FIELDS ENCLOSED BY 'r'; +SELECT t1.id, c1, c2 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +id c1 c2 +SELECT t1.id, c1, c2 FROM t1 RIGHT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +id c1 c2 +DROP TABLE t1,t2; create table t1 (a int default 100, b int, c varchar(60)); load data infile '../std_data_ln/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=concat("b=",@b); select * from t1; @@ -184,3 +238,17 @@ f1 1 2 drop table t1,t2; +CREATE TABLE t1 (c1 INT, c2 TIMESTAMP, c3 REAL, c4 DOUBLE); +INSERT INTO t1 (c1, c2, c3, c4) VALUES (10, '1970-02-01 01:02:03', 1.1E-100, 1.1E+100); +SELECT * FROM t1; +c1 c2 c3 c4 +10 1970-02-01 01:02:03 1.1e-100 1.1e+100 +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY '-' FROM t1; +-10- -1970\-02\-01 01:02:03- -1.1e\-100- -1.1e+100- +EOF +TRUNCATE t1; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t1 FIELDS ENCLOSED BY '-'; +SELECT * FROM t1; +c1 c2 c3 c4 +10 1970-02-01 01:02:03 1.1e-100 1.1e+100 +DROP TABLE t1; diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 9e165721033..75d9582a23c 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1471,4 +1471,32 @@ drop table t1; SELECT 1.000000000000 * 99.999999999998 / 100 a,1.000000000000 * (99.999999999998 / 100) b; a b 0.9999999999999800000000000000 0.9999999999999800000000000000 +SELECT CAST(1 AS decimal(65,10)); +CAST(1 AS decimal(65,10)) +1.0000000000 +SELECT CAST(1 AS decimal(66,10)); +ERROR 42000: Too big precision 66 specified for column '1'. Maximum is 65. +SELECT CAST(1 AS decimal(65,30)); +CAST(1 AS decimal(65,30)) +1.000000000000000000000000000000 +SELECT CAST(1 AS decimal(65,31)); +ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30. +CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL); +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; +aa SUM(b) +2.000000000000000000000000000000 10 +3.000000000000000000000000000000 10 +4.000000000000000000000000000000 30 +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. +DROP TABLE t1; +CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL); +INSERT INTO t1 VALUES (3,30), (1,10), (2,10); +SET @a= CAST(1 AS decimal); +SELECT 1 FROM t1 GROUP BY @b := @a, @b; +1 +1 +1 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9adb3f96142..c51a4c30960 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3500,4 +3500,51 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 ( +person_id int NOT NULL PRIMARY KEY, +username varchar(40) default NULL, +status_flg char(1) NOT NULL default 'A' +); +CREATE TABLE t2 ( +person_role_id int NOT NULL auto_increment PRIMARY KEY, +role_id int NOT NULL, +person_id int NOT NULL, +INDEX idx_person_id (person_id), +INDEX idx_role_id (role_id) +); +CREATE TABLE t3 ( +role_id int NOT NULL auto_increment PRIMARY KEY, +role_name varchar(100) default NULL, +app_name varchar(40) NOT NULL, +INDEX idx_app_name(app_name) +); +CREATE VIEW v1 AS +SELECT profile.person_id AS person_id +FROM t1 profile, t2 userrole, t3 role +WHERE userrole.person_id = profile.person_id AND +role.role_id = userrole.role_id AND +profile.status_flg = 'A' + ORDER BY profile.person_id,role.app_name,role.role_name; +INSERT INTO t1 VALUES +(6,'Sw','A'), (-1136332546,'ols','e'), (0,' *\n','0'), +(-717462680,'ENTS Ta','0'), (-904346964,'ndard SQL\n','0'); +INSERT INTO t2 VALUES +(1,3,6),(2,4,7),(3,5,8),(4,6,9),(5,1,6),(6,1,7),(7,1,8),(8,1,9),(9,1,10); +INSERT INTO t3 VALUES +(1,'NUCANS_APP_USER','NUCANSAPP'),(2,'NUCANS_TRGAPP_USER','NUCANSAPP'), +(3,'IA_INTAKE_COORDINATOR','IACANS'),(4,'IA_SCREENER','IACANS'), +(5,'IA_SUPERVISOR','IACANS'),(6,'IA_READONLY','IACANS'), +(7,'SOC_USER','SOCCANS'),(8,'CAYIT_USER','CAYITCANS'), +(9,'RTOS_DCFSPOS_SUPERVISOR','RTOS'); +EXPLAIN SELECT t.person_id AS a, t.person_id AS b FROM v1 t WHERE t.person_id=6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE profile const PRIMARY PRIMARY 4 const 1 Using temporary; Using filesort +1 SIMPLE userrole ref idx_person_id,idx_role_id idx_person_id 4 const 2 +1 SIMPLE role eq_ref PRIMARY PRIMARY 4 test.userrole.role_id 1 +SELECT t.person_id AS a, t.person_id AS b FROM v1 t WHERE t.person_id=6; +a b +6 6 +6 6 +DROP VIEW v1; +DROP TABLE t1,t2,t3; End of 5.0 tests. diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 95ccc6272e2..79743a0b8f4 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -570,4 +570,24 @@ create table t2 as select f2 as a from t1 union select f3 from t1; desc t2; select AsText(a) from t2; drop table t1, t2; + +# +# Bug #29166: MYsql crash when query is run +# + +# The test query itself is not logged : too large output. +# The real test is the second query : see if the first hasn't crashed the +# server +--disable_query_log +--disable_result_log +SELECT AsText(GeometryFromText(CONCAT( + 'MULTIPOLYGON(((', + REPEAT ('-0.00000000001234567890123456789012 -0.123456789012345678,', 1000), + '-0.00000000001234567890123456789012 -0.123456789012345678', + ')))' +))) AS a; +--enable_result_log +--enable_query_log +SELECT 1; + --echo End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index f3d552a6868..d4ce997ddb1 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1,7 +1,7 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1,t2; +drop table if exists t1,t2,t3,t4; --enable_warnings # BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer @@ -684,4 +684,61 @@ DISCONNECT c1; DISCONNECT c2; DROP TABLE t1,t2; +# +# Bug #25798: a query with forced index merge returns wrong result +# + +CREATE TABLE t1 ( + id int NOT NULL auto_increment PRIMARY KEY, + b int NOT NULL, + c datetime NOT NULL, + INDEX idx_b(b), + INDEX idx_c(c) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + b int NOT NULL auto_increment PRIMARY KEY, + c datetime NOT NULL +) ENGINE= MyISAM; + +INSERT INTO t2(c) VALUES ('2007-01-01'); +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; + +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-02'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-03'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; + +set @@sort_buffer_size=8192; + +SELECT COUNT(*) FROM t1; + +--replace_column 9 # +EXPLAIN +SELECT COUNT(*) FROM t1 + WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +SELECT COUNT(*) FROM t1 + WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; + +--replace_column 9 # +EXPLAIN +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) + WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) + WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; + +set @@sort_buffer_size=default; + +DROP TABLE t1,t2; + --echo End of 5.0 tests diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 2757a37b881..260e760e7b3 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -67,6 +67,41 @@ load data infile '../std_data_ln/loaddata_dq.dat' into table t1 fields terminate select * from t1; drop table t1; +# +# Bug #29294 SELECT INTO OUTFILE/LOAD DATA INFILE with special +# characters in the FIELDS ENCLOSED BY clause +# + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT PRIMARY KEY, + c1 VARCHAR(255) +); + +CREATE TABLE t2 ( + id INT, + c2 VARCHAR(255) +); + +INSERT INTO t1 (c1) VALUES + ('r'), ('rr'), ('rrr'), ('rrrr'), + ('.r'), ('.rr'), ('.rrr'), ('.rrrr'), + ('r.'), ('rr.'), ('rrr.'), ('rrrr.'), + ('.r.'), ('.rr.'), ('.rrr.'), ('.rrrr.'); +SELECT * FROM t1; + +--exec rm -f $MYSQLTEST_VARDIR/tmp/t1 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY 'r' FROM t1; +--exec cat $MYSQLTEST_VARDIR/tmp/t1 + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t2 FIELDS ENCLOSED BY 'r'; +SELECT t1.id, c1, c2 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +SELECT t1.id, c1, c2 FROM t1 RIGHT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; + +--exec rm $MYSQLTEST_VARDIR/tmp/t1 +DROP TABLE t1,t2; + # End of 4.1 tests # @@ -178,4 +213,29 @@ select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1; --exec rm $MYSQLTEST_VARDIR/tmp/t2 drop table t1,t2; +# +# Bug#29442: SELECT INTO OUTFILE FIELDS ENCLOSED BY digit, minus sign etc +# corrupts non-string fields containing this character. +# + +CREATE TABLE t1 (c1 INT, c2 TIMESTAMP, c3 REAL, c4 DOUBLE); + +INSERT INTO t1 (c1, c2, c3, c4) VALUES (10, '1970-02-01 01:02:03', 1.1E-100, 1.1E+100); +SELECT * FROM t1; + +--exec rm -f $MYSQLTEST_VARDIR/tmp/t1 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY '-' FROM t1; +--exec cat $MYSQLTEST_VARDIR/tmp/t1 +--exec echo EOF + +TRUNCATE t1; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t1 FIELDS ENCLOSED BY '-'; +SELECT * FROM t1; + +--exec rm $MYSQLTEST_VARDIR/tmp/t1 +DROP TABLE t1; + # End of 5.0 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index d2b808bd5e0..5a631b6163e 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1162,4 +1162,39 @@ drop table t1; # SELECT 1.000000000000 * 99.999999999998 / 100 a,1.000000000000 * (99.999999999998 / 100) b; + +# +# Bug #29415: CAST AS DECIMAL(P,S) with too big precision/scale +# + +SELECT CAST(1 AS decimal(65,10)); +--error ER_TOO_BIG_PRECISION +SELECT CAST(1 AS decimal(66,10)); + +SELECT CAST(1 AS decimal(65,30)); +--error ER_TOO_BIG_SCALE +SELECT CAST(1 AS decimal(65,31)); + +CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL); +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; +--error ER_TOO_BIG_SCALE +SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa; + +DROP TABLE t1; + +# +# Bug #29417: assertion abort for a grouping query with decimal user variable +# + +CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL); +INSERT INTO t1 VALUES (3,30), (1,10), (2,10); + +SET @a= CAST(1 AS decimal); +SELECT 1 FROM t1 GROUP BY @b := @a, @b; + +DROP TABLE t1; + --echo End of 5.0 tests + + diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f670ac8a49d..c7f722a18a5 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3348,4 +3348,59 @@ EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a; DROP VIEW v1; DROP TABLE t1; +# +# Bug #29392: SELECT over a multi-table view with ORDER BY +# selecting the same view column with two different aliases +# + +CREATE TABLE t1 ( + person_id int NOT NULL PRIMARY KEY, + username varchar(40) default NULL, + status_flg char(1) NOT NULL default 'A' +); + +CREATE TABLE t2 ( + person_role_id int NOT NULL auto_increment PRIMARY KEY, + role_id int NOT NULL, + person_id int NOT NULL, + INDEX idx_person_id (person_id), + INDEX idx_role_id (role_id) +); + +CREATE TABLE t3 ( + role_id int NOT NULL auto_increment PRIMARY KEY, + role_name varchar(100) default NULL, + app_name varchar(40) NOT NULL, + INDEX idx_app_name(app_name) +); + +CREATE VIEW v1 AS +SELECT profile.person_id AS person_id + FROM t1 profile, t2 userrole, t3 role + WHERE userrole.person_id = profile.person_id AND + role.role_id = userrole.role_id AND + profile.status_flg = 'A' + ORDER BY profile.person_id,role.app_name,role.role_name; + +INSERT INTO t1 VALUES + (6,'Sw','A'), (-1136332546,'ols','e'), (0,' *\n','0'), + (-717462680,'ENTS Ta','0'), (-904346964,'ndard SQL\n','0'); + +INSERT INTO t2 VALUES + (1,3,6),(2,4,7),(3,5,8),(4,6,9),(5,1,6),(6,1,7),(7,1,8),(8,1,9),(9,1,10); + +INSERT INTO t3 VALUES + (1,'NUCANS_APP_USER','NUCANSAPP'),(2,'NUCANS_TRGAPP_USER','NUCANSAPP'), + (3,'IA_INTAKE_COORDINATOR','IACANS'),(4,'IA_SCREENER','IACANS'), + (5,'IA_SUPERVISOR','IACANS'),(6,'IA_READONLY','IACANS'), + (7,'SOC_USER','SOCCANS'),(8,'CAYIT_USER','CAYITCANS'), + (9,'RTOS_DCFSPOS_SUPERVISOR','RTOS'); + +EXPLAIN SELECT t.person_id AS a, t.person_id AS b FROM v1 t WHERE t.person_id=6; +SELECT t.person_id AS a, t.person_id AS b FROM v1 t WHERE t.person_id=6; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + --echo End of 5.0 tests. + diff --git a/sql/field.cc b/sql/field.cc index f81b1c33fa7..2e227f0e67e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2267,6 +2267,7 @@ Field_new_decimal::Field_new_decimal(char *ptr_arg, dec_arg, zero_arg, unsigned_arg) { precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); + set_if_smaller(precision, DECIMAL_MAX_PRECISION); DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && (dec <= DECIMAL_MAX_SCALE)); bin_size= my_decimal_get_binary_size(precision, dec); @@ -2286,6 +2287,7 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg, 0, unsigned_arg) { precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); + set_if_smaller(precision, DECIMAL_MAX_PRECISION); DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && (dec <= DECIMAL_MAX_SCALE)); bin_size= my_decimal_get_binary_size(precision, dec); diff --git a/sql/filesort.cc b/sql/filesort.cc index d518ddbb117..f8868ed6927 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1052,6 +1052,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, BUFFPEK *buffpek; QUEUE queue; qsort2_cmp cmp; + void *first_cmp_arg; volatile THD::killed_state *killed= ¤t_thd->killed; THD::killed_state not_killable; DBUG_ENTER("merge_buffers"); @@ -1077,9 +1078,18 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, /* The following will fire if there is not enough space in sort_buffer */ DBUG_ASSERT(maxcount!=0); + if (param->unique_buff) + { + cmp= param->compare; + first_cmp_arg= (void *) ¶m->cmp_context; + } + else + { + cmp= get_ptr_compare(sort_length); + first_cmp_arg= (void*) &sort_length; + } if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0, - (queue_compare) (cmp= get_ptr_compare(sort_length)), - (void*) &sort_length)) + (queue_compare) cmp, first_cmp_arg)) DBUG_RETURN(1); /* purecov: inspected */ for (buffpek= Fb ; buffpek <= Tb ; buffpek++) { @@ -1132,7 +1142,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, buffpek= (BUFFPEK*) queue_top(&queue); if (cmp) // Remove duplicates { - if (!(*cmp)(&sort_length, &(param->unique_buff), + if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key)) goto skip_duplicate; memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length); @@ -1184,7 +1194,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, */ if (cmp) { - if (!(*cmp)(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key)) + if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key)) { buffpek->key+= rec_length; // Remove duplicate --buffpek->mem_count; diff --git a/sql/item.h b/sql/item.h index fdb85b131c1..26b39e0bd00 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1989,6 +1989,12 @@ public: bool fix_fields(THD *, Item **); bool eq(const Item *item, bool binary_cmp) const; + Item *get_tmp_table_item(THD *thd) + { + Item *item= Item_ref::get_tmp_table_item(thd); + item->name= name; + return item; + } virtual Ref_Type ref_type() { return VIEW_REF; } }; diff --git a/sql/item_create.cc b/sql/item_create.cc index 42cbdc8c280..50db1c37371 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -471,6 +471,18 @@ Item *create_func_cast(Item *a, Cast_target cast_type, my_error(ER_M_BIGGER_THAN_D, MYF(0), ""); return 0; } + if (len > DECIMAL_MAX_PRECISION) + { + my_error(ER_TOO_BIG_PRECISION, MYF(0), len, a->name, + DECIMAL_MAX_PRECISION); + return 0; + } + if (dec > DECIMAL_MAX_SCALE) + { + my_error(ER_TOO_BIG_SCALE, MYF(0), dec, a->name, + DECIMAL_MAX_SCALE); + return 0; + } res= new Item_decimal_typecast(a, len, dec); break; case ITEM_CAST_CHAR: diff --git a/sql/log.cc b/sql/log.cc index bcaf352f620..86947d295d8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -85,7 +85,7 @@ bool binlog_init() static int binlog_close_connection(THD *thd) { IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot]; - DBUG_ASSERT(mysql_bin_log.is_open() && !my_b_tell(trans_log)); + DBUG_ASSERT(!my_b_tell(trans_log)); close_cached_file(trans_log); my_free((gptr)trans_log, MYF(0)); return 0; @@ -126,7 +126,7 @@ static int binlog_commit(THD *thd, bool all) { IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot]; DBUG_ENTER("binlog_commit"); - DBUG_ASSERT(mysql_bin_log.is_open() && + DBUG_ASSERT( (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))); if (my_b_tell(trans_log) == 0) @@ -155,7 +155,7 @@ static int binlog_rollback(THD *thd, bool all) unnecessary, doing extra work. The cause should be found and eliminated */ DBUG_ASSERT(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))); - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(my_b_tell(trans_log)); /* Update the binary log with a BEGIN/ROLLBACK block if we have cached some queries and we updated some non-transactional @@ -198,7 +198,7 @@ static int binlog_savepoint_set(THD *thd, void *sv) { IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot]; DBUG_ENTER("binlog_savepoint_set"); - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(my_b_tell(trans_log)); *(my_off_t *)sv= my_b_tell(trans_log); /* Write it to the binary log */ @@ -210,7 +210,7 @@ static int binlog_savepoint_rollback(THD *thd, void *sv) { IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot]; DBUG_ENTER("binlog_savepoint_rollback"); - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(my_b_tell(trans_log)); /* Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some diff --git a/sql/spatial.cc b/sql/spatial.cc index 939e7d2a3b4..69d0c15748a 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -17,7 +17,28 @@ #ifdef HAVE_SPATIAL -#define MAX_DIGITS_IN_DOUBLE 16 +/* + exponential notation : + 1 sign + 1 number before the decimal point + 1 decimal point + 14 number of significant digits (see String::qs_append(double)) + 1 'e' sign + 1 exponent sign + 3 exponent digits + == + 22 + + "f" notation : + 1 optional 0 + 1 sign + 14 number significant digits (see String::qs_append(double) ) + 1 decimal point + == + 17 +*/ + +#define MAX_DIGITS_IN_DOUBLE 22 /***************************** Gis_class_info *******************************/ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 788026d2f67..036ba217a9b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1209,6 +1209,8 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] : field_term_length ? (*exchange->field_term)[0] : INT_MAX); escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1); + is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char)); + is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char)); line_sep_char= (exchange->line_term->length() ? (*exchange->line_term)[0] : INT_MAX); if (!field_term_length) @@ -1283,7 +1285,8 @@ bool select_export::send_data(List<Item> &items) used_length=min(res->length(),item->max_length); else used_length=res->length(); - if (result_type == STRING_RESULT && escape_char != -1) + if ((result_type == STRING_RESULT || is_unsafe_field_sep) && + escape_char != -1) { char *pos, *start, *end; CHARSET_INFO *res_charset= res->charset(); @@ -1349,7 +1352,9 @@ bool select_export::send_data(List<Item> &items) NEED_ESCAPING(pos[1]))) { char tmp_buff[2]; - tmp_buff[0]= escape_char; + tmp_buff[0]= ((int) *pos == field_sep_char && + is_ambiguous_field_sep) ? + field_sep_char : escape_char; tmp_buff[1]= *pos ? *pos : '0'; if (my_b_write(&cache,(byte*) start,(uint) (pos-start)) || my_b_write(&cache,(byte*) tmp_buff,2)) diff --git a/sql/sql_class.h b/sql/sql_class.h index d86f097ebe8..a5cbc21684f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1926,9 +1926,30 @@ public: }; +#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape + + +/* + List of all possible characters of a numeric value text representation. +*/ +#define NUMERIC_CHARS ".0123456789e+-" + + class select_export :public select_to_file { uint field_term_length; int field_sep_char,escape_char,line_sep_char; + /* + The is_ambiguous_field_sep field is true if a value of the field_sep_char + field is one of the 'n', 't', 'r' etc characters + (see the READ_INFO::unescape method and the ESCAPE_CHARS constant value). + */ + bool is_ambiguous_field_sep; + /* + The is_unsafe_field_sep field is true if a value of the field_sep_char + field is one of the '0'..'9', '+', '-', '.' and 'e' characters + (see the NUMERIC_CHARS constant value). + */ + bool is_unsafe_field_sep; bool fixed_row_size; public: select_export(sql_exchange *ex) :select_to_file(ex) {} diff --git a/sql/sql_load.cc b/sql/sql_load.cc index c2267ba5dfc..7b1799baaad 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -847,6 +847,7 @@ continue_loop:; char READ_INFO::unescape(char chr) { + /* keep this switch synchornous with the ESCAPE_CHARS macro */ switch(chr) { case 'n': return '\n'; case 't': return '\t'; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 902b298e423..dc1a7bc3bd3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1909,11 +1909,9 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) if (item->type() == Item::FUNC_ITEM) { Item_func *item_func= (Item_func*)item; - Item **child; - Item **item_end= (item_func->arguments()) + item_func->argument_count(); - for (child= item_func->arguments(); child != item_end; child++) + for (uint i=0; i<item_func->argument_count(); i++) { - if (!uses_only_table_name_fields(*child, table)) + if (!uses_only_table_name_fields(item_func->arguments()[i], table)) return 0; } } diff --git a/sql/sql_sort.h b/sql/sql_sort.h index da28ca07e2c..1e9322f7f5b 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -50,6 +50,12 @@ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */ ulong max_keys; /* Max keys in buffert */ } BUFFPEK; +struct BUFFPEK_COMPARE_CONTEXT +{ + qsort_cmp2 key_compare; + void *key_compare_arg; +}; + typedef struct st_sort_param { uint rec_length; /* Length of sorted records */ uint sort_length; /* Length of sorted columns */ @@ -65,6 +71,9 @@ typedef struct st_sort_param { uchar *unique_buff; bool not_killable; char* tmp_buffer; + /* The fields below are used only by Unique class */ + qsort2_cmp compare; + BUFFPEK_COMPARE_CONTEXT cmp_context; } SORTPARAM; diff --git a/sql/stacktrace.c b/sql/stacktrace.c index d8e9b7fd883..c947beafac3 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -241,6 +241,15 @@ void write_core(int sig) void write_core(int sig) { signal(sig, SIG_DFL); +#ifdef HAVE_gcov + /* + For GCOV build, crashing will prevent the writing of code coverage + information from this process, causing gcov output to be incomplete. + So we force the writing of coverage information here before terminating. + */ + extern void __gcov_flush(void); + __gcov_flush(); +#endif pthread_kill(pthread_self(), sig); #if defined(P_MYID) && !defined(SCO) /* On Solaris, the above kill is not enough */ diff --git a/sql/uniques.cc b/sql/uniques.cc index 9eb827f62a3..7c197d2a2e9 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -361,17 +361,12 @@ Unique::reset() } /* - The comparison function, passed to queue_init() in merge_walk() must + The comparison function, passed to queue_init() in merge_walk() and in + merge_buffers() when the latter is called from Uniques::get() must use comparison function of Uniques::tree, but compare members of struct BUFFPEK. */ -struct BUFFPEK_COMPARE_CONTEXT -{ - qsort_cmp2 key_compare; - void *key_compare_arg; -}; - C_MODE_START static int buffpek_compare(void *arg, byte *key_ptr1, byte *key_ptr2) @@ -630,6 +625,10 @@ bool Unique::get(TABLE *table) sort_param.unique_buff= sort_buffer+(sort_param.keys* sort_param.sort_length); + sort_param.compare= (qsort2_cmp) buffpek_compare; + sort_param.cmp_context.key_compare= tree.compare; + sort_param.cmp_context.key_compare_arg= tree.custom_arg; + /* Merge the buffers to one file, removing duplicates */ if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&file)) goto err; |