Drizzled Public API Documentation

hour.cc
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, Inc.
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 
20 #include <config.h>
21 
22 #include <drizzled/temporal.h>
23 #include <drizzled/error.h>
24 #include <drizzled/function/time/hour.h>
25 
26 namespace drizzled
27 {
28 
30 {
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  */
55  Time temporal_time;
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 
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()))
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  */
73  DateTime temporal_datetime;
74  Item_result arg0_result_type= args[0]->result_type();
75 
76  switch (arg0_result_type)
77  {
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  */
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);
92 
93  if (res && (res != &tmp))
94  {
95  tmp.copy(*res);
96  }
97 
98  if (! temporal_datetime.from_string(tmp.c_ptr(), tmp.length()))
99  {
100  /*
101  * Could not interpret the function argument as a temporal value,
102  * so throw an error and return 0
103  */
104  my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
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 
126  if (res && (res != &tmp))
127  {
128  tmp.copy(*res);
129  }
130 
131  my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
132  return 0;
133  }
134  }
135  return (int64_t) temporal_datetime.hours();
136  }
137  return (int64_t) temporal_time.hours();
138 }
139 
140 } /* namespace drizzled */
bool from_string(const char *from, size_t from_len)
Definition: temporal.cc:978
bool from_string(const char *from, size_t from_len)
Definition: temporal.cc:160
virtual int64_t val_int()=0
uint32_t hours() const
Definition: temporal.h:138
bool fixed
Definition: item.h:120
bool null_value
Definition: item.h:122
int64_t val_int()
Definition: hour.cc:29
bool from_int64_t(const int64_t from, bool convert)
Definition: temporal.cc:1144
bool is_null()
Definition: func.cc:512
virtual String * val_str(String *str)=0