summaryrefslogtreecommitdiff
path: root/sql/sql_cursor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_cursor.cc')
-rw-r--r--sql/sql_cursor.cc113
1 files changed, 62 insertions, 51 deletions
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 1cb96715a76..3521e54e02f 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2005, 2006, 2008 MySQL AB, 2008 Sun Microsystems, Inc.
- Use is subject to license terms.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,7 +12,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation /* gcc class implementation */
#endif
@@ -25,9 +26,9 @@
Declarations.
****************************************************************************/
-/*
+/**
Sensitive_cursor -- a sensitive non-materialized server side
- cursor An instance of this class cursor has its own runtime
+ 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.
@@ -45,7 +46,7 @@ class Sensitive_cursor: public Server_side_cursor
query_id_t query_id;
struct Engine_info
{
- const handlerton *ht;
+ handlerton *ht;
void *read_view;
};
Engine_info ht_info[MAX_HA];
@@ -70,7 +71,7 @@ public:
};
-/*
+/**
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
@@ -99,7 +100,7 @@ public:
};
-/*
+/**
Select_materialize -- a mediator between a cursor query and the
protocol. In case we were not able to open a non-materialzed
cursor, it creates an internal temporary HEAP table, and insert
@@ -110,33 +111,32 @@ public:
class Select_materialize: public select_union
{
- select_result *result; /* the result object of the caller (PS or SP) */
+ select_result *result; /**< the result object of the caller (PS or SP) */
public:
Materialized_cursor *materialized_cursor;
- Select_materialize(select_result *result_arg) :result(result_arg),
- materialized_cursor(0) {}
+ Select_materialize(select_result *result_arg)
+ :result(result_arg), materialized_cursor(0) {}
virtual bool send_fields(List<Item> &list, uint flags);
};
/**************************************************************************/
-/*
+/**
Attempt to open a materialized or non-materialized cursor.
- SYNOPSIS
- mysql_open_cursor()
- thd thread handle
- flags [in] create a materialized cursor or not
- result [in] result class of the caller used as a destination
- for the rows fetched from the cursor
- pcursor [out] a pointer to store a pointer to cursor in
-
- RETURN VALUE
- 0 the query has been successfully executed; in this
- case pcursor may or may not contain
- a pointer to an open cursor.
- non-zero an error, 'pcursor' has been left intact.
+ @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
+
+ @retval
+ 0 the query has been successfully executed; in this
+ case pcursor may or may not contain
+ a pointer to an open cursor.
+ @retval
+ non-zero an error, 'pcursor' has been left intact.
*/
int mysql_open_cursor(THD *thd, uint flags, select_result *result,
@@ -280,6 +280,14 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
}
+/**
+ Save THD state into cursor.
+
+ @todo
+ - XXX: thd->locked_tables is not changed.
+ - 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)
{
@@ -316,14 +324,15 @@ Sensitive_cursor::post_open(THD *thd)
close_at_commit= FALSE; /* reset in case we're reusing the cursor */
info= &ht_info[0];
- for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
+ for (Ha_trx_info *ha_trx_info= thd->transaction.stmt.ha_list;
+ ha_trx_info; ha_trx_info= ha_trx_info->next())
{
- const handlerton *ht= *pht;
+ 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)();
+ info->read_view= (ht->create_cursor_read_view)(ht, thd);
++info;
}
}
@@ -335,6 +344,10 @@ Sensitive_cursor::post_open(THD *thd)
}
+/**
+ bzero cursor state in THD.
+*/
+
void
Sensitive_cursor::reset_thd(THD *thd)
{
@@ -394,20 +407,13 @@ Sensitive_cursor::open(JOIN *join_arg)
}
-/*
- SYNOPSIS
- Sensitive_cursor::fetch()
- num_rows fetch up to this number of rows (maybe less)
-
- DESCRIPTION
- Fetch next num_rows rows from the cursor and send them to the client
+/**
+ Fetch next num_rows rows from the cursor and send them to the client.
- Precondition:
- Sensitive_cursor is open
+ Precondition:
+ - Sensitive_cursor is open
- RETURN VALUES:
- none, this function will send OK to the clinet or set an error
- message in THD
+ @param num_rows fetch up to this number of rows (maybe less)
*/
void
@@ -433,7 +439,7 @@ Sensitive_cursor::fetch(ulong num_rows)
thd->set_n_backup_active_arena(this, &backup_arena);
for (info= ht_info; info->read_view ; info++)
- (info->ht->set_cursor_read_view)(info->read_view);
+ (info->ht->set_cursor_read_view)(info->ht, thd, info->read_view);
join->fetch_limit+= num_rows;
@@ -454,7 +460,7 @@ Sensitive_cursor::fetch(ulong num_rows)
reset_thd(thd);
for (info= ht_info; info->read_view; info++)
- (info->ht->set_cursor_read_view)(0);
+ (info->ht->set_cursor_read_view)(info->ht, thd, 0);
if (error == NESTED_LOOP_CURSOR_LIMIT)
{
@@ -479,6 +485,11 @@ Sensitive_cursor::fetch(ulong num_rows)
}
+/**
+ @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()
{
@@ -487,7 +498,7 @@ Sensitive_cursor::close()
for (Engine_info *info= ht_info; info->read_view; info++)
{
- (info->ht->close_cursor_read_view)(info->read_view);
+ (info->ht->close_cursor_read_view)(info->ht, thd, info->read_view);
info->read_view= 0;
info->ht= 0;
}
@@ -588,7 +599,7 @@ int Materialized_cursor::fill_item_list(THD *thd, List<Item> &send_fields)
end:
thd->restore_active_arena(this, &backup_arena);
/* Check for thd->is_error() in case of OOM */
- return rc || thd->net.report_error;
+ return rc || thd->is_error();
}
int Materialized_cursor::open(JOIN *join __attribute__((unused)))
@@ -626,10 +637,9 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
}
-/*
+/**
Fetch up to the given number of rows from a materialized cursor.
- DESCRIPTION
Precondition: the cursor is open.
If the cursor points after the last row, the fetch will automatically
@@ -637,10 +647,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
and probably should be improved to return
SERVER_STATUS_LAST_ROW_SENT along with the last row.
-
- RETURN VALUE
- none, in case of success the row is sent to the client, otherwise
- an error message is set in THD
*/
void Materialized_cursor::fetch(ulong num_rows)
@@ -654,7 +660,12 @@ void Materialized_cursor::fetch(ulong num_rows)
if ((res= table->file->rnd_next(table->record[0])))
break;
/* Send data only if the read was successful. */
- result->send_data(item_list);
+ /*
+ If network write failed (i.e. due to a closed socked),
+ the error has already been set. Just return.
+ */
+ if (result->send_data(item_list))
+ return;
}
switch (res) {