mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	Merge bk-internal.mysql.com:/data0/bk/mysql-5.1
into bk-internal.mysql.com:/data0/bk/mysql-5.1-opt
This commit is contained in:
		@@ -474,6 +474,7 @@ CREATE TABLE t4 (a DATE);
 | 
				
			|||||||
INSERT INTO t4 VALUES ('1972-02-06'), ('1972-07-29');
 | 
					INSERT INTO t4 VALUES ('1972-02-06'), ('1972-07-29');
 | 
				
			||||||
SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
 | 
					SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
 | 
				
			||||||
a
 | 
					a
 | 
				
			||||||
 | 
					1972-02-06
 | 
				
			||||||
Warnings:
 | 
					Warnings:
 | 
				
			||||||
Warning	1292	Incorrect date value: '19772-07-29' for column 'a' at row 1
 | 
					Warning	1292	Incorrect date value: '19772-07-29' for column 'a' at row 1
 | 
				
			||||||
DROP TABLE t1,t2,t3,t4;
 | 
					DROP TABLE t1,t2,t3,t4;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -336,3 +336,25 @@ id	f1
 | 
				
			|||||||
0	test1
 | 
					0	test1
 | 
				
			||||||
DROP TABLE t1;
 | 
					DROP TABLE t1;
 | 
				
			||||||
