From 78fa2e4d6d89b8d0bb4b26fe648668b97c9400b9 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Fri, 12 Nov 2010 15:56:21 +0300 Subject: Implement a fix for Bug#57058 -- send SERVER_QUERY_WAS_SLOW over network when a query was slow. When a query is slow, sent a special flag to the client indicating this fact. Add a test case. Implement review comments. include/mysql_com.h: Clear SERVER_QUERY_WAS_SLOW at end of each statement. Since this patch removes the technique when thd->server_status is modified briefly only to execute my_eof(), reset more server status bit that may remain in the status from execution of the previous statement. sql/protocol.cc: Always use thd->server_status to in net_* functions to send the latest status to the client. sql/sp_head.cc: Calculate if a query was slow before sending EOF packet. sql/sql_cursor.cc: Remove juggling with thd->server_status. The extra status bits are reset at start of the next statement. sql/sql_db.cc: Remove juggling with thd->server_status. The extra status bits are reset at start of the next statement. sql/sql_error.cc: Remove m_server_status member, it's not really part of the Diagnostics_area. sql/sql_error.h: Remove server_status member, it's not part of the Diagnostics_area. The associated hack is removed as well. sql/sql_parse.cc: Do not calculate if a query was slow twice. Use a status flag in thd->server_status. tests/mysql_client_test.c: Add a test case for Bug#57058. Check that the status is present at the client, when sent. --- sql/sql_cursor.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'sql/sql_cursor.cc') diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 7a9834b4cde..acc591f1ea2 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -277,7 +277,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) rc= result->send_result_set_metadata(item_list, Protocol::SEND_NUM_ROWS); thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; } return rc; } @@ -318,12 +317,10 @@ void Materialized_cursor::fetch(ulong num_rows) case 0: thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; break; case HA_ERR_END_OF_FILE: thd->server_status|= SERVER_STATUS_LAST_ROW_SENT; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; close(); break; default: -- cgit v1.2.1 From 1c4a8872ebbe47b0f10adc5caa849461b383e549 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 8 Dec 2010 18:47:21 +0200 Subject: Bug #58350: 5.5.7-rc compile failed at sp_head.cc Fixed the references to security_ctx->priv_user to be real char * pointers instead of a C array name reference. This is somehow important for some 3d party dtrace replacements --- sql/sql_cursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_cursor.cc') diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index acc591f1ea2..f607936d5b9 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -111,7 +111,7 @@ int mysql_open_cursor(THD *thd, select_result *result, MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 2); rc= mysql_execute_command(thd); -- cgit v1.2.1 From 7117e0635c60f5db23ebb0f4b0866ce93b8ffaed Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 22 Mar 2011 14:48:56 +0300 Subject: A patch for Bug#11763413 (56115: SELECT doesn't work in prepared statements with cursor protocol). The problem was a bug in Materialized-cursor implementation. Materialized_cursor::open() called send_result_metadata() with items pointing to already closed table. The fix is to send metadata when the table is still open. NOTE: this is a "partial" fix: metadata are different with and without --cursor-protocol, but that's a different large problem, one indication of which is reported as Bug 24176. --- sql/sql_cursor.cc | 69 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 24 deletions(-) (limited to 'sql/sql_cursor.cc') diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index f607936d5b9..aaf483f7a2f 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2006 MySQL AB +/* Copyright (c) 2005, 2011, 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 @@ -46,7 +46,7 @@ class Materialized_cursor: public Server_side_cursor public: Materialized_cursor(select_result *result, TABLE *table); - int fill_item_list(THD *thd, List &send_result_set_metadata); + int send_result_set_metadata(THD *thd, List &send_result_set_metadata); virtual bool is_open() const { return table != 0; } virtual int open(JOIN *join __attribute__((unused))); virtual void fetch(ulong num_rows); @@ -133,7 +133,13 @@ int mysql_open_cursor(THD *thd, select_result *result, if (rc) { if (result_materialize->materialized_cursor) + { + /* Rollback metadata in the client-server protocol. */ + result_materialize->abort_result_set(); + delete result_materialize->materialized_cursor; + } + goto end; } @@ -142,6 +148,12 @@ int mysql_open_cursor(THD *thd, select_result *result, Materialized_cursor *materialized_cursor= result_materialize->materialized_cursor; + /* + NOTE: close_thread_tables() has been called in + mysql_execute_command(), so all tables except from the cursor + temporary table have been closed. + */ + if ((rc= materialized_cursor->open(0))) { delete materialized_cursor; @@ -202,14 +214,16 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg, /** - Preserve the original metadata that would be sent to the client. + Preserve the original metadata to be sent to the client. + Initiate sending of the original metadata to the client + (call Protocol::send_result_set_metadata()). @param thd Thread identifier. @param send_result_set_metadata List of fields that would be sent. */ -int Materialized_cursor::fill_item_list(THD *thd, - List &send_result_set_metadata) +int Materialized_cursor::send_result_set_metadata( + THD *thd, List &send_result_set_metadata) { Query_arena backup_arena; int rc; @@ -241,6 +255,14 @@ int Materialized_cursor::fill_item_list(THD *thd, ident->db_name= thd->strdup(send_field.db_name); ident->table_name= thd->strdup(send_field.table_name); } + + /* + Original metadata result set should be sent here. After + mysql_execute_command() is finished, item_list can not be used for + sending metadata, because it references closed table. + */ + rc= result->send_result_set_metadata(item_list, Protocol::SEND_NUM_ROWS); + end: thd->restore_active_arena(this, &backup_arena); /* Check for thd->is_error() in case of OOM */ @@ -253,31 +275,29 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) THD *thd= fake_unit.thd; int rc; Query_arena backup_arena; + thd->set_n_backup_active_arena(this, &backup_arena); - /* Create a list of fields and start sequential scan */ + + /* Create a list of fields and start sequential scan. */ + rc= result->prepare(item_list, &fake_unit); - if (!rc && !(rc= table->file->ha_rnd_init(TRUE))) - is_rnd_inited= 1; + rc= !rc && table->file->ha_rnd_init(TRUE); + is_rnd_inited= !rc; thd->restore_active_arena(this, &backup_arena); - if (rc == 0) + + /* Commit or rollback metadata in the client-server protocol. */ + + if (!rc) { - /* - Now send the result set metadata to the client. We need to - do it here, as in Select_materialize::send_result_set_metadata the items - for column types are not yet created (send_result_set_metadata requires - a list of items). The new types may differ from the original - ones sent at prepare if some of them were altered by MySQL - HEAP tables mechanism -- used when create_tmp_field_from_item - may alter the original column type. - - We can't simply supply SEND_EOF flag to send_result_set_metadata, because - send_result_set_metadata doesn't flush the network buffer. - */ - rc= result->send_result_set_metadata(item_list, Protocol::SEND_NUM_ROWS); thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; result->send_eof(); } + else + { + result->abort_result_set(); + } + return rc; } @@ -370,13 +390,14 @@ bool Select_materialize::send_result_set_metadata(List &list, uint flags) materialized_cursor= new (&table->mem_root) Materialized_cursor(result, table); - if (! materialized_cursor) + if (!materialized_cursor) { free_tmp_table(table->in_use, table); table= 0; return TRUE; } - if (materialized_cursor->fill_item_list(unit->thd, list)) + + if (materialized_cursor->send_result_set_metadata(unit->thd, list)) { delete materialized_cursor; table= 0; -- cgit v1.2.1