summaryrefslogtreecommitdiff
path: root/sql/sql_cursor.cc
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2010-07-27 16:42:36 +0400
committerKonstantin Osipov <kostja@sun.com>2010-07-27 16:42:36 +0400
commit740c0d3a87c07dd5f482db5705449143993e7385 (patch)
treed2ba1f5d61c494084a89dffb85b4cb0b3afd9beb /sql/sql_cursor.cc
parent36290c092392c460132f3d7256aeeb8f94debe8f (diff)
downloadmariadb-git-740c0d3a87c07dd5f482db5705449143993e7385.tar.gz
Implement WL#5502 Remove dead 5.0 class Sensitive_cursor.
Remove dead and unused code. Update to reflect the code review requests. include/thr_lock.h: Remove declarations for THR_LOCK_OWNER, added along with the patch for sensitive cursors. mysys/thr_lock.c: Remove support for multiple thr_lock requestors per THD. sql/lock.cc: Revert the patch that added support for sensitive cursors. sql/sp_rcontext.cc: Updated the use of mysql_open_cursor(). sql/sql_class.cc: Move the instance of Server_side_cursor from class Prepared_statement to class Statement. sql/sql_class.h: Move the isntance of Server_side_cursor from class Prepared_statement to class Statement. Remove multiple lock_ids of thr_lock. sql/sql_cursor.cc: Remove Sensitive_cursor implementation. sql/sql_cursor.h: Remove declarations for sensitive cursors. sql/sql_prepare.cc: Move the declaration of instance of Server_side_cursor from class Statement to class Prepared_statement, where it's used. sql/sql_select.cc: Remove sensitive cursor support. sql/sql_select.h: Remove sensitive cursor support. sql/sql_union.cc: Remove sensitive cursor support.
Diffstat (limited to 'sql/sql_cursor.cc')
-rw-r--r--sql/sql_cursor.cc380
1 files changed, 10 insertions, 370 deletions
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 28d2bd8b4de..9a3eb6ff526 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -19,61 +19,14 @@
#include "sql_priv.h"
#include "unireg.h"
#include "sql_cursor.h"
-#include "sql_select.h"
#include "probes_mysql.h"
#include "sql_parse.h" // mysql_execute_command
-#include "sql_base.h"
/****************************************************************************
Declarations.
****************************************************************************/
/**
- Sensitive_cursor -- a sensitive non-materialized server side
- cursor. An instance of this class cursor has its own runtime
- state -- list of used items and memory root for runtime memory,
- open and locked tables, change list for the changes of the
- parsed tree. This state is freed when the cursor is closed.
-*/
-
-class Sensitive_cursor: public Server_side_cursor
-{
- MEM_ROOT main_mem_root;
- Query_arena *stmt_arena;
- JOIN *join;
- TABLE *open_tables;
- MYSQL_LOCK *lock;
- TABLE *derived_tables;
- /* List of items created during execution */
- query_id_t query_id;
- struct Engine_info
- {
- handlerton *ht;
- void *read_view;
- };
- Engine_info ht_info[MAX_HA];
- Item_change_list change_list;
- my_bool close_at_commit;
- THR_LOCK_OWNER lock_id;
-private:
- /* bzero cursor state in THD */
- void reset_thd(THD *thd);
-public:
- Sensitive_cursor(THD *thd, select_result *result_arg);
-
- THR_LOCK_OWNER *get_lock_id() { return &lock_id; }
- /* Save THD state into cursor */
- void post_open(THD *thd);
-
- virtual bool is_open() const { return join != 0; }
- virtual int open(JOIN *join);
- virtual void fetch(ulong num_rows);
- virtual void close();
- virtual ~Sensitive_cursor();
-};
-
-
-/**
Materialized_cursor -- an insensitive materialized server-side
cursor. The result set of this cursor is saved in a temporary
table at open. The cursor itself is simply an interface for the
@@ -125,10 +78,9 @@ public:
/**************************************************************************/
/**
- Attempt to open a materialized or non-materialized cursor.
+ Attempt to open a materialized cursor.
@param thd thread handle
- @param[in] flags create a materialized cursor or not
@param[in] result result class of the caller used as a destination
for the rows fetched from the cursor
@param[out] pcursor a pointer to store a pointer to cursor in
@@ -141,37 +93,21 @@ public:
non-zero an error, 'pcursor' has been left intact.
*/
-int mysql_open_cursor(THD *thd, uint flags, select_result *result,
+int mysql_open_cursor(THD *thd, select_result *result,
Server_side_cursor **pcursor)
{
- Sensitive_cursor *sensitive_cursor;
select_result *save_result;
Select_materialize *result_materialize;
LEX *lex= thd->lex;
int rc;
- /*
- The lifetime of the sensitive cursor is the same or less as the
- lifetime of the runtime memory of the statement it's opened for.
- */
if (! (result_materialize= new (thd->mem_root) Select_materialize(result)))
return 1;
- if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
- {
- delete result_materialize;
- result_materialize= NULL;
- return 1;
- }
-
save_result= lex->result;
lex->result= result_materialize;
- if (! (flags & (uint) ALWAYS_MATERIALIZED_CURSOR))
- {
- thd->lock_id= sensitive_cursor->get_lock_id();
- thd->cursor= sensitive_cursor;
- }
+
MYSQL_QUERY_EXEC_START(thd->query(),
thd->thread_id,
(char *) (thd->db ? thd->db : ""),
@@ -182,20 +118,14 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
MYSQL_QUERY_EXEC_DONE(rc);
lex->result= save_result;
- thd->lock_id= &thd->main_lock_id;
- thd->cursor= 0;
-
/*
Possible options here:
- - a sensitive cursor is open. In this case rc is 0 and
- result_materialize->materialized_cursor is NULL, or
- a materialized cursor is open. In this case rc is 0 and
result_materialize->materialized is not NULL
- an error occurred during materialization.
result_materialize->materialized_cursor is not NULL, but rc != 0
- successful completion of mysql_execute_command without
- a cursor: rc is 0, result_materialize->materialized_cursor is NULL,
- sensitive_cursor is not open.
+ a cursor: rc is 0, result_materialize->materialized_cursor is NULL.
This is possible if some command writes directly to the
network, bypassing select_result mechanism. An example of
such command is SHOW VARIABLES or SHOW STATUS.
@@ -204,23 +134,10 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
{
if (result_materialize->materialized_cursor)
delete result_materialize->materialized_cursor;
- goto err_open;
- }
-
- if (sensitive_cursor->is_open())
- {
- DBUG_ASSERT(!result_materialize->materialized_cursor);
- /*
- It's safer if we grab THD state after mysql_execute_command
- is finished and not in Sensitive_cursor::open(), because
- currently the call to Sensitive_cursor::open is buried deep
- in JOIN::exec of the top level join.
- */
- sensitive_cursor->post_open(thd);
- *pcursor= sensitive_cursor;
goto end;
}
- else if (result_materialize->materialized_cursor)
+
+ if (result_materialize->materialized_cursor)
{
Materialized_cursor *materialized_cursor=
result_materialize->materialized_cursor;
@@ -228,18 +145,13 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if ((rc= materialized_cursor->open(0)))
{
delete materialized_cursor;
- materialized_cursor= NULL;
- goto err_open;
+ goto end;
}
*pcursor= materialized_cursor;
thd->stmt_arena->cleanup_stmt();
- goto end;
}
-err_open:
- DBUG_ASSERT(! (sensitive_cursor && sensitive_cursor->is_open()));
- delete sensitive_cursor;
end:
delete result_materialize;
return rc;
@@ -271,280 +183,6 @@ void Server_side_cursor::operator delete(void *ptr, size_t size)
DBUG_VOID_RETURN;
}
-/****************************************************************************
- Sensitive_cursor
-****************************************************************************/
-
-Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
- :Server_side_cursor(&main_mem_root, result_arg),
- stmt_arena(0),
- join(0),
- close_at_commit(FALSE)
-{
- /* We will overwrite it at open anyway. */
- init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
- thr_lock_owner_init(&lock_id, &thd->lock_info);
- bzero((void*) ht_info, sizeof(ht_info));
-}
-
-
-/**
- Save THD state into cursor.
-
- @todo
- - What problems can we have with it if cursor is open?
- - TODO: must be fixed because of the prelocked mode.
-*/
-void
-Sensitive_cursor::post_open(THD *thd)
-{
- Engine_info *info;
- /*
- We need to save and reset thd->mem_root, otherwise it'll be
- freed later in mysql_parse.
-
- We can't just change thd->mem_root here as we want to keep the
- things that are already allocated in thd->mem_root for
- Sensitive_cursor::fetch()
- */
- *mem_root= *thd->mem_root;
- stmt_arena= thd->stmt_arena;
- state= stmt_arena->state;
- /* Allocate a new memory root for thd */
- init_sql_alloc(thd->mem_root,
- thd->variables.query_alloc_block_size,
- thd->variables.query_prealloc_size);
-
- /*
- Save tables and zero THD pointers to prevent table close in
- close_thread_tables.
- */
- derived_tables= thd->derived_tables;
- open_tables= thd->open_tables;
- lock= thd->lock;
- query_id= thd->query_id;
- free_list= thd->free_list;
- thd->change_list.move_elements_to(&change_list);
- reset_thd(thd);
- /* Now we have an active cursor and can cause a deadlock */
- thd->lock_info.n_cursors++;
-
- close_at_commit= FALSE; /* reset in case we're reusing the cursor */
- info= &ht_info[0];
- for (Ha_trx_info *ha_trx_info= thd->transaction.stmt.ha_list;
- ha_trx_info; ha_trx_info= ha_trx_info->next())
- {
- handlerton *ht= ha_trx_info->ht();
- close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
- if (ht->create_cursor_read_view)
- {
- info->ht= ht;
- info->read_view= (ht->create_cursor_read_view)(ht, thd);
- ++info;
- }
- }
- /*
- What problems can we have with it if cursor is open?
- TODO: must be fixed because of the prelocked mode.
- */
-}
-
-
-/**
- bzero cursor state in THD.
-*/
-
-void
-Sensitive_cursor::reset_thd(THD *thd)
-{
- thd->derived_tables= 0;
- thd->set_open_tables(NULL);
- thd->lock= 0;
- thd->free_list= 0;
- thd->change_list.empty();
-}
-
-
-int
-Sensitive_cursor::open(JOIN *join_arg)
-{
- join= join_arg;
- THD *thd= join->thd;
- /* First non-constant table */
- JOIN_TAB *join_tab= join->join_tab + join->const_tables;
- DBUG_ENTER("Sensitive_cursor::open");
-
- join->change_result(result);
- /*
- Send fields description to the client; server_status is sent
- in 'EOF' packet, which follows send_result_set_metadata().
- We don't simply use SEND_EOF flag of send_result_set_metadata because we also
- want to flush the network buffer, which is done only in a standalone
- send_eof().
- */
- result->send_result_set_metadata(*join->fields, Protocol::SEND_NUM_ROWS);
- thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
- result->send_eof();
- thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
-
- /* Prepare JOIN for reading rows. */
- join->tmp_table= 0;
- join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
- join->send_records= 0;
- join->fetch_limit= join->unit->offset_limit_cnt;
-
- /* Disable JOIN CACHE as it is not working with cursors yet */
- for (JOIN_TAB *tab= join_tab;
- tab != join->join_tab + join->tables - 1;
- tab++)
- {
- if (tab->next_select == sub_select_cache)
- tab->next_select= sub_select;
- }
-
- DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
- DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
- /*
- null_row is set only if row not found and it's outer join: should never
- happen for the first table in join_tab list
- */
- DBUG_ASSERT(join_tab->table->null_row == 0);
- DBUG_RETURN(0);
-}
-
-
-/**
- Fetch next num_rows rows from the cursor and send them to the client.
-
- Precondition:
- - Sensitive_cursor is open
-
- @param num_rows fetch up to this number of rows (maybe less)
-*/
-
-void
-Sensitive_cursor::fetch(ulong num_rows)
-{
- THD *thd= join->thd;
- JOIN_TAB *join_tab= join->join_tab + join->const_tables;
- enum_nested_loop_state error= NESTED_LOOP_OK;
- Query_arena backup_arena;
- Engine_info *info;
- DBUG_ENTER("Sensitive_cursor::fetch");
- DBUG_PRINT("enter",("rows: %lu", num_rows));
-
- DBUG_ASSERT(thd->derived_tables == 0 && thd->open_tables == 0 &&
- thd->lock == 0);
-
- thd->derived_tables= derived_tables;
- thd->set_open_tables(open_tables);
- thd->lock= lock;
- thd->set_query_id(query_id);
- change_list.move_elements_to(&thd->change_list);
- /* save references to memory allocated during fetch */
- thd->set_n_backup_active_arena(this, &backup_arena);
-
- for (info= ht_info; info->read_view ; info++)
- (info->ht->set_cursor_read_view)(info->ht, thd, info->read_view);
-
- join->fetch_limit+= num_rows;
-
- error= sub_select(join, join_tab, 0);
- if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
- error= sub_select(join,join_tab,1);
- if (error == NESTED_LOOP_QUERY_LIMIT)
- error= NESTED_LOOP_OK; /* select_limit used */
- if (error == NESTED_LOOP_CURSOR_LIMIT)
- join->resume_nested_loop= TRUE;
-
- ha_release_temporary_latches(thd);
-
- /* Grab free_list here to correctly free it in close */
- thd->restore_active_arena(this, &backup_arena);
-
- thd->change_list.move_elements_to(&change_list);
- reset_thd(thd);
-
- for (info= ht_info; info->read_view; info++)
- (info->ht->set_cursor_read_view)(info->ht, thd, 0);
-
- if (error == NESTED_LOOP_CURSOR_LIMIT)
- {
- /* Fetch limit worked, possibly more rows are there */
- thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
- result->send_eof();
- thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
- }
- else
- {
- close();
- if (error == NESTED_LOOP_OK)
- {
- thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
- result->send_eof();
- thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
- }
- else if (error != NESTED_LOOP_KILLED)
- my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
- }
- DBUG_VOID_RETURN;
-}
-
-
-/**
- @todo
- Another hack: we need to set THD state as if in a fetch to be
- able to call stmt close.
-*/
-void
-Sensitive_cursor::close()
-{
- THD *thd= join->thd;
- DBUG_ENTER("Sensitive_cursor::close");
-
- for (Engine_info *info= ht_info; info->read_view; info++)
- {
- (info->ht->close_cursor_read_view)(info->ht, thd, info->read_view);
- info->read_view= 0;
- info->ht= 0;
- }
-
- change_list.move_elements_to(&thd->change_list);
- {
- /*
- XXX: Another hack: we need to set THD state as if in a fetch to be
- able to call stmt close.
- */
- DBUG_ASSERT(lock || open_tables || derived_tables);
-
- TABLE *tmp_derived_tables= thd->derived_tables;
- MYSQL_LOCK *tmp_lock= thd->lock;
-
- thd->set_open_tables(open_tables);
- thd->derived_tables= derived_tables;
- thd->lock= lock;
-
- close_thread_tables(thd);
- /* Is expected to at least close tables and empty thd->change_list */
- stmt_arena->cleanup_stmt();
-
- thd->set_open_tables(tmp_derived_tables);
- thd->derived_tables= tmp_derived_tables;
- thd->lock= tmp_lock;
- }
- thd->lock_info.n_cursors--; /* Decrease the number of active cursors */
- join= 0;
- stmt_arena= 0;
- free_items();
- DBUG_VOID_RETURN;
-}
-
-
-Sensitive_cursor::~Sensitive_cursor()
-{
- if (is_open())
- close();
-}
/***************************************************************************
Materialized_cursor
@@ -570,7 +208,8 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
@param send_result_set_metadata List of fields that would be sent.
*/
-int Materialized_cursor::fill_item_list(THD *thd, List<Item> &send_result_set_metadata)
+int Materialized_cursor::fill_item_list(THD *thd,
+ List<Item> &send_result_set_metadata)
{
Query_arena backup_arena;
int rc;
@@ -608,6 +247,7 @@ end:
return rc || thd->is_error();
}
+
int Materialized_cursor::open(JOIN *join __attribute__((unused)))
{
THD *thd= fake_unit.thd;