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 <cstdio>
00023
00024 #include <drizzled/current_session.h>
00025 #include <drizzled/error.h>
00026 #include <drizzled/function/time/typecast.h>
00027 #include <drizzled/time_functions.h>
00028 #include <drizzled/charset.h>
00029
00030 namespace drizzled
00031 {
00032
00033 bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
00034 {
00035 if (this == item)
00036 return 1;
00037 if (item->type() != FUNC_ITEM ||
00038 functype() != ((Item_func*)item)->functype())
00039 return 0;
00040
00041 Item_char_typecast *cast= (Item_char_typecast*)item;
00042 if (cast_length != cast->cast_length ||
00043 cast_cs != cast->cast_cs)
00044 return 0;
00045
00046 if (!args[0]->eq(cast->args[0], binary_cmp))
00047 return 0;
00048 return 1;
00049 }
00050
00051 void Item_typecast::print(String *str)
00052 {
00053 str->append(STRING_WITH_LEN("cast("));
00054 args[0]->print(str);
00055 str->append(STRING_WITH_LEN(" as "));
00056 str->append(cast_type());
00057 str->append(')');
00058 }
00059
00060
00061 void Item_char_typecast::print(String *str)
00062 {
00063 str->append(STRING_WITH_LEN("cast("));
00064 args[0]->print(str);
00065 str->append(STRING_WITH_LEN(" as char"));
00066 if (cast_length >= 0)
00067 {
00068 str->append('(');
00069 char buffer[20];
00070
00071 String st(buffer, sizeof(buffer), &my_charset_bin);
00072 st.set((uint64_t)cast_length, &my_charset_bin);
00073 str->append(st);
00074 str->append(')');
00075 }
00076 if (cast_cs)
00077 {
00078 str->append(STRING_WITH_LEN(" charset "));
00079 str->append(cast_cs->csname);
00080 }
00081 str->append(')');
00082 }
00083
00084 String *Item_char_typecast::val_str(String *str)
00085 {
00086 assert(fixed == 1);
00087 String *res;
00088 uint32_t length;
00089
00090 if (!charset_conversion)
00091 {
00092 if (!(res= args[0]->val_str(str)))
00093 {
00094 null_value= 1;
00095 return 0;
00096 }
00097 }
00098 else
00099 {
00100
00101 size_t dummy_errors;
00102 if (!(res= args[0]->val_str(&tmp_value)) ||
00103 str->copy(res->ptr(), res->length(), from_cs,
00104 cast_cs, &dummy_errors))
00105 {
00106 null_value= 1;
00107 return 0;
00108 }
00109 res= str;
00110 }
00111
00112 res->set_charset(cast_cs);
00113
00114
00115
00116
00117
00118
00119 if (cast_length >= 0)
00120 {
00121 if (res->length() > (length= (uint32_t) res->charpos(cast_length)))
00122 {
00123 char char_type[40];
00124 snprintf(char_type, sizeof(char_type), "%s(%lu)",
00125 cast_cs == &my_charset_bin ? "BINARY" : "CHAR",
00126 (ulong) cast_length);
00127
00128 if (!res->alloced_length())
00129 {
00130 str_value= *res;
00131 res= &str_value;
00132 }
00133 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00134 ER_TRUNCATED_WRONG_VALUE,
00135 ER(ER_TRUNCATED_WRONG_VALUE), char_type,
00136 res->c_ptr_safe());
00137 res->length((uint) length);
00138 }
00139 else if (cast_cs == &my_charset_bin && res->length() < (uint) cast_length)
00140 {
00141 if (res->alloced_length() < (uint) cast_length)
00142 {
00143 str->alloc(cast_length);
00144 str->copy(*res);
00145 res= str;
00146 }
00147 memset(res->ptr() + res->length(), 0,
00148 (uint) cast_length - res->length());
00149 res->length(cast_length);
00150 }
00151 }
00152 null_value= 0;
00153 return res;
00154 }
00155
00156
00157 void Item_char_typecast::fix_length_and_dec()
00158 {
00159 uint32_t char_length;
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 from_cs= (args[0]->result_type() == INT_RESULT ||
00183 args[0]->result_type() == DECIMAL_RESULT ||
00184 args[0]->result_type() == REAL_RESULT) ?
00185 (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_utf8_general_ci) :
00186 args[0]->collation.collation;
00187 charset_conversion= (cast_cs->mbmaxlen > 1) ||
00188 (!my_charset_same(from_cs, cast_cs) && from_cs != &my_charset_bin && cast_cs != &my_charset_bin);
00189 collation.set(cast_cs, DERIVATION_IMPLICIT);
00190 char_length= (cast_length >= 0) ? (uint32_t)cast_length :
00191 (uint32_t)args[0]->max_length/from_cs->mbmaxlen;
00192 max_length= char_length * cast_cs->mbmaxlen;
00193 }
00194
00195
00196 String *Item_datetime_typecast::val_str(String *str)
00197 {
00198 assert(fixed == 1);
00199 type::Time ltime;
00200
00201 if (not get_arg0_date(ltime, TIME_FUZZY_DATE))
00202 {
00203 if (ltime.second_part)
00204 {
00205 ltime.convert(*str);
00206 }
00207 else
00208 {
00209 ltime.convert(*str);
00210 }
00211
00212 return str;
00213 }
00214
00215 null_value=1;
00216 return 0;
00217 }
00218
00219
00220 int64_t Item_datetime_typecast::val_int()
00221 {
00222 assert(fixed == 1);
00223 type::Time ltime;
00224 if (get_arg0_date(ltime, 1))
00225 {
00226 null_value= 1;
00227 return 0;
00228 }
00229
00230 int64_t tmp;
00231 ltime.convert(tmp);
00232
00233 return tmp;
00234 }
00235
00236
00237 bool Item_date_typecast::get_date(type::Time <ime, uint32_t )
00238 {
00239 bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
00240
00241 ltime.hour= ltime.minute= ltime.second= ltime.second_part= 0;
00242 ltime.time_type= type::DRIZZLE_TIMESTAMP_DATE;
00243
00244 return res;
00245 }
00246
00247
00248 bool Item_date_typecast::get_time(type::Time <ime)
00249 {
00250 ltime.reset();
00251
00252 return args[0]->null_value;
00253 }
00254
00255
00256 String *Item_date_typecast::val_str(String *str)
00257 {
00258 assert(fixed == 1);
00259 type::Time ltime;
00260
00261 if (!get_arg0_date(ltime, TIME_FUZZY_DATE) &&
00262 !str->alloc(type::Time::MAX_STRING_LENGTH))
00263 {
00264 ltime.convert(*str, type::DRIZZLE_TIMESTAMP_DATE);
00265
00266 return str;
00267 }
00268
00269 null_value=1;
00270 return 0;
00271 }
00272
00273 int64_t Item_date_typecast::val_int()
00274 {
00275 assert(fixed == 1);
00276 type::Time ltime;
00277
00278 if ((null_value= args[0]->get_date(ltime, TIME_FUZZY_DATE)))
00279 return 0;
00280
00281 return (int64_t) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
00282 }
00283
00284 }