diff options
-rwxr-xr-x | Build-tools/Bootstrap | 10 | ||||
-rw-r--r-- | client/mysqldump.c | 4 | ||||
-rw-r--r-- | extra/perror.c | 13 | ||||
-rw-r--r-- | mysql-test/r/compare.result | 3 | ||||
-rw-r--r-- | mysql-test/r/derived.result | 9 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 36 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 48 | ||||
-rw-r--r-- | mysql-test/t/compare.test | 3 | ||||
-rw-r--r-- | mysql-test/t/derived.test | 10 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 56 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 18 | ||||
-rw-r--r-- | sql/item.cc | 6 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 9 | ||||
-rw-r--r-- | sql/item_func.cc | 18 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_subselect.cc | 16 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 14 | ||||
-rw-r--r-- | sql/sql_cache.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 8 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_lex.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 6 | ||||
-rw-r--r-- | strings/ctype-simple.c | 2 |
26 files changed, 259 insertions, 48 deletions
diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 10ebc5c2dd1..827eb4022d7 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -210,10 +210,16 @@ if (-d $target_dir) } else { - &logger("Renaming $target_dir to $target_dir.old." . $$); + # Get the time stamp of "configure.in" + @stat= stat("$target_dir/configure.in"); + my $mtime= $stat[9]; + my ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime); + my $mtime= sprintf("%04d%-02d-%02d-%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min); + + &logger("Renaming $target_dir to $target_dir-$mtime"); $command= "mv "; $command.= "-v " if ($opt_verbose || defined $opt_log); - $command.= "$target_dir $target_dir.old." . $$; + $command.= "$target_dir $target_dir-$mtime"; &run_command($command, "Could not rename $target_dir!"); } } diff --git a/client/mysqldump.c b/client/mysqldump.c index 3a93adf5b36..afaa2dc5a6d 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -489,7 +489,7 @@ static void write_header(FILE *sql_file, char *db_name) "); } fprintf(sql_file, - "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=\"%s%s%s\" */;\n", + "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n", path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",", compatible_mode_normal_str); check_io(sql_file); @@ -863,7 +863,7 @@ static int dbConnect(char *host, char *user,char *passwd) cannot reconnect. */ sock->reconnect= 0; - sprintf(buff, "/*!40100 SET @@SQL_MODE=\"%s\" */", + sprintf(buff, "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); if (mysql_query_with_error_report(sock, 0, buff)) { diff --git a/extra/perror.c b/extra/perror.c index 1bd4b203120..fc10d8eaecc 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -184,6 +184,7 @@ int main(int argc,char *argv[]) { int error,code,found; const char *msg; + char *unknown_error = 0; MY_INIT(argv[0]); if (get_options(&argc,&argv)) @@ -212,7 +213,12 @@ int main(int argc,char *argv[]) string 'Unknown Error'. To avoid printing it we try to find the error string by asking for an impossible big error message. */ - const char *unknown_error= strerror(10000); + msg = strerror(10000); + + /* allocate a buffer for unknown_error since strerror always returns the same pointer + on some platforms such as Windows */ + unknown_error = malloc( strlen(msg)+1 ); + strcpy( unknown_error, msg ); for ( ; argc-- > 0 ; argv++) { @@ -262,6 +268,11 @@ int main(int argc,char *argv[]) } } } + + /* if we allocated a buffer for unknown_error, free it now */ + if (unknown_error) + free(unknown_error); + exit(error); return error; } diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result index bf8a5106044..49ec2dd85cc 100644 --- a/mysql-test/r/compare.result +++ b/mysql-test/r/compare.result @@ -36,3 +36,6 @@ hex(a) STRCMP(a,'a') STRCMP(a,'a ') 6109 -1 -1 61 0 0 DROP TABLE t1; +SELECT CHAR(31) = '', '' = CHAR(31); +CHAR(31) = '' '' = CHAR(31) +0 0 diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 7e6b9b44566..61d745d0236 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -330,3 +330,12 @@ SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MA min max avg 10.00 10.00 10 DROP TABLE t1; +create table t1 (a integer, b integer); +insert into t1 values (1,4), (2,2),(2,2), (4,1),(4,1),(4,1),(4,1); +select distinct sum(b) from t1 group by a; +sum(b) +4 +select distinct sum(b) from (select a,b from t1) y group by a; +sum(b) +4 +drop table t1; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 623bd2a0f3c..8f2294caa48 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -60,7 +60,7 @@ INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456) /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, @@ -83,7 +83,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, `b` float default NULL @@ -149,7 +149,7 @@ INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` varchar(255) default NULL @@ -175,7 +175,7 @@ CREATE TABLE t1 (a int) ENGINE=MYISAM; INSERT INTO t1 VALUES (1), (2); /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL40" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL40' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` int(11) default NULL @@ -194,7 +194,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` int(11) default NULL @@ -225,7 +225,7 @@ create table t1(a int); /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` int(11) default NULL @@ -246,7 +246,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,ANSI" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; DROP TABLE IF EXISTS "t1"; CREATE TABLE "t1" ( "a" int(11) default NULL @@ -270,7 +270,7 @@ set global sql_mode='ANSI_QUOTES'; /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` int(11) default NULL @@ -291,7 +291,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,ANSI" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; DROP TABLE IF EXISTS "t1"; CREATE TABLE "t1" ( "a" int(11) default NULL @@ -316,7 +316,7 @@ insert into t1 values (1),(2),(3); /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` int(11) default NULL @@ -339,7 +339,7 @@ drop table t1; /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */; @@ -360,7 +360,7 @@ create database mysqldump_test_db character set latin2 collate latin2_bin; /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CHARACTER SET latin2 COLLATE latin2_bin */; @@ -383,7 +383,7 @@ INSERT INTO t1 VALUES (_latin1 'ÄÖÜß'); /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` char(10) default NULL @@ -405,7 +405,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` char(10) default NULL @@ -424,7 +424,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` char(10) default NULL @@ -443,7 +443,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` char(10) default NULL @@ -462,7 +462,7 @@ UNLOCK TABLES; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a` char(10) default NULL @@ -491,7 +491,7 @@ INSERT INTO t2 VALUES (4),(5),(6); /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `t2`; CREATE TABLE `t2` ( `a` int(11) default NULL diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 02662f9900a..437fd624ae1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2160,3 +2160,51 @@ ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery' select * from t1 where a1 > any(select b1 from t2); a1 drop table t1,t2; +create table t1 (a integer, b integer); +select (select * from t1) = (select 1,2); +(select * from t1) = (select 1,2) +NULL +select (select 1,2) = (select * from t1); +(select 1,2) = (select * from t1) +NULL +select row(1,2) = ANY (select * from t1); +row(1,2) = ANY (select * from t1) +0 +select row(1,2) != ALL (select * from t1); +row(1,2) != ALL (select * from t1) +1 +drop table t1; +create table t1 (a integer, b integer); +select row(1,(2,2)) in (select * from t1 ); +ERROR 21000: Operand should contain 2 column(s) +select row(1,(2,2)) = (select * from t1 ); +ERROR 21000: Operand should contain 2 column(s) +select (select * from t1) = row(1,(2,2)); +ERROR 21000: Operand should contain 1 column(s) +drop table t1; +create table t1 (a integer); +insert into t1 values (1); +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ; +ERROR 42S22: Reference 'xx' not supported (forward reference in item list) +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx; +ERROR 42S22: Reference 'xx' not supported (forward reference in item list) +select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx ); +xx 1 = ALL ( select 1 from t1 where 1 = xx ) +1 1 +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx; +ERROR 42S22: Reference 'xx' not supported (forward reference in item list) +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL; +ERROR 42S22: Reference 'xx' not supported (forward reference in item list) +drop table t1; +CREATE TABLE `t1` ( `a` char(3) NOT NULL default '', `b` char(3) NOT NULL default '', `c` char(3) NOT NULL default '', PRIMARY KEY (`a`,`b`,`c`)) ENGINE=InnoDB; +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (1,1,1); +INSERT INTO t2 VALUES (1,1,1); +PREPARE my_stmt FROM "SELECT t1.b, count(*) FROM t1 group by t1.b having +count(*) > ALL (SELECT COUNT(*) FROM t2 WHERE t2.a=1 GROUP By t2.b)"; +EXECUTE my_stmt; +b count(*) +EXECUTE my_stmt; +b count(*) +deallocate prepare my_stmt; +drop table t1,t2; diff --git a/mysql-test/t/compare.test b/mysql-test/t/compare.test index b0cef48dd3f..e3c042e608a 100644 --- a/mysql-test/t/compare.test +++ b/mysql-test/t/compare.test @@ -30,3 +30,6 @@ CREATE TABLE t1 (a char(10) not null); INSERT INTO t1 VALUES ('a'),('a\0'),('a\t'),('a '); SELECT hex(a),STRCMP(a,'a'), STRCMP(a,'a ') FROM t1; DROP TABLE t1; + +# Bug #8134: Comparison against CHAR(31) at end of string +SELECT CHAR(31) = '', '' = CHAR(31); diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 64e3fe8929b..8b322746ed6 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -214,3 +214,13 @@ CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) N insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10); SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MAX(concat(date_,";",price)), 12) price FROM t1 WHERE itemid=128 AND grpid='rozn' GROUP BY itemid, grpid, vendor) lastprices; DROP TABLE t1; + +# +# DISTINCT over grouped select on subquery in the FROM clause +# +create table t1 (a integer, b integer); +insert into t1 values (1,4), (2,2),(2,2), (4,1),(4,1),(4,1),(4,1); +select distinct sum(b) from t1 group by a; +select distinct sum(b) from (select a,b from t1) y group by a; +drop table t1; + diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3ee498ee380..cdec080611d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1414,8 +1414,11 @@ SELECT f1 FROM t1 WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); drop table t1,t2; + +# # Test for BUG#7885: Server crash when 'any' subselect compared to # non-existant field. +# create table t1 (a1 int); create table t2 (b1 int); --error 1054 @@ -1423,3 +1426,56 @@ select * from t1 where a2 > any(select b1 from t2); select * from t1 where a1 > any(select b1 from t2); drop table t1,t2; + +# +# Comparison subquery with * and row +# +create table t1 (a integer, b integer); +select (select * from t1) = (select 1,2); +select (select 1,2) = (select * from t1); +# queries whih can be converted to IN +select row(1,2) = ANY (select * from t1); +select row(1,2) != ALL (select * from t1); +drop table t1; + +# +# Comparison subquery and row with nested rows +# +create table t1 (a integer, b integer); +-- error 1241 +select row(1,(2,2)) in (select * from t1 ); +-- error 1241 +select row(1,(2,2)) = (select * from t1 ); +-- error 1241 +select (select * from t1) = row(1,(2,2)); +drop table t1; + +# +# Forward reference detection +# +create table t1 (a integer); +insert into t1 values (1); +-- error 1247 +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ; +-- error 1247 +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx; +select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx ); +-- error 1247 +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx; +-- error 1247 +select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL; +drop table t1; + +# +# cleaning up of results of subselects (BUG#8125) +# +CREATE TABLE `t1` ( `a` char(3) NOT NULL default '', `b` char(3) NOT NULL default '', `c` char(3) NOT NULL default '', PRIMARY KEY (`a`,`b`,`c`)) ENGINE=InnoDB; +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (1,1,1); +INSERT INTO t2 VALUES (1,1,1); +PREPARE my_stmt FROM "SELECT t1.b, count(*) FROM t1 group by t1.b having +count(*) > ALL (SELECT COUNT(*) FROM t2 WHERE t2.a=1 GROUP By t2.b)"; +EXECUTE my_stmt; +EXECUTE my_stmt; +deallocate prepare my_stmt; +drop table t1,t2; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 502f8eb92f3..1d75ce99aee 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4672,12 +4672,12 @@ ha_innobase::update_table_comment( dict_print_info_on_foreign_keys(FALSE, file, prebuilt->trx, prebuilt->table); flen = ftell(file); - if(length + flen + 3 > 64000) { + if (flen < 0) { + flen = 0; + } else if (length + flen + 3 > 64000) { flen = 64000 - 3 - length; } - ut_ad(flen > 0); - /* allocate buffer for the full string, and read the contents of the temporary file */ @@ -4741,12 +4741,12 @@ ha_innobase::get_foreign_key_create_info(void) prebuilt->trx->op_info = (char*)""; flen = ftell(file); - if(flen > 64000 - 1) { + if (flen < 0) { + flen = 0; + } else if(flen > 64000 - 1) { flen = 64000 - 1; } - ut_ad(flen >= 0); - /* allocate buffer for the string, and read the contents of the temporary file */ @@ -5142,12 +5142,12 @@ innodb_show_status( srv_printf_innodb_monitor(srv_monitor_file); flen = ftell(srv_monitor_file); os_file_set_eof(srv_monitor_file); - if(flen > 64000 - 1) { + if (flen < 0) { + flen = 0; + } else if (flen > 64000 - 1) { flen = 64000 - 1; } - ut_ad(flen > 0); - /* allocate buffer for the string, and read the contents of the temporary file */ diff --git a/sql/item.cc b/sql/item.cc index 8c45dffce75..ab29c147dfb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1482,12 +1482,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } else if (refer != (Item **)not_found_item) { - if (!(*refer)->fixed) + if (!last->ref_pointer_array[counter]) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); return -1; } + DBUG_ASSERT((*refer)->fixed); /* Here, a subset of actions performed by Item_ref::set_properties is not enough. So we pass ptr to NULL into Item_[direct]_ref @@ -2161,12 +2162,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) mark_as_dependent(thd, last, thd->lex->current_select, fld); return 0; } - if (!(*ref)->fixed) + if (!last->ref_pointer_array[counter]) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); return -1; } + DBUG_ASSERT((*ref)->fixed); mark_as_dependent(thd, last, thd->lex->current_select, this); if (place == IN_HAVING) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 6834799688d..061ed468b78 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -213,7 +213,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2 public: Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) { - allowed_arg_cols= a->cols(); + allowed_arg_cols= 0; // Fetch this value from first argument } Item *neg_transformer(THD *thd); virtual Item *negated_item(); @@ -390,7 +390,10 @@ class Item_func_interval :public Item_int_func double *intervals; public: Item_func_interval(Item_row *a) - :Item_int_func(a),row(a),intervals(0) { allowed_arg_cols= a->cols(); } + :Item_int_func(a),row(a),intervals(0) + { + allowed_arg_cols= 0; // Fetch this value from first argument + } longlong val_int(); void fix_length_and_dec(); const char *func_name() const { return "interval"; } @@ -743,7 +746,7 @@ class Item_func_in :public Item_int_func Item_func_in(List<Item> &list) :Item_int_func(list), array(0), in_item(0), have_null(0) { - allowed_arg_cols= args[0]->cols(); + allowed_arg_cols= 0; // Fetch this value from first argument } longlong val_int(); void fix_length_and_dec(); diff --git a/sql/item_func.cc b/sql/item_func.cc index 7125f4704b8..bff49541252 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -303,10 +303,24 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) We can't yet set item to *arg as fix_fields may change *arg We shouldn't call fix_fields() twice, so check 'fixed' field first */ - if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || - (*arg)->check_cols(allowed_arg_cols)) + if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg))) return 1; /* purecov: inspected */ + item= *arg; + + if (allowed_arg_cols) + { + if (item->check_cols(allowed_arg_cols)) + return 1; + } + else + { + /* we have to fetch allowed_arg_cols from first argument */ + DBUG_ASSERT(arg == args); // it is first argument + allowed_arg_cols= item->cols(); + DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more + } + if (item->maybe_null) maybe_null=1; diff --git a/sql/item_func.h b/sql/item_func.h index ce2b34499d6..8a5347d675e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -32,6 +32,10 @@ class Item_func :public Item_result_field { protected: Item **args, *tmp_arg[2]; + /* + Allowed numbers of columns in result (usually 1, which means scalar value) + 0 means get this number from first argument + */ uint allowed_arg_cols; public: uint arg_count; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8516ea76a7e..16186b1a6d3 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -995,6 +995,10 @@ Item_in_subselect::row_value_transformer(JOIN *join) List_iterator_fast<Item> li(select_lex->item_list); for (uint i= 0; i < n; i++) { + DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed); + if (select_lex->ref_pointer_array[i]-> + check_cols(left_expr->el(i)->cols())) + goto err; Item *func= new Item_ref_null_helper(this, select_lex->ref_pointer_array+i, (char *) "<no matter>", @@ -1123,6 +1127,7 @@ void subselect_single_select_engine::cleanup() DBUG_ENTER("subselect_single_select_engine::cleanup"); prepared= optimized= executed= 0; join= 0; + result->cleanup(); DBUG_VOID_RETURN; } @@ -1131,6 +1136,7 @@ void subselect_union_engine::cleanup() { DBUG_ENTER("subselect_union_engine::cleanup"); unit->reinit_exec_mechanism(); + result->cleanup(); DBUG_VOID_RETURN; } @@ -1138,6 +1144,10 @@ void subselect_union_engine::cleanup() void subselect_uniquesubquery_engine::cleanup() { DBUG_ENTER("subselect_uniquesubquery_engine::cleanup"); + /* + subselect_uniquesubquery_engine have not 'result' assigbed, so we do not + cleanup() it + */ DBUG_VOID_RETURN; } @@ -1421,13 +1431,15 @@ int subselect_indexsubquery_engine::exec() uint subselect_single_select_engine::cols() { - return select_lex->item_list.elements; + DBUG_ASSERT(select_lex->join); // should be called after fix_fields() + return select_lex->join->fields_list.elements; } uint subselect_union_engine::cols() { - return unit->first_select()->item_list.elements; + DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields() + return unit->types.elements; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 06a17acd2a1..6218bc49f53 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -377,6 +377,7 @@ Item *negate_expression(THD *thd, Item *expr); struct Query_cache_query_flags { unsigned int client_long_flag:1; + unsigned int client_protocol_41:1; uint character_set_client_num; uint character_set_results_num; uint collation_connection_num; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 7d26996856d..7434897ab90 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2405,6 +2405,20 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, thd->allow_sum_func= allow_sum_func; thd->where="field list"; + /* + To prevent fail on forward lookup we fill it with zerows, + then if we got pointer on zero after find_item_in_list we will know + that it is forward lookup. + + There is other way to solve problem: fill array with pointers to list, + but it will be slower. + + TODO: remove it when (if) we made one list for allfields and + ref_pointer_array + */ + if (ref_pointer_array) + bzero(ref_pointer_array, sizeof(Item *) * fields.elements); + Item **ref= ref_pointer_array; while ((item= it++)) { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 55e96ec0c6d..e1367412601 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -776,6 +776,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) bzero(&flags, QUERY_CACHE_FLAGS_SIZE); flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ? 1 : 0); + flags.client_protocol_41= (thd->client_capabilities & CLIENT_PROTOCOL_41 ? + 1 : 0); flags.character_set_client_num= thd->variables.character_set_client->number; flags.character_set_results_num= @@ -968,6 +970,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) bzero(&flags, QUERY_CACHE_FLAGS_SIZE); flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ? 1 : 0); + flags.client_protocol_41= (thd->client_capabilities & CLIENT_PROTOCOL_41 ? + 1 : 0); flags.character_set_client_num= thd->variables.character_set_client->number; flags.character_set_results_num= (thd->variables.character_set_results ? diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 596097d9dc2..e11d8369f57 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1240,6 +1240,14 @@ bool select_singlerow_subselect::send_data(List<Item> &items) } +void select_max_min_finder_subselect::cleanup() +{ + DBUG_ENTER("select_max_min_finder_subselect::cleanup"); + cache= 0; + DBUG_VOID_RETURN; +} + + bool select_max_min_finder_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); diff --git a/sql/sql_class.h b/sql/sql_class.h index 8128690ab02..657a92b394c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1386,6 +1386,7 @@ public: select_max_min_finder_subselect(Item_subselect *item, bool mx) :select_subselect(item), cache(0), fmax(mx) {} + void cleanup(); bool send_data(List<Item> &items); bool cmp_real(); bool cmp_int(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3ac783da9c4..ed974a48ad3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -164,7 +164,10 @@ void lex_start(THD *thd, uchar *buf,uint length) void lex_end(LEX *lex) { - lex->select_lex.expr_list.delete_elements(); // If error when parsing sql-varargs + for (SELECT_LEX *sl= lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + sl->expr_list.delete_elements(); // If error when parsing sql-varargs x_free(lex->yacc_yyss); x_free(lex->yacc_yyvs); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e2e0bc61c23..7cb71607edf 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -371,6 +371,7 @@ public: ulong init_prepare_fake_select_lex(THD *thd); int change_result(select_subselect *result, select_subselect *old_result); + inline bool is_prepared() { return prepared; } friend void lex_start(THD *thd, uchar *buf, uint length); friend int subselect_union_engine::exec(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ccfcb213068..8353ca9333d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1320,7 +1320,7 @@ JOIN::exec() curr_join->select_distinct=0; /* Each row is unique */ curr_join->join_free(0); /* Free quick selects */ - if (select_distinct && ! group_list) + if (curr_join->select_distinct && ! curr_join->group_list) { thd->proc_info="Removing duplicates"; if (curr_join->tmp_having) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 423a309767b..f3c107c2696 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2272,8 +2272,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, strxmov(src_path, (*tmp_table)->path, reg_ext, NullS); else { - strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, - reg_ext, NullS); + fn_format( src_path, src_table, src_db, reg_ext, MYF(MY_UNPACK_FILENAME)); if (access(src_path, F_OK)) { my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); @@ -2300,8 +2299,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, } else { - strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, - reg_ext, NullS); + fn_format( dst_path, table_name, db, reg_ext, MYF(MY_UNPACK_FILENAME)); if (!access(dst_path, F_OK)) goto table_exists; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 5bfa9e52595..4dc6a1be27b 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -153,7 +153,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length, /* put shorter key in s */ a_length= b_length; a= b; - swap= -1; /* swap sign of result */ + swap= -1^1; /* swap sign of result */ } for (end= a + a_length-length; a < end ; a++) { |