summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-04-04 16:45:23 +0300
committerunknown <monty@mysql.com>2005-04-04 16:45:23 +0300
commitd17aebaa101c241968e6fe466f141f8682fb14e6 (patch)
tree60a9a02d51166c3fe838db2f6b1c637aede65cd6 /sql
parent73ddce6dbcbbeaf9660343acbf107ce113c3b503 (diff)
parentce169a5424e76969e74828d4214cfedb0a425ee5 (diff)
downloadmariadb-git-d17aebaa101c241968e6fe466f141f8682fb14e6.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/my/mysql-5.0 sql/field.cc: Auto merged sql/field.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_table.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/Makefile.am2
-rw-r--r--sql/field.cc150
-rw-r--r--sql/field.h8
-rw-r--r--sql/field_conv.cc16
-rw-r--r--sql/item.cc70
-rw-r--r--sql/item.h17
-rw-r--r--sql/item_row.cc4
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/item_timefunc.cc36
-rw-r--r--sql/my_decimal.cc2
-rw-r--r--sql/mysql_priv.h15
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/sp.cc33
-rw-r--r--sql/sql_class.h21
-rw-r--r--sql/sql_error.h42
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_table.cc62
-rw-r--r--sql/time.cc9
-rw-r--r--sql/unireg.cc22
20 files changed, 335 insertions, 190 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am
index e0ff324b33c..b506d2a767b 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -49,7 +49,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
mysql_priv.h item_geofunc.h sql_bitmap.h \
procedure.h sql_class.h sql_lex.h sql_list.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
- field.h handler.h mysqld_suffix.h \
+ sql_error.h field.h handler.h mysqld_suffix.h \
ha_myisammrg.h\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
ha_ndbcluster.h opt_range.h protocol.h \
diff --git a/sql/field.cc b/sql/field.cc
index f3666f862af..4ef80a99695 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4512,6 +4512,13 @@ int Field_timestamp::store(longlong nr)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED,
nr, MYSQL_TIMESTAMP_DATETIME, 1);
+ if (!error && timestamp == 0 &&
+ (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE))
+ {
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
+ WARN_DATA_TRUNCATED,
+ nr, MYSQL_TIMESTAMP_DATETIME, 1);
+ }
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -5137,6 +5144,12 @@ int Field_date::store(double nr)
}
else
tmp=(long) rint(nr);
+
+ /*
+ We don't need to check for zero dates here as this date type is only
+ used in .frm tables from very old MySQL versions
+ */
+
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -5165,6 +5178,7 @@ int Field_date::store(longlong nr)
}
else
tmp=(long) nr;
+
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -5277,6 +5291,7 @@ void Field_date::sql_type(String &res) const
res.set_ascii("date", 4);
}
+
/****************************************************************************
** The new date type
** This is identical to the old date type, but stored on 3 bytes instead of 4
@@ -5309,17 +5324,17 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
return error;
}
+
int Field_newdate::store(double nr)
{
if (nr < 0.0 || nr > 99991231235959.0)
{
- (void) Field_newdate::store((longlong) -1);
+ int3store(ptr,(int32) 0);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE);
return 1;
}
- else
- return Field_newdate::store((longlong) rint(nr));
+ return Field_newdate::store((longlong) rint(nr));
}
@@ -5339,6 +5354,8 @@ int Field_newdate::store(longlong nr)
}
else
{
+ uint month, day;
+
tmp=(int32) nr;
if (tmp)
{
@@ -5346,24 +5363,33 @@ int Field_newdate::store(longlong nr)
tmp+= (uint32) 20000000L;
else if (tmp < 999999L)
tmp+= (uint32) 19000000L;
+
+ month= (uint) ((tmp/100) % 100);
+ day= (uint) (tmp%100);
+ if (month > 12 || day > 31)
+ {
+ tmp=0L; // Don't allow date to change
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DATA_OUT_OF_RANGE, nr,
+ MYSQL_TIMESTAMP_DATE, 1);
+ error= 1;
+ }
+ else
+ tmp= day + month*32 + (tmp/10000)*16*32;
}
- uint month= (uint) ((tmp/100) % 100);
- uint day= (uint) (tmp%100);
- if (month > 12 || day > 31)
+ else if (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE)
{
- tmp=0L; // Don't allow date to change
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr,
- MYSQL_TIMESTAMP_DATE, 1);
+ ER_WARN_DATA_OUT_OF_RANGE,
+ 0, MYSQL_TIMESTAMP_DATE);
error= 1;
}
- else
- tmp= day + month*32 + (tmp/10000)*16*32;
}
- int3store(ptr,(int32) tmp);
+ int3store(ptr, tmp);
return error;
}
+
int Field_newdate::store_time(TIME *ltime,timestamp_type type)
{
long tmp;
@@ -5380,6 +5406,7 @@ int Field_newdate::store_time(TIME *ltime,timestamp_type type)
return error;
}
+
bool Field_newdate::send_binary(Protocol *protocol)
{
TIME tm;
@@ -5387,11 +5414,13 @@ bool Field_newdate::send_binary(Protocol *protocol)
return protocol->store_date(&tm);
}
+
double Field_newdate::val_real(void)
{
return (double) Field_newdate::val_int();
}
+
longlong Field_newdate::val_int(void)
{
ulong j= uint3korr(ptr);
@@ -5399,6 +5428,7 @@ longlong Field_newdate::val_int(void)
return (longlong) j;
}
+
String *Field_newdate::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
@@ -5426,6 +5456,7 @@ String *Field_newdate::val_str(String *val_buffer,
return val_buffer;
}
+
bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
{
uint32 tmp=(uint32) uint3korr(ptr);
@@ -5438,11 +5469,13 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
1 : 0);
}
+
bool Field_newdate::get_time(TIME *ltime)
{
return Field_newdate::get_date(ltime,0);
}
+
int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
{
uint32 a,b;
@@ -5451,6 +5484,7 @@ int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
+
void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
{
to[0] = ptr[2];
@@ -5458,6 +5492,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
to[2] = ptr[0];
}
+
void Field_newdate::sql_type(String &res) const
{
res.set_ascii("date", 4);
@@ -5514,10 +5549,10 @@ int Field_datetime::store(double nr)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, MYSQL_TIMESTAMP_DATETIME);
- nr=0.0;
+ nr= 0.0;
error= 1;
}
- error |= Field_datetime::store((longlong) rint(nr));
+ error|= Field_datetime::store((longlong) rint(nr));
return error;
}
@@ -5534,6 +5569,13 @@ int Field_datetime::store(longlong nr)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, initial_nr,
MYSQL_TIMESTAMP_DATETIME, 1);
+ else if (nr == 0 && table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE)
+ {
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DATA_OUT_OF_RANGE,
+ initial_nr, MYSQL_TIMESTAMP_DATE);
+ error= 1;
+ }
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -8285,7 +8327,37 @@ create_field::create_field(Field *old_field,Field *orig_field)
}
-/* Warning handling */
+/*
+ maximum possible display length for blob
+
+ SYNOPSIS
+ Field_blob::max_length()
+
+ RETURN
+ length
+*/
+uint32 Field_blob::max_length()
+{
+ switch (packlength)
+ {
+ case 1:
+ return 255;
+ case 2:
+ return 65535;
+ case 3:
+ return 16777215;
+ case 4:
+ return (uint32) 4294967295U;
+ default:
+ DBUG_ASSERT(0); // we should never go here
+ return 0;
+ }
+}
+
+
+/*****************************************************************************
+ Warning handling
+*****************************************************************************/
/*
Produce warning or note about data saved into field
@@ -8301,18 +8373,20 @@ create_field::create_field(Field *old_field,Field *orig_field)
if count_cuted_fields == FIELD_CHECK_IGNORE for current thread.
RETURN VALUE
- true - if count_cuted_fields == FIELD_CHECK_IGNORE
- false - otherwise
+ 1 if count_cuted_fields == FIELD_CHECK_IGNORE
+ 0 otherwise
*/
+
bool
-Field::set_warning(uint level, uint code, int cuted_increment)
+Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
+ int cuted_increment)
{
THD *thd= table->in_use;
if (thd->count_cuted_fields)
{
thd->cuted_fields+= cuted_increment;
- push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level) level,
- code, ER(code), field_name, thd->row_count);
+ push_warning_printf(thd, level, code, ER(code), field_name,
+ thd->row_count);
return 0;
}
return 1;
@@ -8336,8 +8410,9 @@ Field::set_warning(uint level, uint code, int cuted_increment)
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread.
*/
+
void
-Field::set_datetime_warning(const uint level, const uint code,
+Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
const char *str, uint str_length,
timestamp_type ts_type, int cuted_increment)
{
@@ -8364,8 +8439,9 @@ Field::set_datetime_warning(const uint level, const uint code,
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread.
*/
+
void
-Field::set_datetime_warning(const uint level, const uint code,
+Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
longlong nr, timestamp_type ts_type,
int cuted_increment)
{
@@ -8395,8 +8471,9 @@ Field::set_datetime_warning(const uint level, const uint code,
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread.
*/
+
void
-Field::set_datetime_warning(const uint level, const uint code,
+Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
double nr, timestamp_type ts_type)
{
if (table->in_use->really_abort_on_warning() ||
@@ -8409,30 +8486,3 @@ Field::set_datetime_warning(const uint level, const uint code,
field_name);
}
}
-
-/*
- maximum possible display length for blob
-
- SYNOPSIS
- Field_blob::max_length()
-
- RETURN
- length
-*/
-uint32 Field_blob::max_length()
-{
- switch (packlength)
- {
- case 1:
- return 255;
- case 2:
- return 65535;
- case 3:
- return 16777215;
- case 4:
- return (uint32) 4294967295U;
- default:
- DBUG_ASSERT(0); // we should never go here
- return 0;
- }
-}
diff --git a/sql/field.h b/sql/field.h
index ce6753400bb..365f2c323b9 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -280,17 +280,17 @@ public:
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; }
virtual void set_charset(CHARSET_INFO *charset) { }
- bool set_warning(unsigned int level, unsigned int code,
+ bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
int cuted_increment);
bool check_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs);
- void set_datetime_warning(const uint level, const uint code,
+ void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
const char *str, uint str_len,
timestamp_type ts_type, int cuted_increment);
- void set_datetime_warning(const uint level, const uint code,
+ void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
longlong nr, timestamp_type ts_type,
int cuted_increment);
- void set_datetime_warning(const uint level, const uint code,
+ void set_datetime_warning(MYSQL_ERROR::enum_warning_level, const uint code,
double nr, timestamp_type ts_type);
inline bool check_overflow(int op_result)
{
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 57161a7063e..bbdd6619bf3 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -508,8 +508,16 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
// Check if identical fields
if (from->result_type() == STRING_RESULT)
{
+ /*
+ If we are copying date or datetime's we have to check the dates
+ if we don't allow 'all' dates.
+p */
if (to->real_type() != from->real_type() ||
- !compatible_db_low_byte_first)
+ !compatible_db_low_byte_first ||
+ ((to->table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) &&
+ to->type() == FIELD_TYPE_DATE ||
+ to->type() == FIELD_TYPE_DATETIME))
{
if (from->real_type() == FIELD_TYPE_ENUM ||
from->real_type() == FIELD_TYPE_SET)
@@ -590,7 +598,11 @@ void field_conv(Field *to,Field *from)
(to->field_length == from->field_length &&
(((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
from->charset() == to->charset() &&
- to->table->s->db_low_byte_first == from->table->s->db_low_byte_first)
+ to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
+ (!(to->table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) ||
+ to->type() != FIELD_TYPE_DATE &&
+ to->type() != FIELD_TYPE_DATETIME))
{ // Identical fields
memcpy(to->ptr,from->ptr,to->pack_length());
return;
diff --git a/sql/item.cc b/sql/item.cc
index 48faa3509f4..1572efb0f23 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -46,7 +46,7 @@ void Hybrid_type_traits::fix_length_and_dec(Item *item, Item *arg) const
const Hybrid_type_traits *Hybrid_type_traits::instance()
{
- const static Hybrid_type_traits real_traits;
+ static const Hybrid_type_traits real_traits;
return &real_traits;
}
@@ -70,7 +70,7 @@ Hybrid_type_traits::val_str(Hybrid_type *val, String *to, uint8 decimals) const
const Hybrid_type_traits_decimal *Hybrid_type_traits_decimal::instance()
{
- const static Hybrid_type_traits_decimal decimal_traits;
+ static const Hybrid_type_traits_decimal decimal_traits;
return &decimal_traits;
}
@@ -146,7 +146,7 @@ Hybrid_type_traits_decimal::val_str(Hybrid_type *val, String *to,
const Hybrid_type_traits_integer *Hybrid_type_traits_integer::instance()
{
- const static Hybrid_type_traits_integer integer_traits;
+ static const Hybrid_type_traits_integer integer_traits;
return &integer_traits;
}
@@ -1455,6 +1455,64 @@ void Item_string::print(String *str)
}
+inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str, char *end)
+{
+ return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
+}
+
+
+double Item_string::val_real()
+{
+ DBUG_ASSERT(fixed == 1);
+ int error;
+ char *end, *org_end;
+ double tmp;
+ CHARSET_INFO *cs= str_value.charset();
+
+ org_end= (char*) str_value.ptr() + str_value.length();
+ tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
+ &error);
+ if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
+ {
+ /*
+ We can use str_value.ptr() here as Item_string is gurantee to put an
+ end \0 here.
+ */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
+ str_value.ptr());
+ }
+ return tmp;
+}
+
+
+longlong Item_string::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ int err;
+ longlong tmp;
+ char *end= (char*) str_value.ptr()+ str_value.length();
+ char *org_end= end;
+ CHARSET_INFO *cs= str_value.charset();
+
+ tmp= (*(cs->cset->my_strtoll10))(cs, str_value.ptr(), &end, &err);
+ /*
+ TODO: Give error if we wanted a signed integer and we got an unsigned
+ one
+ */
+ if (err > 0 ||
+ (end != org_end && !check_if_only_end_space(cs, end, org_end)))
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
+ str_value.ptr());
+ }
+ return tmp;
+}
+
+
my_decimal *Item_string::val_decimal(my_decimal *decimal_value)
{
/* following assert is redundant, because fixed=1 assigned in constructor */
@@ -4848,7 +4906,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
int intp2= max_length - min(decimals, NOT_FIXED_DEC - 1);
/* can't be overflow because it work only for decimals (no strings) */
int dec_length= max(intp1, intp2) + decimals;
- max_length= max(max_length, max(item_length, dec_length));
+ max_length= max(max_length, (uint) max(item_length, dec_length));
/*
we can't allow decimals to be NOT_FIXED_DEC, to prevent creation
decimal with max precision (see Field_new_decimal constcuctor)
@@ -4875,8 +4933,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
}
maybe_null|= item->maybe_null;
get_full_info(item);
- DBUG_PRINT("info:", ("become type %d len %d, dec %d",
- fld_type, max_length, decimals));
+ DBUG_PRINT("info", ("become type: %d len: %u dec: %u",
+ (int) fld_type, max_length, (uint) decimals));
DBUG_RETURN(FALSE);
}
diff --git a/sql/item.h b/sql/item.h
index 0a2be74c76c..9acd8ec27fc 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1098,21 +1098,8 @@ public:
fixed= 1;
}
enum Type type() const { return STRING_ITEM; }
- double val_real()
- {
- DBUG_ASSERT(fixed == 1);
- int err_not_used;
- char *end_not_used;
- return my_strntod(str_value.charset(), (char*) str_value.ptr(),
- str_value.length(), &end_not_used, &err_not_used);
- }
- longlong val_int()
- {
- DBUG_ASSERT(fixed == 1);
- int err;
- return my_strntoll(str_value.charset(), str_value.ptr(),
- str_value.length(), 10, (char**) 0, &err);
- }
+ double val_real();
+ longlong val_int();
String *val_str(String*)
{
DBUG_ASSERT(fixed == 1);
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 00d849e55de..0c8baa332ca 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -73,8 +73,8 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
with_null|= item->null_inside();
else
{
- item->val_int();
- with_null|= item->null_value;
+ if (item->is_null())
+ with_null|= 1;
}
}
maybe_null|= item->maybe_null;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3dbc3833f9e..66b64128dab 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2966,8 +2966,7 @@ bool Item_func_group_concat::setup(THD *thd)
DBUG_RETURN(TRUE);
if (item->const_item())
{
- (void) item->val_int();
- if (item->null_value)
+ if (item->is_null())
{
always_null= 1;
DBUG_RETURN(FALSE);
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index c603d41fa2e..1ea20e9d7cc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2181,39 +2181,47 @@ String *Item_char_typecast::val_str(String *str)
res->set_charset(cast_cs);
/*
- Cut the tail if cast with length
- and the result is longer than cast length, e.g.
- CAST('string' AS CHAR(1))
+ Cut the tail if cast with length
+ and the result is longer than cast length, e.g.
+ CAST('string' AS CHAR(1))
*/
if (cast_length >= 0 &&
(res->length() > (length= (uint32) res->charpos(cast_length))))
{ // Safe even if const arg
+ char char_type[40];
+ my_snprintf(char_type, sizeof(char_type), "CHAR(%lu)", length);
+
if (!res->alloced_length())
{ // Don't change const str
str_value= *res; // Not malloced string
res= &str_value;
}
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), char_type,
+ res->c_ptr());
res->length((uint) length);
}
null_value= 0;
return res;
}
+
void Item_char_typecast::fix_length_and_dec()
{
uint32 char_length;
- /*
- We always force character set conversion if cast_cs
- is a multi-byte character set. It garantees that the
- result of CAST is a well-formed string.
- For single-byte character sets we allow just to copy
- from the argument. A single-byte character sets string
- is always well-formed.
+ /*
+ We always force character set conversion if cast_cs is a
+ multi-byte character set. It garantees that the result of CAST is
+ a well-formed string. For single-byte character sets we allow
+ just to copy from the argument. A single-byte character sets
+ string is always well-formed.
*/
- charset_conversion= (cast_cs->mbmaxlen > 1) ||
- !my_charset_same(args[0]->collation.collation, cast_cs) &&
- args[0]->collation.collation != &my_charset_bin &&
- cast_cs != &my_charset_bin;
+ charset_conversion= ((cast_cs->mbmaxlen > 1) ||
+ !my_charset_same(args[0]->collation.collation,
+ cast_cs) &&
+ args[0]->collation.collation != &my_charset_bin &&
+ cast_cs != &my_charset_bin);
collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length :
args[0]->max_length/args[0]->collation.collation->mbmaxlen;
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 19b6abd7243..b4bbef4a637 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -175,7 +175,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
if (end != from_end && !err)
{
- /* Give warining if there is something other than end space */
+ /* Give warning if there is something other than end space */
for ( ; end < from_end; end++)
{
if (!my_isspace(&my_charset_latin1, *end))
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 2685da9780b..7290cfd8e0d 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -442,7 +442,6 @@ extern ulong server_id, concurrency;
typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
uint key_length,
ulonglong *engine_data);
-
#include "sql_string.h"
#include "sql_list.h"
#include "sql_map.h"
@@ -450,6 +449,7 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "handler.h"
#include "parse_file.h"
#include "table.h"
+#include "sql_error.h"
#include "field.h" /* Field definitions */
#include "protocol.h"
#include "sql_udf.h"
@@ -651,11 +651,6 @@ int prepare_create_field(create_field *sql_field,
uint *blob_columns,
int *timestamps, int *timestamps_with_niladic,
uint table_flags);
-int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
- List<create_field> &fields,
- List<Key> &keys, uint &db_options,
- handler *file, KEY *&key_info_buffer,
- uint &key_count, int select_field_count);
bool mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys,
@@ -830,14 +825,6 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
void reset_stmt_for_execute(THD *thd, LEX *lex);
void init_stmt_after_parse(THD*, LEX*);
-/* sql_error.cc */
-MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
- const char *msg);
-void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
- uint code, const char *format, ...);
-void mysql_reset_errors(THD *thd, bool force);
-bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
-
/* sql_handler.cc */
bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 95de170b99d..e1303585114 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1036,8 +1036,8 @@ void clean_up(bool print_message)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
finish_client_errs();
- const char **errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
- x_free((gptr) errmsgs); /* Free messages */
+ my_free((gptr) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
+ MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
(void) pthread_mutex_lock(&LOCK_thread_count);
diff --git a/sql/sp.cc b/sql/sp.cc
index 84169ab8172..23d389cd299 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -64,8 +64,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name,
enum thr_lock_type ltype, TABLE **tablep, bool *opened)
{
TABLE *table;
- byte key[64+64+1]; // db, name, type
- uint keylen;
+ byte key[NAME_LEN*2+4+1]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux");
DBUG_PRINT("enter", ("type: %d name: %*s",
type, name->m_name.length, name->m_name.str));
@@ -78,20 +77,6 @@ db_find_routine_aux(THD *thd, int type, sp_name *name,
if (!mysql_proc_table_exists && ltype == TL_READ)
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
- // Put the key used to read the row together
- keylen= name->m_db.length;
- if (keylen > 64)
- keylen= 64;
- memcpy(key, name->m_db.str, keylen);
- memset(key+keylen, (int)' ', 64-keylen); // Pad with space
- keylen= name->m_name.length;
- if (keylen > 64)
- keylen= 64;
- memcpy(key+64, name->m_name.str, keylen);
- memset(key+64+keylen, (int)' ', 64-keylen); // Pad with space
- key[128]= type;
- keylen= sizeof(key);
-
if (thd->lex->proc_table)
table= thd->lex->proc_table->table;
else
@@ -120,8 +105,22 @@ db_find_routine_aux(THD *thd, int type, sp_name *name,
}
mysql_proc_table_exists= 1;
+ /*
+ Create key to find row. We have to use field->store() to be able to
+ handle VARCHAR and CHAR fields.
+ Assumption here is that the three first fields in the table are
+ 'db', 'name' and 'type' and the first key is the primary key over the
+ same fields.
+ */
+ table->field[0]->store(name->m_db.str, name->m_db.length, &my_charset_bin);
+ table->field[1]->store(name->m_name.str, name->m_name.length,
+ &my_charset_bin);
+ table->field[2]->store((longlong) type);
+ key_copy(key, table->record[0], table->key_info,
+ table->key_info->key_length);
+
if (table->file->index_read_idx(table->record[0], 0,
- key, keylen,
+ key, table->key_info->key_length,
HA_READ_KEY_EXACT))
{
*tablep= NULL;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 39d5c37462b..e712af19a5c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -482,27 +482,6 @@ public:
};
-class MYSQL_ERROR: public Sql_alloc
-{
-public:
- enum enum_warning_level
- { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
-
- uint code;
- enum_warning_level level;
- char *msg;
-
- MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg,
- const char *msg_arg)
- :code(code_arg), level(level_arg)
- {
- if (msg_arg)
- set_msg(thd, msg_arg);
- }
- void set_msg(THD *thd, const char *msg_arg);
-};
-
-
class delayed_insert;
class select_result;
diff --git a/sql/sql_error.h b/sql/sql_error.h
new file mode 100644
index 00000000000..223b50be744
--- /dev/null
+++ b/sql/sql_error.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+class MYSQL_ERROR: public Sql_alloc
+{
+public:
+ enum enum_warning_level
+ { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
+
+ uint code;
+ enum_warning_level level;
+ char *msg;
+
+ MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg,
+ const char *msg_arg)
+ :code(code_arg), level(level_arg)
+ {
+ if (msg_arg)
+ set_msg(thd, msg_arg);
+ }
+ void set_msg(THD *thd, const char *msg_arg);
+};
+
+MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint code, const char *msg);
+void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint code, const char *format, ...);
+void mysql_reset_errors(THD *thd, bool force);
+bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index a0fed715405..c827bbace3e 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -671,7 +671,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (field->type() == FIELD_TYPE_TIMESTAMP)
((Field_timestamp*) field)->set_time();
else if (field != table->next_number_field)
- field->set_warning((uint) MYSQL_ERROR::WARN_LEVEL_WARN,
+ field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_NULL_TO_NOTNULL, 1);
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c0032742a11..1d7eba4ce43 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1909,10 +1909,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
ulong uptime = (ulong) (thd->start_time - start_time);
sprintf((char*) buff,
- "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f",
+ "Uptime: %ld Threads: %d Questions: %lu Slow queries: %lu Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f",
uptime,
- (int) thread_count,thd->query_id,thd->status_var.long_query_count,
- thd->status_var.opened_tables,refresh_version, cached_tables(),
+ (int) thread_count, (ulong) thd->query_id,
+ (ulong) thd->status_var.long_query_count,
+ thd->status_var.opened_tables, refresh_version, cached_tables(),
uptime ? (float)thd->query_id/(float)uptime : 0);
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4105d63330a..49ecd2591dd 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -633,11 +633,12 @@ int prepare_create_field(create_field *sql_field,
-1 error
*/
-int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
- List<create_field> &fields,
- List<Key> &keys, bool tmp_table, uint &db_options,
- handler *file, KEY *&key_info_buffer,
- uint *key_count, int select_field_count)
+static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
+ List<create_field> *fields,
+ List<Key> *keys, bool tmp_table,
+ uint *db_options,
+ handler *file, KEY **key_info_buffer,
+ uint *key_count, int select_field_count)
{
const char *key_name;
create_field *sql_field,*dup_field;
@@ -649,11 +650,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
int timestamps= 0, timestamps_with_niladic= 0;
int field_no,dup_no;
int select_field_pos,auto_increment=0;
- List_iterator<create_field> it(fields),it2(fields);
+ List_iterator<create_field> it(*fields),it2(*fields);
uint total_uneven_bit_length= 0;
DBUG_ENTER("mysql_prepare_table");
- select_field_pos=fields.elements - select_field_count;
+ select_field_pos= fields->elements - select_field_count;
null_fields=blob_columns=0;
create_info->varchar= 0;
@@ -858,11 +859,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if ((sql_field->flags & BLOB_FLAG) ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
create_info->row_type != ROW_TYPE_FIXED)
- db_options|= HA_OPTION_PACK_RECORD;
+ (*db_options)|= HA_OPTION_PACK_RECORD;
it2.rewind();
}
/* If fixed row records, we need one bit to check for deleted rows */
- if (!(db_options & HA_OPTION_PACK_RECORD))
+ if (!((*db_options) & HA_OPTION_PACK_RECORD))
null_fields++;
pos= (null_fields + total_uneven_bit_length + 7) / 8;
@@ -910,7 +911,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* Create keys */
- List_iterator<Key> key_iterator(keys), key_iterator2(keys);
+ List_iterator<Key> key_iterator(*keys), key_iterator2(*keys);
uint key_parts=0, fk_key_count=0;
bool primary_key=0,unique_key=0;
Key *key, *key2;
@@ -997,9 +998,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
- key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)* *key_count);
+ (*key_info_buffer) = key_info= (KEY*) sql_calloc(sizeof(KEY)* *key_count);
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
- if (!key_info_buffer || ! key_part_info)
+ if (!*key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory
key_iterator.rewind();
@@ -1273,7 +1274,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
key_part_info->length=(uint16) length;
/* Use packed keys for long strings on the first column */
- if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
+ if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
(length >= KEY_DEFAULT_PACK_LENGTH &&
(sql_field->sql_type == MYSQL_TYPE_STRING ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
@@ -1304,8 +1305,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
else if (!(key_name = key->name))
key_name=make_unique_key_name(sql_field->field_name,
- key_info_buffer,key_info);
- if (check_if_keyname_exists(key_name,key_info_buffer,key_info))
+ *key_info_buffer, key_info);
+ if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
{
my_error(ER_DUP_KEYNAME, MYF(0), key_name);
DBUG_RETURN(-1);
@@ -1340,7 +1341,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
/* Sort keys in optimized order */
- qsort((gptr) key_info_buffer, *key_count, sizeof(KEY),
+ qsort((gptr) *key_info_buffer, *key_count, sizeof(KEY),
(qsort_cmp) sort_keys);
DBUG_RETURN(0);
@@ -1406,7 +1407,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
ha_get_storage_engine(new_db_type),
table_name);
}
- db_options=create_info->table_options;
+ db_options= create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC)
db_options|=HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
@@ -1445,9 +1446,9 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
create_info->default_table_charset= db_info.default_table_charset;
}
- if (mysql_prepare_table(thd, create_info, fields,
- keys, internal_tmp_table, db_options, file,
- key_info_buffer, &key_count,
+ if (mysql_prepare_table(thd, create_info, &fields,
+ &keys, internal_tmp_table, &db_options, file,
+ &key_info_buffer, &key_count,
select_field_count))
DBUG_RETURN(TRUE);
@@ -2719,9 +2720,9 @@ int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info.db_type=DB_TYPE_DEFAULT;
create_info.default_table_charset= thd->variables.collation_database;
db_options= 0;
- if (mysql_prepare_table(thd, &create_info, fields,
- keys, /*tmp_table*/ 0, db_options, table->file,
- key_info_buffer, key_count,
+ if (mysql_prepare_table(thd, &create_info, &fields,
+ &keys, /*tmp_table*/ 0, &db_options, table->file,
+ &key_info_buffer, key_count,
/*select_field_count*/ 0))
DBUG_RETURN(-1);
@@ -2852,9 +2853,9 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
{
db_options= 0;
if (table->file->drop_index(table, key_numbers, key_count)||
- mysql_prepare_table(thd, &create_info, fields,
- keys, /*tmp_table*/ 0, db_options, table->file,
- key_info_buffer, key_count,
+ mysql_prepare_table(thd, &create_info, &fields,
+ &keys, /*tmp_table*/ 0, &db_options, table->file,
+ &key_info_buffer, key_count,
/*select_field_count*/ 0)||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
table_list->db, (lower_case_table_names == 2)?
@@ -3679,6 +3680,13 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (to->file->external_lock(thd, F_WRLCK))
DBUG_RETURN(-1);
+
+ /* We can abort alter table for any table type */
+ thd->no_trans_update= 0;
+ thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES));
+
from->file->info(HA_STATUS_VARIABLE);
to->file->start_bulk_insert(from->file->records);
@@ -3758,6 +3766,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
else
to->next_number_field->reset();
}
+
for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
{
copy_ptr->do_copy(copy_ptr);
@@ -3802,6 +3811,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
err:
thd->variables.sql_mode= save_sql_mode;
+ thd->abort_on_warning= 0;
free_io_cache(from);
*copied= found_count;
*deleted=delete_count;
diff --git a/sql/time.cc b/sql/time.cc
index f1d21915c23..a3ec2283860 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -186,6 +186,7 @@ ulong convert_month_to_period(ulong month)
NOTE
See description of str_to_datetime() for more information.
*/
+
timestamp_type
str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
uint flags)
@@ -199,7 +200,7 @@ str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
(MODE_INVALID_DATES |
MODE_NO_ZERO_DATE))),
&was_cut);
- if (was_cut)
+ if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
make_truncated_value_warning(current_thd, str, length, ts_type, NullS);
return ts_type;
}
@@ -712,9 +713,9 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
else
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
ER(ER_TRUNCATED_WRONG_VALUE),
- type_str, str.ptr());
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE, warn_buff);
+ type_str, str.c_ptr());
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE, warn_buff);
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 3e85767dc86..57e2c1029f1 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -40,7 +40,7 @@ static bool pack_header(uchar *forminfo,enum db_type table_type,
static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
create_field *last_field);
static bool pack_fields(File file, List<create_field> &create_fields);
-static bool make_empty_rec(int file, enum db_type table_type,
+static bool make_empty_rec(THD *thd, int file, enum db_type table_type,
uint table_options,
List<create_field> &create_fields,
uint reclength,uint null_fields);
@@ -134,7 +134,7 @@ bool mysql_create_frm(THD *thd, my_string file_name,
VOID(my_seek(file,
(ulong) uint2korr(fileinfo+6)+ (ulong) key_buff_length,
MY_SEEK_SET,MYF(0)));
- if (make_empty_rec(file,create_info->db_type,create_info->table_options,
+ if (make_empty_rec(thd,file,create_info->db_type,create_info->table_options,
create_fields,reclength,null_fields))
goto err;
@@ -640,7 +640,7 @@ static bool pack_fields(File file,List<create_field> &create_fields)
/* save an empty record on start of formfile */
-static bool make_empty_rec(File file,enum db_type table_type,
+static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
uint table_options,
List<create_field> &create_fields,
uint reclength, uint null_fields)
@@ -652,6 +652,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
TABLE table;
create_field *field;
handler *handler;
+ enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
DBUG_ENTER("make_empty_rec");
/* We need a table to generate columns for default values */
@@ -666,7 +667,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
DBUG_RETURN(1);
}
- table.in_use= current_thd;
+ table.in_use= thd;
table.s->db_low_byte_first= handler->low_byte_first();
table.s->blob_ptr_size= portable_sizeof_char_ptr;
@@ -681,6 +682,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
null_pos=buff;
List_iterator<create_field> it(create_fields);
+ thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
while ((field=it++))
{
Field *regfield=make_field((char*) buff+field->offset,field->length,
@@ -709,7 +711,14 @@ static bool make_empty_rec(File file,enum db_type table_type,
if (field->def &&
(regfield->real_type() != FIELD_TYPE_YEAR ||
field->def->val_int() != 0))
- (void) field->def->save_in_field(regfield, 1);
+ {
+ if (field->def->save_in_field(regfield, 1))
+ {
+ my_error(ER_INVALID_DEFAULT, MYF(0), regfield->field_name);
+ error= 1;
+ goto err;
+ }
+ }
else if (regfield->real_type() == FIELD_TYPE_ENUM &&
(field->flags & NOT_NULL_FLAG))
{
@@ -728,7 +737,10 @@ static bool make_empty_rec(File file,enum db_type table_type,
/* Fill not used startpos */
bfill((byte*) buff+null_length,firstpos-null_length,255);
error=(int) my_write(file,(byte*) buff,(uint) reclength,MYF_RW);
+
+err:
my_free((gptr) buff,MYF(MY_FAE));
delete handler;
+ thd->count_cuted_fields= old_count_cuted_fields;
DBUG_RETURN(error);
} /* make_empty_rec */