diff options
-rw-r--r-- | sql/item.cc | 29 | ||||
-rw-r--r-- | sql/item.h | 5 | ||||
-rw-r--r-- | sql/protocol.cc | 1 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 93 |
4 files changed, 126 insertions, 2 deletions
diff --git a/sql/item.cc b/sql/item.cc index 6ae9b92295f..359ba486a71 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -347,6 +347,25 @@ void Item_param::set_value(const char *str, uint length) } +void Item_param::set_time(TIME *tm, timestamp_type type) +{ + ltime.year= tm->year; + ltime.month= tm->month; + ltime.day= tm->day; + + ltime.hour= tm->hour; + ltime.minute= tm->minute; + ltime.second= tm->second; + + ltime.second_part= tm->second_part; + + ltime.time_type= type; + + item_is_time= true; + item_type= STRING_ITEM; +} + + void Item_param::set_longdata(const char *str, ulong length) { str_value.append(str,length); @@ -369,11 +388,21 @@ int Item_param::save_in_field(Field *field, bool no_conversions) { double nr=val(); return (field->store(nr)) ? -1 : 0; + } + if (item_is_time) + { + field->store_time(<ime, ltime.time_type); + return 0; } String *result=val_str(&str_value); return (field->store(result->ptr(),result->length(),field->charset())) ? -1 : 0; } +bool Item_param::get_time(TIME *res) +{ + *res=ltime; + return 0; +} double Item_param::val() { diff --git a/sql/item.h b/sql/item.h index 09882b26724..25cc2601281 100644 --- a/sql/item.h +++ b/sql/item.h @@ -201,9 +201,11 @@ class Item_param :public Item public: longlong int_value; double real_value; + TIME ltime; enum Item_result item_result_type; enum Type item_type; enum enum_field_types buffer_type; + bool item_is_time; my_bool long_data_supplied; Item_param(char *name_par=0) @@ -212,6 +214,7 @@ public: long_data_supplied= false; item_type= STRING_ITEM; item_result_type = STRING_RESULT; + item_is_time= false; } enum Type type() const { return item_type; } double val(); @@ -226,6 +229,8 @@ public: void set_long_binary(const char *str, ulong length); void set_longdata(const char *str, ulong length); void set_long_end(); + void set_time(TIME *tm, timestamp_type type); + bool get_time(TIME *tm); void reset() {} void (*setup_param_func)(Item_param *param, uchar **pos); enum Item_result result_type () const diff --git a/sql/protocol.cc b/sql/protocol.cc index da9f5712e3a..b81aa54af99 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -923,6 +923,7 @@ bool Protocol_prep::store_long(longlong from) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || + field_types[field_pos] == MYSQL_TYPE_INT24 || field_types[field_pos] == MYSQL_TYPE_LONG); #endif field_pos++; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index e8ba7e91c7b..758054a6e48 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -256,11 +256,87 @@ static void setup_param_double(Item_param *param, uchar **pos) *pos+= 8; } +static void setup_param_time(Item_param *param, uchar **pos) +{ + ulong length; + + if ((length= get_param_length(pos))) + { + uchar *to= *pos; + TIME tm; + + tm.second_part= (length > 8 ) ? (ulong) sint4korr(to+7): 0; + + tm.day= (ulong) sint4korr(to+1); + tm.hour= (uint) to[5]; + tm.minute= (uint) to[6]; + tm.second= (uint) to[7]; + + tm.year= tm.month= 0; + tm.neg= (bool)to[0]; + + param->set_time(&tm, TIMESTAMP_TIME); + } + *pos+= length; +} + +static void setup_param_datetime(Item_param *param, uchar **pos) +{ + uint length= get_param_length(pos); + + if (length) + { + uchar *to= *pos; + TIME tm; + + tm.second_part= (length > 7 ) ? (ulong) sint4korr(to+7): 0; + + if (length > 4) + { + tm.hour= (uint) to[4]; + tm.minute= (uint) to[5]; + tm.second= (uint) to[6]; + } + else + tm.hour= tm.minute= tm.second= 0; + + tm.year= (uint) sint2korr(to); + tm.month= (uint) to[2]; + tm.day= (uint) to[3]; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_FULL); + } + *pos+= length; +} + +static void setup_param_date(Item_param *param, uchar **pos) +{ + ulong length; + + if ((length= get_param_length(pos))) + { + uchar *to= *pos; + TIME tm; + + tm.year = (uint) sint2korr(to); + tm.month= (uint) to[2]; + tm.day= (uint) to[3]; + + tm.hour= tm.minute= tm.second= 0; + tm.second_part= 0; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_DATE); + } + *pos+= length; +} + static void setup_param_str(Item_param *param, uchar **pos) { - ulong len=get_param_length(pos); + ulong len= get_param_length(pos); param->set_value((const char *)*pos, len); - *pos+=len; + *pos+= len; } static void setup_param_functions(Item_param *param, uchar param_type) @@ -290,6 +366,19 @@ static void setup_param_functions(Item_param *param, uchar param_type) param->setup_param_func= setup_param_double; param->item_result_type = REAL_RESULT; break; + case FIELD_TYPE_TIME: + param->setup_param_func= setup_param_time; + param->item_result_type = STRING_RESULT; + break; + case FIELD_TYPE_DATE: + param->setup_param_func= setup_param_date; + param->item_result_type = STRING_RESULT; + break; + case FIELD_TYPE_DATETIME: + case FIELD_TYPE_TIMESTAMP: + param->setup_param_func= setup_param_datetime; + param->item_result_type = STRING_RESULT; + break; default: param->setup_param_func= setup_param_str; param->item_result_type = STRING_RESULT; |