item_timefunc.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:27k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* This file defines all time functions */
  17. #ifdef __GNUC__
  18. #pragma implementation // gcc: Class implementation
  19. #endif
  20. #include "mysql_priv.h"
  21. #include <m_ctype.h>
  22. #include <time.h>
  23. /*
  24. ** Todo: Move month and days to language files
  25. */
  26. static String month_names[] = { "January", "February", "March", "April",
  27.        "May", "June", "July", "August",
  28.        "September", "October", "November", "December" };
  29. static String day_names[] = { "Monday", "Tuesday", "Wednesday",
  30.      "Thursday", "Friday", "Saturday" ,"Sunday" };
  31. /*
  32. ** Get a array of positive numbers from a string object.
  33. ** Each number is separated by 1 non digit character
  34. ** Return error if there is too many numbers.
  35. ** If there is too few numbers, assume that the numbers are left out
  36. ** from the high end. This allows one to give:
  37. ** DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
  38. */
  39. bool get_interval_info(const char *str,uint length,uint count,
  40.        long *values)
  41. {
  42.   const char *end=str+length;
  43.   uint i;
  44.   while (str != end && !isdigit(*str))
  45.     str++;
  46.   for (i=0 ; i < count ; i++)
  47.   {
  48.     long value;
  49.     for (value=0; str != end && isdigit(*str) ; str++)
  50.       value=value*10L + (long) (*str - '0');
  51.     values[i]= value;
  52.     while (str != end && !isdigit(*str))
  53.       str++;
  54.     if (str == end && i != count-1)
  55.     {
  56.       i++;
  57.       /* Change values[0...i-1] -> values[0...count-1] */
  58.       bmove_upp((char*) (values+count), (char*) (values+i),
  59. sizeof(long)*i);
  60.       bzero((char*) values, sizeof(long)*(count-i));
  61.       break;
  62.     }
  63.   }
  64.   return (str != end);
  65. }
  66. longlong Item_func_period_add::val_int()
  67. {
  68.   ulong period=(ulong) args[0]->val_int();
  69.   int months=(int) args[1]->val_int();
  70.   if ((null_value=args[0]->null_value || args[1]->null_value) ||
  71.       period == 0L)
  72.     return 0; /* purecov: inspected */
  73.   return (longlong)
  74.     convert_month_to_period((uint) ((int) convert_period_to_month(period)+
  75.     months));
  76. }
  77. longlong Item_func_period_diff::val_int()
  78. {
  79.   ulong period1=(ulong) args[0]->val_int();
  80.   ulong period2=(ulong) args[1]->val_int();
  81.   if ((null_value=args[0]->null_value || args[1]->null_value))
  82.     return 0; /* purecov: inspected */
  83.   return (longlong) ((long) convert_period_to_month(period1)-
  84.      (long) convert_period_to_month(period2));
  85. }
  86. longlong Item_func_to_days::val_int()
  87. {
  88.   TIME ltime;
  89.   if (get_arg0_date(&ltime,0))
  90.     return 0;
  91.   return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
  92. }
  93. longlong Item_func_dayofyear::val_int()
  94. {
  95.   TIME ltime;
  96.   if (get_arg0_date(&ltime,0))
  97.     return 0;
  98.   return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) -
  99.     calc_daynr(ltime.year,1,1) + 1;
  100. }
  101. longlong Item_func_dayofmonth::val_int()
  102. {
  103.   TIME ltime;
  104.   (void) get_arg0_date(&ltime,1);
  105.   return (longlong) ltime.day;
  106. }
  107. longlong Item_func_month::val_int()
  108. {
  109.   TIME ltime;
  110.   (void) get_arg0_date(&ltime,1);
  111.   return (longlong) ltime.month;
  112. }
  113. String* Item_func_monthname::val_str(String* str)
  114. {
  115.   uint month=(uint) Item_func_month::val_int();
  116.   if (!month) // This is also true for NULL
  117.   {
  118.     null_value=1;
  119.     return (String*) 0;
  120.   }
  121.   null_value=0;
  122.   return &month_names[month-1];
  123. }
  124. // Returns the quarter of the year
  125. longlong Item_func_quarter::val_int()
  126. {
  127.   TIME ltime;
  128.   (void) get_arg0_date(&ltime,1);
  129.   return (longlong) ((ltime.month+2)/3);
  130. }
  131. longlong Item_func_hour::val_int()
  132. {
  133.   TIME ltime;
  134.   (void) get_arg0_time(&ltime);
  135.   return ltime.hour;
  136. }
  137. longlong Item_func_minute::val_int()
  138. {
  139.   TIME ltime;
  140.   (void) get_arg0_time(&ltime);
  141.   return ltime.minute;
  142. }
  143. // Returns the second in time_exp in the range of 0 - 59
  144. longlong Item_func_second::val_int()
  145. {
  146.   TIME ltime;
  147.   (void) get_arg0_time(&ltime);
  148.   return ltime.second;
  149. }
  150. // Returns the week of year in the range of 0 - 53
  151. longlong Item_func_week::val_int()
  152. {
  153.   uint year;
  154.   TIME ltime;
  155.   if (get_arg0_date(&ltime,0))
  156.     return 0;
  157.   return (longlong) calc_week(&ltime, 0, args[1]->val_int() == 0, &year);
  158. }
  159. longlong Item_func_yearweek::val_int()
  160. {
  161.   uint year,week;
  162.   TIME ltime;
  163.   if (get_arg0_date(&ltime,0))
  164.     return 0;
  165.   week=calc_week(&ltime, 1, args[1]->val_int() == 0, &year);
  166.   return week+year*100;
  167. }
  168. /* weekday() has a automatic to_days() on item */
  169. longlong Item_func_weekday::val_int()
  170. {
  171.   ulong tmp_value=(ulong) args[0]->val_int();
  172.   if ((null_value=(args[0]->null_value || !tmp_value)))
  173.     return 0; /* purecov: inspected */
  174.   return (longlong) calc_weekday(tmp_value,odbc_type)+test(odbc_type);
  175. }
  176. String* Item_func_dayname::val_str(String* str)
  177. {
  178.   uint weekday=(uint) val_int(); // Always Item_func_daynr()
  179.   if (null_value)
  180.     return (String*) 0;
  181.   return &day_names[weekday];
  182. }
  183. longlong Item_func_year::val_int()
  184. {
  185.   TIME ltime;
  186.   (void) get_arg0_date(&ltime,1);
  187.   return (longlong) ltime.year;
  188. }
  189. longlong Item_func_unix_timestamp::val_int()
  190. {
  191.   if (arg_count == 0)
  192.     return (longlong) current_thd->query_start();
  193.   if (args[0]->type() == FIELD_ITEM)
  194.   { // Optimize timestamp field
  195.     Field *field=((Item_field*) args[0])->field;
  196.     if (field->type() == FIELD_TYPE_TIMESTAMP)
  197.       return ((Field_timestamp*) field)->get_timestamp();
  198.   }
  199.   String *str=args[0]->val_str(&value);
  200.   if ((null_value=args[0]->null_value))
  201.   {
  202.     return 0; /* purecov: inspected */
  203.   }
  204.   return (longlong) str_to_timestamp(str->ptr(),str->length());
  205. }
  206. longlong Item_func_time_to_sec::val_int()
  207. {
  208.   TIME ltime;
  209.   (void) get_arg0_time(&ltime);
  210.   return ltime.hour*3600L+ltime.minute*60+ltime.second;
  211. }
  212. /*
  213. ** Convert a string to a interval value
  214. ** To make code easy, allow interval objects without separators.
  215. */
  216. static bool get_interval_value(Item *args,interval_type int_type,
  217.        String *str_value, INTERVAL *t)
  218. {
  219.   long array[4],value;
  220.   const char *str;
  221.   uint32 length;
  222.   LINT_INIT(value);  LINT_INIT(str); LINT_INIT(length);
  223.   bzero((char*) t,sizeof(*t));
  224.   if ((int) int_type <= INTERVAL_SECOND)
  225.   {
  226.     value=(long) args->val_int();
  227.     if (args->null_value)
  228.       return 1;
  229.     if (value < 0)
  230.     {
  231.       t->neg=1;
  232.       value= -value;
  233.     }
  234.   }
  235.   else
  236.   {
  237.     String *res;
  238.     if (!(res=args->val_str(str_value)))
  239.       return (1);
  240.     /* record negative intervalls in t->neg */
  241.     str=res->ptr();
  242.     const char *end=str+res->length();
  243.     while (str != end && isspace(*str))
  244.       str++;
  245.     if (str != end && *str == '-')
  246.     {
  247.       t->neg=1;
  248.       str++;
  249.     }
  250.     length=(uint32) (end-str); // Set up pointers to new str
  251.   }
  252.   switch (int_type) {
  253.   case INTERVAL_YEAR:
  254.     t->year=value;
  255.     break;
  256.   case INTERVAL_MONTH:
  257.     t->month=value;
  258.     break;
  259.   case INTERVAL_DAY:
  260.     t->day=value;
  261.     break;
  262.   case INTERVAL_HOUR:
  263.     t->hour=value;
  264.     break;
  265.   case INTERVAL_MINUTE:
  266.     t->minute=value;
  267.     break;
  268.   case INTERVAL_SECOND:
  269.     t->second=value;
  270.     break;
  271.   case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
  272.     if (get_interval_info(str,length,2,array))
  273.       return (1);
  274.     t->year=array[0];
  275.     t->month=array[1];
  276.     break;
  277.   case INTERVAL_DAY_HOUR:
  278.     if (get_interval_info(str,length,2,array))
  279.       return (1);
  280.     t->day=array[0];
  281.     t->hour=array[1];
  282.     break;
  283.   case INTERVAL_DAY_MINUTE:
  284.     if (get_interval_info(str,length,3,array))
  285.       return (1);
  286.     t->day=array[0];
  287.     t->hour=array[1];
  288.     t->minute=array[2];
  289.     break;
  290.   case INTERVAL_DAY_SECOND:
  291.     if (get_interval_info(str,length,4,array))
  292.       return (1);
  293.     t->day=array[0];
  294.     t->hour=array[1];
  295.     t->minute=array[2];
  296.     t->second=array[3];
  297.     break;
  298.   case INTERVAL_HOUR_MINUTE:
  299.     if (get_interval_info(str,length,2,array))
  300.       return (1);
  301.     t->hour=array[0];
  302.     t->minute=array[1];
  303.     break;
  304.   case INTERVAL_HOUR_SECOND:
  305.     if (get_interval_info(str,length,3,array))
  306.       return (1);
  307.     t->hour=array[0];
  308.     t->minute=array[1];
  309.     t->second=array[2];
  310.     break;
  311.   case INTERVAL_MINUTE_SECOND:
  312.     if (get_interval_info(str,length,2,array))
  313.       return (1);
  314.     t->minute=array[0];
  315.     t->second=array[1];
  316.     break;
  317.   }
  318.   return 0;
  319. }
  320. String *Item_date::val_str(String *str)
  321. {
  322.   ulong value=(ulong) val_int();
  323.   if (null_value)
  324.     return (String*) 0;
  325.   if (!value) // zero daynr
  326.   {
  327.     str->copy("0000-00-00");
  328.     return str;
  329.   }
  330.   if (str->alloc(11))
  331.     return &empty_string; /* purecov: inspected */
  332.   sprintf((char*) str->ptr(),"%04d-%02d-%02d",
  333.   (int) (value/10000L) % 10000,
  334.   (int) (value/100)%100,
  335.   (int) (value%100));
  336.   str->length(10);
  337.   return str;
  338. }
  339. bool Item_date::save_in_field(Field *field)
  340. {
  341.   TIME ltime;
  342.   timestamp_type t_type=TIMESTAMP_FULL;
  343.   if (get_date(&ltime,1))
  344.   {
  345.     if (null_value)
  346.       return set_field_to_null(field);
  347.     t_type=TIMESTAMP_NONE; // Error
  348.   }
  349.   field->set_notnull();
  350.   field->store_time(&ltime,t_type);
  351.   return 0;
  352. }
  353. longlong Item_func_from_days::val_int()
  354. {
  355.   longlong value=args[0]->val_int();
  356.   if ((null_value=args[0]->null_value))
  357.     return 0; /* purecov: inspected */
  358.   uint year,month,day;
  359.   get_date_from_daynr((long) value,&year,&month,&day);
  360.   return (longlong) (year*10000L+month*100+day);
  361. }
  362. void Item_func_curdate::fix_length_and_dec()
  363. {
  364.   struct tm tm_tmp,*start;
  365.   time_t query_start=current_thd->query_start();
  366.   decimals=0; max_length=10;
  367.   localtime_r(&query_start,&tm_tmp);
  368.   start=&tm_tmp;
  369.   value=(longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
  370.     ((uint) start->tm_mon+1)*100+
  371.     (uint) start->tm_mday);
  372.   /* For getdate */
  373.   ltime.year= start->tm_year+1900;
  374.   ltime.month= start->tm_mon+1;
  375.   ltime.day= start->tm_mday;
  376.   ltime.hour= 0;
  377.   ltime.minute= 0;
  378.   ltime.second= 0;
  379.   ltime.second_part=0;
  380.   ltime.neg=0;
  381.   ltime.time_type=TIMESTAMP_DATE;
  382. }
  383. bool Item_func_curdate::get_date(TIME *res,
  384.  bool fuzzy_date __attribute__((unused)))
  385. {
  386.   *res=ltime;
  387.   return 0;
  388. }
  389. void Item_func_curtime::fix_length_and_dec()
  390. {
  391.   struct tm tm_tmp,*start;
  392.   time_t query_start=current_thd->query_start();
  393.   decimals=0; max_length=8;
  394.   localtime_r(&query_start,&tm_tmp);
  395.   start=&tm_tmp;
  396.   value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
  397.     (ulong) (((uint) start->tm_min)*100L+
  398.      (uint) start->tm_sec));
  399.   sprintf(buff,"%02d:%02d:%02d",
  400.   (int) start->tm_hour,
  401.   (int) start->tm_min,
  402.   (int) start->tm_sec);
  403.   buff_length=(uint) strlen(buff);
  404. }
  405. void Item_func_now::fix_length_and_dec()
  406. {
  407.   struct tm tm_tmp,*start;
  408.   time_t query_start=current_thd->query_start();
  409.   decimals=0; max_length=19;
  410.   localtime_r(&query_start,&tm_tmp);
  411.   start=&tm_tmp;
  412.   value=((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
  413.      (((uint) start->tm_mon+1)*100+
  414.       (uint) start->tm_mday))*(longlong) 1000000L+
  415.  (longlong) ((ulong) ((uint) start->tm_hour)*10000L+
  416.      (ulong) (((uint) start->tm_min)*100L+
  417.     (uint) start->tm_sec)));
  418.   sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
  419.   ((int) (start->tm_year+1900)) % 10000,
  420.   (int) start->tm_mon+1,
  421.   (int) start->tm_mday,
  422.   (int) start->tm_hour,
  423.   (int) start->tm_min,
  424.   (int) start->tm_sec);
  425.   buff_length=(uint) strlen(buff);
  426.   /* For getdate */
  427.   ltime.year= start->tm_year+1900;
  428.   ltime.month= start->tm_mon+1;
  429.   ltime.day= start->tm_mday;
  430.   ltime.hour= start->tm_hour;
  431.   ltime.minute= start->tm_min;
  432.   ltime.second= start->tm_sec;
  433.   ltime.second_part=0;
  434.   ltime.neg=0;
  435.   ltime.time_type=TIMESTAMP_FULL;
  436. }
  437. bool Item_func_now::get_date(TIME *res,
  438.      bool fuzzy_date __attribute__((unused)))
  439. {
  440.   *res=ltime;
  441.   return 0;
  442. }
  443. bool Item_func_now::save_in_field(Field *to)
  444. {
  445.   to->set_notnull();
  446.   to->store_time(&ltime,TIMESTAMP_FULL);
  447.   return 0;
  448. }
  449. String *Item_func_sec_to_time::val_str(String *str)
  450. {
  451.   char buff[23];
  452.   const char *sign="";
  453.   longlong seconds=(longlong) args[0]->val_int();
  454.   if ((null_value=args[0]->null_value))
  455.     return (String*) 0;
  456.   if (seconds < 0)
  457.   {
  458.     seconds= -seconds;
  459.     sign= "-";
  460.   }
  461.   uint sec= (uint) (seconds % 3600);
  462.   sprintf(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600),
  463.   sec/60, sec % 60);
  464.   str->copy(buff,(uint) strlen(buff));
  465.   return str;
  466. }
  467. longlong Item_func_sec_to_time::val_int()
  468. {
  469.   longlong seconds=args[0]->val_int();
  470.   longlong sign=1;
  471.   if ((null_value=args[0]->null_value))
  472.     return 0;
  473.   if (seconds < 0)
  474.   {
  475.     seconds= -seconds;
  476.     sign= -1;
  477.   }
  478.   return sign*((seconds / 3600)*10000+((seconds/60) % 60)*100+ (seconds % 60));
  479. }
  480. void Item_func_date_format::fix_length_and_dec()
  481. {
  482.   decimals=0;
  483.   if (args[1]->type() == STRING_ITEM)
  484.   { // Optimize the normal case
  485.     fixed_length=1;
  486.     max_length=format_length(((Item_string*) args[1])->const_string());
  487.   }
  488.   else
  489.   {
  490.     fixed_length=0;
  491.     max_length=args[1]->max_length*10;
  492.     set_if_smaller(max_length,MAX_BLOB_WIDTH);
  493.   }
  494.   maybe_null=1; // If wrong date
  495. }
  496. uint Item_func_date_format::format_length(const String *format)
  497. {
  498.   uint size=0;
  499.   const char *ptr=format->ptr();
  500.   const char *end=ptr+format->length();
  501.   for (; ptr != end ; ptr++)
  502.   {
  503.     if (*ptr != '%' || ptr == end-1)
  504.       size++;
  505.     else
  506.     {
  507.       switch(*++ptr) {
  508.       case 'M': /* month, textual */
  509.       case 'W': /* day (of the week), textual */
  510. size += 9;
  511. break;
  512.       case 'D': /* day (of the month), numeric plus english suffix */
  513.       case 'Y': /* year, numeric, 4 digits */
  514.       case 'x': /* Year, used with 'v' */
  515.       case 'X': /* Year, used with 'v, where week starts with Monday' */
  516. size += 4;
  517. break;
  518.       case 'a': /* locale's abbreviated weekday name (Sun..Sat) */
  519.       case 'b': /* locale's abbreviated month name (Jan.Dec) */
  520.       case 'j': /* day of year (001..366) */
  521. size += 3;
  522. break;
  523.       case 'U': /* week (00..52) */
  524.       case 'u': /* week (00..52), where week starts with Monday */
  525.       case 'V': /* week 1..53 used with 'x' */
  526.       case 'v': /* week 1..53 used with 'x', where week starts with Monday */
  527.       case 'H': /* hour (00..23) */
  528.       case 'y': /* year, numeric, 2 digits */
  529.       case 'm': /* month, numeric */
  530.       case 'd': /* day (of the month), numeric */
  531.       case 'h': /* hour (01..12) */
  532.       case 'I': /* --||-- */
  533.       case 'i': /* minutes, numeric */
  534.       case 'k': /* hour ( 0..23) */
  535.       case 'l': /* hour ( 1..12) */
  536.       case 'p': /* locale's AM or PM */
  537.       case 'S': /* second (00..61) */
  538.       case 's': /* seconds, numeric */
  539.       case 'c': /* month (0..12) */
  540.       case 'e': /* day (0..31) */
  541. size += 2;
  542. break;
  543.       case 'r': /* time, 12-hour (hh:mm:ss [AP]M) */
  544. size += 11;
  545. break;
  546.       case 'T': /* time, 24-hour (hh:mm:ss) */
  547. size += 8;
  548. break;
  549.       case 'w': /* day (of the week), numeric */
  550.       case '%':
  551.       default:
  552. size++;
  553. break;
  554.       }
  555.     }
  556.   }
  557.   return size;
  558. }
  559. String *Item_func_date_format::val_str(String *str)
  560. {
  561.   String *format;
  562.   TIME l_time;
  563.   char intbuff[15];
  564.   uint size,weekday;
  565.   if (!date_or_time)
  566.   {
  567.     if (get_arg0_date(&l_time,1))
  568.       return 0;
  569.   }
  570.   else
  571.   {
  572.     String *res;
  573.     if (!(res=args[0]->val_str(str)))
  574.     {
  575.       null_value=1;
  576.       return 0;
  577.     }
  578.     if (str_to_time(res->ptr(),res->length(),&l_time))
  579.     {
  580.       null_value=1;
  581.       return 0;
  582.     }
  583.     l_time.year=l_time.month=l_time.day=0;
  584.     null_value=0;
  585.   }
  586.   if (!(format = args[1]->val_str(str)) || !format->length())
  587.   {
  588.     null_value=1;
  589.     return 0;
  590.   }
  591.   if (fixed_length)
  592.     size=max_length;
  593.   else
  594.     size=format_length(format);
  595.   if (format == str)
  596.     str=&str_value; // Save result here
  597.   if (str->alloc(size))
  598.   {
  599.     null_value=1;
  600.     return 0;
  601.   }
  602.   str->length(0);
  603.   /* Create the result string */
  604.   const char *ptr=format->ptr();
  605.   const char *end=ptr+format->length();
  606.   for ( ; ptr != end ; ptr++)
  607.   {
  608.     if (*ptr != '%' || ptr+1 == end)
  609.       str->append(*ptr);
  610.     else
  611.     {
  612.       switch (*++ptr) {
  613.       case 'M':
  614. if(!l_time.month)
  615. {
  616.   null_value=1;
  617.   return 0;
  618. }
  619. str->append(month_names[l_time.month-1]);
  620. break;
  621.       case 'b':
  622. if(!l_time.month)
  623. {
  624.   null_value=1;
  625.   return 0;
  626. }
  627. str->append(month_names[l_time.month-1].ptr(),3);
  628. break;
  629.       case 'W':
  630. if(date_or_time)
  631. {
  632.   null_value=1;
  633.   return 0;
  634. }
  635. weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0);
  636. str->append(day_names[weekday]);
  637. break;
  638.       case 'a':
  639. if(date_or_time)
  640. {
  641.   null_value=1;
  642.   return 0;
  643. }
  644. weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0);
  645. str->append(day_names[weekday].ptr(),3);
  646. break;
  647.       case 'D':
  648. if(date_or_time)
  649. {
  650.   null_value=1;
  651.   return 0;
  652. }
  653. sprintf(intbuff,"%d",l_time.day);
  654. str->append(intbuff);
  655. if (l_time.day >= 10 &&  l_time.day <= 19)
  656.   str->append("th");
  657. else
  658. {
  659.   switch (l_time.day %10)
  660.   {
  661.   case 1:
  662.     str->append("st");
  663.     break;
  664.   case 2:
  665.     str->append("nd");
  666.     break;
  667.   case 3:
  668.     str->append("rd");
  669.     break;
  670.   default:
  671.     str->append("th");
  672.     break;
  673.   }
  674. }
  675. break;
  676.       case 'Y':
  677. sprintf(intbuff,"%04d",l_time.year);
  678. str->append(intbuff);
  679. break;
  680.       case 'y':
  681. sprintf(intbuff,"%02d",l_time.year%100);
  682. str->append(intbuff);
  683. break;
  684.       case 'm':
  685. sprintf(intbuff,"%02d",l_time.month);
  686. str->append(intbuff);
  687. break;
  688.       case 'c':
  689. sprintf(intbuff,"%d",l_time.month);
  690. str->append(intbuff);
  691. break;
  692.       case 'd':
  693. sprintf(intbuff,"%02d",l_time.day);
  694. str->append(intbuff);
  695. break;
  696.       case 'e':
  697. sprintf(intbuff,"%d",l_time.day);
  698. str->append(intbuff);
  699. break;
  700.       case 'H':
  701. sprintf(intbuff,"%02d",l_time.hour);
  702. str->append(intbuff);
  703. break;
  704.       case 'h':
  705.       case 'I':
  706. sprintf(intbuff,"%02d", (l_time.hour+11)%12+1);
  707. str->append(intbuff);
  708. break;
  709.       case 'i': /* minutes */
  710. sprintf(intbuff,"%02d",l_time.minute);
  711. str->append(intbuff);
  712. break;
  713.       case 'j':
  714. if(date_or_time)
  715. {
  716.   null_value=1;
  717.   return 0;
  718. }
  719. sprintf(intbuff,"%03d",
  720. (int) (calc_daynr(l_time.year,l_time.month,l_time.day) -
  721.        calc_daynr(l_time.year,1,1)) + 1);
  722. str->append(intbuff);
  723. break;
  724.       case 'k':
  725. sprintf(intbuff,"%d",l_time.hour);
  726. str->append(intbuff);
  727. break;
  728.       case 'l':
  729. sprintf(intbuff,"%d", (l_time.hour+11)%12+1);
  730. str->append(intbuff);
  731. break;
  732.       case 'p':
  733. str->append(l_time.hour < 12 ? "AM" : "PM");
  734. break;
  735.       case 'r':
  736. sprintf(intbuff,(l_time.hour < 12) ? "%02d:%02d:%02d AM" :
  737. "%02d:%02d:%02d PM",(l_time.hour+11)%12+1,l_time.minute,
  738. l_time.second);
  739. str->append(intbuff);
  740. break;
  741.       case 'S':
  742.       case 's':
  743. sprintf(intbuff,"%02d",l_time.second);
  744. str->append(intbuff);
  745. break;
  746.       case 'T':
  747. sprintf(intbuff,"%02d:%02d:%02d",l_time.hour,l_time.minute,l_time.second);
  748. str->append(intbuff);
  749. break;
  750.       case 'U':
  751.       case 'u':
  752.       {
  753. uint year;
  754. sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year));
  755. str->append(intbuff);
  756.       }
  757.       break;
  758.       case 'v':
  759.       case 'V':
  760.       {
  761. uint year;
  762. sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year));
  763. str->append(intbuff);
  764.       }
  765.       break;
  766.       case 'x':
  767.       case 'X':
  768.       {
  769. uint year;
  770. (void) calc_week(&l_time, 1, (*ptr) == 'X', &year);
  771. sprintf(intbuff,"%04d",year);
  772. str->append(intbuff);
  773.       }
  774.       break;
  775.       case 'w':
  776. weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1);
  777. sprintf(intbuff,"%01d",weekday);
  778. str->append(intbuff);
  779. break;
  780.       default:
  781. str->append(*ptr);
  782. break;
  783.       }
  784.     }
  785.   }
  786.   return str;
  787. }
  788. String *Item_func_from_unixtime::val_str(String *str)
  789. {
  790.   struct tm tm_tmp,*start;
  791.   time_t tmp=(time_t) args[0]->val_int();
  792.   if ((null_value=args[0]->null_value))
  793.     return 0;
  794.   localtime_r(&tmp,&tm_tmp);
  795.   start=&tm_tmp;
  796.   if (str->alloc(20))
  797.     return str; /* purecov: inspected */
  798.   sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d",
  799.   (int) start->tm_year+1900,
  800.   (int) start->tm_mon+1,
  801.   (int) start->tm_mday,
  802.   (int) start->tm_hour,
  803.   (int) start->tm_min,
  804.   (int) start->tm_sec);
  805.   str->length(19);
  806.   return str;
  807. }
  808. longlong Item_func_from_unixtime::val_int()
  809. {
  810.   time_t tmp=(time_t) (ulong) args[0]->val_int();
  811.   if ((null_value=args[0]->null_value))
  812.     return 0;
  813.   struct tm tm_tmp,*start;
  814.   localtime_r(&tmp,&tm_tmp);
  815.   start= &tm_tmp;
  816.   return ((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
  817.       (((uint) start->tm_mon+1)*100+
  818.        (uint) start->tm_mday))*LL(1000000)+
  819.   (longlong) ((ulong) ((uint) start->tm_hour)*10000L+
  820.       (ulong) (((uint) start->tm_min)*100L+
  821.        (uint) start->tm_sec)));
  822. }
  823. bool Item_func_from_unixtime::get_date(TIME *ltime,
  824.        bool fuzzy_date __attribute__((unused)))
  825. {
  826.   time_t tmp=(time_t) (ulong) args[0]->val_int();
  827.   if ((null_value=args[0]->null_value))
  828.     return 1;
  829.   struct tm tm_tmp,*start;
  830.   localtime_r(&tmp,&tm_tmp);
  831.   start= &tm_tmp;
  832.   ltime->year= start->tm_year+1900;
  833.   ltime->month= start->tm_mon+1;
  834.   ltime->day= start->tm_mday;
  835.   ltime->hour= start->tm_hour;
  836.   ltime->minute=start->tm_min;
  837.   ltime->second=start->tm_sec;
  838.   ltime->second_part=0;
  839.   ltime->neg=0;
  840.   return 0;
  841. }
  842.   /* Here arg[1] is a Item_interval object */
  843. bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date)
  844. {
  845.   long period,sign;
  846.   INTERVAL interval;
  847.   if (args[0]->get_date(ltime,0) ||
  848.       get_interval_value(args[1],int_type,&value,&interval))
  849.     goto null_date;
  850.   sign= (interval.neg ? -1 : 1);
  851.   if (date_sub_interval)
  852.     sign = -sign;
  853.   null_value=0;
  854.   switch (int_type) {
  855.   case INTERVAL_SECOND:
  856.   case INTERVAL_MINUTE:
  857.   case INTERVAL_HOUR:
  858.   case INTERVAL_MINUTE_SECOND:
  859.   case INTERVAL_HOUR_SECOND:
  860.   case INTERVAL_HOUR_MINUTE:
  861.   case INTERVAL_DAY_SECOND:
  862.   case INTERVAL_DAY_MINUTE:
  863.   case INTERVAL_DAY_HOUR:
  864.     long sec,days,daynr;
  865.     ltime->time_type=TIMESTAMP_FULL; // Return full date
  866.     sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
  867.  ltime->second +
  868.  sign*(interval.day*3600*24L +
  869.        interval.hour*3600+interval.minute*60+interval.second));
  870.     days=sec/(3600*24L); sec=sec-days*3600*24L;
  871.     if (sec < 0)
  872.     {
  873.       days--;
  874.       sec+=3600*24L;
  875.     }
  876.     ltime->second=sec % 60;
  877.     ltime->minute=sec/60 % 60;
  878.     ltime->hour=sec/3600;
  879.     daynr= calc_daynr(ltime->year,ltime->month,1) + days;
  880.     get_date_from_daynr(daynr,&ltime->year,&ltime->month,&ltime->day);
  881.     if (daynr < 0 || daynr >= 3652424) // Day number from year 0 to 9999-12-31
  882.       goto null_date;
  883.     break;
  884.   case INTERVAL_DAY:
  885.     period= calc_daynr(ltime->year,ltime->month,ltime->day) +
  886.       sign*interval.day;
  887.     if (period < 0 || period >= 3652424) // Daynumber from year 0 to 9999-12-31
  888.       goto null_date;
  889.     get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
  890.     break;
  891.   case INTERVAL_YEAR:
  892.     ltime->year += sign*interval.year;
  893.     if ((int) ltime->year < 0 || ltime->year >= 10000L)
  894.       goto null_date;
  895.     if (ltime->month == 2 && ltime->day == 29 &&
  896. calc_days_in_year(ltime->year) != 366)
  897.       ltime->day=28; // Was leap-year
  898.     break;
  899.   case INTERVAL_YEAR_MONTH:
  900.   case INTERVAL_MONTH:
  901.     period= (ltime->year*12 + sign*interval.year*12 +
  902.      ltime->month-1 + sign*interval.month);
  903.     if (period < 0 || period >= 120000L)
  904.       goto null_date;
  905.     ltime->year= (uint) (period / 12);
  906.     ltime->month= (uint) (period % 12L)+1;
  907.     /* Adjust day if the new month doesn't have enough days */
  908.     if (ltime->day > days_in_month[ltime->month-1])
  909.     {
  910.       ltime->day = days_in_month[ltime->month-1];
  911.       if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
  912. ltime->day++; // Leap-year
  913.     }
  914.     break;
  915.   default:
  916.     goto null_date;
  917.   }
  918.   return 0; // Ok
  919.  null_date:
  920.   return (null_value=1);
  921. }
  922. String *Item_date_add_interval::val_str(String *str)
  923. {
  924.   TIME ltime;
  925.   if (Item_date_add_interval::get_date(&ltime,0))
  926.     return 0;
  927.   if (ltime.time_type == TIMESTAMP_DATE)
  928.   {
  929.     if (str->alloc(11))
  930.       goto null_date;
  931.     sprintf((char*) str->ptr(),"%04d-%02d-%02d",
  932.     ltime.year,ltime.month,ltime.day);
  933.     str->length(10);
  934.   }
  935.   else
  936.   {
  937.     if (str->alloc(20))
  938.       goto null_date;
  939.     sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d",
  940.     ltime.year,ltime.month,ltime.day,
  941.     ltime.hour,ltime.minute,ltime.second);
  942.     str->length(19);
  943.   }
  944.   return str;
  945.  null_date:
  946.   null_value=1;
  947.   return 0;
  948. }
  949. longlong Item_date_add_interval::val_int()
  950. {
  951.   TIME ltime;
  952.   if (Item_date_add_interval::get_date(&ltime,0))
  953.     return (longlong) 0;
  954.   return ((longlong) (((ulong) ltime.year)*10000L+
  955.       (((uint) ltime.month)*100+
  956.        (uint) ltime.day))*(longlong) 1000000L+
  957.   (longlong) ((ulong) ((uint) ltime.hour)*10000L+
  958.       (ulong) (((uint)ltime.minute)*100L+
  959.        (uint) ltime.second)));
  960. }
  961. void Item_extract::fix_length_and_dec()
  962. {
  963.   value.alloc(32); // alloc buffer
  964.   maybe_null=1; // If wrong date
  965.   switch (int_type) {
  966.   case INTERVAL_YEAR: max_length=4; date_value=1; break;
  967.   case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break;
  968.   case INTERVAL_MONTH: max_length=2; date_value=1; break;
  969.   case INTERVAL_DAY: max_length=2; date_value=1; break;
  970.   case INTERVAL_DAY_HOUR: max_length=9; date_value=0; break;
  971.   case INTERVAL_DAY_MINUTE: max_length=11; date_value=0; break;
  972.   case INTERVAL_DAY_SECOND: max_length=13; date_value=0; break;
  973.   case INTERVAL_HOUR: max_length=2; date_value=0; break;
  974.   case INTERVAL_HOUR_MINUTE: max_length=4; date_value=0; break;
  975.   case INTERVAL_HOUR_SECOND: max_length=6; date_value=0; break;
  976.   case INTERVAL_MINUTE: max_length=2; date_value=0; break;
  977.   case INTERVAL_MINUTE_SECOND: max_length=4; date_value=0; break;
  978.   case INTERVAL_SECOND: max_length=2; date_value=0; break;
  979.   }
  980. }
  981. longlong Item_extract::val_int()
  982. {
  983.   TIME ltime;
  984.   long neg;
  985.   if (date_value)
  986.   {
  987.     if (get_arg0_date(&ltime,1))
  988.       return 0;
  989.     neg=1;
  990.   }
  991.   else
  992.   {
  993.     String *res= args[0]->val_str(&value);
  994.     if (!res || str_to_time(res->ptr(),res->length(),&ltime))
  995.     {
  996.       null_value=1;
  997.       return 0;
  998.     }
  999.     neg= ltime.neg ? -1 : 1;
  1000.     null_value=0;
  1001.   }
  1002.   switch (int_type) {
  1003.   case INTERVAL_YEAR: return ltime.year;
  1004.   case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month;
  1005.   case INTERVAL_MONTH: return ltime.month;
  1006.   case INTERVAL_DAY: return ltime.day;
  1007.   case INTERVAL_DAY_HOUR: return (long) (ltime.day*100L+ltime.hour)*neg;
  1008.   case INTERVAL_DAY_MINUTE: return (long) (ltime.day*10000L+
  1009.        ltime.hour*100L+
  1010.        ltime.minute)*neg;
  1011.   case INTERVAL_DAY_SECOND:  return ((longlong) ltime.day*1000000L+
  1012.  (longlong) (ltime.hour*10000L+
  1013.      ltime.minute*100+
  1014.      ltime.second))*neg;
  1015.   case INTERVAL_HOUR: return (long) ltime.hour*neg;
  1016.   case INTERVAL_HOUR_MINUTE: return (long) (ltime.hour*100+ltime.minute)*neg;
  1017.   case INTERVAL_HOUR_SECOND: return (long) (ltime.hour*10000+ltime.minute*100+
  1018.        ltime.second)*neg;
  1019.   case INTERVAL_MINUTE: return (long) ltime.minute*neg;
  1020.   case INTERVAL_MINUTE_SECOND: return (long) (ltime.minute*100+ltime.second)*neg;
  1021.   case INTERVAL_SECOND: return (long) ltime.second*neg;
  1022.   }
  1023.   return 0; // Impossible
  1024. }