summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-02-09 12:31:03 +0100
committerunknown <monty@mysql.com>2004-02-09 12:31:03 +0100
commit35b1f5445056951dda823b6ec4ee6f06ca612714 (patch)
tree4cdb6965fba280ace2fc30421a0f25332597e43e /sql
parent44289ba6587b7a2151b4bd3aa7bd5f3b282454d5 (diff)
downloadmariadb-git-35b1f5445056951dda823b6ec4ee6f06ca612714.tar.gz
Added --compact to mysqlbinlog
Fixed output from mysqlbinlog when using --skip-comments Fixed warnings from valgrind Fixed ref_length when used with HEAP tables More efficent need_conversion() Fixed error handling in UPDATE with not updateable tables Fixed bug in null handling in CAST to signed/unsigned client/client_priv.h: cleanup & added OPT_COMPACT client/mysqldump.c: Added option --compact to get a compact readable dump. Ensure that SET CHARACTER_SET_CLIENT is not done if we have not remembered the old character set Print optimization comments even if --skip-comments are given as these are not true comments. (Before these where only printed at end, which was a bug) mysql-test/r/cast.result: More cast tests mysql-test/r/derived.result: Removed warnings mysql-test/r/mysqldump.result: Update results after fixing mysqlbinlog mysql-test/r/query_cache.result: Make test usable with --extern more tests mysql-test/r/rpl_until.result: Make test repeatable under valgrind mysql-test/r/sql_mode.result: Fix test result mysql-test/r/subselect.result: Make test smaller. Update wrong results mysql-test/t/cast.test: More cast tests mysql-test/t/derived.test: Removed warnings mysql-test/t/query_cache.test: Make test usable with --extern more tests mysql-test/t/rpl_until.test: fix for valgrind. Becasue of unknown reason one got 'Slave_SQL_Running=yes' in this setup mysql-test/t/subselect.test: Make test case smaller sql/field.cc: Updated need_conversion() to use new arguments sql/ha_heap.cc: Moved initialization of ref_length to right place. This fixed problem that we had a ref_length of 8 for heap tables, which was not efficent. sql/item_func.cc: Cleanup sql/item_func.h: Fixed bug in null_handling for cast to signed/unsigned sql/item_strfunc.cc: Optimized/cleaned up Item_func_conv_charset3 sql/item_sum.cc: Cleanup. Ensure that some flag variables are cleared in cleanup() sql/item_sum.h: Fixed references to uninitialized memory sql/opt_range.cc: Fixed spelling error sql/sql_class.cc: Fixed wrong return code, which could case protocol problems sql/sql_class.h: After merge fix sql/sql_prepare.cc: Added comments sql/sql_show.cc: Cleanup sql/sql_string.cc: Optimzed usage of need_conversion(). - Removed not used argument - Save diff lenght in 'offset' to not have to recalculate length several times. Cleaned up comment Optimized copy_aligned() based on the knowledge that it's only called when you have wrong data sql/sql_string.h: Updated need_conversion() and copy_aligned() to use new arguments sql/sql_update.cc: Fixed error handling with non-updateable tables sql/sql_yacc.yy: Ensure that lex->lock_options are set correctly (to get rid of warnings from valgrind) Ensure that cast_type sets lex->charset and lex->length. Without these CONVERT() didn't work properly
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc20
-rw-r--r--sql/ha_heap.cc2
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h20
-rw-r--r--sql/item_strfunc.cc60
-rw-r--r--sql/item_sum.cc18
-rw-r--r--sql/item_sum.h7
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_string.cc118
-rw-r--r--sql/sql_string.h8
-rw-r--r--sql/sql_update.cc3
-rw-r--r--sql/sql_yacc.yy28
16 files changed, 157 insertions, 145 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 9f25b770ab0..f337f4ca46c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4058,10 +4058,12 @@ void Field_datetime::sql_type(String &res) const
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
{
int error= 0;
+ uint32 not_used;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
- if (String::needs_conversion(from, length, cs, field_charset))
+ if (String::needs_conversion(length, cs, field_charset, &not_used))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
@@ -4246,10 +4248,12 @@ uint Field_string::max_packed_col_length(uint max_length)
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
{
int error= 0;
+ uint32 not_used;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
- if (String::needs_conversion(from, length, cs, field_charset))
+ if (String::needs_conversion(length, cs, field_charset, &not_used))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
@@ -4565,10 +4569,11 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
bool was_conversion;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+ uint32 not_used;
/* Convert character set if nesessary */
- if ((was_conversion= String::needs_conversion(from, length,
- cs, field_charset)))
+ if ((was_conversion= String::needs_conversion(length, cs, field_charset,
+ &not_used)))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
@@ -5079,10 +5084,12 @@ void Field_enum::store_type(ulonglong value)
int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
{
int err= 0;
+ uint32 not_used;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
- if (String::needs_conversion(from, length, cs, field_charset))
+ if (String::needs_conversion(length, cs, field_charset, &not_used))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
@@ -5259,11 +5266,12 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
int err= 0;
char *not_used;
uint not_used2;
+ uint32 not_used_offset;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if nesessary */
- if (String::needs_conversion(from, length, cs, field_charset))
+ if (String::needs_conversion(length, cs, field_charset, &not_used_offset))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index ae0267b98f3..c1228cbd319 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -40,6 +40,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
if (!create(name, table, &create_info))
file= heap_open(name, mode);
}
+ ref_length= sizeof(HEAP_PTR);
return (file ? 0 : 1);
}
@@ -335,7 +336,6 @@ int ha_heap::create(const char *name, TABLE *table_arg,
my_free((gptr) keydef, MYF(0));
if (file)
info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
- ref_length= sizeof(HEAP_PTR);
return (error);
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index efeb0d456ef..b1378784f92 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1068,9 +1068,8 @@ String *Item_func_min_max::val_str(String *str)
}
}
}
- if (!res) // If NULL
- return 0;
- res->set_charset(collation.collation);
+ if (res) // If !NULL
+ res->set_charset(collation.collation);
return res;
}
case ROW_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index be20a9b4fc7..30f817d133b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -211,20 +211,28 @@ class Item_func_signed :public Item_int_func
{
public:
Item_func_signed(Item *a) :Item_int_func(a) {}
- double val() { null_value=args[0]->null_value; return args[0]->val(); }
- longlong val_int() { null_value=args[0]->null_value; return args[0]->val_int(); }
+ double val()
+ {
+ double tmp= args[0]->val();
+ null_value= args[0]->null_value;
+ return tmp;
+ }
+ longlong val_int()
+ {
+ longlong tmp= args[0]->val_int();
+ null_value= args[0]->null_value;
+ return tmp;
+ }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
};
-class Item_func_unsigned :public Item_int_func
+class Item_func_unsigned :public Item_func_signed
{
public:
- Item_func_unsigned(Item *a) :Item_int_func(a) {}
- double val() { null_value=args[0]->null_value; return args[0]->val(); }
- longlong val_int() { null_value=args[0]->null_value; return args[0]->val_int(); }
+ Item_func_unsigned(Item *a) :Item_func_signed(a) {}
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
void print(String *str);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f5922d03868..fd1222d5f1a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2126,14 +2126,12 @@ void Item_func_conv_charset::print(String *str)
String *Item_func_conv_charset3::val_str(String *str)
{
- my_wc_t wc;
- int cnvres;
- const uchar *s, *se;
- uchar *d, *d0, *de;
- uint32 dmaxlen;
+ char cs1[30], cs2[30];
+ String to_cs_buff(cs1, sizeof(cs1), default_charset_info);
+ String from_cs_buff(cs2, sizeof(cs2), default_charset_info);
String *arg= args[0]->val_str(str);
- String *to_cs= args[1]->val_str(str);
- String *from_cs= args[2]->val_str(str);
+ String *to_cs= args[1]->val_str(&to_cs_buff);
+ String *from_cs= args[2]->val_str(&from_cs_buff);
CHARSET_INFO *from_charset;
CHARSET_INFO *to_charset;
@@ -2143,51 +2141,17 @@ String *Item_func_conv_charset3::val_str(String *str)
!(from_charset=get_charset_by_name(from_cs->ptr(), MYF(MY_WME))) ||
!(to_charset=get_charset_by_name(to_cs->ptr(), MYF(MY_WME))))
{
- null_value=1;
+ null_value= 1;
return 0;
}
- s=(const uchar*)arg->ptr();
- se=s+arg->length();
-
- dmaxlen=arg->length()*to_charset->mbmaxlen+1;
- str->alloc(dmaxlen);
- d0=d=(unsigned char*)str->ptr();
- de=d+dmaxlen;
-
- while (1)
+ if (str_value.copy(arg->ptr(), arg->length(), from_charset, to_charset))
{
- cnvres=from_charset->cset->mb_wc(from_charset,&wc,s,se);
- if (cnvres>0)
- {
- s+=cnvres;
- }
- else if (cnvres==MY_CS_ILSEQ)
- {
- s++;
- wc='?';
- }
- else
- break;
-
-outp:
- cnvres=to_charset->cset->wc_mb(to_charset,wc,d,de);
- if (cnvres>0)
- {
- d+=cnvres;
- }
- else if (cnvres==MY_CS_ILUNI && wc!='?')
- {
- wc='?';
- goto outp;
- }
- else
- break;
- };
-
- str->length((uint32) (d-d0));
- str->set_charset(to_charset);
- return str;
+ null_value= 1;
+ return 0;
+ }
+ null_value= 0;
+ return &str_value;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index e01f9db3463..10b50fa5b3b 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1092,15 +1092,21 @@ void Item_sum_count_distinct::cleanup()
if (!original)
{
if (table)
+ {
free_tmp_table(current_thd, table);
+ table= 0;
+ }
delete tmp_table_param;
+ tmp_table_param= 0;
if (use_tree)
+ {
delete_tree(tree);
- table= 0;
- use_tree= 0;
+ use_tree= 0;
+ }
}
}
+
bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables,
Item **ref)
{
@@ -1674,13 +1680,21 @@ void Item_func_group_concat::cleanup()
{
THD *thd= current_thd;
if (table)
+ {
free_tmp_table(thd, table);
+ table= 0;
+ }
delete tmp_table_param;
+ tmp_table_param= 0;
if (tree_mode)
+ {
+ tree_mode= 0;
delete_tree(tree);
+ }
}
}
+
Item_func_group_concat::~Item_func_group_concat()
{
/*
diff --git a/sql/item_sum.h b/sql/item_sum.h
index dc84e4d4ab7..bb03f029997 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -397,12 +397,13 @@ class Item_sum_hybrid :public Item_sum
public:
Item_sum_hybrid(Item *item_par,int sign)
- :Item_sum(item_par), hybrid_type(INT_RESULT), cmp_sign(sign),
- used_table_cache(~(table_map) 0),
+ :Item_sum(item_par), sum(0.0), sum_int(0),
+ hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
+ cmp_sign(sign), used_table_cache(~(table_map) 0),
cmp_charset(&my_charset_bin)
{}
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item):
- Item_sum(thd, item), value(item->value), tmp_value(item->tmp_value),
+ Item_sum(thd, item), value(item->value),
sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign),
used_table_cache(item->used_table_cache), cmp_charset(item->cmp_charset) {}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2647a0ae818..4c9f3700ef1 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1005,7 +1005,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
}
/*
- We can't use an index when comparing stings of
+ We can't use an index when comparing strings of
different collations
*/
if (field->result_type() == STRING_RESULT &&
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index fc042ae7918..cbac11ac42e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -744,7 +744,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange,
if (!access(path, F_OK))
{
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
- return 1;
+ return -1;
}
/* Create the file world readable */
if ((file= my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 51dc8270d09..b3135202ad6 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -993,10 +993,6 @@ public:
class select_dump :public select_to_file {
- sql_exchange *exchange;
- File file;
- IO_CACHE cache;
- ha_rows row_count;
public:
select_dump(sql_exchange *ex) :select_to_file(ex) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index de0d0c8aca8..9b8ef37757c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1005,8 +1005,10 @@ void mysql_stmt_execute(THD *thd, char *packet)
sl->where= sl->prep_where->copy_andor_structure(thd);
DBUG_ASSERT(sl->join == 0);
ORDER *order;
+ /* Fix GROUP list */
for (order=(ORDER *)sl->group_list.first ; order ; order=order->next)
order->item= (Item **)(order+1);
+ /* Fix ORDER list */
for (order=(ORDER *)sl->order_list.first ; order ; order=order->next)
order->item= (Item **)(order+1);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 5f6167f2cd1..4da2522bd3f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -519,8 +519,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
protocol->store_null();
// Send error to Comment field
protocol->store(thd->net.last_error, system_charset_info);
- thd->net.last_error[0]=0;
- thd->net.last_errno= 0;
+ thd->clear_error();
}
else
{
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 7f26a0febda..cbee67c0a4a 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -230,68 +230,86 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
/*
- Checks that the source string can be just copied
- to the destination string without conversion.
- If either character set conversion or adding leading
- zeros (e.g. for UCS-2) must be done then return
- value is TRUE else FALSE.
+ Checks that the source string can be just copied to the destination string
+ without conversion.
+
+ SYNPOSIS
+
+ needs_conversion()
+ arg_length Length of string to copy.
+ from_cs Character set to copy from
+ to_cs Character set to copy to
+ uint32 *offset Returns number of unaligned characters.
+
+ RETURN
+ 0 No conversion needed
+ 1 Either character set conversion or adding leading zeros
+ (e.g. for UCS-2) must be done
*/
-bool String::needs_conversion(const char *str, uint32 arg_length,
- CHARSET_INFO *from_cs,
- CHARSET_INFO *to_cs)
+
+bool String::needs_conversion(uint32 arg_length,
+ CHARSET_INFO *from_cs,
+ CHARSET_INFO *to_cs,
+ uint32 *offset)
{
+ *offset= 0;
if ((to_cs == &my_charset_bin) ||
(to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) ||
- ((from_cs == &my_charset_bin) && (!(arg_length % to_cs->mbminlen))))
+ ((from_cs == &my_charset_bin) &&
+ (!(*offset=(arg_length % to_cs->mbminlen)))))
return FALSE;
-
return TRUE;
}
+
/*
-** For real multi-byte, ascii incompatible charactser sets,
-** like UCS-2, add leading zeros if we have an incomplete character.
-** Thus,
-** SELECT _ucs2 0xAA
-** will automatically be converted into
-** SELECT _ucs2 0x00AA
+ Copy a multi-byte character sets with adding leading zeros.
+
+ SYNOPSIS
+
+ copy_aligned()
+ str String to copy
+ arg_length Length of string. This should NOT be dividable with
+ cs->mbminlen.
+ offset arg_length % cs->mb_minlength
+ cs Character set for 'str'
+
+ NOTES
+ For real multi-byte, ascii incompatible charactser sets,
+ like UCS-2, add leading zeros if we have an incomplete character.
+ Thus,
+ SELECT _ucs2 0xAA
+ will automatically be converted into
+ SELECT _ucs2 0x00AA
+
+ RETURN
+ 0 ok
+ 1 error
*/
-bool String::copy_aligned(const char *str,uint32 arg_length,
+bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
CHARSET_INFO *cs)
{
/* How many bytes are in incomplete character */
- uint32 offs= (arg_length % cs->mbminlen);
+ offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */
+ DBUG_ASSERT(offset && offset != cs->mbmaxlen);
- if (!offs) /* All characters are complete, just copy */
- {
- copy(str, arg_length, cs);
- return FALSE;
- }
-
- offs= cs->mbmaxlen - offs; /* How many zeros we should prepend */
- uint32 aligned_length= arg_length + offs;
+ uint32 aligned_length= arg_length + offset;
if (alloc(aligned_length))
return TRUE;
/*
- Probably this condition is not really necessary
- because if aligned_length is 0 then offs is 0 too
- and we'll return after calling set().
+ Note, this is only safe for little-endian UCS-2.
+ If we add big-endian UCS-2 sometimes, this code
+ will be more complicated. But it's OK for now.
*/
- if ((str_length= aligned_length))
- {
- /*
- Note, this is only safe for little-endian UCS-2.
- If we add big-endian UCS-2 sometimes, this code
- will be more complicated. But it's OK for now.
- */
- bzero((char*)Ptr, offs);
- memcpy(Ptr + offs, str, arg_length);
- }
+ bzero((char*) Ptr, offset);
+ memcpy(Ptr + offset, str, arg_length);
Ptr[aligned_length]=0;
- str_charset=cs;
+ /* str_length is always >= 0 as arg_length is != 0 */
+ str_length= aligned_length;
+ str_charset= cs;
return FALSE;
}
@@ -300,14 +318,14 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
CHARSET_INFO *cs)
{
/* How many bytes are in incomplete character */
- uint32 offs= (arg_length % cs->mbminlen);
+ uint32 offset= (arg_length % cs->mbminlen);
- if (!offs) /* All characters are complete, just copy */
+ if (!offset) /* All characters are complete, just copy */
{
set(str, arg_length, cs);
return FALSE;
}
- return copy_aligned(str, arg_length, cs);
+ return copy_aligned(str, arg_length, offset, cs);
}
/* Copy with charset convertion */
@@ -315,14 +333,11 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
bool String::copy(const char *str, uint32 arg_length,
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
{
- if (!needs_conversion(str, arg_length, from_cs, to_cs))
- {
+ uint32 offset;
+ if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
return copy(str, arg_length, to_cs);
- }
- if ((from_cs == &my_charset_bin) && (arg_length % to_cs->mbminlen))
- {
- return copy_aligned(str, arg_length, to_cs);
- }
+ if ((from_cs == &my_charset_bin) && offset)
+ return copy_aligned(str, arg_length, offset, to_cs);
uint32 new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
@@ -744,7 +759,8 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
while (1)
{
- if ((cnvres=from_cs->cset->mb_wc(from_cs, &wc, (uchar*) from, from_end)) > 0)
+ if ((cnvres= from_cs->cset->mb_wc(from_cs, &wc, (uchar*) from,
+ from_end)) > 0)
from+= cnvres;
else if (cnvres == MY_CS_ILSEQ)
{
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 9c0900137e3..163156fdfe2 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -183,9 +183,11 @@ public:
bool copy(); // Alloc string if not alloced
bool copy(const String &s); // Allocate new string
bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
- static bool needs_conversion(const char *s, uint32 arg_length,
- CHARSET_INFO *cs_from, CHARSET_INFO *cs_to);
- bool copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
+ static bool needs_conversion(uint32 arg_length,
+ CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
+ uint32 *offset);
+ bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
+ CHARSET_INFO *cs);
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
CHARSET_INFO *csto);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index c6e470fd09f..86593f5ea20 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -482,8 +482,11 @@ int mysql_multi_update(THD *thd,
for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
{
if (tl->derived && (item_tables & tl->table->map))
+ {
my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE),
MYF(0), tl->alias, "UPDATE");
+ DBUG_RETURN(-1);
+ }
}
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f04cc9ec1dc..0dbe8981466 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -918,7 +918,7 @@ create:
&tmp_table_alias :
(LEX_STRING*) 0),
TL_OPTION_UPDATING,
- ((using_update_log)?
+ (using_update_log ?
TL_READ_NO_INSERT:
TL_READ)))
YYABORT;
@@ -2189,10 +2189,9 @@ select_init2:
select_part2:
{
- LEX *lex=Lex;
- SELECT_LEX * sel= lex->current_select;
- if (lex->current_select == &lex->select_lex)
- lex->lock_option= TL_READ; /* Only for global SELECT */
+ LEX *lex= Lex;
+ SELECT_LEX *sel= lex->current_select;
+ lex->lock_option= TL_READ;
if (sel->linkage != UNION_TYPE)
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
@@ -3060,7 +3059,7 @@ opt_gorder_clause:
| order_clause
{
LEX *lex=Lex;
- lex->gorder_list=
+ lex->gorder_list=
(SQL_LIST*) sql_memdup((char*) &lex->current_select->order_list,
sizeof(st_sql_list));
lex->current_select->order_list.empty();
@@ -3084,16 +3083,16 @@ in_sum_expr:
};
cast_type:
- BINARY { $$=ITEM_CAST_BINARY; }
+ BINARY { $$=ITEM_CAST_BINARY; Lex->charset= NULL; Lex->length= (char*)0; }
| CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; }
| NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; }
- | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
- | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
- | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
- | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
- | DATE_SYM { $$=ITEM_CAST_DATE; }
- | TIME_SYM { $$=ITEM_CAST_TIME; }
- | DATETIME { $$=ITEM_CAST_DATETIME; }
+ | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; }
+ | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; }
+ | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; }
+ | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; }
+ | DATE_SYM { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->length= (char*)0; }
+ | TIME_SYM { $$=ITEM_CAST_TIME; Lex->charset= NULL; Lex->length= (char*)0; }
+ | DATETIME { $$=ITEM_CAST_DATETIME; Lex->charset= NULL; Lex->length= (char*)0; }
;
expr_list:
@@ -3895,6 +3894,7 @@ update:
LEX *lex= Lex;
mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE;
+ lex->lock_option= TL_UNLOCK; /* Will be set later */
}
opt_low_priority opt_ignore join_table_list
SET update_list where_clause opt_order_clause delete_limit_clause