summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2003-12-17 17:35:34 +0200
committerunknown <monty@mysql.com>2003-12-17 17:35:34 +0200
commit0fb88806e44f48aba363bfda5ebedaaa3b05b975 (patch)
tree93924b5aab311e02a0f0931cf91e67cdfad04bdf /sql/field.cc
parent029e30b4aa357708bdbf924cfd78069fb19382bb (diff)
parent4bdfe0fb0107f2fb3e9cfb1c8a417e1028c67dcc (diff)
downloadmariadb-git-0fb88806e44f48aba363bfda5ebedaaa3b05b975.tar.gz
Merge with 4.0.17
BitKeeper/etc/logging_ok: auto-union Build-tools/Do-compile: Auto merged acinclude.m4: Auto merged configure.in: Auto merged dbug/dbug.c: Auto merged include/config-win.h: Auto merged include/my_base.h: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/my_sys.h: Auto merged include/mysql.h: Auto merged include/mysql_com.h: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/row/row0umod.c: Auto merged innobase/row/row0upd.c: Auto merged myisam/ft_boolean_search.c: Auto merged myisam/mi_check.c: Auto merged myisam/mi_dbug.c: Auto merged myisam/mi_open.c: Auto merged mysql-test/r/auto_increment.result: Auto merged mysql-test/r/bdb.result: Auto merged mysql-test/r/func_op.result: Auto merged Build-tools/Bootstrap: Merge with 4.0 client/mysql.cc: Merge with 4.0 client/mysqldump.c: Merge with 4.0 client/mysqltest.c: Use local version innobase/btr/btr0cur.c: Merge with 4.0 (Heikki should check if we should remove btr_cur_update_sec_rec_in_place() libmysql/libmysql.c: Merge with 4.0 libmysqld/lib_sql.cc: Merge with 4.0 myisam/mi_key.c: Merge with 4.0 myisam/mi_search.c: Merge with 4.0 mysql-test/r/binary.result: Merge with 4.0 mysql-test/r/func_group.result: Merge with 4.0 mysql-test/r/func_str.result: Merge with 4.0 mysql-test/r/func_time.result: Merge with 4.0 mysql-test/r/group_by.result: Merge with 4.0 mysql-test/r/handler.result: Merge with 4.0 mysql-test/r/innodb.result: Merge with 4.0 mysql-test/r/insert.result: Merge with 4.0 mysql-test/r/join_outer.result: Merge with 4.0 mysql-test/r/loaddata.result: Merge with 4.0 mysql-test/r/lowercase_table.result: Merge with 4.0 mysql-test/r/multi_update.result: Merge with 4.0 mysql-test/r/mysqldump.result: Merge with 4.0 mysql-test/r/query_cache.result: Merge with 4.0 mysql-test/r/rpl_max_relay_size.result: Merge with 4.0 mysql-test/r/rpl_rotate_logs.result: Merge with 4.0 mysql-test/r/rpl_trunc_binlog.result: Merge with 4.0 mysql-test/r/select_found.result: Merge with 4.0 mysql-test/r/symlink.result: Merge with 4.0 mysql-test/r/truncate.result: Merge with 4.0 mysql-test/r/type_blob.result: Merge with 4.0 mysql-test/r/type_datetime.result: Merge with 4.0 mysql-test/r/type_decimal.result: Merge with 4.0 mysql-test/r/type_enum.result: Merge with 4.0 mysql-test/r/type_timestamp.result: Merge with 4.0 mysql-test/r/union.result: Merge with 4.0 mysql-test/t/auto_increment.test: Merge with 4.0 mysql-test/t/bdb.test: Merge with 4.0 mysql-test/t/func_group.test: Merge with 4.0 mysql-test/t/func_op.test: Merge with 4.0 mysql-test/t/func_str.test: Merge with 4.0 mysql-test/t/func_time.test: Merge with 4.0 mysql-test/t/group_by.test: Merge with 4.0 mysql-test/t/handler.test: Merge with 4.0 mysql-test/t/innodb.test: Merge with 4.0 mysql-test/t/insert.test: Merge with 4.0 mysql-test/t/join_outer.test: Merge with 4.0 mysql-test/t/limit.test: Merge with 4.0 mysql-test/t/loaddata.test: Merge with 4.0 mysql-test/t/lowercase_table.test: Merge with 4.0 mysql-test/t/multi_update.test: Merge with 4.0 mysql-test/t/mysqldump.test: Merge with 4.0 mysql-test/t/query_cache.test: Merge with 4.0 mysql-test/t/rpl_log_pos.test: Merge with 4.0 mysql-test/t/rpl_max_relay_size.test: Merge with 4.0 mysql-test/t/rpl_rotate_logs.test: Merge with 4.0 mysql-test/t/rpl_trunc_binlog.test: Merge with 4.0 mysql-test/t/select_found.test: Merge with 4.0 mysql-test/t/symlink.test: Merge with 4.0 mysql-test/t/truncate.test: Merge with 4.0 mysql-test/t/type_blob.test: Merge with 4.0 mysql-test/t/type_datetime.test: Merge with 4.0 mysql-test/t/type_decimal.test: Merge with 4.0 mysql-test/t/type_enum.test: Merge with 4.0 mysql-test/t/type_timestamp.test: Merge with 4.0 mysql-test/t/union.test: Merge with 4.0 mysys/charset.c: Merge with 4.0 mysys/my_init.c: Merge with 4.0 mysys/my_symlink.c: Merge with 4.0 mysys/my_thr_init.c: Merge with 4.0 regex/reginit.c: Merge with 4.0 sql/field.cc: Change fix_datetime() to print errors sql/field.h: Merge with 4.0 sql/ha_innodb.cc: Merge with 4.0 sql/item.cc: Merge with 4.0 sql/item.h: Merge with 4.0 sql/item_cmpfunc.cc: Merge with 4.0 sql/item_func.cc: Merge with 4.0 sql/item_func.h: Merge with 4.0 sql/item_strfunc.cc: Merge with 4.0 sql/item_strfunc.h: Merge with 4.0 sql/item_sum.cc: Merge with 4.0 sql/item_sum.h: Merge with 4.0 sql/item_timefunc.cc: Merge with 4.0 sql/lex.h: Merge with 4.0 sql/log.cc: Merge with 4.0 sql/log_event.cc: Merge with 4.0 sql/log_event.h: Merge with 4.0 sql/mysql_priv.h: Merge with 4.0 sql/mysqld.cc: Merge with 4.0 sql/nt_servc.cc: Merge with 4.0 sql/opt_range.cc: Merge with 4.0 sql/records.cc: Merge with 4.0 sql/repl_failsafe.cc: Merge with 4.0 sql/slave.cc: Merge with 4.0 sql/sql_acl.cc: Merge with 4.0 sql/sql_analyse.cc: Merge with 4.0 sql/sql_base.cc: Merge with 4.0 sql/sql_cache.cc: Merge with 4.0 sql/sql_class.h: Merge with 4.0 sql/sql_db.cc: Merge with 4.0 sql/sql_delete.cc: Merge with 4.0 sql/sql_insert.cc: Merge with 4.0 sql/sql_load.cc: Merge with 4.0 sql/sql_parse.cc: Merge with 4.0 sql/sql_rename.cc: Merge with 4.0 sql/sql_select.cc: Merge with 4.0 sql/sql_show.cc: Merge with 4.0 sql/sql_table.cc: Merge with 4.0 sql/sql_update.cc: Merge with 4.0 sql/sql_yacc.yy: Merge with 4.0 sql/table.cc: Merge with 4.0 sql/table.h: Merge with 4.0 sql/time.cc: Merge with 4.0 sql/uniques.cc: Merge with 4.0 strings/ctype-tis620.c: Merge with 4.0 strings/strto.c: Merge with 4.0 support-files/mysql.server.sh: Merge with 4.0 support-files/mysql.spec.sh: Merge with 4.0
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc136
1 files changed, 81 insertions, 55 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 23f6e1232b6..c54e27360b5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -791,7 +791,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
if (zerofill)
{
left_wall=to-1;
- while (pos != left_wall) // Fill with zeros
+ while (pos > left_wall) // Fill with zeros
*pos--='0';
}
else
@@ -799,7 +799,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
left_wall=to+(sign_char != 0)-1;
if (!expo_sign_char) // If exponent was specified, ignore prezeros
{
- for (;pos != left_wall && pre_zeros_from !=pre_zeros_end;
+ for (;pos > left_wall && pre_zeros_from !=pre_zeros_end;
pre_zeros_from++)
*pos--= '0';
}
@@ -1016,7 +1016,7 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
return 0;
if (*a_ptr == '-')
return -1;
- else if (*b_ptr == '-')
+ if (*b_ptr == '-')
return 1;
while (a_ptr != end)
@@ -2853,34 +2853,71 @@ int Field_timestamp::store(double nr)
function.
*/
-static longlong fix_datetime(longlong nr)
+static longlong fix_datetime(longlong nr, TIME *time_res,
+ const char *field_name, bool *error)
{
- current_thd->last_cuted_field= 0;
+ long part1,part2;
+
+ *error= 0;
if (nr == LL(0) || nr >= LL(10000101000000))
- return nr; // Normal datetime >= Year 1000
+ goto ok;
if (nr < 101)
goto err;
if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
- return (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ {
+ nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ goto ok;
+ }
if (nr < (YY_PART_YEAR)*10000L+101L)
goto err;
if (nr <= 991231L)
- return (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ {
+ nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ goto ok;
+ }
if (nr < 10000101L)
goto err;
if (nr <= 99991231L)
- return nr*1000000L;
+ {
+ nr= nr*1000000L;
+ goto ok;
+ }
if (nr < 101000000L)
goto err;
if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
- return nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ {
+ nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ goto ok;
+ }
if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000))
goto err;
if (nr <= LL(991231235959))
- return nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
-
+ nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
+
+ ok:
+ part1=(long) (nr/LL(1000000));
+ part2=(long) (nr - (longlong) part1*LL(1000000));
+ time_res->year= (int) (part1/10000L); part1%=10000L;
+ time_res->month= (int) part1 / 100;
+ time_res->day= (int) part1 % 100;
+ time_res->hour= (int) (part2/10000L); part2%=10000L;
+ time_res->minute=(int) part2 / 100;
+ time_res->second=(int) part2 % 100;
+
+ if (time_res->year <= 9999 && time_res->month <= 12 &&
+ time_res->day <= 31 && time_res->hour <= 23 &&
+ time_res->minute <= 59 && time_res->second <= 59)
+ return nr;
+
err:
- current_thd->last_cuted_field= 1;
+ if (thd->count_cuted_fields)
+ {
+ thd->cuted_fields++;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
+ field_name, thd->row_count);
+ }
+ *error= 1;
return LL(0);
}
@@ -2888,24 +2925,17 @@ static longlong fix_datetime(longlong nr)
int Field_timestamp::store(longlong nr)
{
TIME l_time;
- time_t timestamp;
- long part1,part2;
+ time_t timestamp= 0;
+ bool error;
- if ((nr=fix_datetime(nr)))
+ if ((nr= fix_datetime(nr, &l_time, field_name, &error)))
{
long not_used;
- part1=(long) (nr/LL(1000000));
- part2=(long) (nr - (longlong) part1*LL(1000000));
- l_time.year= (int) (part1/10000L); part1%=10000L;
- l_time.month= (int) part1 / 100;
- l_time.day= (int) part1 % 100;
- l_time.hour= (int) (part2/10000L); part2%=10000L;
- l_time.minute=(int) part2 / 100;
- l_time.second=(int) part2 % 100;
- timestamp=my_gmt_sec(&l_time, &not_used);
- }
- else
- timestamp=0;
+
+ if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1)
+ goto err;
+ timestamp= my_gmt_sec(&l_time, &not_used);
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2914,9 +2944,14 @@ int Field_timestamp::store(longlong nr)
else
#endif
longstore(ptr,(uint32) timestamp);
- if (current_thd->last_cuted_field)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
- return 0;
+ return error;
+
+err:
+ longstore(ptr,(uint32) 0);
+ if (current_thd->count_cuted_fields)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
+ field_name, 0);
+ return 1;
}
@@ -3350,7 +3385,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE);
return 1;
}
- else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
+ if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
if (nr != 0 || len != 4)
{
@@ -3363,6 +3398,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
return 0;
}
+
int Field_year::store(double nr)
{
if (nr < 0.0 || nr >= 2155.0)
@@ -3825,15 +3861,10 @@ int Field_datetime::store(double nr)
int Field_datetime::store(longlong nr)
{
- int error= 0;
- if (nr < 0 || nr > LL(99991231235959))
- {
- nr=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE);
- error= 1;
- }
- else
- nr=fix_datetime(nr);
+ TIME not_used;
+ bool error;
+
+ nr= fix_datetime(nr, &not_used, field_name, &error);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -3842,11 +3873,10 @@ int Field_datetime::store(longlong nr)
else
#endif
longlongstore(ptr,nr);
- if (current_thd->last_cuted_field)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
return error;
}
+
void Field_datetime::store_time(TIME *ltime,timestamp_type type)
{
longlong tmp;
@@ -5064,7 +5094,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
uint tmp=find_type(typelib, from, length, 0);
if (!tmp)
{
- if (length < 6) // Can't be more than 99999 enums
+ if (length < 6) // Can't be more than 99999 enums
{
/* This is for reading numbers with LOAD DATA INFILE */
char *end;
@@ -5159,7 +5189,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
{
uint tmp=(uint) Field_enum::val_int();
if (!tmp || tmp > typelib->count)
- val_ptr->length(0);
+ val_ptr->set((char*)"",0);
else
val_ptr->set((const char*) typelib->type_names[tmp-1],
(uint) strlen(typelib->type_names[tmp-1]),
@@ -5219,12 +5249,13 @@ void Field_enum::sql_type(String &res) const
int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
{
- bool set_warning= 0;
+ bool got_warning= 0;
int err= 0;
char *not_used;
uint not_used2;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
if (use_conversion(cs, field_charset))
{
@@ -5233,7 +5264,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
length= tmpstr.length();
}
ulonglong tmp= find_set(typelib, from, length, &not_used, &not_used2,
- &set_warning);
+ &got_warning);
if (!tmp && length && length < 22)
{
/* This is for reading numbers with LOAD DATA INFILE */
@@ -5243,16 +5274,11 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1))
{
tmp=0;
- THD *thd= current_thd;
- if (thd->count_cuted_fields)
- {
- thd->cuted_fields++;
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
- field_name, 0);
- }
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
}
}
+ else if (got_warning)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
store_type(tmp);
return err;
}