summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/item.cc29
-rw-r--r--sql/item.h5
-rw-r--r--sql/protocol.cc1
-rw-r--r--sql/sql_prepare.cc93
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(&ltime, 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;