SET SQL_MODE='';
 | 
					SET SQL_MODE='';
 | 
				
			||||||
 | 
					CREATE TABLE t1 (
 | 
				
			||||||
 | 
					id INT AUTO_INCREMENT PRIMARY KEY,
 | 
				
			||||||
 | 
					c1 CHAR(1) UNIQUE KEY,
 | 
				
			||||||
 | 
					cnt INT DEFAULT 1
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
 | 
				
			||||||
 | 
					SELECT * FROM t1;
 | 
				
			||||||
 | 
					id	c1	cnt
 | 
				
			||||||
 | 
					1	A	1
 | 
				
			||||||
 | 
					2	B	1
 | 
				
			||||||
 | 
					3	C	1
 | 
				
			||||||
 | 
					INSERT  INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
 | 
				
			||||||
 | 
					ON DUPLICATE KEY UPDATE cnt=cnt+1;
 | 
				
			||||||
 | 
					SELECT * FROM t1;
 | 
				
			||||||
 | 
					id	c1	cnt
 | 
				
			||||||
 | 
					1	A	2
 | 
				
			||||||
 | 
					2	B	1
 | 
				
			||||||
 | 
					3	C	1
 | 
				
			||||||
 | 
					4	X	1
 | 
				
			||||||
 | 
					5	Y	1
 | 
				
			||||||
 | 
					6	Z	1
 | 
				
			||||||
 | 
					DROP TABLE t1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,6 +174,25 @@ f2
 | 
				
			|||||||
2
 | 
					2
 | 
				
			||||||
SET @@SQL_MODE=@OLD_SQL_MODE;
 | 
					SET @@SQL_MODE=@OLD_SQL_MODE;
 | 
				
			||||||
drop table t1,t2;
 | 
					drop table t1,t2;
 | 
				
			||||||
 | 
					create table t1(f1 int, f2 timestamp not null default current_timestamp);
 | 
				
			||||||
 | 
					create table t2(f1 int);
 | 
				
			||||||
 | 
					insert into t2 values(1),(2);
 | 
				
			||||||
 | 
					Warnings:
 | 
				
			||||||
 | 
					Warning	1261	Row 1 doesn't contain data for all columns
 | 
				
			||||||
 | 
					Warning	1261	Row 2 doesn't contain data for all columns
 | 
				
			||||||
 | 
					select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1;
 | 
				
			||||||
 | 
					f1
 | 
				
			||||||
 | 
					1
 | 
				
			||||||
 | 
					2
 | 
				
			||||||
 | 
					delete from t1;
 | 
				
			||||||
 | 
					Warnings:
 | 
				
			||||||
 | 
					Warning	1261	Row 1 doesn't contain data for all columns
 | 
				
			||||||
 | 
					Warning	1261	Row 2 doesn't contain data for all columns
 | 
				
			||||||
 | 
					select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1;
 | 
				
			||||||
 | 
					f1
 | 
				
			||||||
 | 
					1
 | 
				
			||||||
 | 
					2
 | 
				
			||||||
 | 
					drop table t1,t2;
 | 
				
			||||||
CREATE TABLE t1 (a int);
 | 
					CREATE TABLE t1 (a int);
 | 
				
			||||||
INSERT INTO t1 VALUES (1);
 | 
					INSERT INTO t1 VALUES (1);
 | 
				
			||||||
SET NAMES latin1;
 | 
					SET NAMES latin1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -264,6 +264,52 @@ f2
 | 
				
			|||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
 | 
					SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
 | 
				
			||||||
1
 | 
					1
 | 
				
			||||||
drop table t1;
 | 
					drop table t1;
 | 
				
			||||||
 | 
					create table t1 (f1 date);
 | 
				
			||||||
 | 
					insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
 | 
				
			||||||
 | 
					select * from t1 where f1 in ('01-01-01','2001-01-02','2001-01-03 00:00:00');
 | 
				
			||||||
 | 
					f1
 | 
				
			||||||
 | 
					2001-01-01
 | 
				
			||||||
 | 
					2001-01-02
 | 
				
			||||||
 | 
					2001-01-03
 | 
				
			||||||
 | 
					create table t2(f2 datetime);
 | 
				
			||||||
 | 
					insert into t2 values('01-01-01 00:00:00'),('01-02-03 12:34:56'),('02-04-06 11:22:33');
 | 
				
			||||||
 | 
					select * from t2 where f2 in ('01-01-01','01-02-03 12:34:56','01-02-03');
 | 
				
			||||||
 | 
					f2
 | 
				
			||||||
 | 
					2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-02-03 12:34:56
 | 
				
			||||||
 | 
					select * from t1,t2 where '01-01-02' in (f1, cast(f2 as date));
 | 
				
			||||||
 | 
					f1	f2
 | 
				
			||||||
 | 
					2001-01-02	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-01-02	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2001-01-02	2002-04-06 11:22:33
 | 
				
			||||||
 | 
					select * from t1,t2 where '01-01-01' in (f1, '01-02-03');
 | 
				
			||||||
 | 
					f1	f2
 | 
				
			||||||
 | 
					2001-01-01	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-01-01	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2001-01-01	2002-04-06 11:22:33
 | 
				
			||||||
 | 
					select * from t1,t2 where if(1,'01-02-03 12:34:56','') in (f1, f2);
 | 
				
			||||||
 | 
					f1	f2
 | 
				
			||||||
 | 
					2001-01-01	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2001-01-02	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2001-01-03	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					create table t3(f3 varchar(20));
 | 
				
			||||||
 | 
					insert into t3 select * from t2;
 | 
				
			||||||
 | 
					select * from t2,t3 where f2 in (f3,'03-04-05');
 | 
				
			||||||
 | 
					f2	f3
 | 
				
			||||||
 | 
					2001-01-01 00:00:00	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-02-03 12:34:56	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2002-04-06 11:22:33	2002-04-06 11:22:33
 | 
				
			||||||
 | 
					select f1,f2,f3 from t1,t2,t3 where (f1,'1') in ((f2,'1'),(f3,'1'));
 | 
				
			||||||
 | 
					f1	f2	f3
 | 
				
			||||||
 | 
					2001-01-01	2001-01-01 00:00:00	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-01-01	2001-02-03 12:34:56	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-01-01	2002-04-06 11:22:33	2001-01-01 00:00:00
 | 
				
			||||||
 | 
					2001-01-01	2001-01-01 00:00:00	2001-02-03 12:34:56
 | 
				
			||||||
 | 
					2001-01-01	2001-01-01 00:00:00	2002-04-06 11:22:33
 | 
				
			||||||
 | 
					select f1 from t1 where ('1',f1) in (('1','01-01-01'),('1','2001-1-1 0:0:0'),('1','02-02-02'));
 | 
				
			||||||
 | 
					f1
 | 
				
			||||||
 | 
					2001-01-01
 | 
				
			||||||
 | 
					drop table t1,t2,t3;
 | 
				
			||||||
select least(cast('01-01-01' as date), '01-01-02');
 | 
					select least(cast('01-01-01' as date), '01-01-02');
 | 
				
			||||||
least(cast('01-01-01' as date), '01-01-02')
 | 
					least(cast('01-01-01' as date), '01-01-02')
 | 
				
			||||||
2001-01-01
 | 
					2001-01-01
 | 
				
			||||||
@@ -279,6 +325,12 @@ greatest(cast('01-01-01' as date), '01-01-02') + 0
 | 
				
			|||||||
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
 | 
					select least(cast('01-01-01' as datetime), '01-01-02') + 0;
 | 
				
			||||||
least(cast('01-01-01' as datetime), '01-01-02') + 0
 | 
					least(cast('01-01-01' as datetime), '01-01-02') + 0
 | 
				
			||||||
20010101000000
 | 
					20010101000000
 | 
				
			||||||
 | 
					select cast(least(cast('01-01-01' as datetime), '01-01-02') as signed);
 | 
				
			||||||
 | 
					cast(least(cast('01-01-01' as datetime), '01-01-02') as signed)
 | 
				
			||||||
 | 
					20010101000000
 | 
				
			||||||
 | 
					select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal(16,2));
 | 
				
			||||||
 | 
					cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal(16,2))
 | 
				
			||||||
 | 
					20010101000000.00
 | 
				
			||||||
