mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
A cleanup patch for MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations
Addressing Monty's review suggestions
This commit is contained in:
24
sql/field.h
24
sql/field.h
@@ -3987,16 +3987,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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
|
|||||||
{
|
{
|
||||||
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 @@ public:
|
|||||||
}
|
}
|
||||||
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 @@ public:
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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))
|
||||||
|
Reference in New Issue
Block a user