Drizzled Public API Documentation

date_add_interval.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <cstdio>
00023 
00024 #include <drizzled/function/time/date_add_interval.h>
00025 #include <drizzled/temporal_interval.h>
00026 #include <drizzled/time_functions.h>
00027 
00028 namespace drizzled
00029 {
00030 
00031 /*
00032    'interval_names' reflects the order of the enumeration interval_type.
00033    See item/time.h
00034  */
00035 const char *interval_names[]=
00036 {
00037   "year", "quarter", "month", "week", "day",
00038   "hour", "minute", "second", "microsecond",
00039   "year_month", "day_hour", "day_minute",
00040   "day_second", "hour_minute", "hour_second",
00041   "minute_second", "day_microsecond",
00042   "hour_microsecond", "minute_microsecond",
00043   "second_microsecond"
00044 };
00045 
00046 
00047 void Item_date_add_interval::fix_length_and_dec()
00048 {
00049   enum_field_types arg0_field_type;
00050 
00051   collation.set(&my_charset_bin);
00052   maybe_null=1;
00053   max_length=DateTime::MAX_STRING_LENGTH*MY_CHARSET_BIN_MB_MAXLEN;
00054   value.alloc(max_length);
00055 
00056   /*
00057     The field type for the result of an Item_date function is defined as
00058     follows:
00059 
00060     - If first arg is a DRIZZLE_TYPE_DATETIME result is DRIZZLE_TYPE_DATETIME
00061     - If first arg is a DRIZZLE_TYPE_DATE and the interval type uses hours,
00062       minutes or seconds then type is DRIZZLE_TYPE_DATETIME.
00063     - Otherwise the result is DRIZZLE_TYPE_VARCHAR
00064       (This is because you can't know if the string contains a DATE, type::Time or
00065       DATETIME argument)
00066   */
00067   cached_field_type= DRIZZLE_TYPE_VARCHAR;
00068   arg0_field_type= args[0]->field_type();
00069   if (arg0_field_type == DRIZZLE_TYPE_DATETIME or arg0_field_type == DRIZZLE_TYPE_TIMESTAMP or arg0_field_type == DRIZZLE_TYPE_MICROTIME)
00070   {
00071     cached_field_type= DRIZZLE_TYPE_DATETIME;
00072   }
00073   else if (arg0_field_type == DRIZZLE_TYPE_DATE)
00074   {
00075     if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
00076     {
00077       cached_field_type= arg0_field_type;
00078     }
00079     else
00080     {
00081       cached_field_type= DRIZZLE_TYPE_DATETIME;
00082     }
00083   }
00084 }
00085 
00086 
00087 /* Here arg[1] is a Item_interval object */
00088 
00089 bool Item_date_add_interval::get_date(type::Time &ltime, uint32_t )
00090 {
00091   TemporalInterval interval;
00092 
00093   if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE))
00094     return (null_value= true);
00095 
00096   if (interval.initFromItem(args[1], int_type, &value))
00097     return (null_value= true);
00098 
00099   if (date_sub_interval)
00100     interval.toggleNegative();
00101 
00102   if ((null_value= interval.addDate(&ltime, int_type)))
00103     return true;
00104 
00105   return false;
00106 }
00107 
00108 String *Item_date_add_interval::val_str(String *str)
00109 {
00110   assert(fixed == 1);
00111   type::Time ltime;
00112 
00113   if (Item_date_add_interval::get_date(ltime, TIME_NO_ZERO_DATE))
00114     return 0;
00115 
00116   if (ltime.time_type == type::DRIZZLE_TIMESTAMP_DATE)
00117   {
00118     ltime.convert(*str, type::DRIZZLE_TIMESTAMP_DATE);
00119   }
00120   else if (ltime.second_part)
00121   {
00122     ltime.convert(*str);
00123   }
00124   else
00125   {
00126     ltime.convert(*str);
00127   }
00128 
00129   return str;
00130 }
00131 
00132 int64_t Item_date_add_interval::val_int()
00133 {
00134   assert(fixed == 1);
00135   type::Time ltime;
00136   int64_t date;
00137   if (Item_date_add_interval::get_date(ltime, TIME_NO_ZERO_DATE))
00138     return (int64_t) 0;
00139 
00140   date = (ltime.year*100L + ltime.month)*100L + ltime.day;
00141 
00142   return ltime.time_type == type::DRIZZLE_TIMESTAMP_DATE ? date :
00143     ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
00144 }
00145 
00146 
00147 
00148 bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
00149 {
00150   Item_date_add_interval *other= (Item_date_add_interval*) item;
00151   if (!Item_func::eq(item, binary_cmp))
00152     return 0;
00153   return ((int_type == other->int_type) &&
00154           (date_sub_interval == other->date_sub_interval));
00155 }
00156 
00157 void Item_date_add_interval::print(String *str)
00158 {
00159   str->append('(');
00160   args[0]->print(str);
00161   str->append(date_sub_interval?" - interval ":" + interval ");
00162   args[1]->print(str);
00163   str->append(' ');
00164   str->append(interval_names[int_type]);
00165   str->append(')');
00166 }
00167 
00168 } /* namespace drizzled */