Skip to content
Permalink
Browse files
MDEV-14212 Add Field_row for SP ROW variables
  • Loading branch information
abarkov committed Oct 30, 2017
1 parent 5dd5253 commit 667e4b9
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 92 deletions.
@@ -2271,6 +2271,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))
{
@@ -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 @@ class Field: public Value_source
/* 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 @@ class Field_bit_as_char: public Field_bit {
};


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 @@ class Spvar_definition: public Column_definition
{ }
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,16 +4203,19 @@ class Spvar_definition: public Column_definition
}
void set_table_rowtype_ref(class Table_ident *ref)
{
DBUG_ASSERT(ref);
set_handler(&type_handler_row);
m_table_rowtype_ref= ref;
}

uint cursor_rowtype_offset() const
{
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 @@ class Spvar_definition: public Column_definition
}
void set_row_field_definitions(Row_definition_list *list)
{
DBUG_ASSERT(list);
set_handler(&type_handler_row);
m_row_field_definitions= list;
}

@@ -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);
}


@@ -2093,17 +2093,6 @@ class Item_args
};


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 @@ class Item_splocal :public Item_sp_variable,
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 @@ class Item_splocal :public Item_sp_variable,
};


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 @@ class Item_splocal_with_delayed_data_type: public Item_splocal
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 @@ class Item_splocal_row_field :public Item_splocal
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 @@ class Item_splocal_row_field_by_name :public Item_splocal_row_field
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 @@ class Item_field :public Item_ident
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 @@ class Item_field_row: public Item_field,
}
return false;
}
bool row_create_items(THD *thd, List<Spvar_definition> *list);
Field *get_row_field(uint i) const;
};


@@ -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;
@@ -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;
}

@@ -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);
@@ -60,8 +60,6 @@ class sp_variable : public Sql_alloc
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:
@@ -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];
}


0 comments on commit 667e4b9

Please sign in to comment.