~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2009-02-12 22:59:43 UTC
  • mfrom: (873.1.8 temporal-new)
  • Revision ID: brian@tangent.org-20090212225943-g2fh9aaw82sg9hko
Merge Jay.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include <drizzled/server_includes.h>
25
 
#include <drizzled/sql_select.h>
26
 
#include <drizzled/error.h>
27
 
#include <drizzled/item/cmpfunc.h>
28
 
#include <drizzled/cached_item.h>
29
 
#include <drizzled/item/cache_int.h>
30
 
#include <drizzled/item/int_with_ref.h>
31
 
#include <drizzled/function/bit.h>
32
 
#include <drizzled/check_stack_overrun.h>
 
24
#include "drizzled/server_includes.h"
 
25
#include "drizzled/sql_select.h"
 
26
#include "drizzled/error.h"
 
27
#include "drizzled/temporal.h"
 
28
#include "drizzled/item/cmpfunc.h"
 
29
#include "drizzled/cached_item.h"
 
30
#include "drizzled/item/cache_int.h"
 
31
#include "drizzled/item/int_with_ref.h"
 
32
#include "drizzled/function/bit.h"
 
33
#include "drizzled/check_stack_overrun.h"
33
34
 
34
35
#include CMATH_H
35
36
 
730
731
         int result and the other item (b or a) is an item with string result.
731
732
         If the second item is a constant one then it's checked to be
732
733
         convertible to the DATE/DATETIME type. If the constant can't be
733
 
         converted to a DATE/DATETIME then the compare_datetime() comparator
734
 
         isn't used and the warning about wrong DATE/DATETIME value is issued.
 
734
         converted to a DATE/DATETIME then an error is issued back to the Session.
735
735
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
736
736
      the comparison is handled by other comparators.
 
737
 
737
738
    If the datetime comparator can be used and one the operands of the
738
739
    comparison is a string constant that was successfully converted to a
739
740
    DATE/DATETIME type then the result of the conversion is returned in the
782
783
        (str_arg->type() != Item::FUNC_ITEM ||
783
784
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
784
785
    {
785
 
      Session *session= current_session;
 
786
      /*
 
787
       * OK, we are here if we've got a date field (or something which can be 
 
788
       * compared as a date field) on one side of the equation, and a constant
 
789
       * string on the other side.  In this case, we must verify that the constant
 
790
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
 
791
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
 
792
       * produce an error, and no implicit conversion or truncation should take place.
 
793
       *
 
794
       * If the conversion to a DateTime temporal is successful, then we convert
 
795
       * the Temporal instance to a uint64_t for the comparison operator, which
 
796
       * compares date(times) using int64_t semantics.
 
797
       *
 
798
       * @TODO
 
799
       *
 
800
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
 
801
       * from val_int(), not uint64_t...
 
802
       */
786
803
      uint64_t value;
787
 
      bool error;
788
 
      String tmp, *str_val= 0;
789
 
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_DATE ?
790
 
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
 
804
      String *str_val;
 
805
      String tmp;
 
806
      /* DateTime used to pick up as many string conversion possibilities as possible. */
 
807
      drizzled::DateTime temporal;
791
808
 
792
809
      str_val= str_arg->val_str(&tmp);
793
 
      if (str_arg->null_value)
794
 
        return CMP_DATE_DFLT;
795
 
      value= get_date_from_str(session, str_val, t_type, date_arg->name, &error);
796
 
      if (error)
797
 
        return CMP_DATE_DFLT;
 
810
      if (! str_val)
 
811
      {
 
812
        /* 
 
813
         * If we are here, it is most likely due to the comparison item
 
814
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
 
815
         * be used, not = NULL since no item can be equal to NULL).
 
816
         *
 
817
         * So, return gracefully.
 
818
         */
 
819
        return CMP_DATE_DFLT;
 
820
      }
 
821
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
 
822
      {
 
823
        /* Chuck an error. Bad datetime input. */
 
824
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
 
825
        return CMP_DATE_DFLT; /* :( What else can I return... */
 
826
      }
 
827
 
 
828
      /* String conversion was good.  Convert to an integer for comparison purposes. */
 
829
      int64_t int_value;
 
830
      temporal.to_int64_t(&int_value);
 
831
      value= (uint64_t) int_value;
 
832
 
798
833
      if (const_value)
799
834
        *const_value= value;
800
835
    }