Drizzled Public API Documentation

user_var_entry.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/session.h>
00023 #include <drizzled/internal/m_string.h>
00024 #include <drizzled/user_var_entry.h>
00025 #include <drizzled/type/decimal.h>
00026 #include <drizzled/charset.h>
00027 
00028 namespace drizzled {
00029 
00032 double user_var_entry::val_real(bool *null_value) const
00033 {
00034   if ((*null_value= not value))
00035     return 0.0;
00036 
00037   switch (type) 
00038   {
00039   case REAL_RESULT:
00040     return *(double*) value;
00041 
00042   case INT_RESULT:
00043     return (double) *(int64_t*) value;
00044 
00045   case DECIMAL_RESULT:
00046     {
00047       double result;
00048       class_decimal2double(E_DEC_FATAL_ERROR, (type::Decimal *)value, &result);
00049       return result;
00050     }
00051 
00052   case STRING_RESULT:
00053     return internal::my_atof(value);                      // This is null terminated
00054 
00055   case ROW_RESULT:
00056     assert(false);        // Impossible
00057     break;
00058   }
00059   return 0.0;         // Impossible
00060 }
00061 
00062 
00065 int64_t user_var_entry::val_int(bool *null_value) const
00066 {
00067   if ((*null_value= not value))
00068     return 0;
00069 
00070   switch (type) 
00071   {
00072   case REAL_RESULT:
00073     return (int64_t) *(double*) value;
00074 
00075   case INT_RESULT:
00076     return *(int64_t*) value;
00077 
00078   case DECIMAL_RESULT:
00079     {
00080       int64_t result;
00081       ((type::Decimal *)(value))->val_int32(E_DEC_FATAL_ERROR, 0, &result);
00082       return result;
00083     }
00084 
00085   case STRING_RESULT:
00086     {
00087       int error;
00088       return internal::my_strtoll10(value, (char**) 0, &error);// String is null terminated
00089     }
00090 
00091   case ROW_RESULT:
00092     assert(false);        // Impossible
00093     break;
00094   }
00095 
00096   assert(false);
00097   return 0;         // Impossible
00098 }
00099 
00100 
00103 String *user_var_entry::val_str(bool *null_value, String *str, uint32_t decimals) const
00104 {
00105   if ((*null_value= not value))
00106     return NULL;
00107 
00108   switch (type) 
00109   {
00110   case REAL_RESULT:
00111     str->set_real(*(double*) value, decimals, &my_charset_bin);
00112     break;
00113 
00114   case INT_RESULT:
00115     if (!unsigned_flag)
00116       str->set(*(int64_t*) value, &my_charset_bin);
00117     else
00118       str->set(*(uint64_t*) value, &my_charset_bin);
00119     break;
00120 
00121   case DECIMAL_RESULT:
00122     class_decimal2string((type::Decimal *)value, 0, str);
00123     break;
00124 
00125   case STRING_RESULT:
00126     str->copy(value, length, collation.collation);
00127     break;
00128 
00129   case ROW_RESULT:
00130     assert(false);        // Impossible
00131     break;
00132   }
00133 
00134   return str;
00135 }
00136 
00139 type::Decimal *user_var_entry::val_decimal(bool *null_value, type::Decimal *val) const
00140 {
00141   if ((*null_value= not value))
00142     return 0;
00143 
00144   switch (type) 
00145   {
00146   case REAL_RESULT:
00147     double2_class_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
00148     break;
00149 
00150   case INT_RESULT:
00151     int2_class_decimal(E_DEC_FATAL_ERROR, *(int64_t*) value, 0, val);
00152     break;
00153 
00154   case DECIMAL_RESULT:
00155     val= (type::Decimal *)value;
00156     break;
00157 
00158   case STRING_RESULT:
00159     val->store(E_DEC_FATAL_ERROR, value, length, collation.collation);
00160     break;
00161 
00162   case ROW_RESULT:
00163     assert(false);        // Impossible
00164     break;
00165   }
00166 
00167   return val;
00168 }
00169 
00190 void user_var_entry::update_hash(bool set_null, data_ref data, Item_result arg_type, const charset_info_st* cs, Derivation dv, bool unsigned_arg)
00191 {
00192   if (set_null)
00193   {
00194     if (value)
00195     {
00196       assert(length && size);
00197       free(value);
00198       value= NULL;
00199       length= 0;
00200       size= 0;
00201     }
00202   }
00203   else
00204   {
00205     size_t needed_size= data.size() + ((arg_type == STRING_RESULT) ? 1 : 0);
00206 
00207     if (needed_size > size)
00208     {
00209       value= (char *)realloc(value, needed_size);
00210       size= needed_size;
00211     }
00212 
00213     if (arg_type == STRING_RESULT)
00214       value[data.size()]= 0;      // Store end \0
00215 
00216     memcpy(value, data.data(), data.size());
00217     if (arg_type == DECIMAL_RESULT)
00218       ((type::Decimal*)value)->fix_buffer_pointer();
00219     length= data.size();
00220     collation.set(cs, dv);
00221     unsigned_flag= unsigned_arg;
00222   }
00223   type= arg_type;
00224 }
00225 
00226 } /* namespace drizzled */