diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 256 |
1 files changed, 70 insertions, 186 deletions
diff --git a/sql/item.cc b/sql/item.cc index 8fa3a0b741b..e72c2b80288 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1647,7 +1647,14 @@ Query_fragment::Query_fragment(THD *thd, sp_head *sphead, const char *start, const char *end) { DBUG_ASSERT(start <= end); - if (sphead) + if (thd->lex->clone_spec_offset) + { + Lex_input_stream *lip= (& thd->m_parser_state->m_lip); + DBUG_ASSERT(lip->get_buf() <= start); + DBUG_ASSERT(end <= lip->get_end_of_query()); + set(start - lip->get_buf(), end - start); + } + else if (sphead) { if (sphead->m_tmp_query) { @@ -4062,7 +4069,8 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, For dynamic SQL, settability depends on the type of Item passed as an actual parameter. See Item_param::set_from_item(). */ - m_is_settable_routine_parameter(true) + m_is_settable_routine_parameter(true), + m_clones(thd->mem_root) { name= *name_arg; /* @@ -4074,6 +4082,60 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, } +/* Add reference to Item_param used in a copy of CTE to its master as a clone */ + +bool Item_param::add_as_clone(THD *thd) +{ + LEX *lex= thd->lex; + my_ptrdiff_t master_pos= pos_in_query + lex->clone_spec_offset; + List_iterator_fast<Item_param> it(lex->param_list); + Item_param *master_param; + while ((master_param = it++)) + { + if (master_pos == master_param->pos_in_query) + return master_param->register_clone(this); + } + DBUG_ASSERT(false); + return false; +} + + +/* Update all clones of Item_param to sync their values with the item's value */ + +void Item_param::sync_clones() +{ + Item_param **c_ptr= m_clones.begin(); + Item_param **end= m_clones.end(); + for ( ; c_ptr < end; c_ptr++) + { + Item_param *c= *c_ptr; + /* Scalar-type members: */ + c->maybe_null= maybe_null; + c->null_value= null_value; + c->Type_std_attributes::operator=(*this); + c->Type_handler_hybrid_field_type::operator=(*this); + c->Type_geometry_attributes::operator=(*this); + + c->state= state; + c->item_type= item_type; + c->m_empty_string_is_null= m_empty_string_is_null; + + c->value.PValue_simple::operator=(value); + c->value.Type_handler_hybrid_field_type::operator=(value); + type_handler()->Item_param_setup_conversion(current_thd, c); + + /* Class-type members: */ + c->value.m_decimal= value.m_decimal; + /* + Note that String's assignment op properly sets m_is_alloced to 'false', + which is correct here: c->str_value doesn't own anything. + */ + c->value.m_string= value.m_string; + c->value.m_string_ptr= value.m_string_ptr; + } +} + + void Item_param::set_null() { DBUG_ENTER("Item_param::set_null"); @@ -4530,7 +4592,7 @@ longlong Item_param::PValue::val_int(const Type_std_attributes *attr) const { switch (type_handler()->cmp_type()) { case REAL_RESULT: - return (longlong) rint(real); + return Converter_double_to_longlong(real, attr->unsigned_flag).result(); case INT_RESULT: return integer; case DECIMAL_RESULT: @@ -5040,32 +5102,6 @@ bool Item_param::append_for_log(THD *thd, String *str) return str->append(*val); } -/**************************************************************************** - Item_copy -****************************************************************************/ - -Item_copy *Item_copy::create(THD *thd, Item *item) -{ - MEM_ROOT *mem_root= thd->mem_root; - switch (item->result_type()) - { - case STRING_RESULT: - return new (mem_root) Item_copy_string(thd, item); - case REAL_RESULT: - return new (mem_root) Item_copy_float(thd, item); - case INT_RESULT: - return item->unsigned_flag ? - new (mem_root) Item_copy_uint(thd, item) : - new (mem_root) Item_copy_int(thd, item); - case DECIMAL_RESULT: - return new (mem_root) Item_copy_decimal(thd, item); - case TIME_RESULT: - case ROW_RESULT: - DBUG_ASSERT (0); - } - /* should not happen */ - return NULL; -} /**************************************************************************** Item_copy_string @@ -5123,156 +5159,6 @@ my_decimal *Item_copy_string::val_decimal(my_decimal *decimal_value) } -/**************************************************************************** - Item_copy_int -****************************************************************************/ - -void Item_copy_int::copy() -{ - cached_value= item->val_int(); - null_value=item->null_value; -} - -static int save_int_value_in_field (Field *, longlong, bool, bool); - -int Item_copy_int::save_in_field(Field *field, bool no_conversions) -{ - return save_int_value_in_field(field, cached_value, - null_value, unsigned_flag); -} - - -String *Item_copy_int::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set(cached_value, &my_charset_bin); - return str; -} - - -my_decimal *Item_copy_int::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - - int2my_decimal(E_DEC_FATAL_ERROR, cached_value, unsigned_flag, decimal_value); - return decimal_value; -} - - -/**************************************************************************** - Item_copy_uint -****************************************************************************/ - -String *Item_copy_uint::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set((ulonglong) cached_value, &my_charset_bin); - return str; -} - - -/**************************************************************************** - Item_copy_float -****************************************************************************/ - -String *Item_copy_float::val_str(String *str) -{ - if (null_value) - return (String *) 0; - else - { - double nr= val_real(); - str->set_real(nr,decimals, &my_charset_bin); - return str; - } -} - - -my_decimal *Item_copy_float::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - else - { - double nr= val_real(); - double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value); - return decimal_value; - } -} - - -int Item_copy_float::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store(cached_value); -} - - -/**************************************************************************** - Item_copy_decimal -****************************************************************************/ - -int Item_copy_decimal::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store_decimal(&cached_value); -} - - -String *Item_copy_decimal::val_str(String *result) -{ - if (null_value) - return (String *) 0; - result->set_charset(&my_charset_bin); - my_decimal2string(E_DEC_FATAL_ERROR, &cached_value, 0, 0, 0, result); - return result; -} - - -double Item_copy_decimal::val_real() -{ - if (null_value) - return 0.0; - else - { - double result; - my_decimal2double(E_DEC_FATAL_ERROR, &cached_value, &result); - return result; - } -} - - -longlong Item_copy_decimal::val_int() -{ - if (null_value) - return 0; - else - { - longlong result; - my_decimal2int(E_DEC_FATAL_ERROR, &cached_value, unsigned_flag, &result); - return result; - } -} - - -void Item_copy_decimal::copy() -{ - my_decimal *nr= item->val_decimal(&cached_value); - if (nr && nr != &cached_value) - my_decimal2decimal (nr, &cached_value); - null_value= item->null_value; -} - - /* Functions to convert item to field (for send_result_set_metadata) */ @@ -9744,13 +9630,11 @@ void Item_trigger_field::cleanup() Item_result item_cmp_type(Item_result a,Item_result b) { - if (a == STRING_RESULT && b == STRING_RESULT) - return STRING_RESULT; - if (a == INT_RESULT && b == INT_RESULT) - return INT_RESULT; - else if (a == ROW_RESULT || b == ROW_RESULT) + if (a == b) + return a; + if (a == ROW_RESULT || b == ROW_RESULT) return ROW_RESULT; - else if (a == TIME_RESULT || b == TIME_RESULT) + if (a == TIME_RESULT || b == TIME_RESULT) return TIME_RESULT; if ((a == INT_RESULT || a == DECIMAL_RESULT) && (b == INT_RESULT || b == DECIMAL_RESULT)) @@ -10196,7 +10080,7 @@ longlong Item_cache_real::val_int() DBUG_ASSERT(fixed == 1); if (!has_value()) return 0; - return (longlong) rint(value); + return Converter_double_to_longlong(value, unsigned_flag).result(); } |