summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-07-07 17:27:34 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-07-07 17:29:40 +0300
commitd3e44d37b8d9924ed6d96e6984ddad49e9cf39fd (patch)
treef03279bb58d8eed25a383176089b7682afb1321e
parent0ba528fe56f6c637d9fbc9d177a62610038fd519 (diff)
downloadmariadb-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.cc743
-rw-r--r--sql/sql_prepare.h279
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