summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorunknown <msvensson@shellback.(none)>2006-11-29 15:44:09 +0100
committerunknown <msvensson@shellback.(none)>2006-11-29 15:44:09 +0100
commitd988576610f49682fbb5d51bf4697a66c25f2043 (patch)
tree9a20c4415bb69ebb31576302a0e46beb9863997e /sql/item.cc
parent4f912e049871bf3a4a708dc66477d4b55247bddd (diff)
parentb51cf266293929dec21e41bdc97c4eead4884f0e (diff)
downloadmariadb-git-d988576610f49682fbb5d51bf4697a66c25f2043.tar.gz
Merge shellback.(none):/home/msvensson/mysql/mysql-5.1
into shellback.(none):/home/msvensson/mysql/mysql-5.1-maint BitKeeper/etc/ignore: auto-union Makefile.am: Auto merged client/mysql.cc: Auto merged client/mysql_upgrade.c: Auto merged client/mysqltest.c: Auto merged extra/yassl/src/ssl.cpp: Auto merged mysql-test/lib/mtr_report.pl: Auto merged mysql-test/mysql-test-run-shell.sh: Auto merged mysql-test/mysql-test-run.pl: Auto merged mysql-test/r/query_cache.result: Auto merged mysql-test/r/udf.result: Auto merged mysql-test/t/alter_table.test: Auto merged mysql-test/t/disabled.def: Auto merged mysql-test/t/limit.test: Auto merged mysql-test/t/mysql.test: Auto merged mysql-test/t/mysqldump.test: Auto merged mysql-test/t/query_cache.test: Auto merged mysql-test/t/system_mysql_db_fix30020.test: Auto merged mysql-test/t/udf.test: Auto merged mysql-test/t/view_grant.test: Auto merged mysys/Makefile.am: Auto merged scripts/mysql_fix_privilege_tables.sql: Auto merged sql/item.cc: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_timefunc.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_handler.cc: Auto merged sql/sql_parse.cc: Auto merged sql-common/my_time.c: Auto merged sql/sql_table.cc: Auto merged extra/yassl/taocrypt/include/algebra.hpp: Remove fix as it conflicts with "import from yassl" and it's been fixed there sql/ha_ndbcluster.cc: Merge fix of warnings sql/sql_base.cc: Merge
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc111
1 files changed, 105 insertions, 6 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 0662ddefbb4..eff7defda0c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -269,6 +269,34 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
}
+my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ longlong date;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ {
+ my_decimal_set_zero(decimal_value);
+ return 0;
+ }
+ return date2my_decimal(&ltime, decimal_value);
+}
+
+
+my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ longlong date;
+ if (get_time(&ltime))
+ {
+ my_decimal_set_zero(decimal_value);
+ return 0;
+ }
+ return date2my_decimal(&ltime, decimal_value);
+}
+
+
double Item::val_real_from_decimal()
{
/* Note that fix_fields may not be called for Item_avg_field items */
@@ -292,6 +320,25 @@ longlong Item::val_int_from_decimal()
return result;
}
+int Item::save_time_in_field(Field *field)
+{
+ TIME ltime;
+ if (get_time(&ltime))
+ return set_field_to_null(field);
+ field->set_notnull();
+ return field->store_time(&ltime, MYSQL_TIMESTAMP_TIME);
+}
+
+
+int Item::save_date_in_field(Field *field)
+{
+ TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ return set_field_to_null(field);
+ field->set_notnull();
+ return field->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
+}
+
Item::Item():
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
@@ -1176,6 +1223,28 @@ void Item_name_const::print(String *str)
/*
+ need a special class to adjust printing : references to aggregate functions
+ must not be printed as refs because the aggregate functions that are added to
+ the front of select list are not printed as well.
+*/
+class Item_aggregate_ref : public Item_ref
+{
+public:
+ Item_aggregate_ref(Name_resolution_context *context_arg, Item **item,
+ const char *table_name_arg, const char *field_name_arg)
+ :Item_ref(context_arg, item, table_name_arg, field_name_arg) {}
+
+ void print (String *str)
+ {
+ if (ref)
+ (*ref)->print(str);
+ else
+ Item_ident::print(str);
+ }
+};
+
+
+/*
Move SUM items out from item tree and replace with reference
SYNOPSIS
@@ -1228,8 +1297,8 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
Item *new_item, *real_itm= real_item();
ref_pointer_array[el]= real_itm;
- if (!(new_item= new Item_ref(&thd->lex->current_select->context,
- ref_pointer_array + el, 0, name)))
+ if (!(new_item= new Item_aggregate_ref(&thd->lex->current_select->context,
+ ref_pointer_array + el, 0, name)))
return; // fatal_error is set
fields.push_front(real_itm);
thd->change_item_tree(ref, new_item);
@@ -3672,11 +3741,37 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND,
&not_used);
- if (res != (Item **)not_found_item &&
- (*res)->type() == Item::FIELD_ITEM)
+ if (res != (Item **)not_found_item)
{
- set_field((*((Item_field**)res))->field);
- return 0;
+ if ((*res)->type() == Item::FIELD_ITEM)
+ {
+ /*
+ It's an Item_field referencing another Item_field in the select
+ list.
+ use the field from the Item_field in the select list and leave
+ the Item_field instance in place.
+ */
+ set_field((*((Item_field**)res))->field);
+ return 0;
+ }
+ else
+ {
+ /*
+ It's not an Item_field in the select list so we must make a new
+ Item_ref to point to the Item in the select list and replace the
+ Item_field created by the parser with the new Item_ref.
+ */
+ Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
+ if (!rf)
+ return 1;
+ thd->change_item_tree(reference, rf);
+ /*
+ Because Item_ref never substitutes itself with other items
+ in Item_ref::fix_fields(), we can safely use the original
+ pointer to it even after fix_fields()
+ */
+ return rf->fix_fields(thd, reference) || rf->check_cols(1);
+ }
}
}
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
@@ -4193,6 +4288,10 @@ void Item_field::make_field(Send_field *tmp_field)
DBUG_ASSERT(tmp_field->table_name != 0);
if (name)
tmp_field->col_name=name; // Use user supplied name
+ if (table_name)
+ tmp_field->table_name= table_name;
+ if (db_name)
+ tmp_field->db_name= db_name;
}