DROP PROCEDURE IF EXISTS test27759 ;
 | 
					DROP PROCEDURE IF EXISTS test27759 ;
 | 
				
			||||||
CREATE PROCEDURE test27759()
 | 
					CREATE PROCEDURE test27759()
 | 
				
			||||||
BEGIN
 | 
					BEGIN
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -247,3 +247,20 @@ REPLACE INTO t1 VALUES (0,"test1",null);
 | 
				
			|||||||
SELECT id, f1 FROM t1;
 | 
					SELECT id, f1 FROM t1;
 | 
				
			||||||
DROP TABLE t1;
 | 
					DROP TABLE t1;
 | 
				
			||||||
SET SQL_MODE='';
 | 
					SET SQL_MODE='';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Bug#27954: multi-row INSERT ... ON DUPLICATE with duplicated
 | 
				
			||||||
 | 
					# row at the first place into table with AUTO_INCREMENT and
 | 
				
			||||||
 | 
					# additional UNIQUE key.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					CREATE TABLE t1 (
 | 
				
			||||||
 | 
					  id INT AUTO_INCREMENT PRIMARY KEY,
 | 
				
			||||||
 | 
					  c1 CHAR(1) UNIQUE KEY,
 | 
				
			||||||
 | 
					  cnt INT DEFAULT 1
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
 | 
				
			||||||
 | 
					SELECT * FROM t1;
 | 
				
			||||||
 | 
					INSERT  INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
 | 
				
			||||||
 | 
					  ON DUPLICATE KEY UPDATE cnt=cnt+1;
 | 
				
			||||||
 | 
					SELECT * FROM t1;
 | 
				
			||||||
 | 
					DROP TABLE t1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,6 +156,32 @@ select * from t2;
 | 
				
			|||||||
--exec rm $MYSQLTEST_VARDIR/tmp/t1
 | 
					--exec rm $MYSQLTEST_VARDIR/tmp/t1
 | 
				
			||||||
SET @@SQL_MODE=@OLD_SQL_MODE;
 | 
					SET @@SQL_MODE=@OLD_SQL_MODE;
 | 
				
			||||||
drop table t1,t2;
 | 
					drop table t1,t2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Bug#27670: LOAD DATA does not set CURRENT_TIMESTAMP default value for a
 | 
				
			||||||
 | 
					#            TIMESTAMP field when no value has been provided.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					create table t1(f1 int, f2 timestamp not null default current_timestamp);
 | 
				
			||||||
 | 
					create table t2(f1 int);
 | 
				
			||||||
 | 
					insert into t2 values(1),(2);
 | 
				
			||||||
 | 
					disable_query_log;
 | 
				
			||||||
 | 
					eval select * into outfile '$MYSQLTEST_VARDIR/tmp/t2' from t2;
 | 
				
			||||||
 | 
					eval load data infile '$MYSQLTEST_VARDIR/tmp/t2' into table t1;
 | 
				
			||||||
 | 
					enable_query_log;
 | 
				
			||||||
 | 
					select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1;
 | 
				
			||||||
 | 
					--exec rm $MYSQLTEST_VARDIR/tmp/t2
 | 
				
			||||||
 | 
					delete from t1;
 | 
				
			||||||
 | 
					disable_query_log;
 | 
				
			||||||
 | 
					eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t2'
 | 
				
			||||||
 | 
					FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n'
 | 
				
			||||||
 | 
					FROM t2;
 | 
				
			||||||
 | 
					eval load data infile '$MYSQLTEST_VARDIR/tmp/t2' into table t1
 | 
				
			||||||
 | 
					FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n';
 | 
				
			||||||
 | 
					enable_query_log;
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# End of 5.0 tests
 | 
					# End of 5.0 tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,6 +179,25 @@ select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
 | 
				
			|||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
 | 
					SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
 | 
				
			||||||
drop table t1;
 | 
					drop table t1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Bug#28133: Wrong DATE/DATETIME comparison in IN() function.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					create table t1 (f1 date);
 | 
				
			||||||
 | 
					insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
 | 
				
			||||||
 | 
					select * from t1 where f1 in ('01-01-01','2001-01-02','2001-01-03 00:00:00');
 | 
				
			||||||
 | 
					create table t2(f2 datetime);
 | 
				
			||||||
 | 
					insert into t2 values('01-01-01 00:00:00'),('01-02-03 12:34:56'),('02-04-06 11:22:33');
 | 
				
			||||||
 | 
					select * from t2 where f2 in ('01-01-01','01-02-03 12:34:56','01-02-03');
 | 
				
			||||||
 | 
					select * from t1,t2 where '01-01-02' in (f1, cast(f2 as date));
 | 
				
			||||||
 | 
					select * from t1,t2 where '01-01-01' in (f1, '01-02-03');
 | 
				
			||||||
 | 
					select * from t1,t2 where if(1,'01-02-03 12:34:56','') in (f1, f2);
 | 
				
			||||||
 | 
					create table t3(f3 varchar(20));
 | 
				
			||||||
 | 
					insert into t3 select * from t2;
 | 
				
			||||||
 | 
					select * from t2,t3 where f2 in (f3,'03-04-05');
 | 
				
			||||||
 | 
					select f1,f2,f3 from t1,t2,t3 where (f1,'1') in ((f2,'1'),(f3,'1'));
 | 
				
			||||||
 | 
					select f1 from t1 where ('1',f1) in (('1','01-01-01'),('1','2001-1-1 0:0:0'),('1','02-02-02'));
 | 
				
			||||||
 | 
					drop table t1,t2,t3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
 | 
					# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -187,6 +206,8 @@ select greatest(cast('01-01-01' as date), '01-01-02');
 | 
				
			|||||||
