Skip to content

Commit

Permalink
MDEV-34317: Implement RECORD type
Browse files Browse the repository at this point in the history
Implement `DECLARE TYPE type_name IS RECORD (..)` with scalar members in
 stored routines and anonymous blocks
  • Loading branch information
iqbal-hasprime committed Sep 13, 2024
1 parent fe3432b commit 84cbea9
Show file tree
Hide file tree
Showing 12 changed files with 1,632 additions and 11 deletions.
639 changes: 639 additions & 0 deletions mysql-test/suite/compat/oracle/r/sp-record.result

Large diffs are not rendered by default.

705 changes: 705 additions & 0 deletions mysql-test/suite/compat/oracle/t/sp-record.test

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions sql/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ SYMBOL symbols[] = {
{ "READS", SYM(READS_SYM)},
{ "REAL", SYM(REAL)},
{ "REBUILD", SYM(REBUILD_SYM)},
{ "RECORD", SYM(RECORD_SYM)},
{ "RECOVER", SYM(RECOVER_SYM)},
{ "RECURSIVE", SYM(RECURSIVE_SYM)},
{ "REDO_BUFFER_SIZE", SYM(REDO_BUFFER_SIZE_SYM)},
Expand Down
5 changes: 2 additions & 3 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12148,9 +12148,8 @@ ER_UNKNOWN_OPERATOR
eng "Operator does not exist: '%-.128s'"
spa "El operador no existe: '%-.128s'"
sw "Opereta haipo: '% -.128s'"
ER_UNUSED_29
eng "You should never see it"
sw "Hupaswi kuiona kamwe"
ER_SP_DUP_DECL
eng "Duplicate declaration: '%-.64s'"
ER_PART_STARTS_BEYOND_INTERVAL
eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value"
spa "%`s: STARTS es posterior al momento de consulta (query), la primera partición de historia puede exceder el valor INTERVAL"
Expand Down
32 changes: 32 additions & 0 deletions sql/sp_head.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3928,6 +3928,38 @@ bool sp_head::spvar_fill_type_reference(THD *thd,
}


bool sp_head::spvar_def_fill_type_reference(THD *thd, Spvar_definition *def,
const LEX_CSTRING &table,
const LEX_CSTRING &column)
{
Qualified_column_ident *ref;
if (!(ref= new (thd->mem_root) Qualified_column_ident(&table, &column)))
return true;

def->set_column_type_ref(ref);
m_flags|= sp_head::HAS_COLUMN_TYPE_REFS;

return false;
}


bool sp_head::spvar_def_fill_type_reference(THD *thd, Spvar_definition *def,
const LEX_CSTRING &db,
const LEX_CSTRING &table,
const LEX_CSTRING &column)
{
Qualified_column_ident *ref;
if (!(ref= new (thd->mem_root) Qualified_column_ident(thd, &db, &table,
&column)))
return true;

def->set_column_type_ref(ref);
m_flags|= sp_head::HAS_COLUMN_TYPE_REFS;

return false;
}


bool sp_head::spvar_fill_table_rowtype_reference(THD *thd,
sp_variable *spvar,
const LEX_CSTRING &table)
Expand Down
8 changes: 8 additions & 0 deletions sql/sp_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,14 @@ class sp_head :private Query_arena,
const LEX_CSTRING &db,
const LEX_CSTRING &table);

bool spvar_def_fill_type_reference(THD *thd, Spvar_definition *def,
const LEX_CSTRING &table,
const LEX_CSTRING &column);
bool spvar_def_fill_type_reference(THD *thd, Spvar_definition *def,
const LEX_CSTRING &db,
const LEX_CSTRING &table,
const LEX_CSTRING &column);

void set_c_chistics(const st_sp_chistics &chistics);
void set_info(longlong created, longlong modified,
const st_sp_chistics &chistics, sql_mode_t sql_mode);
Expand Down
42 changes: 38 additions & 4 deletions sql/sp_pcontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ sp_pcontext::sp_pcontext()
m_parent(NULL), m_pboundary(0),
m_vars(PSI_INSTRUMENT_MEM), m_case_expr_ids(PSI_INSTRUMENT_MEM),
m_conditions(PSI_INSTRUMENT_MEM), m_cursors(PSI_INSTRUMENT_MEM),
m_handlers(PSI_INSTRUMENT_MEM), m_children(PSI_INSTRUMENT_MEM),
m_scope(REGULAR_SCOPE)
m_handlers(PSI_INSTRUMENT_MEM), m_records(PSI_INSTRUMENT_MEM),
m_children(PSI_INSTRUMENT_MEM), m_scope(REGULAR_SCOPE)
{
init(0, 0, 0);
}
Expand All @@ -111,8 +111,8 @@ sp_pcontext::sp_pcontext(sp_pcontext *prev, sp_pcontext::enum_scope scope)
m_parent(prev), m_pboundary(0),
m_vars(PSI_INSTRUMENT_MEM), m_case_expr_ids(PSI_INSTRUMENT_MEM),
m_conditions(PSI_INSTRUMENT_MEM), m_cursors(PSI_INSTRUMENT_MEM),
m_handlers(PSI_INSTRUMENT_MEM), m_children(PSI_INSTRUMENT_MEM),
m_scope(scope)
m_handlers(PSI_INSTRUMENT_MEM), m_records(PSI_INSTRUMENT_MEM),
m_children(PSI_INSTRUMENT_MEM), m_scope(scope)
{
init(prev->m_var_offset + prev->m_max_var_index,
prev->current_cursor_count(),
Expand Down Expand Up @@ -413,6 +413,40 @@ sp_condition_value *sp_pcontext::find_condition(const LEX_CSTRING *name,
NULL;
}


bool sp_pcontext::add_record(THD *thd, const Lex_ident_column &name,
Row_definition_list *field)
{
sp_record *p= new (thd->mem_root) sp_record(name, field);

if (p == NULL)
return true;

return m_records.append(p);
}


sp_record *sp_pcontext::find_record(const LEX_CSTRING *name,
bool current_scope_only) const
{
size_t i= m_records.elements();

while (i--)
{
sp_record *p= m_records.at(i);

if (p->eq_name(name))
{
return p;
}
}

return (!current_scope_only && m_parent) ?
m_parent->find_record(name, false) :
NULL;
}


sp_condition_value *
sp_pcontext::find_declared_or_predefined_condition(THD *thd,
const LEX_CSTRING *name)
Expand Down
51 changes: 51 additions & 0 deletions sql/sp_pcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,31 @@ class sp_handler : public Sql_alloc
{ }
};


///////////////////////////////////////////////////////////////////////////

/// This class represents 'DECLARE RECORD' statement.

class sp_record : public Sql_alloc
{
public:
/// Name of the record.
Lex_ident_column name;
Row_definition_list *field;

public:
sp_record(const Lex_ident_column &name_arg, Row_definition_list *prmfield)
:Sql_alloc(),
name(name_arg),
field(prmfield)
{ }
bool eq_name(const LEX_CSTRING *str) const
{
return name.streq(*str);
}
};


///////////////////////////////////////////////////////////////////////////

/// The class represents parse-time context, which keeps track of declared
Expand Down Expand Up @@ -700,6 +725,29 @@ class sp_pcontext : public Sql_alloc
return m_for_loop;
}

