00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00033
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
00058
00059
00060
00061
00062
00063
00064
00065
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
00088
00089 bool Item_date_add_interval::get_date(type::Time <ime, 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(<ime, 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 }