~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/time/to_days.cc

Merged from Toru - removal of my_time_t.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
21
 
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
22
22
#include <drizzled/function/time/to_days.h>
23
 
#include <drizzled/error.h>
24
 
#include <drizzled/temporal.h>
25
 
 
26
 
namespace drizzled
27
 
{
28
 
 
29
 
/* 
30
 
 * We intepret the first argument as a DateTime and then convert
31
 
 * it to a Julian Day Number and return it.
32
 
 */
 
23
 
33
24
int64_t Item_func_to_days::val_int()
34
25
{
35
 
  assert(fixed);
36
 
 
37
 
  /* We return NULL from FROM_DAYS() only when supplied a NULL argument */
38
 
  if (args[0]->null_value)
39
 
  {
40
 
    null_value= true;
41
 
    return false;
42
 
  }
43
 
 
44
 
  /*
45
 
   * We attempt to convert the first argument into a
46
 
   * temporal value.  If the conversion is successful, 
47
 
   * we know that a conversion to a Julian Day Number
48
 
   * is always possible.  Upon successful conversion, 
49
 
   * we return the Julian Day Number.  If no conversion
50
 
   * was possible into a temporal value, we throw an 
51
 
   * error and return 0, setting the null_value flag to true.
52
 
   */
53
 
  /* Grab the first argument as a DateTime object */
54
 
  DateTime temporal;
55
 
  Item_result arg0_result_type= args[0]->result_type();
56
 
  
57
 
  switch (arg0_result_type)
58
 
  {
59
 
    case REAL_RESULT:
60
 
    case DECIMAL_RESULT: 
61
 
      /* 
62
 
       * For doubles supplied, interpret the arg as a string, 
63
 
       * so intentionally fall-through here...
64
 
       * This allows us to accept double parameters like 
65
 
       * 19971231235959.01 and interpret it the way MySQL does:
66
 
       * as a TIMESTAMP-like thing with a microsecond component.
67
 
       * Ugh, but need to keep backwards-compat.
68
 
       */
69
 
    case STRING_RESULT:
70
 
      {
71
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
72
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
73
 
        String *res= args[0]->val_str(&tmp);
74
 
 
75
 
        if (! res)
76
 
        {
77
 
          /* 
78
 
           * Likely a nested function issue where the nested
79
 
           * function had bad input.  We rely on the nested
80
 
           * function my_error() and simply return false here.
81
 
           */
82
 
          return false;
83
 
        }
84
 
 
85
 
        if (res != &tmp)
86
 
        {
87
 
          tmp.copy(*res);
88
 
        }
89
 
 
90
 
        if (! temporal.from_string(tmp.c_ptr(), tmp.length()))
91
 
        {
92
 
          /* 
93
 
          * Could not interpret the function argument as a temporal value, 
94
 
          * so throw an error and return 0
95
 
          */
96
 
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
97
 
          return 0;
98
 
        }
99
 
      }
100
 
      break;
101
 
    case INT_RESULT:
102
 
      if (temporal.from_int64_t(args[0]->val_int()))
103
 
        break;
104
 
      /* Intentionally fall-through on invalid conversion from integer */
105
 
    default:
106
 
      {
107
 
        /* 
108
 
        * Could not interpret the function argument as a temporal value, 
109
 
        * so throw an error and return 0
110
 
        */
111
 
        null_value= true;
112
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
113
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
114
 
        String *res;
115
 
 
116
 
        res= args[0]->val_str(&tmp);
117
 
 
118
 
        if (! res)
119
 
        {
120
 
          /* 
121
 
           * Likely a nested function issue where the nested
122
 
           * function had bad input.  We rely on the nested
123
 
           * function my_error() and simply return false here.
124
 
           */
125
 
          return false;
126
 
        }
127
 
 
128
 
        if (res != &tmp)
129
 
        {
130
 
          tmp.copy(*res);
131
 
        }
132
 
 
133
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
134
 
        return 0;
135
 
      }
136
 
  }
137
 
  int64_t julian_day_number;
138
 
  temporal.to_julian_day_number(&julian_day_number);
139
 
  return julian_day_number;
 
26
  assert(fixed == 1);
 
27
  DRIZZLE_TIME ltime;
 
28
  if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
 
29
    return 0;
 
30
  return (int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
 
31
}
 
32
 
 
33
 
 
34
/*
 
35
  Get information about this Item tree monotonicity
 
36
 
 
37
  SYNOPSIS
 
38
    Item_func_to_days::get_monotonicity_info()
 
39
 
 
40
  DESCRIPTION
 
41
  Get information about monotonicity of the function represented by this item
 
42
  tree.
 
43
 
 
44
  RETURN
 
45
    See enum_monotonicity_info.
 
46
*/
 
47
 
 
48
enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const
 
49
{
 
50
  if (args[0]->type() == Item::FIELD_ITEM)
 
51
  {
 
52
    if (args[0]->field_type() == DRIZZLE_TYPE_DATE)
 
53
      return MONOTONIC_STRICT_INCREASING;
 
54
    if (args[0]->field_type() == DRIZZLE_TYPE_DATETIME)
 
55
      return MONOTONIC_INCREASING;
 
56
  }
 
57
  return NON_MONOTONIC;
140
58
}
141
59
 
142
60
int64_t Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
143
61
{
144
 
  assert(fixed);
145
 
 
146
 
  /*
147
 
   * We attempt to convert the first argument into a
148
 
   * temporal value.  If the conversion is successful, 
149
 
   * we know that a conversion to a Julian Day Number
150
 
   * is always possible. Depending on whether the 
151
 
   * first argument is a Date, or a DateTime with no
152
 
   * time-portion, we return the Julian Day Number or
153
 
   * the appropriate end-point integer.
154
 
   */
155
 
  /* Grab the first argument as a DateTime object */
156
 
  DateTime temporal;
157
 
  Item_result arg0_result_type= args[0]->result_type();
158
 
  
159
 
  switch (arg0_result_type)
160
 
  {
161
 
    case REAL_RESULT:
162
 
    case DECIMAL_RESULT: 
163
 
      /* 
164
 
       * For doubles supplied, interpret the arg as a string, 
165
 
       * so intentionally fall-through here...
166
 
       * This allows us to accept double parameters like 
167
 
       * 19971231235959.01 and interpret it the way MySQL does:
168
 
       * as a TIMESTAMP-like thing with a microsecond component.
169
 
       * Ugh, but need to keep backwards-compat.
170
 
       */
171
 
    case STRING_RESULT:
172
 
      {
173
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
174
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
175
 
        String *res= args[0]->val_str(&tmp);
176
 
 
177
 
        if (! res)
178
 
        {
179
 
          /* 
180
 
           * Likely a nested function issue where the nested
181
 
           * function had bad input.  We rely on the nested
182
 
           * function my_error() and simply return false here.
183
 
           */
184
 
          return 0;
185
 
        }
186
 
 
187
 
        if (res != &tmp)
188
 
        {
189
 
          tmp.copy(*res);
190
 
        }
191
 
 
192
 
        if (! temporal.from_string(tmp.c_ptr(), tmp.length()))
193
 
        {
194
 
          /* 
195
 
          * Could not interpret the function argument as a temporal value, 
196
 
          * so throw an error and return 0
197
 
          */
198
 
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
199
 
          return 0;
200
 
        }
201
 
      }
202
 
      break;
203
 
    case INT_RESULT:
204
 
      if (temporal.from_int64_t(args[0]->val_int()))
205
 
        break;
206
 
      /* Intentionally fall-through on invalid conversion from integer */
207
 
    default:
208
 
      {
209
 
        /* 
210
 
        * Could not interpret the function argument as a temporal value, 
211
 
        * so throw an error and return 0
212
 
        */
213
 
        null_value= true;
214
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
215
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
216
 
        String *res;
217
 
 
218
 
        res= args[0]->val_str(&tmp);
219
 
 
220
 
        if (! res)
221
 
        {
222
 
          /* 
223
 
           * Likely a nested function issue where the nested
224
 
           * function had bad input.  We rely on the nested
225
 
           * function my_error() and simply return false here.
226
 
           */
227
 
          return 0;
228
 
        }
229
 
 
230
 
        if (res != &tmp)
231
 
        {
232
 
          tmp.copy(*res);
233
 
        }
234
 
 
235
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
236
 
        return 0;
237
 
      }
238
 
  }
239
 
 
240
 
  if (null_value == true)
 
62
  assert(fixed == 1);
 
63
  DRIZZLE_TIME ltime;
 
64
  int64_t res;
 
65
  if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
241
66
  {
242
67
    /* got NULL, leave the incl_endp intact */
243
68
    return INT64_MIN;
244
69
  }
245
 
 
246
 
  int64_t julian_day_number;
247
 
  temporal.to_julian_day_number(&julian_day_number);
 
70
  res=(int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
248
71
 
249
72
  if (args[0]->field_type() == DRIZZLE_TYPE_DATE)
250
73
  {
251
 
    /* TO_DAYS() is strictly monotonic for dates, leave incl_endp intact */
252
 
    return julian_day_number;
 
74
    // TO_DAYS() is strictly monotonic for dates, leave incl_endp intact
 
75
    return res;
253
76
  }
254
77
 
255
78
  /*
263
86
 
264
87
      col < '2007-09-15 12:34:56'  -> TO_DAYS(col) <= TO_DAYS('2007-09-15')
265
88
  */
266
 
  if (!left_endp && ! (
267
 
                    temporal.hours() 
268
 
                    || temporal.minutes()
269
 
                    || temporal.seconds() 
270
 
                    || temporal.useconds()
271
 
                    || temporal.nseconds()
272
 
                    )
273
 
                    )
 
89
  if (!left_endp && !(ltime.hour || ltime.minute || ltime.second ||
 
90
                      ltime.second_part))
274
91
    ; /* do nothing */
275
92
  else
276
93
    *incl_endp= true;
277
 
  return julian_day_number;
 
94
  return res;
278
95
}
279
96
 
280
 
} /* namespace drizzled */