Commit ce4b291b authored by Alexander Barkov's avatar Alexander Barkov

A cleanup patch for MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations

Addressing Monty's review suggestions
parent 48a7ea6d
...@@ -3987,16 +3987,6 @@ class Row_definition_list: public List<class Spvar_definition> ...@@ -3987,16 +3987,6 @@ class Row_definition_list: public List<class Spvar_definition>
}; };
class Cursor_rowtype: public Sql_alloc
{
public:
uint m_cursor;
Cursor_rowtype(uint cursor)
:m_cursor(cursor)
{ }
};
/** /**
This class is used during a stored routine or a trigger execution, This class is used during a stored routine or a trigger execution,
at sp_rcontext::create() time. at sp_rcontext::create() time.
...@@ -4020,20 +4010,20 @@ class Spvar_definition: public Column_definition ...@@ -4020,20 +4010,20 @@ class Spvar_definition: public Column_definition
{ {
class Qualified_column_ident *m_column_type_ref; // for %TYPE class Qualified_column_ident *m_column_type_ref; // for %TYPE
class Table_ident *m_table_rowtype_ref; // for table%ROWTYPE class Table_ident *m_table_rowtype_ref; // for table%ROWTYPE
class Cursor_rowtype *m_cursor_rowtype_ref; // for cursor%ROWTYPE bool m_cursor_rowtype_ref; // for cursor%ROWTYPE
Row_definition_list *m_row_field_definitions; // for ROW Row_definition_list *m_row_field_definitions; // for ROW
public: public:
Spvar_definition() Spvar_definition()
:m_column_type_ref(NULL), :m_column_type_ref(NULL),
m_table_rowtype_ref(NULL), m_table_rowtype_ref(NULL),
m_cursor_rowtype_ref(NULL), m_cursor_rowtype_ref(false),
m_row_field_definitions(NULL) m_row_field_definitions(NULL)
{ } { }
Spvar_definition(THD *thd, Field *field) Spvar_definition(THD *thd, Field *field)
:Column_definition(thd, field, NULL), :Column_definition(thd, field, NULL),
m_column_type_ref(NULL), m_column_type_ref(NULL),
m_table_rowtype_ref(NULL), m_table_rowtype_ref(NULL),
m_cursor_rowtype_ref(NULL), m_cursor_rowtype_ref(false),
m_row_field_definitions(NULL) m_row_field_definitions(NULL)
{ } { }
const Type_handler *type_handler() const const Type_handler *type_handler() const
...@@ -4044,7 +4034,7 @@ class Spvar_definition: public Column_definition ...@@ -4044,7 +4034,7 @@ class Spvar_definition: public Column_definition
} }
bool is_column_type_ref() const { return m_column_type_ref != 0; } bool is_column_type_ref() const { return m_column_type_ref != 0; }
bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; } bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; }
bool is_cursor_rowtype_ref() const { return m_cursor_rowtype_ref != NULL; } bool is_cursor_rowtype_ref() const { return m_cursor_rowtype_ref; }
class Qualified_column_ident *column_type_ref() const class Qualified_column_ident *column_type_ref() const
{ {
return m_column_type_ref; return m_column_type_ref;
...@@ -4062,11 +4052,7 @@ class Spvar_definition: public Column_definition ...@@ -4062,11 +4052,7 @@ class Spvar_definition: public Column_definition
{ {
m_table_rowtype_ref= ref; m_table_rowtype_ref= ref;
} }
class Cursor_rowtype *cursor_rowtype_ref() const void set_cursor_rowtype_ref(bool ref)
{
return m_cursor_rowtype_ref;
}
void set_cursor_rowtype_ref(class Cursor_rowtype *ref)
{ {
m_cursor_rowtype_ref= ref; m_cursor_rowtype_ref= ref;
} }
......
...@@ -3183,8 +3183,7 @@ int sp_lex_keeper::cursor_reset_lex_and_exec_core(THD *thd, uint *nextp, ...@@ -3183,8 +3183,7 @@ int sp_lex_keeper::cursor_reset_lex_and_exec_core(THD *thd, uint *nextp,
*/ */
thd->stmt_arena= m_lex->query_arena(); thd->stmt_arena= m_lex->query_arena();
int res= reset_lex_and_exec_core(thd, nextp, open_tables, instr); int res= reset_lex_and_exec_core(thd, nextp, open_tables, instr);
if (thd->stmt_arena->free_list) cleanup_items(thd->stmt_arena->free_list);
cleanup_items(thd->stmt_arena->free_list);
thd->stmt_arena= old_arena; thd->stmt_arena= old_arena;
return res; return res;
} }
...@@ -4170,10 +4169,18 @@ sp_instr_cfetch::print(String *str) ...@@ -4170,10 +4169,18 @@ sp_instr_cfetch::print(String *str)
sp_instr_cursor_copy_struct class functions sp_instr_cursor_copy_struct class functions
*/ */
/**
This methods processes cursor %ROWTYPE declarations, e.g.:
CURSOR cur IS SELECT * FROM t1;
rec cur%ROWTYPE;
and does the following:
- opens the cursor without copying data (materialization).
- copies the cursor structure to the associated %ROWTYPE variable.
*/
int int
sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
{ {
DBUG_ENTER("sp_instr_cusrot_copy_struct::exec_core"); DBUG_ENTER("sp_instr_cursor_copy_struct::exec_core");
int ret= 0; int ret= 0;
Item_field_row *row= (Item_field_row*) thd->spcont->get_item(m_var); Item_field_row *row= (Item_field_row*) thd->spcont->get_item(m_var);
DBUG_ASSERT(row->type_handler() == &type_handler_row); DBUG_ASSERT(row->type_handler() == &type_handler_row);
...@@ -4188,6 +4195,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) ...@@ -4188,6 +4195,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
if (!row->arguments()) if (!row->arguments())
{ {
sp_cursor tmp(thd, &m_lex_keeper); sp_cursor tmp(thd, &m_lex_keeper);
// Open the cursor without copying data
if (!(ret= tmp.open_view_structure_only(thd))) if (!(ret= tmp.open_view_structure_only(thd)))
{ {
Row_definition_list defs; Row_definition_list defs;
......
...@@ -743,11 +743,17 @@ int sp_cursor::open(THD *thd) ...@@ -743,11 +743,17 @@ int sp_cursor::open(THD *thd)
} }
/**
Open the cursor, but do not copy data.
This method is used to fetch the cursor structure
to cursor%ROWTYPE routine variables.
Data copying is suppressed by setting thd->lex->limit_rows_examined to 0.
*/
int sp_cursor::open_view_structure_only(THD *thd) int sp_cursor::open_view_structure_only(THD *thd)
{ {
int res; int res;
int thd_no_errors_save= thd->no_errors; int thd_no_errors_save= thd->no_errors;
Item *limit_rows_examined= thd->lex->limit_rows_examined; Item *limit_rows_examined= thd->lex->limit_rows_examined; // No data copying
if (!(thd->lex->limit_rows_examined= new (thd->mem_root) Item_uint(thd, 0))) if (!(thd->lex->limit_rows_examined= new (thd->mem_root) Item_uint(thd, 0)))
return -1; return -1;
thd->no_errors= true; // Suppress ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT thd->no_errors= true; // Suppress ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
......
...@@ -5303,10 +5303,7 @@ LEX::sp_variable_declarations_rowtype_finalize(THD *thd, int nvars, ...@@ -5303,10 +5303,7 @@ LEX::sp_variable_declarations_rowtype_finalize(THD *thd, int nvars,
if (pcursor) if (pcursor)
{ {
Cursor_rowtype *ref; spvar->field_def.set_cursor_rowtype_ref(true);
if (!(ref= new (thd->mem_root) Cursor_rowtype(coffp)))
return true;
spvar->field_def.set_cursor_rowtype_ref(ref);
sp_instr_cursor_copy_struct *instr= sp_instr_cursor_copy_struct *instr=
new (thd->mem_root) sp_instr_cursor_copy_struct(sphead->instructions(), new (thd->mem_root) sp_instr_cursor_copy_struct(sphead->instructions(),
spcont, pcursor->lex(), spcont, pcursor->lex(),
...@@ -5435,10 +5432,7 @@ LEX::sp_add_for_loop_cursor_variable(THD *thd, ...@@ -5435,10 +5432,7 @@ LEX::sp_add_for_loop_cursor_variable(THD *thd,
sphead->fill_spvar_definition(thd, &spvar->field_def, spvar->name.str); sphead->fill_spvar_definition(thd, &spvar->field_def, spvar->name.str);
spvar->default_value= new (thd->mem_root) Item_null(thd); spvar->default_value= new (thd->mem_root) Item_null(thd);
Cursor_rowtype *ref; spvar->field_def.set_cursor_rowtype_ref(true);
if (!(ref= new (thd->mem_root) Cursor_rowtype(coffset)))
return NULL;
spvar->field_def.set_cursor_rowtype_ref(ref);
if (sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, coffset, if (sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, coffset,
param_lex, parameters)) param_lex, parameters))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment