summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc229
1 files changed, 155 insertions, 74 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 6eb2adb9392..10d26060278 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -22,6 +22,7 @@
#include "mysql_priv.h"
#include <m_ctype.h>
#include "my_dir.h"
+#include <assert.h>
/*****************************************************************************
** Item functions
@@ -46,6 +47,12 @@ Item::Item():
loop_id= 0;
}
+Item_ref_in_optimizer::Item_ref_in_optimizer(Item_in_optimizer *master,
+ char *table_name_par,
+ char *field_name_par):
+ Item_ref(master->args, table_name_par, field_name_par), owner(master) {}
+
+
bool Item::check_loop(uint id)
{
DBUG_ENTER("Item::check_loop");
@@ -372,12 +379,6 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
-void Item_param::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_STRING);
-}
-
-
double Item_param::val()
{
switch (item_result_type) {
@@ -436,6 +437,20 @@ String *Item_copy_string::val_str(String *str)
return &str_value;
}
+double Item_ref_in_optimizer::val()
+{
+ return owner->get_cache();
+}
+longlong Item_ref_in_optimizer::val_int()
+{
+ return owner->get_cache_int();
+}
+String* Item_ref_in_optimizer::val_str(String* s)
+{
+ return owner->get_cache_str(s);
+}
+
+
/*
Functions to convert item to field (for send_fields)
*/
@@ -511,10 +526,31 @@ bool Item_asterisk_remover::fix_fields(THD *thd,
res= item->fix_fields(thd, list, &item);
else
thd->fatal_error= 1; // no item given => out of memory
- *ref= item;
DBUG_RETURN(res);
}
+double Item_ref_null_helper::val()
+{
+ double tmp= (*ref)->val_result();
+ owner->was_null|= null_value= (*ref)->null_value;
+ return tmp;
+}
+longlong Item_ref_null_helper::val_int()
+{
+ longlong tmp= (*ref)->val_int_result();
+ owner->was_null|= null_value= (*ref)->null_value;
+ return tmp;
+}
+String* Item_ref_null_helper::val_str(String* s)
+{
+ String* tmp= (*ref)->str_result(s);
+ owner->was_null|= null_value= (*ref)->null_value;
+ return tmp;
+}
+bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
+{
+ return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
+}
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
@@ -632,65 +668,24 @@ void Item::init_make_field(Send_field *tmp_field,
tmp_field->flags |= UNSIGNED_FLAG;
}
-/* ARGSUSED */
-void Item_field::make_field(Send_field *tmp_field)
-{
- field->make_field(tmp_field);
- if (name)
- tmp_field->col_name=name; // Use user supplied name
-}
-
-void Item_int::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
-}
-
-void Item_uint::make_field(Send_field *tmp_field)
+void Item::make_field(Send_field *tmp_field)
{
- init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
- tmp_field->flags|= UNSIGNED_FLAG;
- unsigned_flag=1;
+ init_make_field(tmp_field, field_type());
}
-void Item_real::make_field(Send_field *tmp_field)
+enum_field_types Item::field_type() const
{
- init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
+ return ((result_type() == STRING_RESULT) ? FIELD_TYPE_VAR_STRING :
+ (result_type() == INT_RESULT) ? FIELD_TYPE_LONGLONG :
+ FIELD_TYPE_DOUBLE);
}
-void Item_string::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_STRING);
-}
-
-void Item_datetime::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_DATETIME);
-}
-
-
-void Item_null::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_NULL);
- tmp_field->length=4;
-}
-
-
-void Item_func::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field, ((result_type() == STRING_RESULT) ?
- FIELD_TYPE_VAR_STRING :
- (result_type() == INT_RESULT) ?
- FIELD_TYPE_LONGLONG : FIELD_TYPE_DOUBLE));
-}
-
-void Item_avg_field::make_field(Send_field *tmp_field)
-{
- init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
-}
-
-void Item_std_field::make_field(Send_field *tmp_field)
+/* ARGSUSED */
+void Item_field::make_field(Send_field *tmp_field)
{
- init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
+ field->make_field(tmp_field);
+ if (name)
+ tmp_field->col_name=name; // Use user supplied name
}
/*
@@ -899,31 +894,118 @@ int Item_varbinary::save_in_field(Field *field, bool no_conversions)
}
-void Item_varbinary::make_field(Send_field *tmp_field)
+/*
+ Pack data in buffer for sending
+*/
+
+bool Item_null::send(Protocol *protocol, String *packet)
{
- init_make_field(tmp_field,FIELD_TYPE_STRING);
+ return protocol->store_null();
}
/*
-** pack data in buffer for sending
+ This is only called from items that is not of type item_field
*/
-bool Item::send(THD *thd, String *packet)
+bool Item::send(Protocol *protocol, String *buffer)
{
- char buff[MAX_FIELD_WIDTH];
- CONVERT *convert;
- String s(buff,sizeof(buff),packet->charset()),*res;
- if (!(res=val_str(&s)))
- return net_store_null(packet);
- if ((convert=thd->variables.convert_set))
- return convert->store(packet,res->ptr(),res->length());
- return net_store_data(packet,res->ptr(),res->length());
+ bool result;
+ enum_field_types type;
+ LINT_INIT(result);
+
+ switch ((type=field_type())) {
+ default:
+ case MYSQL_TYPE_NULL:
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_GEOMETRY:
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_VAR_STRING:
+ {
+ String *res;
+ if ((res=val_str(buffer)))
+ result= protocol->store(res->ptr(),res->length());
+ break;
+ }
+ case MYSQL_TYPE_TINY:
+ {
+ longlong nr;
+ nr= val_int();
+ if (!null_value)
+ result= protocol->store_tiny(nr);
+ break;
+ }
+ case MYSQL_TYPE_SHORT:
+ {
+ longlong nr;
+ nr= val_int();
+ if (!null_value)
+ result= protocol->store_short(nr);
+ break;
+ }
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_LONG:
+ {
+ longlong nr;
+ nr= val_int();
+ if (!null_value)
+ result= protocol->store_long(nr);
+ break;
+ }
+ case MYSQL_TYPE_LONGLONG:
+ {
+ longlong nr;
+ nr= val_int();
+ if (!null_value)
+ result= protocol->store_longlong(nr, unsigned_flag);
+ break;
+ }
+ case MYSQL_TYPE_DOUBLE:
+ {
+ double nr;
+ nr= val();
+ if (!null_value)
+ result= protocol->store(nr, decimals, buffer);
+ break;
+ }
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIMESTAMP:
+ {
+ TIME tm;
+ get_date(&tm, 1);
+ if (!null_value)
+ {
+ if (type == MYSQL_TYPE_DATE)
+ return protocol->store_date(&tm);
+ else
+ result= protocol->store(&tm);
+ }
+ break;
+ }
+ case MYSQL_TYPE_TIME:
+ {
+ TIME tm;
+ get_time(&tm);
+ if (!null_value)
+ result= protocol->store_time(&tm);
+ break;
+ }
+ }
+ if (null_value)
+ result= protocol->store_null();
+ return result;
}
-bool Item_null::send(THD *thd, String *packet)
+bool Item_field::send(Protocol *protocol, String *buffer)
{
- return net_store_null(packet);
+ return protocol->store(result_field);
}
#ifdef EMBEDDED_LIBRARY
@@ -985,7 +1067,6 @@ bool Item_field::embedded_send(const CONVERT *convert, CHARSET_INFO *charset, ME
#endif
-
/*
This is used for HAVING clause
Find field in select list having the same name