Drizzled Public API Documentation

last_day.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 <drizzled/function/time/last_day.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/calendar.h>
00025 #include <drizzled/temporal.h>
00026 
00027 #include <sstream>
00028 #include <string>
00029 
00030 namespace drizzled
00031 {
00032 
00038 bool Item_func_last_day::get_temporal(Date &to)
00039 {
00040   assert(fixed);
00041 
00042   /* We return NULL from LAST_DAY() only when supplied a NULL argument */
00043   if (args[0]->null_value)
00044   {
00045     null_value= true;
00046     return false;
00047   }
00048 
00049   /* We use a DateTime to match as many temporal formats as possible. */
00050   DateTime temporal;
00051   Item_result arg0_result_type= args[0]->result_type();
00052   
00053   switch (arg0_result_type)
00054   {
00055     case REAL_RESULT:
00056     case DECIMAL_RESULT: 
00057       /* 
00058        * For doubles supplied, interpret the arg as a string, 
00059        * so intentionally fall-through here...
00060        * This allows us to accept double parameters like 
00061        * 19971231235959.01 and interpret it the way MySQL does:
00062        * as a TIMESTAMP-like thing with a microsecond component.
00063        * Ugh, but need to keep backwards-compat.
00064        */
00065     case STRING_RESULT:
00066       {
00067         char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00068         String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00069         String *res= args[0]->val_str(&tmp);
00070 
00071         if (! res)
00072         {
00073           /* 
00074            * Likely a nested function issue where the nested
00075            * function had bad input.  We rely on the nested
00076            * function my_error() and simply return false here.
00077            */
00078           return false;
00079         }
00080 
00081         if (res != &tmp)
00082         {
00083           tmp.copy(*res);
00084         }
00085 
00086         if (! temporal.from_string(tmp.c_ptr(), tmp.length()))
00087         {
00088           /* 
00089           * Could not interpret the function argument as a temporal value, 
00090           * so throw an error and return 0
00091           */
00092           my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
00093           return false;
00094         }
00095       }
00096       break;
00097     case INT_RESULT:
00098       if (temporal.from_int64_t(args[0]->val_int()))
00099         break;
00100       /* Intentionally fall-through on invalid conversion from integer */
00101     default:
00102       {
00103         /* 
00104         * Could not interpret the function argument as a temporal value, 
00105         * so throw an error and return 0
00106         */
00107         null_value= true;
00108         char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
00109         String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
00110         String *res;
00111 
00112         res= args[0]->val_str(&tmp);
00113 
00114         if (! res)
00115         {
00116           /* 
00117            * Likely a nested function issue where the nested
00118            * function had bad input.  We rely on the nested
00119            * function my_error() and simply return false here.
00120            */
00121           return false;
00122         }
00123 
00124         if (res != &tmp)
00125         {
00126           tmp.copy(*res);
00127         }
00128 
00129         my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
00130         return false;
00131       }
00132   }
00133   null_value= false;
00134 
00135   /* Now strip to the last day of the month... */
00136   temporal.set_days(days_in_gregorian_year_month(temporal.years(), temporal.months()));
00137   to= temporal; /* Operator overload in effect for assign DateTime to Date. */
00138 
00139   return true;
00140 }
00141 
00142 } /* namespace drizzled */