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