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 <drizzled/temporal.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/session.h>
00025 #include <drizzled/calendar.h>
00026 #include <drizzled/function/time/extract.h>
00027
00028 namespace drizzled
00029 {
00030
00031
00032
00033
00034
00035
00036 extern const char *interval_names[];
00037
00038 void Item_extract::print(String *str)
00039 {
00040 str->append(STRING_WITH_LEN("extract("));
00041 str->append(interval_names[int_type]);
00042 str->append(STRING_WITH_LEN(" from "));
00043 args[0]->print(str);
00044 str->append(')');
00045 }
00046
00047 void Item_extract::fix_length_and_dec()
00048 {
00049 value.alloc(DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING);
00050
00051 maybe_null= 1;
00052 switch (int_type) {
00053 case INTERVAL_YEAR: max_length=4; date_value=1; break;
00054 case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break;
00055 case INTERVAL_QUARTER: max_length=2; date_value=1; break;
00056 case INTERVAL_MONTH: max_length=2; date_value=1; break;
00057 case INTERVAL_WEEK: max_length=2; date_value=1; break;
00058 case INTERVAL_DAY: max_length=2; date_value=1; break;
00059 case INTERVAL_DAY_HOUR: max_length=9; date_value=0; break;
00060 case INTERVAL_DAY_MINUTE: max_length=11; date_value=0; break;
00061 case INTERVAL_DAY_SECOND: max_length=13; date_value=0; break;
00062 case INTERVAL_HOUR: max_length=2; date_value=0; break;
00063 case INTERVAL_HOUR_MINUTE: max_length=4; date_value=0; break;
00064 case INTERVAL_HOUR_SECOND: max_length=6; date_value=0; break;
00065 case INTERVAL_MINUTE: max_length=2; date_value=0; break;
00066 case INTERVAL_MINUTE_SECOND: max_length=4; date_value=0; break;
00067 case INTERVAL_SECOND: max_length=2; date_value=0; break;
00068 case INTERVAL_MICROSECOND: max_length=2; date_value=0; break;
00069 case INTERVAL_DAY_MICROSECOND: max_length=20; date_value=0; break;
00070 case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break;
00071 case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break;
00072 case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break;
00073 case INTERVAL_LAST: assert(0); break;
00074 }
00075 }
00076
00077 int64_t Item_extract::val_int()
00078 {
00079 assert(fixed);
00080
00081 if (args[0]->is_null())
00082 {
00083
00084 null_value= true;
00085 return 0;
00086 }
00087
00088
00089 DateTime datetime_temporal;
00090 Time time_temporal;
00091
00092
00093 Temporal *temporal;
00094
00095 if (date_value)
00096 {
00097
00098 Item_result arg0_result_type= args[0]->result_type();
00099
00100 switch (arg0_result_type)
00101 {
00102 case DECIMAL_RESULT:
00103
00104
00105
00106
00107
00108
00109
00110
00111 case STRING_RESULT:
00112 {
00113 char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00114 String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00115 String *res= args[0]->val_str(&tmp);
00116
00117 if (res && (res != &tmp))
00118 {
00119 tmp.copy(*res);
00120 }
00121
00122 if (! datetime_temporal.from_string(tmp.c_ptr(), tmp.length()))
00123 {
00124
00125
00126
00127
00128 my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
00129 return 0;
00130 }
00131 }
00132 break;
00133 case INT_RESULT:
00134 if (datetime_temporal.from_int64_t(args[0]->val_int()))
00135 break;
00136
00137 default:
00138 {
00139
00140
00141
00142
00143 null_value= true;
00144 char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00145 String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00146 String *res;
00147
00148 res= args[0]->val_str(&tmp);
00149
00150 if (res && (res != &tmp))
00151 {
00152 tmp.copy(*res);
00153 }
00154
00155 my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
00156 return 0;
00157 }
00158 }
00159
00160
00161
00162
00163 temporal= &datetime_temporal;
00164 }
00165 else
00166 {
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 char time_buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00184 String tmp_time(time_buff,sizeof(time_buff), &my_charset_utf8_bin);
00185 String *time_res= args[0]->val_str(&tmp_time);
00186
00187 if (time_res && (time_res != &tmp_time))
00188 {
00189 tmp_time.copy(*time_res);
00190 }
00191
00192 if (! time_temporal.from_string(tmp_time.c_ptr(), tmp_time.length()))
00193 {
00194
00195
00196
00197
00198
00199 Item_result arg0_result_type= args[0]->result_type();
00200
00201 switch (arg0_result_type)
00202 {
00203 case DECIMAL_RESULT:
00204
00205
00206
00207
00208
00209
00210
00211
00212 case STRING_RESULT:
00213 {
00214 char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00215 String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00216 String *res= args[0]->val_str(&tmp);
00217
00218 if (res && (res != &tmp))
00219 {
00220 tmp.copy(*res);
00221 }
00222
00223 if (! datetime_temporal.from_string(tmp.c_ptr(), tmp.length()))
00224 {
00225
00226
00227
00228
00229 my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
00230 return 0;
00231 }
00232 }
00233 break;
00234 case INT_RESULT:
00235 if (datetime_temporal.from_int64_t(args[0]->val_int()))
00236 break;
00237
00238 default:
00239 {
00240
00241
00242
00243
00244 null_value= true;
00245 char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00246 String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00247 String *res;
00248
00249 res= args[0]->val_str(&tmp);
00250
00251 my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
00252 return 0;
00253 }
00254 }
00255
00256 temporal= &datetime_temporal;
00257 }
00258 else
00259 {
00260
00261 temporal= &time_temporal;
00262 }
00263 }
00264
00265
00266 switch (int_type) {
00267 case INTERVAL_YEAR:
00268 return (int64_t) temporal->years();
00269 case INTERVAL_YEAR_MONTH:
00270 return (int64_t) ((temporal->years() * 100L) + temporal->months());
00271 case INTERVAL_QUARTER:
00272 return (int64_t) (temporal->months() + 2) / 3;
00273 case INTERVAL_MONTH:
00274 return (int64_t) temporal->months();
00275 case INTERVAL_WEEK:
00276 return iso_week_number_from_gregorian_date(temporal->years()
00277 , temporal->months()
00278 , temporal->days());
00279 case INTERVAL_DAY:
00280 return (int64_t) temporal->days();
00281 case INTERVAL_DAY_HOUR:
00282 return (int64_t) ((temporal->days() * 100L) + temporal->hours());
00283 case INTERVAL_DAY_MINUTE:
00284 return (int64_t) ((temporal->days() * 10000L)
00285 + (temporal->hours() * 100L)
00286 + temporal->minutes());
00287 case INTERVAL_DAY_SECOND:
00288 return (int64_t) (
00289 (int64_t) (temporal->days() * 1000000L)
00290 + (int64_t) (temporal->hours() * 10000L)
00291 + (temporal->minutes() * 100L)
00292 + temporal->seconds());
00293 case INTERVAL_HOUR:
00294 return (int64_t) temporal->hours();
00295 case INTERVAL_HOUR_MINUTE:
00296 return (int64_t) (temporal->hours() * 100L)
00297 + temporal->minutes();
00298 case INTERVAL_HOUR_SECOND:
00299 return (int64_t) (temporal->hours() * 10000L)
00300 + (temporal->minutes() * 100L)
00301 + temporal->seconds();
00302 case INTERVAL_MINUTE:
00303 return (int64_t) temporal->minutes();
00304 case INTERVAL_MINUTE_SECOND:
00305 return (int64_t) (temporal->minutes() * 100L) + temporal->seconds();
00306 case INTERVAL_SECOND:
00307 return (int64_t) temporal->seconds();
00308 case INTERVAL_MICROSECOND:
00309 return (int64_t) temporal->useconds();
00310 case INTERVAL_DAY_MICROSECOND:
00311 return (int64_t)
00312 (
00313 (
00314 (int64_t) (temporal->days() * 1000000L)
00315 + (int64_t) (temporal->hours() * 10000L)
00316 + (temporal->minutes() * 100L)
00317 + temporal->seconds()
00318 )
00319 * 1000000L
00320 )
00321 + temporal->useconds();
00322 case INTERVAL_HOUR_MICROSECOND:
00323 return (int64_t)
00324 (
00325 (
00326 (int64_t) (temporal->hours() * 10000L)
00327 + (temporal->minutes() * 100L)
00328 + temporal->seconds()
00329 )
00330 * 1000000L
00331 )
00332 + temporal->useconds();
00333 case INTERVAL_MINUTE_MICROSECOND:
00334 return (int64_t)
00335 (
00336 (
00337 (temporal->minutes() * 100L)
00338 + temporal->seconds()
00339 )
00340 * 1000000L
00341 )
00342 + temporal->useconds();
00343 case INTERVAL_SECOND_MICROSECOND:
00344 return (int64_t) (temporal->seconds() * 1000000L)
00345 + temporal->useconds();
00346 case INTERVAL_LAST:
00347 default:
00348 assert(0);
00349 return 0;
00350 }
00351 }
00352
00353 bool Item_extract::eq(const Item *item, bool binary_cmp) const
00354 {
00355 if (this == item)
00356 return 1;
00357 if (item->type() != FUNC_ITEM ||
00358 functype() != ((Item_func*)item)->functype())
00359 return 0;
00360
00361 Item_extract* ie= (Item_extract*)item;
00362 if (ie->int_type != int_type)
00363 return 0;
00364
00365 if (!args[0]->eq(ie->args[0], binary_cmp))
00366 return 0;
00367 return 1;
00368 }
00369
00370 }