diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2022-07-07 17:27:34 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2022-07-07 17:29:40 +0300 |
commit | d3e44d37b8d9924ed6d96e6984ddad49e9cf39fd (patch) | |
tree | f03279bb58d8eed25a383176089b7682afb1321e | |
parent | 0ba528fe56f6c637d9fbc9d177a62610038fd519 (diff) | |
download | mariadb-git-bb-10.2-midenok.tar.gz |
MDEV-20088 Cleanup: unused Ed_connection, Execute_sql_statement, Protocol_local, etcbb-10.2-midenok
Removed needless classes.
-rw-r--r-- | sql/sql_prepare.cc | 743 | ||||
-rw-r--r-- | sql/sql_prepare.h | 279 |
2 files changed, 0 insertions, 1022 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 64e4cd30561..32a3ab87006 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -204,7 +204,6 @@ public: bool execute_bulk_loop(String *expanded_query, bool open_cursor, uchar *packet_arg, uchar *packet_end_arg); - bool execute_server_runnable(Server_runnable *server_runnable); my_bool set_bulk_parameters(bool reset); bool bulk_iterations() { return iterations; }; /* Destroy this statement */ @@ -228,78 +227,6 @@ private: void swap_prepared_statement(Prepared_statement *copy); }; -/** - Execute one SQL statement in an isolated context. -*/ - -class Execute_sql_statement: public Server_runnable -{ -public: - Execute_sql_statement(LEX_STRING sql_text); - virtual bool execute_server_code(THD *thd); -private: - LEX_STRING m_sql_text; -}; - - -class Ed_connection; - -/** - Protocol_local: a helper class to intercept the result - of the data written to the network. -*/ - -class Protocol_local :public Protocol -{ -public: - Protocol_local(THD *thd, Ed_connection *ed_connection); - ~Protocol_local() { free_root(&m_rset_root, MYF(0)); } -protected: - virtual void prepare_for_resend(); - virtual bool write(); - virtual bool store_null(); - virtual bool store_tiny(longlong from); - virtual bool store_short(longlong from); - virtual bool store_long(longlong from); - virtual bool store_longlong(longlong from, bool unsigned_flag); - virtual bool store_decimal(const my_decimal *); - virtual bool store(const char *from, size_t length, CHARSET_INFO *cs); - virtual bool store(const char *from, size_t length, - CHARSET_INFO *fromcs, CHARSET_INFO *tocs); - virtual bool store(MYSQL_TIME *time, int decimals); - virtual bool store_date(MYSQL_TIME *time); - virtual bool store_time(MYSQL_TIME *time, int decimals); - virtual bool store(float value, uint32 decimals, String *buffer); - virtual bool store(double value, uint32 decimals, String *buffer); - virtual bool store(Field *field); - - virtual bool send_result_set_metadata(List<Item> *list, uint flags); - virtual bool send_out_parameters(List<Item_param> *sp_params); -#ifdef EMBEDDED_LIBRARY - void remove_last_row(); -#endif - virtual enum enum_protocol_type type() { return PROTOCOL_LOCAL; }; - - virtual bool send_ok(uint server_status, uint statement_warn_count, - ulonglong affected_rows, ulonglong last_insert_id, - const char *message, bool skip_flush); - - virtual bool send_eof(uint server_status, uint statement_warn_count); - virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate); -private: - bool store_string(const char *str, size_t length, - CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs); - - bool store_column(const void *data, size_t length); - void opt_add_row_to_rset(); -private: - Ed_connection *m_connection; - MEM_ROOT m_rset_root; - List<Ed_row> *m_rset; - size_t m_column_count; - Ed_column *m_current_row; - Ed_column *m_current_column; -}; /****************************************************************************** Implementation @@ -3917,71 +3844,6 @@ Reprepare_observer::report_error(THD *thd) } -/******************************************************************* -* Server_runnable -*******************************************************************/ - -Server_runnable::~Server_runnable() -{ -} - -/////////////////////////////////////////////////////////////////////////// - -Execute_sql_statement:: -Execute_sql_statement(LEX_STRING sql_text) - :m_sql_text(sql_text) -{} - - -/** - Parse and execute a statement. Does not prepare the query. - - Allows to execute a statement from within another statement. - The main property of the implementation is that it does not - affect the environment -- i.e. you can run many - executions without having to cleanup/reset THD in between. -*/ - -bool -Execute_sql_statement::execute_server_code(THD *thd) -{ - PSI_statement_locker *parent_locker; - bool error; - - if (alloc_query(thd, m_sql_text.str, m_sql_text.length)) - return TRUE; - - Parser_state parser_state; - if (parser_state.init(thd, thd->query(), thd->query_length())) - return TRUE; - - parser_state.m_lip.multi_statements= FALSE; - lex_start(thd); - - error= parse_sql(thd, &parser_state, NULL) || thd->is_error(); - - if (error) - goto end; - - thd->lex->set_trg_event_type_for_tables(); - - parent_locker= thd->m_statement_psi; - thd->m_statement_psi= NULL; - error= mysql_execute_command(thd); - thd->m_statement_psi= parent_locker; - - /* report error issued during command execution */ - if (error == 0 && thd->spcont == NULL) - general_log_write(thd, COM_STMT_EXECUTE, - thd->query(), thd->query_length()); - -end: - thd->lex->restore_set_statement_var(); - lex_end(thd->lex); - - return error; -} - /*************************************************************************** Prepared_statement ****************************************************************************/ @@ -4727,40 +4589,6 @@ reexecute: } -bool -Prepared_statement::execute_server_runnable(Server_runnable *server_runnable) -{ - Statement stmt_backup; - bool error; - Query_arena *save_stmt_arena= thd->stmt_arena; - Item_change_list save_change_list; - thd->Item_change_list::move_elements_to(&save_change_list); - - state= STMT_CONVENTIONAL_EXECUTION; - - if (!(lex= new (mem_root) st_lex_local)) - return TRUE; - - thd->set_n_backup_statement(this, &stmt_backup); - thd->set_n_backup_active_arena(this, &stmt_backup); - thd->stmt_arena= this; - - error= server_runnable->execute_server_code(thd); - - thd->cleanup_after_query(); - - thd->restore_active_arena(this, &stmt_backup); - thd->restore_backup_statement(this, &stmt_backup); - thd->stmt_arena= save_stmt_arena; - - save_change_list.move_elements_to(thd); - - /* Items and memory will freed in destructor */ - - return error; -} - - /** Reprepare this prepared statement. @@ -5205,574 +5033,3 @@ void Prepared_statement::deallocate() /* Statement map calls delete stmt on erase */ thd->stmt_map.erase(this); } - - -/*************************************************************************** -* Ed_result_set -***************************************************************************/ -/** - Use operator delete to free memory of Ed_result_set. - Accessing members of a class after the class has been destroyed - is a violation of the C++ standard but is commonly used in the - server code. -*/ - -void Ed_result_set::operator delete(void *ptr, size_t size) throw () -{ - if (ptr) - { - /* - Make a stack copy, otherwise free_root() will attempt to - write to freed memory. - */ - MEM_ROOT own_root= ((Ed_result_set*) ptr)->m_mem_root; - free_root(&own_root, MYF(0)); - } -} - - -/** - Initialize an instance of Ed_result_set. - - Instances of the class, as well as all result set rows, are - always allocated in the memory root passed over as the second - argument. In the constructor, we take over ownership of the - memory root. It will be freed when the class is destroyed. - - sic: Ed_result_est is not designed to be allocated on stack. -*/ - -Ed_result_set::Ed_result_set(List<Ed_row> *rows_arg, - size_t column_count_arg, - MEM_ROOT *mem_root_arg) - :m_mem_root(*mem_root_arg), - m_column_count(column_count_arg), - m_rows(rows_arg), - m_next_rset(NULL) -{ - /* Take over responsibility for the memory */ - clear_alloc_root(mem_root_arg); -} - -/*************************************************************************** -* Ed_result_set -***************************************************************************/ - -/** - Create a new "execute direct" connection. -*/ - -Ed_connection::Ed_connection(THD *thd) - :m_diagnostics_area(thd->query_id, false, true), - m_thd(thd), - m_rsets(0), - m_current_rset(0) -{ -} - - -/** - Free all result sets of the previous statement, if any, - and reset warnings and errors. - - Called before execution of the next query. -*/ - -void -Ed_connection::free_old_result() -{ - while (m_rsets) - { - Ed_result_set *rset= m_rsets->m_next_rset; - delete m_rsets; - m_rsets= rset; - } - m_current_rset= m_rsets; - m_diagnostics_area.reset_diagnostics_area(); - m_diagnostics_area.clear_warning_info(m_thd->query_id); -} - - -/** - A simple wrapper that uses a helper class to execute SQL statements. -*/ - -bool -Ed_connection::execute_direct(LEX_STRING sql_text) -{ - Execute_sql_statement execute_sql_statement(sql_text); - DBUG_PRINT("ed_query", ("%s", sql_text.str)); - - return execute_direct(&execute_sql_statement); -} - - -/** - Execute a fragment of server functionality without an effect on - thd, and store results in memory. - - Conventions: - - the code fragment must finish with OK, EOF or ERROR. - - the code fragment doesn't have to close thread tables, - free memory, commit statement transaction or do any other - cleanup that is normally done in the end of dispatch_command(). - - @param server_runnable A code fragment to execute. -*/ - -bool Ed_connection::execute_direct(Server_runnable *server_runnable) -{ - bool rc= FALSE; - Protocol_local protocol_local(m_thd, this); - Prepared_statement stmt(m_thd); - Protocol *save_protocol= m_thd->protocol; - Diagnostics_area *save_diagnostics_area= m_thd->get_stmt_da(); - - DBUG_ENTER("Ed_connection::execute_direct"); - - free_old_result(); /* Delete all data from previous execution, if any */ - - m_thd->protocol= &protocol_local; - m_thd->set_stmt_da(&m_diagnostics_area); - - rc= stmt.execute_server_runnable(server_runnable); - m_thd->protocol->end_statement(); - - m_thd->protocol= save_protocol; - m_thd->set_stmt_da(save_diagnostics_area); - /* - Protocol_local makes use of m_current_rset to keep - track of the last result set, while adding result sets to the end. - Reset it to point to the first result set instead. - */ - m_current_rset= m_rsets; - - DBUG_RETURN(rc); -} - - -/** - A helper method that is called only during execution. - - Although Ed_connection doesn't support multi-statements, - a statement may generate many result sets. All subsequent - result sets are appended to the end. - - @pre This is called only by Protocol_local. -*/ - -void -Ed_connection::add_result_set(Ed_result_set *ed_result_set) -{ - if (m_rsets) - { - m_current_rset->m_next_rset= ed_result_set; - /* While appending, use m_current_rset as a pointer to the tail. */ - m_current_rset= ed_result_set; - } - else - m_current_rset= m_rsets= ed_result_set; -} - - -/** - Release ownership of the current result set to the client. - - Since we use a simple linked list for result sets, - this method uses a linear search of the previous result - set to exclude the released instance from the list. - - @todo Use double-linked list, when this is really used. - - XXX: This has never been tested with more than one result set! - - @pre There must be a result set. -*/ - -Ed_result_set * -Ed_connection::store_result_set() -{ - Ed_result_set *ed_result_set; - - DBUG_ASSERT(m_current_rset); - - if (m_current_rset == m_rsets) - { - /* Assign the return value */ - ed_result_set= m_current_rset; - /* Exclude the return value from the list. */ - m_current_rset= m_rsets= m_rsets->m_next_rset; - } - else - { - Ed_result_set *prev_rset= m_rsets; - /* Assign the return value. */ - ed_result_set= m_current_rset; - - /* Exclude the return value from the list */ - while (prev_rset->m_next_rset != m_current_rset) - prev_rset= ed_result_set->m_next_rset; - m_current_rset= prev_rset->m_next_rset= m_current_rset->m_next_rset; - } - ed_result_set->m_next_rset= NULL; /* safety */ - - return ed_result_set; -} - -/************************************************************************* -* Protocol_local -**************************************************************************/ - -Protocol_local::Protocol_local(THD *thd, Ed_connection *ed_connection) - :Protocol(thd), - m_connection(ed_connection), - m_rset(NULL), - m_column_count(0), - m_current_row(NULL), - m_current_column(NULL) -{ - clear_alloc_root(&m_rset_root); -} - -/** - Called between two result set rows. - - Prepare structures to fill result set rows. - Unfortunately, we can't return an error here. If memory allocation - fails, we'll have to return an error later. And so is done - in methods such as @sa store_column(). -*/ - -void Protocol_local::prepare_for_resend() -{ - DBUG_ASSERT(alloc_root_inited(&m_rset_root)); - - opt_add_row_to_rset(); - /* Start a new row. */ - m_current_row= (Ed_column *) alloc_root(&m_rset_root, - sizeof(Ed_column) * m_column_count); - m_current_column= m_current_row; -} - - -/** - In "real" protocols this is called to finish a result set row. - Unused in the local implementation. -*/ - -bool Protocol_local::write() -{ - return FALSE; -} - -/** - A helper function to add the current row to the current result - set. Called in @sa prepare_for_resend(), when a new row is started, - and in send_eof(), when the result set is finished. -*/ - -void Protocol_local::opt_add_row_to_rset() -{ - if (m_current_row) - { - /* Add the old row to the result set */ - Ed_row *ed_row= new (&m_rset_root) Ed_row(m_current_row, m_column_count); - if (ed_row) - m_rset->push_back(ed_row, &m_rset_root); - } -} - - -/** - Add a NULL column to the current row. -*/ - -bool Protocol_local::store_null() -{ - if (m_current_column == NULL) - return TRUE; /* prepare_for_resend() failed to allocate memory. */ - - bzero(m_current_column, sizeof(*m_current_column)); - ++m_current_column; - return FALSE; -} - - -/** - A helper method to add any column to the current row - in its binary form. - - Allocates memory for the data in the result set memory root. -*/ - -bool Protocol_local::store_column(const void *data, size_t length) -{ - if (m_current_column == NULL) - return TRUE; /* prepare_for_resend() failed to allocate memory. */ - /* - alloc_root() automatically aligns memory, so we don't need to - do any extra alignment if we're pointing to, say, an integer. - */ - m_current_column->str= (char*) memdup_root(&m_rset_root, - data, - length + 1 /* Safety */); - if (! m_current_column->str) - return TRUE; - m_current_column->str[length]= '\0'; /* Safety */ - m_current_column->length= length; - ++m_current_column; - return FALSE; -} - - -/** - Store a string value in a result set column, optionally - having converted it to character_set_results. -*/ - -bool -Protocol_local::store_string(const char *str, size_t length, - CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs) -{ - /* Store with conversion */ - uint error_unused; - - if (dst_cs && !my_charset_same(src_cs, dst_cs) && - src_cs != &my_charset_bin && - dst_cs != &my_charset_bin) - { - if (convert->copy(str, length, src_cs, dst_cs, &error_unused)) - return TRUE; - str= convert->ptr(); - length= convert->length(); - } - return store_column(str, length); -} - - -/** Store a tiny int as is (1 byte) in a result set column. */ - -bool Protocol_local::store_tiny(longlong value) -{ - char v= (char) value; - return store_column(&v, 1); -} - - -/** Store a short as is (2 bytes, host order) in a result set column. */ - -bool Protocol_local::store_short(longlong value) -{ - int16 v= (int16) value; - return store_column(&v, 2); -} - - -/** Store a "long" as is (4 bytes, host order) in a result set column. */ - -bool Protocol_local::store_long(longlong value) -{ - int32 v= (int32) value; - return store_column(&v, 4); -} - - -/** Store a "longlong" as is (8 bytes, host order) in a result set column. */ - -bool Protocol_local::store_longlong(longlong value, bool unsigned_flag) -{ - int64 v= (int64) value; - return store_column(&v, 8); -} - - -/** Store a decimal in string format in a result set column */ - -bool Protocol_local::store_decimal(const my_decimal *value) -{ - char buf[DECIMAL_MAX_STR_LENGTH]; - String str(buf, sizeof (buf), &my_charset_bin); - int rc; - - rc= my_decimal2string(E_DEC_FATAL_ERROR, value, 0, 0, 0, &str); - - if (rc) - return TRUE; - - return store_column(str.ptr(), str.length()); -} - - -/** Convert to cs_results and store a string. */ - -bool Protocol_local::store(const char *str, size_t length, - CHARSET_INFO *src_cs) -{ - CHARSET_INFO *dst_cs; - - dst_cs= m_connection->m_thd->variables.character_set_results; - return store_string(str, length, src_cs, dst_cs); -} - - -/** Store a string. */ - -bool Protocol_local::store(const char *str, size_t length, - CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs) -{ - return store_string(str, length, src_cs, dst_cs); -} - - -/* Store MYSQL_TIME (in binary format) */ - -bool Protocol_local::store(MYSQL_TIME *time, int decimals) -{ - if (decimals != AUTO_SEC_PART_DIGITS) - my_time_trunc(time, decimals); - return store_column(time, sizeof(MYSQL_TIME)); -} - - -/** Store MYSQL_TIME (in binary format) */ - -bool Protocol_local::store_date(MYSQL_TIME *time) -{ - return store_column(time, sizeof(MYSQL_TIME)); -} - - -/** Store MYSQL_TIME (in binary format) */ - -bool Protocol_local::store_time(MYSQL_TIME *time, int decimals) -{ - if (decimals != AUTO_SEC_PART_DIGITS) - my_time_trunc(time, decimals); - return store_column(time, sizeof(MYSQL_TIME)); -} - - -/* Store a floating point number, as is. */ - -bool Protocol_local::store(float value, uint32 decimals, String *buffer) -{ - return store_column(&value, sizeof(float)); -} - - -/* Store a double precision number, as is. */ - -bool Protocol_local::store(double value, uint32 decimals, String *buffer) -{ - return store_column(&value, sizeof (double)); -} - - -/* Store a Field. */ - -bool Protocol_local::store(Field *field) -{ - if (field->is_null()) - return store_null(); - return field->send_binary(this); -} - - -/** Called to start a new result set. */ - -bool Protocol_local::send_result_set_metadata(List<Item> *columns, uint) -{ - DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root)); - - init_sql_alloc(&m_rset_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); - - if (! (m_rset= new (&m_rset_root) List<Ed_row>)) - return TRUE; - - m_column_count= columns->elements; - - return FALSE; -} - - -/** - Normally this is a separate result set with OUT parameters - of stored procedures. Currently unsupported for the local - version. -*/ - -bool Protocol_local::send_out_parameters(List<Item_param> *sp_params) -{ - return FALSE; -} - - -/** Called for statements that don't have a result set, at statement end. */ - -bool -Protocol_local::send_ok(uint server_status, uint statement_warn_count, - ulonglong affected_rows, ulonglong last_insert_id, - const char *message, bool skip_flush) -{ - /* - Just make sure nothing is sent to the client, we have grabbed - the status information in the connection diagnostics area. - */ - return FALSE; -} - - -/** - Called at the end of a result set. Append a complete - result set to the list in Ed_connection. - - Don't send anything to the client, but instead finish - building of the result set at hand. -*/ - -bool Protocol_local::send_eof(uint server_status, uint statement_warn_count) -{ - Ed_result_set *ed_result_set; - - DBUG_ASSERT(m_rset); - - opt_add_row_to_rset(); - m_current_row= 0; - - ed_result_set= new (&m_rset_root) Ed_result_set(m_rset, m_column_count, - &m_rset_root); - - m_rset= NULL; - - if (! ed_result_set) - return TRUE; - - /* In case of successful allocation memory ownership was transferred. */ - DBUG_ASSERT(!alloc_root_inited(&m_rset_root)); - - /* - Link the created Ed_result_set instance into the list of connection - result sets. Never fails. - */ - m_connection->add_result_set(ed_result_set); - return FALSE; -} - - -/** Called to send an error to the client at the end of a statement. */ - -bool -Protocol_local::send_error(uint sql_errno, const char *err_msg, const char*) -{ - /* - Just make sure that nothing is sent to the client (default - implementation). - */ - return FALSE; -} - - -#ifdef EMBEDDED_LIBRARY -void Protocol_local::remove_last_row() -{ } -#endif diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index ebadafd2d2e..1d39b544c87 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -86,284 +86,5 @@ void reinit_stmt_before_use(THD *thd, LEX *lex); my_bool bulk_parameters_iterations(THD *thd); my_bool bulk_parameters_set(THD *thd); -/** - Execute a fragment of server code in an isolated context, so that - it doesn't leave any effect on THD. THD must have no open tables. - The code must not leave any open tables around. - The result of execution (if any) is stored in Ed_result. -*/ - -class Server_runnable -{ -public: - virtual bool execute_server_code(THD *thd)= 0; - virtual ~Server_runnable(); -}; - - -/** - Execute direct interface. - - @todo Implement support for prelocked mode. -*/ - -class Ed_row; - -/** - Ed_result_set -- a container with result set rows. - @todo Implement support for result set metadata and - automatic type conversion. -*/ - -class Ed_result_set: public Sql_alloc -{ -public: - operator List<Ed_row>&() { return *m_rows; } - unsigned int size() const { return m_rows->elements; } - - Ed_result_set(List<Ed_row> *rows_arg, size_t column_count, - MEM_ROOT *mem_root_arg); - - /** We don't call member destructors, they all are POD types. */ - ~Ed_result_set() {} - - size_t get_field_count() const { return m_column_count; } - - static void operator delete(void *ptr, size_t size) throw (); -private: - Ed_result_set(const Ed_result_set &); /* not implemented */ - Ed_result_set &operator=(Ed_result_set &); /* not implemented */ -private: - MEM_ROOT m_mem_root; - size_t m_column_count; - List<Ed_row> *m_rows; - Ed_result_set *m_next_rset; - friend class Ed_connection; -}; - - -class Ed_connection -{ -public: - /** - Construct a new "execute direct" connection. - - The connection can be used to execute SQL statements. - If the connection failed to initialize, the error - will be returned on the attempt to execute a statement. - - @pre thd must have no open tables - while the connection is used. However, - Ed_connection works okay in LOCK TABLES mode. - Other properties of THD, such as the current warning - information, errors, etc. do not matter and are - preserved by Ed_connection. One thread may have many - Ed_connections created for it. - */ - Ed_connection(THD *thd); - - /** - Execute one SQL statement. - - Until this method is executed, no other methods of - Ed_connection can be used. Life cycle of Ed_connection is: - - Initialized -> a statement has been executed -> - look at result, move to next result -> - look at result, move to next result -> - ... - moved beyond the last result == Initialized. - - This method can be called repeatedly. Once it's invoked, - results of the previous execution are lost. - - A result of execute_direct() can be either: - - - success, no result set rows. In this case get_field_count() - returns 0. This happens after execution of INSERT, UPDATE, - DELETE, DROP and similar statements. Some other methods, such - as get_affected_rows() can be used to retrieve additional - result information. - - - success, there are some result set rows (maybe 0). E.g. - happens after SELECT. In this case get_field_count() returns - the number of columns in a result set and store_result() - can be used to retrieve a result set.. - - - an error, methods to retrieve error information can - be used. - - @return execution status - @retval FALSE success, use get_field_count() - to determine what to do next. - @retval TRUE error, use get_last_error() - to see the error number. - */ - bool execute_direct(LEX_STRING sql_text); - - /** - Same as the previous, but takes an instance of Server_runnable - instead of SQL statement text. - - @return execution status - - @retval FALSE success, use get_field_count() - if your code fragment is supposed to - return a result set - @retval TRUE failure - */ - bool execute_direct(Server_runnable *server_runnable); - - /** - Get the number of result set fields. - - This method is valid only if we have a result: - execute_direct() has been called. Otherwise - the returned value is undefined. - - @sa Documentation for C API function - mysql_field_count() - */ - ulong get_field_count() const - { - return m_current_rset ? m_current_rset->get_field_count() : 0; - } - - /** - Get the number of affected (deleted, updated) - rows for the current statement. Can be - used for statements with get_field_count() == 0. - - @sa Documentation for C API function - mysql_affected_rows(). - */ - ulonglong get_affected_rows() const - { - return m_diagnostics_area.affected_rows(); - } - - /** - Get the last insert id, if any. - - @sa Documentation for mysql_insert_id(). - */ - ulonglong get_last_insert_id() const - { - return m_diagnostics_area.last_insert_id(); - } - - /** - Get the total number of warnings for the last executed - statement. Note, that there is only one warning list even - if a statement returns multiple results. - - @sa Documentation for C API function - mysql_num_warnings(). - */ - ulong get_warn_count() const - { - return m_diagnostics_area.warn_count(); - } - - /** - The following members are only valid if execute_direct() - or move_to_next_result() returned an error. - They never fail, but if they are called when there is no - result, or no error, the result is not defined. - */ - const char *get_last_error() const { return m_diagnostics_area.message(); } - unsigned int get_last_errno() const { return m_diagnostics_area.sql_errno(); } - const char *get_last_sqlstate() const { return m_diagnostics_area.get_sqlstate(); } - - /** - Provided get_field_count() is not 0, this never fails. You don't - need to free the result set, this is done automatically when - you advance to the next result set or destroy the connection. - Not returning const because of List iterator not accepting - Should be used when you would like Ed_connection to manage - result set memory for you. - */ - Ed_result_set *use_result_set() { return m_current_rset; } - /** - Provided get_field_count() is not 0, this never fails. You - must free the returned result set. This can be called only - once after execute_direct(). - Should be used when you would like to get the results - and destroy the connection. - */ - Ed_result_set *store_result_set(); - - /** - If the query returns multiple results, this method - can be checked if there is another result beyond the next - one. - Never fails. - */ - bool has_next_result() const { return MY_TEST(m_current_rset->m_next_rset); } - /** - Only valid to call if has_next_result() returned true. - Otherwise the result is undefined. - */ - bool move_to_next_result() - { - m_current_rset= m_current_rset->m_next_rset; - return MY_TEST(m_current_rset); - } - - ~Ed_connection() { free_old_result(); } -private: - Diagnostics_area m_diagnostics_area; - /** - Execute direct interface does not support multi-statements, only - multi-results. So we never have a situation when we have - a mix of result sets and OK or error packets. We either - have a single result set, a single error, or a single OK, - or we have a series of result sets, followed by an OK or error. - */ - THD *m_thd; - Ed_result_set *m_rsets; - Ed_result_set *m_current_rset; - friend class Protocol_local; -private: - void free_old_result(); - void add_result_set(Ed_result_set *ed_result_set); -private: - Ed_connection(const Ed_connection &); /* not implemented */ - Ed_connection &operator=(Ed_connection &); /* not implemented */ -}; - - -/** One result set column. */ - -struct Ed_column: public LEX_STRING -{ - /** Implementation note: destructor for this class is never called. */ -}; - - -/** One result set record. */ - -class Ed_row: public Sql_alloc -{ -public: - const Ed_column &operator[](const unsigned int column_index) const - { - return *get_column(column_index); - } - const Ed_column *get_column(const unsigned int column_index) const - { - DBUG_ASSERT(column_index < size()); - return m_column_array + column_index; - } - size_t size() const { return m_column_count; } - - Ed_row(Ed_column *column_array_arg, size_t column_count_arg) - :m_column_array(column_array_arg), - m_column_count(column_count_arg) - {} -private: - Ed_column *m_column_array; - size_t m_column_count; /* TODO: change to point to metadata */ -}; #endif // SQL_PREPARE_H |