mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Cleanups & safety fixes
include/mysql.h: cleanup of load data infile patch libmysql/libmysql.c: cleanup of load data infile patch myisam/mi_search.c: Added missing assert.h mysql-test/r/func_time.result: Make test more secure mysql-test/t/func_time.test: Make test more secure sql/item.cc: restore to use str_value in item::save_in_field sql/item.h: Simple cleanup sql/item_cmpfunc.cc: Safety fix sql/item_cmpfunc.h: Simple optimization sql/item_func.cc: Updated comment sql/sql_base.cc: Simple optimization sql/sql_select.cc: Simple optimization sql/sql_union.cc: safey fixes
This commit is contained in:
@ -187,9 +187,9 @@ struct st_mysql_options {
|
|||||||
my_bool secure_auth;
|
my_bool secure_auth;
|
||||||
|
|
||||||
/* function pointers for local infile support */
|
/* function pointers for local infile support */
|
||||||
int (*local_infile_init)(void **, char *);
|
int (*local_infile_init)(void **, const char *);
|
||||||
int (*local_infile_read)(void *, char *, uint);
|
int (*local_infile_read)(void *, char *, uint);
|
||||||
int (*local_infile_end)(void *);
|
void (*local_infile_end)(void *);
|
||||||
int (*local_infile_error)(void *, char *, uint);
|
int (*local_infile_error)(void *, char *, uint);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -394,12 +394,12 @@ my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
|
|||||||
|
|
||||||
#define LOCAL_INFILE_ERROR_LEN 512
|
#define LOCAL_INFILE_ERROR_LEN 512
|
||||||
|
|
||||||
int
|
void
|
||||||
mysql_set_local_infile_handler(MYSQL *mysql,
|
mysql_set_local_infile_handler(MYSQL *mysql,
|
||||||
int (*local_infile_init)(void **, char *),
|
int (*local_infile_init)(void **, const char *),
|
||||||
int (*local_infile_read)(void *, char *, uint),
|
int (*local_infile_read)(void *, char *, uint),
|
||||||
int (*local_infile_end)(void *),
|
void (*local_infile_end)(void *),
|
||||||
int (*local_infile_error)(void *, char *, uint));
|
int (*local_infile_error)(void *, char*, uint));
|
||||||
|
|
||||||
void
|
void
|
||||||
mysql_set_local_infile_default(MYSQL *mysql);
|
mysql_set_local_infile_default(MYSQL *mysql);
|
||||||
|
@ -799,54 +799,51 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
|
|||||||
my_bool result= 1;
|
my_bool result= 1;
|
||||||
uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
|
uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
int error;
|
|
||||||
int readcount;
|
int readcount;
|
||||||
void *li_ptr; /* pass state to local_infile functions */
|
void *li_ptr; /* pass state to local_infile functions */
|
||||||
char *buf = NULL; /* buffer to be filled by local_infile_read */
|
char *buf;; /* buffer to be filled by local_infile_read */
|
||||||
char *filename = NULL; /* local copy of filename arg */
|
struct st_mysql_options *options= &mysql->options;
|
||||||
|
|
||||||
DBUG_ENTER("handle_local_infile");
|
DBUG_ENTER("handle_local_infile");
|
||||||
|
|
||||||
/* check that we've got valid callback functions */
|
/* check that we've got valid callback functions */
|
||||||
if (!((mysql->options.local_infile_init) &&
|
if (!(options->local_infile_init &&
|
||||||
(mysql->options.local_infile_read) &&
|
options->local_infile_read &&
|
||||||
(mysql->options.local_infile_end) &&
|
options->local_infile_end &&
|
||||||
(mysql->options.local_infile_error)))
|
options->local_infile_error))
|
||||||
{
|
{
|
||||||
/* if any of the functions is invalid, set the default */
|
/* if any of the functions is invalid, set the default */
|
||||||
mysql_set_local_infile_default(mysql);
|
mysql_set_local_infile_default(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy filename into local memory and allocate read buffer */
|
/* copy filename into local memory and allocate read buffer */
|
||||||
if ((!(filename = my_strdup(net_filename, MYF(0)))) ||
|
if (!(buf=my_malloc(packet_length, MYF(0))))
|
||||||
(!(buf=my_malloc(packet_length, MYF(0)))))
|
{
|
||||||
goto oom;
|
strmov(net->sqlstate, unknown_sqlstate);
|
||||||
|
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize local infile (open file, usually) */
|
/* initialize local infile (open file, usually) */
|
||||||
if ( (error = (*mysql->options.local_infile_init)(&li_ptr, filename)) )
|
if ((*options->local_infile_init)(&li_ptr, net_filename))
|
||||||
{
|
{
|
||||||
my_net_write(net,"",0); /* Server needs one packet */
|
my_net_write(net,"",0); /* Server needs one packet */
|
||||||
net_flush(net);
|
net_flush(net);
|
||||||
if(error < 0)
|
|
||||||
goto oom;
|
|
||||||
strmov(net->sqlstate, unknown_sqlstate);
|
strmov(net->sqlstate, unknown_sqlstate);
|
||||||
net->last_errno=error;
|
net->last_errno= (*options->local_infile_error)(li_ptr,
|
||||||
(*mysql->options.local_infile_error)(li_ptr,
|
net->last_error,
|
||||||
net->last_error,
|
sizeof(net->last_error)-1);
|
||||||
sizeof(net->last_error)-1);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read blocks of data from local infile callback */
|
/* read blocks of data from local infile callback */
|
||||||
while ( (readcount =
|
while ((readcount =
|
||||||
(*mysql->options.local_infile_read)(li_ptr,
|
(*options->local_infile_read)(li_ptr, buf,
|
||||||
buf,
|
packet_length)) > 0)
|
||||||
packet_length) ) > 0)
|
|
||||||
{
|
{
|
||||||
if (my_net_write(net,buf,readcount))
|
if (my_net_write(net,buf,readcount))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
|
DBUG_PRINT("error",
|
||||||
|
("Lost connection to MySQL server during LOAD DATA of local file"));
|
||||||
strmov(net->sqlstate, unknown_sqlstate);
|
strmov(net->sqlstate, unknown_sqlstate);
|
||||||
net->last_errno=CR_SERVER_LOST;
|
net->last_errno=CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
@ -865,10 +862,9 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
|
|||||||
|
|
||||||
if (readcount < 0)
|
if (readcount < 0)
|
||||||
{
|
{
|
||||||
strmov(net->sqlstate, unknown_sqlstate);
|
net->last_errno= (*options->local_infile_error)(li_ptr,
|
||||||
net->last_errno=EE_READ; /* the errmsg for not entire file read */
|
net->last_error,
|
||||||
my_snprintf(net->last_error,sizeof(net->last_error)-1,
|
sizeof(net->last_error)-1);
|
||||||
filename, errno);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -876,117 +872,165 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
/* free up memory allocated with _init, usually */
|
/* free up memory allocated with _init, usually */
|
||||||
(*mysql->options.local_infile_end)(li_ptr);
|
(*options->local_infile_end)(li_ptr);
|
||||||
|
|
||||||
my_free(filename, MYF(0));
|
|
||||||
my_free(buf, MYF(0));
|
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
|
|
||||||
oom:
|
|
||||||
/* out of memory */
|
|
||||||
my_free(filename, MYF(MY_ALLOW_ZERO_PTR));
|
|
||||||
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
|
||||||
strmov(net->sqlstate, unknown_sqlstate);
|
|
||||||
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct default_local_infile_st {
|
/****************************************************************************
|
||||||
|
Default handlers for LOAD LOCAL INFILE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct st_default_local_infile
|
||||||
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int error_num;
|
int error_num;
|
||||||
|
const char *filename;
|
||||||
char error_msg[LOCAL_INFILE_ERROR_LEN];
|
char error_msg[LOCAL_INFILE_ERROR_LEN];
|
||||||
} default_local_infile_data;
|
} default_local_infile_data;
|
||||||
|
|
||||||
|
|
||||||
int
|
/*
|
||||||
default_local_infile_init(void **ptr, char *filename)
|
Open file for LOAD LOCAL INFILE
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
default_local_infile_init()
|
||||||
|
ptr Store pointer to internal data here
|
||||||
|
filename File name to open. This may be in unix format !
|
||||||
|
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Even if this function returns an error, the load data interface
|
||||||
|
guarantees that default_local_infile_end() is called.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int default_local_infile_init(void **ptr, const char *filename)
|
||||||
{
|
{
|
||||||
default_local_infile_data *data;
|
default_local_infile_data *data;
|
||||||
|
char tmp_name[FN_REFLEN];
|
||||||
|
|
||||||
if (!(*ptr= data= ((default_local_infile_data *)
|
if (!(*ptr= data= ((default_local_infile_data *)
|
||||||
my_malloc(sizeof(default_local_infile_data), MYF(0)))))
|
my_malloc(sizeof(default_local_infile_data), MYF(0)))))
|
||||||
return -1; /* out of memory */
|
return 1; /* out of memory */
|
||||||
|
|
||||||
*ptr = data; /* save the struct, we need it to return an error */
|
|
||||||
|
|
||||||
data->error_msg[0]= 0;
|
data->error_msg[0]= 0;
|
||||||
data->error_num= 0;
|
data->error_num= 0;
|
||||||
|
data->filename= filename;
|
||||||
|
|
||||||
if ((data->fd = my_open(filename, O_RDONLY, MYF(0))) < 0)
|
fn_format(tmp_name, filename, "", "", MY_UNPACK_FILENAME);
|
||||||
|
if ((data->fd = my_open(tmp_name, O_RDONLY, MYF(0))) < 0)
|
||||||
{
|
{
|
||||||
|
data->error_num= my_errno;
|
||||||
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
|
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
|
||||||
EE(EE_FILENOTFOUND), filename, errno);
|
EE(EE_FILENOTFOUND), tmp_name, data->error_num);
|
||||||
return data->error_num=errno; /* error */
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* ok */
|
return 0; /* ok */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
/*
|
||||||
default_local_infile_read(void *ptr, char *buf, uint buf_len)
|
Read data for LOAD LOCAL INFILE
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
default_local_infile_read()
|
||||||
|
ptr Points to handle allocated by _init
|
||||||
|
buf Read data here
|
||||||
|
buf_len Ammount of data to read
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
> 0 number of bytes read
|
||||||
|
== 0 End of data
|
||||||
|
< 0 Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int default_local_infile_read(void *ptr, char *buf, uint buf_len)
|
||||||
{
|
{
|
||||||
default_local_infile_data *data = (default_local_infile_data *) ptr;
|
int count;
|
||||||
|
default_local_infile_data*data = (default_local_infile_data *) ptr;
|
||||||
|
|
||||||
return ((int) my_read(data->fd, (byte *)buf, buf_len, MYF(0)));
|
if ((count= (int) my_read(data->fd, (byte *) buf, buf_len, MYF(0))) < 0)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
default_local_infile_end(void *ptr)
|
|
||||||
{
|
|
||||||
default_local_infile_data *data = (default_local_infile_data *) ptr;
|
|
||||||
if(data)
|
|
||||||
{
|
{
|
||||||
my_close(data->fd, MYF(0));
|
data->error_num= EE_READ; /* the errmsg for not entire file read */
|
||||||
my_free(ptr, MYF(0));
|
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
|
||||||
|
EE(EE_READ),
|
||||||
|
data->filename, my_errno);
|
||||||
}
|
}
|
||||||
return 0;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
/*
|
||||||
|
Read data for LOAD LOCAL INFILE
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
default_local_infile_end()
|
||||||
|
ptr Points to handle allocated by _init
|
||||||
|
May be NULL if _init failed!
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void default_local_infile_end(void *ptr)
|
||||||
|
{
|
||||||
|
default_local_infile_data *data= (default_local_infile_data *) ptr;
|
||||||
|
if (data) /* If not error on open */
|
||||||
|
{
|
||||||
|
if (data->fd >= 0)
|
||||||
|
my_close(data->fd, MYF(MY_WME));
|
||||||
|
my_free(ptr, MYF(MY_WME));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return error from LOAD LOCAL INFILE
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
default_local_infile_end()
|
||||||
|
ptr Points to handle allocated by _init
|
||||||
|
May be NULL if _init failed!
|
||||||
|
error_msg Store error text here
|
||||||
|
error_msg_len Max lenght of error_msg
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
error message number
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
|
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
|
||||||
{
|
{
|
||||||
default_local_infile_data *data = (default_local_infile_data *) ptr;
|
default_local_infile_data *data = (default_local_infile_data *) ptr;
|
||||||
|
if (data) /* If not error on open */
|
||||||
if(data) {
|
{
|
||||||
strmake(error_msg, data->error_msg, error_msg_len);
|
strmake(error_msg, data->error_msg, error_msg_len);
|
||||||
return data->error_num;
|
return data->error_num;
|
||||||
}
|
}
|
||||||
else
|
/* This can only happen if we got error on malloc of handle */
|
||||||
{
|
strmov(error_msg, ER(CR_OUT_OF_MEMORY));
|
||||||
strmake(error_msg, "Internal error", error_msg_len);
|
return CR_OUT_OF_MEMORY;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
mysql_set_local_infile_handler(MYSQL *mysql,
|
|
||||||
int (*local_infile_init)(void **, char *),
|
|
||||||
int (*local_infile_read)(void *, char *, uint),
|
|
||||||
int (*local_infile_end)(void *),
|
|
||||||
int (*local_infile_error)(void *, char *, uint))
|
|
||||||
{
|
|
||||||
if(mysql &&
|
|
||||||
local_infile_init &&
|
|
||||||
local_infile_read &&
|
|
||||||
local_infile_end &&
|
|
||||||
local_infile_error) {
|
|
||||||
mysql->options.local_infile_init= local_infile_init;
|
|
||||||
mysql->options.local_infile_read= local_infile_read;
|
|
||||||
mysql->options.local_infile_end= local_infile_end;
|
|
||||||
mysql->options.local_infile_error= local_infile_error;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mysql_set_local_infile_default(MYSQL *mysql)
|
mysql_set_local_infile_handler(MYSQL *mysql,
|
||||||
|
int (*local_infile_init)(void **, const char *),
|
||||||
|
int (*local_infile_read)(void *, char *, uint),
|
||||||
|
void (*local_infile_end)(void *),
|
||||||
|
int (*local_infile_error)(void *, char *, uint))
|
||||||
|
{
|
||||||
|
mysql->options.local_infile_init= local_infile_init;
|
||||||
|
mysql->options.local_infile_read= local_infile_read;
|
||||||
|
mysql->options.local_infile_end= local_infile_end;
|
||||||
|
mysql->options.local_infile_error= local_infile_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mysql_set_local_infile_default(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
mysql->options.local_infile_init= default_local_infile_init;
|
mysql->options.local_infile_init= default_local_infile_init;
|
||||||
mysql->options.local_infile_read= default_local_infile_read;
|
mysql->options.local_infile_read= default_local_infile_read;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "fulltext.h"
|
#include "fulltext.h"
|
||||||
#include "m_ctype.h"
|
#include "m_ctype.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
|
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
|
||||||
uchar *key, uchar *keypos,
|
uchar *key, uchar *keypos,
|
||||||
|
@ -555,11 +555,12 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select high_priority no_cache period_add(_latin1'9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,_latin1'9404') AS `period_diff(199505,"9404")`,from_days(to_days(_latin1'960101')) AS `from_days(to_days("960101"))`,dayofmonth(_latin1'1997-01-02') AS `dayofmonth("1997-01-02")`,month(_latin1'1997-01-02') AS `month("1997-01-02")`,monthname(_latin1'1972-03-04') AS `monthname("1972-03-04")`,dayofyear(_latin1'0000-00-00') AS `dayofyear("0000-00-00")`,hour(_latin1'1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute(_latin1'23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week(_latin1'1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek(_latin1'2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year(_latin1'98-02-03') AS `year("98-02-03")`,(weekday(to_days(curdate())) - weekday(to_days(now()))) AS `weekday(curdate())-weekday(now())`,dayname(to_days(_latin1'1962-03-03')) AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec(_latin1'0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format(_latin1'1997-01-02 03:04:05',_latin1'%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp(_latin1'1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,(_latin1'1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,(_latin1'1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from _latin1'1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
|
Note 1003 select high_priority no_cache period_add(_latin1'9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,_latin1'9404') AS `period_diff(199505,"9404")`,from_days(to_days(_latin1'960101')) AS `from_days(to_days("960101"))`,dayofmonth(_latin1'1997-01-02') AS `dayofmonth("1997-01-02")`,month(_latin1'1997-01-02') AS `month("1997-01-02")`,monthname(_latin1'1972-03-04') AS `monthname("1972-03-04")`,dayofyear(_latin1'0000-00-00') AS `dayofyear("0000-00-00")`,hour(_latin1'1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute(_latin1'23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week(_latin1'1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek(_latin1'2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year(_latin1'98-02-03') AS `year("98-02-03")`,(weekday(to_days(curdate())) - weekday(to_days(now()))) AS `weekday(curdate())-weekday(now())`,dayname(to_days(_latin1'1962-03-03')) AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec(_latin1'0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format(_latin1'1997-01-02 03:04:05',_latin1'%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp(_latin1'1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,(_latin1'1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,(_latin1'1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from _latin1'1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
|
||||||
|
SET @TMP=NOW();
|
||||||
CREATE TABLE t1 (d DATETIME);
|
CREATE TABLE t1 (d DATETIME);
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(NOW())) AND d<=FROM_DAYS(TO_DAYS(NOW())+1);
|
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(@TMP)) AND d<=FROM_DAYS(TO_DAYS(@TMP)+1);
|
||||||
count(*)
|
count(*)
|
||||||
3
|
3
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -273,10 +273,11 @@ select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0;
|
|||||||
|
|
||||||
explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_days(to_days("960101")),dayofmonth("1997-01-02"), month("1997-01-02"), monthname("1972-03-04"),dayofyear("0000-00-00"),HOUR("1997-03-03 23:03:22"),MINUTE("23:03:22"),SECOND(230322),QUARTER(980303),WEEK("1998-03-03"),yearweek("2000-01-01",1),week(19950101,1),year("98-02-03"),weekday(curdate())-weekday(now()),dayname("1962-03-03"),unix_timestamp(),sec_to_time(time_to_sec("0:30:47")/6.21),curtime(),utc_time(),curdate(),utc_date(),utc_timestamp(),date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"),from_unixtime(unix_timestamp("1994-03-02 10:11:12")),"1997-12-31 23:59:59" + INTERVAL 1 SECOND,"1998-01-01 00:00:00" - INTERVAL 1 SECOND,INTERVAL 1 DAY + "1997-12-31", extract(YEAR FROM "1999-01-02 10:11:12"),date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
|
explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_days(to_days("960101")),dayofmonth("1997-01-02"), month("1997-01-02"), monthname("1972-03-04"),dayofyear("0000-00-00"),HOUR("1997-03-03 23:03:22"),MINUTE("23:03:22"),SECOND(230322),QUARTER(980303),WEEK("1998-03-03"),yearweek("2000-01-01",1),week(19950101,1),year("98-02-03"),weekday(curdate())-weekday(now()),dayname("1962-03-03"),unix_timestamp(),sec_to_time(time_to_sec("0:30:47")/6.21),curtime(),utc_time(),curdate(),utc_date(),utc_timestamp(),date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"),from_unixtime(unix_timestamp("1994-03-02 10:11:12")),"1997-12-31 23:59:59" + INTERVAL 1 SECOND,"1998-01-01 00:00:00" - INTERVAL 1 SECOND,INTERVAL 1 DAY + "1997-12-31", extract(YEAR FROM "1999-01-02 10:11:12"),date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
|
||||||
|
|
||||||
|
SET @TMP=NOW();
|
||||||
CREATE TABLE t1 (d DATETIME);
|
CREATE TABLE t1 (d DATETIME);
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
INSERT INTO t1 VALUES (NOW());
|
INSERT INTO t1 VALUES (NOW());
|
||||||
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(NOW())) AND d<=FROM_DAYS(TO_DAYS(NOW())+1);
|
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(@TMP)) AND d<=FROM_DAYS(TO_DAYS(@TMP)+1);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
14
sql/item.cc
14
sql/item.cc
@ -820,6 +820,16 @@ String *Item_copy_string::val_str(String *str)
|
|||||||
return &str_value;
|
return &str_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Item_copy_string::save_in_field(Field *field, bool no_conversions)
|
||||||
|
{
|
||||||
|
if (null_value)
|
||||||
|
return set_field_to_null(field);
|
||||||
|
field->set_notnull();
|
||||||
|
return field->store(str_value.ptr(),str_value.length(),
|
||||||
|
collation.collation);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Functions to convert item to field (for send_fields)
|
Functions to convert item to field (for send_fields)
|
||||||
*/
|
*/
|
||||||
@ -1284,8 +1294,8 @@ int Item::save_in_field(Field *field, bool no_conversions)
|
|||||||
String *result;
|
String *result;
|
||||||
CHARSET_INFO *cs= collation.collation;
|
CHARSET_INFO *cs= collation.collation;
|
||||||
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
|
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
|
||||||
String loc_value(buff, sizeof(buff), cs);
|
str_value.set_quick(buff, sizeof(buff), cs);
|
||||||
result=val_str(&loc_value);
|
result=val_str(&str_value);
|
||||||
if (null_value)
|
if (null_value)
|
||||||
return set_field_to_null_with_conversions(field, no_conversions);
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -102,7 +102,11 @@ public:
|
|||||||
|
|
||||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||||
|
|
||||||
String str_value; /* used to store value */
|
/*
|
||||||
|
str_values's main purpose is to be used to cache the value in
|
||||||
|
save_in_field
|
||||||
|
*/
|
||||||
|
String str_value;
|
||||||
my_string name; /* Name from select */
|
my_string name; /* Name from select */
|
||||||
Item *next;
|
Item *next;
|
||||||
uint32 max_length;
|
uint32 max_length;
|
||||||
@ -138,7 +142,7 @@ public:
|
|||||||
virtual void make_field(Send_field *field);
|
virtual void make_field(Send_field *field);
|
||||||
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
|
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
/*
|
/*
|
||||||
should be used in case where we are shure that we do not need
|
should be used in case where we are sure that we do not need
|
||||||
complete fix_fields() procedure.
|
complete fix_fields() procedure.
|
||||||
*/
|
*/
|
||||||
inline void quick_fix_field() { fixed= 1; }
|
inline void quick_fix_field() { fixed= 1; }
|
||||||
@ -250,7 +254,7 @@ public:
|
|||||||
class Item_num: public Item
|
class Item_num: public Item
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Item_num* neg()= 0;
|
virtual Item_num *neg()= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -813,6 +817,7 @@ public:
|
|||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
void make_field(Send_field *field) { item->make_field(field); }
|
void make_field(Send_field *field) { item->make_field(field); }
|
||||||
void copy();
|
void copy();
|
||||||
|
int save_in_field(Field *field, bool no_conversions);
|
||||||
table_map used_tables() const { return (table_map) 1L; }
|
table_map used_tables() const { return (table_map) 1L; }
|
||||||
bool const_item() const { return 0; }
|
bool const_item() const { return 0; }
|
||||||
bool is_null() { return null_value; }
|
bool is_null() { return null_value; }
|
||||||
|
@ -1920,7 +1920,8 @@ void Item_cond::neg_arguments(THD *thd)
|
|||||||
Item *new_item= item->neg_transformer(thd);
|
Item *new_item= item->neg_transformer(thd);
|
||||||
if (!new_item)
|
if (!new_item)
|
||||||
{
|
{
|
||||||
new_item= new Item_func_not(item);
|
if (!(new_item= new Item_func_not(item)))
|
||||||
|
return; // Fatal OEM error
|
||||||
/*
|
/*
|
||||||
We can use 0 as tables list because Item_func_not do not use it
|
We can use 0 as tables list because Item_func_not do not use it
|
||||||
on fix_fields and its arguments are already fixed.
|
on fix_fields and its arguments are already fixed.
|
||||||
|
@ -991,13 +991,13 @@ public:
|
|||||||
|
|
||||||
/* Some usefull inline functions */
|
/* Some usefull inline functions */
|
||||||
|
|
||||||
inline Item *and_conds(Item *a, Item *b, TABLE_LIST *tables)
|
inline Item *and_conds(THD *thd, Item *a, Item *b, TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
if (!b) return a;
|
if (!b) return a;
|
||||||
if (!a) return b;
|
if (!a) return b;
|
||||||
Item *cond= new Item_cond_and(a,b);
|
Item *cond= new Item_cond_and(a,b);
|
||||||
if (cond)
|
if (cond)
|
||||||
cond->fix_fields(current_thd, tables, &cond);
|
cond->fix_fields(thd, tables, &cond);
|
||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2783,8 +2783,8 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
/*
|
/*
|
||||||
Above function used only to get value and do not need fix_fields for it:
|
Above function used only to get value and do not need fix_fields for it:
|
||||||
Item_string - basic constant
|
Item_string - basic constant
|
||||||
fields - fix_fieds already was called for this arguments
|
fields - fix_fields() was already called for this arguments
|
||||||
Item_func_concat_ws - do not need fix_fields to produce value
|
Item_func_concat_ws - do not need fix_fields() to produce value
|
||||||
*/
|
*/
|
||||||
concat->quick_fix_field();
|
concat->quick_fix_field();
|
||||||
}
|
}
|
||||||
|
@ -2365,7 +2365,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
!(specialflag & SPECIAL_NO_NEW_FUNC)))
|
!(specialflag & SPECIAL_NO_NEW_FUNC)))
|
||||||
{
|
{
|
||||||
table->outer_join= 0;
|
table->outer_join= 0;
|
||||||
if (!(*conds= and_conds(*conds, table->on_expr, tables)))
|
if (!(*conds= and_conds(thd, *conds, table->on_expr, tables)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
table->on_expr=0;
|
table->on_expr=0;
|
||||||
}
|
}
|
||||||
@ -2407,14 +2407,14 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
|
|
||||||
if (!table->outer_join) // Not left join
|
if (!table->outer_join) // Not left join
|
||||||
{
|
{
|
||||||
if (!(*conds= and_conds(*conds, cond_and, tables)) ||
|
if (!(*conds= and_conds(thd, *conds, cond_and, tables)) ||
|
||||||
(*conds && !(*conds)->fixed &&
|
(*conds && !(*conds)->fixed &&
|
||||||
(*conds)->fix_fields(thd, tables, conds)))
|
(*conds)->fix_fields(thd, tables, conds)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table->on_expr= and_conds(table->on_expr, cond_and, tables);
|
table->on_expr= and_conds(thd, table->on_expr, cond_and, tables);
|
||||||
if (table->on_expr && !table->on_expr->fixed &&
|
if (table->on_expr && !table->on_expr->fixed &&
|
||||||
table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@ -3536,7 +3536,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
{
|
{
|
||||||
/* Join with outer join condition */
|
/* Join with outer join condition */
|
||||||
COND *orig_cond=sel->cond;
|
COND *orig_cond=sel->cond;
|
||||||
sel->cond=and_conds(sel->cond, tab->on_expr, 0);
|
sel->cond=and_conds(join->thd, sel->cond, tab->on_expr, 0);
|
||||||
if (sel->test_quick_select(join->thd, tab->keys,
|
if (sel->test_quick_select(join->thd, tab->keys,
|
||||||
used_tables & ~ current_map,
|
used_tables & ~ current_map,
|
||||||
(join->select_options &
|
(join->select_options &
|
||||||
|
@ -150,6 +150,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
JOIN *join= new JOIN(thd_arg, sl->item_list,
|
JOIN *join= new JOIN(thd_arg, sl->item_list,
|
||||||
sl->options | thd_arg->options | additional_options,
|
sl->options | thd_arg->options | additional_options,
|
||||||
tmp_result);
|
tmp_result);
|
||||||
|
if (!join)
|
||||||
|
goto err;
|
||||||
|
|
||||||
thd_arg->lex->current_select= sl;
|
thd_arg->lex->current_select= sl;
|
||||||
offset_limit_cnt= sl->offset_limit;
|
offset_limit_cnt= sl->offset_limit;
|
||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
||||||
@ -178,6 +181,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
Item *item_tmp;
|
Item *item_tmp;
|
||||||
while ((item_tmp= it++))
|
while ((item_tmp= it++))
|
||||||
{
|
{
|
||||||
|
/* Error's in 'new' will be detected after loop */
|
||||||
types.push_back(new Item_type_holder(thd_arg, item_tmp));
|
types.push_back(new Item_type_holder(thd_arg, item_tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +388,10 @@ int st_select_lex_unit::exec()
|
|||||||
allocate JOIN for fake select only once (privent
|
allocate JOIN for fake select only once (privent
|
||||||
mysql_select automatic allocation)
|
mysql_select automatic allocation)
|
||||||
*/
|
*/
|
||||||
fake_select_lex->join= new JOIN(thd, item_list, thd->options, result);
|
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,
|
||||||
|
result)))
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Fake st_select_lex should have item list for correctref_array
|
Fake st_select_lex should have item list for correctref_array
|
||||||
allocation.
|
allocation.
|
||||||
|
Reference in New Issue
Block a user