Commit 011d9053 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

merge

parents 734a953e 0cbbca70
......@@ -1812,7 +1812,7 @@ AC_CHECK_FUNCS(alarm bmove \
gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \
tell atod memcpy memmove \
setupterm strcasecmp sighold vidattr lrand48 localtime_r \
setupterm strcasecmp sighold vidattr lrand48 localtime_r gmtime_r \
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
......
......@@ -463,6 +463,9 @@ typedef unsigned long long os_off_t;
/* Define if you have the getwd function. */
#define HAVE_GETWD 1
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define if you have the index function. */
#define HAVE_INDEX 1
......
......@@ -100,6 +100,8 @@ int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att);
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
......@@ -109,6 +111,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#endif
#define pthread_self() win_pthread_self
#define HAVE_LOCALTIME_R 1
#define HAVE_GMTIME_R 1
#define _REENTRANT 1
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
......@@ -276,6 +279,8 @@ extern int my_pthread_create_detached;
#define USE_ALARM_THREAD
#undef HAVE_LOCALTIME_R
#define HAVE_LOCALTIME_R
#undef HAVE_GMTIME_R
#define HAVE_GMTIME_R
#undef HAVE_PTHREAD_ATTR_SETSCOPE
#define HAVE_PTHREAD_ATTR_SETSCOPE
#undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE /* If we are running linux */
......@@ -376,6 +381,10 @@ void *my_pthread_getspecific_imp(pthread_key_t key);
struct tm *localtime_r(const time_t *clock, struct tm *res);
#endif
#ifndef HAVE_GMTIME_R
struct tm *gmtime_r(const time_t *clock, struct tm *res);
#endif
#ifdef HAVE_PTHREAD_CONDATTR_CREATE
/* DCE threads on HPUX 10.20 */
#define pthread_condattr_init pthread_condattr_create
......
CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'тест' as c2;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` char(4) character set utf8 NOT NULL default '',
`c2` char(4) character set utf8 NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
DELETE FROM t1;
ALTER TABLE t1 ADD c3 CHAR(4) CHARACTER SET utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` char(4) character set utf8 NOT NULL default '',
`c2` char(4) character set utf8 NOT NULL default '',
`c3` char(4) character set utf8 default NULL
) TYPE=MyISAM CHARSET=latin1
INSERT INTO t1 VALUES ('aaaabbbbccccdddd','aaaabbbbccccdddd','aaaabbbbccccdddd');
SELECT * FROM t1;
c1 c2 c3
aaaabbbbcccc aaaabbbbcccc aaaabbbbcccc
DROP TABLE t1;
SET CHARACTER SET koi8r;
DROP TABLE IF EXISTS ;
SET CHARACTER SET koi8r;
CREATE TABLE t1 (a CHAR(10) CHARACTER SET cp1251) SELECT _koi8r'' AS a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(10) character set cp1251 default NULL
) TYPE=MyISAM CHARSET=latin1
SELECT a FROM t1;
a
SELECT HEX(a) FROM t1;
HEX(a)
EFF0EEE1E0
DROP TABLE t1;
CREATE TABLE
(
CHAR(32) CHARACTER SET koi8r NOT NULL
......
......@@ -160,3 +160,35 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
drop table t1;
create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id mat_id
100 1
101 1
102 1
103 2
104 2
105 3
SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id test
100 1
101 1
102 1
103 2
104 2
105 3
explain SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m2 index NULL PRIMARY 3 NULL 9 Using index
explain SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m2 index NULL PRIMARY 3 NULL 9 Using index
......@@ -37,3 +37,70 @@ select * from t1 where a like "%abc\d%";
a
abcd
drop table t1;
SET NAMES koi8r;
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET koi8r);
INSERT INTO t1 VALUES (''),(''),(''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
SELECT * FROM t1 WHERE a LIKE '%%';
a
SELECT * FROM t1 WHERE a LIKE '%%';
a
SELECT * FROM t1 WHERE a LIKE '%';
a
DROP TABLE t1;
......@@ -41,9 +41,9 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`database()` char(102) character set utf8 NOT NULL default '',
`user()` char(231) character set utf8 NOT NULL default '',
`version` char(40) character set utf8 default NULL
`database()` char(34) character set utf8 NOT NULL default '',
`user()` char(77) character set utf8 NOT NULL default '',
`version` char(40) default NULL
) TYPE=MyISAM CHARSET=latin1
drop table t1;
select TRUE,FALSE,NULL;
......
......@@ -465,3 +465,21 @@ select date_add(time,INTERVAL 1 SECOND) from t1;
date_add(time,INTERVAL 1 SECOND)
2006-07-08 00:00:01
drop table t1;
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
1
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0;
strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0
1
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0;
strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0
1
select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0;
strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0
1
select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0;
strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0
1
select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0;
strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0
1
......@@ -1225,6 +1225,18 @@ SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1
'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1')
0
drop table t1;
create table t1 (a int) type=innodb;
create table t2 (a int) type=innodb;
create table t3 (a int) type=innodb;
insert into t1 values (1),(2),(3),(4);
insert into t2 values (10),(20),(30),(40);
insert into t3 values (1),(2),(10),(50);
select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30);
a
1
2
10
drop table t1,t2;
create table t1 (a int not null, b int, primary key (a));
create table t2 (a int not null, primary key (a));
create table t3 (a int not null, b int, primary key (a));
......
CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'тест' as c2;
SHOW CREATE TABLE t1;
DELETE FROM t1;
ALTER TABLE t1 ADD c3 CHAR(4) CHARACTER SET utf8;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('aaaabbbbccccdddd','aaaabbbbccccdddd','aaaabbbbccccdddd');
SELECT * FROM t1;
DROP TABLE t1;
......@@ -4,6 +4,13 @@ SET CHARACTER SET koi8r;
DROP TABLE IF EXISTS ;
--enable_warnings
SET CHARACTER SET koi8r;
CREATE TABLE t1 (a CHAR(10) CHARACTER SET cp1251) SELECT _koi8r'' AS a;
SHOW CREATE TABLE t1;
SELECT a FROM t1;
SELECT HEX(a) FROM t1;
DROP TABLE t1;
CREATE TABLE
(
CHAR(32) CHARACTER SET koi8r NOT NULL
......
......@@ -74,3 +74,19 @@ create table t1 (id int);
insert into t1 values (1),(2),(3);
describe select * from (select * from t1 group by id) bar;
drop table t1;
#
# test->used_keys test for derived tables
#
create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
explain SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
explain SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
drop table t1,t2
......@@ -24,3 +24,23 @@ select * from t1 where a like "%abcd%";
select * from t1 where a like "%abc\d%";
drop table t1;
#
# Test like with non-default character set
#
SET NAMES koi8r;
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET koi8r);
INSERT INTO t1 VALUES (''),(''),(''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
INSERT INTO t1 VALUES (''),(''),(''),('');
SELECT * FROM t1 WHERE a LIKE '%%';
SELECT * FROM t1 WHERE a LIKE '%%';
SELECT * FROM t1 WHERE a LIKE '%';
DROP TABLE t1;
......@@ -220,3 +220,12 @@ select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1;
# The following is not as one would expect...
select date_add(time,INTERVAL 1 SECOND) from t1;
drop table t1;
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
# TZ variable set to GMT-3
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0;
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0;
select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0;
select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0;
select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0;
......@@ -887,3 +887,15 @@ insert into t2 values (1);
update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
DROP TABLE t1, t2;
#
# UNION unlocking test
#
create table t1 (a int) type=innodb;
create table t2 (a int) type=innodb;
create table t3 (a int) type=innodb;
insert into t1 values (1),(2),(3),(4);
insert into t2 values (10),(20),(30),(40);
insert into t3 values (1),(2),(10),(50);
select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30);
drop table t1,t2;
......@@ -133,10 +133,13 @@ int my_sigwait(const sigset_t *set,int *sig)
/* localtime_r for SCO 3.2V4.2 */
#ifndef HAVE_LOCALTIME_R
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
extern pthread_mutex_t LOCK_localtime_r;
#endif
#if !defined(HAVE_LOCALTIME_R)
struct tm *localtime_r(const time_t *clock, struct tm *res)
{
struct tm *tmp;
......@@ -148,6 +151,22 @@ struct tm *localtime_r(const time_t *clock, struct tm *res)
}
#endif
#if !defined(HAVE_GMTIME_R)
/*
Reentrant version of standard gmtime() function.
Needed on some systems which don't implement it.
*/
struct tm *gmtime_r(const time_t *clock, struct tm *res)
{
struct tm *tmp;
pthread_mutex_lock(&LOCK_localtime_r);
tmp= gmtime(clock);
*res= *tmp;
pthread_mutex_unlock(&LOCK_localtime_r);
return res;
}
#endif
/****************************************************************************
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
......
......@@ -31,7 +31,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys);
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
THR_LOCK_net, THR_LOCK_charset;
#ifndef HAVE_LOCALTIME_R
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_t LOCK_localtime_r;
#endif
#ifndef HAVE_GETHOSTBYNAME_R
......@@ -73,7 +73,7 @@ my_bool my_thread_global_init(void)
#if defined( __WIN__) || defined(OS2)
win_pthread_init();
#endif
#ifndef HAVE_LOCALTIME_R
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
#endif
#ifndef HAVE_GETHOSTBYNAME_R
......@@ -103,7 +103,7 @@ void my_thread_global_end(void)
pthread_mutex_destroy(&THR_LOCK_heap);
pthread_mutex_destroy(&THR_LOCK_net);
pthread_mutex_destroy(&THR_LOCK_charset);
#ifndef HAVE_LOCALTIME_R
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_destroy(&LOCK_localtime_r);
#endif
#ifndef HAVE_GETHOSTBYNAME_R
......
......@@ -4012,7 +4012,7 @@ void Field_string::sql_type(String &res) const
(table->db_options_in_use &
HA_OPTION_PACK_RECORD) ?
"varchar" : "char"),
(int) field_length);
(int) field_length / charset()->mbmaxlen);
res.length(length);
}
......@@ -4178,7 +4178,7 @@ void Field_varstring::sql_type(String &res) const
CHARSET_INFO *cs=res.charset();
ulong length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(),"varchar(%u)",
field_length);
field_length / charset()->mbmaxlen);
res.length(length);
}
......@@ -5267,6 +5267,26 @@ bool Field_num::eq_def(Field *field)
** Handling of field and create_field
*****************************************************************************/
void create_field::create_length_to_internal_length(void)
{
switch (sql_type)
{
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
length*= charset->mbmaxlen;
pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ?
FIELD_TYPE_STRING : sql_type, length);
break;
default:
/* do nothing */
break;
}
}
/*
Make a field from the .frm file info
*/
......
......@@ -1066,6 +1066,7 @@ class create_field :public Sql_alloc {
uint offset,pack_flag;
create_field() :after(0) {}
create_field(Field *field, Field *orig_field);
void create_length_to_internal_length(void);
};
......
......@@ -427,7 +427,7 @@ class Item_string :public Item
{
collation.set(cs, dv);
str_value.set(str,length,cs);
max_length=length;
max_length= str_value.numchars()*cs->mbmaxlen;
set_name(str, length, cs);
decimals=NOT_FIXED_DEC;
}
......@@ -436,7 +436,7 @@ class Item_string :public Item
{
collation.set(cs, dv);
str_value.set(str,length,cs);
max_length=length;
max_length= str_value.numchars()*cs->mbmaxlen;
set_name(name_par,0,cs);
decimals=NOT_FIXED_DEC;
}
......
......@@ -2147,7 +2147,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
int shift = pattern_len;
int j = 0;
int u = 0;
CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed
CHARSET_INFO *cs= cmp.cmp_collation.collation; // QQ Needs to be fixed
const int plm1= pattern_len - 1;
const int tlmpl= text_len - pattern_len;
......
......@@ -571,21 +571,21 @@ longlong Item_func_from_days::val_int()
void Item_func_curdate::fix_length_and_dec()
{
struct tm tm_tmp,*start;
time_t query_start=current_thd->query_start();
struct tm start;
collation.set(default_charset());
decimals=0;
max_length=10*default_charset()->mbmaxlen;
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp;
value=(longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
((uint) start->tm_mon+1)*100+
(uint) start->tm_mday);
store_now_in_tm(current_thd->query_start(),&start);
value=(longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
((uint) start.tm_mon+1)*100+
(uint) start.tm_mday);
/* For getdate */
ltime.year= start->tm_year+1900;
ltime.month= start->tm_mon+1;
ltime.day= start->tm_mday;
ltime.year= start.tm_year+1900;
ltime.month= start.tm_mon+1;
ltime.day= start.tm_mday;
ltime.hour= 0;
ltime.minute= 0;
ltime.second= 0;
......@@ -594,6 +594,7 @@ void Item_func_curdate::fix_length_and_dec()
ltime.time_type=TIMESTAMP_DATE;
}
bool Item_func_curdate::get_date(TIME *res,
bool fuzzy_date __attribute__((unused)))
{
......@@ -601,6 +602,27 @@ bool Item_func_curdate::get_date(TIME *res,
return 0;
}
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURDATE function
*/
void Item_func_curdate_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC
Defines timezone (UTC) used for whole UTC_DATE function
*/
void Item_func_curdate_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
}
String *Item_func_curtime::val_str(String *str)
{
str_value.set(buff,buff_length,default_charset());
......@@ -609,23 +631,43 @@ String *Item_func_curtime::val_str(String *str)
void Item_func_curtime::fix_length_and_dec()
{
struct tm tm_tmp,*start;
time_t query_start=current_thd->query_start();
CHARSET_INFO *cs=default_charset();
struct tm start;
CHARSET_INFO *cs= default_charset();
decimals=0;
max_length=8*cs->mbmaxlen;
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp;
collation.set(cs);
value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+
(uint) start->tm_sec));
store_now_in_tm(current_thd->query_start(),&start);
value=(longlong) ((ulong) ((uint) start.tm_hour)*10000L+
(ulong) (((uint) start.tm_min)*100L+
(uint) start.tm_sec));
buff_length=cs->cset->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d",
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec);
(int) start.tm_hour,
(int) start.tm_min,
(int) start.tm_sec);
}
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURTIME function
*/
void Item_func_curtime_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC.
Defines timezone (UTC) used for whole UTC_TIME function
*/
void Item_func_curtime_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
}
......@@ -638,37 +680,37 @@ String *Item_func_now::val_str(String *str)
void Item_func_now::fix_length_and_dec()
{
struct tm tm_tmp,*start;
time_t query_start=current_thd->query_start();
struct tm start;
CHARSET_INFO *cs= &my_charset_bin;
decimals=0;
max_length=19*cs->mbmaxlen;
collation.set(cs);
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp;
value=((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
(((uint) start->tm_mon+1)*100+
(uint) start->tm_mday))*(longlong) 1000000L+
(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+
(uint) start->tm_sec)));
store_now_in_tm(current_thd->query_start(),&start);
value=((longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
(((uint) start.tm_mon+1)*100+
(uint) start.tm_mday))*(longlong) 1000000L+
(longlong) ((ulong) ((uint) start.tm_hour)*10000L+
(ulong) (((uint) start.tm_min)*100L+
(uint) start.tm_sec)));
buff_length= (uint) cs->cset->snprintf(cs,buff, sizeof(buff),
"%04d-%02d-%02d %02d:%02d:%02d",
((int) (start->tm_year+1900)) % 10000,
(int) start->tm_mon+1,
(int) start->tm_mday,
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec);
((int) (start.tm_year+1900)) % 10000,
(int) start.tm_mon+1,
(int) start.tm_mday,
(int) start.tm_hour,
(int) start.tm_min,
(int) start.tm_sec);
/* For getdate */
ltime.year= start->tm_year+1900;
ltime.month= start->tm_mon+1;
ltime.day= start->tm_mday;
ltime.hour= start->tm_hour;
ltime.minute= start->tm_min;
ltime.second= start->tm_sec;
ltime.year= start.tm_year+1900;
ltime.month= start.tm_mon+1;
ltime.day= start.tm_mday;
ltime.hour= start.tm_hour;
ltime.minute= start.tm_min;
ltime.second= start.tm_sec;
ltime.second_part=0;
ltime.neg=0;
ltime.time_type=TIMESTAMP_FULL;
......@@ -690,6 +732,26 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
}
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURRENT_TIMESTAMP function
*/
void Item_func_now_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC.
Defines timezone (UTC) used for whole UTC_TIMESTAMP function
*/
void Item_func_now_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
}
String *Item_func_sec_to_time::val_str(String *str)
{
char buff[23*2];
......
......@@ -350,6 +350,8 @@ class Item_date_func :public Item_str_func
};
/* Abstract CURTIME function. Children should define what timezone is used */
class Item_func_curtime :public Item_func
{
longlong value;
......@@ -363,29 +365,77 @@ class Item_func_curtime :public Item_func
double val() { return (double) value; }
longlong val_int() { return value; }
String *val_str(String *str);
const char *func_name() const { return "curtime"; }
void fix_length_and_dec();
Field *tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg)
{
return (new Field_time(maybe_null, name, t_arg, default_charset()));
}
}
/*
Abstract method that defines which time zone is used for conversion.
Converts time from time_t representation to broken down representation
in struct tm using gmtime_r or localtime_r functions.
*/
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
};
class Item_func_curtime_local :public Item_func_curtime
{
public:
Item_func_curtime_local() :Item_func_curtime() {}
Item_func_curtime_local(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "curtime"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
class Item_func_curtime_utc :public Item_func_curtime
{
public:
Item_func_curtime_utc() :Item_func_curtime() {}
Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "utc_time"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
/* Abstract CURDATE function. See also Item_func_curtime. */
class Item_func_curdate :public Item_date
{
longlong value;
TIME ltime;
public:
Item_func_curdate() :Item_date() {}
void set_result_from_tm(struct tm *now);
longlong val_int() { return (value) ; }
const char *func_name() const { return "curdate"; }
void fix_length_and_dec(); /* Retrieves curtime */
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
};
class Item_func_curdate_local :public Item_func_curdate
{
public:
Item_func_curdate_local() :Item_func_curdate() {}
const char *func_name() const { return "curdate"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
class Item_func_curdate_utc :public Item_func_curdate
{
public:
Item_func_curdate_utc() :Item_func_curdate() {}
const char *func_name() const { return "utc_date"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */
class Item_func_now :public Item_date_func
{
longlong value;
......@@ -400,9 +450,29 @@ class Item_func_now :public Item_date_func
longlong val_int() { return value; }
int save_in_field(Field *to, bool no_conversions);
String *val_str(String *str);
const char *func_name() const { return "now"; }
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
};
class Item_func_now_local :public Item_func_now
{
public:
Item_func_now_local() :Item_func_now() {}
Item_func_now_local(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "now"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
class Item_func_now_utc :public Item_func_now
{
public:
Item_func_now_utc() :Item_func_now() {}
Item_func_now_utc(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "utc_timestamp"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
......
......@@ -404,6 +404,9 @@ static SYMBOL symbols[] = {
{ "USE_FRM", SYM(USE_FRM),0,0},
{ "USER", SYM(USER),0,0},
{ "USING", SYM(USING),0,0},
{ "UTC_DATE", SYM(UTC_DATE_SYM),0,0},
{ "UTC_TIME", SYM(UTC_TIME_SYM),0,0},
{ "UTC_TIMESTAMP", SYM(UTC_TIMESTAMP_SYM),0,0},
{ "UPDATE", SYM(UPDATE_SYM),0,0},
{ "USAGE", SYM(USAGE),0,0},
{ "VALUE", SYM(VALUE_SYM),0,0},
......
......@@ -2078,10 +2078,20 @@ mysql_execute_command(THD *thd)
res= mysql_create_like_table(thd, tables, &lex->create_info,
(Table_ident *)lex->name);
else
{
List_iterator<create_field> fields(lex->create_list);
create_field *field;
while ((field= fields++))
{
if (!field->charset)
field->charset= lex->create_info.table_charset;
field->create_length_to_internal_length();
}
res= mysql_create_table(thd,tables->db ? tables->db : thd->db,
tables->real_name, &lex->create_info,
lex->create_list,
lex->key_list,0,0,0); // do logging
}
if (!res)
send_ok(thd);
}
......@@ -3805,7 +3815,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
break;
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
if (new_field->length < MAX_FIELD_WIDTH || default_value)
if (new_field->length <= MAX_FIELD_CHARLENGTH || default_value)
break;
/* Convert long CHAR() and VARCHAR columns to TEXT or BLOB */
new_field->sql_type= FIELD_TYPE_BLOB;
......@@ -3971,13 +3981,13 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
}
}
if (new_field->length >= MAX_FIELD_WIDTH ||
if (new_field->length > MAX_FIELD_CHARLENGTH ||
(!new_field->length && !(new_field->flags & BLOB_FLAG) &&
type != FIELD_TYPE_STRING &&
type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY))
{
net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name,
MAX_FIELD_WIDTH-1); /* purecov: inspected */
MAX_FIELD_CHARLENGTH); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
type_modifier&= AUTO_INCREMENT_FLAG;
......
......@@ -457,12 +457,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
else
{
/* Field redefined */
sql_field->sql_type= dup_field->sql_type;
sql_field->charset= dup_field->charset ? dup_field->charset : create_info->table_charset;
sql_field->length= dup_field->length;
sql_field->pack_length= dup_field->pack_length;
sql_field->create_length_to_internal_length();
sql_field->decimals= dup_field->decimals;
sql_field->flags= dup_field->flags;
sql_field->pack_length= dup_field->pack_length;
sql_field->unireg_check= dup_field->unireg_check;
sql_field->sql_type= dup_field->sql_type;
it2.remove(); // Remove first (create) definition
select_field_pos--;
break;
......@@ -480,10 +482,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
while ((sql_field=it++))
{
if (!sql_field->charset)
sql_field->charset = create_info->table_charset ?
create_info->table_charset :
thd->variables.character_set_database;
sql_field->charset = create_info->table_charset;
switch (sql_field->sql_type) {
case FIELD_TYPE_BLOB:
case FIELD_TYPE_MEDIUM_BLOB:
......@@ -1891,18 +1890,42 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/* Full alter table */
/* let new create options override the old ones */
if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
create_info->min_rows=table->min_rows;
if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
create_info->max_rows=table->max_rows;
if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
create_info->avg_row_length=table->avg_row_length;
if (!(used_fields & HA_CREATE_USED_CHARSET))
create_info->table_charset=table->table_charset;
restore_record(table,default_values); // Empty record for DEFAULT
List_iterator<Alter_drop> drop_it(drop_list);
List_iterator<create_field> def_it(fields);
List_iterator<Alter_column> alter_it(alter_list);
List<create_field> create_list; // Add new fields here
List<Key> key_list; // Add new keys here
create_field *def;
/*
For each column set charset to the table
default if the column charset hasn't been specified
explicitely. Change CREATE length into internal length
*/
def_it.rewind();
while ((def= def_it++))
{
if (!def->charset)
def->charset= create_info->table_charset;
def->create_length_to_internal_length();
}
/*
First collect all fields from table which isn't in drop_list
*/
create_field *def;
Field **f_ptr,*field;
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
......@@ -2121,16 +2144,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (!create_info->comment)
create_info->comment=table->comment;
/* let new create options override the old ones */
if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
create_info->min_rows=table->min_rows;
if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
create_info->max_rows=table->max_rows;
if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
create_info->avg_row_length=table->avg_row_length;
if (!(used_fields & HA_CREATE_USED_CHARSET))
create_info->table_charset=table->table_charset;
table->file->update_create_info(create_info);
if ((create_info->table_options &
(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
......
......@@ -368,7 +368,8 @@ int st_select_lex_unit::exec()
global_parameters->order_list.elements,
(ORDER*)global_parameters->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result, this, fake_select_lex, 0);
thd->options | SELECT_NO_UNLOCK,
result, this, fake_select_lex, 0);
if (found_rows_for_union && !res)
thd->limit_found_rows = (ulonglong)table->file->records;
/*
......
......@@ -526,6 +526,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UNIQUE_USERS
%token UNIX_TIMESTAMP
%token USER
%token UTC_DATE_SYM
%token UTC_TIME_SYM
%token UTC_TIMESTAMP_SYM
%token WEEK_SYM
%token WHEN_SYM
%token WORK_SYM
......@@ -1915,7 +1918,8 @@ select:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SELECT;
lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
};
}
;
/* Need select_init2 for subselects. */
select_init:
......@@ -2372,12 +2376,12 @@ simple_expr:
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
| CURDATE optional_braces
{ $$= new Item_func_curdate(); Lex->safe_to_cache_query=0; }
{ $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; }
| CURTIME optional_braces
{ $$= new Item_func_curtime(); Lex->safe_to_cache_query=0; }
{ $$= new Item_func_curtime_local(); Lex->safe_to_cache_query=0; }
| CURTIME '(' expr ')'
{
$$= new Item_func_curtime($3);
$$= new Item_func_curtime_local($3);
Lex->safe_to_cache_query=0;
}
| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
......@@ -2539,9 +2543,9 @@ simple_expr:
{ $$= new Item_func_spatial_collection(* $3,
Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); }
| NOW_SYM optional_braces
{ $$= new Item_func_now(); Lex->safe_to_cache_query=0;}
{ $$= new Item_func_now_local(); Lex->safe_to_cache_query=0;}
| NOW_SYM '(' expr ')'
{ $$= new Item_func_now($3); Lex->safe_to_cache_query=0;}
{ $$= new Item_func_now_local($3); Lex->safe_to_cache_query=0;}
| PASSWORD '(' expr ')'
{ $$= new Item_func_password($3); }
| PASSWORD '(' expr ',' expr ')'
......@@ -2669,6 +2673,12 @@ simple_expr:
{ $$= new Item_func_unix_timestamp($3); }
| USER '(' ')'
{ $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
| UTC_DATE_SYM optional_braces
{ $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
| UTC_TIME_SYM optional_braces
{ $$= new Item_func_curtime_utc(); Lex->safe_to_cache_query=0;}
| UTC_TIMESTAMP_SYM optional_braces
{ $$= new Item_func_now_utc(); Lex->safe_to_cache_query=0;}
| WEEK_SYM '(' expr ')'
{
$$= new Item_func_week($3,new Item_int((char*) "0",
......
......@@ -58,7 +58,12 @@
#endif
#define MAX_HOSTNAME 61 /* len+1 in mysql.user */
#define MAX_FIELD_WIDTH 256 /* Max column width +1 */
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FIELD_CHARLENGTH 255
/* Max column width +1 */
#define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1)
#define MAX_TABLES (sizeof(table_map)*8-2) /* Max tables in join */
#define OUTER_REF_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-2))
#define RAND_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-1))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment