~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
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
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);
1750.3.1 by David Shrewsbury
Use of String::c_ptr() in temporal functions can corrupt PBXT row cache, so make sure temporaries are used.
60
61
  if (time_res && (time_res != &tmp_time))
62
  {
63
    tmp_time.copy(*time_res);
64
  }
65
66
  if (! temporal_time.from_string(tmp_time.c_ptr(), tmp_time.length()))
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... :)
67
  {
68
    /* 
69
     * OK, we failed to match the first argument as a string
70
     * representing a time value, so we grab the first argument 
71
     * as a DateTime object and try that for a match...
72
     */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
73
    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... :)
74
    Item_result arg0_result_type= args[0]->result_type();
75
    
76
    switch (arg0_result_type)
77
    {
813.1.19 by Jay Pipes
To remain in compatibility with MySQL, added ability to interpret
78
      case DECIMAL_RESULT: 
79
        /* 
80
         * For doubles supplied, interpret the arg as a string, 
81
         * so intentionally fall-through here...
82
         * This allows us to accept double parameters like 
83
         * 19971231235959.01 and interpret it the way MySQL does:
84
         * as a TIMESTAMP-like thing with a microsecond component.
85
         * Ugh, but need to keep backwards-compat.
86
         */
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... :)
87
      case STRING_RESULT:
88
        {
89
          char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
90
          String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
91
          String *res= args[0]->val_str(&tmp);
1750.3.1 by David Shrewsbury
Use of String::c_ptr() in temporal functions can corrupt PBXT row cache, so make sure temporaries are used.
92
93
          if (res && (res != &tmp))
94
          {
95
            tmp.copy(*res);
96
          }
97
98
          if (! temporal_datetime.from_string(tmp.c_ptr(), tmp.length()))
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... :)
99
          {
100
            /* 
101
            * Could not interpret the function argument as a temporal value, 
102
            * so throw an error and return 0
103
            */
1750.3.1 by David Shrewsbury
Use of String::c_ptr() in temporal functions can corrupt PBXT row cache, so make sure temporaries are used.
104
            my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
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... :)
105
            return 0;
106
          }
107
        }
108
        break;
109
      case INT_RESULT:
110
        if (temporal_datetime.from_int64_t(args[0]->val_int()))
111
          break;
112
        /* Intentionally fall-through on invalid conversion from integer */
113
      default:
114
        {
115
          /* 
116
          * Could not interpret the function argument as a temporal value, 
117
          * so throw an error and return 0
118
          */
119
          null_value= true;
120
          char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
121
          String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
122
          String *res;
123
124
          res= args[0]->val_str(&tmp);
125
1750.3.1 by David Shrewsbury
Use of String::c_ptr() in temporal functions can corrupt PBXT row cache, so make sure temporaries are used.
126
          if (res && (res != &tmp))
127
          {
128
            tmp.copy(*res);
129
          }
130
131
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
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... :)
132
          return 0;
133
        }
134
    }
135
    return (int64_t) temporal_datetime.useconds();
136
  }
137
  return (int64_t) temporal_time.useconds();
574.3.19 by Lee
moving functions from item_timefunc to functions/time directory
138
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
139
140
} /* namespace drizzled */