select least(cast('01-01-01' as date), '01-01-02') + 0;
 | 
					select least(cast('01-01-01' as date), '01-01-02') + 0;
 | 
				
			||||||
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
 | 
					select greatest(cast('01-01-01' as date), '01-01-02') + 0;
 | 
				
			||||||
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
 | 
					select least(cast('01-01-01' as datetime), '01-01-02') + 0;
 | 
				
			||||||
 | 
					select cast(least(cast('01-01-01' as datetime), '01-01-02') as signed);
 | 
				
			||||||
 | 
					select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal(16,2));
 | 
				
			||||||
--disable_warnings
 | 
					--disable_warnings
 | 
				
			||||||
DROP PROCEDURE IF EXISTS test27759 ;
 | 
					DROP PROCEDURE IF EXISTS test27759 ;
 | 
				
			||||||
--enable_warnings
 | 
					--enable_warnings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2830,7 +2830,6 @@ in_row::in_row(uint elements, Item * item)
 | 
				
			|||||||
  base= (char*) new cmp_item_row[count= elements];
 | 
					  base= (char*) new cmp_item_row[count= elements];
 | 
				
			||||||
  size= sizeof(cmp_item_row);
 | 
					  size= sizeof(cmp_item_row);
 | 
				
			||||||
  compare= (qsort2_cmp) cmp_row;
 | 
					  compare= (qsort2_cmp) cmp_row;
 | 
				
			||||||
  tmp.store_value(item);
 | 
					 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
    We need to reset these as otherwise we will call sort() with
 | 
					    We need to reset these as otherwise we will call sort() with
 | 
				
			||||||
    uninitialized (even if not used) elements
 | 
					    uninitialized (even if not used) elements
 | 
				
			||||||
