~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Jay Pipes
  • Date: 2009-02-04 15:44:25 UTC
  • mfrom: (829 drizzle)
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090204154425-th8xfk2ujz2y8xwg
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "drizzled/server_includes.h"
 
20
#include <drizzled/server_includes.h>
21
21
#include CSTDINT_H
22
 
#include "drizzled/function/time/last_day.h"
23
 
#include "drizzled/error.h"
24
 
#include "drizzled/calendar.h"
25
 
#include "drizzled/temporal.h"
26
 
 
27
 
#include <sstream>
28
 
#include <string>
29
 
 
30
 
/**
31
 
 * Interpret the first argument as a DateTime string and then populate
32
 
 * our supplied temporal object with a Date representing the last day of 
33
 
 * the corresponding month and year.
34
 
 */
35
 
bool Item_func_last_day::get_temporal(drizzled::Date &to)
 
22
#include <drizzled/function/time/last_day.h>
 
23
 
 
24
bool Item_func_last_day::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
36
25
{
37
 
  assert(fixed);
38
 
 
39
 
  /* We return NULL from LAST_DAY() only when supplied a NULL argument */
40
 
  if (args[0]->null_value)
41
 
  {
42
 
    null_value= true;
43
 
    return false;
44
 
  }
45
 
 
46
 
  /* We use a DateTime to match as many temporal formats as possible. */
47
 
  drizzled::DateTime temporal;
48
 
  Item_result arg0_result_type= args[0]->result_type();
49
 
  
50
 
  switch (arg0_result_type)
51
 
  {
52
 
    case REAL_RESULT:
53
 
    case DECIMAL_RESULT: 
54
 
      /* 
55
 
       * For doubles supplied, interpret the arg as a string, 
56
 
       * so intentionally fall-through here...
57
 
       * This allows us to accept double parameters like 
58
 
       * 19971231235959.01 and interpret it the way MySQL does:
59
 
       * as a TIMESTAMP-like thing with a microsecond component.
60
 
       * Ugh, but need to keep backwards-compat.
61
 
       */
62
 
    case STRING_RESULT:
63
 
      {
64
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
65
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
66
 
        String *res= args[0]->val_str(&tmp);
67
 
 
68
 
        if (! res)
69
 
        {
70
 
          /* 
71
 
           * Likely a nested function issue where the nested
72
 
           * function had bad input.  We rely on the nested
73
 
           * function my_error() and simply return false here.
74
 
           */
75
 
          return false;
76
 
        }
77
 
 
78
 
        if (! temporal.from_string(res->c_ptr(), res->length()))
79
 
        {
80
 
          /* 
81
 
          * Could not interpret the function argument as a temporal value, 
82
 
          * so throw an error and return 0
83
 
          */
84
 
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
85
 
          return false;
86
 
        }
87
 
      }
88
 
      break;
89
 
    case INT_RESULT:
90
 
      if (temporal.from_int64_t(args[0]->val_int()))
91
 
        break;
92
 
      /* Intentionally fall-through on invalid conversion from integer */
93
 
    default:
94
 
      {
95
 
        /* 
96
 
        * Could not interpret the function argument as a temporal value, 
97
 
        * so throw an error and return 0
98
 
        */
99
 
        null_value= true;
100
 
        char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
101
 
        String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
102
 
        String *res;
103
 
 
104
 
        res= args[0]->val_str(&tmp);
105
 
 
106
 
        if (! res)
107
 
        {
108
 
          /* 
109
 
           * Likely a nested function issue where the nested
110
 
           * function had bad input.  We rely on the nested
111
 
           * function my_error() and simply return false here.
112
 
           */
113
 
          return false;
114
 
        }
115
 
 
116
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
117
 
        return false;
118
 
      }
119
 
  }
120
 
  null_value= false;
121
 
 
122
 
  /* Now strip to the last day of the month... */
123
 
  temporal.set_days(days_in_gregorian_year_month(temporal.years(), temporal.months()));
124
 
  to= temporal; /* Operator overload in effect for assign DateTime to Date. */
125
 
 
126
 
  return true;
 
26
  if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
 
27
      (ltime->month == 0))
 
28
  {
 
29
    null_value= 1;
 
30
    return 1;
 
31
  }
 
32
  null_value= 0;
 
33
  uint32_t month_idx= ltime->month-1;
 
34
  ltime->day= days_in_month[month_idx];
 
35
  if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
 
36
    ltime->day= 29;
 
37
  ltime->hour= ltime->minute= ltime->second= 0;
 
38
  ltime->second_part= 0;
 
39
  ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
 
40
  return 0;
127
41
}
 
42