summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2007-10-16 15:37:31 -0400
committerunknown <cmiller@zippy.cornsilk.net>2007-10-16 15:37:31 -0400
commit4a0ec7864ea5c97bb51954c26674f1b6db04b13f (patch)
tree4acbb9810f77d631511db02c68f5b04305b106c7 /sql
parent12796f0291846a169aee61ec86bb5bf16bf5ff63 (diff)
downloadmariadb-git-4a0ec7864ea5c97bb51954c26674f1b6db04b13f.tar.gz
Doxygenized comments.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_base.cc30
-rw-r--r--sql/sql_cache.cc22
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_cursor.cc78
-rw-r--r--sql/sql_parse.cc812
-rw-r--r--sql/sql_prepare.cc600
-rw-r--r--sql/sql_select.cc2412
-rw-r--r--sql/sql_trigger.cc361
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_view.cc2
10 files changed, 2158 insertions, 2163 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 337fde53dac..bf6c7ebaf92 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1817,8 +1817,8 @@ static void relink_unused(TABLE *table)
/**
- @brief Remove all instances of table from thread's open list and
- table cache.
+ Remove all instances of table from thread's open list and
+ table cache.
@param thd Thread context
@param find Table to remove
@@ -1867,7 +1867,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
/**
- @brief Auxiliary routine which closes and drops open table.
+ Auxiliary routine which closes and drops open table.
@param thd Thread handle
@param table TABLE object for table to be dropped
@@ -2039,9 +2039,9 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
/**
- @brief Create and insert into table cache placeholder for table
- which will prevent its opening (or creation) (a.k.a lock
- table name).
+ Create and insert into table cache placeholder for table
+ which will prevent its opening (or creation) (a.k.a lock
+ table name).
@param thd Thread context
@param key Table cache key for name to be locked
@@ -2090,8 +2090,8 @@ TABLE *table_cache_insert_placeholder(THD *thd, const char *key,
/**
- @brief Obtain an exclusive name lock on the table if it is not cached
- in the table cache.
+ Obtain an exclusive name lock on the table if it is not cached
+ in the table cache.
@param thd Thread context
@param db Name of database
@@ -2142,8 +2142,8 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db,
/**
- @brief Check that table exists in table definition cache, on disk
- or in some storage engine.
+ Check that table exists in table definition cache, on disk
+ or in some storage engine.
@param thd Thread context
@param table Table list element
@@ -2815,8 +2815,8 @@ bool reopen_table(TABLE *table)
/**
- @brief Close all instances of a table open by this thread and replace
- them with exclusive name-locks.
+ Close all instances of a table open by this thread and replace
+ them with exclusive name-locks.
@param thd Thread context
@param db Database name for the table to be closed
@@ -2867,7 +2867,7 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
/**
- @brief Reopen all tables with closed data files.
+ Reopen all tables with closed data files.
@param thd Thread context
@param get_locks Should we get locks after reopening tables ?
@@ -2957,8 +2957,8 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
/**
- @brief Close handlers for tables in list, but leave the TABLE structure
- intact so that we can re-open these quickly.
+ Close handlers for tables in list, but leave the TABLE structure
+ intact so that we can re-open these quickly.
@param thd Thread context
@param table Head of the list of TABLE objects
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index ada927fa467..ed28ca35628 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1524,7 +1524,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
/**
- @brief Synchronize the thread with any flushing operations.
+ Synchronize the thread with any flushing operations.
This helper function is called whenever a thread needs to operate on the
query cache structure (example: during invalidation). If a table flush is in
@@ -1565,7 +1565,7 @@ void Query_cache::wait_while_table_flush_is_in_progress(bool *interrupt)
/**
- @brief Remove all cached queries that uses the given database
+ Remove all cached queries that uses the given database.
*/
void Query_cache::invalidate(char *db)
@@ -1675,8 +1675,8 @@ void Query_cache::flush()
/**
- @brief Rearrange the memory blocks and join result in cache in 1 block (if
- result length > join_limit)
+ Rearrange the memory blocks and join result in cache in 1 block (if
+ result length > join_limit)
@param[in] join_limit If the minimum length of a result block to be joined.
@param[in] iteration_limit The maximum number of packing and joining
@@ -1946,7 +1946,7 @@ void Query_cache::make_disabled()
/**
@class Query_cache
- @brief Free all resources allocated by the cache.
+ Free all resources allocated by the cache.
This function frees all resources allocated by the cache. You
have to call init_cache() before using the cache again. This function
@@ -1970,7 +1970,7 @@ void Query_cache::free_cache()
/**
- @brief Flush the cache.
+ Flush the cache.
This function will flush cache contents. It assumes we have
'structure_guard_mutex' locked. The function sets the m_cache_status flag and
@@ -2516,7 +2516,7 @@ Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
}
/**
- @brief Invalidate a linked list of query cache blocks.
+ Invalidate a linked list of query cache blocks.
Each block tries to aquire a block level lock before
free_query is a called. This function will in turn affect
@@ -2684,7 +2684,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
/**
- @brief Insert used table name into the cache.
+ Insert used table name into the cache.
@return Error status
@retval FALSE On error
@@ -3413,8 +3413,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
/**
- @brief Rearrange all memory blocks so that free memory joins at the
- 'bottom' of the allocated memory block containing all cache data.
+ Rearrange all memory blocks so that free memory joins at the
+ 'bottom' of the allocated memory block containing all cache data.
@see Query_cache::pack(ulong join_limit, uint iteration_limit)
*/
@@ -4028,7 +4028,7 @@ void Query_cache::tables_dump()
/**
- @brief Checks integrity of the various linked lists
+ Checks integrity of the various linked lists
@return Error status code
@retval FALSE Query cache is operational.
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 66a51d5bb00..df14e94850c 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -934,7 +934,7 @@ void THD::cleanup_after_query()
/**
- Create a LEX_STRING in this connection
+ Create a LEX_STRING in this connection.
@param lex_str pointer to LEX_STRING object to be initialized
@param str initializer to be copied into lex_str
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index d31c0af1163..2301b561797 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -24,9 +24,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.
@@ -69,7 +69,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
@@ -96,7 +96,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
@@ -107,7 +107,7 @@ 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:
Select_materialize(select_result *result_arg) :result(result_arg) {}
virtual bool send_fields(List<Item> &list, uint flags);
@@ -116,22 +116,21 @@ public:
/**************************************************************************/
-/*
+/**
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,
@@ -279,6 +278,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)
{
@@ -334,6 +341,10 @@ Sensitive_cursor::post_open(THD *thd)
}
+/**
+ bzero cursor state in THD.
+*/
+
void
Sensitive_cursor::reset_thd(THD *thd)
{
@@ -393,20 +404,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
@@ -478,6 +482,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()
{
@@ -579,10 +588,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
@@ -590,10 +598,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)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ae347bebb47..26055731547 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -158,8 +158,8 @@ bool begin_trans(THD *thd)
}
#ifdef HAVE_REPLICATION
-/*
- Returns true if all tables should be ignored
+/**
+ Returns true if all tables should be ignored.
*/
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
@@ -182,9 +182,10 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
}
-/*
- Mark all commands that somehow changes a table
- This is used to check number of updates / hour
+/**
+ Mark all commands that somehow changes a table.
+
+ This is used to check number of updates / hour.
sql_command is actually set to SQLCOM_END sometimes
so we need the +1 to include it in the array.
@@ -339,9 +340,10 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
}
-/*
+/**
Execute commands from bootstrap_file.
- Used when creating the initial grant tables
+
+ Used when creating the initial grant tables.
*/
pthread_handler_t handle_bootstrap(void *arg)
@@ -495,21 +497,20 @@ void cleanup_items(Item *item)
DBUG_VOID_RETURN;
}
-/*
- Handle COM_TABLE_DUMP command
+/**
+ Handle COM_TABLE_DUMP command.
- SYNOPSIS
- mysql_table_dump
- thd thread handle
- db database name or an empty string. If empty,
- the current database of the connection is used
- tbl_name name of the table to dump
+ @param thd thread handle
+ @param db database name or an empty string. If empty,
+ the current database of the connection is used
+ @param tbl_name name of the table to dump
- NOTES
+ @note
This function is written to handle one specific command only.
- RETURN VALUE
+ @retval
0 success
+ @retval
1 error, the error message is set in THD
*/
@@ -563,16 +564,14 @@ err:
DBUG_RETURN(error);
}
-/*
- Ends the current transaction and (maybe) begin the next
+/**
+ Ends the current transaction and (maybe) begin the next.
- SYNOPSIS
- end_trans()
- thd Current thread
- completion Completion type
+ @param thd Current thread
+ @param completion Completion type
- RETURN
- 0 - OK
+ @retval
+ 0 OK
*/
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
@@ -641,13 +640,12 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
#ifndef EMBEDDED_LIBRARY
-/*
+/**
Read one command from connection and execute it (query or simple command).
This function is called in loop from thread function.
- SYNOPSIS
- do_command()
- RETURN VALUE
+ @retval
0 success
+ @retval
1 request of thread shutdown (see dispatch_command() description)
*/
@@ -719,21 +717,25 @@ bool do_command(THD *thd)
#endif /* EMBEDDED_LIBRARY */
-/*
- Perform one connection-level (COM_XXXX) command.
+/**
+ Perform one connection-level (COM_XXXX) command.
- SYNOPSIS
- dispatch_command()
- thd connection handle
- command type of command to perform
- packet data for the command, packet is always null-terminated
- packet_length length of packet + 1 (to show that data is
- null-terminated) except for COM_SLEEP, where it
- can be zero.
- RETURN VALUE
+ @param command type of command to perform
+ @param thd connection handle
+ @param packet data for the command, packet is always null-terminated
+ @param packet_length length of packet + 1 (to show that data is
+ null-terminated) except for COM_SLEEP, where it
+ can be zero.
+
+ @todo
+ - TODO: set thd->lex->sql_command to SQLCOM_END here
+ - TODO: The following has to be changed to an 8 byte integer
+
+ @retval
0 ok
+ @retval
1 request of thread shutdown, i. e. if command is
- COM_QUIT/COM_SHUTDOWN
+ COM_QUIT/COM_SHUTDOWN
*/
bool dispatch_command(enum enum_server_command command, THD *thd,
@@ -1380,32 +1382,30 @@ void log_slow_statement(THD *thd)
}
-/*
+/**
Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
- SYNOPSIS
- prepare_schema_table()
- thd thread handle
- lex current lex
- table_ident table alias if it's used
- schema_table_idx the type of the INFORMATION_SCHEMA table to be
- created
-
- DESCRIPTION
This function is used in the parser to convert a SHOW or DESCRIBE
table_name command to a SELECT from INFORMATION_SCHEMA.
It prepares a SELECT_LEX and a TABLE_LIST object to represent the
given command as a SELECT parse tree.
- NOTES
+ @param thd thread handle
+ @param lex current lex
+ @param table_ident table alias if it's used
+ @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
+ created
+
+ @note
Due to the way this function works with memory and LEX it cannot
be used outside the parser (parse tree transformations outside
the parser break PS and SP).
- RETURN VALUE
+ @retval
0 success
+ @retval
1 out of memory or SHOW commands are not allowed
- in this version of the server.
+ in this version of the server.
*/
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
@@ -1505,17 +1505,17 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
}
-/*
- Read query from packet and store in thd->query
- Used in COM_QUERY and COM_STMT_PREPARE
+/**
+ Read query from packet and store in thd->query.
+ Used in COM_QUERY and COM_STMT_PREPARE.
- DESCRIPTION
- Sets the following THD variables:
- query
- query_length
+ Sets the following THD variables:
+ - query
+ - query_length
- RETURN VALUES
+ @retval
FALSE ok
+ @retval
TRUE error; In this case thd->fatal_error is set
*/
@@ -1655,14 +1655,8 @@ bool sp_process_definer(THD *thd)
}
-/*
- Execute command saved in thd and lex->sql_command
-
- SYNOPSIS
- mysql_execute_command()
- thd Thread handle
-
- IMPLEMENTATION
+/**
+ Execute command saved in thd and lex->sql_command.
Before every operation that can request a write lock for a table
wait if a global read lock exists. However do not wait if this
@@ -1674,8 +1668,20 @@ bool sp_process_definer(THD *thd)
global read lock when it succeeds. This needs to be released by
start_waiting_global_read_lock() after the operation.
- RETURN
+ @param thd Thread handle
+
+ @todo
+ - Invalidate the table in the query cache if something changed
+ after unlocking when changes become visible.
+ TODO: this is workaround. right way will be move invalidating in
+ the unlock procedure.
+ - TODO: use check_change_password()
+ - JOIN is not supported yet. TODO
+ - SUSPEND and FOR MIGRATE are not supported yet. TODO
+
+ @retval
FALSE OK
+ @retval
TRUE Error
*/
@@ -4555,20 +4561,19 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
-/*
+/**
Check grants for commands which work only with one table.
- SYNOPSIS
- check_single_table_access()
- thd Thread handler
- privilege requested privilege
- all_tables global table list of query
- no_errors FALSE/TRUE - report/don't report error to
- the client (using my_error() call).
+ @param thd Thread handler
+ @param privilege requested privilege
+ @param all_tables global table list of query
+ @param no_errors FALSE/TRUE - report/don't report error to
+ the client (using my_error() call).
- RETURN
- 0 - OK
- 1 - access denied, error is sent to client
+ @retval
+ 0 OK
+ @retval
+ 1 access denied, error is sent to client
*/
bool check_single_table_access(THD *thd, ulong privilege,
@@ -4606,19 +4611,18 @@ deny:
return 1;
}
-/*
+/**
Check grants for commands which work only with one table and all other
tables belonging to subselects or implicitly opened tables.
- SYNOPSIS
- check_one_table_access()
- thd Thread handler
- privilege requested privilege
- all_tables global table list of query
+ @param thd Thread handler
+ @param privilege requested privilege
+ @param all_tables global table list of query
- RETURN
- 0 - OK
- 1 - access denied, error is sent to client
+ @retval
+ 0 OK
+ @retval
+ 1 access denied, error is sent to client
*/
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
@@ -4648,25 +4652,26 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
}
-/****************************************************************************
- Get the user (global) and database privileges for all used tables
+/**
+ Get the user (global) and database privileges for all used tables.
+
+ @param save_priv In this we store global and db level grants for the
+ table. Note that we don't store db level grants if the
+ global grants is enough to satisfy the request and the
+ global grants contains a SELECT grant.
- NOTES
+ @note
The idea of EXTRA_ACL is that one will be granted access to the table if
one has the asked privilege on any column combination of the table; For
example to be able to check a table one needs to have SELECT privilege on
any column of the table.
- RETURN
+ @retval
0 ok
- 1 If we can't get the privileges and we don't use table/column grants.
-
- save_priv In this we store global and db level grants for the table
- Note that we don't store db level grants if the global grants
- is enough to satisfy the request and the global grants contains
- a SELECT grant.
-****************************************************************************/
-
+ @retval
+ 1 If we can't get the privileges and we don't use table/column
+ grants.
+*/
bool
check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors, bool schema_db)
@@ -4788,22 +4793,21 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
}
-/*
- check for global access and give descriptive error message if it fails
+/**
+ check for global access and give descriptive error message if it fails.
- SYNOPSIS
- check_global_access()
- thd Thread handler
- want_access Use should have any of these global rights
+ @param thd Thread handler
+ @param want_access Use should have any of these global rights
- WARNING
- One gets access right if one has ANY of the rights in want_access
+ @warning
+ One gets access right if one has ANY of the rights in want_access.
This is useful as one in most cases only need one global right,
but in some case we want to check if the user has SUPER or
REPL_CLIENT_ACL rights.
- RETURN
+ @retval
0 ok
+ @retval
1 Access denied. In this case an error is sent to the client
*/
@@ -4881,27 +4885,26 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
}
-/*
+/**
Check the privilege for all used tables.
- SYNOPSYS
- check_table_access()
- thd Thread context
- want_access Privileges requested
- tables List of tables to be checked
- no_errors FALSE/TRUE - report/don't report error to
- the client (using my_error() call).
+ @param thd Thread context
+ @param want_access Privileges requested
+ @param tables List of tables to be checked
+ @param no_errors FALSE/TRUE - report/don't report error to
+ the client (using my_error() call).
- NOTES
+ @note
Table privileges are cached in the table list for GRANT checking.
This functions assumes that table list used and
thd->lex->query_tables_own_last value correspond to each other
(the latter should be either 0 or point to next_global member
of one of elements of this table list).
- RETURN VALUE
- FALSE - OK
- TRUE - Access denied
+ @retval
+ FALSE OK
+ @retval
+ TRUE Access denied
*/
bool
@@ -5005,17 +5008,16 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
}
-/*
- Check if the routine has any of the routine privileges
+/**
+ Check if the routine has any of the routine privileges.
- SYNOPSIS
- check_some_routine_access()
- thd Thread handler
- db Database name
- name Routine name
+ @param thd Thread handler
+ @param db Database name
+ @param name Routine name
- RETURN
+ @retval
0 ok
+ @retval
1 error
*/
@@ -5039,17 +5041,15 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name,
/*
Check if the given table has any of the asked privileges
- SYNOPSIS
- check_some_access()
- thd Thread handler
- want_access Bitmap of possible privileges to check for
+ @param thd Thread handler
+ @param want_access Bitmap of possible privileges to check for
- RETURN
+ @retval
0 ok
+ @retval
1 error
*/
-
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
{
ulong access;
@@ -5108,12 +5108,13 @@ bool check_merge_table_access(THD *thd, char *db,
long max_stack_used;
#endif
-/*
+/**
+ @note
Note: The 'buf' parameter is necessary, even if it is unused here.
- fix_fields functions has a "dummy" buffer large enough for the
corresponding exec. (Thus we only have to check in fix_fields.)
- Passing to check_stack_overrun() prevents the compiler from removing it.
- */
+*/
bool check_stack_overrun(THD *thd, long margin,
uchar *buf __attribute__((unused)))
{
@@ -5167,17 +5168,17 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
}
-/*
- Reset THD part responsible for command processing state.
+/**
+ Reset THD part responsible for command processing state.
- DESCRIPTION
- This needs to be called before execution of every statement
- (prepared or conventional).
- It is not called by substatements of routines.
+ This needs to be called before execution of every statement
+ (prepared or conventional).
+ It is not called by substatements of routines.
- TODO
+ @todo
Make it a method of THD and align its name with the rest of
reset/end/start/init methods.
+ @todo
Call it after we use THD for queries, not before.
*/
@@ -5322,17 +5323,14 @@ mysql_new_select(LEX *lex, bool move_down)
DBUG_RETURN(0);
}
-/*
+/**
Create a select to return the same output as 'SELECT @@var_name'.
- SYNOPSIS
- create_select_for_variable()
- var_name Variable name
+ Used for SHOW COUNT(*) [ WARNINGS | ERROR].
- DESCRIPTION
- Used for SHOW COUNT(*) [ WARNINGS | ERROR]
+ This will crash with a core dump if the variable doesn't exists.
- This will crash with a core dump if the variable doesn't exists
+ @param var_name Variable name
*/
void create_select_for_variable(const char *var_name)
@@ -5498,8 +5496,9 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
Usable by the replication SQL thread only: just parse a query to know if it
can be ignored because of replicate-*-table rules.
- RETURN VALUES
+ @retval
0 cannot be ignored
+ @retval
1 can be ignored
*/
@@ -5524,10 +5523,12 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
-/*****************************************************************************
-** Store field definition for create
-** Return 0 if ok
-******************************************************************************/
+/**
+ Store field definition for create.
+
+ @return
+ Return 0 if ok
+*/
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
char *length, char *decimals,
@@ -5631,7 +5632,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
}
-/* Store position for column in ALTER TABLE .. ADD column */
+/** Store position for column in ALTER TABLE .. ADD column. */
void store_position_for_column(const char *name)
{
@@ -5655,10 +5656,9 @@ add_proc_to_list(THD* thd, Item *item)
}
-/****************************************************************************
-** save order by and tables in own lists
-****************************************************************************/
-
+/**
+ save order by and tables in own lists.
+*/
bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
{
@@ -5677,24 +5677,23 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
}
-/*
- Add a table to list of used tables
-
- SYNOPSIS
- add_table_to_list()
- table Table to add
- alias alias for table (or null if no alias)
- table_options A set of the following bits:
- TL_OPTION_UPDATING Table will be updated
- TL_OPTION_FORCE_INDEX Force usage of index
- TL_OPTION_ALIAS an alias in multi table DELETE
- lock_type How table should be locked
- use_index List of indexed used in USE INDEX
- ignore_index List of indexed used in IGNORE INDEX
-
- RETURN
- 0 Error
- # Pointer to TABLE_LIST element added to the total table list
+/**
+ Add a table to list of used tables.
+
+ @param table Table to add
+ @param alias alias for table (or null if no alias)
+ @param table_options A set of the following bits:
+ - TL_OPTION_UPDATING : Table will be updated
+ - TL_OPTION_FORCE_INDEX : Force usage of index
+ - TL_OPTION_ALIAS : an alias in multi table DELETE
+ @param lock_type How table should be locked
+ @param use_index List of indexed used in USE INDEX
+ @param ignore_index List of indexed used in IGNORE INDEX
+
+ @retval
+ 0 Error
+ @retval
+ \# Pointer to TABLE_LIST element added to the total table list
*/
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
@@ -5832,14 +5831,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
}
-/*
- Initialize a new table list for a nested join
-
- SYNOPSIS
- init_nested_join()
- thd current thread
+/**
+ Initialize a new table list for a nested join.
- DESCRIPTION
The function initializes a structure of the TABLE_LIST type
for a nested join. It sets up its nested join list as empty.
The created structure is added to the front of the current
@@ -5848,9 +5842,12 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
created empty list after having saved the info on the old level
in the initialized structure.
- RETURN VALUE
- 0, if success
- 1, otherwise
+ @param thd current thread
+
+ @retval
+ 0 if success
+ @retval
+ 1 otherwise
*/
bool st_select_lex::init_nested_join(THD *thd)
@@ -5876,21 +5873,18 @@ bool st_select_lex::init_nested_join(THD *thd)
}
-/*
- End a nested join table list
-
- SYNOPSIS
- end_nested_join()
- thd current thread
+/**
+ End a nested join table list.
- DESCRIPTION
The function returns to the previous join nest level.
If the current level contains only one member, the function
moves it one level up, eliminating the nest.
- RETURN VALUE
- Pointer to TABLE_LIST element added to the total table list, if success
- 0, otherwise
+ @param thd current thread
+
+ @return
+ - Pointer to TABLE_LIST element added to the total table list, if success
+ - 0, otherwise
*/
TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
@@ -5922,20 +5916,17 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
}
-/*
- Nest last join operation
+/**
+ Nest last join operation.
- SYNOPSIS
- nest_last_join()
- thd current thread
+ The function nest last join operation as if it was enclosed in braces.
- DESCRIPTION
- The function nest last join operation as if it was enclosed in braces.
+ @param thd current thread
- RETURN VALUE
+ @retval
0 Error
- # Pointer to TABLE_LIST element created for the new nested join
-
+ @retval
+ \# Pointer to TABLE_LIST element created for the new nested join
*/
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
@@ -5980,20 +5971,17 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
}
-/*
- Add a table to the current join list
-
- SYNOPSIS
- add_joined_table()
- table the table to add
+/**
+ Add a table to the current join list.
- DESCRIPTION
The function puts a table in front of the current join list
of st_select_lex object.
Thus, joined tables are put into this list in the reverse order
(the most outer join operation follows first).
- RETURN VALUE
+ @param table the table to add
+
+ @return
None
*/
@@ -6007,14 +5995,9 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
}
-/*
- Convert a right join into equivalent left join
-
- SYNOPSIS
- convert_right_join()
- thd current thread
+/**
+ Convert a right join into equivalent left join.
- DESCRIPTION
The function takes the current join list t[0],t[1] ... and
effectively converts it into the list t[1],t[0] ...
Although the outer_join flag for the new nested table contains
@@ -6022,21 +6005,25 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
operation.
EXAMPLES
- SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
- SELECT * FROM t2 LEFT JOIN t1 ON on_expr
+ @verbatim
+ SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
+ SELECT * FROM t2 LEFT JOIN t1 ON on_expr
- SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
- SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
+ SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
+ SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
- SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
- SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
+ SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
+ SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
- SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
- SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
+ SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
+ SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
+ @endverbatim
- RETURN
- Pointer to the table representing the inner table, if success
- 0, otherwise
+ @param thd current thread
+
+ @return
+ - Pointer to the table representing the inner table, if success
+ - 0, otherwise
*/
TABLE_LIST *st_select_lex::convert_right_join()
@@ -6052,14 +6039,12 @@ TABLE_LIST *st_select_lex::convert_right_join()
DBUG_RETURN(tab1);
}
-/*
- Set lock for all tables in current select level
+/**
+ Set lock for all tables in current select level.
- SYNOPSIS:
- set_lock_for_tables()
- lock_type Lock to set for tables
+ @param lock_type Lock to set for tables
- NOTE:
+ @note
If lock is a write lock, then tables->updating is set 1
This is to get tables_ok to know that the table is updated by the
query
@@ -6083,27 +6068,29 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
}
-/*
- Create a fake SELECT_LEX for a unit
-
- SYNOPSIS:
- add_fake_select_lex()
- thd thread handle
+/**
+ Create a fake SELECT_LEX for a unit.
- DESCRIPTION
The method create a fake SELECT_LEX object for a unit.
This object is created for any union construct containing a union
operation and also for any single select union construct of the form
+ @verbatim
(SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
+ @endvarbatim
or of the form
+ @varbatim
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
-
- NOTES
+ @endvarbatim
+
+ @param thd_arg thread handle
+
+ @note
The object is used to retrieve rows from the temporary table
where the result on the union is obtained.
- RETURN VALUES
+ @retval
1 on failure to create the object
+ @retval
0 on success
*/
@@ -6145,24 +6132,22 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
}
-/*
+/**
Push a new name resolution context for a JOIN ... ON clause to the
context stack of a query block.
- SYNOPSIS
- push_new_name_resolution_context()
- thd pointer to current thread
- left_op left operand of the JOIN
- right_op rigth operand of the JOIN
-
- DESCRIPTION
Create a new name resolution context for a JOIN ... ON clause,
set the first and last leaves of the list of table references
to be used for name resolution, and push the newly created
context to the stack of contexts of the query.
- RETURN
+ @param thd pointer to current thread
+ @param left_op left operand of the JOIN
+ @param right_op rigth operand of the JOIN
+
+ @retval
FALSE if all is OK
+ @retval
TRUE if a memory allocation error occured
*/
@@ -6182,19 +6167,17 @@ push_new_name_resolution_context(THD *thd,
}
-/*
+/**
Add an ON condition to the second operand of a JOIN ... ON.
- SYNOPSIS
- add_join_on
- b the second operand of a JOIN ... ON
- expr the condition to be added to the ON clause
+ Add an ON condition to the right operand of a JOIN ... ON clause.
- DESCRIPTION
- Add an ON condition to the right operand of a JOIN ... ON clause.
+ @param b the second operand of a JOIN ... ON
+ @param expr the condition to be added to the ON clause
- RETURN
+ @retval
FALSE if there was some error
+ @retval
TRUE if all is OK
*/
@@ -6218,18 +6201,10 @@ void add_join_on(TABLE_LIST *b, Item *expr)
}
-/*
+/**
Mark that there is a NATURAL JOIN or JOIN ... USING between two
tables.
- SYNOPSIS
- add_join_natural()
- a Left join argument
- b Right join argument
- using_fields Field names from USING clause
- lex The current st_select_lex
-
- IMPLEMENTATION
This function marks that table b should be joined with a either via
a NATURAL JOIN or via JOIN ... USING. Both join types are special
cases of each other, so we treat them together. The function
@@ -6240,20 +6215,23 @@ void add_join_on(TABLE_LIST *b, Item *expr)
was an outer join.
EXAMPLE
- SELECT * FROM t1 NATURAL LEFT JOIN t2
- <=>
- SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
-
- SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
- <=>
- SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
-
- SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
- <=>
- SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
-
- RETURN
- None
+ @verbatim
+ SELECT * FROM t1 NATURAL LEFT JOIN t2
+ <=>
+ SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
+
+ SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
+ <=>
+ SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
+
+ SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
+ <=>
+ SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
+ @endverbatim
+
+ @param a Left join argument
+ @param b Right join argument
+ @param using_fields Field names from USING clause
*/
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
@@ -6264,24 +6242,24 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
}
-/*
+/**
Reload/resets privileges and the different caches.
- SYNOPSIS
- reload_acl_and_cache()
- thd Thread handler (can be NULL!)
- options What should be reset/reloaded (tables, privileges,
- slave...)
- tables Tables to flush (if any)
- write_to_binlog Depending on 'options', it may be very bad to write the
- query to the binlog (e.g. FLUSH SLAVE); this is a
- pointer where reload_acl_and_cache() will put 0 if
- it thinks we really should not write to the binlog.
- Otherwise it will put 1.
-
- RETURN
+ @param thd Thread handler (can be NULL!)
+ @param options What should be reset/reloaded (tables, privileges,
+ slave...)
+ @param tables Tables to flush (if any)
+ @param write_to_binlog Depending on 'options', it may be very bad to
+ write the query to the binlog (e.g. FLUSH SLAVE);
+ this is a pointer where reload_acl_and_cache()
+ will put 0 if it thinks we really should not write
+ to the binlog.
+ Otherwise it will put 1.
+
+ @retval
0 ok
- !=0 error. thd->killed or thd->net.report_error is set
+ @retval
+ !=0 error. thd->killed or thd->net.report_error is set
*/
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
@@ -6454,16 +6432,14 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
-/*
- kills a thread
+/**
+ kill on thread.
- SYNOPSIS
- kill_one_thread()
- thd Thread class
- id Thread id
- only_kill_query Should it kill the query or the connection
+ @param thd Thread class
+ @param id Thread id
+ @param only_kill_query Should it kill the query or the connection
- NOTES
+ @note
This is written such that we have a short lock on LOCK_thread_count
*/
@@ -6523,7 +6499,7 @@ void sql_kill(THD *thd, ulong id, bool only_kill_query)
}
- /* If pointer is not a null pointer, append filename to it */
+/** If pointer is not a null pointer, append filename to it. */
bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name)
@@ -6550,14 +6526,12 @@ bool append_file_to_dir(THD *thd, const char **filename_ptr,
}
-/*
- Check if the select is a simple select (not an union)
-
- SYNOPSIS
- check_simple_select()
+/**
+ Check if the select is a simple select (not an union).
- RETURN VALUES
+ @retval
0 ok
+ @retval
1 error ; In this case the error messege is sent to the client
*/
@@ -6614,17 +6588,15 @@ Comp_creator *comp_ne_creator(bool invert)
}
-/*
- Construct ALL/ANY/SOME subquery Item
+/**
+ Construct ALL/ANY/SOME subquery Item.
- SYNOPSIS
- all_any_subquery_creator()
- left_expr - pointer to left expression
- cmp - compare function creator
- all - true if we create ALL subquery
- select_lex - pointer on parsed subquery structure
+ @param left_expr pointer to left expression
+ @param cmp compare function creator
+ @param all true if we create ALL subquery
+ @param select_lex pointer on parsed subquery structure
- RETURN VALUE
+ @return
constructed Item (or 0 if out of memory)
*/
Item * all_any_subquery_creator(Item *left_expr,
@@ -6647,16 +6619,15 @@ Item * all_any_subquery_creator(Item *left_expr,
}
-/*
- Multi update query pre-check
+/**
+ Multi update query pre-check.
- SYNOPSIS
- multi_update_precheck()
- thd Thread handler
- tables Global/local table list (have to be the same)
+ @param thd Thread handler
+ @param tables Global/local table list (have to be the same)
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE Error
*/
@@ -6724,16 +6695,15 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
DBUG_RETURN(FALSE);
}
-/*
- Multi delete query pre-check
+/**
+ Multi delete query pre-check.
- SYNOPSIS
- multi_delete_precheck()
- thd Thread handler
- tables Global/local table list
+ @param thd Thread handler
+ @param tables Global/local table list
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE error
*/
@@ -6773,17 +6743,16 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
}
-/*
+/**
Link tables in auxilary table list of multi-delete with corresponding
elements in main table list, and set proper locks for them.
- SYNOPSIS
- multi_delete_set_locks_and_link_aux_tables()
- lex - pointer to LEX representing multi-delete
+ @param lex pointer to LEX representing multi-delete
- RETURN VALUE
- FALSE - success
- TRUE - error
+ @retval
+ FALSE success
+ @retval
+ TRUE error
*/
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
@@ -6826,16 +6795,15 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
}
-/*
- simple UPDATE query pre-check
+/**
+ simple UPDATE query pre-check.
- SYNOPSIS
- update_precheck()
- thd Thread handler
- tables Global table list
+ @param thd Thread handler
+ @param tables Global table list
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE Error
*/
@@ -6851,16 +6819,15 @@ bool update_precheck(THD *thd, TABLE_LIST *tables)
}
-/*
- simple DELETE query pre-check
+/**
+ simple DELETE query pre-check.
- SYNOPSIS
- delete_precheck()
- thd Thread handler
- tables Global table list
+ @param thd Thread handler
+ @param tables Global table list
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE error
*/
@@ -6875,16 +6842,15 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables)
}
-/*
- simple INSERT query pre-check
+/**
+ simple INSERT query pre-check.
- SYNOPSIS
- insert_precheck()
- thd Thread handler
- tables Global table list
+ @param thd Thread handler
+ @param tables Global table list
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE error
*/
@@ -6932,17 +6898,16 @@ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
}
-/*
- CREATE TABLE query pre-check
+/**
+ CREATE TABLE query pre-check.
- SYNOPSIS
- create_table_precheck()
- thd Thread handler
- tables Global table list
- create_table Table which will be created
+ @param thd Thread handler
+ @param tables Global table list
+ @param create_table Table which will be created
- RETURN VALUE
+ @retval
FALSE OK
+ @retval
TRUE Error
*/
@@ -7008,15 +6973,13 @@ err:
}
-/*
- negate given expression
+/**
+ negate given expression.
- SYNOPSIS
- negate_expression()
- thd thread handler
- expr expression for negation
+ @param thd thread handler
+ @param expr expression for negation
- RETURN
+ @return
negated expression
*/
@@ -7043,14 +7006,12 @@ Item *negate_expression(THD *thd, Item *expr)
return new Item_func_not(expr);
}
-/*
- Set the specified definer to the default value, which is the current user in
- the thread.
-
- SYNOPSIS
- get_default_definer()
- thd [in] thread handler
- definer [out] definer
+/**
+ Set the specified definer to the default value, which is the
+ current user in the thread.
+
+ @param[in] thd thread handler
+ @param[out] definer definer
*/
void get_default_definer(THD *thd, LEX_USER *definer)
@@ -7065,17 +7026,15 @@ void get_default_definer(THD *thd, LEX_USER *definer)
}
-/*
+/**
Create default definer for the specified THD.
- SYNOPSIS
- create_default_definer()
- thd [in] thread handler
+ @param[in] thd thread handler
- RETURN
- On success, return a valid pointer to the created and initialized
+ @return
+ - On success, return a valid pointer to the created and initialized
LEX_USER, which contains definer information.
- On error, return 0.
+ - On error, return 0.
*/
LEX_USER *create_default_definer(THD *thd)
@@ -7091,19 +7050,17 @@ LEX_USER *create_default_definer(THD *thd)
}
-/*
+/**
Create definer with the given user and host names.
- SYNOPSIS
- create_definer()
- thd [in] thread handler
- user_name [in] user name
- host_name [in] host name
+ @param[in] thd thread handler
+ @param[in] user_name user name
+ @param[in] host_name host name
- RETURN
- On success, return a valid pointer to the created and initialized
+ @return
+ - On success, return a valid pointer to the created and initialized
LEX_USER, which contains definer information.
- On error, return 0.
+ - On error, return 0.
*/
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
@@ -7122,18 +7079,16 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
}
-/*
+/**
Retuns information about user or current user.
- SYNOPSIS
- get_current_user()
- thd [in] thread handler
- user [in] user
+ @param[in] thd thread handler
+ @param[in] user user
- RETURN
- On success, return a valid pointer to initialized
+ @return
+ - On success, return a valid pointer to initialized
LEX_USER, which contains user information.
- On error, return 0.
+ - On error, return 0.
*/
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
@@ -7145,17 +7100,16 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user)
}
-/*
+/**
Check that byte length of a string does not exceed some limit.
- SYNOPSIS
- check_string_byte_length()
- str string to be checked
- err_msg error message to be displayed if the string is too long
- max_byte_length max length in bytes
+ @param str string to be checked
+ @param err_msg error message to be displayed if the string is too long
+ @param max_length max length
- RETURN
+ @retval
FALSE the passed string is not longer than max_length
+ @retval
TRUE the passed string is longer than max_length
NOTE
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 9337a2aa329..fb657df54cd 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -13,7 +13,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/**********************************************************************
+/**
+ @file
+
This file contains the implementation of prepared statements.
When one prepares a statement:
@@ -28,11 +30,13 @@ When one prepares a statement:
- Without executing the query, return back to client the total
number of parameters along with result-set metadata information
(if any) in the following format:
+ @verbatim
[STMT_ID:4]
[Column_count:2]
[Param_count:2]
[Params meta info (stubs only for now)] (if Param_count > 0)
[Columns meta info] (if Column_count > 0)
+ @endverbatim
During prepare the tables used in a statement are opened, but no
locks are acquired. Table opening will block any DDL during the
@@ -45,12 +49,14 @@ When one executes a statement:
- Server gets the command 'COM_STMT_EXECUTE' to execute the
previously prepared query. If there are any parameter markers, then the
client will send the data in the following format:
+ @verbatim
[COM_STMT_EXECUTE:1]
[STMT_ID:4]
[NULL_BITS:(param_count+7)/8)]
[TYPES_SUPPLIED_BY_CLIENT(0/1):1]
[[length]data]
[[length]data] .. [[length]data].
+ @endverbatim
(Note: Except for string/binary types; all other types will not be
supplied with length field)
- If it is a first execute or types of parameters were altered by client,
@@ -75,8 +81,7 @@ When one supplies long data for a placeholder:
server doesn't care; also, the server doesn't notify the client whether
it got the data or not; if there is any error, then it will be returned
at statement execute.
-
-***********************************************************************/
+*/
#include "mysql_priv.h"
#include "sql_select.h" // for JOIN
@@ -91,7 +96,9 @@ When one supplies long data for a placeholder:
#include <mysql_com.h>
#endif
-/* A result class used to send cursor rows using the binary protocol. */
+/**
+ A result class used to send cursor rows using the binary protocol.
+*/
class Select_fetch_protocol_binary: public select_send
{
@@ -112,7 +119,7 @@ public:
/****************************************************************************/
/**
- @brief Prepared_statement: a statement that can contain placeholders
+ Prepared_statement: a statement that can contain placeholders.
*/
class Prepared_statement: public Statement
@@ -176,20 +183,17 @@ inline bool is_param_null(const uchar *pos, ulong param_no)
return pos[param_no/8] & (1 << (param_no & 7));
}
-/*
+/**
Find a prepared statement in the statement map by id.
- SYNOPSIS
- find_prepared_statement()
- thd thread handle
- id statement id
- where the place from which this function is called (for
- error reporting).
-
- DESCRIPTION
Try to find a prepared statement and set THD error if it's not found.
- RETURN VALUE
+ @param thd thread handle
+ @param id statement id
+ @param where the place from which this function is called (for
+ error reporting).
+
+ @return
0 if the statement was not found, a pointer otherwise.
*/
@@ -214,13 +218,13 @@ find_prepared_statement(THD *thd, ulong id, const char *where)
}
-/*
+/**
Send prepared statement id and metadata to the client after prepare.
- SYNOPSIS
- send_prep_stmt()
+ @todo
+ Fix this nasty upcast from List<Item_param> to List<Item>
- RETURN VALUE
+ @return
0 in case of success, 1 otherwise
*/
@@ -265,24 +269,22 @@ static bool send_prep_stmt(Prepared_statement *stmt,
#endif /*!EMBEDDED_LIBRARY*/
-/*
+#ifndef EMBEDDED_LIBRARY
+
+/**
Read the length of the parameter data and return it back to
the caller.
- SYNOPSIS
- get_param_length()
- packet a pointer to the data
- len remaining packet length
-
- DESCRIPTION
Read data length, position the packet to the first byte after it,
and return the length to the caller.
- RETURN VALUE
+ @param packet a pointer to the data
+ @param len remaining packet length
+
+ @return
Length of data piece.
*/
-#ifndef EMBEDDED_LIBRARY
static ulong get_param_length(uchar **packet, ulong len)
{
reg1 uchar *pos= *packet;
@@ -323,16 +325,9 @@ static ulong get_param_length(uchar **packet, ulong len)
#define get_param_length(packet, len) len
#endif /*!EMBEDDED_LIBRARY*/
- /*
- Data conversion routines.
-
- SYNOPSIS
- set_param_xx()
- param parameter item
- pos input data buffer
- len length of data in the buffer
+/**
+ Data conversion routines.
- DESCRIPTION
All these functions read the data from pos, convert it to requested
type and assign to param; pos is advanced to predefined length.
@@ -340,8 +335,9 @@ static ulong get_param_length(uchar **packet, ulong len)
(i.e. when input types altered) and for all subsequent executions
we don't read any values for this.
- RETURN VALUE
- none
+ @param param parameter item
+ @param pos input data buffer
+ @param len length of data in the buffer
*/
static void set_param_tiny(Item_param *param, uchar **pos, ulong len)
@@ -443,6 +439,10 @@ static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
libmysql.c (store_param_{time,date,datetime}).
*/
+/**
+ @todo
+ Add warning 'Data truncated' here
+*/
static void set_param_time(Item_param *param, uchar **pos, ulong len)
{
MYSQL_TIME tm;
@@ -532,6 +532,10 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
}
#else/*!EMBEDDED_LIBRARY*/
+/**
+ @todo
+ Add warning 'Data truncated' here
+*/
void set_param_time(Item_param *param, uchar **pos, ulong len)
{
MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
@@ -684,14 +688,13 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
}
#ifndef EMBEDDED_LIBRARY
-/*
+/**
Routines to assign parameters from data supplied by the client.
- DESCRIPTION
Update the parameter markers by reading data from the packet and
and generate a valid query for logging.
- NOTES
+ @note
This function, along with other _with_log functions is called when one of
binary, slow or general logs is open. Logging of prepared statements in
all cases is performed by means of conventional queries: if parameter
@@ -699,21 +702,28 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
replaced with its actual value; if we're logging a [Dynamic] SQL
prepared statement, parameter markers are replaced with variable names.
Example:
+ @verbatim
mysql_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
--> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
mysql_stmt_execute(stmt);
--> general and binary logs get
[Execute] UPDATE t1 SET a*1.25 WHERE a=1"
- If a statement has been prepared using SQL syntax:
+ @endverbatim
+
+ If a statement has been prepared using SQL syntax:
+ @verbatim
PREPARE stmt FROM "UPDATE t1 SET a=a*1.25 WHERE a=?"
--> general log gets
[Query] PREPARE stmt FROM "UPDATE ..."
EXECUTE stmt USING @a
--> general log gets
- [Query] EXECUTE stmt USING @a;
+ [Query] EXECUTE stmt USING @a;
+ @endverbatim
- RETURN VALUE
- 0 if success, 1 otherwise
+ @retval
+ 0 if success
+ @retval
+ 1 otherwise
*/
static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
@@ -829,12 +839,12 @@ static bool setup_conversion_functions(Prepared_statement *stmt,
#else
-/*
+/**
Embedded counterparts of parameter assignment routines.
- DESCRIPTION
The main difference between the embedded library and the server is
that in embedded case we don't serialize/deserialize parameters data.
+
Additionally, for unknown reason, the client-side flag raised for
changed types of placeholders is ignored and we simply setup conversion
functions at each execute (TODO: fix).
@@ -928,15 +938,14 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt,
#endif /*!EMBEDDED_LIBRARY*/
-/*
+/**
Assign prepared statement parameters from user variables.
- SYNOPSIS
- insert_params_from_vars()
- stmt Statement
- varnames List of variables. Caller must ensure that number of variables
- in the list is equal to number of statement parameters
- query Ignored
+ @param stmt Statement
+ @param varnames List of variables. Caller must ensure that number
+ of variables in the list is equal to number of statement
+ parameters
+ @param query Ignored
*/
static bool insert_params_from_vars(Prepared_statement *stmt,
@@ -965,17 +974,16 @@ static bool insert_params_from_vars(Prepared_statement *stmt,
}
-/*
+/**
Do the same as insert_params_from_vars but also construct query text for
binary log.
- SYNOPSIS
- insert_params_from_vars()
- stmt Prepared statement
- varnames List of variables. Caller must ensure that number of variables
- in the list is equal to number of statement parameters
- query The query with parameter markers replaced with corresponding
- user variables that were used to execute the query.
+ @param stmt Prepared statement
+ @param varnames List of variables. Caller must ensure that number of
+ variables in the list is equal to number of statement
+ parameters
+ @param query The query with parameter markers replaced with corresponding
+ user variables that were used to execute the query.
*/
static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
@@ -1024,17 +1032,16 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
DBUG_RETURN(0);
}
-/*
+/**
Validate INSERT statement.
- SYNOPSIS
- mysql_test_insert()
- stmt prepared statement
- tables global/local table list
+ @param stmt prepared statement
+ @param tables global/local table list
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_insert(Prepared_statement *stmt,
@@ -1112,18 +1119,21 @@ error:
}
-/*
- Validate UPDATE statement
+/**
+ Validate UPDATE statement.
+
+ @param stmt prepared statement
+ @param tables list of tables used in this query
- SYNOPSIS
- mysql_test_update()
- stmt prepared statement
- tables list of tables used in this query
+ @todo
+ - here we should send types of placeholders to the client.
- RETURN VALUE
- 0 success
- 1 error, error message is set in THD
- 2 convert to multi_update
+ @retval
+ 0 success
+ @retval
+ 1 error, error message is set in THD
+ @retval
+ 2 convert to multi_update
*/
static int mysql_test_update(Prepared_statement *stmt,
@@ -1196,17 +1206,16 @@ error:
}
-/*
+/**
Validate DELETE statement.
- SYNOPSIS
- mysql_test_delete()
- stmt prepared statement
- tables list of tables used in this query
+ @param stmt prepared statement
+ @param tables list of tables used in this query
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_delete(Prepared_statement *stmt,
@@ -1233,22 +1242,21 @@ error:
}
-/*
+/**
Validate SELECT statement.
- SYNOPSIS
- mysql_test_select()
- stmt prepared statement
- tables list of tables used in the query
-
- DESCRIPTION
In case of success, if this query is not EXPLAIN, send column list info
back to the client.
- RETURN VALUE
- 0 success
- 1 error, error message is set in THD
- 2 success, and statement metadata has been sent
+ @param stmt prepared statement
+ @param tables list of tables used in the query
+
+ @retval
+ 0 success
+ @retval
+ 1 error, error message is set in THD
+ @retval
+ 2 success, and statement metadata has been sent
*/
static int mysql_test_select(Prepared_statement *stmt,
@@ -1313,18 +1321,17 @@ error:
}
-/*
+/**
Validate and prepare for execution DO statement expressions.
- SYNOPSIS
- mysql_test_do_fields()
- stmt prepared statement
- tables list of tables used in this query
- values list of expressions
+ @param stmt prepared statement
+ @param tables list of tables used in this query
+ @param values list of expressions
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_do_fields(Prepared_statement *stmt,
@@ -1343,18 +1350,17 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
}
-/*
- Validate and prepare for execution SET statement expressions
+/**
+ Validate and prepare for execution SET statement expressions.
- SYNOPSIS
- mysql_test_set_fields()
- stmt prepared statement
- tables list of tables used in this query
- values list of expressions
+ @param stmt prepared statement
+ @param tables list of tables used in this query
+ @param values list of expressions
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_set_fields(Prepared_statement *stmt,
@@ -1381,23 +1387,22 @@ error:
}
-/*
- Check internal SELECT of the prepared command
+/**
+ Check internal SELECT of the prepared command.
- SYNOPSIS
- select_like_stmt_test()
- stmt prepared statement
- specific_prepare function of command specific prepare
- setup_tables_done_option options to be passed to LEX::unit.prepare()
+ @param stmt prepared statement
+ @param specific_prepare function of command specific prepare
+ @param setup_tables_done_option options to be passed to LEX::unit.prepare()
- NOTE
+ @note
This function won't directly open tables used in select. They should
be opened either by calling function (and in this case you probably
should use select_like_stmt_test_with_open()) or by
"specific_prepare" call (like this happens in case of multi-update).
- RETURN VALUE
+ @retval
FALSE success
+ @retval
TRUE error, error message is set in THD
*/
@@ -1420,20 +1425,19 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));
}
-/*
+/**
Check internal SELECT of the prepared command (with opening of used
tables).
- SYNOPSIS
- select_like_stmt_test_with_open()
- stmt prepared statement
- tables list of tables to be opened before calling
- specific_prepare function
- specific_prepare function of command specific prepare
- setup_tables_done_option options to be passed to LEX::unit.prepare()
+ @param stmt prepared statement
+ @param tables list of tables to be opened
+ before calling specific_prepare function
+ @param specific_prepare function of command specific prepare
+ @param setup_tables_done_option options to be passed to LEX::unit.prepare()
- RETURN VALUE
+ @retval
FALSE success
+ @retval
TRUE error
*/
@@ -1459,17 +1463,16 @@ select_like_stmt_test_with_open(Prepared_statement *stmt,
}
-/*
- Validate and prepare for execution CREATE TABLE statement
+/**
+ Validate and prepare for execution CREATE TABLE statement.
- SYNOPSIS
- mysql_test_create_table()
- stmt prepared statement
- tables list of tables used in this query
+ @param stmt prepared statement
+ @param tables list of tables used in this query
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_create_table(Prepared_statement *stmt)
@@ -1512,18 +1515,17 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
}
-/*
+/**
Validate and prepare for execution a multi update statement.
- SYNOPSIS
- mysql_test_multiupdate()
- stmt prepared statement
- tables list of tables used in this query
- converted converted to multi-update from usual update
+ @param stmt prepared statement
+ @param tables list of tables used in this query
+ @param converted converted to multi-update from usual update
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_multiupdate(Prepared_statement *stmt,
@@ -1539,17 +1541,16 @@ static bool mysql_test_multiupdate(Prepared_statement *stmt,
}
-/*
+/**
Validate and prepare for execution a multi delete statement.
- SYNOPSIS
- mysql_test_multidelete()
- stmt prepared statement
- tables list of tables used in this query
+ @param stmt prepared statement
+ @param tables list of tables used in this query
- RETURN VALUE
- FALSE success
- TRUE error, error message in THD is set.
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message in THD is set.
*/
static bool mysql_test_multidelete(Prepared_statement *stmt,
@@ -1579,15 +1580,13 @@ error:
}
-/*
+/**
Wrapper for mysql_insert_select_prepare, to make change of local tables
after open_normal_and_derived_tables() call.
- SYNOPSIS
- mysql_insert_select_prepare_tester()
- thd thread handle
+ @param thd thread handle
- NOTE
+ @note
We need to remove the first local table after
open_normal_and_derived_tables(), because mysql_handle_derived
uses local tables lists.
@@ -1608,17 +1607,16 @@ static bool mysql_insert_select_prepare_tester(THD *thd)
}
-/*
+/**
Validate and prepare for execution INSERT ... SELECT statement.
- SYNOPSIS
- mysql_test_insert_select()
- stmt prepared statement
- tables list of tables used in this query
+ @param stmt prepared statement
+ @param tables list of tables used in this query
- RETURN VALUE
- FALSE success
- TRUE error, error message is set in THD
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
*/
static bool mysql_test_insert_select(Prepared_statement *stmt,
@@ -1651,23 +1649,21 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
}
-/*
+/**
Perform semantic analysis of the parsed tree and send a response packet
to the client.
- SYNOPSIS
- check_prepared_statement()
- stmt prepared statement
-
- DESCRIPTION
This function
- opens all tables and checks access rights
- validates semantics of statement columns and SQL functions
by calling fix_fields.
- RETURN VALUE
- FALSE success, statement metadata is sent to client
- TRUE error, error message is set in THD (but not sent)
+ @param stmt prepared statement
+
+ @retval
+ FALSE success, statement metadata is sent to client
+ @retval
+ TRUE error, error message is set in THD (but not sent)
*/
static bool check_prepared_statement(Prepared_statement *stmt,
@@ -1834,7 +1830,7 @@ error:
DBUG_RETURN(TRUE);
}
-/*
+/**
Initialize array of parameters in statement from LEX.
(We need to have quick access to items by number in mysql_stmt_get_longdata).
This is to avoid using malloc/realloc in the parser.
@@ -1870,31 +1866,28 @@ static bool init_param_array(Prepared_statement *stmt)
}
-/*
+/**
COM_STMT_PREPARE handler.
- SYNOPSIS
- mysql_stmt_prepare()
- packet query to be prepared
- packet_length query string length, including ignored
- trailing NULL or quote char.
-
- DESCRIPTION
Given a query string with parameter markers, create a prepared
statement from it and send PS info back to the client.
- NOTES
- This function parses the query and sends the total number of parameters
- and resultset metadata information back to client (if any), without
- executing the query i.e. without any log/disk writes. This allows the
- queries to be re-executed without re-parsing during execute.
-
If parameter markers are found in the query, then store the information
using Item_param along with maintaining a list in lex->param_array, so
that a fast and direct retrieval can be made without going through all
field items.
- RETURN VALUE
+ @param packet query to be prepared
+ @param packet_length query string length, including ignored
+ trailing NULL or quote char.
+
+ @note
+ This function parses the query and sends the total number of parameters
+ and resultset metadata information back to client (if any), without
+ executing the query i.e. without any log/disk writes. This allows the
+ queries to be re-executed without re-parsing during execute.
+
+ @return
none: in case of success a new statement id and metadata is sent
to the client, otherwise an error message is set in THD.
*/
@@ -1944,22 +1937,22 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
DBUG_VOID_RETURN;
}
-/*
- SYNOPSIS
- get_dynamic_sql_string()
- lex in main lex
- query_len out length of the SQL statement (is set only
- in case of success)
-
- DESCRIPTION
- Get an SQL statement text from a user variable or from plain
- text. If the statement is plain text, just assign the
- pointers, otherwise allocate memory in thd->mem_root and copy
- the contents of the variable, possibly with character
- set conversion.
-
- RETURN VALUE
- non-zero success, 0 in case of error (out of memory)
+/**
+ Get an SQL statement text from a user variable or from plain text.
+
+ If the statement is plain text, just assign the
+ pointers, otherwise allocate memory in thd->mem_root and copy
+ the contents of the variable, possibly with character
+ set conversion.
+
+ @param[in] lex main lex
+ @param[out] query_len length of the SQL statement (is set only
+ in case of success)
+
+ @retval
+ non-zero success
+ @retval
+ 0 in case of error (out of memory)
*/
static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
@@ -2037,7 +2030,7 @@ end:
}
-/* Init PS/SP specific parse tree members. */
+/** Init PS/SP specific parse tree members. */
static void init_stmt_after_parse(LEX *lex)
{
@@ -2050,19 +2043,16 @@ static void init_stmt_after_parse(LEX *lex)
sl->uncacheable&= ~UNCACHEABLE_PREPARE;
}
-/*
+/**
SQLCOM_PREPARE implementation.
- SYNOPSIS
- mysql_sql_stmt_prepare()
- thd thread handle
-
- DESCRIPTION
Prepare an SQL prepared statement. This is called from
mysql_execute_command and should therefore behave like an
ordinary query (e.g. should not reset any global THD data).
- RETURN VALUE
+ @param thd thread handle
+
+ @return
none: in case of success, OK packet is sent to the client,
otherwise an error message is set in THD
*/
@@ -2118,7 +2108,14 @@ void mysql_sql_stmt_prepare(THD *thd)
DBUG_VOID_RETURN;
}
-/* Reinit prepared statement/stored procedure before execution */
+/**
+ Reinit prepared statement/stored procedure before execution.
+
+ @todo
+ When the new table structure is ready, then have a status bit
+ to indicate the table is altered, and re-do the setup_*
+ and open the tables back.
+*/
void reinit_stmt_before_use(THD *thd, LEX *lex)
{
@@ -2224,13 +2221,11 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
-/*
- Clears parameters from data left from previous execution or long data
+/**
+ Clears parameters from data left from previous execution or long data.
- SYNOPSIS
- reset_stmt_params()
- stmt prepared statement for which parameters should
- be reset
+ @param stmt prepared statement for which parameters should
+ be reset
*/
static void reset_stmt_params(Prepared_statement *stmt)
@@ -2242,22 +2237,19 @@ static void reset_stmt_params(Prepared_statement *stmt)
}
-/*
+/**
COM_STMT_EXECUTE handler: execute a previously prepared statement.
- SYNOPSIS
- mysql_stmt_execute()
- thd current thread
- packet parameter types and data, if any
- packet_length packet length, including the terminator character.
-
- DESCRIPTION
If there are any parameters, then replace parameter markers with the
data supplied from the client, and then execute the statement.
This function uses binary protocol to send a possible result set
to the client.
- RETURN VALUE
+ @param thd current thread
+ @param packet_arg parameter types and data, if any
+ @param packet_length packet length, including the terminator character.
+
+ @return
none: in case of success OK packet or a result set is sent to the
client, otherwise an error message is set in THD.
*/
@@ -2331,14 +2323,9 @@ set_params_data_err:
}
-/*
+/**
SQLCOM_EXECUTE implementation.
- SYNOPSIS
- mysql_sql_stmt_execute()
- thd thread handle
-
- DESCRIPTION
Execute prepared statement using parameter values from
lex->prepared_stmt_params and send result to the client using
text protocol. This is called from mysql_execute_command and
@@ -2346,7 +2333,9 @@ set_params_data_err:
global THD data, such as warning count, server status, etc).
This function uses text protocol to send a possible result set.
- RETURN
+ @param thd thread handle
+
+ @return
none: in case of success, OK (or result set) packet is sent to the
client, otherwise an error is set in THD
*/
@@ -2398,14 +2387,12 @@ set_params_data_err:
}
-/*
- COM_STMT_FETCH handler: fetches requested amount of rows from cursor
+/**
+ COM_STMT_FETCH handler: fetches requested amount of rows from cursor.
- SYNOPSIS
- mysql_stmt_fetch()
- thd Thread handle
- packet Packet from client (with stmt_id & num_rows)
- packet_length Length of packet
+ @param thd Thread handle
+ @param packet Packet from client (with stmt_id & num_rows)
+ @param packet_length Length of packet
*/
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
@@ -2456,22 +2443,20 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
}
-/*
+/**
Reset a prepared statement in case there was a recoverable error.
- SYNOPSIS
- mysql_stmt_reset()
- thd Thread handle
- packet Packet with stmt id
- DESCRIPTION
This function resets statement to the state it was right after prepare.
It can be used to:
- - clear an error happened during mysql_stmt_send_long_data
- - cancel long data stream for all placeholders without
- having to call mysql_stmt_execute.
- - close an open cursor
+ - clear an error happened during mysql_stmt_send_long_data
+ - cancel long data stream for all placeholders without
+ having to call mysql_stmt_execute.
+ - close an open cursor
Sends 'OK' packet in case of success (statement was reset)
or 'ERROR' packet (unrecoverable error/statement not found/etc).
+
+ @param thd Thread handle
+ @param packet Packet with stmt id
*/
void mysql_stmt_reset(THD *thd, char *packet)
@@ -2504,9 +2489,11 @@ void mysql_stmt_reset(THD *thd, char *packet)
}
-/*
+/**
Delete a prepared statement from memory.
- Note: we don't send any reply to this command.
+
+ @note
+ we don't send any reply to this command.
*/
void mysql_stmt_close(THD *thd, char *packet)
@@ -2530,15 +2517,14 @@ void mysql_stmt_close(THD *thd, char *packet)
}
-/*
+/**
SQLCOM_DEALLOCATE implementation.
- DESCRIPTION
Close an SQL prepared statement. As this can be called from Dynamic
SQL, we should be careful to not close a statement that is currently
being executed.
- RETURN VALUE
+ @return
none: OK packet is sent in case of success, otherwise an error
message is set in THD
*/
@@ -2561,21 +2547,18 @@ void mysql_sql_stmt_close(THD *thd)
send_ok(thd);
}
-/*
+/**
Handle long data in pieces from client.
- SYNOPSIS
- mysql_stmt_get_longdata()
- thd Thread handle
- packet String to append
- packet_length Length of string (including end \0)
-
- DESCRIPTION
Get a part of a long data. To make the protocol efficient, we are
not sending any return packets here. If something goes wrong, then
we will send the error on 'execute' We assume that the client takes
care of checking that all parts are sent to the server. (No checking
that we get a 'end of column' in the server is performed).
+
+ @param thd Thread handle
+ @param packet String to append
+ @param packet_length Length of string (including end \\0)
*/
void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
@@ -2742,12 +2725,12 @@ void Prepared_statement::setup_set_params()
}
-/*
- DESCRIPTION
- Destroy this prepared statement, cleaning up all used memory
- and resources. This is called from ::deallocate() to
- handle COM_STMT_CLOSE and DEALLOCATE PREPARE or when
- THD ends and all prepared statements are freed.
+/**
+ Destroy this prepared statement, cleaning up all used memory
+ and resources.
+
+ This is called from ::deallocate() to handle COM_STMT_CLOSE and
+ DEALLOCATE PREPARE or when THD ends and all prepared statements are freed.
*/
Prepared_statement::~Prepared_statement()
@@ -2804,28 +2787,24 @@ bool Prepared_statement::set_name(LEX_STRING *name_arg)
global THD state management to the caller.
***************************************************************************/
-/*
+/**
Parse statement text, validate the statement, and prepare it for execution.
- SYNOPSIS
- Prepared_statement::prepare()
- packet statement text
- packet_len
-
- DESCRIPTION
You should not change global THD state in this function, if at all
possible: it may be called from any context, e.g. when executing
a COM_* command, and SQLCOM_* command, or a stored procedure.
- NOTES
- Precondition.
- -------------
+ @param packet statement text
+ @param packet_len
+
+ @note
+ Precondition:
The caller must ensure that thd->change_list and thd->free_list
is empty: this function will not back them up but will free
in the end of its execution.
- Postcondition.
- --------------
+ @note
+ Postcondition:
thd->mem_root contains unused memory allocated during validation.
*/
@@ -2956,28 +2935,25 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
DBUG_RETURN(error);
}
-/*
+/**
Execute a prepared statement.
- SYNOPSIS
- Prepared_statement::execute()
- expanded_query A query for binlogging which has all parameter
- markers ('?') replaced with their actual values.
- open_cursor True if an attempt to open a cursor should be made.
- Currenlty used only in the binary protocol.
-
- DESCRIPTION
You should not change global THD state in this function, if at all
possible: it may be called from any context, e.g. when executing
a COM_* command, and SQLCOM_* command, or a stored procedure.
- NOTES
- Preconditions, postconditions.
- ------------------------------
- See the comment for Prepared_statement::prepare().
+ @param expanded_query A query for binlogging which has all parameter
+ markers ('?') replaced with their actual values.
+ @param open_cursor True if an attempt to open a cursor should be made.
+ Currenlty used only in the binary protocol.
+
+ @note
+ Preconditions, postconditions.
+ - See the comment for Prepared_statement::prepare().
- RETURN
- FALSE ok
+ @retval
+ FALSE ok
+ @retval
TRUE Error
*/
@@ -3161,7 +3137,7 @@ error:
}
-/* Common part of DEALLOCATE PREPARE and mysql_stmt_close */
+/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
bool Prepared_statement::deallocate()
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b77bb719e1e..7c751fa7393 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -14,12 +14,16 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/**
+ @file
+
+ @brief
+ mysql_select and join optimization
+
+
@defgroup Query_Optimizer Query Optimizer
@{
*/
-/* mysql_select and join optimization */
-
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
#endif
@@ -225,8 +229,8 @@ static Item *remove_additional_cond(Item* conds);
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
-/*
- This handles SELECT with and without UNION
+/**
+ This handles SELECT with and without UNION.
*/
bool handle_select(THD *thd, LEX *lex, select_result *result,
@@ -382,8 +386,8 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
return res;
}
-/*
- Function to setup clauses without sum functions
+/**
+ Function to setup clauses without sum functions.
*/
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
TABLE_LIST *tables,
@@ -416,10 +420,17 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
mysql_select assumes that all tables are already opened
*****************************************************************************/
-/*
+/**
Prepare of whole select (including sub queries in future).
- return -1 on error
- 0 on success
+
+ @todo
+ Add check of calculation of GROUP functions and fields:
+ SELECT COUNT(*)+table.col1 from table1;
+
+ @retval
+ -1 on error
+ @retval
+ 0 on success
*/
int
JOIN::prepare(Item ***rref_pointer_array,
@@ -742,11 +753,16 @@ static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
}
-/*
+/**
global select optimisation.
- return 0 - success
- 1 - error
- error code saved in field 'error'
+
+ @note
+ error code saved in field 'error'
+
+ @retval
+ 0 success
+ @retval
+ 1 error
*/
int
@@ -1495,8 +1511,8 @@ JOIN::optimize()
}
-/*
- Restore values in temporary join
+/**
+ Restore values in temporary join.
*/
void JOIN::restore_tmp()
{
@@ -1584,8 +1600,16 @@ JOIN::save_join_tab()
}
-/*
- Exec select
+/**
+ Exec select.
+
+ @todo
+ Note, that create_sort_index calls test_if_skip_sort_order and may
+ finally replace sorting with index scan if there is a LIMIT clause in
+ the query. It's never shown in EXPLAIN!
+
+ @todo
+ When can we have here thd->net.report_error not zero?
*/
void
JOIN::exec()
@@ -2157,8 +2181,11 @@ JOIN::exec()
}
-/*
- Clean up join. Return error that hold JOIN.
+/**
+ Clean up join.
+
+ @return
+ Return error that hold JOIN.
*/
int
@@ -2192,49 +2219,48 @@ JOIN::destroy()
DBUG_RETURN(error);
}
-/*
+/**
An entry point to single-unit select (a select without UNION).
- SYNOPSIS
- mysql_select()
-
- thd thread handler
- rref_pointer_array a reference to ref_pointer_array of
- the top-level select_lex for this query
- tables list of all tables used in this query.
- The tables have been pre-opened.
- wild_num number of wildcards used in the top level
- select of this query.
- For example statement
- SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
- has 3 wildcards.
- fields list of items in SELECT list of the top-level
- select
- e.g. SELECT a, b, c FROM t1 will have Item_field
- for a, b and c in this list.
- conds top level item of an expression representing
- WHERE clause of the top level select
- og_num total number of ORDER BY and GROUP BY clauses
- arguments
- order linked list of ORDER BY agruments
- group linked list of GROUP BY arguments
- having top level item of HAVING expression
- proc_param list of PROCEDUREs
- select_options select options (BIG_RESULT, etc)
- result an instance of result set handling class.
- This object is responsible for send result
- set rows to the client or inserting them
- into a table.
- select_lex the only SELECT_LEX of this query
- unit top-level UNIT of this query
- UNIT is an artificial object created by the parser
- for every SELECT clause.
- e.g. SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2)
- has 2 unions.
-
- RETURN VALUE
- FALSE success
- TRUE an error
+ @param thd thread handler
+ @param rref_pointer_array a reference to ref_pointer_array of
+ the top-level select_lex for this query
+ @param tables list of all tables used in this query.
+ The tables have been pre-opened.
+ @param wild_num number of wildcards used in the top level
+ select of this query.
+ For example statement
+ SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
+ has 3 wildcards.
+ @param fields list of items in SELECT list of the top-level
+ select
+ e.g. SELECT a, b, c FROM t1 will have Item_field
+ for a, b and c in this list.
+ @param conds top level item of an expression representing
+ WHERE clause of the top level select
+ @param og_num total number of ORDER BY and GROUP BY clauses
+ arguments
+ @param order linked list of ORDER BY agruments
+ @param group linked list of GROUP BY arguments
+ @param having top level item of HAVING expression
+ @param proc_param list of PROCEDUREs
+ @param select_options select options (BIG_RESULT, etc)
+ @param result an instance of result set handling class.
+ This object is responsible for send result
+ set rows to the client or inserting them
+ into a table.
+ @param select_lex the only SELECT_LEX of this query
+ @param unit top-level UNIT of this query
+ UNIT is an artificial object created by the
+ parser for every SELECT clause.
+ e.g.
+ SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2)
+ has 2 unions.
+
+ @retval
+ FALSE success
+ @retval
+ TRUE an error
*/
bool
@@ -2380,12 +2406,13 @@ typedef struct st_sargable_param
uint num_values; /* number of values in the above array */
} SARGABLE_PARAM;
-/*
- Calculate the best possible join and initialize the join structure
+/**
+ Calculate the best possible join and initialize the join structure.
- RETURN VALUES
- 0 ok
- 1 Fatal error
+ @retval
+ 0 ok
+ @retval
+ 1 Fatal error
*/
static bool
@@ -2826,13 +2853,14 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
keyuse Pointer to possible keys
*****************************************************************************/
-typedef struct key_field_t { // Used when finding key fields
+/// Used when finding key fields
+typedef struct key_field_t {
Field *field;
- Item *val; // May be empty if diff constant
+ Item *val; ///< May be empty if diff constant
uint level;
uint optimize;
bool eq_func;
- /*
+ /**
If true, the condition this struct represents will not be satisfied
when val IS NULL.
*/
@@ -2844,22 +2872,28 @@ typedef struct key_field_t { // Used when finding key fields
#define KEY_OPTIMIZE_EXISTS 1
#define KEY_OPTIMIZE_REF_OR_NULL 2
-/*
- Merge new key definitions to old ones, remove those not used in both
+/**
+ Merge new key definitions to old ones, remove those not used in both.
- This is called for OR between different levels
+ This is called for OR between different levels.
To be able to do 'ref_or_null' we merge a comparison of a column
and 'column IS NULL' to one test. This is useful for sub select queries
- that are internally transformed to something like:
+ that are internally transformed to something like:.
+ @code
SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
+ @endcode
- KEY_FIELD::null_rejecting is processed as follows:
+ KEY_FIELD::null_rejecting is processed as follows: @n
result has null_rejecting=true if it is set for both ORed references.
for example:
- (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
- (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
+ - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
+ - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
+
+ @todo
+ The result of this is that we're missing some 'ref' accesses.
+ OptimizerTeam: Fix this
*/
static KEY_FIELD *
@@ -2968,25 +3002,23 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
}
-/*
+/**
Add a possible key to array of possible keys if it's usable as a key
- SYNPOSIS
- add_key_field()
- key_fields Pointer to add key, if usable
- and_level And level, to be stored in KEY_FIELD
- cond Condition predicate
- field Field used in comparision
- eq_func True if we used =, <=> or IS NULL
- value Value used for comparison with field
- usable_tables Tables which can be used for key optimization
- sargables IN/OUT Array of found sargable candidates
-
- NOTES
+ @param key_fields Pointer to add key, if usable
+ @param and_level And level, to be stored in KEY_FIELD
+ @param cond Condition predicate
+ @param field Field used in comparision
+ @param eq_func True if we used =, <=> or IS NULL
+ @param value Value used for comparison with field
+ @param usable_tables Tables which can be used for key optimization
+ @param sargables IN/OUT Array of found sargable candidates
+
+ @note
If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
table, we store this to be able to do not exists optimization later.
- RETURN
+ @returns
*key_fields is incremented if we stored a key in the array
*/
@@ -3137,26 +3169,25 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
(*key_fields)++;
}
-/*
- Add possible keys to array of possible keys originated from a simple predicate
-
- SYNPOSIS
- add_key_equal_fields()
- key_fields Pointer to add key, if usable
- and_level And level, to be stored in KEY_FIELD
- cond Condition predicate
- field Field used in comparision
- eq_func True if we used =, <=> or IS NULL
- value Value used for comparison with field
- Is NULL for BETWEEN and IN
- usable_tables Tables which can be used for key optimization
- sargables IN/OUT Array of found sargable candidates
-
- NOTES
+/**
+ Add possible keys to array of possible keys originated from a simple
+ predicate.
+
+ @param key_fields Pointer to add key, if usable
+ @param and_level And level, to be stored in KEY_FIELD
+ @param cond Condition predicate
+ @param field Field used in comparision
+ @param eq_func True if we used =, <=> or IS NULL
+ @param value Value used for comparison with field
+ Is NULL for BETWEEN and IN
+ @param usable_tables Tables which can be used for key optimization
+ @param sargables IN/OUT Array of found sargable candidates
+
+ @note
If field items f1 and f2 belong to the same multiple equality and
a key is added for f1, the the same key is added for f2.
- RETURN
+ @returns
*key_fields is incremented if we stored a key in the array
*/
@@ -3387,9 +3418,13 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
}
}
-/*
- Add all keys with uses 'field' for some keypart
- If field->and_level != and_level then only mark key_part as const_part
+/**
+ Add all keys with uses 'field' for some keypart.
+
+ If field->and_level != and_level then only mark key_part as const_part.
+
+ @todo
+ ft-keys in non-ft queries. SerG
*/
static uint
@@ -3522,33 +3557,37 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
/*
- Add to KEY_FIELD array all 'ref' access candidates within nested join
-
- SYNPOSIS
- add_key_fields_for_nj()
- nested_join_table IN Nested join pseudo-table to process
- end INOUT End of the key field array
- and_level INOUT And-level
- sargables IN/OUT Array of found sargable candidates
+ Add to KEY_FIELD array all 'ref' access candidates within nested join.
- DESCRIPTION
This function populates KEY_FIELD array with entries generated from the
ON condition of the given nested join, and does the same for nested joins
contained within this nested join.
- NOTES
+ @param[in] nested_join_table Nested join pseudo-table to process
+ @param[in,out] end End of the key field array
+ @param[in,out] and_level And-level
+ @param[in,out] sargables Array of found sargable candidates
+
+
+ @note
We can add accesses to the tables that are direct children of this nested
join (1), and are not inner tables w.r.t their neighbours (2).
Example for #1 (outer brackets pair denotes nested join this function is
invoked for):
+ @code
... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
+ @endcode
Example for #2:
+ @code
... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
+ @endcode
In examples 1-2 for condition cond, we can add 'ref' access candidates to
t1 only.
Example #3:
+ @code
... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
+ @endcode
Here we can add 'ref' access candidates for t1 and t2, but not for t3.
*/
@@ -3574,25 +3613,25 @@ static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
}
-/*
- Update keyuse array with all possible keys we can use to fetch rows
+/**
+ Update keyuse array with all possible keys we can use to fetch rows.
- SYNOPSIS
- update_ref_and_keys()
- thd
- keyuse OUT Put here ordered array of KEYUSE structures
- join_tab Array in tablenr_order
- tables Number of tables in join
- cond WHERE condition (note that the function analyzes
- join_tab[i]->on_expr too)
- normal_tables Tables not inner w.r.t some outer join (ones for which
- we can make ref access based the WHERE clause)
- select_lex current SELECT
- sargables OUT Array of found sargable candidates
+ @param thd
+ @param[out] keyuse Put here ordered array of KEYUSE structures
+ @param join_tab Array in tablenr_order
+ @param tables Number of tables in join
+ @param cond WHERE condition (note that the function analyzes
+ join_tab[i]->on_expr too)
+ @param normal_tables Tables not inner w.r.t some outer join (ones
+ for which we can make ref access based the WHERE
+ clause)
+ @param select_lex current SELECT
+ @param[out] sargables Array of found sargable candidates
- RETURN
- 0 - OK
- 1 - Out of memory.
+ @retval
+ 0 OK
+ @retval
+ 1 Out of memory.
*/
static bool
@@ -3751,8 +3790,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
return FALSE;
}
-/*
- Update some values in keyuse for faster choose_plan() loop
+/**
+ Update some values in keyuse for faster choose_plan() loop.
*/
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
@@ -3793,23 +3832,21 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
}
-/*
+/**
Discover the indexes that can be used for GROUP BY or DISTINCT queries.
- SYNOPSIS
- add_group_and_distinct_keys()
- join
- join_tab
+ If the query has a GROUP BY clause, find all indexes that contain all
+ GROUP BY fields, and add those indexes to join->const_keys.
- DESCRIPTION
- If the query has a GROUP BY clause, find all indexes that contain all
- GROUP BY fields, and add those indexes to join->const_keys.
- If the query has a DISTINCT clause, find all indexes that contain all
- SELECT fields, and add those indexes to join->const_keys.
- This allows later on such queries to be processed by a
- QUICK_GROUP_MIN_MAX_SELECT.
+ If the query has a DISTINCT clause, find all indexes that contain all
+ SELECT fields, and add those indexes to join->const_keys.
+ This allows later on such queries to be processed by a
+ QUICK_GROUP_MIN_MAX_SELECT.
- RETURN
+ @param join
+ @param join_tab
+
+ @return
None
*/
@@ -3861,7 +3898,7 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
which uses least records
*****************************************************************************/
-/* Save const tables first as used tables */
+/** Save const tables first as used tables. */
static void
set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
@@ -3884,31 +3921,28 @@ set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
}
-/*
- Find the best access path for an extension of a partial execution plan and
- add this path to the plan.
-
- SYNOPSIS
- best_access_path()
- join pointer to the structure providing all context info
- for the query
- s the table to be joined by the function
- thd thread for the connection that submitted the query
- remaining_tables set of tables not included into the partial plan yet
- idx the length of the partial plan
- record_count estimate for the number of records returned by the partial
- plan
- read_time the cost of the partial plan
-
- DESCRIPTION
- The function finds the best access path to table 's' from the passed
- partial plan where an access path is the general term for any means to
- access the data in 's'. An access path may use either an index or a scan,
- whichever is cheaper. The input partial plan is passed via the array
- 'join->positions' of length 'idx'. The chosen access method for 's' and its
- cost are stored in 'join->positions[idx]'.
-
- RETURN
+/**
+ Find the best access path for an extension of a partial execution
+ plan and add this path to the plan.
+
+ The function finds the best access path to table 's' from the passed
+ partial plan where an access path is the general term for any means to
+ access the data in 's'. An access path may use either an index or a scan,
+ whichever is cheaper. The input partial plan is passed via the array
+ 'join->positions' of length 'idx'. The chosen access method for 's' and its
+ cost are stored in 'join->positions[idx]'.
+
+ @param join pointer to the structure providing all context info
+ for the query
+ @param s the table to be joined by the function
+ @param thd thread for the connection that submitted the query
+ @param remaining_tables set of tables not included into the partial plan yet
+ @param idx the length of the partial plan
+ @param record_count estimate for the number of records returned by the
+ partial plan
+ @param read_time the cost of the partial plan
+
+ @return
None
*/
@@ -4436,24 +4470,26 @@ best_access_path(JOIN *join,
}
-/*
+/**
Selects and invokes a search strategy for an optimal query plan.
- SYNOPSIS
- choose_plan()
- join pointer to the structure providing all context info for
- the query
- join_tables set of the tables in the query
+ The function checks user-configurable parameters that control the search
+ strategy for an optimal plan, selects the search method and then invokes
+ it. Each specific optimization procedure stores the final optimal plan in
+ the array 'join->best_positions', and the cost of the plan in
+ 'join->best_read'.
- DESCRIPTION
- The function checks user-configurable parameters that control the search
- strategy for an optimal plan, selects the search method and then invokes
- it. Each specific optimization procedure stores the final optimal plan in
- the array 'join->best_positions', and the cost of the plan in
- 'join->best_read'.
+ @param join pointer to the structure providing all context info for
+ the query
+ @param join_tables set of the tables in the query
- RETURN VALUES
+ @todo
+ 'MAX_TABLES+2' denotes the old implementation of find_best before
+ the greedy version. Will be removed when greedy_search is approved.
+
+ @retval
FALSE ok
+ @retval
TRUE Fatal error
*/
@@ -4515,17 +4551,17 @@ choose_plan(JOIN *join, table_map join_tables)
}
-/*
+/**
Compare two JOIN_TAB objects based on the number of accessed records.
- SYNOPSIS
- join_tab_cmp()
- ptr1 pointer to first JOIN_TAB object
- ptr2 pointer to second JOIN_TAB object
+ @param ptr1 pointer to first JOIN_TAB object
+ @param ptr2 pointer to second JOIN_TAB object
- RETURN
+ @retval
1 if first is bigger
- -1 if second is bigger
+ @retval
+ -1 if second is bigger
+ @retval
0 if equal
*/
@@ -4547,7 +4583,7 @@ join_tab_cmp(const void* ptr1, const void* ptr2)
}
-/*
+/**
Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
*/
@@ -4564,27 +4600,33 @@ join_tab_cmp_straight(const void* ptr1, const void* ptr2)
return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
}
-/*
+/**
Heuristic procedure to automatically guess a reasonable degree of
exhaustiveness for the greedy search procedure.
- SYNOPSIS
- determine_search_depth()
- join pointer to the structure providing all context info for the query
+ The procedure estimates the optimization time and selects a search depth
+ big enough to result in a near-optimal QEP, that doesn't take too long to
+ find. If the number of tables in the query exceeds some constant, then
+ search_depth is set to this constant.
- DESCRIPTION
- The procedure estimates the optimization time and selects a search depth
- big enough to result in a near-optimal QEP, that doesn't take too long to
- find. If the number of tables in the query exceeds some constant, then
- search_depth is set to this constant.
+ @param join pointer to the structure providing all context info for
+ the query
- NOTES
+ @note
This is an extremely simplistic implementation that serves as a stub for a
more advanced analysis of the join. Ideally the search depth should be
determined by learning from previous query optimizations, because it will
depend on the CPU power (and other factors).
- RETURN
+ @todo
+ this value should be determined dynamically, based on statistics:
+ uint max_tables_for_exhaustive_opt= 7;
+
+ @todo
+ this value could be determined by some mapping of the form:
+ depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
+
+ @return
A positive integer that specifies the search depth (and thus the
exhaustiveness) of the depth-first search algorithm used by
'greedy_search'.
@@ -4611,16 +4653,9 @@ determine_search_depth(JOIN *join)
}
-/*
+/**
Select the best ways to access the tables in a query without reordering them.
- SYNOPSIS
- optimize_straight_join()
- join pointer to the structure providing all context info for
- the query
- join_tables set of the tables in the query
-
- DESCRIPTION
Find the best access paths for each query table and compute their costs
according to their order in the array 'join->best_ref' (thus without
reordering the join tables). The function calls sequentially
@@ -4628,15 +4663,17 @@ determine_search_depth(JOIN *join)
access method. The final optimal plan is stored in the array
'join->best_positions', and the corresponding cost in 'join->best_read'.
- NOTES
+ @param join pointer to the structure providing all context info for
+ the query
+ @param join_tables set of the tables in the query
+
+ @note
This function can be applied to:
- queries with STRAIGHT_JOIN
- internally to compute the cost of an arbitrary QEP
+ @par
Thus 'optimize_straight_join' can be used at any stage of the query
optimization process to finalize a QEP as it is.
-
- RETURN
- None
*/
static void
@@ -4669,31 +4706,24 @@ optimize_straight_join(JOIN *join, table_map join_tables)
}
-/*
+/**
Find a good, possibly optimal, query execution plan (QEP) by a greedy search.
- SYNOPSIS
- join pointer to the structure providing all context info
- for the query
- remaining_tables set of tables not included into the partial plan yet
- search_depth controlls the exhaustiveness of the search
- prune_level the pruning heuristics that should be applied during
- search
-
- DESCRIPTION
The search procedure uses a hybrid greedy/exhaustive search with controlled
exhaustiveness. The search is performed in N = card(remaining_tables)
steps. Each step evaluates how promising is each of the unoptimized tables,
selects the most promising table, and extends the current partial QEP with
that table. Currenly the most 'promising' table is the one with least
- expensive extension.
+ expensive extension.\
+
There are two extreme cases:
- 1. When (card(remaining_tables) < search_depth), the estimate finds the best
- complete continuation of the partial QEP. This continuation can be
- used directly as a result of the search.
- 2. When (search_depth == 1) the 'best_extension_by_limited_search'
- consideres the extension of the current QEP with each of the remaining
- unoptimized tables.
+ -# When (card(remaining_tables) < search_depth), the estimate finds the
+ best complete continuation of the partial QEP. This continuation can be
+ used directly as a result of the search.
+ -# When (search_depth == 1) the 'best_extension_by_limited_search'
+ consideres the extension of the current QEP with each of the remaining
+ unoptimized tables.
+
All other cases are in-between these two extremes. Thus the parameter
'search_depth' controlls the exhaustiveness of the search. The higher the
value, the longer the optimizaton time and possibly the better the
@@ -4701,16 +4731,18 @@ optimize_straight_join(JOIN *join, table_map join_tables)
estimated, but the more likely to get a bad QEP.
All intermediate and final results of the procedure are stored in 'join':
- join->positions modified for every partial QEP that is explored
- join->best_positions modified for the current best complete QEP
- join->best_read modified for the current best complete QEP
- join->best_ref might be partially reordered
+ - join->positions : modified for every partial QEP that is explored
+ - join->best_positions: modified for the current best complete QEP
+ - join->best_read : modified for the current best complete QEP
+ - join->best_ref : might be partially reordered
+
The final optimal plan is stored in 'join->best_positions', and its
corresponding cost in 'join->best_read'.
- NOTES
+ @note
The following pseudocode describes the algorithm of 'greedy_search':
+ @code
procedure greedy_search
input: remaining_tables
output: pplan;
@@ -4724,6 +4756,7 @@ optimize_straight_join(JOIN *join, table_map join_tables)
return pplan;
}
+ @endcode
where 'best_extension' is a placeholder for a procedure that selects the
most "promising" of all tables in 'remaining_tables'.
Currently this estimate is performed by calling
@@ -4731,16 +4764,26 @@ optimize_straight_join(JOIN *join, table_map join_tables)
current QEP of size 'search_depth', thus the complexity of 'greedy_search'
mainly depends on that of 'best_extension_by_limited_search'.
+ @par
If 'best_extension()' == 'best_extension_by_limited_search()', then the
worst-case complexity of this algorithm is <=
O(N*N^search_depth/search_depth). When serch_depth >= N, then the
complexity of greedy_search is O(N!).
+ @par
In the future, 'greedy_search' might be extended to support other
implementations of 'best_extension', e.g. some simpler quadratic procedure.
- RETURN VALUES
+ @param join pointer to the structure providing all context info
+ for the query
+ @param remaining_tables set of tables not included into the partial plan yet
+ @param search_depth controlls the exhaustiveness of the search
+ @param prune_level the pruning heuristics that should be applied during
+ search
+
+ @retval
FALSE ok
+ @retval
TRUE Fatal error
*/
@@ -4816,29 +4859,10 @@ greedy_search(JOIN *join,
}
-/*
+/**
Find a good, possibly optimal, query execution plan (QEP) by a possibly
exhaustive search.
- SYNOPSIS
- best_extension_by_limited_search()
- join pointer to the structure providing all context info for
- the query
- remaining_tables set of tables not included into the partial plan yet
- idx length of the partial QEP in 'join->positions';
- since a depth-first search is used, also corresponds to
- the current depth of the search tree;
- also an index in the array 'join->best_ref';
- record_count estimate for the number of records returned by the best
- partial plan
- read_time the cost of the best partial plan
- search_depth maximum depth of the recursion and thus size of the found
- optimal plan (0 < search_depth <= join->tables+1).
- prune_level pruning heuristics that should be applied during
- optimization
- (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)
-
- DESCRIPTION
The procedure searches for the optimal ordering of the query tables in set
'remaining_tables' of size N, and the corresponding optimal access paths to
each table. The choice of a table order and an access path for each table
@@ -4865,16 +4889,18 @@ greedy_search(JOIN *join,
The final optimal plan is stored in 'join->best_positions'. The
corresponding cost of the optimal plan is in 'join->best_read'.
- NOTES
+ @note
The procedure uses a recursive depth-first search where the depth of the
recursion (and thus the exhaustiveness of the search) is controlled by the
parameter 'search_depth'.
+ @note
The pseudocode below describes the algorithm of
'best_extension_by_limited_search'. The worst-case complexity of this
algorithm is O(N*N^search_depth/search_depth). When serch_depth >= N, then
the complexity of greedy_search is O(N!).
+ @code
procedure best_extension_by_limited_search(
pplan in, // in, partial plan of tables-joined-so-far
pplan_cost, // in, cost of pplan
@@ -4914,18 +4940,39 @@ greedy_search(JOIN *join,
}
}
}
+ @endcode
- IMPLEMENTATION
+ @note
When 'best_extension_by_limited_search' is called for the first time,
'join->best_read' must be set to the largest possible value (e.g. DBL_MAX).
The actual implementation provides a way to optionally use pruning
heuristic (controlled by the parameter 'prune_level') to reduce the search
space by skipping some partial plans.
+
+ @note
The parameter 'search_depth' provides control over the recursion
depth, and thus the size of the resulting optimal plan.
- RETURN VALUES
+ @param join pointer to the structure providing all context info
+ for the query
+ @param remaining_tables set of tables not included into the partial plan yet
+ @param idx length of the partial QEP in 'join->positions';
+ since a depth-first search is used, also corresponds
+ to the current depth of the search tree;
+ also an index in the array 'join->best_ref';
+ @param record_count estimate for the number of records returned by the
+ best partial plan
+ @param read_time the cost of the best partial plan
+ @param search_depth maximum depth of the recursion and thus size of the
+ found optimal plan
+ (0 < search_depth <= join->tables+1).
+ @param prune_level pruning heuristics that should be applied during
+ optimization
+ (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)
+
+ @retval
FALSE ok
+ @retval
TRUE Fatal error
*/
@@ -5065,8 +5112,9 @@ best_extension_by_limited_search(JOIN *join,
}
-/*
- TODO: this function is here only temporarily until 'greedy_search' is
+/**
+ @todo
+ - TODO: this function is here only temporarily until 'greedy_search' is
tested and accepted.
RETURN VALUES
@@ -5147,8 +5195,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
}
-/*
- Find how much space the prevous read not const tables takes in cache
+/**
+ Find how much space the prevous read not const tables takes in cache.
*/
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
@@ -5292,9 +5340,9 @@ prev_record_reads(JOIN *join, uint idx, table_map found_ref)
}
-/*****************************************************************************
+/**
Set up join struct according to best position.
-*****************************************************************************/
+*/
static bool
get_best_combination(JOIN *join)
@@ -5535,9 +5583,11 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
keyuse->val);
}
-/*
- This function is only called for const items on fields which are keys
- returns 1 if there was some conversion made when the field was stored.
+/**
+ This function is only called for const items on fields which are keys.
+
+ @return
+ returns 1 if there was some conversion made when the field was stored.
*/
bool
@@ -5647,22 +5697,18 @@ inline void add_cond_and_fix(Item **e1, Item *e2)
}
-/*
- Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions we've
- inferred from ref/eq_ref access performed.
-
- SYNOPSIS
- add_not_null_conds()
- join Join to process
+/**
+ Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions
+ we've inferred from ref/eq_ref access performed.
- NOTES
This function is a part of "Early NULL-values filtering for ref access"
optimization.
Example of this optimization:
- For query SELECT * FROM t1,t2 WHERE t2.key=t1.field
- and plan " any-access(t1), ref(t2.key=t1.field) "
- add "t1.field IS NOT NULL" to t1's table condition.
+ For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n
+ and plan " any-access(t1), ref(t2.key=t1.field) " @n
+ add "t1.field IS NOT NULL" to t1's table condition. @n
+
Description of the optimization:
We look through equalities choosen to perform ref/eq_ref access,
@@ -5674,8 +5720,10 @@ inline void add_cond_and_fix(Item **e1, Item *e2)
Exception from that is the case when referred_tab->join != join.
I.e. don't add NOT NULL constraints from any embedded subquery.
Consider this query:
+ @code
SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1
WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL;
+ @endocde
Here condition A.f3 IS NOT NULL is going to be added to the WHERE
condition of the embedding query.
Another example:
@@ -5746,25 +5794,21 @@ static void add_not_null_conds(JOIN *join)
DBUG_VOID_RETURN;
}
-/*
- Build a predicate guarded by match variables for embedding outer joins
-
- SYNOPSIS
- add_found_match_trig_cond()
- tab the first inner table for most nested outer join
- cond the predicate to be guarded (must be set)
- root_tab the first inner table to stop
-
- DESCRIPTION
- The function recursively adds guards for predicate cond
- assending from tab to the first inner table next embedding
- nested outer join and so on until it reaches root_tab
- (root_tab can be 0).
-
- RETURN VALUE
- pointer to the guarded predicate, if success
- 0, otherwise
-*/
+/**
+ Build a predicate guarded by match variables for embedding outer joins.
+ The function recursively adds guards for predicate cond
+ assending from tab to the first inner table next embedding
+ nested outer join and so on until it reaches root_tab
+ (root_tab can be 0).
+
+ @param tab the first inner table for most nested outer join
+ @param cond the predicate to be guarded (must be set)
+ @param root_tab the first inner table to stop
+
+ @return
+ - pointer to the guarded predicate, if success
+ - 0, otherwise
+*/
static COND*
add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
@@ -5784,14 +5828,9 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
}
-/*
- Fill in outer join related info for the execution plan structure
-
- SYNOPSIS
- make_outerjoin_info()
- join - reference to the info fully describing the query
+/**
+ Fill in outer join related info for the execution plan structure.
- DESCRIPTION
For each outer join operation left after simplification of the
original query the function set up the following pointers in the linear
structure join->join_tab representing the selected execution plan.
@@ -5806,21 +5845,25 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
corresponding first inner table through the field t0->on_expr_ref.
Here ti are structures of the JOIN_TAB type.
- EXAMPLE
- For the query:
- SELECT * FROM t1
- LEFT JOIN
- (t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
- ON (t1.a=t2.a AND t1.b=t3.b)
- WHERE t1.c > 5,
+ EXAMPLE. For the query:
+ @code
+ SELECT * FROM t1
+ LEFT JOIN
+ (t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
+ ON (t1.a=t2.a AND t1.b=t3.b)
+ WHERE t1.c > 5,
+ @endcode
+
given the execution plan with the table order t1,t2,t3,t4
is selected, the following references will be set;
t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2]
t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2],
on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to
*t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref.
-
- NOTES
+
+ @param join reference to the info fully describing the query
+
+ @note
The function assumes that the simplification procedure has been
already applied to the join query (see simplify_joins).
This function can be called only after the execution plan
@@ -6444,20 +6487,18 @@ make_join_readinfo(JOIN *join, ulonglong options)
}
-/*
- Give error if we some tables are done with a full join
+/**
+ Give error if we some tables are done with a full join.
- SYNOPSIS
- error_if_full_join()
- join Join condition
+ This is used by multi_table_update and multi_table_delete when running
+ in safe mode.
- USAGE
- This is used by multi_table_update and multi_table_delete when running
- in safe mode
+ @param join Join condition
- RETURN VALUES
- 0 ok
- 1 Error (full join used)
+ @retval
+ 0 ok
+ @retval
+ 1 Error (full join used)
*/
bool error_if_full_join(JOIN *join)
@@ -6477,11 +6518,8 @@ bool error_if_full_join(JOIN *join)
}
-/*
- cleanup JOIN_TAB
-
- SYNOPSIS
- JOIN_TAB::cleanup()
+/**
+ cleanup JOIN_TAB.
*/
void JOIN_TAB::cleanup()
@@ -6511,11 +6549,10 @@ void JOIN_TAB::cleanup()
}
-/*
+/**
Partially cleanup JOIN after it has executed: close index or rnd read
(table cursors), free quick selects.
- DESCRIPTION
This function is called in the end of execution of a JOIN, before the used
tables are unlocked and closed.
@@ -6535,23 +6572,24 @@ void JOIN_TAB::cleanup()
If a JOIN is executed for a subquery or if it has a subquery, we can't
do the full cleanup and need to do a partial cleanup only.
- o If a JOIN is not the top level join, we must not unlock the tables
- because the outer select may not have been evaluated yet, and we
- can't unlock only selected tables of a query.
-
- o Additionally, if this JOIN corresponds to a correlated subquery, we
- should not free quick selects and join buffers because they will be
- needed for the next execution of the correlated subquery.
-
- o However, if this is a JOIN for a [sub]select, which is not
- a correlated subquery itself, but has subqueries, we can free it
- fully and also free JOINs of all its subqueries. The exception
- is a subquery in SELECT list, e.g:
- SELECT a, (select max(b) from t1) group by c
- This subquery will not be evaluated at first sweep and its value will
- not be inserted into the temporary table. Instead, it's evaluated
- when selecting from the temporary table. Therefore, it can't be freed
- here even though it's not correlated.
+ - If a JOIN is not the top level join, we must not unlock the tables
+ because the outer select may not have been evaluated yet, and we
+ can't unlock only selected tables of a query.
+ - Additionally, if this JOIN corresponds to a correlated subquery, we
+ should not free quick selects and join buffers because they will be
+ needed for the next execution of the correlated subquery.
+ - However, if this is a JOIN for a [sub]select, which is not
+ a correlated subquery itself, but has subqueries, we can free it
+ fully and also free JOINs of all its subqueries. The exception
+ is a subquery in SELECT list, e.g: @n
+ SELECT a, (select max(b) from t1) group by c @n
+ This subquery will not be evaluated at first sweep and its value will
+ not be inserted into the temporary table. Instead, it's evaluated
+ when selecting from the temporary table. Therefore, it can't be freed
+ here even though it's not correlated.
+
+ @todo
+ Unlock tables even if the join isn't top level select in the tree
*/
void JOIN::join_free()
@@ -6611,15 +6649,15 @@ void JOIN::join_free()
}
-/*
- Free resources of given join
+/**
+ Free resources of given join.
- SYNOPSIS
- JOIN::cleanup()
- fill - true if we should free all resources, call with full==1 should be
- last, before it this function can be called with full==0
+ @param fill true if we should free all resources, call with full==1
+ should be last, before it this function can be called with
+ full==0
- NOTE: with subquery this function definitely will be called several times,
+ @note
+ With subquery this function definitely will be called several times,
but even for simple query it can be called several times.
*/
@@ -6689,21 +6727,25 @@ void JOIN::cleanup(bool full)
}
-/*****************************************************************************
+/**
Remove the following expressions from ORDER BY and GROUP BY:
- Constant expressions
+ Constant expressions @n
Expression that only uses tables that are of type EQ_REF and the reference
is in the ORDER list or if all refereed tables are of the above type.
In the following, the X field can be removed:
+ @code
SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
+ @endcode
These can't be optimized:
+ @code
SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
-*****************************************************************************/
+ @endcode
+*/
static bool
eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
@@ -6771,7 +6813,7 @@ only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
}
-/* Update the dependency map for the tables */
+/** Update the dependency map for the tables. */
static void update_depend_map(JOIN *join)
{
@@ -6798,7 +6840,7 @@ static void update_depend_map(JOIN *join)
}
-/* Update the dependency map for the sort order */
+/** Update the dependency map for the sort order. */
static void update_depend_map(JOIN *join, ORDER *order)
{
@@ -6823,25 +6865,23 @@ static void update_depend_map(JOIN *join, ORDER *order)
}
-/*
- Remove all constants and check if ORDER only contains simple expressions
-
- SYNOPSIS
- remove_const()
- join Join handler
- first_order List of SORT or GROUP order
- cond WHERE statement
- change_list Set to 1 if we should remove things from list
- If this is not set, then only simple_order is
- calculated
- simple_order Set to 1 if we are only using simple expressions
+/**
+ Remove all constants and check if ORDER only contains simple
+ expressions.
- RETURN
- Returns new sort order
+ simple_order is set to 1 if sort_order only uses fields from head table
+ and the head table is not a LEFT JOIN table.
- simple_order is set to 1 if sort_order only uses fields from head table
- and the head table is not a LEFT JOIN table
+ @param join Join handler
+ @param first_order List of SORT or GROUP order
+ @param cond WHERE statement
+ @param change_list Set to 1 if we should remove things from list.
+ If this is not set, then only simple_order is
+ calculated.
+ @param simple_order Set to 1 if we are only using simple expressions
+ @return
+ Returns new sort order
*/
static ORDER *
@@ -6997,25 +7037,23 @@ template class List_iterator<Item_func_match>;
#endif
-/*
- Find the multiple equality predicate containing a field
-
- SYNOPSIS
- find_item_equal()
- cond_equal multiple equalities to search in
- field field to look for
- inherited_fl :out set up to TRUE if multiple equality is found
- on upper levels (not on current level of cond_equal)
-
- DESCRIPTION
- The function retrieves the multiple equalities accessed through
- the con_equal structure from current level and up looking for
- an equality containing field. It stops retrieval as soon as the equality
- is found and set up inherited_fl to TRUE if it's found on upper levels.
-
- RETURN
- Item_equal for the found multiple equality predicate if a success;
- NULL - otherwise.
+/**
+ Find the multiple equality predicate containing a field.
+
+ The function retrieves the multiple equalities accessed through
+ the con_equal structure from current level and up looking for
+ an equality containing field. It stops retrieval as soon as the equality
+ is found and set up inherited_fl to TRUE if it's found on upper levels.
+
+ @param cond_equal multiple equalities to search in
+ @param field field to look for
+ @param[out] inherited_fl set up to TRUE if multiple equality is found
+ on upper levels (not on current level of
+ cond_equal)
+
+ @return
+ - Item_equal for the found multiple equality predicate if a success;
+ - NULL otherwise.
*/
Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
@@ -7041,18 +7079,9 @@ finish:
}
-/*
- Check whether an equality can be used to build multiple equalities
-
- SYNOPSIS
- check_simple_equality()
- left_item left term of the quality to be checked
- right_item right term of the equality to be checked
- item equality item if the equality originates from a condition
- predicate, 0 if the equality is the result of row elimination
- cond_equal multiple equalities that must hold together with the equality
+/**
+ Check whether an equality can be used to build multiple equalities.
- DESCRIPTION
This function first checks whether the equality (left_item=right_item)
is a simple equality i.e. the one that equates a field with another field
or a constant (field=field_item or field=const_item).
@@ -7067,22 +7096,24 @@ finish:
This guarantees that the set of multiple equalities covering equality
predicates will be minimal.
- EXAMPLE
+ EXAMPLE:
For the where condition
- WHERE a=b AND b=c AND
- (b=2 OR f=e)
+ @code
+ WHERE a=b AND b=c AND
+ (b=2 OR f=e)
+ @endcode
the check_equality will be called for the following equality
predicates a=b, b=c, b=2 and f=e.
- For a=b it will be called with *cond_equal=(0,[]) and will transform
- *cond_equal into (0,[Item_equal(a,b)]).
- For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
- and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
- For b=2 it will be called with *cond_equal=(ptr(CE),[])
- and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
- For f=e it will be called with *cond_equal=(ptr(CE), [])
- and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
-
- NOTES
+ - For a=b it will be called with *cond_equal=(0,[]) and will transform
+ *cond_equal into (0,[Item_equal(a,b)]).
+ - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
+ and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
+ - For b=2 it will be called with *cond_equal=(ptr(CE),[])
+ and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
+ - For f=e it will be called with *cond_equal=(ptr(CE), [])
+ and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
+
+ @note
Now only fields that have the same type definitions (verified by
the Field::eq_def method) are placed to the same multiple equalities.
Because of this some equality predicates are not eliminated and
@@ -7094,8 +7125,8 @@ finish:
equality. But at the same time it would allow us to get rid
of constant propagation completely: it would be done by the call
to build_equal_items_for_cond.
-
- IMPLEMENTATION
+
+
The implementation does not follow exactly the above rules to
build a new multiple equality for the equality predicate.
If it processes the equality of the form field1=field2, it
@@ -7115,9 +7146,18 @@ finish:
acceptable, as this happens rarely. The implementation without
copying would be much more complicated.
- RETURN
+ @param left_item left term of the quality to be checked
+ @param right_item right term of the equality to be checked
+ @param item equality item if the equality originates from a condition
+ predicate, 0 if the equality is the result of row
+ elimination
+ @param cond_equal multiple equalities that must hold together with the
+ equality
+
+ @retval
TRUE if the predicate is a simple equality predicate to be used
- for building multiple equalities
+ for building multiple equalities
+ @retval
FALSE otherwise
*/
@@ -7286,30 +7326,30 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
}
-/*
- Convert row equalities into a conjunction of regular equalities
-
- SYNOPSIS
- check_row_equality()
- thd thread handle
- left_row left term of the row equality to be processed
- right_row right term of the row equality to be processed
- cond_equal multiple equalities that must hold together with the predicate
- eq_list results of conversions of row equalities that are not simple
- enough to form multiple equalities
+/**
+ Convert row equalities into a conjunction of regular equalities.
- DESCRIPTION
The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
- Ei=E'i the function checks whether it is a simple equality or a row equality.
- If it is a simple equality it is used to expand multiple equalities of
- cond_equal. If it is a row equality it converted to a sequence of equalities
- between row elements. If Ei=E'i is neither a simple equality nor a row
- equality the item for this predicate is added to eq_list.
-
- RETURN
- TRUE if conversion has succeeded (no fatal error)
- FALSE otherwise
+ Ei=E'i the function checks whether it is a simple equality or a row
+ equality. If it is a simple equality it is used to expand multiple
+ equalities of cond_equal. If it is a row equality it converted to a
+ sequence of equalities between row elements. If Ei=E'i is neither a
+ simple equality nor a row equality the item for this predicate is added
+ to eq_list.
+
+ @param thd thread handle
+ @param left_row left term of the row equality to be processed
+ @param right_row right term of the row equality to be processed
+ @param cond_equal multiple equalities that must hold together with the
+ predicate
+ @param eq_list results of conversions of row equalities that are not
+ simple enough to form multiple equalities
+
+ @retval
+ TRUE if conversion has succeeded (no fatal error)
+ @retval
+ FALSE otherwise
*/
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
@@ -7351,18 +7391,9 @@ static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
}
-/*
- Eliminate row equalities and form multiple equalities predicates
-
- SYNOPSIS
- check_equality()
- thd thread handle
- item predicate to process
- cond_equal multiple equalities that must hold together with the predicate
- eq_list results of conversions of row equalities that are not simple
- enough to form multiple equalities
+/**
+ Eliminate row equalities and form multiple equalities predicates.
- DESCRIPTION
This function checks whether the item is a simple equality
i.e. the one that equates a field with another field or a constant
(field=field_item or field=constant_item), or, a row equality.
@@ -7370,11 +7401,20 @@ static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
in the lists referenced directly or indirectly by cond_equal inferring
the given simple equality. If it doesn't find any, it builds/expands
multiple equality that covers the predicate.
- Row equalities are eliminated substituted for conjunctive regular equalities
- which are treated in the same way as original equality predicates.
-
- RETURN
+ Row equalities are eliminated substituted for conjunctive regular
+ equalities which are treated in the same way as original equality
+ predicates.
+
+ @param thd thread handle
+ @param item predicate to process
+ @param cond_equal multiple equalities that must hold together with the
+ predicate
+ @param eq_list results of conversions of row equalities that are not
+ simple enough to form multiple equalities
+
+ @retval
TRUE if re-writing rules have been applied
+ @retval
FALSE otherwise, i.e.
if the predicate is not an equality,
or, if the equality is neither a simple one nor a row equality,
@@ -7406,16 +7446,9 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
}
-/*
- Replace all equality predicates in a condition by multiple equality items
-
- SYNOPSIS
- build_equal_items_for_cond()
- thd thread handle
- cond condition(expression) where to make replacement
- inherited path to all inherited multiple equality items
+/**
+ Replace all equality predicates in a condition by multiple equality items.
- DESCRIPTION
At each 'and' level the function detects items for equality predicates
and replaced them by a set of multiple equality items of class Item_equal,
taking into account inherited equalities from upper levels.
@@ -7434,7 +7467,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
equality lists of each Item_cond_and object assigning it to
thd->lex->current_select->max_equal_elems.
- NOTES
+ @note
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
f1=f2, .., fn-1=fn. It substitutes any inference from these
equality predicates that is equivalent to the conjunction.
@@ -7452,7 +7485,6 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
but if additionally =(t4.d,t2.b) is inherited, it
will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)
- IMPLEMENTATION
The function performs the substitution in a recursive descent by
the condtion tree, passing to the next AND level a chain of multiple
equality predicates which have been built at the upper levels.
@@ -7466,10 +7498,15 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
- join them into disjoint Item_equal() groups
- process the included OR conditions recursively to do the same for
lower AND levels.
+
We need to do things in this order as lower AND levels need to know about
all possible Item_equal objects in upper levels.
- RETURN
+ @param thd thread handle
+ @param cond condition(expression) where to make replacement
+ @param inherited path to all inherited multiple equality items
+
+ @return
pointer to the transformed condition
*/
@@ -7617,19 +7654,10 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
}
-/*
+/**
Build multiple equalities for a condition and all on expressions that
- inherit these multiple equalities
+ inherit these multiple equalities.
- SYNOPSIS
- build_equal_items()
- thd thread handle
- cond condition to build the multiple equalities for
- inherited path to all inherited multiple equality items
- join_list list of join tables to which the condition refers to
- cond_equal_ref :out pointer to the structure to place built equalities in
-
- DESCRIPTION
The function first applies the build_equal_items_for_cond function
to build all multiple equalities for condition cond utilizing equalities
referred through the parameter inherited. The extended set of
@@ -7638,14 +7666,16 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
all on expressions whose direct references can be found in join_list
and who inherit directly the multiple equalities just having built.
- NOTES
+ @note
The on expression used in an outer join operation inherits all equalities
- from the on expression of the embedding join, if there is any, or
+ from the on expression of the embedding join, if there is any, or
otherwise - from the where condition.
This fact is not obvious, but presumably can be proved.
Consider the following query:
+ @code
SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
WHERE t1.a=t2.a;
+ @endcode
If the on expression in the query inherits =(t1.a,t2.a), then we
can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
the equality t3.a=t4.a. Although the on expression
@@ -7655,23 +7685,38 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
to use t1.a=t3.a AND t3.a=t4.a under the on condition:
+ @code
SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
WHERE t1.a=t2.a
+ @endcode
This query equivalent to:
+ @code
SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
WHERE t1.a=t2.a
+ @endcode
Similarly the original query can be rewritten to the query:
+ @code
SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
WHERE t1.a=t2.a
+ @endcode
that is equivalent to:
+ @code
SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
WHERE t1.a=t2.a
+ @endcode
Thus, applying equalities from the where condition we basically
can get more freedom in performing join operations.
Althogh we don't use this property now, it probably makes sense to use
it in the future.
-
- RETURN
+ @param thd Thread handler
+ @param cond condition to build the multiple equalities for
+ @param inherited path to all inherited multiple equality items
+ @param join_list list of join tables to which the condition
+ refers to
+ @param[out] cond_equal_ref pointer to the structure to place built
+ equalities in
+
+ @return
pointer to the transformed condition containing multiple equalities
*/
@@ -7729,25 +7774,24 @@ static COND *build_equal_items(THD *thd, COND *cond,
}
-/*
- Compare field items by table order in the execution plan
-
- SYNOPSIS
- compare_fields_by_table_order()
- field1 first field item to compare
- field2 second field item to compare
- table_join_idx index to tables determining table order
+/**
+ Compare field items by table order in the execution plan.
- DESCRIPTION
field1 considered as better than field2 if the table containing
field1 is accessed earlier than the table containing field2.
The function finds out what of two fields is better according
this criteria.
- RETURN
- 1, if field1 is better than field2
- -1, if field2 is better than field1
- 0, otherwise
+ @param field1 first field item to compare
+ @param field2 second field item to compare
+ @param table_join_idx index to tables determining table order
+
+ @retval
+ 1 if field1 is better than field2
+ @retval
+ -1 if field2 is better than field1
+ @retval
+ 0 otherwise
*/
static int compare_fields_by_table_order(Item_field *field1,
@@ -7774,16 +7818,9 @@ static int compare_fields_by_table_order(Item_field *field1,
}
-/*
- Generate minimal set of simple equalities equivalent to a multiple equality
-
- SYNOPSIS
- eliminate_item_equal()
- cond condition to add the generated equality to
- upper_levels structure to access multiple equality of upper levels
- item_equal multiple equality to generate simple equality from
+/**
+ Generate minimal set of simple equalities equivalent to a multiple equality.
- DESCRIPTION
The function retrieves the fields of the multiple equality item
item_equal and for each field f:
- if item_equal contains const it generates the equality f=const_item;
@@ -7791,7 +7828,11 @@ static int compare_fields_by_table_order(Item_field *field1,
f=item_equal->get_first().
All generated equality are added to the cond conjunction.
- NOTES
+ @param cond condition to add the generated equality to
+ @param upper_levels structure to access multiple equality of upper levels
+ @param item_equal multiple equality to generate simple equality from
+
+ @note
Before generating an equality function checks that it has not
been generated for multiple equalities of the upper levels.
E.g. for the following where condition
@@ -7811,10 +7852,10 @@ static int compare_fields_by_table_order(Item_field *field1,
If cond is equal to 0, then not more then one equality is generated
and a pointer to it is returned as the result of the function.
- RETURN
- The condition with generated simple equalities or
+ @return
+ - The condition with generated simple equalities or
a pointer to the simple generated equality, if success.
- 0, otherwise.
+ - 0, otherwise.
*/
static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
@@ -7889,17 +7930,10 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
}
-/*
- Substitute every field reference in a condition by the best equal field
- and eliminate all multiple equality predicates
-
- SYNOPSIS
- substitute_for_best_equal_field()
- cond condition to process
- cond_equal multiple equalities to take into consideration
- table_join_idx index to tables determining field preference
+/**
+ Substitute every field reference in a condition by the best equal field
+ and eliminate all multiple equality predicates.
- DESCRIPTION
The function retrieves the cond condition and for each encountered
multiple equality predicate it sorts the field references in it
according to the order of tables specified by the table_join_idx
@@ -7910,14 +7944,17 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
After this the function retrieves all other conjuncted
predicates substitute every field reference by the field reference
to the first equal field or equal constant if there are any.
-
- NOTES
+ @param cond condition to process
+ @param cond_equal multiple equalities to take into consideration
+ @param table_join_idx index to tables determining field preference
+
+ @note
At the first glance full sort of fields in multiple equality
seems to be an overkill. Yet it's not the case due to possible
new fields in multiple equality item of lower levels. We want
the order in them to comply with the order of upper levels.
- RETURN
+ @return
The transformed condition
*/
@@ -7992,20 +8029,17 @@ static COND* substitute_for_best_equal_field(COND *cond,
}
-/*
+/**
Check appearance of new constant items in multiple equalities
- of a condition after reading a constant table
-
- SYNOPSIS
- update_const_equal_items()
- cond condition whose multiple equalities are to be checked
- table constant table that has been read
+ of a condition after reading a constant table.
- DESCRIPTION
The function retrieves the cond condition and for each encountered
multiple equality checks whether new constants have appeared after
reading the constant (single row) table tab. If so it adjusts
the multiple equality appropriately.
+
+ @param cond condition whose multiple equalities are to be checked
+ @param table constant table that has been read
*/
static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
@@ -8144,14 +8178,12 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
}
}
-/*
- Remove additional condition inserted by IN/ALL/ANY transformation
+/**
+ Remove additional condition inserted by IN/ALL/ANY transformation.
- SYNOPSIS
- remove_additional_cond()
- conds Condition for processing
+ @param conds condition for processing
- RETURN VALUES
+ @return
new conditions
*/
@@ -8239,17 +8271,10 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
}
-/*
- Simplify joins replacing outer joins by inner joins whenever it's possible
-
- SYNOPSIS
- simplify_joins()
- join reference to the query info
- join_list list representation of the join to be converted
- conds conditions to add on expressions for converted joins
- top true <=> conds is the where condition
+/**
+ Simplify joins replacing outer joins by inner joins whenever it's
+ possible.
- DESCRIPTION
The function, during a retrieval of join_list, eliminates those
outer joins that can be converted into inner join, possibly nested.
It also moves the on expressions for the converted outer joins
@@ -8273,26 +8298,39 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
The function also removes all braces that can be removed from the join
expression without changing its meaning.
- NOTES
+ @note
An outer join can be replaced by an inner join if the where condition
or the on expression for an embedding nested join contains a conjunctive
predicate rejecting null values for some attribute of the inner tables.
E.g. in the query:
+ @code
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
+ @endcode
the predicate t2.b < 5 rejects nulls.
The query is converted first to:
+ @code
SELECT * FROM t1 INNER JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
+ @endcode
then to the equivalent form:
- SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a.
+ @code
+ SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a
+ @endcode
+
Similarly the following query:
+ @code
SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b
WHERE t2.c < 5
+ @endcode
is converted to:
+ @code
SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b
+ @endcode
+
One conversion might trigger another:
+ @code
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a
LEFT JOIN t3 ON t3.b=t2.b
WHERE t3 IS NOT NULL =>
@@ -8300,16 +8338,26 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
WHERE t3 IS NOT NULL AND t3.b=t2.b =>
SELECT * FROM t1, t2, t3
WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a
-
+ @endcode
+
The function removes all unnecessary braces from the expression
produced by the conversions.
- E.g. SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
+ E.g.
+ @code
+ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
+ @endcode
finally is converted to:
+ @code
SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
+ @endcode
+
+
It also will remove braces from the following queries:
+ @code
SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b
SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b.
+ @endcode
The benefit of this simplification procedure is that it might return
a query for which the optimizer can evaluate execution plan with more
@@ -8317,20 +8365,26 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
consider any plan where one of the inner tables is before some of outer
tables.
- IMPLEMENTATION.
+
The function is implemented by a recursive procedure. On the recursive
ascent all attributes are calculated, all outer joins that can be
converted are replaced and then all unnecessary braces are removed.
As join list contains join tables in the reverse order sequential
elimination of outer joins does not require extra recursive calls.
- EXAMPLES
Here is an example of a join query with invalid cross references:
+ @code
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
-
- RETURN VALUE
- The new condition, if success
- 0, otherwise
+ @endcode
+
+ @param join reference to the query info
+ @param join_list list representation of the join to be converted
+ @param conds conditions to add on expressions for converted joins
+ @param top true <=> conds is the where condition
+
+ @return
+ - The new condition, if success
+ - 0, otherwise
*/
static COND *
@@ -8492,26 +8546,23 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
}
-/*
- Assign each nested join structure a bit in nested_join_map
-
- SYNOPSIS
- build_bitmap_for_nested_joins()
- join Join being processed
- join_list List of tables
- first_unused Number of first unused bit in nested_join_map before the
- call
+/**
+ Assign each nested join structure a bit in nested_join_map.
- DESCRIPTION
Assign each nested join structure (except "confluent" ones - those that
embed only one element) a bit in nested_join_map.
- NOTE
+ @param join Join being processed
+ @param join_list List of tables
+ @param first_unused Number of first unused bit in nested_join_map before the
+ call
+
+ @note
This function is called after simplify_joins(), when there are no
redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
we will not run out of bits in nested_join_map.
- RETURN
+ @return
First unused bit in nested_join_map after the call.
*/
@@ -8547,17 +8598,14 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
}
-/*
- Set NESTED_JOIN::counter=0 in all nested joins in passed list
-
- SYNOPSIS
- reset_nj_counters()
- join_list List of nested joins to process. It may also contain base
- tables which will be ignored.
+/**
+ Set NESTED_JOIN::counter=0 in all nested joins in passed list.
- DESCRIPTION
Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
the passed join_list.
+
+ @param join_list List of nested joins to process. It may also contain base
+ tables which will be ignored.
*/
static void reset_nj_counters(List<TABLE_LIST> *join_list)
@@ -8578,95 +8626,96 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
}
-/*
- Check interleaving with an inner tables of an outer join for extension table
-
- SYNOPSIS
- check_interleaving_with_nj()
- join Join being processed
- last_tab Last table in current partial join order (this function is
- not called for empty partial join orders)
- next_tab Table we're going to extend the current partial join with
+/**
+ Check interleaving with an inner tables of an outer join for
+ extension table.
- DESCRIPTION
Check if table next_tab can be added to current partial join order, and
if yes, record that it has been added.
The function assumes that both current partial join order and its
extension with next_tab are valid wrt table dependencies.
- IMPLEMENTATION
- LIMITATIONS ON JOIN ORDER
- The nested [outer] joins executioner algorithm imposes these limitations
- on join order:
- 1. "Outer tables first" - any "outer" table must be before any
- corresponding "inner" table.
- 2. "No interleaving" - tables inside a nested join must form a continuous
- sequence in join order (i.e. the sequence must not be interrupted by
- tables that are outside of this nested join).
-
- #1 is checked elsewhere, this function checks #2 provided that #1 has
- been already checked.
-
- WHY NEED NON-INTERLEAVING
- Consider an example:
-
- select * from t0 join t1 left join (t2 join t3) on cond1
-
- The join order "t1 t2 t0 t3" is invalid:
-
- table t0 is outside of the nested join, so WHERE condition for t0 is
- attached directly to t0 (without triggers, and it may be used to access
- t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
- combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
- null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
- been produced.
-
- If table t0 is not between t2 and t3, the problem doesn't exist:
- * If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
- processing has finished.
- * If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
- wrapped into condition triggers, which takes care of correct nested
- join processing.
-
- HOW IT IS IMPLEMENTED
- The limitations on join order can be rephrased as follows: for valid
- join order one must be able to:
- 1. write down the used tables in the join order on one line.
- 2. for each nested join, put one '(' and one ')' on the said line
- 3. write "LEFT JOIN" and "ON (...)" where appropriate
- 4. get a query equivalent to the query we're trying to execute.
-
- Calls to check_interleaving_with_nj() are equivalent to writing the
- above described line from left to right.
- A single check_interleaving_with_nj(A,B) call is equivalent to writing
- table B and appropriate brackets on condition that table A and
- appropriate brackets is the last what was written. Graphically the
- transition is as follows:
-
- +---- current position
- |
- ... last_tab ))) | ( next_tab ) )..) | ...
- X Y Z |
- +- need to move to this
- position.
-
- Notes about the position:
- The caller guarantees that there is no more then one X-bracket by
- checking "!(remaining_tables & s->dependent)" before calling this
- function. X-bracket may have a pair in Y-bracket.
-
- When "writing" we store/update this auxilary info about the current
- position:
- 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
- joins) we've opened but didn't close.
- 2. {each NESTED_JOIN structure not simplified away}->counter - number
- of this nested join's children that have already been added to to
- the partial join order.
-
- RETURN
- FALSE Join order extended, nested joins info about current join order
- (see NOTE section) updated.
+ @verbatim
+ IMPLEMENTATION
+ LIMITATIONS ON JOIN ORDER
+ The nested [outer] joins executioner algorithm imposes these limitations
+ on join order:
+ 1. "Outer tables first" - any "outer" table must be before any
+ corresponding "inner" table.
+ 2. "No interleaving" - tables inside a nested join must form a continuous
+ sequence in join order (i.e. the sequence must not be interrupted by
+ tables that are outside of this nested join).
+
+ #1 is checked elsewhere, this function checks #2 provided that #1 has
+ been already checked.
+
+ WHY NEED NON-INTERLEAVING
+ Consider an example:
+
+ select * from t0 join t1 left join (t2 join t3) on cond1
+
+ The join order "t1 t2 t0 t3" is invalid:
+
+ table t0 is outside of the nested join, so WHERE condition for t0 is
+ attached directly to t0 (without triggers, and it may be used to access
+ t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
+ combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
+ null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
+ been produced.
+
+ If table t0 is not between t2 and t3, the problem doesn't exist:
+ If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
+ processing has finished.
+ If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
+ wrapped into condition triggers, which takes care of correct nested
+ join processing.
+
+ HOW IT IS IMPLEMENTED
+ The limitations on join order can be rephrased as follows: for valid
+ join order one must be able to:
+ 1. write down the used tables in the join order on one line.
+ 2. for each nested join, put one '(' and one ')' on the said line
+ 3. write "LEFT JOIN" and "ON (...)" where appropriate
+ 4. get a query equivalent to the query we're trying to execute.
+
+ Calls to check_interleaving_with_nj() are equivalent to writing the
+ above described line from left to right.
+ A single check_interleaving_with_nj(A,B) call is equivalent to writing
+ table B and appropriate brackets on condition that table A and
+ appropriate brackets is the last what was written. Graphically the
+ transition is as follows:
+
+ +---- current position
+ |
+ ... last_tab ))) | ( next_tab ) )..) | ...
+ X Y Z |
+ +- need to move to this
+ position.
+
+ Notes about the position:
+ The caller guarantees that there is no more then one X-bracket by
+ checking "!(remaining_tables & s->dependent)" before calling this
+ function. X-bracket may have a pair in Y-bracket.
+
+ When "writing" we store/update this auxilary info about the current
+ position:
+ 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
+ joins) we've opened but didn't close.
+ 2. {each NESTED_JOIN structure not simplified away}->counter - number
+ of this nested join's children that have already been added to to
+ the partial join order.
+ @endverbatim
+
+ @param join Join being processed
+ @param last_tab Last table in current partial join order (this function is
+ not called for empty partial join orders)
+ @param next_tab Table we're going to extend the current partial join with
+
+ @retval
+ FALSE Join order extended, nested joins info about current join
+ order (see NOTE section) updated.
+ @retval
TRUE Requested join order extension not allowed.
*/
@@ -8715,19 +8764,16 @@ static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
}
-/*
- Nested joins perspective: Remove the last table from the join order
+/**
+ Nested joins perspective: Remove the last table from the join order.
- SYNOPSIS
- restore_prev_nj_state()
- last join table to remove, it is assumed to be the last in current
- partial join order.
-
- DESCRIPTION
Remove the last table from the partial join order and update the nested
joins counters and join->cur_embedding_map. It is ok to call this
function for the first table in join order (for which
check_interleaving_with_nj has not been called)
+
+ @param last join table to remove, it is assumed to be the last in current
+ partial join order.
*/
static void restore_prev_nj_state(JOIN_TAB *last)
@@ -8786,12 +8832,15 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
}
-/*
- Remove const and eq items. Return new item, or NULL if no condition
- cond_value is set to according:
- COND_OK query is possible (field = constant)
- COND_TRUE always true ( 1 = 1 )
- COND_FALSE always false ( 1 = 2 )
+/**
+ Remove const and eq items.
+
+ @return
+ Return new item, or NULL if no condition @n
+ cond_value is set to according:
+ - COND_OK : query is possible (field = constant)
+ - COND_TRUE : always true ( 1 = 1 )
+ - COND_FALSE : always false ( 1 = 2 )
*/
COND *
@@ -8982,8 +9031,8 @@ test_if_equality_guarantees_uniqueness(Item *l, Item *r)
l->collation.collation == r->collation.collation)));
}
-/*
- Return 1 if the item is a const value in all the WHERE clause
+/**
+ Return TRUE if the item is a const value in all the WHERE clause.
*/
static bool
@@ -9044,26 +9093,25 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
Create internal temporary table
****************************************************************************/
-/*
- Create field for temporary table from given field
-
- SYNOPSIS
- create_tmp_field_from_field()
- thd Thread handler
- org_field field from which new field will be created
- name New field name
- table Temporary table
- item !=NULL if item->result_field should point to new field.
- This is relevant for how fill_record() is going to work:
- If item != NULL then fill_record() will update
- the record in the original table.
- If item == NULL then fill_record() will update
- the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
- instead of blob.
-
- RETURN
- 0 on error
+/**
+ Create field for temporary table from given field.
+
+ @param thd Thread handler
+ @param org_field field from which new field will be created
+ @param name New field name
+ @param table Temporary table
+ @param item !=NULL if item->result_field should point to new field.
+ This is relevant for how fill_record() is going to work:
+ If item != NULL then fill_record() will update
+ the record in the original table.
+ If item == NULL then fill_record() will update
+ the temporary table
+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
+ field instead of blob.
+
+ @retval
+ NULL on error
+ @retval
new_created field
*/
@@ -9106,28 +9154,27 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
return new_field;
}
-/*
- Create field for temporary table using type of given item
-
- SYNOPSIS
- create_tmp_field_from_item()
- thd Thread handler
- item Item to create a field for
- table Temporary table
- copy_func If set and item is a function, store copy of item
- in this array
- modify_item 1 if item->result_field should point to new item.
- This is relevent for how fill_record() is going to
- work:
- If modify_item is 1 then fill_record() will update
- the record in the original table.
- If modify_item is 0 then fill_record() will update
- the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
- instead of blob.
-
- RETURN
- 0 on error
+/**
+ Create field for temporary table using type of given item.
+
+ @param thd Thread handler
+ @param item Item to create a field for
+ @param table Temporary table
+ @param copy_func If set and item is a function, store copy of
+ item in this array
+ @param modify_item 1 if item->result_field should point to new
+ item. This is relevent for how fill_record()
+ is going to work:
+ If modify_item is 1 then fill_record() will
+ update the record in the original table.
+ If modify_item is 0 then fill_record() will
+ update the temporary table
+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
+ field instead of blob.
+
+ @retval
+ 0 on error
+ @retval
new_created field
*/
@@ -9206,17 +9253,16 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
}
-/*
- Create field for information schema table
+/**
+ Create field for information schema table.
- SYNOPSIS
- create_tmp_field_for_schema()
- thd Thread handler
- table Temporary table
- item Item to create a field for
+ @param thd Thread handler
+ @param table Temporary table
+ @param item Item to create a field for
- RETURN
+ @retval
0 on error
+ @retval
new_created field
*/
@@ -9240,33 +9286,32 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
}
-/*
- Create field for temporary table
-
- SYNOPSIS
- create_tmp_field()
- thd Thread handler
- table Temporary table
- item Item to create a field for
- type Type of item (normally item->type)
- copy_func If set and item is a function, store copy of item
- in this array
- from_field if field will be created using other field as example,
- pointer example field will be written here
- default_field If field has a default value field, store it here
- group 1 if we are going to do a relative group by on result
- modify_item 1 if item->result_field should point to new item.
- This is relevent for how fill_record() is going to
- work:
- If modify_item is 1 then fill_record() will update
- the record in the original table.
- If modify_item is 0 then fill_record() will update
- the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
- instead of blob.
-
- RETURN
+/**
+ Create field for temporary table.
+
+ @param thd Thread handler
+ @param table Temporary table
+ @param item Item to create a field for
+ @param type Type of item (normally item->type)
+ @param copy_func If set and item is a function, store copy of item
+ in this array
+ @param from_field if field will be created using other field as example,
+ pointer example field will be written here
+ @param default_field If field has a default value field, store it here
+ @param group 1 if we are going to do a relative group by on result
+ @param modify_item 1 if item->result_field should point to new item.
+ This is relevent for how fill_record() is going to
+ work:
+ If modify_item is 1 then fill_record() will update
+ the record in the original table.
+ If modify_item is 0 then fill_record() will update
+ the temporary table
+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
+ field instead of blob.
+
+ @retval
0 on error
+ @retval
new_created field
*/
@@ -9397,33 +9442,30 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
}
-/*
+/**
Create a temp table according to a field list.
- SYNOPSIS
- create_tmp_table()
- thd thread handle
- param a description used as input to create the table
- fields list of items that will be used to define
- column types of the table (also see NOTES)
- group TODO document
- distinct should table rows be distinct
- save_sum_fields see NOTES
- select_options
- rows_limit
- table_alias possible name of the temporary table that can be used
- for name resolving; can be "".
-
- DESCRIPTION
- Given field pointers are changed to point at tmp_table for
- send_fields. The table object is self contained: it's
- allocated in its own memory root, as well as Field objects
- created for table columns.
- This function will replace Item_sum items in 'fields' list with
- corresponding Item_field items, pointing at the fields in the
- temporary table, unless this was prohibited by TRUE
- value of argument save_sum_fields. The Item_field objects
- are created in THD memory root.
+ Given field pointers are changed to point at tmp_table for
+ send_fields. The table object is self contained: it's
+ allocated in its own memory root, as well as Field objects
+ created for table columns.
+ This function will replace Item_sum items in 'fields' list with
+ corresponding Item_field items, pointing at the fields in the
+ temporary table, unless this was prohibited by TRUE
+ value of argument save_sum_fields. The Item_field objects
+ are created in THD memory root.
+
+ @param thd thread handle
+ @param param a description used as input to create the table
+ @param fields list of items that will be used to define
+ column types of the table (also see NOTES)
+ @param group TODO document
+ @param distinct should table rows be distinct
+ @param save_sum_fields see NOTES
+ @param select_options
+ @param rows_limit
+ @param table_alias possible name of the temporary table that can
+ be used for name resolving; can be "".
*/
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
@@ -10094,16 +10136,10 @@ err:
/****************************************************************************/
-/*
+/**
Create a reduced TABLE object with properly set up Field list from a
list of field definitions.
- SYNOPSIS
- create_virtual_tmp_table()
- thd connection handle
- field_list list of column definitions
-
- DESCRIPTION
The created table doesn't have a table handler associated with
it, has no keys, no group/distinct, no copy_funcs array.
The sole purpose of this TABLE object is to use the power of Field
@@ -10112,7 +10148,10 @@ err:
The table is created in THD mem_root, so are the table's fields.
Consequently, if you don't BLOB fields, you don't need to free it.
- RETURN
+ @param thd connection handle
+ @param field_list list of column definitions
+
+ @return
0 if out of memory, TABLE object in case of success
*/
@@ -10385,8 +10424,9 @@ free_tmp_table(THD *thd, TABLE *entry)
DBUG_VOID_RETURN;
}
-/*
-* If a HEAP table gets full, create a MyISAM table and copy all rows to this
+/**
+ If a HEAP table gets full, create a MyISAM table and copy all rows
+ to this.
*/
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
@@ -10496,17 +10536,15 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
-/*
- SYNOPSIS
- setup_end_select_func()
- join join to setup the function for.
+/**
+ @details
+ Rows produced by a join sweep may end up in a temporary table or be sent
+ to a client. Setup the function of the nested loop join algorithm which
+ handles final fully constructed and matched records.
- DESCRIPTION
- Rows produced by a join sweep may end up in a temporary table or be sent
- to a client. Setup the function of the nested loop join algorithm which
- handles final fully constructed and matched records.
+ @param join join to setup the function for.
- RETURN
+ @return
end_select function to use. This function can't fail.
*/
@@ -10570,12 +10608,16 @@ Next_select_func setup_end_select_func(JOIN *join)
}
-/****************************************************************************
- Make a join of all tables and write it on socket or to table
- Return: 0 if ok
- 1 if error is sent
- -1 if error should be sent
-****************************************************************************/
+/**
+ Make a join of all tables and write it on socket or to table.
+
+ @retval
+ 0 if ok
+ @retval
+ 1 if error is sent
+ @retval
+ -1 if error should be sent
+*/
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
@@ -10713,30 +10755,25 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
return rc;
}
-/*
- Retrieve records ends with a given beginning from the result of a join
-
- SYNPOSIS
- sub_select()
- join pointer to the structure providing all context info for the query
- join_tab the first next table of the execution plan to be retrieved
- end_records true when we need to perform final steps of retrival
+/**
+ Retrieve records ends with a given beginning from the result of a join.
- DESCRIPTION
For a given partial join record consisting of records from the tables
preceding the table join_tab in the execution plan, the function
retrieves all matching full records from the result set and
send them to the result set stream.
- NOTES
+ @note
The function effectively implements the final (n-k) nested loops
of nested loops join algorithm, where k is the ordinal number of
the join_tab table and n is the total number of tables in the join query.
It performs nested loops joins with all conjunctive predicates from
the where condition pushed as low to the tables as possible.
E.g. for the query
- SELECT * FROM t1,t2,t3
- WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
+ @code
+ SELECT * FROM t1,t2,t3
+ WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
+ @endcode
the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1,
given the selected plan prescribes to nest retrievals of the
joined tables in the following order: t1,t2,t3.
@@ -10752,9 +10789,11 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
the execution plan. In this case the pushed down predicates can be
checked only at certain conditions.
Suppose for the query
- SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
- WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
- the optimizer has chosen a plan with the table order t1,t2,t3.
+ @code
+ SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
+ WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
+ @endcode
+ the optimizer has chosen a plan with the table order t1,t2,t3.
The predicate P1=t1>2 will be pushed down to the table t1, while the
predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table
t2. But the second predicate can not be unconditionally tested right
@@ -10782,7 +10821,9 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
been done for the first row with a match. The only difference is
the predicates from on expressions are not checked.
- IMPLEMENTATION
+ @par
+ @b IMPLEMENTATION
+ @par
The function forms output rows for a current partial join of k
tables tables recursively.
For each partial join record ending with a certain row from
@@ -10798,11 +10839,13 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
To carry out a return to a nested loop level of join table t the pointer
to t is remembered in the field 'return_tab' of the join structure.
Consider the following query:
- SELECT * FROM t1,
- LEFT JOIN
- (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a)
- ON t4.a=t2.a
- WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL)
+ @code
+ SELECT * FROM t1,
+ LEFT JOIN
+ (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a)
+ ON t4.a=t2.a
+ WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL)
+ @endcode
Suppose the chosen execution plan dictates the order t1,t2,t3,t4,t5
and suppose for a given joined rows from tables t1,t2,t3 there are
no rows in the result set yet.
@@ -10817,11 +10860,18 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
Thus, when the first row from t5 with t5.a=t3.a is found
this pointer for t5 is changed from t4 to t2.
- STRUCTURE NOTES
+ @par
+ @b STRUCTURE @b NOTES
+ @par
join_tab->first_unmatched points always backwards to the first inner
table of the embedding nested join, if any.
- RETURN
+ @param join pointer to the structure providing all context info for
+ the query
+ @param join_tab the first next table of the execution plan to be retrieved
+ @param end_records true when we need to perform final steps of retrival
+
+ @return
return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
*/
@@ -10885,10 +10935,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
}
-/*
+/**
Process one record of the nested loop join.
- DESCRIPTION
This function will evaluate parts of WHERE/ON clauses that are
applicable to the partial record on hand and in case of success
submit this record to the next level of the nested loop.
@@ -11012,8 +11061,9 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
}
-/*
- DESCRIPTION
+/**
+
+ @details
Construct a NULL complimented partial join record and feed it to the next
level of the nested loop. This function is used in case we have
an OUTER join and no matching record was found.
@@ -11157,7 +11207,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
Returns -1 if row was not found, 0 if row was found and 1 on errors
*****************************************************************************/
-/* Help function when we get some an error from the table handler */
+/** Help function when we get some an error from the table handler. */
int report_error(TABLE *table, int error)
{
@@ -11296,17 +11346,17 @@ join_read_system(JOIN_TAB *tab)
}
-/*
- Read a table when there is at most one matching row
+/**
+ Read a table when there is at most one matching row.
- SYNOPSIS
- join_read_const()
- tab Table to read
+ @param tab Table to read
- RETURN
+ @retval
0 Row was found
- -1 Row was not found
- 1 Got an error (other than row not found) during read
+ @retval
+ -1 Row was not found
+ @retval
+ 1 Got an error (other than row not found) during read
*/
static int
@@ -11407,9 +11457,9 @@ join_read_always_key(JOIN_TAB *tab)
}
-/*
+/**
This function is used when optimizing away ORDER BY in
- SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC.
*/
static int
@@ -11624,8 +11674,8 @@ join_ft_read_next(READ_RECORD *info)
}
-/*
- Reading of key with key reference and one part that may be NULL
+/**
+ Reading of key with key reference and one part that may be NULL.
*/
int
@@ -11934,8 +11984,8 @@ end:
DBUG_RETURN(NESTED_LOOP_OK);
}
-/* Group by searching after group record and updating it if possible */
/* ARGSUSED */
+/** Group by searching after group record and updating it if possible. */
static enum_nested_loop_state
end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
@@ -12010,7 +12060,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
-/* Like end_update, but this is done with unique constraints instead of keys */
+/** Like end_update, but this is done with unique constraints instead of keys. */
static enum_nested_loop_state
end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
@@ -12141,7 +12191,10 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
in sorted order.
*****************************************************************************/
-/* Return 1 if right_item is used removable reference key on left_item */
+/**
+ @return
+ 1 if right_item is used removable reference key on left_item
+*/
static bool test_if_ref(Item_field *left_item,Item *right_item)
{
@@ -12291,26 +12344,26 @@ part_of_refkey(TABLE *table,Field *field)
}
-/*****************************************************************************
- Test if one can use the key to resolve ORDER BY
+/**
+ Test if one can use the key to resolve ORDER BY.
- SYNOPSIS
- test_if_order_by_key()
- order Sort order
- table Table to sort
- idx Index to check
- used_key_parts Return value for used key parts.
+ @param order Sort order
+ @param table Table to sort
+ @param idx Index to check
+ @param used_key_parts Return value for used key parts.
- NOTES
+ @note
used_key_parts is set to correct key parts used if return value != 0
(On other cases, used_key_part may be changed)
- RETURN
+ @retval
1 key is ok.
+ @retval
0 Key can't be used
- -1 Reverse key can be used
-*****************************************************************************/
+ @retval
+ -1 Reverse key can be used
+*/
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
uint *used_key_parts)
@@ -12405,20 +12458,19 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
return best;
}
-/*
+/**
Test if a second key is the subkey of the first one.
- SYNOPSIS
- is_subkey()
- key_part First key parts
- ref_key_part Second key parts
- ref_key_part_end Last+1 part of the second key
+ @param key_part First key parts
+ @param ref_key_part Second key parts
+ @param ref_key_part_end Last+1 part of the second key
- NOTE
+ @note
Second key MUST be shorter than the first one.
- RETURN
+ @retval
1 is a subkey
+ @retval
0 no sub key
*/
@@ -12432,17 +12484,16 @@ is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
return 1;
}
-/*
- Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting
+/**
+ Test if we can use one of the 'usable_keys' instead of 'ref' key
+ for sorting.
- SYNOPSIS
- test_if_subkey()
- ref Number of key, used for WHERE clause
- usable_keys Keys for testing
+ @param ref Number of key, used for WHERE clause
+ @param usable_keys Keys for testing
- RETURN
- MAX_KEY If we can't use other key
- the number of found key Otherwise
+ @return
+ - MAX_KEY If we can't use other key
+ - the number of found key Otherwise
*/
static uint
@@ -12473,24 +12524,19 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
}
-/*
+/**
Check if GROUP BY/DISTINCT can be optimized away because the set is
already known to be distinct.
-
- SYNOPSIS
- list_contains_unique_index ()
- table The table to operate on.
- find_func function to iterate over the list and search
- for a field
- DESCRIPTION
- Used in removing the GROUP BY/DISTINCT of the following types of
- statements:
- SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
- [GROUP BY <unique_key_cols>,...]
+ Used in removing the GROUP BY/DISTINCT of the following types of
+ statements:
+ @code
+ SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
+ [GROUP BY <unique_key_cols>,...]
+ @endcode
If (a,b,c is distinct)
- then <any combination of a,b,c>,{whatever} is also distinct
+ then <any combination of a,b,c>,{whatever} is also distinct
This function checks if all the key parts of any of the unique keys
of the table are referenced by a list : either the select list
@@ -12499,9 +12545,14 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
If the above holds and the key parts cannot contain NULLs then we
can safely remove the GROUP BY/DISTINCT,
as no result set can be more distinct than an unique key.
-
- RETURN VALUE
+
+ @param table The table to operate on.
+ @param find_func function to iterate over the list and search
+ for a field
+
+ @retval
1 found
+ @retval
0 not found.
*/
@@ -12534,20 +12585,17 @@ list_contains_unique_index(TABLE *table,
}
-/*
+/**
Helper function for list_contains_unique_index.
Find a field reference in a list of ORDER structures.
-
- SYNOPSIS
- find_field_in_order_list ()
- field The field to search for.
- data ORDER *.The list to search in
-
- DESCRIPTION
- Finds a direct reference of the Field in the list.
-
- RETURN VALUE
+ Finds a direct reference of the Field in the list.
+
+ @param field The field to search for.
+ @param data ORDER *.The list to search in
+
+ @retval
1 found
+ @retval
0 not found.
*/
@@ -12570,20 +12618,17 @@ find_field_in_order_list (Field *field, void *data)
}
-/*
+/**
Helper function for list_contains_unique_index.
Find a field reference in a dynamic list of Items.
-
- SYNOPSIS
- find_field_in_item_list ()
- field in The field to search for.
- data in List<Item> *.The list to search in
-
- DESCRIPTION
- Finds a direct reference of the Field in the list.
-
- RETURN VALUE
+ Finds a direct reference of the Field in the list.
+
+ @param[in] field The field to search for.
+ @param[in] data List<Item> *.The list to search in
+
+ @retval
1 found
+ @retval
0 not found.
*/
@@ -12608,15 +12653,20 @@ find_field_in_item_list (Field *field, void *data)
}
-/*
+/**
Test if we can skip the ORDER BY by using an index.
If we can use an index, the JOIN_TAB / tab->select struct
is changed to use the index.
- Return:
- 0 We have to use filesort to do the sorting
- 1 We can use an index.
+ @todo
+ - sergeyp: Results of all index merge selects actually are ordered
+ by clustered PK values.
+
+ @retval
+ 0 We have to use filesort to do the sorting
+ @retval
+ 1 We can use an index.
*/
static bool
@@ -13155,11 +13205,11 @@ err:
DBUG_RETURN(-1);
}
-/*
- Add the HAVING criteria to table->select
+#ifdef NOT_YET
+/**
+ Add the HAVING criteria to table->select.
*/
-#ifdef NOT_YET
static bool fix_having(JOIN *join, Item **having)
{
(*having)->update_used_tables(); // Some tables may have been const
@@ -13366,9 +13416,11 @@ err:
}
-/*
- Generate a hash index for each row to quickly find duplicate rows
- Note that this will not work on tables with blobs!
+/**
+ Generate a hash index for each row to quickly find duplicate rows.
+
+ @note
+ Note that this will not work on tables with blobs!
*/
static int remove_dup_with_hash_index(THD *thd, TABLE *table,
@@ -13805,37 +13857,37 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
Group and order functions
*****************************************************************************/
-/*
+/**
Resolve an ORDER BY or GROUP BY column reference.
- SYNOPSIS
- find_order_in_list()
- thd [in] Pointer to current thread structure
- ref_pointer_array [in/out] All select, group and order by fields
- tables [in] List of tables to search in (usually FROM clause)
- order [in] Column reference to be resolved
- fields [in] List of fields to search in (usually SELECT list)
- all_fields [in/out] All select, group and order by fields
- is_group_field [in] True if order is a GROUP field, false if
- ORDER by field
-
- DESCRIPTION
- Given a column reference (represented by 'order') from a GROUP BY or ORDER
- BY clause, find the actual column it represents. If the column being
- resolved is from the GROUP BY clause, the procedure searches the SELECT
- list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
- the ORDER BY clause, only the SELECT list is being searched.
-
- If 'order' is resolved to an Item, then order->item is set to the found
- Item. If there is no item for the found column (that is, it was resolved
- into a table field), order->item is 'fixed' and is added to all_fields and
- ref_pointer_array.
-
- RETURN
+ Given a column reference (represented by 'order') from a GROUP BY or ORDER
+ BY clause, find the actual column it represents. If the column being
+ resolved is from the GROUP BY clause, the procedure searches the SELECT
+ list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
+ the ORDER BY clause, only the SELECT list is being searched.
+
+ If 'order' is resolved to an Item, then order->item is set to the found
+ Item. If there is no item for the found column (that is, it was resolved
+ into a table field), order->item is 'fixed' and is added to all_fields and
+ ref_pointer_array.
+
+ ref_pointer_array and all_fields are updated.
+
+ @param[in] thd Pointer to current thread structure
+ @param[in,out] ref_pointer_array All select, group and order by fields
+ @param[in] tables List of tables to search in (usually
+ FROM clause)
+ @param[in] order Column reference to be resolved
+ @param[in] fields List of fields to search in (usually
+ SELECT list)
+ @param[in,out] all_fields All select, group and order by fields
+ @param[in] is_group_field True if order is a GROUP field, false if
+ ORDER by field
+
+ @retval
FALSE if OK
+ @retval
TRUE if error occurred
-
- ref_pointer_array and all_fields are updated
*/
static bool
@@ -13969,9 +14021,11 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
-/*
- Change order to point at item in select list. If item isn't a number
- and doesn't exits in the select list, add it the the field list.
+/**
+ Change order to point at item in select list.
+
+ If item isn't a number and doesn't exits in the select list, add it the
+ the field list.
*/
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
@@ -13988,27 +14042,30 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
-/*
+/**
Intitialize the GROUP BY list.
- SYNOPSIS
- setup_group()
- thd Thread handler
- ref_pointer_array We store references to all fields that was not in
- 'fields' here.
- fields All fields in the select part. Any item in 'order'
- that is part of these list is replaced by a pointer
- to this fields.
- all_fields Total list of all unique fields used by the select.
- All items in 'order' that was not part of fields will
- be added first to this list.
- order The fields we should do GROUP BY on.
- hidden_group_fields Pointer to flag that is set to 1 if we added any fields
- to all_fields.
-
- RETURN
- 0 ok
- 1 error (probably out of memory)
+ @param thd Thread handler
+ @param ref_pointer_array We store references to all fields that was
+ not in 'fields' here.
+ @param fields All fields in the select part. Any item in
+ 'order' that is part of these list is replaced
+ by a pointer to this fields.
+ @param all_fields Total list of all unique fields used by the
+ select. All items in 'order' that was not part
+ of fields will be added first to this list.
+ @param order The fields we should do GROUP BY on.
+ @param hidden_group_fields Pointer to flag that is set to 1 if we added
+ any fields to all_fields.
+
+ @todo
+ change ER_WRONG_FIELD_WITH_GROUP to more detailed
+ ER_NON_GROUPING_FIELD_USED
+
+ @retval
+ 0 ok
+ @retval
+ 1 error (probably out of memory)
*/
int
@@ -14101,8 +14158,11 @@ next_field:
return 0;
}
-/*
- Add fields with aren't used at start of field list. Return FALSE if ok
+/**
+ Add fields with aren't used at start of field list.
+
+ @return
+ FALSE if ok
*/
static bool
@@ -14132,10 +14192,11 @@ setup_new_fields(THD *thd, List<Item> &fields,
DBUG_RETURN(0);
}
-/*
- Create a group by that consist of all non const fields. Try to use
- the fields in the order given by 'order' to allow one to optimize
- away 'order by'.
+/**
+ Create a group by that consist of all non const fields.
+
+ Try to use the fields in the order given by 'order' to allow one to
+ optimize away 'order by'.
*/
static ORDER *
@@ -14222,9 +14283,9 @@ next_item:
}
-/*****************************************************************************
- Update join with count of the different type of fields
-*****************************************************************************/
+/**
+ Update join with count of the different type of fields.
+*/
void
count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
@@ -14274,8 +14335,9 @@ count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
}
-/*
- Return 1 if second is a subpart of first argument
+/**
+ Return 1 if second is a subpart of first argument.
+
If first parts has different direction, change it to second part
(group is sorted like order)
*/
@@ -14293,10 +14355,9 @@ test_if_subpart(ORDER *a,ORDER *b)
return test(!b);
}
-/*
+/**
Return table number if there is only one table in sort order
- and group and order is compatible
- else return 0;
+ and group and order is compatible, else return 0.
*/
static TABLE *
@@ -14327,7 +14388,9 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
}
- /* calc how big buffer we need for comparing group entries */
+/**
+ calc how big buffer we need for comparing group entries.
+*/
static void
calc_group_buffer(JOIN *join,ORDER *group)
@@ -14393,17 +14456,17 @@ calc_group_buffer(JOIN *join,ORDER *group)
}
-/*
- allocate group fields or take prepared (cached)
+/**
+ allocate group fields or take prepared (cached).
- SYNOPSIS
- make_group_fields()
- main_join - join of current select
- curr_join - current join (join of current select or temporary copy of it)
+ @param main_join join of current select
+ @param curr_join current join (join of current select or temporary copy
+ of it)
- RETURN
- 0 - ok
- 1 - failed
+ @retval
+ 0 ok
+ @retval
+ 1 failed
*/
static bool
@@ -14424,9 +14487,10 @@ make_group_fields(JOIN *main_join, JOIN *curr_join)
}
-/*
- Get a list of buffers for saveing last group
- Groups are saved in reverse order for easyer check loop
+/**
+ Get a list of buffers for saveing last group.
+
+ Groups are saved in reverse order for easyer check loop.
*/
static bool
@@ -14464,27 +14528,33 @@ test_if_group_changed(List<Cached_item> &list)
}
-/*
- Setup copy_fields to save fields at start of new group
+/**
+ Setup copy_fields to save fields at start of new group.
- setup_copy_fields()
- thd - THD pointer
- param - temporary table parameters
- ref_pointer_array - array of pointers to top elements of filed list
- res_selected_fields - new list of items of select item list
- res_all_fields - new list of all items
- elements - number of elements in select item list
- all_fields - all fields list
+ Setup copy_fields to save fields at start of new group
- DESCRIPTION
- Setup copy_fields to save fields at start of new group
- Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
- Change old item_field to use a new field with points at saved fieldvalue
- This function is only called before use of send_fields
-
- RETURN
- 0 - ok
- !=0 - error
+ Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
+ Change old item_field to use a new field with points at saved fieldvalue
+ This function is only called before use of send_fields.
+
+ @param thd THD pointer
+ @param param temporary table parameters
+ @param ref_pointer_array array of pointers to top elements of filed list
+ @param res_selected_fields new list of items of select item list
+ @param res_all_fields new list of all items
+ @param elements number of elements in select item list
+ @param all_fields all fields list
+
+ @todo
+ In most cases this result will be sent to the user.
+ This should be changed to use copy_int or copy_real depending
+ on how the value is to be used: In some cases this may be an
+ argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
+
+ @retval
+ 0 ok
+ @retval
+ !=0 error
*/
bool
@@ -14618,8 +14688,8 @@ err2:
}
-/*
- Make a copy of all simple SELECT'ed items
+/**
+ Make a copy of all simple SELECT'ed items.
This is done at the start of a new group so that we can retrieve
these later when the group changes.
@@ -14641,14 +14711,13 @@ copy_fields(TMP_TABLE_PARAM *param)
}
-/*
- Make an array of pointers to sum_functions to speed up sum_func calculation
-
- SYNOPSIS
- alloc_func_list()
+/**
+ Make an array of pointers to sum_functions to speed up
+ sum_func calculation.
- RETURN
+ @retval
0 ok
+ @retval
1 Error
*/
@@ -14693,18 +14762,17 @@ bool JOIN::alloc_func_list()
}
-/*
- Initialize 'sum_funcs' array with all Item_sum objects
+/**
+ Initialize 'sum_funcs' array with all Item_sum objects.
- SYNOPSIS
- make_sum_func_list()
- field_list All items
- send_fields Items in select list
- before_group_by Set to 1 if this is called before GROUP BY handling
- recompute Set to TRUE if sum_funcs must be recomputed
+ @param field_list All items
+ @param send_fields Items in select list
+ @param before_group_by Set to 1 if this is called before GROUP BY handling
+ @param recompute Set to TRUE if sum_funcs must be recomputed
- RETURN
+ @retval
0 ok
+ @retval
1 error
*/
@@ -14745,21 +14813,21 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
}
-/*
+/**
Change all funcs and sum_funcs to fields in tmp table, and create
new list of all items.
- change_to_use_tmp_fields()
- thd - THD pointer
- ref_pointer_array - array of pointers to top elements of filed list
- res_selected_fields - new list of items of select item list
- res_all_fields - new list of all items
- elements - number of elements in select item list
- all_fields - all fields list
-
- RETURN
- 0 - ok
- !=0 - error
+ @param thd THD pointer
+ @param ref_pointer_array array of pointers to top elements of filed list
+ @param res_selected_fields new list of items of select item list
+ @param res_all_fields new list of all items
+ @param elements number of elements in select item list
+ @param all_fields all fields list
+
+ @retval
+ 0 ok
+ @retval
+ !=0 error
*/
static bool
@@ -14833,20 +14901,20 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
}
-/*
- Change all sum_func refs to fields to point at fields in tmp table
- Change all funcs to be fields in tmp table
-
- change_refs_to_tmp_fields()
- thd - THD pointer
- ref_pointer_array - array of pointers to top elements of filed list
- res_selected_fields - new list of items of select item list
- res_all_fields - new list of all items
- elements - number of elements in select item list
- all_fields - all fields list
-
- RETURN
+/**
+ Change all sum_func refs to fields to point at fields in tmp table.
+ Change all funcs to be fields in tmp table.
+
+ @param thd THD pointer
+ @param ref_pointer_array array of pointers to top elements of filed list
+ @param res_selected_fields new list of items of select item list
+ @param res_all_fields new list of all items
+ @param elements number of elements in select item list
+ @param all_fields all fields list
+
+ @retval
0 ok
+ @retval
1 error
*/
@@ -14884,16 +14952,15 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
******************************************************************************/
-/*
- Call ::setup for all sum functions
+/**
+ Call ::setup for all sum functions.
- SYNOPSIS
- setup_sum_funcs()
- thd thread handler
- func_ptr sum function list
+ @param thd thread handler
+ @param func_ptr sum function list
- RETURN
+ @retval
FALSE ok
+ @retval
TRUE error
*/
@@ -14919,7 +14986,7 @@ init_tmptable_sum_functions(Item_sum **func_ptr)
}
- /* Update record 0 in tmp_table from record 1 */
+/** Update record 0 in tmp_table from record 1. */
static void
update_tmptable_sum_func(Item_sum **func_ptr,
@@ -14931,7 +14998,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
}
- /* Copy result of sum functions to record in tmp_table */
+/** Copy result of sum functions to record in tmp_table. */
static void
copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr)
@@ -14970,7 +15037,7 @@ update_sum_func(Item_sum **func_ptr)
return 0;
}
- /* Copy result of functions to record in tmp_table */
+/** Copy result of functions to record in tmp_table. */
void
copy_funcs(Item **func_ptr)
@@ -14981,9 +15048,9 @@ copy_funcs(Item **func_ptr)
}
-/*
+/**
Create a condition for a const reference and add this to the
- currenct select for the table
+ currenct select for the table.
*/
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
@@ -15023,12 +15090,11 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
-/*
+/**
Free joins of subselect of this select.
- free_underlaid_joins()
- thd - THD pointer
- select - pointer to st_select_lex which subselects joins we will free
+ @param thd THD pointer
+ @param select pointer to st_select_lex which subselects joins we will free
*/
void free_underlaid_joins(THD *thd, SELECT_LEX *select)
@@ -15043,41 +15109,43 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select)
ROLLUP handling
****************************************************************************/
-/*
- Replace occurences of group by fields in an expression by ref items
+/**
+ Replace occurences of group by fields in an expression by ref items.
- SYNOPSIS
- change_group_ref()
- thd reference to the context
- expr expression to make replacement
- group_list list of references to group by items
- changed out: returns 1 if item contains a replaced field item
+ The function replaces occurrences of group by fields in expr
+ by ref objects for these fields unless they are under aggregate
+ functions.
+ The function also corrects value of the the maybe_null attribute
+ for the items of all subexpressions containing group by fields.
- DESCRIPTION
- The function replaces occurrences of group by fields in expr
- by ref objects for these fields unless they are under aggregate
- functions.
- The function also corrects value of the the maybe_null attribute
- for the items of all subexpressions containing group by fields.
+ @b EXAMPLES
+ @code
+ SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
+ SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
+ @endcode
+
+ @b IMPLEMENTATION
- IMPLEMENTATION
The function recursively traverses the tree of the expr expression,
looks for occurrences of the group by fields that are not under
aggregate functions and replaces them for the corresponding ref items.
- NOTES
+ @note
This substitution is needed GROUP BY queries with ROLLUP if
SELECT list contains expressions over group by attributes.
- TODO: Some functions are not null-preserving. For those functions
+ @param thd reference to the context
+ @param expr expression to make replacement
+ @param group_list list of references to group by items
+ @param changed out: returns 1 if item contains a replaced field item
+
+ @todo
+ - TODO: Some functions are not null-preserving. For those functions
updating of the maybe_null attribute is an overkill.
- EXAMPLES
- SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
- SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
-
- RETURN
+ @retval
0 if ok
+ @retval
1 on error
*/
@@ -15126,7 +15194,7 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
}
-/* Allocate memory needed for other rollup functions */
+/** Allocate memory needed for other rollup functions. */
bool JOIN::rollup_init()
{
@@ -15229,22 +15297,20 @@ bool JOIN::rollup_init()
}
-/*
- Fill up rollup structures with pointers to fields to use
+/**
+ Fill up rollup structures with pointers to fields to use.
- SYNOPSIS
- rollup_make_fields()
- fields_arg List of all fields (hidden and real ones)
- sel_fields Pointer to selected fields
- func Store here a pointer to all fields
+ Creates copies of item_sum items for each sum level.
- IMPLEMENTATION:
- Creates copies of item_sum items for each sum level
+ @param fields_arg List of all fields (hidden and real ones)
+ @param sel_fields Pointer to selected fields
+ @param func Store here a pointer to all fields
- RETURN
- 0 if ok
- In this case func is pointing to next not used element.
- 1 on error
+ @retval
+ 0 if ok;
+ In this case func is pointing to next not used element.
+ @retval
+ 1 on error
*/
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
@@ -15362,21 +15428,22 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
return 0;
}
-/*
- Send all rollup levels higher than the current one to the client
+/**
+ Send all rollup levels higher than the current one to the client.
- SYNOPSIS:
- rollup_send_data()
- idx Level we are on:
- 0 = Total sum level
- 1 = First group changed (a)
- 2 = Second group changed (a,b)
+ @b SAMPLE
+ @code
+ SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
+ @endcode
- SAMPLE
- SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
+ @param idx Level we are on:
+ - 0 = Total sum level
+ - 1 = First group changed (a)
+ - 2 = Second group changed (a,b)
- RETURN
- 0 ok
+ @retval
+ 0 ok
+ @retval
1 If send_data_failed()
*/
@@ -15402,22 +15469,23 @@ int JOIN::rollup_send_data(uint idx)
return 0;
}
-/*
- Write all rollup levels higher than the current one to a temp table
-
- SYNOPSIS:
- rollup_write_data()
- idx Level we are on:
- 0 = Total sum level
- 1 = First group changed (a)
- 2 = Second group changed (a,b)
- table reference to temp table
-
- SAMPLE
- SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP
-
- RETURN
- 0 ok
+/**
+ Write all rollup levels higher than the current one to a temp table.
+
+ @b SAMPLE
+ @code
+ SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP
+ @endcode
+
+ @param idx Level we are on:
+ - 0 = Total sum level
+ - 1 = First group changed (a)
+ - 2 = Second group changed (a,b)
+ @param table reference to temp table
+
+ @retval
+ 0 ok
+ @retval
1 if write_data_failed()
*/
@@ -15454,12 +15522,9 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
return 0;
}
-/*
+/**
clear results if there are not rows found for group
(end_send_group/end_write_group)
-
- SYNOPSYS
- JOIN::clear()
*/
void JOIN::clear()
@@ -15475,11 +15540,11 @@ void JOIN::clear()
}
}
-/****************************************************************************
- EXPLAIN handling
+/**
+ EXPLAIN handling.
- Send a description about what how the select will be done to stdout
-****************************************************************************/
+ Send a description about what how the select will be done to stdout.
+*/
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct,const char *message)
@@ -15994,14 +16059,12 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
}
-/*
- Print joins from the FROM clause
+/**
+ Print joins from the FROM clause.
- SYNOPSIS
- print_join()
- thd thread handler
- str string where table should be printed
- tables list of tables in join
+ @param thd thread handler
+ @param str string where table should be printed
+ @param tables list of tables in join
*/
static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
@@ -16043,12 +16106,10 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
}
-/*
- Print table as it should be in join list
+/**
+ Print table as it should be in join list.
- SYNOPSIS
- TABLE_LIST::print();
- str string where table should bbe printed
+ @param str string where table should bbe printed
*/
void TABLE_LIST::print(THD *thd, String *str)
@@ -16234,16 +16295,15 @@ void st_select_lex::print(THD *thd, String *str)
}
-/*
- change select_result object of JOIN
+/**
+ change select_result object of JOIN.
- SYNOPSIS
- JOIN::change_result()
- res new select_result object
+ @param res new select_result object
- RETURN
- FALSE - OK
- TRUE - error
+ @retval
+ FALSE OK
+ @retval
+ TRUE error
*/
bool JOIN::change_result(select_result *res)
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index ce26b025430..7b255a8ce59 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -168,7 +168,7 @@ static const LEX_STRING triggers_file_type=
const char * const TRG_EXT= ".TRG";
-/*
+/**
Table of .TRG file field descriptors.
We have here only one field now because in nearest future .TRG
files will be merged into .FRM files (so we don't need something
@@ -216,7 +216,7 @@ File_option sql_modes_parameters=
FILE_OPTIONS_ULLLIST
};
-/*
+/**
This must be kept up to date whenever a new option is added to the list
above, as it specifies the number of required parameters of the trigger in
.trg file.
@@ -292,23 +292,27 @@ private:
};
-/*
+/**
Create or drop trigger for table.
- SYNOPSIS
- mysql_create_or_drop_trigger()
- thd - current thread context (including trigger definition in LEX)
- tables - table list containing one table for which trigger is created.
- create - whenever we create (TRUE) or drop (FALSE) trigger
+ @param thd current thread context (including trigger definition in LEX)
+ @param tables table list containing one table for which trigger is created.
+ @param create whenever we create (TRUE) or drop (FALSE) trigger
- NOTE
+ @note
This function is mainly responsible for opening and locking of table and
invalidation of all its instances in table cache after trigger creation.
Real work on trigger creation/dropping is done inside Table_triggers_list
methods.
- RETURN VALUE
+ @todo
+ TODO: We should check if user has TRIGGER privilege for table here.
+ Now we just require SUPER privilege for creating/dropping because
+ we don't have proper privilege checking for triggers in place yet.
+
+ @retval
FALSE Success
+ @retval
TRUE error
*/
bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
@@ -479,29 +483,28 @@ end:
}
-/*
+/**
Create trigger for table.
- SYNOPSIS
- create_trigger()
- thd - current thread context (including trigger definition in
- LEX)
- tables - table list containing one open table for which the
- trigger is created.
- stmt_query - [OUT] after successful return, this string contains
- well-formed statement for creating this trigger.
+ @param thd current thread context (including trigger definition in
+ LEX)
+ @param tables table list containing one open table for which the
+ trigger is created.
+ @param[out] stmt_query after successful return, this string contains
+ well-formed statement for creation this trigger.
- NOTE
+ @note
- Assumes that trigger name is fully qualified.
- NULL-string means the following LEX_STRING instance:
- { str = 0; length = 0 }.
+ { str = 0; length = 0 }.
- In other words, definer_user and definer_host should contain
- simultaneously NULL-strings (non-SUID/old trigger) or valid strings
- (SUID/new trigger).
+ simultaneously NULL-strings (non-SUID/old trigger) or valid strings
+ (SUID/new trigger).
- RETURN VALUE
- False - success
- True - error
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
String *stmt_query)
@@ -767,19 +770,18 @@ err_with_cleanup:
}
-/*
- Deletes the .TRG file for a table
-
- SYNOPSIS
- rm_trigger_file()
- path - char buffer of size FN_REFLEN to be used
- for constructing path to .TRG file.
- db - table's database name
- table_name - table's name
-
- RETURN VALUE
- False - success
- True - error
+/**
+ Deletes the .TRG file for a table.
+
+ @param path char buffer of size FN_REFLEN to be used
+ for constructing path to .TRG file.
+ @param db table's database name
+ @param table_name table's name
+
+ @retval
+ False success
+ @retval
+ True error
*/
static bool rm_trigger_file(char *path, const char *db,
@@ -790,19 +792,18 @@ static bool rm_trigger_file(char *path, const char *db,
}
-/*
- Deletes the .TRN file for a trigger
-
- SYNOPSIS
- rm_trigname_file()
- path - char buffer of size FN_REFLEN to be used
- for constructing path to .TRN file.
- db - trigger's database name
- table_name - trigger's name
-
- RETURN VALUE
- False - success
- True - error
+/**
+ Deletes the .TRN file for a trigger.
+
+ @param path char buffer of size FN_REFLEN to be used
+ for constructing path to .TRN file.
+ @param db trigger's database name
+ @param table_name trigger's name
+
+ @retval
+ False success
+ @retval
+ True error
*/
static bool rm_trigname_file(char *path, const char *db,
@@ -813,17 +814,16 @@ static bool rm_trigname_file(char *path, const char *db,
}
-/*
+/**
Helper function that saves .TRG file for Table_triggers_list object.
- SYNOPSIS
- save_trigger_file()
- triggers Table_triggers_list object for which file should be saved
- db Name of database for subject table
- table_name Name of subject table
+ @param triggers Table_triggers_list object for which file should be saved
+ @param db Name of database for subject table
+ @param table_name Name of subject table
- RETURN VALUE
+ @retval
FALSE Success
+ @retval
TRUE Error
*/
@@ -842,21 +842,26 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
}
-/*
+/**
Drop trigger for table.
- SYNOPSIS
- drop_trigger()
- thd - current thread context
- (including trigger definition in LEX)
- tables - table list containing one open table for which trigger
- is dropped.
- stmt_query - [OUT] after successful return, this string contains
- well-formed statement for deleting this trigger.
-
- RETURN VALUE
- False - success
- True - error
+ @param thd current thread context
+ (including trigger definition in LEX)
+ @param tables table list containing one open table for which trigger
+ is dropped.
+ @param[out] stmt_query after successful return, this string contains
+ well-formed statement for creation this trigger.
+
+ @todo
+ Probably instead of removing .TRG file we should move
+ to archive directory but this should be done as part of
+ parse_file.cc functionality (because we will need it
+ elsewhere).
+
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
String *stmt_query)
@@ -939,18 +944,17 @@ Table_triggers_list::~Table_triggers_list()
}
-/*
+/**
Prepare array of Field objects referencing to TABLE::record[1] instead
of record[0] (they will represent OLD.* row values in ON UPDATE trigger
and in ON DELETE trigger which will be called during REPLACE execution).
- SYNOPSIS
- prepare_record1_accessors()
- table - pointer to TABLE object for which we are creating fields.
+ @param table pointer to TABLE object for which we are creating fields.
- RETURN VALUE
- False - success
- True - error
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
{
@@ -979,12 +983,10 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
}
-/*
+/**
Adjust Table_triggers_list with new TABLE pointer.
- SYNOPSIS
- set_table()
- new_table - new pointer to TABLE instance
+ @param new_table new pointer to TABLE instance
*/
void Table_triggers_list::set_table(TABLE *new_table)
@@ -998,20 +1000,26 @@ void Table_triggers_list::set_table(TABLE *new_table)
}
-/*
+/**
Check whenever .TRG file for table exist and load all triggers it contains.
- SYNOPSIS
- check_n_load()
- thd - current thread context
- db - table's database name
- table_name - table's name
- table - pointer to table object
- names_only - stop after loading trigger names
-
- RETURN VALUE
- False - success
- True - error
+ @param thd current thread context
+ @param db table's database name
+ @param table_name table's name
+ @param table pointer to table object
+ @param names_only stop after loading trigger names
+
+ @todo
+ A lot of things to do here e.g. how about other funcs and being
+ more paranoical ?
+
+ @todo
+ This could be avoided if there is no triggers for UPDATE and DELETE.
+
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::check_n_load(THD *thd, const char *db,
@@ -1394,24 +1402,23 @@ err_with_lex_cleanup:
}
-/*
- Obtains and returns trigger metadata
-
- SYNOPSIS
- get_trigger_info()
- thd - current thread context
- event - trigger event type
- time_type - trigger action time
- name - returns name of trigger
- stmt - returns statement of trigger
- sql_mode - returns sql_mode of trigger
- definer_user - returns definer/creator of trigger. The caller is
- responsible to allocate enough space for storing definer
- information.
-
- RETURN VALUE
- False - success
- True - error
+/**
+ Obtains and returns trigger metadata.
+
+ @param thd current thread context
+ @param event trigger event type
+ @param time_type trigger action time
+ @param trigger_name returns name of trigger
+ @param trigger_stmt returns statement of trigger
+ @param sql_mode returns sql_mode of trigger
+ @param definer returns definer/creator of trigger. The caller is
+ responsible to allocate enough space for storing
+ definer information.
+
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
@@ -1577,21 +1584,20 @@ bool add_table_for_trigger(THD *thd,
}
-/*
+/**
Drop all triggers for table.
- SYNOPSIS
- drop_all_triggers()
- thd - current thread context
- db - schema for table
- name - name for table
+ @param thd current thread context
+ @param db schema for table
+ @param name name for table
- NOTE
+ @note
The calling thread should hold the LOCK_open mutex;
- RETURN VALUE
- False - success
- True - error
+ @retval
+ False success
+ @retval
+ True error
*/
bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
@@ -1641,19 +1647,18 @@ end:
}
-/*
+/**
Update .TRG file after renaming triggers' subject table
(change name of table in triggers' definitions).
- SYNOPSIS
- change_table_name_in_triggers()
- thd Thread context
- db_name Database of subject table
- old_table_name Old subject table's name
- new_table_name New subject table's name
+ @param thd Thread context
+ @param db_name Database of subject table
+ @param old_table_name Old subject table's name
+ @param new_table_name New subject table's name
- RETURN VALUE
+ @retval
FALSE Success
+ @retval
TRUE Failure
*/
@@ -1723,21 +1728,20 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
}
-/*
- Iterate though Table_triggers_list::names_list list and update .TRN files
- after renaming triggers' subject table.
+/**
+ Iterate though Table_triggers_list::names_list list and update
+ .TRN files after renaming triggers' subject table.
- SYNOPSIS
- change_table_name_in_trignames()
- db_name Database of subject table
- new_table_name New subject table's name
- stopper Pointer to Table_triggers_list::names_list at
- which we should stop updating.
+ @param db_name Database of subject table
+ @param new_table_name New subject table's name
+ @param stopper Pointer to Table_triggers_list::names_list at
+ which we should stop updating.
- RETURN VALUE
+ @retval
0 Success
+ @retval
non-0 Failure, pointer to Table_triggers_list::names_list element
- for which update failed.
+ for which update failed.
*/
LEX_STRING*
@@ -1771,7 +1775,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
/**
- @brief Update .TRG and .TRN files after renaming triggers' subject table.
+ Update .TRG and .TRN files after renaming triggers' subject table.
@param[in,out] thd Thread context
@param[in] db Old database of subject table
@@ -1933,19 +1937,17 @@ bool Table_triggers_list::process_triggers(THD *thd,
}
-/*
- Mark fields of subject table which we read/set in its triggers as such.
-
- SYNOPSIS
- mark_fields_used()
- thd Current thread context
- event Type of event triggers for which we are going to ins
-
- DESCRIPTION
- This method marks fields of subject table which are read/set in its
- triggers as such (by properly updating TABLE::read_set/write_set)
- and thus informs handler that values for these fields should be
- retrieved/stored during execution of statement.
+/**
+ Mark fields of subject table which we read/set in its triggers
+ as such.
+
+ This method marks fields of subject table which are read/set in its
+ triggers as such (by properly updating TABLE::read_set/write_set)
+ and thus informs handler that values for these fields should be
+ retrieved/stored during execution of statement.
+
+ @param thd Current thread context
+ @param event Type of event triggers for which we are going to inspect
*/
void Table_triggers_list::mark_fields_used(trg_event_type event)
@@ -1971,23 +1973,23 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
}
-/*
- Trigger BUG#14090 compatibility hook
+/**
+ Trigger BUG#14090 compatibility hook.
- SYNOPSIS
- Handle_old_incorrect_sql_modes_hook::process_unknown_string()
- unknown_key [in/out] reference on the line with unknown
- parameter and the parsing point
- base [in] base address for parameter writing (structure
- like TABLE)
- mem_root [in] MEM_ROOT for parameters allocation
- end [in] the end of the configuration
+ @param[in,out] unknown_key reference on the line with unknown
+ parameter and the parsing point
+ @param[in] base base address for parameter writing
+ (structure like TABLE)
+ @param[in] mem_root MEM_ROOT for parameters allocation
+ @param[in] end the end of the configuration
- NOTE: this hook process back compatibility for incorrectly written
- sql_modes parameter (see BUG#14090).
+ @note
+ NOTE: this hook process back compatibility for incorrectly written
+ sql_modes parameter (see BUG#14090).
- RETURN
+ @retval
FALSE OK
+ @retval
TRUE Error
*/
@@ -2029,13 +2031,12 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
DBUG_RETURN(FALSE);
}
-/*
+#define INVALID_TRIGGER_TABLE_LENGTH 15
+
+/**
Trigger BUG#15921 compatibility hook. For details see
Handle_old_incorrect_sql_modes_hook::process_unknown_string().
*/
-
-#define INVALID_TRIGGER_TABLE_LENGTH 15
-
bool
Handle_old_incorrect_trigger_table_hook::
process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
@@ -2074,9 +2075,9 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
/**
Contruct path to TRN-file.
- @param[in] thd Thread context.
- @param[in] trg_name Trigger name.
- @param[out] trn_path Variable to store constructed path
+ @param thd[in] Thread context.
+ @param trg_name[in] Trigger name.
+ @param trn_path[out] Variable to store constructed path
*/
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
@@ -2109,10 +2110,10 @@ bool check_trn_exists(const LEX_STRING *trn_path)
/**
Retrieve table name for given trigger.
- @param[in] thd Thread context.
- @param[in] trg_name Trigger name.
- @param[in] trn_path Path to the corresponding TRN-file.
- @param[out] tbl_name Variable to store retrieved table name.
+ @param thd[in] Thread context.
+ @param trg_name[in] Trigger name.
+ @param trn_path[in] Path to the corresponding TRN-file.
+ @param tbl_name[out] Variable to store retrieved table name.
@return Error status.
@retval FALSE on success.
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 4071bb86c90..127e2b94214 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -84,7 +84,7 @@ static bool check_fields(THD *thd, List<Item> &items)
/**
- @brief Re-read record if more columns are needed for error message.
+ Re-read record if more columns are needed for error message.
If we got a duplicate key error, we want to write an error
message containing the value of the duplicate key. If we do not have
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 56d50761d95..d0e03ec3237 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -206,7 +206,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
/**
- @brief Creating/altering VIEW procedure
+ Creating/altering VIEW procedure
@param thd thread handler
@param views views to create