~drizzle-trunk/drizzle/development

574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
20
#include "config.h"
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
21
813.1.17 by Jay Pipes
Fixes MICROSECOND() to use new Temporal system and throw appropriate errors on bad datetimes. Adds new microsecond.test case. Still to do: don't have microseconds thrown away by DATETIME type... :)
22
#include "drizzled/temporal.h"
23
#include "drizzled/error.h"
24
#include "drizzled/function/time/microsecond.h"
574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
25
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
26
namespace drizzled
27
{
28
574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
29
int64_t Item_func_microsecond::val_int()
30
{
813.1.17 by Jay Pipes
Fixes MICROSECOND() to use new Temporal system and throw appropriate errors on bad datetimes. Adds new microsecond.test case. Still to do: don't have microseconds thrown away by DATETIME type... :)
31
  assert(fixed);
32
33
  if (args[0]->is_null())
34
  {
35
    /* For NULL argument, we return a NULL result */
36
    null_value= true;
37
    return 0;
38
  }
39
40
  /* 
41
   * Because of the ridiculous way in which MySQL handles
42
   * TIME values (it does implicit integer -> string conversions
43
   * but only for DATETIME, not TIME values) we must first 
44
   * try a conversion into a TIME from a string.  If this
45
   * fails, we fall back on a DATETIME conversion.  This is
46
   * necessary because of the fact that DateTime::from_string()
47
   * looks first for DATETIME, then DATE regex matches.  6 consecutive
48
   * numbers, say 231130, will match the DATE regex YYMMDD
49
   * with no TIME part, but MySQL actually implicitly treats
50
   * parameters to SECOND(), HOUR(), and MINUTE() as TIME-only
51
   * values and matches 231130 as HHmmSS!
52
   *
53
   * Oh, and Brian Aker MADE me do this. :) --JRP
54
   */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
55
  Time temporal_time;
813.1.17 by Jay Pipes
Fixes MICROSECOND() to use new Temporal system and throw appropriate errors on bad datetimes. Adds new microsecond.test case. Still to do: don't have microseconds thrown away by DATETIME type... :)
56
  
57
  char time_buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
58
  String tmp_time(time_buff,sizeof(time_buff), &my_charset_utf8_bin);
59
  String *time_res= args[0]->val_str(&tmp_time);
60
  if (! temporal_time.from_string(time_res->c_ptr(), time_res->length()))
61
  {
62
    /* 
63
     * OK, we failed to match the first argument as a string
64
     * representing a time value, so we grab the first argument 
65
     * as a DateTime object and try that for a match...
66
     */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
67
    DateTime temporal_datetime;
813.1.17 by Jay Pipes
Fixes MICROSECOND() to use new Temporal system and throw appropriate errors on bad datetimes. Adds new microsecond.test case. Still to do: don't have microseconds thrown away by DATETIME type... :)
68
    Item_result arg0_result_type= args[0]->result_type();
69
    
70
    switch (arg0_result_type)
71
    {
813.1.19 by Jay Pipes
To remain in compatibility with MySQL, added ability to interpret
72
      case DECIMAL_RESULT: 
73
        /* 
74
         * For doubles supplied, interpret the arg as a string, 
75
         * so intentionally fall-through here...
76
         * This allows us to accept double parameters like 
77
         * 19971231235959.01 and interpret it the way MySQL does:
78
         * as a TIMESTAMP-like thing with a microsecond component.
79
         * Ugh, but need to keep backwards-compat.
80
         */
813.1.17 by Jay Pipes
Fixes MICROSECOND() to use new Temporal system and throw appropriate errors on bad datetimes. Adds new microsecond.test case. Still to do: don't have microseconds thrown away by DATETIME type... :)
81
      case STRING_RESULT:
82
        {
83
          char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
84
          String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
85
          String *res= args[0]->val_str(&tmp);
86
          if (! temporal_datetime.from_string(res->c_ptr(), res->length()))
87
          {
88
            /* 
89
            * Could not interpret the function argument as a temporal value, 
90
            * so throw an error and return 0
91
            */
92
            my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
93
            return 0;
94
          }
95
        }
96
        break;
97
      case INT_RESULT:
98
        if (temporal_datetime.from_int64_t(args[0]->val_int()))
99
          break;
100
        /* Intentionally fall-through on invalid conversion from integer */
101
      default:
102
        {
103
          /* 
104
          * Could not interpret the function argument as a temporal value, 
105
          * so throw an error and return 0
106
          */
107
          null_value= true;
108
          char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
109
          String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
110
          String *res;
111
112
          res= args[0]->val_str(&tmp);
113
114
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
115
          return 0;
116
        }
117
    }
118
    return (int64_t) temporal_datetime.useconds();
119
  }
120
  return (int64_t) temporal_time.useconds();
574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
121
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
122
123
} /* namespace drizzled */