summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authordlenev@mysql.com <>2003-12-02 20:30:10 +0300
committerdlenev@mysql.com <>2003-12-02 20:30:10 +0300
commit0add9610617e690c5a6340f7783795d74f3a27c6 (patch)
treefbf0eec48406e657e106f0fcd0312f6f4bf8cfc9 /sql/field.cc
parentb40eb13b792038c0820d6e0833009558e4980357 (diff)
parentdd37ef055b73645e3f6314239ab276106c3bfa1f (diff)
downloadmariadb-git-0add9610617e690c5a6340f7783795d74f3a27c6.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-4.0
into mysql.com:/home/dlenev/src/mysql-4.0-tsbg
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc72
1 files changed, 50 insertions, 22 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 43481ca0963..259314cb4db 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2520,31 +2520,59 @@ void Field_timestamp::store(double nr)
** function.
*/
-static longlong fix_datetime(longlong nr)
+static longlong fix_datetime(longlong nr, TIME *time_res)
{
+ long part1,part2;
+
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->month <= 12 && time_res->day <= 31 && time_res->hour <= 23 &&
+ time_res->minute <= 59 && time_res->second <= 59)
+ return nr;
+
err:
current_thd->cuted_fields++;
return LL(0);
@@ -2555,20 +2583,18 @@ void Field_timestamp::store(longlong nr)
{
TIME l_time;
time_t timestamp;
- long part1,part2;
- if ((nr=fix_datetime(nr)))
+ if ((nr=fix_datetime(nr, &l_time)))
{
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);
+
+ if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR)
+ {
+ current_thd->cuted_fields++;
+ timestamp=0;
+ }
+ else
+ timestamp=my_gmt_sec(&l_time, &not_used);
}
else
timestamp=0;
@@ -3406,13 +3432,15 @@ void Field_datetime::store(double nr)
void Field_datetime::store(longlong nr)
{
- if (nr < 0 || nr > LL(99991231235959))
+ TIME l_time;
+
+ nr=fix_datetime(nr, &l_time);
+
+ if (l_time.year > 9999)
{
nr=0;
current_thd->cuted_fields++;
}
- else
- nr=fix_datetime(nr);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{