diff options
author | unknown <monty@mysql.com> | 2004-03-25 22:11:22 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-03-25 22:11:22 +0200 |
commit | cf5e9e65f5344bd038c03d4d6b8db4c5b872e0cb (patch) | |
tree | 36abf1d40f08cd21cd81f6d5966b89ab4e995ac6 | |
parent | fe596dee5869ac1f99a9d88061bc9dff402849f6 (diff) | |
download | mariadb-git-cf5e9e65f5344bd038c03d4d6b8db4c5b872e0cb.tar.gz |
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
-rw-r--r-- | include/mysql.h | 12 | ||||
-rw-r--r-- | libmysql/libmysql.c | 222 | ||||
-rw-r--r-- | myisam/mi_search.c | 1 | ||||
-rw-r--r-- | mysql-test/r/func_time.result | 3 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 3 | ||||
-rw-r--r-- | sql/item.cc | 14 | ||||
-rw-r--r-- | sql/item.h | 11 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 3 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 9 |
13 files changed, 182 insertions, 112 deletions
diff --git a/include/mysql.h b/include/mysql.h index d922b552e38..dcdbe3a07a4 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -187,9 +187,9 @@ struct st_mysql_options { my_bool secure_auth; /* 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_end)(void *); + void (*local_infile_end)(void *); 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 -int +void 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_end)(void *), - int (*local_infile_error)(void *, char *, uint)); + void (*local_infile_end)(void *), + int (*local_infile_error)(void *, char*, uint)); void mysql_set_local_infile_default(MYSQL *mysql); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 357c85c09b2..9ad51518d83 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -799,54 +799,51 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename) my_bool result= 1; uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); NET *net= &mysql->net; - int error; int readcount; void *li_ptr; /* pass state to local_infile functions */ - char *buf = NULL; /* buffer to be filled by local_infile_read */ - char *filename = NULL; /* local copy of filename arg */ - + char *buf;; /* buffer to be filled by local_infile_read */ + struct st_mysql_options *options= &mysql->options; DBUG_ENTER("handle_local_infile"); /* check that we've got valid callback functions */ - if (!((mysql->options.local_infile_init) && - (mysql->options.local_infile_read) && - (mysql->options.local_infile_end) && - (mysql->options.local_infile_error))) + if (!(options->local_infile_init && + options->local_infile_read && + options->local_infile_end && + options->local_infile_error)) { /* 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 */ - if ((!(filename = my_strdup(net_filename, MYF(0)))) || - (!(buf=my_malloc(packet_length, MYF(0))))) - goto oom; - + if (!(buf=my_malloc(packet_length, MYF(0)))) + { + 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) */ - 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 */ net_flush(net); - if(error < 0) - goto oom; strmov(net->sqlstate, unknown_sqlstate); - net->last_errno=error; - (*mysql->options.local_infile_error)(li_ptr, - net->last_error, - sizeof(net->last_error)-1); + net->last_errno= (*options->local_infile_error)(li_ptr, + net->last_error, + sizeof(net->last_error)-1); goto err; } /* read blocks of data from local infile callback */ - while ( (readcount = - (*mysql->options.local_infile_read)(li_ptr, - buf, - packet_length) ) > 0) + while ((readcount = + (*options->local_infile_read)(li_ptr, buf, + packet_length)) > 0) { 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); net->last_errno=CR_SERVER_LOST; 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) { - strmov(net->sqlstate, unknown_sqlstate); - net->last_errno=EE_READ; /* the errmsg for not entire file read */ - my_snprintf(net->last_error,sizeof(net->last_error)-1, - filename, errno); + net->last_errno= (*options->local_infile_error)(li_ptr, + net->last_error, + sizeof(net->last_error)-1); goto err; } @@ -876,117 +872,165 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename) err: /* free up memory allocated with _init, usually */ - (*mysql->options.local_infile_end)(li_ptr); - - my_free(filename, MYF(0)); - my_free(buf, MYF(0)); + (*options->local_infile_end)(li_ptr); 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 error_num; + const char *filename; char error_msg[LOCAL_INFILE_ERROR_LEN]; } 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; + char tmp_name[FN_REFLEN]; if (!(*ptr= data= ((default_local_infile_data *) - my_malloc(sizeof(default_local_infile_data), MYF(0))))) - return -1; /* out of memory */ - - *ptr = data; /* save the struct, we need it to return an error */ + my_malloc(sizeof(default_local_infile_data), MYF(0))))) + return 1; /* out of memory */ data->error_msg[0]= 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, - EE(EE_FILENOTFOUND), filename, errno); - return data->error_num=errno; /* error */ + EE(EE_FILENOTFOUND), tmp_name, data->error_num); + return 1; } - 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) + { + data->error_num= EE_READ; /* the errmsg for not entire file read */ + my_snprintf(data->error_msg, sizeof(data->error_msg)-1, + EE(EE_READ), + data->filename, my_errno); + } + return count; } -int -default_local_infile_end(void *ptr) +/* + 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) + default_local_infile_data *data= (default_local_infile_data *) ptr; + if (data) /* If not error on open */ { - my_close(data->fd, MYF(0)); - my_free(ptr, MYF(0)); + if (data->fd >= 0) + my_close(data->fd, MYF(MY_WME)); + my_free(ptr, MYF(MY_WME)); } - return 0; } -int +/* + 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_data *data = (default_local_infile_data *) ptr; - - if(data) { + default_local_infile_data *data = (default_local_infile_data *) ptr; + if (data) /* If not error on open */ + { strmake(error_msg, data->error_msg, error_msg_len); return data->error_num; } - else - { - strmake(error_msg, "Internal error", error_msg_len); - return 0; - } + /* This can only happen if we got error on malloc of handle */ + strmov(error_msg, ER(CR_OUT_OF_MEMORY)); + return CR_OUT_OF_MEMORY; } -int +void 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_end)(void *), + void (*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; + 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) +void mysql_set_local_infile_default(MYSQL *mysql) { mysql->options.local_infile_init= default_local_infile_init; mysql->options.local_infile_read= default_local_infile_read; diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 73a4d229fd6..1c4342ff39a 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -18,6 +18,7 @@ #include "fulltext.h" #include "m_ctype.h" +#include <assert.h> static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, uchar *keypos, diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 38dcf17ae1d..d2ea3c4a87c 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -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 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)` +SET @TMP=NOW(); CREATE TABLE t1 (d DATETIME); 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(*) 3 DROP TABLE t1; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index ecb440ff079..4b8c26a00d8 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -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); +SET @TMP=NOW(); CREATE TABLE t1 (d DATETIME); 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; diff --git a/sql/item.cc b/sql/item.cc index e889bbf1930..36b263f62cf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -820,6 +820,16 @@ String *Item_copy_string::val_str(String *str) 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) */ @@ -1284,8 +1294,8 @@ int Item::save_in_field(Field *field, bool no_conversions) String *result; CHARSET_INFO *cs= collation.collation; char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns - String loc_value(buff, sizeof(buff), cs); - result=val_str(&loc_value); + str_value.set_quick(buff, sizeof(buff), cs); + result=val_str(&str_value); if (null_value) return set_field_to_null_with_conversions(field, no_conversions); field->set_notnull(); diff --git a/sql/item.h b/sql/item.h index 5f94320b547..dffa93eaac8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -102,7 +102,11 @@ public: 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 */ Item *next; uint32 max_length; @@ -138,7 +142,7 @@ public: virtual void make_field(Send_field *field); 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. */ inline void quick_fix_field() { fixed= 1; } @@ -250,7 +254,7 @@ public: class Item_num: public Item { public: - virtual Item_num* neg()= 0; + virtual Item_num *neg()= 0; }; @@ -813,6 +817,7 @@ public: String *val_str(String*); void make_field(Send_field *field) { item->make_field(field); } void copy(); + int save_in_field(Field *field, bool no_conversions); table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } bool is_null() { return null_value; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8f55467a23e..9175f12a60c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1920,7 +1920,8 @@ void Item_cond::neg_arguments(THD *thd) Item *new_item= item->neg_transformer(thd); 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 on fix_fields and its arguments are already fixed. diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 95520c0c222..cbd1e9feffa 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -991,13 +991,13 @@ public: /* 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 (!a) return b; Item *cond= new Item_cond_and(a,b); if (cond) - cond->fix_fields(current_thd, tables, &cond); + cond->fix_fields(thd, tables, &cond); return cond; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 5151fb2876d..984dee3ade9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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: Item_string - basic constant - fields - fix_fieds already was called for this arguments - Item_func_concat_ws - do not need fix_fields to produce value + fields - fix_fields() was already called for this arguments + Item_func_concat_ws - do not need fix_fields() to produce value */ concat->quick_fix_field(); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 56857aaa632..7a913a0a73d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2365,7 +2365,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) !(specialflag & SPECIAL_NO_NEW_FUNC))) { 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); 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 (!(*conds= and_conds(*conds, cond_and, tables)) || + if (!(*conds= and_conds(thd, *conds, cond_and, tables)) || (*conds && !(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds))) DBUG_RETURN(1); } 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 && table->on_expr->fix_fields(thd, tables, &table->on_expr)) DBUG_RETURN(1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 94bedd9bfa2..34bfabd845f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3536,7 +3536,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { /* Join with outer join condition */ 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, used_tables & ~ current_map, (join->select_options & diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 3a27e606cff..1f35c6b6f3d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -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, sl->options | thd_arg->options | additional_options, tmp_result); + if (!join) + goto err; + thd_arg->lex->current_select= sl; offset_limit_cnt= 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; while ((item_tmp= it++)) { + /* Error's in 'new' will be detected after loop */ 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 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 allocation. |