Implement MarkM optimization request to avoid redundnat packet exchange
in cursors.
This commit is contained in:
parent
3cf9a4c4fc
commit
509531421c
@ -4907,13 +4907,12 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
|
|||||||
{
|
{
|
||||||
MYSQL *mysql= stmt->mysql;
|
MYSQL *mysql= stmt->mysql;
|
||||||
MYSQL_DATA *result= &stmt->result;
|
MYSQL_DATA *result= &stmt->result;
|
||||||
my_bool has_cursor= stmt->read_row_func == stmt_read_row_from_cursor;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reset stored result set if so was requested or it's a part
|
Reset stored result set if so was requested or it's a part
|
||||||
of cursor fetch.
|
of cursor fetch.
|
||||||
*/
|
*/
|
||||||
if (result->data && (has_cursor || (flags & RESET_STORE_RESULT)))
|
if (result->data && (flags & RESET_STORE_RESULT))
|
||||||
{
|
{
|
||||||
/* Result buffered */
|
/* Result buffered */
|
||||||
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
|
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
|
||||||
@ -4944,7 +4943,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
|
|||||||
mysql->status= MYSQL_STATUS_READY;
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_cursor || (flags & RESET_SERVER_SIDE))
|
if (flags & RESET_SERVER_SIDE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Reset the server side statement and close the server side
|
Reset the server side statement and close the server side
|
||||||
|
@ -106,6 +106,7 @@ public:
|
|||||||
virtual ~Prepared_statement();
|
virtual ~Prepared_statement();
|
||||||
void setup_set_params();
|
void setup_set_params();
|
||||||
virtual Query_arena::Type type() const;
|
virtual Query_arena::Type type() const;
|
||||||
|
virtual void close_cursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
static void execute_stmt(THD *thd, Prepared_statement *stmt,
|
static void execute_stmt(THD *thd, Prepared_statement *stmt,
|
||||||
@ -1986,10 +1987,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||||||
|
|
||||||
cursor= stmt->cursor;
|
cursor= stmt->cursor;
|
||||||
if (cursor && cursor->is_open())
|
if (cursor && cursor->is_open())
|
||||||
{
|
stmt->close_cursor();
|
||||||
my_error(ER_EXEC_STMT_WITH_OPEN_CURSOR, MYF(0));
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_ASSERT(thd->free_list == NULL);
|
DBUG_ASSERT(thd->free_list == NULL);
|
||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
@ -2284,6 +2282,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
|||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
|
stmt->close_cursor(); /* will reset statement params */
|
||||||
cursor= stmt->cursor;
|
cursor= stmt->cursor;
|
||||||
if (cursor && cursor->is_open())
|
if (cursor && cursor->is_open())
|
||||||
{
|
{
|
||||||
@ -2295,12 +2294,6 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
|||||||
|
|
||||||
stmt->state= Query_arena::PREPARED;
|
stmt->state= Query_arena::PREPARED;
|
||||||
|
|
||||||
/*
|
|
||||||
Clear parameters from data which could be set by
|
|
||||||
mysql_stmt_send_long_data() call.
|
|
||||||
*/
|
|
||||||
reset_stmt_params(stmt);
|
|
||||||
|
|
||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
|
|
||||||
@ -2448,10 +2441,17 @@ void Prepared_statement::setup_set_params()
|
|||||||
Prepared_statement::~Prepared_statement()
|
Prepared_statement::~Prepared_statement()
|
||||||
{
|
{
|
||||||
if (cursor)
|
if (cursor)
|
||||||
|
{
|
||||||
|
if (cursor->is_open())
|
||||||
|
{
|
||||||
|
cursor->close(FALSE);
|
||||||
|
free_items();
|
||||||
|
free_root(cursor->mem_root, MYF(0));
|
||||||
|
}
|
||||||
cursor->Cursor::~Cursor();
|
cursor->Cursor::~Cursor();
|
||||||
free_items();
|
}
|
||||||
if (cursor)
|
else
|
||||||
free_root(cursor->mem_root, MYF(0));
|
free_items();
|
||||||
delete lex->result;
|
delete lex->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2460,3 +2460,20 @@ Query_arena::Type Prepared_statement::type() const
|
|||||||
{
|
{
|
||||||
return PREPARED_STATEMENT;
|
return PREPARED_STATEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Prepared_statement::close_cursor()
|
||||||
|
{
|
||||||
|
if (cursor && cursor->is_open())
|
||||||
|
{
|
||||||
|
thd->change_list= cursor->change_list;
|
||||||
|
cursor->close(FALSE);
|
||||||
|
cleanup_stmt_and_thd_after_use(this, thd);
|
||||||
|
free_root(cursor->mem_root, MYF(0));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Clear parameters from data which could be set by
|
||||||
|
mysql_stmt_send_long_data() call.
|
||||||
|
*/
|
||||||
|
reset_stmt_params(this);
|
||||||
|
}
|
||||||
|
@ -1915,12 +1915,6 @@ Cursor::close(bool is_active)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Cursor::~Cursor()
|
|
||||||
{
|
|
||||||
if (is_open())
|
|
||||||
close(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -408,7 +408,7 @@ public:
|
|||||||
|
|
||||||
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
||||||
Cursor(THD *thd);
|
Cursor(THD *thd);
|
||||||
~Cursor();
|
~Cursor() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -13050,27 +13050,6 @@ static void test_bug9478()
|
|||||||
check_execute(stmt, rc);
|
check_execute(stmt, rc);
|
||||||
if (!opt_silent && i == 0)
|
if (!opt_silent && i == 0)
|
||||||
printf("Fetched row: %s\n", a);
|
printf("Fetched row: %s\n", a);
|
||||||
/*
|
|
||||||
Although protocol-wise an attempt to execute a statement which
|
|
||||||
already has an open cursor associated with it will yield an error,
|
|
||||||
the client library behavior tested here is consistent with
|
|
||||||
the non-cursor execution scenario: mysql_stmt_execute will
|
|
||||||
silently close the cursor if necessary.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char buff[9];
|
|
||||||
/* Fill in the execute packet */
|
|
||||||
int4store(buff, stmt->stmt_id);
|
|
||||||
buff[4]= 0; /* Flag */
|
|
||||||
int4store(buff+5, 1); /* Reserved for array bind */
|
|
||||||
rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_EXECUTE, buff,
|
|
||||||
sizeof(buff), 0,0,1) ||
|
|
||||||
(*mysql->methods->read_query_result)(mysql));
|
|
||||||
DIE_UNLESS(rc);
|
|
||||||
if (!opt_silent && i == 0)
|
|
||||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc= mysql_stmt_execute(stmt);
|
rc= mysql_stmt_execute(stmt);
|
||||||
check_execute(stmt, rc);
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
@ -13429,7 +13408,7 @@ static void test_bug10794()
|
|||||||
bind[1].length= &a_len;
|
bind[1].length= &a_len;
|
||||||
rc= mysql_stmt_bind_param(stmt, bind);
|
rc= mysql_stmt_bind_param(stmt, bind);
|
||||||
check_execute(stmt, rc);
|
check_execute(stmt, rc);
|
||||||
for (i= 0; i < 34; i++)
|
for (i= 0; i < 42; i++)
|
||||||
{
|
{
|
||||||
id_val= (i+1)*10;
|
id_val= (i+1)*10;
|
||||||
sprintf(a, "a%d", i);
|
sprintf(a, "a%d", i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user