~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

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