diff options
-rw-r--r-- | sql/field.cc | 32 | ||||
-rw-r--r-- | sql/field.h | 32 | ||||
-rw-r--r-- | sql/item.cc | 8 | ||||
-rw-r--r-- | sql/item.h | 44 | ||||
-rw-r--r-- | sql/item_xmlfunc.cc | 2 | ||||
-rw-r--r-- | sql/sp_head.cc | 8 | ||||
-rw-r--r-- | sql/sp_head.h | 2 | ||||
-rw-r--r-- | sql/sp_pcontext.h | 2 | ||||
-rw-r--r-- | sql/sp_rcontext.cc | 23 | ||||
-rw-r--r-- | sql/sql_lex.cc | 27 | ||||
-rw-r--r-- | sql/sql_type.cc | 11 | ||||
-rw-r--r-- | sql/sql_type.h | 12 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
13 files changed, 113 insertions, 92 deletions
diff --git a/sql/field.cc b/sql/field.cc index e7329feecb1..068a7285c8e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2272,6 +2272,16 @@ void Field_null::sql_type(String &res) const /**************************************************************************** + Field_row, e.g. for ROW-type SP variables +****************************************************************************/ + +Field_row::~Field_row() +{ + delete m_table; +} + + +/**************************************************************************** Functions for the Field_decimal class This is an number stored as a pre-space (or pre-zero) string ****************************************************************************/ @@ -10096,6 +10106,21 @@ Field *make_field(TABLE_SHARE *share, uchar *UNINIT_VAR(bit_ptr); uchar UNINIT_VAR(bit_offset); + DBUG_PRINT("debug", ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s", + handler->name().ptr(), field_length, interval, + FLAGSTR(pack_flag, FIELDFLAG_BINARY), + FLAGSTR(pack_flag, FIELDFLAG_INTERVAL), + FLAGSTR(pack_flag, FIELDFLAG_NUMBER), + FLAGSTR(pack_flag, FIELDFLAG_PACK), + FLAGSTR(pack_flag, FIELDFLAG_BLOB))); + + if (handler == &type_handler_row) + { + DBUG_ASSERT(field_length == 0); + DBUG_ASSERT(f_maybe_null(pack_flag)); + return new (mem_root) Field_row(ptr, field_name); + } + if (handler->real_field_type() == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) { bit_ptr= null_pos; @@ -10117,13 +10142,6 @@ Field *make_field(TABLE_SHARE *share, null_bit= ((uchar) 1) << null_bit; } - DBUG_PRINT("debug", ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s", - handler->name().ptr(), field_length, interval, - FLAGSTR(pack_flag, FIELDFLAG_BINARY), - FLAGSTR(pack_flag, FIELDFLAG_INTERVAL), - FLAGSTR(pack_flag, FIELDFLAG_NUMBER), - FLAGSTR(pack_flag, FIELDFLAG_PACK), - FLAGSTR(pack_flag, FIELDFLAG_BLOB))); if (f_is_alpha(pack_flag)) { diff --git a/sql/field.h b/sql/field.h index 5999f3e0a34..3147374d496 100644 --- a/sql/field.h +++ b/sql/field.h @@ -44,6 +44,7 @@ class Column_statistics_collected; class Item_func; class Item_bool_func; class Item_equal; +class Virtual_tmp_table; enum enum_check_fields { @@ -1510,6 +1511,11 @@ public: /* Mark field in read map. Updates also virtual fields */ void register_field_in_read_map(); + virtual Virtual_tmp_table **virtual_tmp_table_addr() + { + return NULL; + } + friend int cre_myisam(char * name, register TABLE *form, uint options, ulonglong auto_increment_value); friend class Copy_field; @@ -3814,6 +3820,19 @@ public: }; +class Field_row: public Field_null +{ + class Virtual_tmp_table *m_table; +public: + Field_row(uchar *ptr_arg, const LEX_CSTRING *field_name_arg) + :Field_null(ptr_arg, 0, Field::NONE, field_name_arg, &my_charset_bin), + m_table(NULL) + {} + ~Field_row(); + Virtual_tmp_table **virtual_tmp_table_addr() { return &m_table; } +}; + + extern const LEX_CSTRING null_clex_str; Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, @@ -4164,9 +4183,7 @@ public: { } const Type_handler *type_handler() const { - return is_row() || is_table_rowtype_ref() || is_cursor_rowtype_ref() ? - &type_handler_row : - Type_handler_hybrid_field_type::type_handler(); + return Type_handler_hybrid_field_type::type_handler(); } bool is_column_type_ref() const { return m_column_type_ref != 0; } bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; } @@ -4186,6 +4203,8 @@ public: } void set_table_rowtype_ref(class Table_ident *ref) { + DBUG_ASSERT(ref); + set_handler(&type_handler_row); m_table_rowtype_ref= ref; } @@ -4193,9 +4212,10 @@ public: { return m_cursor_rowtype_offset; } - void set_cursor_rowtype_ref(bool ref, uint offset) + void set_cursor_rowtype_ref(uint offset) { - m_cursor_rowtype_ref= ref; + set_handler(&type_handler_row); + m_cursor_rowtype_ref= true; m_cursor_rowtype_offset= offset; } @@ -4224,6 +4244,8 @@ public: } void set_row_field_definitions(Row_definition_list *list) { + DBUG_ASSERT(list); + set_handler(&type_handler_row); m_row_field_definitions= list; } diff --git a/sql/item.cc b/sql/item.cc index 72703c2f7b0..999b64fcc1e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1753,17 +1753,15 @@ void Item_sp_variable::make_field(THD *thd, Send_field *field) Item_splocal::Item_splocal(THD *thd, const LEX_CSTRING *sp_var_name, uint sp_var_idx, - enum_field_types sp_var_type, + const Type_handler *handler, uint pos_in_q, uint len_in_q): Item_sp_variable(thd, sp_var_name), Rewritable_query_parameter(pos_in_q, len_in_q), + Type_handler_hybrid_field_type(handler), m_var_idx(sp_var_idx) { maybe_null= TRUE; - - sp_var_type= real_type_to_type(sp_var_type); - m_type= sp_map_item_type(sp_var_type); - set_handler_by_field_type(sp_var_type); + m_type= sp_map_item_type(handler); } diff --git a/sql/item.h b/sql/item.h index f21c88c69a4..d3636ccc263 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2093,17 +2093,6 @@ public: }; -class Item_spvar_args: public Item_args -{ - Virtual_tmp_table *m_table; -public: - Item_spvar_args():Item_args(), m_table(NULL) { } - ~Item_spvar_args(); - bool row_create_items(THD *thd, List<Spvar_definition> *list); - Field *get_row_field(uint i) const; -}; - - /* Class to be used to enumerate all field references in an item tree. This includes references to outside but not fields of the tables within a @@ -2337,7 +2326,7 @@ protected: bool append_value_for_log(THD *thd, String *str); public: Item_splocal(THD *thd, const LEX_CSTRING *sp_var_name, uint sp_var_idx, - enum_field_types sp_var_type, + const Type_handler *handler, uint pos_in_q= 0, uint len_in_q= 0); bool fix_fields(THD *, Item **); @@ -2390,20 +2379,6 @@ public: }; -class Item_splocal_row: public Item_splocal -{ -public: - Item_splocal_row(THD *thd, const LEX_CSTRING *sp_var_name, - uint sp_var_idx, uint pos_in_q, uint len_in_q) - :Item_splocal(thd, sp_var_name, sp_var_idx, MYSQL_TYPE_NULL, - pos_in_q, len_in_q) - { - set_handler(&type_handler_row); - } - enum Type type() const { return ROW_ITEM; } -}; - - /** An Item_splocal variant whose data type becomes known only at sp_rcontext creation time, e.g. "DECLARE var1 t1.col1%TYPE". @@ -2415,7 +2390,7 @@ public: const LEX_CSTRING *sp_var_name, uint sp_var_idx, uint pos_in_q, uint len_in_q) - :Item_splocal(thd, sp_var_name, sp_var_idx, MYSQL_TYPE_NULL, + :Item_splocal(thd, sp_var_name, sp_var_idx, &type_handler_null, pos_in_q, len_in_q) { } }; @@ -2437,9 +2412,9 @@ public: const LEX_CSTRING *sp_var_name, const LEX_CSTRING *sp_field_name, uint sp_var_idx, uint sp_field_idx, - enum_field_types sp_var_type, + const Type_handler *handler, uint pos_in_q= 0, uint len_in_q= 0) - :Item_splocal(thd, sp_var_name, sp_var_idx, sp_var_type, + :Item_splocal(thd, sp_var_name, sp_var_idx, handler, pos_in_q, len_in_q), m_field_name(*sp_field_name), m_field_idx(sp_field_idx) @@ -2461,11 +2436,11 @@ public: const LEX_CSTRING *sp_var_name, const LEX_CSTRING *sp_field_name, uint sp_var_idx, - enum_field_types sp_var_type, + const Type_handler *handler, uint pos_in_q= 0, uint len_in_q= 0) :Item_splocal_row_field(thd, sp_var_name, sp_field_name, sp_var_idx, 0 /* field index will be set later */, - sp_var_type, pos_in_q, len_in_q) + handler, pos_in_q, len_in_q) { } bool fix_fields(THD *thd, Item **it); void print(String *str, enum_query_type query_type); @@ -2930,14 +2905,13 @@ public: Item_field for the ROW data type */ class Item_field_row: public Item_field, - public Item_spvar_args + public Item_args { public: Item_field_row(THD *thd, Field *field) :Item_field(thd, field), - Item_spvar_args() + Item_args() { } - Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_field_row>(thd, mem_root, this); } @@ -2955,6 +2929,8 @@ public: } return false; } + bool row_create_items(THD *thd, List<Spvar_definition> *list); + Field *get_row_field(uint i) const; }; diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 2b3d2374405..8b428a45bee 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2621,7 +2621,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath) (spv= spc->find_variable(&name, false))) { Item_splocal *splocal= new (thd->mem_root) - Item_splocal(thd, &name, spv->offset, spv->sql_type(), 0); + Item_splocal(thd, &name, spv->offset, spv->type_handler(), 0); #ifndef DBUG_OFF if (splocal) splocal->m_sp= lex->sphead; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ed4b76026a0..82123c6ad6e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -70,8 +70,12 @@ static void reset_start_time_for_sp(THD *thd) Item::Type -sp_map_item_type(enum enum_field_types type) +sp_map_item_type(const Type_handler *handler) { + if (handler == &type_handler_row) + return Item::ROW_ITEM; + enum_field_types type= real_type_to_type(handler->real_field_type()); + switch (type) { case MYSQL_TYPE_BIT: case MYSQL_TYPE_TINY: @@ -4757,11 +4761,11 @@ bool sp_head::spvar_fill_row(THD *thd, sp_variable *spvar, Row_definition_list *defs) { + spvar->field_def.set_row_field_definitions(defs); spvar->field_def.field_name= spvar->name; if (fill_spvar_definition(thd, &spvar->field_def)) return true; row_fill_field_definitions(thd, defs); - spvar->field_def.set_row_field_definitions(defs); return false; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 272bc5d445c..ac0f406f854 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -41,7 +41,7 @@ */ Item::Type -sp_map_item_type(enum enum_field_types type); +sp_map_item_type(const Type_handler *handler); uint sp_get_flags_for_command(LEX *lex); diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 9c879099410..990ad35cb57 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -60,8 +60,6 @@ public: Spvar_definition field_def; /// Field-type of the SP-variable. - enum_field_types sql_type() const { return field_def.real_field_type(); } - const Type_handler *type_handler() const { return field_def.type_handler(); } public: diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 8a86d522e1e..ee13eac6a1c 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -358,10 +358,13 @@ bool sp_rcontext::init_var_items(THD *thd, } -bool Item_spvar_args::row_create_items(THD *thd, List<Spvar_definition> *list) +bool Item_field_row::row_create_items(THD *thd, List<Spvar_definition> *list) { DBUG_ASSERT(list); - if (!(m_table= create_virtual_tmp_table(thd, *list))) + DBUG_ASSERT(field); + Virtual_tmp_table **ptable= field->virtual_tmp_table_addr(); + DBUG_ASSERT(ptable); + if (!(ptable[0]= create_virtual_tmp_table(thd, *list))) return true; if (alloc_arguments(thd, list->elements)) @@ -372,23 +375,19 @@ bool Item_spvar_args::row_create_items(THD *thd, List<Spvar_definition> *list) for (arg_count= 0; (def= it++); arg_count++) { if (!(args[arg_count]= new (thd->mem_root) - Item_field(thd, m_table->field[arg_count]))) + Item_field(thd, ptable[0]->field[arg_count]))) return true; } return false; } -Field *Item_spvar_args::get_row_field(uint i) const +Field *Item_field_row::get_row_field(uint i) const { - DBUG_ASSERT(m_table); - return m_table->field[i]; -} - - -Item_spvar_args::~Item_spvar_args() -{ - delete m_table; + DBUG_ASSERT(field); + Virtual_tmp_table **ptable= field->virtual_tmp_table_addr(); + DBUG_ASSERT(ptable); + return ptable[0]->field[i]; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 938b386a816..831b4ee4ca7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -5294,7 +5294,11 @@ LEX::sp_variable_declarations_copy_type_finalize(THD *thd, int nvars, { sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i); spvar->field_def.set_type(ref); - spvar->field_def.set_row_field_definitions(fields); + if (fields) + { + DBUG_ASSERT(ref.type_handler() == &type_handler_row); + spvar->field_def.set_row_field_definitions(fields); + } spvar->field_def.field_name= spvar->name; } if (sp_variable_declarations_set_default(thd, nvars, default_value)) @@ -5340,9 +5344,9 @@ bool LEX::sp_variable_declarations_row_finalize(THD *thd, int nvars, for (uint i= 0 ; i < (uint) nvars ; i++) { sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i); + spvar->field_def.set_row_field_definitions(row); if (sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name)) return true; - spvar->field_def.set_row_field_definitions(row); } if (sp_variable_declarations_set_default(thd, nvars, dflt_value_item)) @@ -5428,7 +5432,7 @@ LEX::sp_variable_declarations_cursor_rowtype_finalize(THD *thd, int nvars, { sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i); - spvar->field_def.set_cursor_rowtype_ref(true, offset); + spvar->field_def.set_cursor_rowtype_ref(offset); sp_instr_cursor_copy_struct *instr= new (thd->mem_root) sp_instr_cursor_copy_struct(sphead->instructions(), spcont, pcursor->lex(), @@ -5592,7 +5596,7 @@ LEX::sp_add_for_loop_cursor_variable(THD *thd, if (!(spvar->default_value= new (thd->mem_root) Item_null(thd))) return NULL; - spvar->field_def.set_cursor_rowtype_ref(true, coffset); + spvar->field_def.set_cursor_rowtype_ref(coffset); if (sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, coffset, param_lex, parameters)) @@ -5616,7 +5620,7 @@ bool LEX::sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop) { sp_variable *src= i == 0 ? loop.m_index : loop.m_upper_bound; args[i]= new (thd->mem_root) - Item_splocal(thd, &src->name, src->offset, src->sql_type()); + Item_splocal(thd, &src->name, src->offset, src->type_handler()); if (args[i] == NULL) return true; #ifndef DBUG_OFF @@ -5750,7 +5754,7 @@ bool LEX::sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop) { Item_splocal *splocal= new (thd->mem_root) Item_splocal(thd, &loop.m_index->name, loop.m_index->offset, - loop.m_index->sql_type()); + loop.m_index->type_handler()); if (splocal == NULL) return true; #ifndef DBUG_OFF @@ -6521,7 +6525,7 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd, { if (!(item= new (thd->mem_root) Item_splocal_row_field_by_name(thd, a, b, spv->offset, - MYSQL_TYPE_NULL, + &type_handler_null, pos.pos(), pos.length()))) return NULL; } @@ -6535,7 +6539,7 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd, if (!(item= new (thd->mem_root) Item_splocal_row_field(thd, a, b, spv->offset, row_field_offset, - def->real_field_type(), + def->type_handler(), pos.pos(), pos.length()))) return NULL; } @@ -6704,7 +6708,7 @@ Item *LEX::create_item_limit(THD *thd, Query_fragment pos(thd, sphead, start, end); Item_splocal *item; if (!(item= new (thd->mem_root) Item_splocal(thd, a, - spv->offset, spv->sql_type(), + spv->offset, spv->type_handler(), pos.pos(), pos.length()))) return NULL; #ifndef DBUG_OFF @@ -6823,11 +6827,8 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name, spv->offset, pos.pos(), pos.length()) : - spv->field_def.is_row() || spv->field_def.is_table_rowtype_ref() ? - new (thd->mem_root) Item_splocal_row(thd, name, spv->offset, - pos.pos(), pos.length()) : new (thd->mem_root) Item_splocal(thd, name, - spv->offset, spv->sql_type(), + spv->offset, spv->type_handler(), pos.pos(), pos.length()); if (splocal == NULL) return NULL; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 737d01f7b89..d6b861eaaf2 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1589,6 +1589,17 @@ bool Type_handler_null:: return false; } +bool Type_handler_row:: + Column_definition_prepare_stage1(THD *thd, + MEM_ROOT *mem_root, + Column_definition *def, + handler *file, + ulonglong table_flags) const +{ + def->create_length_to_internal_length_null(); + return false; +} + bool Type_handler_newdecimal:: Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, diff --git a/sql/sql_type.h b/sql/sql_type.h index 910172134fd..c2e2127994a 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1046,18 +1046,13 @@ public: } bool Column_definition_fix_attributes(Column_definition *c) const { - DBUG_ASSERT(0); - return true; + return false; } bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, Column_definition *c, handler *file, - ulonglong table_flags) const - { - DBUG_ASSERT(0); - return true; - } + ulonglong table_flags) const; bool Column_definition_redefine_stage1(Column_definition *def, const Column_definition *dup, const handler *file, @@ -1071,8 +1066,7 @@ public: handler *file, ulonglong table_flags) const { - DBUG_ASSERT(0); - return true; + return false; } Field *make_table_field(const LEX_CSTRING *name, const Record_addr &addr, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0a62361e222..8c6c6bb58e8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -396,7 +396,7 @@ LEX::create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, len_in_q= (uint)(end_in_q - start_in_q); item= new (thd->mem_root) - Item_splocal(thd, name, spvar->offset, spvar->sql_type(), + Item_splocal(thd, name, spvar->offset, spvar->type_handler(), pos_in_q, len_in_q); #ifndef DBUG_OFF |