Drizzled Public API Documentation

date_add_interval.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 <cstdio>
23 
24 #include <drizzled/function/time/date_add_interval.h>
25 #include <drizzled/temporal_interval.h>
26 #include <drizzled/time_functions.h>
27 
28 namespace drizzled
29 {
30 
31 /*
32  'interval_names' reflects the order of the enumeration interval_type.
33  See item/time.h
34  */
35 const char *interval_names[]=
36 {
37  "year", "quarter", "month", "week", "day",
38  "hour", "minute", "second", "microsecond",
39  "year_month", "day_hour", "day_minute",
40  "day_second", "hour_minute", "hour_second",
41  "minute_second", "day_microsecond",
42  "hour_microsecond", "minute_microsecond",
43  "second_microsecond"
44 };
45 
46 
47 void Item_date_add_interval::fix_length_and_dec()
48 {
49  enum_field_types arg0_field_type;
50 
51  collation.set(&my_charset_bin);
52  maybe_null=1;
53  max_length=DateTime::MAX_STRING_LENGTH*MY_CHARSET_BIN_MB_MAXLEN;
54  value.alloc(max_length);
55 
56  /*
57  The field type for the result of an Item_date function is defined as
58  follows:
59 
60  - If first arg is a DRIZZLE_TYPE_DATETIME result is DRIZZLE_TYPE_DATETIME
61  - If first arg is a DRIZZLE_TYPE_DATE and the interval type uses hours,
62  minutes or seconds then type is DRIZZLE_TYPE_DATETIME.
63  - Otherwise the result is DRIZZLE_TYPE_VARCHAR
64  (This is because you can't know if the string contains a DATE, type::Time or
65  DATETIME argument)
66  */
67  cached_field_type= DRIZZLE_TYPE_VARCHAR;
68  arg0_field_type= args[0]->field_type();
69  if (arg0_field_type == DRIZZLE_TYPE_DATETIME or arg0_field_type == DRIZZLE_TYPE_TIMESTAMP or arg0_field_type == DRIZZLE_TYPE_MICROTIME)
70  {
71  cached_field_type= DRIZZLE_TYPE_DATETIME;
72  }
73  else if (arg0_field_type == DRIZZLE_TYPE_DATE)
74  {
75  if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
76  {
77  cached_field_type= arg0_field_type;
78  }
79  else
80  {
81  cached_field_type= DRIZZLE_TYPE_DATETIME;
82  }
83  }
84 }
85 
86 
87 /* Here arg[1] is a Item_interval object */
88 
90 {
91  TemporalInterval interval;
92 
93  if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE))
94  return (null_value= true);
95 
96  if (interval.initFromItem(args[1], int_type, &value))
97  return (null_value= true);
98 
99  if (date_sub_interval)
100  interval.toggleNegative();
101 
102  if ((null_value= interval.addDate(&ltime, int_type)))
103  return true;
104 
105  return false;
106 }
107 
109 {
110  assert(fixed == 1);
111  type::Time ltime;
112 
113  if (Item_date_add_interval::get_date(ltime, TIME_NO_ZERO_DATE))
114  return 0;
115 
116  if (ltime.time_type == type::DRIZZLE_TIMESTAMP_DATE)
117  {
118  ltime.convert(*str, type::DRIZZLE_TIMESTAMP_DATE);
119  }
120  else if (ltime.second_part)
121  {
122  ltime.convert(*str);
123  }
124  else
125  {
126  ltime.convert(*str);
127  }
128 
129  return str;
130 }
131 
133 {
134  assert(fixed == 1);
135  type::Time ltime;
136  int64_t date;
137  if (Item_date_add_interval::get_date(ltime, TIME_NO_ZERO_DATE))
138  return (int64_t) 0;
139 
140  date = (ltime.year*100L + ltime.month)*100L + ltime.day;
141 
142  return ltime.time_type == type::DRIZZLE_TIMESTAMP_DATE ? date :
143  ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
144 }
145 
146 
147 
148 bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
149 {
151  if (!Item_func::eq(item, binary_cmp))
152  return 0;
153  return ((int_type == other->int_type) &&
154  (date_sub_interval == other->date_sub_interval));
155 }
156 
158 {
159  str->append('(');
160  args[0]->print(str);
161  if (date_sub_interval)
162  {
163  str->append(STRING_WITH_LEN(" - interval "));
164  }
165  else
166  {
167  str->append(STRING_WITH_LEN(" + interval "));
168  }
169  args[1]->print(str);
170  str->append(' ');
171  str->append(interval_names[int_type], strlen(interval_names[int_type]));
172  str->append(')');
173 }
174 
175 } /* namespace drizzled */
virtual void print(String *str)
bool initFromItem(Item *args, interval_type int_type, String *str_value)
bool eq(const Item *item, bool binary_cmp) const
Definition: func.cc:477
Stores time interval for date/time manipulation.
bool fixed
Definition: item.h:120
bool addDate(type::Time *ltime, interval_type int_type)
bool null_value
Definition: item.h:122
static const int MAX_STRING_LENGTH
Definition: temporal.h:608
bool get_date(type::Time &res, uint32_t fuzzy_date)
bool maybe_null
Definition: item.h:121
virtual void print(String *str)
Definition: item.cc:362
bool eq(const Item *item, bool binary_cmp) const