/////////////////////////////////////////////////////////////////////////
// Record.
/////////////////////////////////////////////////////////////////////////

bool add_record(THD *thd,
const Lex_ident_column &name,
Row_definition_list *field);

sp_record *find_record(const LEX_CSTRING *name,
bool current_scope_only) const;

bool declare_record(THD *thd,
const Lex_ident_column &name,
Row_definition_list *field)
{
if (find_record(&name, true))
{
my_error(ER_SP_DUP_DECL, MYF(0), name.str);
return true;
}
return add_record(thd, name, field);
}

private:
/// Constructor for a tree node.
/// @param prev the parent parsing context
Expand Down Expand Up @@ -764,6 +812,9 @@ class sp_pcontext : public Sql_alloc
/// Stack of SQL-handlers.
Dynamic_array<sp_handler *> m_handlers;

/// Stack of records.
Dynamic_array<sp_record *> m_records;

/*
In the below example the label <<lab>> has two meanings:
- GOTO lab : must go before the beginning of the loop
Expand Down
7 changes: 6 additions & 1 deletion sql/sp_rcontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,12 @@ bool Row_definition_list::resolve_type_refs(THD *thd)
Spvar_definition *def;
while ((def= it++))
{
if (def->is_column_type_ref() &&
if (def->is_row())
{
if (def->row_field_definitions()->resolve_type_refs(thd))
return true;
}
else if (def->is_column_type_ref() &&
def->column_type_ref()->resolve_type_ref(thd, def))
return true;
}
Expand Down
39 changes: 39 additions & 0 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6678,6 +6678,17 @@ bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
const LEX_CSTRING &expr_str)
{
DBUG_ASSERT(cdef);

if (cdef->type_handler() == &type_handler_row)
{
if (sp_record *sprec=
(sp_record *)cdef->get_attr_const_void_ptr(0)) {
return sp_variable_declarations_rec_finalize(thd, nvars,
sprec->field,
dflt_value_item, expr_str);
}
}

Column_definition tmp(*cdef);
if (sphead->fill_spvar_definition(thd, &tmp))
return true;
Expand All @@ -6686,6 +6697,34 @@ bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
}


bool LEX::sp_variable_declarations_rec_finalize(THD *thd, int nvars,
Row_definition_list *src_row,
Item *dflt_value_item,
const LEX_CSTRING &expr_str)
{
DBUG_ASSERT(src_row);

// Create a copy of the row definition list to fill
// definitions
Row_definition_list *row= new (thd->mem_root) Row_definition_list();
if (unlikely(row == NULL))
return true;

// Create a deep copy of the elements
List_iterator<Spvar_definition> it(*src_row);
for (Spvar_definition *def= it++; def; def= it++)
{
Spvar_definition *new_def= new (thd->mem_root) Spvar_definition(*def);
if (unlikely(new_def == NULL))
return true;

row->push_back(new_def, thd->mem_root);
}

return sp_variable_declarations_row_finalize(thd, nvars, row,
dflt_value_item, expr_str);
}

bool LEX::sp_variable_declarations_row_finalize(THD *thd, int nvars,
Row_definition_list *row,
Item *dflt_value_item,
Expand Down
4 changes: 4 additions & 0 deletions sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -3859,6 +3859,10 @@ struct LEX: public Query_tables_list
const LEX_CSTRING &expr_str);
bool sp_variable_declarations_set_default(THD *thd, int nvars, Item *def,
const LEX_CSTRING &expr_str);
bool sp_variable_declarations_rec_finalize(THD *thd, int nvars,
Row_definition_list *src_row,
Item *def,
const LEX_CSTRING &expr_str);
bool sp_variable_declarations_row_finalize(THD *thd, int nvars,
Row_definition_list *row,
Item *def,
Expand Down
Loading

0 comments on commit 84cbea9

Please sign in to comment.