@@ -2882,6 +2881,27 @@ byte *in_longlong::get_value(Item *item)
 | 
				
			|||||||
  return (byte*) &tmp;
 | 
					  return (byte*) &tmp;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void in_datetime::set(uint pos,Item *item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Item **tmp= &item;
 | 
				
			||||||
 | 
					  bool is_null;
 | 
				
			||||||
 | 
					  struct packed_longlong *buff= &((packed_longlong*) base)[pos];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  buff->val= get_datetime_value(thd, &tmp, 0, warn_item, &is_null);
 | 
				
			||||||
 | 
					  buff->unsigned_flag= 1L;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte *in_datetime::get_value(Item *item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  bool is_null;
 | 
				
			||||||
 | 
					  Item **tmp_item= lval_cache ? &lval_cache : &item;
 | 
				
			||||||
 | 
					  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 | 
				
			||||||
 | 
					  if (item->null_value)
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  tmp.unsigned_flag= 1L;
 | 
				
			||||||
 | 
					  return (byte*) &tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
in_double::in_double(uint elements)
 | 
					in_double::in_double(uint elements)
 | 
				
			||||||
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
 | 
					  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
 | 
				
			||||||
{}
 | 
					{}
 | 
				
			||||||
@@ -2986,12 +3006,18 @@ cmp_item_row::~cmp_item_row()
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cmp_item_row::alloc_comparators()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!comparators)
 | 
				
			||||||
 | 
					    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmp_item_row::store_value(Item *item)
 | 
					void cmp_item_row::store_value(Item *item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  DBUG_ENTER("cmp_item_row::store_value");
 | 
					  DBUG_ENTER("cmp_item_row::store_value");
 | 
				
			||||||
  n= item->cols();
 | 
					  n= item->cols();
 | 
				
			||||||
  if (!comparators)
 | 
					  alloc_comparators();
 | 
				
			||||||
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 | 
					 | 
				
			||||||
  if (comparators)
 | 
					  if (comparators)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    item->bring_value();
 | 
					    item->bring_value();
 | 
				
			||||||
@@ -3103,6 +3129,36 @@ cmp_item* cmp_item_decimal::make_same()
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cmp_item_datetime::store_value(Item *item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  bool is_null;
 | 
				
			||||||
 | 
					  Item **tmp_item= lval_cache ? &lval_cache : &item;
 | 
				
			||||||
 | 
					  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cmp_item_datetime::cmp(Item *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  bool is_null;
 | 
				
			||||||
 | 
					  Item **tmp_item= &arg;
 | 
				
			||||||
 | 
					  return value !=
 | 
				
			||||||
 | 
					    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cmp_item_datetime::compare(cmp_item *ci)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  cmp_item_datetime *l_cmp= (cmp_item_datetime *)ci;
 | 
				
			||||||
 | 
					  return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cmp_item *cmp_item_datetime::make_same()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return new cmp_item_datetime(warn_item);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Item_func_in::nulls_in_row()
 | 
					bool Item_func_in::nulls_in_row()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  Item **arg,**arg_end;
 | 
					  Item **arg,**arg_end;
 | 
				
			||||||
@@ -3178,6 +3234,10 @@ void Item_func_in::fix_length_and_dec()
 | 
				
			|||||||
  Item **arg, **arg_end;
 | 
					  Item **arg, **arg_end;
 | 
				
			||||||
  bool const_itm= 1;
 | 
					  bool const_itm= 1;
 | 
				
			||||||
  THD *thd= current_thd;
 | 
					  THD *thd= current_thd;
 | 
				
			||||||
 | 
					  bool datetime_found= FALSE;
 | 
				
			||||||
 | 
					  /* TRUE <=> arguments values will be compared as DATETIMEs. */
 | 
				
			||||||
 | 
					  bool compare_as_datetime= FALSE;
 | 
				
			||||||
 | 
					  Item *date_arg= 0;
 | 
				
			||||||
  uint found_types= 0;
 | 
					  uint found_types= 0;
 | 
				
			||||||
  uint type_cnt= 0, i;
 | 
					  uint type_cnt= 0, i;
 | 
				
			||||||
  Item_result cmp_type= STRING_RESULT;
 | 
					  Item_result cmp_type= STRING_RESULT;
 | 
				
			||||||
@@ -3209,16 +3269,103 @@ void Item_func_in::fix_length_and_dec()
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    arg_types_compatible= TRUE;
 | 
					    arg_types_compatible= TRUE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (type_cnt == 1)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					      When comparing rows create the row comparator object beforehand to ease
 | 
				
			||||||
 | 
					      the DATETIME comparison detection procedure.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    if (cmp_type == ROW_RESULT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cmp_item_row *cmp= 0;
 | 
				
			||||||
 | 
					      if (const_itm && !nulls_in_row())
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        array= new in_row(arg_count-1, 0);
 | 
				
			||||||
 | 
					        cmp= &((in_row*)array)->tmp;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        if (!(cmp= new cmp_item_row))
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        cmp_items[ROW_RESULT]= cmp;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      cmp->n= args[0]->cols();
 | 
				
			||||||
 | 
					      cmp->alloc_comparators();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* All DATE/DATETIME fields/functions has the STRING result type. */
 | 
				
			||||||
 | 
					    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      uint col, cols= args[0]->cols();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (col= 0; col < cols; col++)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        bool skip_column= FALSE;
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					          Check that all items to be compared has the STRING result type and at
 | 
				
			||||||
 | 
					          least one of them is a DATE/DATETIME item.
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
 | 
				
			||||||
 | 
					                      arg[0]->element_index(col));
 | 
				
			||||||
 | 
					          if (itm->result_type() != STRING_RESULT)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            skip_column= TRUE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          else if (itm->is_datetime())
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            datetime_found= TRUE;
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
 | 
					              Internally all DATE/DATETIME values are converted to the DATETIME
 | 
				
			||||||
 | 
					              type. So try to find a DATETIME item to issue correct warnings.
 | 
				
			||||||
 | 
					            */
 | 
				
			||||||
 | 
					            if (!date_arg)
 | 
				
			||||||
 | 
					              date_arg= itm;
 | 
				
			||||||
 | 
					            else if (itm->field_type() == MYSQL_TYPE_DATETIME)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              date_arg= itm;
 | 
				
			||||||
 | 
					              /* All arguments are already checked to have the STRING result. */
 | 
				
			||||||
 | 
					              if (cmp_type == STRING_RESULT)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (skip_column)
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					        if (datetime_found)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (cmp_type == ROW_RESULT)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            cmp_item **cmp= 0;
 | 
				
			||||||
 | 
					            if (array)
 | 
				
			||||||
 | 
					              cmp= ((in_row*)array)->tmp.comparators + col;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
 | 
				
			||||||
 | 
					            *cmp= new cmp_item_datetime(date_arg);
 | 
				
			||||||
 | 
					            /* Reset variables for the next column. */
 | 
				
			||||||
 | 
					            date_arg= 0;
 | 
				
			||||||
 | 
					            datetime_found= FALSE;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            compare_as_datetime= TRUE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
    Row item with NULLs inside can return NULL or FALSE =>
 | 
					    Row item with NULLs inside can return NULL or FALSE =>
 | 
				
			||||||
    they can't be processed as static
 | 
					    they can't be processed as static
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  if (type_cnt == 1 && const_itm && !nulls_in_row())
 | 
					  if (type_cnt == 1 && const_itm && !nulls_in_row())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (compare_as_datetime)
 | 
				
			||||||
 | 
					      array= new in_datetime(date_arg, arg_count - 1);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      /*
 | 
					      /*
 | 
				
			||||||
      IN must compare INT/DATE/DATETIME/TIMESTAMP columns and constants
 | 
					        IN must compare INT columns and constants as int values (the same
 | 
				
			||||||
      as int values (the same way as equality does).
 | 
					        way as equality does).
 | 
				
			||||||
        So we must check here if the column on the left and all the constant 
 | 
					        So we must check here if the column on the left and all the constant 
 | 
				
			||||||
        values on the right can be compared as integers and adjust the 
 | 
					        values on the right can be compared as integers and adjust the 
 | 
				
			||||||
        comparison type accordingly.
 | 
					        comparison type accordingly.
 | 
				
			||||||
@@ -3253,7 +3400,12 @@ void Item_func_in::fix_length_and_dec()
 | 
				
			|||||||
        array= new in_double(arg_count-1);
 | 
					        array= new in_double(arg_count-1);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case ROW_RESULT:
 | 
					      case ROW_RESULT:
 | 
				
			||||||
      array= new in_row(arg_count - 1, args[0]);
 | 
					        /*
 | 
				
			||||||
 | 
					          The row comparator was created at the beginning but only DATETIME
 | 
				
			||||||
 | 
					          items comparators were initialized. Call store_value() to setup
 | 
				
			||||||
 | 
					          others.
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        ((in_row*)array)->tmp.store_value(args[0]);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case DECIMAL_RESULT:
 | 
					      case DECIMAL_RESULT:
 | 
				
			||||||
        array= new in_decimal(arg_count - 1);
 | 
					        array= new in_decimal(arg_count - 1);
 | 
				
			||||||
@@ -3262,6 +3414,7 @@ void Item_func_in::fix_length_and_dec()
 | 
				
			|||||||
        DBUG_ASSERT(0);
 | 
					        DBUG_ASSERT(0);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (array && !(thd->is_fatal_error))		// If not EOM
 | 
					    if (array && !(thd->is_fatal_error))		// If not EOM
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      uint j=0;
 | 
					      uint j=0;
 | 
				
			||||||
@@ -3278,21 +3431,27 @@ void Item_func_in::fix_length_and_dec()
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (compare_as_datetime)
 | 
				
			||||||
 | 
					      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
 | 
					      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (found_types & (1 << i) && !cmp_items[i])
 | 
					        if (found_types & (1 << i) && !cmp_items[i])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          if ((Item_result)i == STRING_RESULT &&
 | 
					          if ((Item_result)i == STRING_RESULT &&
 | 
				
			||||||
            agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
 | 
					              agg_arg_charsets(cmp_collation, args, arg_count,
 | 
				
			||||||
 | 
					                               MY_COLL_CMP_CONV, 1))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        if (!(cmp_items[i]=
 | 
					          if (!cmp_items[i] && !(cmp_items[i]=
 | 
				
			||||||
              cmp_item::get_comparator((Item_result)i,
 | 
					              cmp_item::get_comparator((Item_result)i,
 | 
				
			||||||
                                       cmp_collation.collation)))
 | 
					                                       cmp_collation.collation)))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  max_length= 1;
 | 
					  max_length= 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -798,6 +798,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class in_longlong :public in_vector
 | 
					class in_longlong :public in_vector
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
    Here we declare a temporary variable (tmp) of the same type as the
 | 
					    Here we declare a temporary variable (tmp) of the same type as the
 | 
				
			||||||
    elements of this vector. tmp is used in finding if a given value is in 
 | 
					    elements of this vector. tmp is used in finding if a given value is in 
 | 
				
			||||||
@@ -832,6 +833,30 @@ public:
 | 
				
			|||||||
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
 | 
					  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  Class to represent a vector of constant DATE/DATETIME values.
 | 
				
			||||||
 | 
					  Values are obtained with help of the get_datetime_value() function.
 | 
				
			||||||
 | 
					  If the left item is a constant one then its value is cached in the
 | 
				
			||||||
 | 
					  lval_cache variable.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					class in_datetime :public in_longlong
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  THD *thd;
 | 
				
			||||||
 | 
					  /* An item used to issue warnings. */
 | 
				
			||||||
 | 
					  Item *warn_item;
 | 
				
			||||||
 | 
					  /* Cache for the left item. */
 | 
				
			||||||
 | 
					  Item *lval_cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  in_datetime(Item *warn_item_arg, uint elements)
 | 
				
			||||||
 | 
					    :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
 | 
				
			||||||
 | 
					     lval_cache(0) {};
 | 
				
			||||||
 | 
					  void set(uint pos,Item *item);
 | 
				
			||||||
 | 
					  byte *get_value(Item *item);
 | 
				
			||||||
 | 
					  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class in_double :public in_vector
 | 
					class in_double :public in_vector
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  double tmp;
 | 
					  double tmp;
 | 
				
			||||||
@@ -964,6 +989,30 @@ public:
 | 
				
			|||||||
  cmp_item *make_same();
 | 
					  cmp_item *make_same();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  Compare items in the DATETIME context.
 | 
				
			||||||
 | 
					  Values are obtained with help of the get_datetime_value() function.
 | 
				
			||||||
 | 
					  If the left item is a constant one then its value is cached in the
 | 
				
			||||||
 | 
					  lval_cache variable.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					class cmp_item_datetime :public cmp_item
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ulonglong value;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  THD *thd;
 | 
				
			||||||
 | 
					  /* Item used for issuing warnings. */
 | 
				
			||||||
 | 
					  Item *warn_item;
 | 
				
			||||||
 | 
					  /* Cache for the left item. */
 | 
				
			||||||
 | 
					  Item *lval_cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cmp_item_datetime(Item *warn_item_arg)
 | 
				
			||||||
 | 
					    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
 | 
				
			||||||
 | 
					  void store_value(Item *item);
 | 
				
			||||||
 | 
					  int cmp(Item *arg);
 | 
				
			||||||
 | 
					  int compare(cmp_item *ci);
 | 
				
			||||||
 | 
					  cmp_item *make_same();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cmp_item_real :public cmp_item
 | 
					class cmp_item_real :public cmp_item
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  double value;
 | 
					  double value;
 | 
				
			||||||
@@ -998,32 +1047,6 @@ public:
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cmp_item_row :public cmp_item
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  cmp_item **comparators;
 | 
					 | 
				
			||||||
  uint n;
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  cmp_item_row(): comparators(0), n(0) {}
 | 
					 | 
				
			||||||
  ~cmp_item_row();
 | 
					 | 
				
			||||||
  void store_value(Item *item);
 | 
					 | 
				
			||||||
  int cmp(Item *arg);
 | 
					 | 
				
			||||||
  int compare(cmp_item *arg);
 | 
					 | 
				
			||||||
  cmp_item *make_same();
 | 
					 | 
				
			||||||
  void store_value_by_template(cmp_item *tmpl, Item *);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class in_row :public in_vector
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  cmp_item_row tmp;
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  in_row(uint elements, Item *);
 | 
					 | 
				
			||||||
  ~in_row();
 | 
					 | 
				
			||||||
  void set(uint pos,Item *item);
 | 
					 | 
				
			||||||
  byte *get_value(Item *item);
 | 
					 | 
				
			||||||
  Item_result result_type() { return ROW_RESULT; }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
   cmp_item for optimized IN with row (right part string, which never
 | 
					   cmp_item for optimized IN with row (right part string, which never
 | 
				
			||||||
   be changed)
 | 
					   be changed)
 | 
				
			||||||
@@ -1163,7 +1186,7 @@ public:
 | 
				
			|||||||
  */
 | 
					  */
 | 
				
			||||||
  bool arg_types_compatible;
 | 
					  bool arg_types_compatible;
 | 
				
			||||||
  Item_result left_result_type;
 | 
					  Item_result left_result_type;
 | 
				
			||||||
  cmp_item *cmp_items[5]; /* One cmp_item for each result type */
 | 
					  cmp_item *cmp_items[6]; /* One cmp_item for each result type */
 | 
				
			||||||
  DTCollation cmp_collation;
 | 
					  DTCollation cmp_collation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Item_func_in(List<Item> &list)
 | 
					  Item_func_in(List<Item> &list)
 | 
				
			||||||
@@ -1184,7 +1207,7 @@ public:
 | 
				
			|||||||
    Item_int_func::cleanup();
 | 
					    Item_int_func::cleanup();
 | 
				
			||||||
    delete array;
 | 
					    delete array;
 | 
				
			||||||
    array= 0;
 | 
					    array= 0;
 | 
				
			||||||
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 | 
					    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      delete cmp_items[i];
 | 
					      delete cmp_items[i];
 | 
				
			||||||
      cmp_items[i]= 0;
 | 
					      cmp_items[i]= 0;
 | 
				
			||||||
@@ -1202,6 +1225,35 @@ public:
 | 
				
			|||||||
  bool check_partition_func_processor(byte *int_arg) {return FALSE;}
 | 
					  bool check_partition_func_processor(byte *int_arg) {return FALSE;}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class cmp_item_row :public cmp_item
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  cmp_item **comparators;
 | 
				
			||||||
 | 
					  uint n;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  cmp_item_row(): comparators(0), n(0) {}
 | 
				
			||||||
 | 
					  ~cmp_item_row();
 | 
				
			||||||
 | 
					  void store_value(Item *item);
 | 
				
			||||||
 | 
					  inline void alloc_comparators();
 | 
				
			||||||
 | 
					  int cmp(Item *arg);
 | 
				
			||||||
 | 
					  int compare(cmp_item *arg);
 | 
				
			||||||
 | 
					  cmp_item *make_same();
 | 
				
			||||||
 | 
					  void store_value_by_template(cmp_item *tmpl, Item *);
 | 
				
			||||||
 | 
					  friend void Item_func_in::fix_length_and_dec();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class in_row :public in_vector
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  cmp_item_row tmp;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  in_row(uint elements, Item *);
 | 
				
			||||||
 | 
					  ~in_row();
 | 
				
			||||||
 | 
					  void set(uint pos,Item *item);
 | 
				
			||||||
 | 
					  byte *get_value(Item *item);
 | 
				
			||||||
 | 
					  friend void Item_func_in::fix_length_and_dec();
 | 
				
			||||||
 | 
					  Item_result result_type() { return ROW_RESULT; };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Functions used by where clause */
 | 
					/* Functions used by where clause */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Item_func_isnull :public Item_bool_func
 | 
					class Item_func_isnull :public Item_bool_func
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2344,7 +2344,7 @@ double Item_func_min_max::val_real()
 | 
				
			|||||||
  double value=0.0;
 | 
					  double value=0.0;
 | 
				
			||||||
  if (compare_as_dates)
 | 
					  if (compare_as_dates)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    ulonglong result;
 | 
					    ulonglong result= 0;
 | 
				
			||||||
    (void)cmp_datetimes(&result);
 | 
					    (void)cmp_datetimes(&result);
 | 
				
			||||||
    return (double)result;
 | 
					    return (double)result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -2371,7 +2371,7 @@ longlong Item_func_min_max::val_int()
 | 
				
			|||||||
  longlong value=0;
 | 
					  longlong value=0;
 | 
				
			||||||
  if (compare_as_dates)
 | 
					  if (compare_as_dates)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    ulonglong result;
 | 
					    ulonglong result= 0;
 | 
				
			||||||
    (void)cmp_datetimes(&result);
 | 
					    (void)cmp_datetimes(&result);
 | 
				
			||||||
    return (longlong)result;
 | 
					    return (longlong)result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -2400,7 +2400,7 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (compare_as_dates)
 | 
					  if (compare_as_dates)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    ulonglong value;
 | 
					    ulonglong value= 0;
 | 
				
			||||||
    (void)cmp_datetimes(&value);
 | 
					    (void)cmp_datetimes(&value);
 | 
				
			||||||
    ulonglong2decimal(value, dec);
 | 
					    ulonglong2decimal(value, dec);
 | 
				
			||||||
    return dec;
 | 
					    return dec;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -724,6 +724,7 @@ public:
 | 
				
			|||||||
  my_decimal *val_decimal(my_decimal *);
 | 
					  my_decimal *val_decimal(my_decimal *);
 | 
				
			||||||
  void fix_length_and_dec();
 | 
					  void fix_length_and_dec();
 | 
				
			||||||
  enum Item_result result_type () const { return cmp_type; }
 | 
					  enum Item_result result_type () const { return cmp_type; }
 | 
				
			||||||
 | 
					  bool result_as_longlong() { return compare_as_dates; };
 | 
				
			||||||
  bool check_partition_func_processor(byte *int_arg) {return FALSE;}
 | 
					  bool check_partition_func_processor(byte *int_arg) {return FALSE;}
 | 
				
			||||||
  uint cmp_datetimes(ulonglong *value);
 | 
					  uint cmp_datetimes(ulonglong *value);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -605,6 +605,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 | 
				
			|||||||
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
 | 
					        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
 | 
				
			||||||
                            ER_WARN_TOO_FEW_RECORDS, 
 | 
					                            ER_WARN_TOO_FEW_RECORDS, 
 | 
				
			||||||
                            ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 | 
					                            ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 | 
				
			||||||
 | 
					        if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
 | 
				
			||||||
 | 
					            ((Field_timestamp*) field)->set_time();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
@@ -782,6 +784,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 | 
				
			|||||||
                     thd->row_count);
 | 
					                     thd->row_count);
 | 
				
			||||||
            DBUG_RETURN(1);
 | 
					            DBUG_RETURN(1);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
 | 
				
			||||||
 | 
					              ((Field_timestamp*) field)->set_time();
 | 
				
			||||||
          /*
 | 
					          /*
 | 
				
			||||||
            QQ: We probably should not throw warning for each field.
 | 
					            QQ: We probably should not throw warning for each field.
 | 
				
			||||||
            But how about intention to always have the same number
 | 
					            But how about intention to always have the same number
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user