Doxygenization of comments.

This commit is contained in:
unknown 2007-10-11 13:29:09 -04:00
parent 39062b7e4e
commit d43c15b0de
25 changed files with 2510 additions and 2472 deletions

View File

@ -14,11 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
@file
@brief
Functions to copy data to or from fields Functions to copy data to or from fields
This could be done with a single short function but opencoding this This could be done with a single short function but opencoding this
gives much more speed. gives much more speed.
*/ */
#include "mysql_priv.h" #include "mysql_priv.h"
#include <m_ctype.h> #include <m_ctype.h>
@ -129,20 +133,19 @@ set_field_to_null(Field *field)
} }
/* /**
Set field to NULL or TIMESTAMP or to next auto_increment number Set field to NULL or TIMESTAMP or to next auto_increment number.
SYNOPSIS @param field Field to update
set_field_to_null_with_conversions() @param no_conversions Set to 1 if we should return 1 if field can't
field Field to update
no_conversion Set to 1 if we should return 1 if field can't
take null values. take null values.
If set to 0 we will do store the 'default value' If set to 0 we will do store the 'default value'
if the field is a special field. If not we will if the field is a special field. If not we will
give an error. give an error.
RETURN VALUES @retval
0 Field could take 0 or an automatic conversion was used 0 Field could take 0 or an automatic conversion was used
@retval
-1 Field could not take NULL and no conversion was used. -1 Field could not take NULL and no conversion was used.
If no_conversion was not set, an error message is printed If no_conversion was not set, an error message is printed
*/ */
@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy)
copy->tmp.charset()); copy->tmp.charset());
} }
/* Save blob in copy->tmp for GROUP BY */ /** Save blob in copy->tmp for GROUP BY. */
static void do_save_blob(Copy_field *copy) static void do_save_blob(Copy_field *copy)
{ {
@ -352,9 +355,9 @@ static void do_field_decimal(Copy_field *copy)
} }
/* /**
string copy for single byte characters set when to string is shorter than string copy for single byte characters set when to string is shorter than
from string from string.
*/ */
static void do_cut_string(Copy_field *copy) static void do_cut_string(Copy_field *copy)
@ -374,9 +377,9 @@ static void do_cut_string(Copy_field *copy)
} }
/* /**
string copy for multi byte characters set when to string is shorter than string copy for multi byte characters set when to string is shorter than
from string from string.
*/ */
static void do_cut_string_complex(Copy_field *copy) static void do_cut_string_complex(Copy_field *copy)
@ -507,7 +510,7 @@ static void do_varstring2_mb(Copy_field *copy)
** The different functions that fills in a Copy_field class ** The different functions that fills in a Copy_field class
***************************************************************************/ ***************************************************************************/
/* /**
copy of field to maybe null string. copy of field to maybe null string.
If field is null then the all bytes are set to 0. If field is null then the all bytes are set to 0.
if field is not null then the first byte is set to 1 and the rest of the if field is not null then the first byte is set to 1 and the rest of the
@ -748,7 +751,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
} }
/* Simple quick field convert that is called on insert */ /** Simple quick field convert that is called on insert. */
int field_conv(Field *to,Field *from) int field_conv(Field *to,Field *from)
{ {

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sorts a database */ /**
@file
@brief
Sorts a database
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#ifdef HAVE_STDDEF_H #ifdef HAVE_STDDEF_H
@ -27,8 +32,7 @@
#define SKIP_DBUG_IN_FILESORT #define SKIP_DBUG_IN_FILESORT
#endif #endif
/* How to write record_ref. */ /// How to write record_ref.
#define WRITE_REF(file,from) \ #define WRITE_REF(file,from) \
if (my_b_write((file),(uchar*) (from),param->ref_length)) \ if (my_b_write((file),(uchar*) (from),param->ref_length)) \
DBUG_RETURN(1); DBUG_RETURN(1);
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
uint sortlength, uint *plength); uint sortlength, uint *plength);
static void unpack_addon_fields(struct st_sort_addon_field *addon_field, static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
uchar *buff); uchar *buff);
/**
/* Sort a table.
Sort a table
SYNOPSIS
filesort()
table Table to sort
sortorder How to sort the table
s_length Number of elements in sortorder
select Condition to apply to the rows
ha_maxrows Return only this many rows
sort_positions Set to 1 if we want to force sorting by position
(Needed by UPDATE/INSERT or ALTER TABLE)
examined_rows Store number of examined rows here
IMPLEMENTATION
Creates a set of pointers that can be used to read the rows Creates a set of pointers that can be used to read the rows
in sorted order. This should be done with the functions in sorted order. This should be done with the functions
in records.cc in records.cc.
REQUIREMENTS
Before calling filesort, one must have done Before calling filesort, one must have done
table->file->info(HA_STATUS_VARIABLE) table->file->info(HA_STATUS_VARIABLE)
NOTES The result set is stored in table->io_cache or
table->record_pointers.
@param thd Current thread
@param table Table to sort
@param sortorder How to sort the table
@param s_length Number of elements in sortorder
@param select condition to apply to the rows
@param max_rows Return only this many rows
@param sort_positions Set to 1 if we want to force sorting by position
(Needed by UPDATE/INSERT or ALTER TABLE)
@param examined_rows Store number of examined rows here
@todo
check why we do this (param.keys--)
@note
If we sort by position (like if sort_positions is 1) filesort() will If we sort by position (like if sort_positions is 1) filesort() will
call table->prepare_for_position(). call table->prepare_for_position().
RETURN @retval
HA_POS_ERROR Error HA_POS_ERROR Error
# Number of rows @retval
\# Number of rows
@retval
examined_rows will be set to number of examined rows examined_rows will be set to number of examined rows
The result set is stored in table->io_cache or
table->record_pointers
*/ */
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
@ -351,7 +353,7 @@ void filesort_free_buffers(TABLE *table, bool full)
} }
} }
/* Make a array of string pointers */ /** Make a array of string pointers. */
static char **make_char_array(char **old_pos, register uint fields, static char **make_char_array(char **old_pos, register uint fields,
uint length, myf my_flag) uint length, myf my_flag)
@ -372,7 +374,7 @@ static char **make_char_array(char **old_pos, register uint fields,
} /* make_char_array */ } /* make_char_array */
/* Read 'count' number of buffer pointers into memory */ /** Read 'count' number of buffer pointers into memory. */
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count) static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
{ {
@ -395,20 +397,21 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
} }
/* /**
Search after sort_keys and write them into tempfile. Search after sort_keys and write them into tempfile.
SYNOPSIS All produced sequences are guaranteed to be non-empty.
find_all_keys()
param Sorting parameter
select Use this to get source data
sort_keys Array of pointers to sort key + addon buffers.
buffpek_pointers File to write BUFFPEKs describing sorted segments
in tempfile.
tempfile File to write sorted sequences of sortkeys to.
indexfile If !NULL, use it for source data (contains rowids)
NOTE @param param Sorting parameter
@param select Use this to get source data
@param sort_keys Array of pointers to sort key + addon buffers.
@param buffpek_pointers File to write BUFFPEKs describing sorted segments
in tempfile.
@param tempfile File to write sorted sequences of sortkeys to.
@param indexfile If !NULL, use it for source data (contains rowids)
@note
Basic idea: Basic idea:
@verbatim
while (get_next_sortkey()) while (get_next_sortkey())
{ {
if (no free space in sort_keys buffers) if (no free space in sort_keys buffers)
@ -423,10 +426,11 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
sort-dump-dump as above; sort-dump-dump as above;
else else
don't sort, leave sort_keys array to be sorted by caller. don't sort, leave sort_keys array to be sorted by caller.
@endverbatim
All produced sequences are guaranteed to be non-empty. @retval
RETURN
Number of records written on success. Number of records written on success.
@retval
HA_POS_ERROR on error. HA_POS_ERROR on error.
*/ */
@ -591,23 +595,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} /* find_all_keys */ } /* find_all_keys */
/* /**
@details
Sort the buffer and write: Sort the buffer and write:
1) the sorted sequence to tempfile -# the sorted sequence to tempfile
2) a BUFFPEK describing the sorted sequence position to buffpek_pointers -# a BUFFPEK describing the sorted sequence position to buffpek_pointers
(was: Skriver en buffert med nycklar till filen) (was: Skriver en buffert med nycklar till filen)
SYNOPSIS
write_keys() @param param Sort parameters
param Sort parameters @param sort_keys Array of pointers to keys to sort
sort_keys Array of pointers to keys to sort @param count Number of elements in sort_keys array
count Number of elements in sort_keys array @param buffpek_pointers One 'BUFFPEK' struct will be written into this file.
buffpek_pointers One 'BUFFPEK' struct will be written into this file.
The BUFFPEK::{file_pos, count} will indicate where The BUFFPEK::{file_pos, count} will indicate where
the sorted data was stored. the sorted data was stored.
tempfile The sorted sequence will be written into this file. @param tempfile The sorted sequence will be written into this file.
RETURN @retval
0 OK 0 OK
@retval
1 Error 1 Error
*/ */
@ -650,8 +656,8 @@ err:
} /* write_keys */ } /* write_keys */
/* /**
Store length as suffix in high-byte-first order Store length as suffix in high-byte-first order.
*/ */
static inline void store_length(uchar *to, uint length, uint pack_length) static inline void store_length(uchar *to, uint length, uint pack_length)
@ -673,7 +679,7 @@ static inline void store_length(uchar *to, uint length, uint pack_length)
} }
/* makes a sort-key from record */ /** Make a sort-key from record. */
static void make_sortkey(register SORTPARAM *param, static void make_sortkey(register SORTPARAM *param,
register uchar *to, uchar *ref_pos) register uchar *to, uchar *ref_pos)
@ -987,7 +993,7 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
} }
/* Merge buffers to make < MERGEBUFF2 buffers */ /** Merge buffers to make < MERGEBUFF2 buffers. */
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file) BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
@ -1040,8 +1046,12 @@ cleanup:
} /* merge_many_buff */ } /* merge_many_buff */
/* Read data to buffer */ /**
/* This returns (uint) -1 if something goes wrong */ Read data to buffer.
@retval
(uint)-1 if something goes wrong
*/
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
uint rec_length) uint rec_length)
@ -1063,15 +1073,15 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
} /* read_to_buffer */ } /* read_to_buffer */
/* /**
Put all room used by freed buffer to use in adjacent buffer. Note, that Put all room used by freed buffer to use in adjacent buffer.
we can't simply distribute memory evenly between all buffers, because
new areas must not overlap with old ones. Note, that we can't simply distribute memory evenly between all buffers,
SYNOPSIS because new areas must not overlap with old ones.
reuse_freed_buff()
queue IN list of non-empty buffers, without freed buffer @param[in] queue list of non-empty buffers, without freed buffer
reuse IN empty buffer @param[in] reuse empty buffer
key_length IN key length @param[in] key_length key length
*/ */
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length) void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
@ -1096,22 +1106,22 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
} }
/* /**
Merge buffers to one buffer Merge buffers to one buffer.
SYNOPSIS
merge_buffers()
param Sort parameter
from_file File with source data (BUFFPEKs point to this file)
to_file File to write the sorted result data.
sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
lastbuff OUT Store here BUFFPEK describing data written to to_file
Fb First element in source BUFFPEKs array
Tb Last element in source BUFFPEKs array
flag
RETURN @param param Sort parameter
0 - OK @param from_file File with source data (BUFFPEKs point to this file)
other - error @param to_file File to write the sorted result data.
@param sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
@param lastbuff OUT Store here BUFFPEK describing data written to to_file
@param Fb First element in source BUFFPEKs array
@param Tb Last element in source BUFFPEKs array
@param flag
@retval
0 OK
@retval
other error
*/ */
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
@ -1347,23 +1357,21 @@ static uint suffix_length(ulong string_length)
/* /**
Calculate length of sort key Calculate length of sort key.
SYNOPSIS @param thd Thread handler
sortlength() @param sortorder Order of items to sort
thd Thread handler @param s_length Number of items to sort
sortorder Order of items to sort @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
uint s_length Number of items to sort
multi_byte_charset (out)
Set to 1 if we are using multi-byte charset
(In which case we have to use strxnfrm()) (In which case we have to use strxnfrm())
NOTES @note
sortorder->length is updated for each sort item sortorder->length is updated for each sort item.
@n
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
RETURN @return
Total length of sort buffer in bytes Total length of sort buffer in bytes
*/ */
@ -1450,18 +1458,10 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
} }
/* /**
Get descriptors of fields appended to sorted fields and Get descriptors of fields appended to sorted fields and
calculate its total length calculate its total length.
SYNOPSIS
get_addon_fields()
thd Current thread
ptabfields Array of references to the table fields
sortlength Total length of sorted fields
plength out: Total length of appended fields
DESCRIPTION
The function first finds out what fields are used in the result set. The function first finds out what fields are used in the result set.
Then it calculates the length of the buffer to store the values of Then it calculates the length of the buffer to store the values of
these fields together with the value of sort values. these fields together with the value of sort values.
@ -1470,13 +1470,19 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
layouts for the values of the non-sorted fields in the buffer and layouts for the values of the non-sorted fields in the buffer and
fills them. fills them.
NOTES @param thd Current thread
@param ptabfield Array of references to the table fields
@param sortlength Total length of sorted fields
@param[out] plength Total length of appended fields
@note
The null bits for the appended values are supposed to be put together The null bits for the appended values are supposed to be put together
and stored the buffer just ahead of the value of the first field. and stored the buffer just ahead of the value of the first field.
RETURN @return
Pointer to the layout descriptors for the appended fields, if any Pointer to the layout descriptors for the appended fields, if any
NULL - if we do not store field values with sort data. @retval
NULL if we do not store field values with sort data.
*/ */
static SORT_ADDON_FIELD * static SORT_ADDON_FIELD *
@ -1552,20 +1558,18 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
} }
/* /**
Copy (unpack) values appended to sorted fields from a buffer back to Copy (unpack) values appended to sorted fields from a buffer back to
their regular positions specified by the Field::ptr pointers. their regular positions specified by the Field::ptr pointers.
SYNOPSIS @param addon_field Array of descriptors for appended fields
unpack_addon_fields() @param buff Buffer which to unpack the value from
addon_field Array of descriptors for appended fields
buff Buffer which to unpack the value from
NOTES @note
The function is supposed to be used only as a callback function The function is supposed to be used only as a callback function
when getting field values for the sorted result set. when getting field values for the sorted result set.
RETURN @return
void. void.
*/ */

View File

@ -13,8 +13,11 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
@file
@details
@verbatim
The idea of presented algorithm see in The idea of presented algorithm see in
"The Art of Computer Programming" by Donald E. Knuth "The Art of Computer Programming" by Donald E. Knuth
Volume 3 "Sorting and searching" Volume 3 "Sorting and searching"
@ -63,11 +66,13 @@ for optimization, link is the 16-bit index in 'symbols' or 'sql_functions'
or search-array.. or search-array..
So, we can read full search-structure as 32-bit word So, we can read full search-structure as 32-bit word
@endverbatim
TODO: @todo
1. use instead to_upper_lex, special array use instead to_upper_lex, special array
(substitute chars) without skip codes.. (substitute chars) without skip codes..
2. try use reverse order of comparing.. @todo
try use reverse order of comparing..
*/ */

View File

@ -14,9 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* /**
This file defines the NDB Cluster handler: the interface between MySQL and @file
NDB Cluster
@brief
This file defines the NDB Cluster handler: the interface between
MySQL and NDB Cluster
*/ */
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
@ -140,10 +143,10 @@ static Ndb* g_ndb= NULL;
Ndb_cluster_connection* g_ndb_cluster_connection= NULL; Ndb_cluster_connection* g_ndb_cluster_connection= NULL;
uchar g_node_id_map[max_ndb_nodes]; uchar g_node_id_map[max_ndb_nodes];
// Handler synchronization /// Handler synchronization
pthread_mutex_t ndbcluster_mutex; pthread_mutex_t ndbcluster_mutex;
// Table lock handling /// Table lock handling
HASH ndbcluster_open_tables; HASH ndbcluster_open_tables;
static uchar *ndbcluster_get_key(NDB_SHARE *share, size_t *length, static uchar *ndbcluster_get_key(NDB_SHARE *share, size_t *length,
@ -164,14 +167,14 @@ pthread_cond_t COND_ndb_util_ready;
pthread_handler_t ndb_util_thread_func(void *arg); pthread_handler_t ndb_util_thread_func(void *arg);
ulong ndb_cache_check_time; ulong ndb_cache_check_time;
/* /**
Dummy buffer to read zero pack_length fields Dummy buffer to read zero pack_length fields
which are mapped to 1 char which are mapped to 1 char.
*/ */
static uint32 dummy_buf; static uint32 dummy_buf;
/* /**
Stats that can be retrieved from ndb Stats that can be retrieved from ndb.
*/ */
struct Ndb_statistics { struct Ndb_statistics {
@ -602,10 +605,10 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
} }
/* /**
Override the default get_error_message in order to add the Override the default get_error_message in order to add the
error message of NDB error message of NDB .
*/ */
bool ha_ndbcluster::get_error_message(int error, bool ha_ndbcluster::get_error_message(int error,
String *buf) String *buf)
@ -626,7 +629,7 @@ bool ha_ndbcluster::get_error_message(int error,
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* /**
Check if type is supported by NDB. Check if type is supported by NDB.
*/ */
@ -668,8 +671,8 @@ static bool ndb_supported_type(enum_field_types type)
#endif /* !DBUG_OFF */ #endif /* !DBUG_OFF */
/* /**
Check if MySQL field type forces var part in ndb storage Check if MySQL field type forces var part in ndb storage.
*/ */
static bool field_type_forces_var_part(enum_field_types type) static bool field_type_forces_var_part(enum_field_types type)
{ {
@ -688,8 +691,8 @@ static bool field_type_forces_var_part(enum_field_types type)
} }
} }
/* /**
Instruct NDB to set the value of the hidden primary key Instruct NDB to set the value of the hidden primary key.
*/ */
bool ha_ndbcluster::set_hidden_key(NdbOperation *ndb_op, bool ha_ndbcluster::set_hidden_key(NdbOperation *ndb_op,
@ -700,8 +703,8 @@ bool ha_ndbcluster::set_hidden_key(NdbOperation *ndb_op,
} }
/* /**
Instruct NDB to set the value of one primary key attribute Instruct NDB to set the value of one primary key attribute.
*/ */
int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field, int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field,
@ -721,8 +724,8 @@ int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field,
} }
/* /**
Instruct NDB to set the value of one attribute Instruct NDB to set the value of one attribute.
*/ */
int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
@ -817,7 +820,9 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
} }
/* NdbBlob::ActiveHook g_get_ndb_blobs_value;
/**
Callback to read all blob values. Callback to read all blob values.
- not done in unpack_record because unpack_record is valid - not done in unpack_record because unpack_record is valid
after execute(Commit) but reading blobs is not after execute(Commit) but reading blobs is not
@ -825,11 +830,11 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
somewhere before the data is available somewhere before the data is available
- due to single buffer for all blobs, we let the last blob - due to single buffer for all blobs, we let the last blob
process all blobs (last so that all are active) process all blobs (last so that all are active)
- null bit is still set in unpack_record - null bit is still set in unpack_record.
- TODO allocate blob part aligned buffers
*/
NdbBlob::ActiveHook g_get_ndb_blobs_value; @todo
allocate blob part aligned buffers
*/
int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg) int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg)
{ {
@ -925,10 +930,11 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
} }
/* /**
Instruct NDB to fetch one field Instruct NDB to fetch one field.
- data is read directly into buffer provided by field
if field is NULL, data is read into memory provided by NDBAPI Data is read directly into buffer provided by field
if field is NULL, data is read into memory provided by NDBAPI.
*/ */
int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
@ -990,7 +996,7 @@ int ha_ndbcluster::get_ndb_partition_id(NdbOperation *ndb_op)
(char *)&m_part_id) == NULL); (char *)&m_part_id) == NULL);
} }
/* /**
Check if any set or get of blob value in current query. Check if any set or get of blob value in current query.
*/ */
@ -1013,15 +1019,15 @@ bool ha_ndbcluster::uses_blob_value()
} }
/* /**
Get metadata for this table from NDB Get metadata for this table from NDB.
IMPLEMENTATION Check that frm-file on disk is equal to frm-file
- check that frm-file on disk is equal to frm-file of table accessed in NDB.
of table accessed in NDB
RETURN @retval
0 ok 0 ok
@retval
-2 Meta data has changed; Re-read data and try again -2 Meta data has changed; Re-read data and try again
*/ */
@ -1419,9 +1425,9 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Decode the type of an index from information Decode the type of an index from information
provided in table object provided in table object.
*/ */
NDB_INDEX_TYPE ha_ndbcluster::get_index_type_from_table(uint inx) const NDB_INDEX_TYPE ha_ndbcluster::get_index_type_from_table(uint inx) const
{ {
@ -1563,10 +1569,10 @@ inline bool ha_ndbcluster::has_null_in_unique_index(uint idx_no) const
} }
/* /**
Get the flags for an index Get the flags for an index.
RETURN @return
flags depending on the type of the index. flags depending on the type of the index.
*/ */
@ -1719,8 +1725,8 @@ int ha_ndbcluster::define_read_attrs(uchar* buf, NdbOperation* op)
} }
/* /**
Read one record from NDB using primary key Read one record from NDB using primary key.
*/ */
int ha_ndbcluster::pk_read(const uchar *key, uint key_len, uchar *buf, int ha_ndbcluster::pk_read(const uchar *key, uint key_len, uchar *buf,
@ -1787,9 +1793,9 @@ int ha_ndbcluster::pk_read(const uchar *key, uint key_len, uchar *buf,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /**
Read one complementing record from NDB using primary key from old_data Read one complementing record from NDB using primary key from old_data
or hidden key or hidden key.
*/ */
int ha_ndbcluster::complemented_read(const uchar *old_data, uchar *new_data, int ha_ndbcluster::complemented_read(const uchar *old_data, uchar *new_data,
@ -1850,7 +1856,7 @@ int ha_ndbcluster::complemented_read(const uchar *old_data, uchar *new_data,
unpack_record(new_data); unpack_record(new_data);
table->status= 0; table->status= 0;
/** /*
* restore m_value * restore m_value
*/ */
for (i= 0; i < no_fields; i++) for (i= 0; i < no_fields; i++)
@ -1866,12 +1872,12 @@ int ha_ndbcluster::complemented_read(const uchar *old_data, uchar *new_data,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /**
* Check that all operations between first and last all Check that all operations between first and last all
* have gotten the errcode have gotten the errcode
* If checking for HA_ERR_KEY_NOT_FOUND then update m_dupkey If checking for HA_ERR_KEY_NOT_FOUND then update m_dupkey
* for all succeeding operations for all succeeding operations
*/ */
bool ha_ndbcluster::check_all_operations_for_error(NdbTransaction *trans, bool ha_ndbcluster::check_all_operations_for_error(NdbTransaction *trans,
const NdbOperation *first, const NdbOperation *first,
const NdbOperation *last, const NdbOperation *last,
@ -1951,9 +1957,9 @@ check_null_in_record(const KEY* key_info, const uchar *record)
*/ */
} }
/* /**
* Peek to check if any rows already exist with conflicting Peek to check if any rows already exist with conflicting
* primary key or unique index values primary key or unique index values
*/ */
int ha_ndbcluster::peek_indexed_rows(const uchar *record, int ha_ndbcluster::peek_indexed_rows(const uchar *record,
@ -2056,8 +2062,8 @@ int ha_ndbcluster::peek_indexed_rows(const uchar *record,
} }
/* /**
Read one record from NDB using unique secondary index Read one record from NDB using unique secondary index.
*/ */
int ha_ndbcluster::unique_index_read(const uchar *key, int ha_ndbcluster::unique_index_read(const uchar *key,
@ -2199,15 +2205,14 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* /**
Get the next record of a started scan. Try to fetch Get the next record of a started scan. Try to fetch
it locally from NdbApi cached records if possible, it locally from NdbApi cached records if possible,
otherwise ask NDB for more. otherwise ask NDB for more.
NOTE @note
If this is a update/delete make sure to not contact If this is a update/delete make sure to not contact
NDB before any pending ops have been sent to NDB. NDB before any pending ops have been sent to NDB.
*/ */
inline int ha_ndbcluster::next_result(uchar *buf) inline int ha_ndbcluster::next_result(uchar *buf)
@ -2240,7 +2245,7 @@ inline int ha_ndbcluster::next_result(uchar *buf)
} }
} }
/* /**
Set bounds for ordered index scan. Set bounds for ordered index scan.
*/ */
@ -2421,8 +2426,8 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
DBUG_RETURN(op->end_of_bound(range_no)); DBUG_RETURN(op->end_of_bound(range_no));
} }
/* /**
Start ordered index scan in NDB Start ordered index scan in NDB.
*/ */
int ha_ndbcluster::ordered_index_scan(const key_range *start_key, int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
@ -2606,10 +2611,9 @@ int ha_ndbcluster::unique_index_scan(const KEY* key_info,
} }
/* /**
Start full table scan in NDB Start full table scan in NDB.
*/ */
int ha_ndbcluster::full_table_scan(uchar *buf) int ha_ndbcluster::full_table_scan(uchar *buf)
{ {
int res; int res;
@ -2674,8 +2678,8 @@ int ha_ndbcluster::full_table_scan(uchar *buf)
DBUG_RETURN(next_result(buf)); DBUG_RETURN(next_result(buf));
} }
/* /**
Insert one record into NDB Insert one record into NDB.
*/ */
int ha_ndbcluster::write_row(uchar *record) int ha_ndbcluster::write_row(uchar *record)
{ {
@ -2900,7 +2904,9 @@ int ha_ndbcluster::write_row(uchar *record)
} }
/* Compare if a key in a row has changed */ /**
Compare if a key in a row has changed.
*/
int ha_ndbcluster::key_cmp(uint keynr, const uchar * old_row, int ha_ndbcluster::key_cmp(uint keynr, const uchar * old_row,
const uchar * new_row) const uchar * new_row)
@ -2934,8 +2940,8 @@ int ha_ndbcluster::key_cmp(uint keynr, const uchar * old_row,
return 0; return 0;
} }
/* /**
Update one record in NDB using primary key Update one record in NDB using primary key.
*/ */
int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data) int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
@ -3142,8 +3148,8 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
} }
/* /**
Delete one record from NDB, using primary key Delete one record from NDB, using primary key .
*/ */
int ha_ndbcluster::delete_row(const uchar *record) int ha_ndbcluster::delete_row(const uchar *record)
@ -3257,14 +3263,12 @@ int ha_ndbcluster::delete_row(const uchar *record)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /**
Unpack a record read from NDB Unpack a record read from NDB.
SYNOPSIS @param buf Buffer to store read row
unpack_record()
buf Buffer to store read row
NOTE @note
The data for each row is read directly into the The data for each row is read directly into the
destination buffer. This function is primarily destination buffer. This function is primarily
called in order to check if any fields should be called in order to check if any fields should be
@ -3425,12 +3429,12 @@ void ha_ndbcluster::unpack_record(uchar *buf)
#endif #endif
} }
/* /**
Utility function to print/dump the fetched field Utility function to print/dump the fetched field.
to avoid unnecessary work, wrap in DBUG_EXECUTE as in:
To avoid unnecessary work, wrap in DBUG_EXECUTE as in:
DBUG_EXECUTE("value", print_results();); DBUG_EXECUTE("value", print_results(););
*/ */
void ha_ndbcluster::print_results() void ha_ndbcluster::print_results()
{ {
@ -3512,8 +3516,8 @@ int ha_ndbcluster::index_end()
} }
/** /**
* Check if key contains null Check if key contains null.
*/ */
static static
int int
check_null_in_key(const KEY* key_info, const uchar *key, uint key_len) check_null_in_key(const KEY* key_info, const uchar *key, uint key_len)
@ -3786,11 +3790,10 @@ int ha_ndbcluster::rnd_next(uchar *buf)
} }
/* /**
An "interesting" record has been found and it's pk An "interesting" record has been found and it's pk
retrieved by calling position retrieved by calling position. Now it's time to read
Now it's time to read the record from db once the record from db once again.
again
*/ */
int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos) int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos)
@ -3833,10 +3836,10 @@ int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos)
} }
/* /**
Store the primary key of this record in ref Store the primary key of this record in ref
variable, so that the row can be retrieved again later variable, so that the row can be retrieved again later
using "reference" in rnd_pos using "reference" in rnd_pos.
*/ */
void ha_ndbcluster::position(const uchar *record) void ha_ndbcluster::position(const uchar *record)
@ -4110,14 +4113,13 @@ int ha_ndbcluster::reset()
} }
/* /**
Start of an insert, remember number of rows to be inserted, it will Start of an insert, remember number of rows to be inserted, it will
be used in write_row and get_autoincrement to send an optimal number be used in write_row and get_autoincrement to send an optimal number
of rows in each roundtrip to the server of rows in each roundtrip to the server.
SYNOPSIS @param
rows number of rows to insert, 0 if unknown rows number of rows to insert, 0 if unknown
*/ */
void ha_ndbcluster::start_bulk_insert(ha_rows rows) void ha_ndbcluster::start_bulk_insert(ha_rows rows)
@ -4167,9 +4169,9 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
End of an insert End of an insert.
*/ */
int ha_ndbcluster::end_bulk_insert() int ha_ndbcluster::end_bulk_insert()
{ {
int error= 0; int error= 0;
@ -4230,8 +4232,9 @@ const char** ha_ndbcluster::bas_ext() const
return ha_ndbcluster_exts; return ha_ndbcluster_exts;
} }
/* /**
How many seeks it will take to read through the table How many seeks it will take to read through the table.
This is to be comparable to the number returned by records_in_range so This is to be comparable to the number returned by records_in_range so
that we can decide if we should scan the table or use keys. that we can decide if we should scan the table or use keys.
*/ */
@ -4582,7 +4585,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Unlock the last row read in an open scan. Unlock the last row read in an open scan.
Rows are unlocked by default in ndb, but Rows are unlocked by default in ndb, but
for SELECT FOR UPDATE and SELECT LOCK WIT SHARE MODE for SELECT FOR UPDATE and SELECT LOCK WIT SHARE MODE
@ -4598,12 +4601,12 @@ void ha_ndbcluster::unlock_row()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
Start a transaction for running a statement if one is not Start a transaction for running a statement if one is not
already running in a transaction. This will be the case in already running in a transaction. This will be the case in
a BEGIN; COMMIT; block a BEGIN; COMMIT; block
When using LOCK TABLE's external_lock will start a transaction When using LOCK TABLE's external_lock will start a transaction
since ndb does not currently does not support table locking since ndb does not currently does not support table locking.
*/ */
int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type) int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
@ -4633,9 +4636,9 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
} }
/* /**
Commit a transaction started in NDB Commit a transaction started in NDB.
*/ */
static int ndbcluster_commit(handlerton *hton, THD *thd, bool all) static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
{ {
@ -4695,9 +4698,9 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
} }
/* /**
Rollback a transaction started in NDB Rollback a transaction started in NDB.
*/ */
static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all) static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
{ {
@ -4735,14 +4738,17 @@ static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
} }
/* /**
Define NDB column based on Field. Define NDB column based on Field.
Returns 0 or mysql error code.
Not member of ha_ndbcluster because NDBCOL cannot be declared. Not member of ha_ndbcluster because NDBCOL cannot be declared.
MySQL text types with character set "binary" are mapped to true MySQL text types with character set "binary" are mapped to true
NDB binary types without a character set. This may change. NDB binary types without a character set. This may change.
*/
@return
Returns 0 or mysql error code.
*/
static int create_ndb_column(NDBCOL &col, static int create_ndb_column(NDBCOL &col,
Field *field, Field *field,
@ -5029,7 +5035,7 @@ static int create_ndb_column(NDBCOL &col,
return 0; return 0;
} }
/* /**
Create a table in NDB Cluster Create a table in NDB Cluster
*/ */
@ -5577,9 +5583,12 @@ int ha_ndbcluster::create_unique_index(const char *name,
} }
/* /**
Create an index in NDB Cluster Create an index in NDB Cluster.
*/
@todo
Only temporary ordered indexes supported
*/
int ha_ndbcluster::create_ndb_index(const char *name, int ha_ndbcluster::create_ndb_index(const char *name,
KEY *key_info, KEY *key_info,
@ -5722,8 +5731,8 @@ int ha_ndbcluster::final_drop_index(TABLE *table_arg)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Rename a table in NDB Cluster Rename a table in NDB Cluster.
*/ */
int ha_ndbcluster::rename_table(const char *from, const char *to) int ha_ndbcluster::rename_table(const char *from, const char *to)
@ -5903,10 +5912,9 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
} }
/* /**
Delete table from NDB Cluster Delete table from NDB Cluster.
*/
*/
/* static version which does not need a handler */ /* static version which does not need a handler */
@ -6175,9 +6183,9 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
} }
/* /**
Constructor for the NDB Cluster table handler Constructor for the NDB Cluster table handler .
*/ */
/* /*
Normal flags for binlogging is that ndb has HA_HAS_OWN_BINLOGGING Normal flags for binlogging is that ndb has HA_HAS_OWN_BINLOGGING
@ -6263,9 +6271,9 @@ int ha_ndbcluster::ha_initialise()
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* /**
Destructor for NDB Cluster table handler Destructor for NDB Cluster table handler.
*/ */
ha_ndbcluster::~ha_ndbcluster() ha_ndbcluster::~ha_ndbcluster()
{ {
@ -6305,13 +6313,15 @@ ha_ndbcluster::~ha_ndbcluster()
/* /**
Open a table for further use Open a table for further use.
- fetch metadata for this table from NDB - fetch metadata for this table from NDB
- check that table exists - check that table exists
RETURN @retval
0 ok 0 ok
@retval
< 0 Table has changed < 0 Table has changed
*/ */
@ -6419,10 +6429,9 @@ void ha_ndbcluster::set_part_info(partition_info *part_info)
m_use_partition_function= TRUE; m_use_partition_function= TRUE;
} }
/* /**
Close the table Close the table; release resources setup by open().
- release resources setup by open() */
*/
int ha_ndbcluster::close(void) int ha_ndbcluster::close(void)
{ {
@ -6439,6 +6448,12 @@ int ha_ndbcluster::close(void)
} }
/**
@todo
- Alt.1 If init fails because to many allocated Ndb
wait on condition for a Ndb object to be released.
- Alt.2 Seize/release from pool, wait until next release
*/
Thd_ndb* ha_ndbcluster::seize_thd_ndb() Thd_ndb* ha_ndbcluster::seize_thd_ndb()
{ {
Thd_ndb *thd_ndb; Thd_ndb *thd_ndb;
@ -6474,7 +6489,7 @@ void ha_ndbcluster::release_thd_ndb(Thd_ndb* thd_ndb)
} }
/* /**
If this thread already has a Thd_ndb object allocated If this thread already has a Thd_ndb object allocated
in current THD, reuse it. Otherwise in current THD, reuse it. Otherwise
seize a Thd_ndb object, assign it to current THD and use it. seize a Thd_ndb object, assign it to current THD and use it.
@ -6523,9 +6538,9 @@ static int ndbcluster_close_connection(handlerton *hton, THD *thd)
} }
/* /**
Try to discover one table from NDB Try to discover one table from NDB.
*/ */
int ndbcluster_discover(handlerton *hton, THD* thd, const char *db, int ndbcluster_discover(handlerton *hton, THD* thd, const char *db,
const char *name, const char *name,
@ -6632,10 +6647,9 @@ err:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Check if a table exists in NDB Check if a table exists in NDB.
*/
*/
int ndbcluster_table_exists_in_engine(handlerton *hton, THD* thd, int ndbcluster_table_exists_in_engine(handlerton *hton, THD* thd,
const char *db, const char *db,
@ -6674,11 +6688,12 @@ extern "C" uchar* tables_get_key(const char *entry, size_t *length,
} }
/* /**
Drop a database in NDB Cluster Drop a database in NDB Cluster
NOTE add a dummy void function, since stupid handlerton is returning void instead of int...
*/
@note
add a dummy void function, since stupid handlerton is returning void instead of int...
*/
int ndbcluster_drop_database_impl(const char *path) int ndbcluster_drop_database_impl(const char *path)
{ {
DBUG_ENTER("ndbcluster_drop_database"); DBUG_ENTER("ndbcluster_drop_database");
@ -7434,10 +7449,9 @@ void ha_ndbcluster::print_error(int error, myf errflag)
} }
/* /**
Static error print function called from Static error print function called from static handler method
static handler method ndbcluster_commit ndbcluster_commit and ndbcluster_rollback.
and ndbcluster_rollback
*/ */
void ndbcluster_print_error(int error, const NdbOperation *error_op) void ndbcluster_print_error(int error, const NdbOperation *error_op)
@ -7455,9 +7469,9 @@ void ndbcluster_print_error(int error, const NdbOperation *error_op)
} }
/** /**
* Set a given location from full pathname to database name Set a given location from full pathname to database name.
* */
*/
void ha_ndbcluster::set_dbname(const char *path_name, char *dbname) void ha_ndbcluster::set_dbname(const char *path_name, char *dbname)
{ {
char *end, *ptr, *tmp_name; char *end, *ptr, *tmp_name;
@ -7490,9 +7504,9 @@ void ha_ndbcluster::set_dbname(const char *path_name, char *dbname)
filename_to_tablename(tmp_name, dbname, FN_REFLEN); filename_to_tablename(tmp_name, dbname, FN_REFLEN);
} }
/* /**
Set m_dbname from full pathname to table file Set m_dbname from full pathname to table file.
*/ */
void ha_ndbcluster::set_dbname(const char *path_name) void ha_ndbcluster::set_dbname(const char *path_name)
{ {
@ -7500,9 +7514,9 @@ void ha_ndbcluster::set_dbname(const char *path_name)
} }
/** /**
* Set a given location from full pathname to table file Set a given location from full pathname to table file.
* */
*/
void void
ha_ndbcluster::set_tabname(const char *path_name, char * tabname) ha_ndbcluster::set_tabname(const char *path_name, char * tabname)
{ {
@ -7531,9 +7545,9 @@ ha_ndbcluster::set_tabname(const char *path_name, char * tabname)
filename_to_tablename(tmp_name, tabname, FN_REFLEN); filename_to_tablename(tmp_name, tabname, FN_REFLEN);
} }
/* /**
Set m_tabname from full pathname to table file Set m_tabname from full pathname to table file.
*/ */
void ha_ndbcluster::set_tabname(const char *path_name) void ha_ndbcluster::set_tabname(const char *path_name)
{ {
@ -7804,31 +7818,30 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
} }
/* /**
Check if a cached query can be used. Check if a cached query can be used.
This is done by comparing the supplied engine_data to commit_count of This is done by comparing the supplied engine_data to commit_count of
the table. the table.
The commit_count is either retrieved from the share for the table, where The commit_count is either retrieved from the share for the table, where
it has been cached by the util thread. If the util thread is not started, it has been cached by the util thread. If the util thread is not started,
NDB has to be contacetd to retrieve the commit_count, this will introduce NDB has to be contacetd to retrieve the commit_count, this will introduce
a small delay while waiting for NDB to answer. a small delay while waiting for NDB to answer.
SYNOPSIS @param thd thread handle
ndbcluster_cache_retrieval_allowed @param full_name concatenation of database name,
thd thread handle the null character '\\0', and the table name
full_name concatenation of database name, @param full_name_len length of the full name,
the null character '\0', and the table
name
full_name_len length of the full name,
i.e. len(dbname) + len(tablename) + 1 i.e. len(dbname) + len(tablename) + 1
@param engine_data parameter retrieved when query was first inserted into
engine_data parameter retrieved when query was first inserted into
the cache. If the value of engine_data is changed, the cache. If the value of engine_data is changed,
all queries for this table should be invalidated. all queries for this table should be invalidated.
RETURN VALUE @retval
TRUE Yes, use the query from cache TRUE Yes, use the query from cache
@retval
FALSE No, don't use the cached query, and if engine_data FALSE No, don't use the cached query, and if engine_data
has changed, all queries for this table should be invalidated has changed, all queries for this table should be invalidated
@ -7884,25 +7897,25 @@ ndbcluster_cache_retrieval_allowed(THD *thd,
/** /**
Register a table for use in the query cache. Fetch the commit_count Register a table for use in the query cache.
for the table and return it in engine_data, this will later be used
to check if the table has changed, before the cached query is reused.
SYNOPSIS Fetch the commit_count for the table and return it in engine_data,
ha_ndbcluster::can_query_cache_table this will later be used to check if the table has changed, before
thd thread handle the cached query is reused.
full_name concatenation of database name,
the null character '\0', and the table @param thd thread handle
name @param full_name concatenation of database name,
full_name_len length of the full name, the null character '\\0', and the table name
@param full_name_len length of the full name,
i.e. len(dbname) + len(tablename) + 1 i.e. len(dbname) + len(tablename) + 1
qc_engine_callback function to be called before using cache on this table @param engine_callback function to be called before using cache on
engine_data out, commit_count for this table this table
@param[out] engine_data commit_count for this table
RETURN VALUE @retval
TRUE Yes, it's ok to cahce this query TRUE Yes, it's ok to cahce this query
@retval
FALSE No, don't cach the query FALSE No, don't cach the query
*/ */
my_bool my_bool
@ -7939,13 +7952,14 @@ ha_ndbcluster::register_query_cache_table(THD *thd,
} }
/* /**
Handling the shared NDB_SHARE structure that is needed to Handling the shared NDB_SHARE structure that is needed to
provide table locking. provide table locking.
It's also used for sharing data with other NDB handlers It's also used for sharing data with other NDB handlers
in the same MySQL Server. There is currently not much in the same MySQL Server. There is currently not much
data we want to or can share. data we want to or can share.
*/ */
static uchar *ndbcluster_get_key(NDB_SHARE *share, size_t *length, static uchar *ndbcluster_get_key(NDB_SHARE *share, size_t *length,
my_bool not_used __attribute__((unused))) my_bool not_used __attribute__((unused)))
@ -8498,9 +8512,9 @@ retry:
DBUG_RETURN(reterr); DBUG_RETURN(reterr);
} }
/* /**
Create a .ndb file to serve as a placeholder indicating Create a .ndb file to serve as a placeholder indicating
that the table with this name is a ndb table that the table with this name is a ndb table.
*/ */
int ha_ndbcluster::write_ndb_file(const char *name) int ha_ndbcluster::write_ndb_file(const char *name)
@ -8607,7 +8621,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE; thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE;
m_disable_multi_read= FALSE; m_disable_multi_read= FALSE;
/** /*
* Copy arguments into member variables * Copy arguments into member variables
*/ */
m_multi_ranges= ranges; m_multi_ranges= ranges;
@ -8616,7 +8630,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
multi_range_sorted= sorted; multi_range_sorted= sorted;
multi_range_buffer= buffer; multi_range_buffer= buffer;
/** /*
* read multi range will read ranges as follows (if not ordered) * read multi range will read ranges as follows (if not ordered)
* *
* input read order * input read order
@ -8629,7 +8643,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
* pk-op 6 pk-ok 6 * pk-op 6 pk-ok 6
*/ */
/** /*
* Variables for loop * Variables for loop
*/ */
uchar *curr= (uchar*)buffer->buffer; uchar *curr= (uchar*)buffer->buffer;
@ -8756,7 +8770,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
if (multi_range_curr != multi_range_end) if (multi_range_curr != multi_range_end)
{ {
/** /*
* Mark that we're using entire buffer (even if might not) as * Mark that we're using entire buffer (even if might not) as
* we haven't read all ranges for some reason * we haven't read all ranges for some reason
* This as we don't want mysqld to reuse the buffer when we read * This as we don't want mysqld to reuse the buffer when we read
@ -8769,7 +8783,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
buffer->end_of_used_area= curr; buffer->end_of_used_area= curr;
} }
/** /*
* Set first operation in multi range * Set first operation in multi range
*/ */
m_current_multi_operation= m_current_multi_operation=
@ -8873,10 +8887,10 @@ ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
continue; continue;
} }
} }
else /** m_multi_cursor == 0 */ else /* m_multi_cursor == 0 */
{ {
DBUG_MULTI_RANGE(7); DBUG_MULTI_RANGE(7);
/** /*
* Corresponds to range 5 in example in read_multi_range_first * Corresponds to range 5 in example in read_multi_range_first
*/ */
(void)1; (void)1;
@ -8907,7 +8921,7 @@ close_scan:
DBUG_RETURN(HA_ERR_END_OF_FILE); DBUG_RETURN(HA_ERR_END_OF_FILE);
} }
/** /*
* Read remaining ranges * Read remaining ranges
*/ */
DBUG_RETURN(read_multi_range_first(multi_range_found_p, DBUG_RETURN(read_multi_range_first(multi_range_found_p,
@ -8917,7 +8931,7 @@ close_scan:
multi_range_buffer)); multi_range_buffer));
found: found:
/** /*
* Found a record belonging to a scan * Found a record belonging to a scan
*/ */
m_active_cursor= m_multi_cursor; m_active_cursor= m_multi_cursor;
@ -8929,7 +8943,7 @@ found:
DBUG_RETURN(0); DBUG_RETURN(0);
found_next: found_next:
/** /*
* Found a record belonging to a pk/index op, * Found a record belonging to a pk/index op,
* copy result and move to next to prepare for next call * copy result and move to next to prepare for next call
*/ */
@ -8970,6 +8984,12 @@ ha_ndbcluster::setup_recattr(const NdbRecAttr* curr)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/**
@param[in] comment table comment defined by user
@return
table comment + additional
*/
char* char*
ha_ndbcluster::update_table_comment( ha_ndbcluster::update_table_comment(
/* out: table comment + additional */ /* out: table comment + additional */
@ -9011,7 +9031,9 @@ ha_ndbcluster::update_table_comment(
} }
// Utility thread main loop /**
Utility thread main loop.
*/
pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
{ {
THD *thd; /* needs to be first for thread_stack */ THD *thd; /* needs to be first for thread_stack */
@ -9298,7 +9320,7 @@ ndb_util_thread_fail:
/* /*
Condition pushdown Condition pushdown
*/ */
/* /**
Push a condition to ndbcluster storage engine for evaluation Push a condition to ndbcluster storage engine for evaluation
during table and index scans. The conditions will be stored on a stack during table and index scans. The conditions will be stored on a stack
for possibly storing several conditions. The stack can be popped for possibly storing several conditions. The stack can be popped
@ -9309,9 +9331,10 @@ ndb_util_thread_fail:
expressions and function calls) and the following comparison operators: expressions and function calls) and the following comparison operators:
=, !=, >, >=, <, <=, "is null", and "is not null". =, !=, >, >=, <, <=, "is null", and "is not null".
RETURN @retval
NULL The condition was supported and will be evaluated for each NULL The condition was supported and will be evaluated for each
row found during the scan row found during the scan
@retval
cond The condition was not supported and all rows will be returned from cond The condition was not supported and all rows will be returned from
the scan for evaluation (and thus not saved on stack) the scan for evaluation (and thus not saved on stack)
*/ */
@ -9331,7 +9354,7 @@ ha_ndbcluster::cond_push(const COND *cond)
DBUG_RETURN(m_cond->cond_push(cond, table, (NDBTAB *)m_table)); DBUG_RETURN(m_cond->cond_push(cond, table, (NDBTAB *)m_table));
} }
/* /**
Pop the top condition from the condition stack of the handler instance. Pop the top condition from the condition stack of the handler instance.
*/ */
void void

View File

@ -199,8 +199,8 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
} }
/** @brief /**
Use other database handler if databasehandler is not compiled in Use other database handler if databasehandler is not compiled in.
*/ */
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
bool no_substitute, bool report_error) bool no_substitute, bool report_error)
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
#endif #endif
/** @brief /**
Register handler error messages for use with my_error(). Register handler error messages for use with my_error().
SYNOPSIS @retval
ha_init_errors()
RETURN
0 OK 0 OK
!= 0 Error @retval
!=0 Error
*/ */
static int ha_init_errors(void) static int ha_init_errors(void)
{ {
@ -349,15 +347,13 @@ static int ha_init_errors(void)
} }
/** @brief /**
Unregister handler error messages. Unregister handler error messages.
SYNOPSIS @retval
ha_finish_errors()
RETURN
0 OK 0 OK
!= 0 Error @retval
!=0 Error
*/ */
static int ha_finish_errors(void) static int ha_finish_errors(void)
{ {
@ -567,7 +563,8 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
} }
/** @brief /**
@note
don't bother to rollback here, it's done already don't bother to rollback here, it's done already
*/ */
void ha_close_connection(THD* thd) void ha_close_connection(THD* thd)
@ -578,17 +575,16 @@ void ha_close_connection(THD* thd)
/* ======================================================================== /* ========================================================================
======================= TRANSACTIONS ===================================*/ ======================= TRANSACTIONS ===================================*/
/** @brief /**
Register a storage engine for a transaction Register a storage engine for a transaction.
DESCRIPTION
Every storage engine MUST call this function when it starts Every storage engine MUST call this function when it starts
a transaction or a statement (that is it must be called both for the a transaction or a statement (that is it must be called both for the
"beginning of transaction" and "beginning of statement"). "beginning of transaction" and "beginning of statement").
Only storage engines registered for the transaction/statement Only storage engines registered for the transaction/statement
will know when to commit/rollback it. will know when to commit/rollback it.
NOTE @note
trans_register_ha is idempotent - storage engine may register many trans_register_ha is idempotent - storage engine may register many
times per transaction. times per transaction.
@ -620,10 +616,11 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/** @brief /**
RETURN @retval
0 - ok 0 ok
1 - error, transaction was rolled back @retval
1 error, transaction was rolled back
*/ */
int ha_prepare(THD *thd) int ha_prepare(THD *thd)
{ {
@ -660,11 +657,19 @@ int ha_prepare(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/** @brief /**
RETURN @retval
0 - ok 0 ok
1 - transaction was rolled back @retval
2 - error during commit, data may be inconsistent 1 transaction was rolled back
@retval
2 error during commit, data may be inconsistent
@todo
Since we don't support nested statement transactions in 5.0,
we can't commit or rollback stmt transactions while we are inside
stored functions or triggers. So we simply do nothing now.
TODO: This should be fixed in later ( >= 5.1) releases.
*/ */
int ha_commit_trans(THD *thd, bool all) int ha_commit_trans(THD *thd, bool all)
{ {
@ -757,9 +762,9 @@ end:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/** @brief /**
NOTE - this function does not care about global read lock. @note
A caller should. This function does not care about global read lock. A caller should.
*/ */
int ha_commit_one_phase(THD *thd, bool all) int ha_commit_one_phase(THD *thd, bool all)
{ {
@ -869,9 +874,12 @@ int ha_rollback_trans(THD *thd, bool all)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/** @brief /**
This is used to commit or rollback a single statement depending on the value This is used to commit or rollback a single statement depending on
of error. Note that if the autocommit is on, then the following call inside the value of error.
@note
Note that if the autocommit is on, then the following call inside
InnoDB will commit or rollback the whole transaction (= the statement). The InnoDB will commit or rollback the whole transaction (= the statement). The
autocommit mechanism built into InnoDB is based on counting locks, but if autocommit mechanism built into InnoDB is based on counting locks, but if
the user has used LOCK TABLES then that mechanism does not know to do the the user has used LOCK TABLES then that mechanism does not know to do the
@ -944,7 +952,10 @@ int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* this does not need to be multi-byte safe or anything */ /**
@note
This does not need to be multi-byte safe or anything
*/
static char* xid_to_str(char *buf, XID *xid) static char* xid_to_str(char *buf, XID *xid)
{ {
int i; int i;
@ -996,21 +1007,18 @@ static char* xid_to_str(char *buf, XID *xid)
} }
#endif #endif
/** @brief /**
recover() step of xa recover() step of xa.
NOTE @note
there are three modes of operation: there are three modes of operation:
- automatic recover after a crash - automatic recover after a crash
in this case commit_list != 0, tc_heuristic_recover==0 in this case commit_list != 0, tc_heuristic_recover==0
all xids from commit_list are committed, others are rolled back all xids from commit_list are committed, others are rolled back
- manual (heuristic) recover - manual (heuristic) recover
in this case commit_list==0, tc_heuristic_recover != 0 in this case commit_list==0, tc_heuristic_recover != 0
DBA has explicitly specified that all prepared transactions should DBA has explicitly specified that all prepared transactions should
be committed (or rolled back). be committed (or rolled back).
- no recovery (MySQL did not detect a crash) - no recovery (MySQL did not detect a crash)
in this case commit_list==0, tc_heuristic_recover == 0 in this case commit_list==0, tc_heuristic_recover == 0
there should be no prepared transactions in this case. there should be no prepared transactions in this case.
@ -1146,10 +1154,10 @@ int ha_recover(HASH *commit_list)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/** @brief /**
return the list of XID's to a client, the same way SHOW commands do return the list of XID's to a client, the same way SHOW commands do.
NOTE @note
I didn't find in XA specs that an RM cannot return the same XID twice, I didn't find in XA specs that an RM cannot return the same XID twice,
so mysql_xa_recover does not filter XID's to ensure uniqueness. so mysql_xa_recover does not filter XID's to ensure uniqueness.
It can be easily fixed later, if necessary. It can be easily fixed later, if necessary.
@ -1195,7 +1203,8 @@ bool mysql_xa_recover(THD *thd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/** @brief /**
@details
This function should be called when MySQL sends rows of a SELECT result set This function should be called when MySQL sends rows of a SELECT result set
or the EOF mark to the client. It releases a possible adaptive hash index or the EOF mark to the client. It releases a possible adaptive hash index
S-latch held by thd in InnoDB and also releases a possible InnoDB query S-latch held by thd in InnoDB and also releases a possible InnoDB query
@ -1207,9 +1216,10 @@ bool mysql_xa_recover(THD *thd)
performs another SQL query. In MySQL-4.1 this is even more important because performs another SQL query. In MySQL-4.1 this is even more important because
there a connection can have several SELECT queries open at the same time. there a connection can have several SELECT queries open at the same time.
arguments: @param thd the thread handle of the current connection
thd: the thread handle of the current connection
return value: always 0 @return
always 0
*/ */
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin, static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
void *unused) void *unused)
@ -1276,8 +1286,9 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/** @brief /**
note, that according to the sql standard (ISO/IEC 9075-2:2003) @note
according to the sql standard (ISO/IEC 9075-2:2003)
section "4.33.4 SQL-statements and transaction states", section "4.33.4 SQL-statements and transaction states",
SAVEPOINT is *not* transaction-initiating SQL-statement SAVEPOINT is *not* transaction-initiating SQL-statement
*/ */
@ -1573,8 +1584,9 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
} }
/** @brief /**
Read first row (only) from a table Read first row (only) from a table.
This is never called for InnoDB tables, as these table types This is never called for InnoDB tables, as these table types
has the HA_STATS_RECORDS_IS_EXACT set. has the HA_STATS_RECORDS_IS_EXACT set.
*/ */
@ -1607,16 +1619,16 @@ int handler::read_first_row(uchar * buf, uint primary_key)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/** @brief /**
Generate the next auto-increment number based on increment and offset: Generate the next auto-increment number based on increment and offset.
computes the lowest number computes the lowest number
- strictly greater than "nr" - strictly greater than "nr"
- of the form: auto_increment_offset + N * auto_increment_increment - of the form: auto_increment_offset + N * auto_increment_increment
In most cases increment= offset= 1, in which case we get: In most cases increment= offset= 1, in which case we get:
1,2,3,4,5,... @verbatim 1,2,3,4,5,... @endverbatim
If increment=10 and offset=5 and previous number is 1, we get: If increment=10 and offset=5 and previous number is 1, we get:
1,5,15,25,35,... @verbatim 1,5,15,25,35,... @endverbatim
*/ */
inline ulonglong inline ulonglong
compute_next_insert_id(ulonglong nr,struct system_variables *variables) compute_next_insert_id(ulonglong nr,struct system_variables *variables)
@ -1682,23 +1694,10 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
} }
/* /**
Update the auto_increment field if necessary Update the auto_increment field if necessary.
SYNOPSIS Updates columns with type NEXT_NUMBER if:
update_auto_increment()
RETURN
0 ok
HA_ERR_AUTOINC_READ_FAILED
get_auto_increment() was called and returned ~(ulonglong) 0
HA_ERR_AUTOINC_ERANGE
storing value in field caused strict mode failure.
IMPLEMENTATION
Updates the record's Field of type NEXT_NUMBER if:
- If column value is set to NULL (in which case - If column value is set to NULL (in which case
auto_increment_field_not_null is 0) auto_increment_field_not_null is 0)
@ -1749,13 +1748,20 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
this list. this list.
TODO @todo
Replace all references to "next number" or NEXT_NUMBER to Replace all references to "next number" or NEXT_NUMBER to
"auto_increment", everywhere (see below: there is "auto_increment", everywhere (see below: there is
table->auto_increment_field_not_null, and there also exists table->auto_increment_field_not_null, and there also exists
table->next_number_field, it's not consistent). table->next_number_field, it's not consistent).
@retval
0 ok
@retval
HA_ERR_AUTOINC_READ_FAILED get_auto_increment() was called and
returned ~(ulonglong) 0
@retval
HA_ERR_AUTOINC_ERANGE storing value in field caused strict mode
failure.
*/ */
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here #define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
@ -2059,14 +2065,14 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
} }
/** @brief /**
Print error that we got from handler function Print error that we got from handler function.
NOTE @note
In case of delete table it's only safe to use the following parts of In case of delete table it's only safe to use the following parts of
the 'table' structure: the 'table' structure:
table->s->path - table->s->path
table->alias - table->alias
*/ */
void handler::print_error(int error, myf errflag) void handler::print_error(int error, myf errflag)
{ {
@ -2253,13 +2259,13 @@ void handler::print_error(int error, myf errflag)
} }
/** @brief /**
Return an error message specific to this handler Return an error message specific to this handler.
SYNOPSIS @param error error code previously returned by handler
error error code previously returned by handler @param buf pointer to String where to add error message
buf Pointer to String where to add error message
@return
Returns true if this is a temporary error Returns true if this is a temporary error
*/ */
bool handler::get_error_message(int error, String* buf) bool handler::get_error_message(int error, String* buf)
@ -2367,8 +2373,10 @@ err:
/** @brief /**
Return key if error because of duplicated keys */ @return
key if error because of duplicated keys
*/
uint handler::get_dup_key(int error) uint handler::get_dup_key(int error)
{ {
DBUG_ENTER("handler::get_dup_key"); DBUG_ENTER("handler::get_dup_key");
@ -2381,21 +2389,20 @@ uint handler::get_dup_key(int error)
} }
/** @brief /**
Delete all files with extension from bas_ext() Delete all files with extension from bas_ext().
SYNOPSIS @param name Base name of table
delete_table()
name Base name of table
NOTES @note
We assume that the handler may return more extensions than We assume that the handler may return more extensions than
was actually used for the file. was actually used for the file.
RETURN @retval
0 If we successfully deleted at least one file from base_ext and 0 If we successfully deleted at least one file from base_ext and
didn't get any other errors than ENOENT didn't get any other errors than ENOENT
# Error @retval
!0 Error
*/ */
int handler::delete_table(const char *name) int handler::delete_table(const char *name)
{ {
@ -2442,20 +2449,19 @@ void handler::drop_table(const char *name)
} }
/** @brief /**
Performs checks upon the table. Performs checks upon the table.
SYNOPSIS @param thd thread doing CHECK TABLE operation
check() @param check_opt options from the parser
thd thread doing CHECK TABLE operation
check_opt options from the parser
NOTES @retval
RETURN
HA_ADMIN_OK Successful upgrade HA_ADMIN_OK Successful upgrade
@retval
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
@retval
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
@retval
HA_ADMIN_NOT_IMPLEMENTED HA_ADMIN_NOT_IMPLEMENTED
*/ */
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
@ -2491,7 +2497,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
} }
/** @brief /**
Tell the storage engine that it is allowed to "disable transaction" in the Tell the storage engine that it is allowed to "disable transaction" in the
handler. It is a hint that ACID is not required - it is used in NDB for handler. It is a hint that ACID is not required - it is used in NDB for
ALTER TABLE, for example, when data are copied to temporary table. ALTER TABLE, for example, when data are copied to temporary table.
@ -2559,15 +2565,12 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
** Some general functions that isn't in the handler class ** Some general functions that isn't in the handler class
****************************************************************************/ ****************************************************************************/
/** @brief /**
Initiates table-file and calls appropriate database-creator Initiates table-file and calls appropriate database-creator.
NOTES @retval
We must have a write lock on LOCK_open to be sure no other thread
interferes with table
RETURN
0 ok 0 ok
@retval
1 error 1 error
*/ */
int ha_create_table(THD *thd, const char *path, int ha_create_table(THD *thd, const char *path,
@ -2605,17 +2608,18 @@ err:
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);
} }
/** @brief /**
Try to discover table from engine Try to discover table from engine.
NOTES @note
If found, write the frm file to disk. If found, write the frm file to disk.
RETURN VALUES: @retval
-1 Table did not exists -1 Table did not exists
@retval
0 Table created ok 0 Table created ok
@retval
> 0 Error, table existed but could not be created > 0 Error, table existed but could not be created
*/ */
int ha_create_table_from_engine(THD* thd, const char *db, const char *name) int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
{ {
@ -2687,8 +2691,8 @@ void st_ha_check_opt::init()
call to ha_init_key_cache() (probably out of memory) call to ha_init_key_cache() (probably out of memory)
*****************************************************************************/ *****************************************************************************/
/** @brief /**
Init a key cache if it has not been initied before Init a key cache if it has not been initied before.
*/ */
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache) int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
{ {
@ -2711,8 +2715,8 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
} }
/** @brief /**
Resize key cache Resize key cache.
*/ */
int ha_resize_key_cache(KEY_CACHE *key_cache) int ha_resize_key_cache(KEY_CACHE *key_cache)
{ {
@ -2734,7 +2738,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
} }
/** @brief /**
Change parameters for key cache (like size) Change parameters for key cache (like size)
*/ */
int ha_change_key_cache_param(KEY_CACHE *key_cache) int ha_change_key_cache_param(KEY_CACHE *key_cache)
@ -2750,8 +2754,8 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache)
return 0; return 0;
} }
/** @brief /**
Free memory allocated by a key cache Free memory allocated by a key cache.
*/ */
int ha_end_key_cache(KEY_CACHE *key_cache) int ha_end_key_cache(KEY_CACHE *key_cache)
{ {
@ -2759,8 +2763,8 @@ int ha_end_key_cache(KEY_CACHE *key_cache)
return 0; return 0;
} }
/** @brief /**
Move all tables from one key cache to another one Move all tables from one key cache to another one.
*/ */
int ha_change_key_cache(KEY_CACHE *old_key_cache, int ha_change_key_cache(KEY_CACHE *old_key_cache,
KEY_CACHE *new_key_cache) KEY_CACHE *new_key_cache)
@ -2770,13 +2774,15 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
} }
/** @brief /**
Try to discover one table from handler(s) Try to discover one table from handler(s).
RETURN @retval
-1 : Table did not exists -1 Table did not exists
0 : OK. In this case *frmblob and *frmlen are set @retval
>0 : error. frmblob and frmlen may not be set 0 OK. In this case *frmblob and *frmlen are set
@retval
>0 error. frmblob and frmlen may not be set
*/ */
struct st_discover_args struct st_discover_args
{ {
@ -2821,8 +2827,8 @@ int ha_discover(THD *thd, const char *db, const char *name,
} }
/** @brief /**
Call this function in order to give the handler the possibility Call this function in order to give the handler the possiblity
to ask engine if there are any new tables that should be written to disk to ask engine if there are any new tables that should be written to disk
or any dropped tables that need to be removed from disk or any dropped tables that need to be removed from disk
*/ */
@ -2866,16 +2872,15 @@ ha_find_files(THD *thd,const char *db,const char *path,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Ask handler if the table exists in engine Ask handler if the table exists in engine.
@retval
RETURN
HA_ERR_NO_SUCH_TABLE Table does not exist HA_ERR_NO_SUCH_TABLE Table does not exist
@retval
HA_ERR_TABLE_EXIST Table exists HA_ERR_TABLE_EXIST Table exists
# Error code @retval
\# Error code
*/ */
struct st_table_exists_in_engine_args struct st_table_exists_in_engine_args
{ {
const char *db; const char *db;
@ -3050,29 +3055,29 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
} }
#endif #endif
/** @brief /**
Read the first row of a multi-range set. Read the first row of a multi-range set.
SYNOPSIS @param found_range_p Returns a pointer to the element in 'ranges' that
read_multi_range_first()
found_range_p Returns a pointer to the element in 'ranges' that
corresponds to the returned row. corresponds to the returned row.
ranges An array of KEY_MULTI_RANGE range descriptions. @param ranges An array of KEY_MULTI_RANGE range descriptions.
range_count Number of ranges in 'ranges'. @param range_count Number of ranges in 'ranges'.
sorted If result should be sorted per key. @param sorted If result should be sorted per key.
buffer A HANDLER_BUFFER for internal handler usage. @param buffer A HANDLER_BUFFER for internal handler usage.
NOTES @note
Record is read into table->record[0]. - Record is read into table->record[0].
*found_range_p returns a valid value only if read_multi_range_first() - *found_range_p returns a valid value only if read_multi_range_first()
returns 0. returns 0.
Sorting is done within each range. If you want an overall sort, enter - Sorting is done within each range. If you want an overall sort, enter
'ranges' with sorted ranges. 'ranges' with sorted ranges.
RETURN @retval
0 OK, found a row 0 OK, found a row
@retval
HA_ERR_END_OF_FILE No rows in range HA_ERR_END_OF_FILE No rows in range
# Error code @retval
\# Error code
*/ */
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE *ranges, uint range_count, KEY_MULTI_RANGE *ranges, uint range_count,
@ -3106,23 +3111,23 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
} }
/** @brief /**
Read the next row of a multi-range set. Read the next row of a multi-range set.
SYNOPSIS @param found_range_p Returns a pointer to the element in 'ranges' that
read_multi_range_next()
found_range_p Returns a pointer to the element in 'ranges' that
corresponds to the returned row. corresponds to the returned row.
NOTES @note
Record is read into table->record[0]. - Record is read into table->record[0].
*found_range_p returns a valid value only if read_multi_range_next() - *found_range_p returns a valid value only if read_multi_range_next()
returns 0. returns 0.
RETURN @retval
0 OK, found a row 0 OK, found a row
@retval
HA_ERR_END_OF_FILE No (more) rows in range HA_ERR_END_OF_FILE No (more) rows in range
# Error code @retval
\# Error code
*/ */
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p) int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{ {
@ -3176,25 +3181,24 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
} }
/** @brief /**
Read first row between two ranges. Read first row between two ranges.
Store ranges for future calls to read_range_next Store ranges for future calls to read_range_next.
SYNOPSIS @param start_key Start key. Is 0 if no min range
read_range_first() @param end_key End key. Is 0 if no max range
start_key Start key. Is 0 if no min range @param eq_range_arg Set to 1 if start_key == end_key
end_key End key. Is 0 if no max range @param sorted Set to 1 if result should be sorted per key
eq_range_arg Set to 1 if start_key == end_key and the range endpoints
will not change during query execution.
sorted Set to 1 if result should be sorted per key
NOTES @note
Record is read into table->record[0] Record is read into table->record[0]
RETURN @retval
0 Found row 0 Found row
@retval
HA_ERR_END_OF_FILE No rows in range HA_ERR_END_OF_FILE No rows in range
# Error code @retval
\# Error code
*/ */
int handler::read_range_first(const key_range *start_key, int handler::read_range_first(const key_range *start_key,
const key_range *end_key, const key_range *end_key,
@ -3230,19 +3234,18 @@ int handler::read_range_first(const key_range *start_key,
} }
/** @brief /**
Read next row between two ranges. Read next row between two ranges.
SYNOPSIS @note
read_range_next()
NOTES
Record is read into table->record[0] Record is read into table->record[0]
RETURN @retval
0 Found row 0 Found row
@retval
HA_ERR_END_OF_FILE No rows in range HA_ERR_END_OF_FILE No rows in range
# Error code @retval
\# Error code
*/ */
int handler::read_range_next() int handler::read_range_next()
{ {
@ -3263,22 +3266,20 @@ int handler::read_range_next()
} }
/** @brief /**
Compare if found key (in row) is over max-value Compare if found key (in row) is over max-value.
SYNOPSIS @param range range to compare to row. May be 0 for no range
compare_key
range range to compare to row. May be 0 for no range
NOTES @seealso
See key.cc::key_cmp() for details key.cc::key_cmp()
RETURN @return
The return value is SIGN(key_in_row - range_key): The return value is SIGN(key_in_row - range_key):
0 Key is equal to range or 'range' == 0 (no range) - 0 : Key is equal to range or 'range' == 0 (no range)
-1 Key is less than range - -1 : Key is less than range
1 Key is larger than range - 1 : Key is larger than range
*/ */
int handler::compare_key(key_range *range) int handler::compare_key(key_range *range)
{ {
@ -3307,18 +3308,14 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
} }
/** @brief /**
Returns a list of all known extensions. Returns a list of all known extensions.
SYNOPSIS
ha_known_exts()
NOTES
No mutexes, worst case race is a minor surplus memory allocation No mutexes, worst case race is a minor surplus memory allocation
We have to recreate the extension map if mysqld is restarted (for example We have to recreate the extension map if mysqld is restarted (for example
within libmysqld) within libmysqld)
RETURN VALUE @retval
pointer pointer to TYPELIB structure pointer pointer to TYPELIB structure
*/ */
static my_bool exts_handlerton(THD *unused, plugin_ref plugin, static my_bool exts_handlerton(THD *unused, plugin_ref plugin,

View File

@ -14,8 +14,13 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
Get hostname for an IP. Hostnames are checked with reverse name lookup and @file
@brief
Get hostname for an IP.
Hostnames are checked with reverse name lookup and
checked that they doesn't resemble an ip. checked that they doesn't resemble an ip.
*/ */

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Init and dummy functions for interface with unireg */ /**
@file
@brief
Init and dummy functions for interface with unireg
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include <m_ctype.h> #include <m_ctype.h>

File diff suppressed because it is too large Load Diff

View File

@ -14,12 +14,17 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Buffers to save and compare item values */ /**
@file
@brief
Buffers to save and compare item values
*/
#include "mysql_priv.h" #include "mysql_priv.h"
/* /**
** Create right type of Cached_item for an item Create right type of Cached_item for an item.
*/ */
Cached_item *new_Cached_item(THD *thd, Item *item) Cached_item *new_Cached_item(THD *thd, Item *item)
@ -45,9 +50,11 @@ Cached_item *new_Cached_item(THD *thd, Item *item)
Cached_item::~Cached_item() {} Cached_item::~Cached_item() {}
/* /**
** Compare with old value and replace value with new value Compare with old value and replace value with new value.
** Return true if values have changed
@return
Return true if values have changed
*/ */
Cached_item_str::Cached_item_str(THD *thd, Item *arg) Cached_item_str::Cached_item_str(THD *thd, Item *arg)

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all compare functions */ /**
@file
@brief
This file defines all compare functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -104,7 +109,7 @@ static int cmp_row_type(Item* item1, Item* item2)
} }
/* /**
Aggregates result types from the array of items. Aggregates result types from the array of items.
SYNOPSIS: SYNOPSIS:
@ -117,11 +122,13 @@ static int cmp_row_type(Item* item1, Item* item2)
This function aggregates result types from the array of items. Found type This function aggregates result types from the array of items. Found type
supposed to be used later for comparison of values of these items. supposed to be used later for comparison of values of these items.
Aggregation itself is performed by the item_cmp_type() function. Aggregation itself is performed by the item_cmp_type() function.
The function also checks compatibility of row signatures for the @param[out] type the aggregated type
submitted items (see the spec for the cmp_row_type function). @param items array of items to aggregate the type from
@param nitems number of items in the array
RETURN VALUES @retval
1 type incompatibility has been detected 1 type incompatibility has been detected
@retval
0 otherwise 0 otherwise
*/ */
@ -257,10 +264,11 @@ void Item_func_not::print(String *str)
str->append(')'); str->append(')');
} }
/* /**
special NOT for ALL subquery special NOT for ALL subquery.
*/ */
longlong Item_func_not_all::val_int() longlong Item_func_not_all::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -293,8 +301,11 @@ void Item_func_not_all::print(String *str)
} }
/* /**
Special NOP (No OPeration) for ALL subquery it is like Item_func_not_all Special NOP (No OPeration) for ALL subquery. It is like
Item_func_not_all.
@return
(return TRUE if underlying subquery do not return rows) but if subquery (return TRUE if underlying subquery do not return rows) but if subquery
returns some rows it return same value as argument (TRUE/FALSE). returns some rows it return same value as argument (TRUE/FALSE).
*/ */
@ -316,16 +327,9 @@ longlong Item_func_nop_all::val_int()
} }
/* /**
Convert a constant item to an int and replace the original item Convert a constant item to an int and replace the original item.
SYNOPSIS
convert_constant_item()
thd thread handle
field item will be converted using the type of this field
item [in/out] reference to the item to convert
DESCRIPTION
The function converts a constant expression or string to an integer. The function converts a constant expression or string to an integer.
On successful conversion the original item is substituted for the On successful conversion the original item is substituted for the
result of the item evaluation. result of the item evaluation.
@ -333,15 +337,20 @@ longlong Item_func_nop_all::val_int()
also when comparing bigint to strings (in which case strings also when comparing bigint to strings (in which case strings
are converted to bigints). are converted to bigints).
NOTES @param thd thread handle
@param field item will be converted using the type of this field
@param[in,out] item reference to the item to convert
@note
This function is called only at prepare stage. This function is called only at prepare stage.
As all derived tables are filled only after all derived tables As all derived tables are filled only after all derived tables
are prepared we do not evaluate items with subselects here because are prepared we do not evaluate items with subselects here because
they can contain derived tables and thus we may attempt to use a they can contain derived tables and thus we may attempt to use a
table that has not been populated yet. table that has not been populated yet.
RESULT VALUES @retval
0 Can't convert item 0 Can't convert item
@retval
1 Item was replaced with an integer version of the item 1 Item was replaced with an integer version of the item
*/ */
@ -1013,13 +1022,15 @@ int Arg_comparator::compare_string()
} }
/* /**
Compare strings byte by byte. End spaces are also compared. Compare strings byte by byte. End spaces are also compared.
RETURN @retval
< 0 *a < *b <0 *a < *b
@retval
0 *b == *b 0 *b == *b
> 0 *a > *b @retval
>0 *a > *b
*/ */
int Arg_comparator::compare_binary_string() int Arg_comparator::compare_binary_string()
@ -1041,10 +1052,11 @@ int Arg_comparator::compare_binary_string()
} }
/* /**
Compare strings, but take into account that NULL == NULL Compare strings, but take into account that NULL == NULL.
*/ */
int Arg_comparator::compare_e_string() int Arg_comparator::compare_e_string()
{ {
String *res1,*res2; String *res1,*res2;
@ -1185,7 +1197,7 @@ int Arg_comparator::compare_int_signed()
} }
/* /**
Compare values as BIGINT UNSIGNED. Compare values as BIGINT UNSIGNED.
*/ */
@ -1208,7 +1220,7 @@ int Arg_comparator::compare_int_unsigned()
} }
/* /**
Compare signed (*a) with unsigned (*B) Compare signed (*a) with unsigned (*B)
*/ */
@ -1233,7 +1245,7 @@ int Arg_comparator::compare_int_signed_unsigned()
} }
/* /**
Compare unsigned (*a) with signed (*B) Compare unsigned (*a) with signed (*B)
*/ */
@ -1269,7 +1281,7 @@ int Arg_comparator::compare_e_int()
return test(val1 == val2); return test(val1 == val2);
} }
/* /**
Compare unsigned *a with signed *b or signed *a with unsigned *b. Compare unsigned *a with signed *b or signed *a with unsigned *b.
*/ */
int Arg_comparator::compare_e_int_diff_signedness() int Arg_comparator::compare_e_int_diff_signedness()
@ -1558,7 +1570,7 @@ longlong Item_func_eq::val_int()
} }
/* Same as Item_func_eq, but NULL = NULL */ /** Same as Item_func_eq, but NULL = NULL. */
void Item_func_equal::fix_length_and_dec() void Item_func_equal::fix_length_and_dec()
{ {
@ -1709,21 +1721,18 @@ void Item_func_interval::fix_length_and_dec()
} }
/* /**
Execute Item_func_interval() Execute Item_func_interval().
SYNOPSIS @note
Item_func_interval::val_int() If we are doing a decimal comparison, we are evaluating the first
item twice.
NOTES @return
If we are doing a decimal comparison, we are - -1 if null value,
evaluating the first item twice. - 0 if lower than lowest
- 1 - arg_count-1 if between args[n] and args[n+1]
RETURN - arg_count if higher than biggest argument
-1 if null value,
0 if lower than lowest
1 - arg_count-1 if between args[n] and args[n+1]
arg_count if higher than biggest argument
*/ */
longlong Item_func_interval::val_int() longlong Item_func_interval::val_int()
@ -1795,32 +1804,31 @@ longlong Item_func_interval::val_int()
} }
/* /**
Perform context analysis of a BETWEEN item tree Perform context analysis of a BETWEEN item tree.
SYNOPSIS:
fix_fields()
thd reference to the global context of the query thread
tables list of all open tables involved in the query
ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
DESCRIPTION
This function performs context analysis (name resolution) and calculates This function performs context analysis (name resolution) and calculates
various attributes of the item tree with Item_func_between as its root. various attributes of the item tree with Item_func_between as its root.
The function saves in ref the pointer to the item or to a newly created The function saves in ref the pointer to the item or to a newly created
item that is considered as a replacement for the original one. item that is considered as a replacement for the original one.
NOTES @param thd reference to the global context of the query thread
@param ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
@note
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
a predicate/function level. Then it's easy to show that: a predicate/function level. Then it's easy to show that:
@verbatim
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2)) T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2))) T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2))) T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2))) T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
@endverbatim
RETURN @retval
0 ok 0 ok
@retval
1 got error 1 got error
*/ */
@ -2156,30 +2164,29 @@ Item_func_ifnull::str_op(String *str)
} }
/* /**
Perform context analysis of an IF item tree Perform context analysis of an IF item tree.
SYNOPSIS:
fix_fields()
thd reference to the global context of the query thread
tables list of all open tables involved in the query
ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
DESCRIPTION
This function performs context analysis (name resolution) and calculates This function performs context analysis (name resolution) and calculates
various attributes of the item tree with Item_func_if as its root. various attributes of the item tree with Item_func_if as its root.
The function saves in ref the pointer to the item or to a newly created The function saves in ref the pointer to the item or to a newly created
item that is considered as a replacement for the original one. item that is considered as a replacement for the original one.
NOTES @param thd reference to the global context of the query thread
@param ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
@note
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
a predicate/function level. Then it's easy to show that: a predicate/function level. Then it's easy to show that:
@verbatim
T0(IF(e,e1,e2) = T1(IF(e,e1,e2)) T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2)) T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
@endverbatim
RETURN @retval
0 ok 0 ok
@retval
1 got error 1 got error
*/ */
@ -2321,11 +2328,14 @@ Item_func_nullif::fix_length_and_dec()
} }
/* /**
nullif () returns NULL if arguments are equal, else it returns the @note
first argument.
Note that we have to evaluate the first argument twice as the compare Note that we have to evaluate the first argument twice as the compare
may have been done with a different type than return value may have been done with a different type than return value
@return
NULL if arguments are equal
@return
the first argument if not equal
*/ */
double double
@ -2397,14 +2407,7 @@ Item_func_nullif::is_null()
} }
/* /**
Return the matching ITEM or NULL if all compares (including else) failed
SYNOPSIS
find_item()
str Buffer string
DESCRIPTION
Find and return matching items for CASE or ELSE item if all compares Find and return matching items for CASE or ELSE item if all compares
are failed or NULL if ELSE item isn't defined. are failed or NULL if ELSE item isn't defined.
@ -2418,9 +2421,10 @@ Item_func_nullif::is_null()
to it according to their int values i.e. STRING_RESULT is mapped to bit to it according to their int values i.e. STRING_RESULT is mapped to bit
0, REAL_RESULT to bit 1, so on. 0, REAL_RESULT to bit 1, so on.
RETURN @retval
NULL - Nothing found and there is no ELSE expression defined NULL Nothing found and there is no ELSE expression defined
item - Found item or ELSE item if defined and all comparisons are @retval
item Found item or ELSE item if defined and all comparisons are
failed failed
*/ */
@ -2645,7 +2649,10 @@ uint Item_func_case::decimal_precision() const
} }
/* TODO: Fix this so that it prints the whole CASE expression */ /**
@todo
Fix this so that it prints the whole CASE expression
*/
void Item_func_case::print(String *str) void Item_func_case::print(String *str)
{ {
@ -2687,7 +2694,7 @@ void Item_func_case::cleanup()
} }
/* /**
Coalesce - return first not NULL argument. Coalesce - return first not NULL argument.
*/ */
@ -3305,32 +3312,31 @@ bool Item_func_in::nulls_in_row()
} }
/* /**
Perform context analysis of an IN item tree Perform context analysis of an IN item tree.
SYNOPSIS:
fix_fields()
thd reference to the global context of the query thread
tables list of all open tables involved in the query
ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
DESCRIPTION
This function performs context analysis (name resolution) and calculates This function performs context analysis (name resolution) and calculates
various attributes of the item tree with Item_func_in as its root. various attributes of the item tree with Item_func_in as its root.
The function saves in ref the pointer to the item or to a newly created The function saves in ref the pointer to the item or to a newly created
item that is considered as a replacement for the original one. item that is considered as a replacement for the original one.
NOTES @param thd reference to the global context of the query thread
@param ref pointer to Item* variable where pointer to resulting "fixed"
item is to be assigned
@note
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
a predicate/function level. Then it's easy to show that: a predicate/function level. Then it's easy to show that:
@verbatim
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei))) T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei))) T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei))) T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei))) T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
@endverbatim
RETURN @retval
0 ok 0 ok
@retval
1 got error 1 got error
*/ */
@ -3805,16 +3811,9 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
} }
/* /**
Transform an Item_cond object with a transformer callback function Transform an Item_cond object with a transformer callback function.
SYNOPSIS
transform()
transformer the transformer callback function to be applied to the nodes
of the tree of the object
arg parameter to be passed to the transformer
DESCRIPTION
The function recursively applies the transform method to each The function recursively applies the transform method to each
member item of the condition list. member item of the condition list.
If the call of the method for a member item returns a new item If the call of the method for a member item returns a new item
@ -3822,7 +3821,11 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
After this the transformer is applied to the root node After this the transformer is applied to the root node
of the Item_cond object. of the Item_cond object.
RETURN VALUES @param transformer the transformer callback function to be applied to
the nodes of the tree of the object
@param arg parameter to be passed to the transformer
@return
Item returned as the result of transformation of the root node Item returned as the result of transformation of the root node
*/ */
@ -3851,19 +3854,10 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
} }
/* /**
Compile Item_cond object with a processor and a transformer callback functions Compile Item_cond object with a processor and a transformer
callback functions.
SYNOPSIS
compile()
analyzer the analyzer callback function to be applied to the nodes
of the tree of the object
arg_p in/out parameter to be passed to the analyzer
transformer the transformer callback function to be applied to the nodes
of the tree of the object
arg_t parameter to be passed to the transformer
DESCRIPTION
First the function applies the analyzer to the root node of First the function applies the analyzer to the root node of
the Item_func object. Then if the analyzer succeeeds (returns TRUE) the Item_func object. Then if the analyzer succeeeds (returns TRUE)
the function recursively applies the compile method to member the function recursively applies the compile method to member
@ -3873,7 +3867,14 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
After this the transformer is applied to the root node After this the transformer is applied to the root node
of the Item_cond object. of the Item_cond object.
RETURN VALUES @param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
@param[in,out] arg_p parameter to be passed to the analyzer
@param transformer the transformer callback function to be applied to the
nodes of the tree of the object
@param arg_t parameter to be passed to the transformer
@return
Item returned as the result of transformation of the root node Item returned as the result of transformation of the root node
*/ */
@ -3923,23 +3924,21 @@ void Item_cond::traverse_cond(Cond_traverser traverser,
} }
} }
/* /**
Move SUM items out from item tree and replace with reference Move SUM items out from item tree and replace with reference.
SYNOPSIS
split_sum_func()
thd Thread handler
ref_pointer_array Pointer to array of reference fields
fields All fields in select
NOTES
This function is run on all expression (SELECT list, WHERE, HAVING etc)
that have or refer (HAVING) to a SUM expression.
The split is done to get an unique item for each SUM function The split is done to get an unique item for each SUM function
so that we can easily find and calculate them. so that we can easily find and calculate them.
(Calculation done by update_sum_func() and copy_sum_funcs() in (Calculation done by update_sum_func() and copy_sum_funcs() in
sql_select.cc) sql_select.cc)
@param thd Thread handler
@param ref_pointer_array Pointer to array of reference fields
@param fields All fields in select
@note
This function is run on all expression (SELECT list, WHERE, HAVING etc)
that have or refer (HAVING) to a SUM expression.
*/ */
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
@ -4010,20 +4009,22 @@ void Item_cond::neg_arguments(THD *thd)
} }
/* /**
Evaluation of AND(expr, expr, expr ...) Evaluation of AND(expr, expr, expr ...).
NOTES: @note
abort_if_null is set for AND expressions for which we don't care if the abort_if_null is set for AND expressions for which we don't care if the
result is NULL or 0. This is set for: result is NULL or 0. This is set for:
- WHERE clause - WHERE clause
- HAVING clause - HAVING clause
- IF(expression) - IF(expression)
RETURN VALUES @retval
1 If all expressions are true 1 If all expressions are true
@retval
0 If all expressions are false or if we find a NULL expression and 0 If all expressions are false or if we find a NULL expression and
'abort_on_null' is set. 'abort_on_null' is set.
@retval
NULL if all expression are either 1 or NULL NULL if all expression are either 1 or NULL
*/ */
@ -4065,24 +4066,23 @@ longlong Item_cond_or::val_int()
return 0; return 0;
} }
/* /**
Create an AND expression from two expressions Create an AND expression from two expressions.
SYNOPSIS @param a expression or NULL
and_expressions() @param b expression.
a expression or NULL @param org_item Don't modify a if a == *org_item.
b expression.
org_item Don't modify a if a == *org_item
If a == NULL, org_item is set to point at b, If a == NULL, org_item is set to point at b,
to ensure that future calls will not modify b. to ensure that future calls will not modify b.
NOTES @note
This will not modify item pointed to by org_item or b This will not modify item pointed to by org_item or b
The idea is that one can call this in a loop and create and The idea is that one can call this in a loop and create and
'and' over all items without modifying any of the original items. 'and' over all items without modifying any of the original items.
RETURN @retval
NULL Error NULL Error
@retval
Item Item
*/ */
@ -4140,7 +4140,9 @@ longlong Item_is_not_null_test::val_int()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Optimize case of not_null_column IS NULL */ /**
Optimize case of not_null_column IS NULL.
*/
void Item_is_not_null_test::update_used_tables() void Item_is_not_null_test::update_used_tables()
{ {
if (!args[0]->maybe_null) if (!args[0]->maybe_null)
@ -4200,7 +4202,9 @@ longlong Item_func_like::val_int()
} }
/* We can optimize a where if first character isn't a wildcard */ /**
We can optimize a where if first character isn't a wildcard
*/
Item_func::optimize_type Item_func_like::select_optimize() const Item_func::optimize_type Item_func_like::select_optimize() const
{ {
@ -4463,10 +4467,9 @@ void Item_func_regex::cleanup()
#endif #endif
/********************************************************************** /**
turboBM_compute_suffixes()
Precomputation dependent only on pattern_len. Precomputation dependent only on pattern_len.
**********************************************************************/ */
void Item_func_like::turboBM_compute_suffixes(int *suff) void Item_func_like::turboBM_compute_suffixes(int *suff)
{ {
@ -4520,10 +4523,9 @@ void Item_func_like::turboBM_compute_suffixes(int *suff)
} }
/********************************************************************** /**
turboBM_compute_good_suffix_shifts()
Precomputation dependent only on pattern_len. Precomputation dependent only on pattern_len.
**********************************************************************/ */
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff) void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
{ {
@ -4565,10 +4567,9 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
} }
/********************************************************************** /**
turboBM_compute_bad_character_shifts()
Precomputation dependent on pattern_len. Precomputation dependent on pattern_len.
**********************************************************************/ */
void Item_func_like::turboBM_compute_bad_character_shifts() void Item_func_like::turboBM_compute_bad_character_shifts()
{ {
@ -4594,10 +4595,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
} }
/********************************************************************** /**
turboBM_matches() Search for pattern in text.
Search for pattern in text, returns true/false for match/no match
**********************************************************************/ @return
returns true/false for match/no match
*/
bool Item_func_like::turboBM_matches(const char* text, int text_len) const bool Item_func_like::turboBM_matches(const char* text, int text_len) const
{ {
@ -4677,24 +4680,20 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
} }
/* /**
Make a logical XOR of the arguments. Make a logical XOR of the arguments.
SYNOPSIS
val_int()
DESCRIPTION
If either operator is NULL, return NULL. If either operator is NULL, return NULL.
NOTE @todo
As we don't do any index optimization on XOR this is not going to be (low priority) Change this to be optimized as: @n
very fast to use. A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
TODO (low priority)
Change this to be optimized as:
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
To be able to do this, we would however first have to extend the MySQL To be able to do this, we would however first have to extend the MySQL
range optimizer to handle OR better. range optimizer to handle OR better.
@note
As we don't do any index optimization on XOR this is not going to be
very fast to use.
*/ */
longlong Item_cond_xor::val_int() longlong Item_cond_xor::val_int()
@ -4716,15 +4715,12 @@ longlong Item_cond_xor::val_int()
return (longlong) result; return (longlong) result;
} }
/* /**
Apply NOT transformation to the item and return a new one. Apply NOT transformation to the item and return a new one.
SYNOPSIS
neg_transformer()
thd thread handler
DESCRIPTION
Transform the item using next rules: Transform the item using next rules:
@verbatim
a AND b AND ... -> NOT(a) OR NOT(b) OR ... a AND b AND ... -> NOT(a) OR NOT(b) OR ...
a OR b OR ... -> NOT(a) AND NOT(b) AND ... a OR b OR ... -> NOT(a) AND NOT(b) AND ...
NOT(a) -> a NOT(a) -> a
@ -4736,8 +4732,11 @@ longlong Item_cond_xor::val_int()
a <= b -> a > b a <= b -> a > b
IS NULL(a) -> IS NOT NULL(a) IS NULL(a) -> IS NOT NULL(a)
IS NOT NULL(a) -> IS NULL(a) IS NOT NULL(a) -> IS NULL(a)
@endverbatim
RETURN @param thd thread handler
@return
New item or New item or
NULL if we cannot apply NOT transformation (see Item::neg_transformer()). NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
*/ */
@ -4755,7 +4754,9 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
} }
/* a IS NULL -> a IS NOT NULL */ /**
a IS NULL -> a IS NOT NULL.
*/
Item *Item_func_isnull::neg_transformer(THD *thd) Item *Item_func_isnull::neg_transformer(THD *thd)
{ {
Item *item= new Item_func_isnotnull(args[0]); Item *item= new Item_func_isnotnull(args[0]);
@ -4763,7 +4764,9 @@ Item *Item_func_isnull::neg_transformer(THD *thd)
} }
/* a IS NOT NULL -> a IS NULL */ /**
a IS NOT NULL -> a IS NULL.
*/
Item *Item_func_isnotnull::neg_transformer(THD *thd) Item *Item_func_isnotnull::neg_transformer(THD *thd)
{ {
Item *item= new Item_func_isnull(args[0]); Item *item= new Item_func_isnull(args[0]);
@ -4846,7 +4849,9 @@ Item *Item_func_le::negated_item() /* a <= b -> a > b */
return new Item_func_gt(args[0], args[1]); return new Item_func_gt(args[0], args[1]);
} }
// just fake method, should never be called /**
just fake method, should never be called.
*/
Item *Item_bool_rowready_func2::negated_item() Item *Item_bool_rowready_func2::negated_item()
{ {
DBUG_ASSERT(0); DBUG_ASSERT(0);
@ -4911,18 +4916,16 @@ uint Item_equal::members()
} }
/* /**
Check whether a field is referred in the multiple equality Check whether a field is referred in the multiple equality.
SYNOPSIS The function checks whether field is occurred in the Item_equal object .
contains()
field field whose occurrence is to be checked
DESCRIPTION @param field field whose occurrence is to be checked
The function checks whether field is occurred in the Item_equal object
RETURN VALUES @retval
1 if nultiple equality contains a reference to field 1 if nultiple equality contains a reference to field
@retval
0 otherwise 0 otherwise
*/ */
@ -4939,22 +4942,15 @@ bool Item_equal::contains(Field *field)
} }
/* /**
Join members of another Item_equal object Join members of another Item_equal object.
SYNOPSIS
merge()
item multiple equality whose members are to be joined
DESCRIPTION
The function actually merges two multiple equalities. The function actually merges two multiple equalities.
After this operation the Item_equal object additionally contains After this operation the Item_equal object additionally contains
the field items of another item of the type Item_equal. the field items of another item of the type Item_equal.
If the optional constant items are not equal the cond_false flag is If the optional constant items are not equal the cond_false flag is
set to 1. set to 1.
@param item multiple equality whose members are to be joined
RETURN VALUES
none
*/ */
void Item_equal::merge(Item_equal *item) void Item_equal::merge(Item_equal *item)
@ -4974,28 +4970,21 @@ void Item_equal::merge(Item_equal *item)
} }
/* /**
Order field items in multiple equality according to a sorting criteria Order field items in multiple equality according to a sorting criteria.
SYNOPSIS
sort()
cmp function to compare field item
arg context extra parameter for the cmp function
DESCRIPTION
The function perform ordering of the field items in the Item_equal The function perform ordering of the field items in the Item_equal
object according to the criteria determined by the cmp callback parameter. object according to the criteria determined by the cmp callback parameter.
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
placed after item_fiel2. placed after item_fiel2.
IMPLEMENTATION
The function sorts field items by the exchange sort algorithm. The function sorts field items by the exchange sort algorithm.
The list of field items is looked through and whenever two neighboring The list of field items is looked through and whenever two neighboring
members follow in a wrong order they are swapped. This is performed members follow in a wrong order they are swapped. This is performed
again and again until we get all members in a right order. again and again until we get all members in a right order.
RETURN VALUES @param cmp function to compare field item
None @param arg context extra parameter for the cmp function
*/ */
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg) void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
@ -5030,21 +5019,14 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
} }
/* /**
Check appearance of new constant items in the multiple equality object Check appearance of new constant items in the multiple equality object.
SYNOPSIS
update_const()
DESCRIPTION
The function checks appearance of new constant items among The function checks appearance of new constant items among
the members of multiple equalities. Each new constant item is the members of multiple equalities. Each new constant item is
compared with the designated constant item if there is any in the compared with the designated constant item if there is any in the
multiple equality. If there is none the first new constant item multiple equality. If there is none the first new constant item
becomes designated. becomes designated.
RETURN VALUES
none
*/ */
void Item_equal::update_const() void Item_equal::update_const()

View File

@ -13,7 +13,12 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to create an item. Used by sql_yacc.yy */ /**
@file
@brief
Functions to create an item. Used by sql_yac.yy
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include "item_create.h" #include "item_create.h"

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all numerical functions */ /**
@file
@brief
This file defines all numerical functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -46,7 +51,10 @@ bool check_reserved_words(LEX_STRING *name)
} }
/* return TRUE if item is a constant */ /**
@return
TRUE if item is a constant
*/
bool bool
eval_const_cond(COND *cond) eval_const_cond(COND *cond)
@ -237,24 +245,20 @@ void Item_func::traverse_cond(Cond_traverser traverser,
} }
/* /**
Transform an Item_func object with a transformer callback function Transform an Item_func object with a transformer callback function.
SYNOPSIS
transform()
transformer the transformer callback function to be applied to the nodes
of the tree of the object
argument parameter to be passed to the transformer
DESCRIPTION
The function recursively applies the transform method to each The function recursively applies the transform method to each
argument of the Item_func node. argument of the Item_func node.
If the call of the method for an argument item returns a new item If the call of the method for an argument item returns a new item
the old item is substituted for a new one. the old item is substituted for a new one.
After this the transformer is applied to the root node After this the transformer is applied to the root node
of the Item_func object. of the Item_func object.
@param transformer the transformer callback function to be applied to
the nodes of the tree of the object
@param argument parameter to be passed to the transformer
RETURN VALUES @return
Item returned as the result of transformation of the root node Item returned as the result of transformation of the root node
*/ */
@ -285,19 +289,10 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
} }
/* /**
Compile Item_func object with a processor and a transformer callback functions Compile Item_func object with a processor and a transformer
callback functions.
SYNOPSIS
compile()
analyzer the analyzer callback function to be applied to the nodes
of the tree of the object
arg_p in/out parameter to be passed to the processor
transformer the transformer callback function to be applied to the nodes
of the tree of the object
arg_t parameter to be passed to the transformer
DESCRIPTION
First the function applies the analyzer to the root node of First the function applies the analyzer to the root node of
the Item_func object. Then if the analizer succeeeds (returns TRUE) the Item_func object. Then if the analizer succeeeds (returns TRUE)
the function recursively applies the compile method to each argument the function recursively applies the compile method to each argument
@ -307,7 +302,14 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
After this the transformer is applied to the root node After this the transformer is applied to the root node
of the Item_func object. of the Item_func object.
RETURN VALUES @param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
@param[in,out] arg_p parameter to be passed to the processor
@param transformer the transformer callback function to be applied to the
nodes of the tree of the object
@param arg_t parameter to be passed to the transformer
@return
Item returned as the result of transformation of the root node Item returned as the result of transformation of the root node
*/ */
@ -334,7 +336,9 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
return (this->*transformer)(arg_t); return (this->*transformer)(arg_t);
} }
/* See comments in Item_cmp_func::split_sum_func() */ /**
See comments in Item_cmp_func::split_sum_func()
*/
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields) List<Item> &fields)
@ -523,12 +527,9 @@ void Item_func_numhybrid::fix_num_length_and_dec()
{} {}
/* /**
Set max_length/decimals of function if function is fixed point and Set max_length/decimals of function if function is fixed point and
result length/precision depends on argument ones result length/precision depends on argument ones.
SYNOPSIS
Item_func::count_decimal_length()
*/ */
void Item_func::count_decimal_length() void Item_func::count_decimal_length()
@ -548,11 +549,8 @@ void Item_func::count_decimal_length()
} }
/* /**
Set max_length of if it is maximum length of its arguments Set max_length of if it is maximum length of its arguments.
SYNOPSIS
Item_func::count_only_length()
*/ */
void Item_func::count_only_length() void Item_func::count_only_length()
@ -567,12 +565,9 @@ void Item_func::count_only_length()
} }
/* /**
Set max_length/decimals of function if function is floating point and Set max_length/decimals of function if function is floating point and
result length/precision depends on argument ones result length/precision depends on argument ones.
SYNOPSIS
Item_func::count_real_length()
*/ */
void Item_func::count_real_length() void Item_func::count_real_length()
@ -655,12 +650,9 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
} }
/* /**
Check arguments here to determine result's type for a numeric Check arguments here to determine result's type for a numeric
function of two arguments. function of two arguments.
SYNOPSIS
Item_num_op::find_num_type()
*/ */
void Item_num_op::find_num_type(void) void Item_num_op::find_num_type(void)
@ -699,13 +691,10 @@ void Item_num_op::find_num_type(void)
} }
/* /**
Set result type for a numeric function of one argument Set result type for a numeric function of one argument
(can be also used by a numeric function of many arguments, if the result (can be also used by a numeric function of many arguments, if the result
type depends only on the first argument) type depends only on the first argument)
SYNOPSIS
Item_func_num1::find_num_type()
*/ */
void Item_func_num1::find_num_type() void Item_func_num1::find_num_type()
@ -1117,16 +1106,15 @@ longlong Item_func_plus::int_op()
} }
/* /**
Calculate plus of two decimail's Calculate plus of two decimals.
SYNOPSIS @param decimal_value Buffer that can be used to store result
decimal_op()
decimal_value Buffer that can be used to store result
RETURN @retval
0 Value was NULL; In this case null_value is set 0 Value was NULL; In this case null_value is set
# Value of operation as a decimal @retval
\# Value of operation as a decimal
*/ */
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
@ -1144,11 +1132,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
return 0; return 0;
} }
/* /**
Set precision of results for additive operations (+ and -) Set precision of results for additive operations (+ and -)
SYNOPSIS
Item_func_additive_op::result_precision()
*/ */
void Item_func_additive_op::result_precision() void Item_func_additive_op::result_precision()
{ {
@ -1167,7 +1152,7 @@ void Item_func_additive_op::result_precision()
} }
/* /**
The following function is here to allow the user to force The following function is here to allow the user to force
subtraction of UNSIGNED BIGINT to return negative values. subtraction of UNSIGNED BIGINT to return negative values.
*/ */
@ -1199,7 +1184,9 @@ longlong Item_func_minus::int_op()
} }
/* See Item_func_plus::decimal_op for comments */ /**
See Item_func_plus::decimal_op for comments.
*/
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
{ {
@ -1238,7 +1225,7 @@ longlong Item_func_mul::int_op()
} }
/* See Item_func_plus::decimal_op for comments */ /** See Item_func_plus::decimal_op for comments. */
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
{ {
@ -1570,7 +1557,7 @@ void Item_func_abs::fix_length_and_dec()
} }
/* Gateway to natural LOG function */ /** Gateway to natural LOG function. */
double Item_func_ln::val_real() double Item_func_ln::val_real()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -1585,8 +1572,9 @@ double Item_func_ln::val_real()
return log(value); return log(value);
} }
/* /**
Extended but so slower LOG function Extended but so slower LOG function.
We have to check if all values are > zero and first one is not one We have to check if all values are > zero and first one is not one
as these are the cases then result is not a number. as these are the cases then result is not a number.
*/ */
@ -3014,8 +3002,10 @@ bool udf_handler::get_arguments()
return 0; return 0;
} }
/* This returns (String*) 0 in case of NULL values */ /**
@return
(String*)NULL in case of NULL values
*/
String *udf_handler::val_str(String *str,String *save_str) String *udf_handler::val_str(String *str,String *save_str)
{ {
uchar is_null_tmp=0; uchar is_null_tmp=0;
@ -3219,10 +3209,11 @@ String *Item_func_udf_str::val_str(String *str)
} }
/* /**
@note
This has to come last in the udf_handler methods, or C for AIX This has to come last in the udf_handler methods, or C for AIX
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.) version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
*/ */
udf_handler::~udf_handler() udf_handler::~udf_handler()
{ {
@ -3320,10 +3311,10 @@ void item_user_lock_release(User_level_lock *ull)
delete ull; delete ull;
} }
/* /**
Wait until we are at or past the given position in the master binlog Wait until we are at or past the given position in the master binlog
on the slave on the slave.
*/ */
longlong Item_master_pos_wait::val_int() longlong Item_master_pos_wait::val_int()
{ {
@ -3425,11 +3416,15 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
#endif #endif
/* /**
Get a user level lock. If the thread has an old lock this is first released. Get a user level lock. If the thread has an old lock this is first released.
Returns 1: Got lock
Returns 0: Timeout @retval
Returns NULL: Error 1 : Got lock
@retval
0 : Timeout
@retval
NULL : Error
*/ */
longlong Item_func_get_lock::val_int() longlong Item_func_get_lock::val_int()
@ -3549,12 +3544,12 @@ longlong Item_func_get_lock::val_int()
} }
/* /**
Release a user level lock. Release a user level lock.
Return: @return
1 if lock released - 1 if lock released
0 if lock wasn't held - 0 if lock wasn't held
(SQL) NULL if no such lock - (SQL) NULL if no such lock
*/ */
longlong Item_func_release_lock::val_int() longlong Item_func_release_lock::val_int()
@ -3679,7 +3674,7 @@ void Item_func_benchmark::print(String *str)
} }
/* This function is just used to create tests with time gaps */ /** This function is just used to create tests with time gaps. */
longlong Item_func_sleep::val_int() longlong Item_func_sleep::val_int()
{ {
@ -3835,22 +3830,22 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
} }
/* /**
Set value to user variable. Set value to user variable.
SYNOPSYS @param entry pointer to structure representing variable
update_hash() @param set_null should we set NULL value ?
entry - pointer to structure representing variable @param ptr pointer to buffer with new value
set_null - should we set NULL value ? @param length length of new value
ptr - pointer to buffer with new value @param type type of new value
length - length of new value @param cs charset info for new value
type - type of new value @param dv derivation for new value
cs - charset info for new value @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
dv - derivation for new value
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
RETURN VALUE @retval
False - success, True - failure false success
@retval
true failure
*/ */
static bool static bool
@ -3935,7 +3930,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
} }
/* Get the value of a variable as a double */ /** Get the value of a variable as a double. */
double user_var_entry::val_real(my_bool *null_value) double user_var_entry::val_real(my_bool *null_value)
{ {
@ -3963,7 +3958,7 @@ double user_var_entry::val_real(my_bool *null_value)
} }
/* Get the value of a variable as an integer */ /** Get the value of a variable as an integer. */
longlong user_var_entry::val_int(my_bool *null_value) longlong user_var_entry::val_int(my_bool *null_value)
{ {
@ -3994,7 +3989,7 @@ longlong user_var_entry::val_int(my_bool *null_value)
} }
/* Get the value of a variable as a string */ /** Get the value of a variable as a string. */
String *user_var_entry::val_str(my_bool *null_value, String *str, String *user_var_entry::val_str(my_bool *null_value, String *str,
uint decimals) uint decimals)
@ -4025,7 +4020,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
return(str); return(str);
} }
/* Get the value of a variable as a decimal */ /** Get the value of a variable as a decimal. */
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
{ {
@ -4052,18 +4047,17 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
return(val); return(val);
} }
/* /**
This functions is invoked on SET @variable or @variable:= expression. This functions is invoked on SET \@variable or
\@variable:= expression.
Evaluate (and check expression), store results. Evaluate (and check expression), store results.
SYNOPSYS @note
Item_func_set_user_var::check()
NOTES
For now it always return OK. All problem with value evaluating For now it always return OK. All problem with value evaluating
will be caught by thd->net.report_error check in sql_set_variables(). will be caught by thd->net.report_error check in sql_set_variables().
RETURN @retval
FALSE OK. FALSE OK.
*/ */
@ -4112,18 +4106,17 @@ Item_func_set_user_var::check(bool use_result_field)
} }
/* /**
This functions is invoked on SET @variable or @variable:= expression. This functions is invoked on
SET \@variable or \@variable:= expression.
SYNOPSIS @note
Item_func_set_user_var::update()
NOTES
We have to store the expression as such in the variable, independent of We have to store the expression as such in the variable, independent of
the value method used by the user the value method used by the user
RETURN @retval
0 OK 0 OK
@retval
1 EOM Error 1 EOM Error
*/ */
@ -4432,24 +4425,23 @@ longlong Item_func_get_user_var::val_int()
} }
/* /**
Get variable by name and, if necessary, put the record of variable Get variable by name and, if necessary, put the record of variable
use into the binary log. use into the binary log.
SYNOPSIS
get_var_with_binlog()
thd Current thread
name Variable name
out_entry [out] variable structure or NULL. The pointer is set
regardless of whether function succeeded or not.
When a user variable is invoked from an update query (INSERT, UPDATE etc), When a user variable is invoked from an update query (INSERT, UPDATE etc),
stores this variable and its value in thd->user_var_events, so that it can be stores this variable and its value in thd->user_var_events, so that it can be
written to the binlog (will be written just before the query is written, see written to the binlog (will be written just before the query is written, see
log.cc). log.cc).
RETURN @param thd Current thread
@param name Variable name
@param[out] out_entry variable structure or NULL. The pointer is set
regardless of whether function succeeded or not.
@retval
0 OK 0 OK
@retval
1 Failed to put appropriate record into binary log 1 Failed to put appropriate record into binary log
*/ */
@ -5104,22 +5096,20 @@ longlong Item_func_bit_xor::val_int()
System variables System variables
****************************************************************************/ ****************************************************************************/
/* /**
Return value of an system variable base[.name] as a constant item Return value of an system variable base[.name] as a constant item.
SYNOPSIS @param thd Thread handler
get_system_var() @param var_type global / session
thd Thread handler @param name Name of base or system variable
var_type global / session @param component Component.
name Name of base or system variable
component Component
NOTES @note
If component.str = 0 then the variable name is in 'name' If component.str = 0 then the variable name is in 'name'
RETURN @return
0 error - 0 : error
# constant item - # : constant item
*/ */
@ -5159,16 +5149,15 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
} }
/* /**
Check a user level lock. Check a user level lock.
SYNOPSIS: Sets null_value=TRUE on error.
val_int()
RETURN VALUES @retval
1 Available 1 Available
0 Already taken @retval
NULL Error 0 Already taken, or error
*/ */
longlong Item_func_is_free_lock::val_int() longlong Item_func_is_free_lock::val_int()

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all spatial functions */ /**
@file
@brief
This file defines all spatial functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -360,7 +365,7 @@ String *Item_func_point::val_str(String *str)
} }
/* /**
Concatenates various items into various collections Concatenates various items into various collections
with checkings for valid wkb type of items. with checkings for valid wkb type of items.
For example, MultiPoint can be a collection of Points only. For example, MultiPoint can be a collection of Points only.
@ -542,6 +547,10 @@ longlong Item_func_isempty::val_int()
} }
/**
@todo
Ramil or Holyfoot, add real IsSimple calculation
*/
longlong Item_func_issimple::val_int() longlong Item_func_issimple::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);

View File

@ -15,13 +15,18 @@
#include "mysql_priv.h" #include "mysql_priv.h"
/* /**
Row items used for comparing rows and IN operations on rows: Row items used for comparing rows and IN operations on rows:
@verbatim
(a, b, c) > (10, 10, 30) (a, b, c) > (10, 10, 30)
(a, b, c) = (select c, d, e, from t1 where x=12) (a, b, c) = (select c, d, e, from t1 where x=12)
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8) (a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
(a, b, c) IN (select c, d, e, from t1) (a, b, c) IN (select c, d, e, from t1)
@endverbatim
@todo
think placing 2-3 component items in item (as it done for function
*/ */
Item_row::Item_row(List<Item> &arg): Item_row::Item_row(List<Item> &arg):

View File

@ -14,9 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all string functions /**
** Warning: Some string functions doesn't always put and end-null on a String @file
** (This shouldn't be needed)
@brief
This file defines all string functions
@warning
Some string functions don't always put and end-null on a String.
(This shouldn't be needed)
*/ */
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
@ -297,9 +303,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
} }
/* /**
Concatenate args with the following premises: Concatenate args with the following premises:
If only one arg (which is ok), return value of arg If only one arg (which is ok), return value of arg;
Don't reallocate val_str() if not absolute necessary. Don't reallocate val_str() if not absolute necessary.
*/ */
@ -430,13 +436,15 @@ void Item_func_concat::fix_length_and_dec()
max_length= (ulong) max_result_length; max_length= (ulong) max_result_length;
} }
/* /**
@details
Function des_encrypt() by tonu@spam.ee & monty Function des_encrypt() by tonu@spam.ee & monty
Works only if compiled with OpenSSL library support. Works only if compiled with OpenSSL library support.
This returns a binary string where first character is CHAR(128 | key-number). @return
A binary string where first character is CHAR(128 | key-number).
If one uses a string key key_number is 127. If one uses a string key key_number is 127.
Encryption result is longer than original by formula: Encryption result is longer than original by formula:
new_length= org_length + (8-(org_length % 8))+1 @code new_length= org_length + (8-(org_length % 8))+1 @endcode
*/ */
String *Item_func_des_encrypt::val_str(String *str) String *Item_func_des_encrypt::val_str(String *str)
@ -609,7 +617,7 @@ wrong_key:
} }
/* /**
concat with separator. First arg is the separator concat with separator. First arg is the separator
concat_ws takes at least two arguments. concat_ws takes at least two arguments.
*/ */
@ -806,12 +814,14 @@ void Item_func_reverse::fix_length_and_dec()
max_length = args[0]->max_length; max_length = args[0]->max_length;
} }
/* /**
** Replace all occurences of string2 in string1 with string3. Replace all occurences of string2 in string1 with string3.
** Don't reallocate val_str() if not needed
*/
/* TODO: Fix that this works with binary strings when using USE_MB */ Don't reallocate val_str() if not needed.
@todo
Fix that this works with binary strings when using USE_MB
*/
String *Item_func_replace::val_str(String *str) String *Item_func_replace::val_str(String *str)
{ {
@ -1776,8 +1786,9 @@ String *Item_func_database::val_str(String *str)
} }
/* /**
TODO: make USER() replicate properly (currently it is replicated to "") @todo
make USER() replicate properly (currently it is replicated to "")
*/ */
bool Item_func_user::init(const char *user, const char *host) bool Item_func_user::init(const char *user, const char *host)
{ {
@ -1837,7 +1848,7 @@ void Item_func_soundex::fix_length_and_dec()
} }
/* /**
If alpha, map input letter to soundex code. If alpha, map input letter to soundex code.
If not alpha and remove_garbage is set then skip to next char If not alpha and remove_garbage is set then skip to next char
else return 0 else return 0
@ -1981,9 +1992,10 @@ String *Item_func_soundex::val_str(String *str)
} }
/* /**
** Change a number to format '3,333,333,333.000' Change a number to format '3,333,333,333.000'.
** This should be 'internationalized' sometimes.
This should be 'internationalized' sometimes.
*/ */
const int FORMAT_MAX_DECIMALS= 30; const int FORMAT_MAX_DECIMALS= 30;
@ -2002,8 +2014,9 @@ void Item_func_format::fix_length_and_dec()
} }
/* /**
TODO: This needs to be fixed for multi-byte character set where numbers @todo
This needs to be fixed for multi-byte character set where numbers
are stored in more than one byte are stored in more than one byte
*/ */
@ -2349,9 +2362,9 @@ void Item_func_repeat::fix_length_and_dec()
} }
} }
/* /**
** Item_func_repeat::str is carefully written to avoid reallocs Item_func_repeat::str is carefully written to avoid reallocs
** as much as possible at the cost of a local buffer as much as possible at the cost of a local buffer
*/ */
String *Item_func_repeat::val_str(String *str) String *Item_func_repeat::val_str(String *str)
@ -2827,7 +2840,7 @@ String *Item_func_hex::val_str(String *str)
return &tmp_value; return &tmp_value;
} }
/* Convert given hex string to a binary string */ /** Convert given hex string to a binary string. */
String *Item_func_unhex::val_str(String *str) String *Item_func_unhex::val_str(String *str)
{ {
@ -3060,27 +3073,27 @@ String* Item_func_inet_ntoa::val_str(String* str)
} }
/* #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
/**
QUOTE() function returns argument string in single quotes suitable for QUOTE() function returns argument string in single quotes suitable for
using in a SQL statement. using in a SQL statement.
DESCRIPTION Adds a \\ before all characters that needs to be escaped in a SQL string.
Adds a \ before all characters that needs to be escaped in a SQL string.
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
running commands from a file in windows. running commands from a file in windows.
This function is very useful when you want to generate SQL statements This function is very useful when you want to generate SQL statements.
NOTE @note
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes). QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
RETURN VALUES @retval
str Quoted string str Quoted string
@retval
NULL Out of memory. NULL Out of memory.
*/ */
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
String *Item_func_quote::val_str(String *str) String *Item_func_quote::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -3326,8 +3339,10 @@ static uint nanoseq;
static ulonglong uuid_time=0; static ulonglong uuid_time=0;
static char clock_seq_and_node_str[]="-0000-000000000000"; static char clock_seq_and_node_str[]="-0000-000000000000";
/* number of 100-nanosecond intervals between /**
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */ number of 100-nanosecond intervals between
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
*/
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 ) #define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
#define UUID_VERSION 0x1000 #define UUID_VERSION 0x1000

View File

@ -13,12 +13,15 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
@file
@brief
subselect Item subselect Item
SUBSELECT TODO: @todo
- add function from mysql_select that use JOIN* as parameter to JOIN methods - add function from mysql_select that use JOIN* as parameter to JOIN
(sql_select.h/sql_select.cc) methods (sql_select.h/sql_select.cc)
*/ */
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
@ -403,6 +406,16 @@ void Item_singlerow_subselect::reset()
} }
/**
@todo
- We cant change name of Item_field or Item_ref, because it will
prevent it's correct resolving, but we should save name of
removed item => we do not make optimization if top item of
list is field or reference.
- switch off this optimization for prepare statement,
because we do not rollback this changes.
Make rollback for it, or special name resolving mode in 5.0.
*/
Item_subselect::trans_res Item_subselect::trans_res
Item_singlerow_subselect::select_transformer(JOIN *join) Item_singlerow_subselect::select_transformer(JOIN *join)
{ {
@ -1445,24 +1458,24 @@ Item_in_subselect::select_transformer(JOIN *join)
} }
/* /**
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
transformation function transformation function.
SYNOPSIS
Item_in_subselect::select_in_like_transformer()
join JOIN object of transforming subquery
func creator of condition function of subquery
DESCRIPTION
To decide which transformation procedure (scalar or row) applicable here To decide which transformation procedure (scalar or row) applicable here
we have to call fix_fields() for left expression to be able to call we have to call fix_fields() for left expression to be able to call
cols() method on it. Also this method make arena management for cols() method on it. Also this method make arena management for
underlying transformation methods. underlying transformation methods.
RETURN @param join JOIN object of transforming subquery
@param func creator of condition function of subquery
@retval
RES_OK OK RES_OK OK
RES_REDUCE OK, and current subquery was reduced during transformation @retval
RES_REDUCE OK, and current subquery was reduced during
transformation
@retval
RES_ERROR Error RES_ERROR Error
*/ */
@ -2412,16 +2425,15 @@ void subselect_indexsubquery_engine::print(String *str)
str->append(')'); str->append(')');
} }
/* /**
change select_result object of engine change select_result object of engine.
SYNOPSIS @param si new subselect Item
subselect_single_select_engine::change_result() @param res new select_result object
si new subselect Item
res new select_result object
RETURN @retval
FALSE OK FALSE OK
@retval
TRUE error TRUE error
*/ */
@ -2434,16 +2446,15 @@ bool subselect_single_select_engine::change_result(Item_subselect *si,
} }
/* /**
change select_result object of engine change select_result object of engine.
SYNOPSIS @param si new subselect Item
subselect_single_select_engine::change_result() @param res new select_result object
si new subselect Item
res new select_result object
RETURN @retval
FALSE OK FALSE OK
@retval
TRUE error TRUE error
*/ */
@ -2457,16 +2468,15 @@ bool subselect_union_engine::change_result(Item_subselect *si,
} }
/* /**
change select_result emulation, never should be called change select_result emulation, never should be called.
SYNOPSIS @param si new subselect Item
subselect_single_select_engine::change_result() @param res new select_result object
si new subselect Item
res new select_result object
RETURN @retval
FALSE OK FALSE OK
@retval
TRUE error TRUE error
*/ */
@ -2478,14 +2488,12 @@ bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
} }
/* /**
Report about presence of tables in subquery Report about presence of tables in subquery.
SYNOPSIS @retval
subselect_single_select_engine::no_tables()
RETURN
TRUE there are not tables used in subquery TRUE there are not tables used in subquery
@retval
FALSE there are some tables in subquery FALSE there are some tables in subquery
*/ */
bool subselect_single_select_engine::no_tables() bool subselect_single_select_engine::no_tables()
@ -2510,14 +2518,12 @@ bool subselect_single_select_engine::may_be_null()
} }
/* /**
Report about presence of tables in subquery Report about presence of tables in subquery.
SYNOPSIS @retval
subselect_union_engine::no_tables()
RETURN
TRUE there are not tables used in subquery TRUE there are not tables used in subquery
@retval
FALSE there are some tables in subquery FALSE there are some tables in subquery
*/ */
bool subselect_union_engine::no_tables() bool subselect_union_engine::no_tables()
@ -2531,14 +2537,12 @@ bool subselect_union_engine::no_tables()
} }
/* /**
Report about presence of tables in subquery Report about presence of tables in subquery.
SYNOPSIS @retval
subselect_uniquesubquery_engine::no_tables()
RETURN
TRUE there are not tables used in subquery TRUE there are not tables used in subquery
@retval
FALSE there are some tables in subquery FALSE there are some tables in subquery
*/ */

View File

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sum functions (COUNT, MIN...) */ /**
@file
@brief
Sum functions (COUNT, MIN...)
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -23,28 +28,25 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h" #include "sql_select.h"
/* /**
Prepare an aggregate function item for checking context conditions Prepare an aggregate function item for checking context conditions.
SYNOPSIS
init_sum_func_check()
thd reference to the thread context info
DESCRIPTION
The function initializes the members of the Item_sum object created The function initializes the members of the Item_sum object created
for a set function that are used to check validity of the set function for a set function that are used to check validity of the set function
occurrence. occurrence.
If the set function is not allowed in any subquery where it occurs If the set function is not allowed in any subquery where it occurs
an error is reported immediately. an error is reported immediately.
NOTES @param thd reference to the thread context info
@note
This function is to be called for any item created for a set function This function is to be called for any item created for a set function
object when the traversal of trees built for expressions used in the query object when the traversal of trees built for expressions used in the query
is performed at the phase of context analysis. This function is to is performed at the phase of context analysis. This function is to
be invoked at the descent of this traversal. be invoked at the descent of this traversal.
@retval
RETURN
TRUE if an error is reported TRUE if an error is reported
@retval
FALSE otherwise FALSE otherwise
*/ */
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
return FALSE; return FALSE;
} }
/* /**
Check constraints imposed on a usage of a set function Check constraints imposed on a usage of a set function.
SYNOPSIS
check_sum_func()
thd reference to the thread context info
ref location of the pointer to this item in the embedding expression
DESCRIPTION
The method verifies whether context conditions imposed on a usage The method verifies whether context conditions imposed on a usage
of any set function are met for this occurrence. of any set function are met for this occurrence.
It checks whether the set function occurs in the position where it It checks whether the set function occurs in the position where it
@ -89,13 +85,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
adds it to the chain of items for such set functions that is attached adds it to the chain of items for such set functions that is attached
to the the st_select_lex structure for this subquery. to the the st_select_lex structure for this subquery.
NOTES
This function is to be called for any item created for a set function
object when the traversal of trees built for expressions used in the query
is performed at the phase of context analysis. This function is to
be invoked at the ascent of this traversal.
IMPLEMENTATION
A number of designated members of the object are used to check the A number of designated members of the object are used to check the
conditions. They are specified in the comment before the Item_sum conditions. They are specified in the comment before the Item_sum
class declaration. class declaration.
@ -106,16 +95,28 @@ bool Item_sum::init_sum_func_check(THD *thd)
of set functions are allowed (i.e either in the SELECT list or of set functions are allowed (i.e either in the SELECT list or
in the HAVING clause of the corresponding subquery) in the HAVING clause of the corresponding subquery)
Consider the query: Consider the query:
@code
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
t1.a > (SELECT MIN(t2.d) FROM t2); t1.a > (SELECT MIN(t2.d) FROM t2);
@endcode
allow_sum_func will contain: allow_sum_func will contain:
for SUM(t1.b) - 1 at the first position - for SUM(t1.b) - 1 at the first position
for AVG(t1.b) - 1 at the first position, 0 at the second position - for AVG(t1.b) - 1 at the first position, 0 at the second position
for MIN(t2.d) - 1 at the first position, 1 at the second position. - for MIN(t2.d) - 1 at the first position, 1 at the second position.
RETURN @param thd reference to the thread context info
@param ref location of the pointer to this item in the embedding expression
@note
This function is to be called for any item created for a set function
object when the traversal of trees built for expressions used in the query
is performed at the phase of context analysis. This function is to
be invoked at the ascent of this traversal.
@retval
TRUE if an error is reported TRUE if an error is reported
@retval
FALSE otherwise FALSE otherwise
*/ */
@ -200,15 +201,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
return FALSE; return FALSE;
} }
/* /**
Attach a set function to the subquery where it must be aggregated Attach a set function to the subquery where it must be aggregated.
SYNOPSIS
register_sum_func()
thd reference to the thread context info
ref location of the pointer to this item in the embedding expression
DESCRIPTION
The function looks for an outer subquery where the set function must be The function looks for an outer subquery where the set function must be
aggregated. If it finds such a subquery then aggr_level is set to aggregated. If it finds such a subquery then aggr_level is set to
the nest level of this subquery and the item for the set function the nest level of this subquery and the item for the set function
@ -216,14 +211,18 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
inner_sum_func_list defined for each subquery. When the item is placed inner_sum_func_list defined for each subquery. When the item is placed
there the field 'ref_by' is set to ref. there the field 'ref_by' is set to ref.
NOTES. @note
Now we 'register' only set functions that are aggregated in outer Now we 'register' only set functions that are aggregated in outer
subqueries. Actually it makes sense to link all set function for subqueries. Actually it makes sense to link all set function for
a subquery in one chain. It would simplify the process of 'splitting' a subquery in one chain. It would simplify the process of 'splitting'
for set functions. for set functions.
RETURN @param thd reference to the thread context info
@param ref location of the pointer to this item in the embedding expression
@retval
FALSE if the executes without failures (currently always) FALSE if the executes without failures (currently always)
@retval
TRUE otherwise TRUE otherwise
*/ */
@ -311,8 +310,8 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
} }
/* /**
Constructor used in processing select with temporary tebles Constructor used in processing select with temporary tebles.
*/ */
Item_sum::Item_sum(THD *thd, Item_sum *item): Item_sum::Item_sum(THD *thd, Item_sum *item):
@ -655,6 +654,10 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
** reset and add of sum_func ** reset and add of sum_func
***********************************************************************/ ***********************************************************************/
/**
@todo
check if the following assignments are really needed
*/
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type), :Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
curr_dec_buff(item->curr_dec_buff) curr_dec_buff(item->curr_dec_buff)
@ -833,7 +836,7 @@ Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
} }
/* /**
Behaves like an Integer except to fix_length_and_dec(). Behaves like an Integer except to fix_length_and_dec().
Additionally div() converts val with this traits to a val with true Additionally div() converts val with this traits to a val with true
decimal traits along with conversion of integer value to decimal value. decimal traits along with conversion of integer value to decimal value.
@ -910,6 +913,10 @@ void Item_sum_distinct::fix_length_and_dec()
} }
/**
@todo
check that the case of CHAR(0) works OK
*/
bool Item_sum_distinct::setup(THD *thd) bool Item_sum_distinct::setup(THD *thd)
{ {
List<Create_field> field_list; List<Create_field> field_list;
@ -2002,8 +2009,8 @@ void Item_sum_bit::update_field()
} }
/* /**
** calc next value and merge it with field_value calc next value and merge it with field_value.
*/ */
void Item_sum_sum::update_field() void Item_sum_sum::update_field()
@ -2179,6 +2186,10 @@ Item_sum_hybrid::min_max_update_int_field()
} }
/**
@todo
optimize: do not get result_field in case of args[0] is NULL
*/
void void
Item_sum_hybrid::min_max_update_decimal_field() Item_sum_hybrid::min_max_update_decimal_field()
{ {
@ -2367,7 +2378,7 @@ int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
return f->cmp(key1, key2); return f->cmp(key1, key2);
} }
/* /**
Did not make this one static - at least gcc gets confused when Did not make this one static - at least gcc gets confused when
I try to declare a static function as a friend. If you can figure I try to declare a static function as a friend. If you can figure
out the syntax to make a static function a friend, make this one out the syntax to make a static function a friend, make this one
@ -2434,7 +2445,10 @@ void Item_sum_count_distinct::cleanup()
} }
/* This is used by rollup to create a separate usable copy of the function */ /**
This is used by rollup to create a separate usable copy of
the function.
*/
void Item_sum_count_distinct::make_unique() void Item_sum_count_distinct::make_unique()
{ {
@ -2801,7 +2815,7 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
} }
/* Default max_length is max argument length */ /** Default max_length is max argument length. */
void Item_sum_udf_str::fix_length_and_dec() void Item_sum_udf_str::fix_length_and_dec()
{ {
@ -2851,9 +2865,8 @@ String *Item_sum_udf_str::val_str(String *str)
Blobs doesn't work with DISTINCT or ORDER BY Blobs doesn't work with DISTINCT or ORDER BY
*****************************************************************************/ *****************************************************************************/
/* /**
function of sort for syntax: function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...)
GROUP_CONCAT(DISTINCT expr,...)
*/ */
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1, int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
@ -2890,9 +2903,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
} }
/* /**
function of sort for syntax: function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
GROUP_CONCAT(expr,... ORDER BY col,... )
*/ */
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2) int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
@ -2934,11 +2946,11 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
} }
/* /**
function of sort for syntax: function of sort for syntax:
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ) GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ).
BUG: @bug
This doesn't work in the case when the order by contains data that This doesn't work in the case when the order by contains data that
is not part of the field list because tree-insert will not notice is not part of the field list because tree-insert will not notice
the duplicated values when inserting things sorted by ORDER BY the duplicated values when inserting things sorted by ORDER BY
@ -2953,8 +2965,8 @@ int group_concat_key_cmp_with_distinct_and_order(void* arg,uchar* key1,
} }
/* /**
Append data from current leaf to item->result Append data from current leaf to item->result.
*/ */
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
@ -3025,12 +3037,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
} }
/* /**
Constructor of Item_func_group_concat Constructor of Item_func_group_concat.
distinct_arg - distinct
select_list - list of expression for show values @param distinct_arg distinct
order_list - list of sort columns @param select_list list of expression for show values
separator_arg - string value of separator @param order_list list of sort columns
@param separator_arg string value of separator.
*/ */
Item_func_group_concat:: Item_func_group_concat::

View File

@ -14,7 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all time functions */ /**
@file
@brief
This file defines all time functions
@todo
Move month and days to language files
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -24,13 +32,12 @@
#include <m_ctype.h> #include <m_ctype.h>
#include <time.h> #include <time.h>
/* TODO: Move month and days to language files */ /** Day number for Dec 31st, 9999. */
/* Day number for Dec 31st, 9999 */
#define MAX_DAY_NUMBER 3652424L #define MAX_DAY_NUMBER 3652424L
/* /**
OPTIMIZATION TODO: @todo
OPTIMIZATION
- Replace the switch with a function that should be called for each - Replace the switch with a function that should be called for each
date type. date type.
- Remove sprintf and opencode the conversion, like we do in - Remove sprintf and opencode the conversion, like we do in
@ -226,36 +233,36 @@ static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0,
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0, static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
{(char *)"%H:%i:%S", 8}}; {(char *)"%H:%i:%S", 8}};
/* /**
Extract datetime value to MYSQL_TIME struct from string value Extract datetime value to MYSQL_TIME struct from string value
according to format string. according to format string.
SYNOPSIS @param format date/time format specification
extract_date_time() @param val String to decode
format date/time format specification @param length Length of string
val String to decode @param l_time Store result here
length Length of string @param cached_timestamp_type It uses to get an appropriate warning
l_time Store result here
cached_timestamp_type
It uses to get an appropriate warning
in the case when the value is truncated. in the case when the value is truncated.
sub_pattern_end if non-zero then we are parsing string which @param sub_pattern_end if non-zero then we are parsing string which
should correspond compound specifier (like %T or should correspond compound specifier (like %T or
%r) and this parameter is pointer to place where %r) and this parameter is pointer to place where
pointer to end of string matching this specifier pointer to end of string matching this specifier
should be stored. should be stored.
NOTE
@note
Possibility to parse strings matching to patterns equivalent to compound Possibility to parse strings matching to patterns equivalent to compound
specifiers is mainly intended for use from inside of this function in specifiers is mainly intended for use from inside of this function in
order to understand %T and %r conversion specifiers, so number of order to understand %T and %r conversion specifiers, so number of
conversion specifiers that can be used in such sub-patterns is limited. conversion specifiers that can be used in such sub-patterns is limited.
Also most of checks are skipped in this case. Also most of checks are skipped in this case.
@note
If one adds new format specifiers to this function he should also If one adds new format specifiers to this function he should also
consider adding them to get_date_time_result_type() function. consider adding them to get_date_time_result_type() function.
RETURN @retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -603,8 +610,8 @@ err:
} }
/* /**
Create a formated date/time value in a string Create a formated date/time value in a string.
*/ */
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
@ -838,7 +845,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
} }
/* /**
@details
Get a array of positive numbers from a string object. Get a array of positive numbers from a string object.
Each number is separated by 1 non digit character Each number is separated by 1 non digit character
Return error if there is too many numbers. Return error if there is too many numbers.
@ -846,13 +854,11 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
from the high end. This allows one to give: from the high end. This allows one to give:
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds. DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
SYNOPSIS @param length: length of str
str: string value @param cs: charset of str
length: length of str @param values: array of results
cs: charset of str @param count: count of elements in result array
values: array of results @param transform_msec: if value is true we suppose
count: count of elements in result array
transform_msec: if value is true we suppose
that the last part of string value is microseconds that the last part of string value is microseconds
and we should transform value to six digit value. and we should transform value to six digit value.
For example, '1.1' -> '1.100000' For example, '1.1' -> '1.100000'
@ -1046,7 +1052,9 @@ String* Item_func_monthname::val_str(String* str)
} }
// Returns the quarter of the year /**
Returns the quarter of the year.
*/
longlong Item_func_quarter::val_int() longlong Item_func_quarter::val_int()
{ {
@ -1072,8 +1080,10 @@ longlong Item_func_minute::val_int()
(void) get_arg0_time(&ltime); (void) get_arg0_time(&ltime);
return ltime.minute; return ltime.minute;
} }
// Returns the second in time_exp in the range of 0 - 59
/**
Returns the second in time_exp in the range of 0 - 59.
*/
longlong Item_func_second::val_int() longlong Item_func_second::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
return week_format; return week_format;
} }
/* /**
@verbatim
The bits in week_format(for calc_week() function) has the following meaning: The bits in week_format(for calc_week() function) has the following meaning:
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
If set Monday is first day of week If set Monday is first day of week
@ -1118,6 +1129,7 @@ uint week_mode(uint mode)
four or more days in the new year, then it is week 1; four or more days in the new year, then it is week 1;
Otherwise it is the last week of the previous year, and the Otherwise it is the last week of the previous year, and the
next week is week 1. next week is week 1.
@endverbatim
*/ */
longlong Item_func_week::val_int() longlong Item_func_week::val_int()
@ -1281,8 +1293,9 @@ longlong Item_func_time_to_sec::val_int()
} }
/* /**
Convert a string to a interval value Convert a string to a interval value.
To make code easy, allow interval objects without separators. To make code easy, allow interval objects without separators.
*/ */
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
return str; return str;
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURDATE function. time zone. Defines time zone (local) used for whole CURDATE function.
*/ */
@ -1519,7 +1532,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_DATE function. time zone. Defines time zone (UTC) used for whole UTC_DATE function.
*/ */
@ -1563,7 +1576,7 @@ void Item_func_curtime::fix_length_and_dec()
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURTIME function. time zone. Defines time zone (local) used for whole CURTIME function.
*/ */
@ -1576,7 +1589,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIME function. time zone. Defines time zone (UTC) used for whole UTC_TIME function.
*/ */
@ -1612,7 +1625,7 @@ void Item_func_now::fix_length_and_dec()
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole NOW function. time zone. Defines time zone (local) used for whole NOW function.
*/ */
@ -1625,7 +1638,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function. time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
*/ */
@ -1656,7 +1669,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole SYSDATE function. time zone. Defines time zone (local) used for whole SYSDATE function.
*/ */
@ -2612,7 +2625,7 @@ longlong Item_date_typecast::val_int()
return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day); return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
} }
/* /**
MAKEDATE(a,b) is a date function that creates a date value MAKEDATE(a,b) is a date function that creates a date value
from a year and day value. from a year and day value.
@ -2722,7 +2735,7 @@ void Item_func_add_time::fix_length_and_dec()
cached_field_type= MYSQL_TYPE_TIME; cached_field_type= MYSQL_TYPE_TIME;
} }
/* /**
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
time/datetime value time/datetime value
@ -2824,7 +2837,7 @@ void Item_func_add_time::print(String *str)
} }
/* /**
TIMEDIFF(t,s) is a time function that calculates the TIMEDIFF(t,s) is a time function that calculates the
time value between a start and end time. time value between a start and end time.
@ -2874,7 +2887,7 @@ null_date:
return 0; return 0;
} }
/* /**
MAKETIME(h,m,s) is a time function that calculates a time value MAKETIME(h,m,s) is a time function that calculates a time value
from the total number of hours, minutes, and seconds. from the total number of hours, minutes, and seconds.
Result: Time value Result: Time value
@ -2941,7 +2954,7 @@ String *Item_func_maketime::val_str(String *str)
} }
/* /**
MICROSECOND(a) is a function ( extraction) that extracts the microseconds MICROSECOND(a) is a function ( extraction) that extracts the microseconds
from a. from a.
@ -3167,25 +3180,28 @@ void Item_func_get_format::print(String *str)
} }
/* /**
Get type of datetime value (DATE/TIME/...) which will be produced Get type of datetime value (DATE/TIME/...) which will be produced
according to format string. according to format string.
SYNOPSIS @param format format string
get_date_time_result_type() @param length length of format string
format - format string
length - length of format string
NOTE @note
We don't process day format's characters('D', 'd', 'e') because day We don't process day format's characters('D', 'd', 'e') because day
may be a member of all date/time types. may be a member of all date/time types.
@note
Format specifiers supported by this function should be in sync with Format specifiers supported by this function should be in sync with
specifiers supported by extract_date_time() function. specifiers supported by extract_date_time() function.
RETURN VALUE @return
One of date_time_format_types values: One of date_time_format_types values:
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY - DATE_TIME_MICROSECOND
- DATE_TIME
- DATE_ONLY
- TIME_MICROSECOND
- TIME_ONLY
*/ */
static date_time_format_types static date_time_format_types

View File

@ -90,25 +90,19 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
} }
/* /**
Copy part of a record that forms a key or key prefix to a buffer. Copy part of a record that forms a key or key prefix to a buffer.
SYNOPSIS
key_copy()
to_key buffer that will be used as a key
from_record full record to be copied from
key_info descriptor of the index
key_length specifies length of all keyparts that will be copied
DESCRIPTION
The function takes a complete table record (as e.g. retrieved by The function takes a complete table record (as e.g. retrieved by
handler::index_read()), and a description of an index on the same table, handler::index_read()), and a description of an index on the same table,
and extracts the first key_length bytes of the record which are part of a and extracts the first key_length bytes of the record which are part of a
key into to_key. If length == 0 then copy all bytes from the record that key into to_key. If length == 0 then copy all bytes from the record that
form a key. form a key.
RETURN @param to_key buffer that will be used as a key
None @param from_record full record to be copied from
@param key_info descriptor of the index
@param key_length specifies length of all keyparts that will be copied
*/ */
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
@ -163,22 +157,16 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
} }
/* /**
Restore a key from some buffer to record. Restore a key from some buffer to record.
SYNOPSIS
key_restore()
to_record record buffer where the key will be restored to
from_key buffer that contains a key
key_info descriptor of the index
key_length specifies length of all keyparts that will be restored
DESCRIPTION
This function converts a key into record format. It can be used in cases This function converts a key into record format. It can be used in cases
when we want to return a key as a result row. when we want to return a key as a result row.
RETURN @param to_record record buffer where the key will be restored to
None @param from_key buffer that contains a key
@param key_info descriptor of the index
@param key_length specifies length of all keyparts that will be restored
*/ */
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info, void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
@ -255,24 +243,23 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
} }
/* /**
Compare if a key has changed Compare if a key has changed.
SYNOPSIS @param table TABLE
key_cmp_if_same() @param key key to compare to row
table TABLE @param idx Index used
key key to compare to row @param key_length Length of key
idx Index used
key_length Length of key
NOTES @note
In theory we could just call field->cmp() for all field types, In theory we could just call field->cmp() for all field types,
but as we are only interested if a key has changed (not if the key is but as we are only interested if a key has changed (not if the key is
larger or smaller than the previous value) we can do things a bit larger or smaller than the previous value) we can do things a bit
faster by using memcmp() instead. faster by using memcmp() instead.
RETURN @retval
0 If key is equal 0 If key is equal
@retval
1 Key has changed 1 Key has changed
*/ */
@ -331,17 +318,17 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
} }
/* /*
unpack key-fields from record to some buffer unpack key-fields from record to some buffer.
SYNOPSIS This is used mainly to get a good error message. We temporary
key_unpack() change the column bitmap so that all columns are readable.
@param
to Store value here in an easy to read form to Store value here in an easy to read form
@param
table Table to use table Table to use
@param
idx Key number idx Key number
NOTES
This is used mainly to get a good error message
We temporary change the column bitmap so that all columns are readable.
*/ */
void key_unpack(String *to,TABLE *table,uint idx) void key_unpack(String *to,TABLE *table,uint idx)
@ -419,21 +406,18 @@ bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
} }
/* /**
Compare key in row to a given key Compare key in row to a given key.
SYNOPSIS @param key_part Key part handler
key_cmp() @param key Key to compare to value in table->record[0]
key_part Key part handler @param key_length length of 'key'
key Key to compare to value in table->record[0]
key_length length of 'key'
RETURN @return
The return value is SIGN(key_in_row - range_key): The return value is SIGN(key_in_row - range_key):
- 0 Key is equal to range or 'range' == 0 (no range)
0 Key is equal to range or 'range' == 0 (no range) - -1 Key is less than range
-1 Key is less than range - 1 Key is larger than range
1 Key is larger than range
*/ */
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length) int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)

View File

@ -14,8 +14,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* locking functions for mysql */ /**
/* @file
Locking functions for mysql.
Because of the new concurrent inserts, we must first get external locks Because of the new concurrent inserts, we must first get external locks
before getting internal locks. If we do it in the other order, the status before getting internal locks. If we do it in the other order, the status
information is not up to date when called from the lock handler. information is not up to date when called from the lock handler.
@ -65,7 +68,7 @@
excluding one that caused failure. That means handler must cleanup itself excluding one that caused failure. That means handler must cleanup itself
in case external_lock() fails. in case external_lock() fails.
TODO: @todo
Change to use my_malloc() ONLY when using LOCK TABLES command or when Change to use my_malloc() ONLY when using LOCK TABLES command or when
we are forced to use mysql_lock_merge. we are forced to use mysql_lock_merge.
*/ */
@ -390,10 +393,11 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
Unlock some of the tables locked by mysql_lock_tables Unlock some of the tables locked by mysql_lock_tables.
This will work even if get_lock_data fails (next unlock will free all) This will work even if get_lock_data fails (next unlock will free all)
*/ */
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count) void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
{ {
@ -405,8 +409,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
} }
/* /**
** unlock all tables locked for read. unlock all tables locked for read.
*/ */
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
@ -567,7 +571,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
} }
/* abort all other threads waiting to get lock in table */ /** Abort all other threads waiting to get lock in table. */
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
{ {
@ -586,16 +590,15 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
} }
/* /**
Abort one thread / table combination Abort one thread / table combination.
SYNOPSIS @param thd Thread handler
mysql_lock_abort_for_thread() @param table Table that should be removed from lock queue
thd Thread handler
table Table that should be removed from lock queue
RETURN @retval
0 Table was not locked by another thread 0 Table was not locked by another thread
@retval
1 Table was locked by at least one other thread 1 Table was locked by at least one other thread
*/ */
@ -663,28 +666,27 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
} }
/* /**
Find duplicate lock in tables. Find duplicate lock in tables.
SYNOPSIS
mysql_lock_have_duplicate()
thd The current thread.
needle The table to check for duplicate lock.
haystack The list of tables to search for the dup lock.
NOTE
This is mainly meant for MERGE tables in INSERT ... SELECT
situations. The 'real', underlying tables can be found only after
the MERGE tables are opened. This function assumes that the tables are
already locked.
Temporary tables are ignored here like they are ignored in Temporary tables are ignored here like they are ignored in
get_lock_data(). If we allow two opens on temporary tables later, get_lock_data(). If we allow two opens on temporary tables later,
both functions should be checked. both functions should be checked.
RETURN @param thd The current thread.
@param needle The table to check for duplicate lock.
@param haystack The list of tables to search for the dup lock.
@note
This is mainly meant for MERGE tables in INSERT ... SELECT
situations. The 'real', underlying tables can be found only after
the MERGE tables are opened. This function assumes that the tables are
already locked.
@retval
NULL No duplicate lock found. NULL No duplicate lock found.
! NULL First table from 'haystack' that matches a lock on 'needle'. @retval
!NULL First table from 'haystack' that matches a lock on 'needle'.
*/ */
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
@ -768,7 +770,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
} }
/* unlock a set of external */ /** Unlock a set of external. */
static int unlock_external(THD *thd, TABLE **table,uint count) static int unlock_external(THD *thd, TABLE **table,uint count)
{ {
@ -793,21 +795,17 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
} }
/* /**
Get lock structures from table structs and initialize locks Get lock structures from table structs and initialize locks.
SYNOPSIS @param thd Thread handler
get_lock_data() @param table_ptr Pointer to tables that should be locks
thd Thread handler @param flags One of:
table_ptr Pointer to tables that should be locks - GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
flags One of: - GET_LOCK_STORE_LOCKS : Store lock info in TABLE
GET_LOCK_UNLOCK: If we should send TL_IGNORE to @param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
store lock
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
*/ */
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
uint flags, TABLE **write_lock_used) uint flags, TABLE **write_lock_used)
{ {
@ -893,20 +891,15 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
} }
/* /**
Reset lock type in lock data. Reset lock type in lock data.
SYNOPSIS
reset_lock_data()
sql_lock The MySQL lock.
DESCRIPTION
After a locking error we want to quit the locking of the table(s). After a locking error we want to quit the locking of the table(s).
The test case in the bug report for Bug #18544 has the following The test case in the bug report for Bug #18544 has the following
cases: 1. Locking error in lock_external() due to InnoDB timeout. cases:
2. Locking error in get_lock_data() due to missing write permission. -# Locking error in lock_external() due to InnoDB timeout.
3. Locking error in wait_if_global_read_lock() due to lock conflict. -# Locking error in get_lock_data() due to missing write permission.
-# Locking error in wait_if_global_read_lock() due to lock conflict.
In all these cases we have already set the lock type into the lock In all these cases we have already set the lock type into the lock
data of the open table(s). If the table(s) are in the open table data of the open table(s). If the table(s) are in the open table
@ -916,8 +909,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
Clear the lock type of all lock data. This ensures that the next Clear the lock type of all lock data. This ensures that the next
lock request will set its lock type properly. lock request will set its lock type properly.
RETURN @param sql_lock The MySQL lock.
void
*/ */
static void reset_lock_data(MYSQL_LOCK *sql_lock) static void reset_lock_data(MYSQL_LOCK *sql_lock)
@ -940,20 +932,19 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock)
This is used when we need total access to a closed, not open table This is used when we need total access to a closed, not open table
*****************************************************************************/ *****************************************************************************/
/* /**
Lock and wait for the named lock. Lock and wait for the named lock.
SYNOPSIS @param thd Thread handler
lock_and_wait_for_table_name() @param table_list Lock first table in this list
thd Thread handler
table_list Lock first table in this list
NOTES @note
Works together with global read lock. Works together with global read lock.
RETURN @retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -982,30 +973,30 @@ end:
} }
/* /**
Put a not open table with an old refresh version in the table cache. Put a not open table with an old refresh version in the table cache.
SYNPOSIS @param thd Thread handler
lock_table_name() @param table_list Lock first table in this list
thd Thread handler @param check_in_use Do we need to check if table already in use by us
table_list Lock first table in this list
check_in_use Do we need to check if table already in use by us
WARNING @note
One must have a lock on LOCK_open!
@warning
If you are going to update the table, you should use If you are going to update the table, you should use
lock_and_wait_for_table_name instead of this function as this works lock_and_wait_for_table_name instead of this function as this works
together with 'FLUSH TABLES WITH READ LOCK' together with 'FLUSH TABLES WITH READ LOCK'
NOTES @note
This will force any other threads that uses the table to release it This will force any other threads that uses the table to release it
as soon as possible. as soon as possible.
REQUIREMENTS @return
One must have a lock on LOCK_open !
RETURN:
< 0 error < 0 error
@return
== 0 table locked == 0 table locked
@return
> 0 table locked, but someone is using it > 0 table locked, but someone is using it
*/ */
@ -1102,23 +1093,22 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
} }
/* /**
Lock all tables in list with a name lock Lock all tables in list with a name lock.
SYNOPSIS REQUIREMENTS
lock_table_names() - One must have a lock on LOCK_open when calling this
thd Thread handle
table_list Names of tables to lock
NOTES @param thd Thread handle
@param table_list Names of tables to lock
@note
If you are just locking one table, you should use If you are just locking one table, you should use
lock_and_wait_for_table_name(). lock_and_wait_for_table_name().
REQUIREMENTS @retval
One must have a lock on LOCK_open when calling this
RETURN
0 ok 0 ok
@retval
1 Fatal error (end of memory ?) 1 Fatal error (end of memory ?)
*/ */
@ -1148,12 +1138,13 @@ end:
/** /**
@brief Lock all tables in list with an exclusive table name lock. Unlock all tables in list with a name lock.
@param thd Thread handle. @param thd Thread handle.
@param table_list Names of tables to lock. @param table_list Names of tables to lock.
@note This function needs to be protected by LOCK_open. If we're @note
This function needs to be protected by LOCK_open. If we're
under LOCK TABLES, this function does not work as advertised. Namely, under LOCK TABLES, this function does not work as advertised. Namely,
it does not exclude other threads from using this table and does not it does not exclude other threads from using this table and does not
put an exclusive name lock on this table into the table cache. put an exclusive name lock on this table into the table cache.
@ -1183,7 +1174,7 @@ bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
/** /**
@brief Test is 'table' is protected by an exclusive name lock. Test is 'table' is protected by an exclusive name lock.
@param[in] thd The current thread handler @param[in] thd The current thread handler
@param[in] table_list Table container containing the single table to be @param[in] table_list Table container containing the single table to be
@ -1211,7 +1202,7 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd,
/** /**
@brief Test is 'table key' is protected by an exclusive name lock. Test is 'table key' is protected by an exclusive name lock.
@param[in] thd The current thread handler. @param[in] thd The current thread handler.
@param[in] key @param[in] key
@ -1245,23 +1236,27 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
return FALSE; return FALSE;
} }
/* /**
Unlock all tables in list with a name lock Unlock all tables in list with a name lock.
SYNOPSIS @param
unlock_table_names()
thd Thread handle thd Thread handle
@param
table_list Names of tables to unlock table_list Names of tables to unlock
@param
last_table Don't unlock any tables after this one. last_table Don't unlock any tables after this one.
(default 0, which will unlock all tables) (default 0, which will unlock all tables)
NOTES @note
One must have a lock on LOCK_open when calling this. One must have a lock on LOCK_open when calling this.
@note
This function will broadcast refresh signals to inform other threads This function will broadcast refresh signals to inform other threads
that the name locks are removed. that the name locks are removed.
RETURN @retval
0 ok 0 ok
@retval
1 Fatal error (end of memory ?) 1 Fatal error (end of memory ?)
*/ */
@ -1565,14 +1560,9 @@ bool make_global_read_lock_block_commit(THD *thd)
} }
/* /**
Broadcast COND_refresh and COND_global_read_lock. Broadcast COND_refresh and COND_global_read_lock.
SYNOPSIS
broadcast_refresh()
void No parameters.
DESCRIPTION
Due to a bug in a threading library it could happen that a signal Due to a bug in a threading library it could happen that a signal
did not reach its target. A condition for this was that the same did not reach its target. A condition for this was that the same
condition variable was used with different mutexes in condition variable was used with different mutexes in
@ -1584,12 +1574,9 @@ bool make_global_read_lock_block_commit(THD *thd)
in global read lock handling. But now it is necessary to signal in global read lock handling. But now it is necessary to signal
both conditions at the same time. both conditions at the same time.
NOTE @note
When signalling COND_global_read_lock within the global read lock When signalling COND_global_read_lock within the global read lock
handling, it is not necessary to also signal COND_refresh. handling, it is not necessary to also signal COND_refresh.
RETURN
void
*/ */
void broadcast_refresh(void) void broadcast_refresh(void)

View File

@ -14,8 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* logging of commands */ /**
/* TODO: Abort logging when we get an error in reading or writing log files */ @file
@brief
logging of commands
@todo
Abort logging when we get an error in reading or writing log files
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_repl.h" #include "sql_repl.h"
@ -689,7 +696,7 @@ void Log_to_file_event_handler::init_pthread_objects()
} }
/* Wrapper around MYSQL_LOG::write() for slow log */ /** Wrapper around MYSQL_LOG::write() for slow log. */
bool Log_to_file_event_handler:: bool Log_to_file_event_handler::
log_slow(THD *thd, time_t current_time, time_t query_start_arg, log_slow(THD *thd, time_t current_time, time_t query_start_arg,
@ -704,7 +711,7 @@ bool Log_to_file_event_handler::
} }
/* /**
Wrapper around MYSQL_LOG::write() for general log. We need it since we Wrapper around MYSQL_LOG::write() for general log. We need it since we
want all log event handlers to have the same signature. want all log event handlers to have the same signature.
*/ */
@ -806,7 +813,7 @@ void LOGGER::cleanup_end()
} }
/* /**
Perform basic log initialization: create file-based log handler and Perform basic log initialization: create file-based log handler and
init error log. init error log.
*/ */
@ -1466,9 +1473,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
NOTE: how do we handle this (unlikely but legal) case: @note
How do we handle this (unlikely but legal) case:
@verbatim
[transaction] + [update to non-trans table] + [rollback to savepoint] ? [transaction] + [update to non-trans table] + [rollback to savepoint] ?
@endverbatim
The problem occurs when a savepoint is before the update to the The problem occurs when a savepoint is before the update to the
non-transactional table. Then when there's a rollback to the savepoint, if we non-transactional table. Then when there's a rollback to the savepoint, if we
simply truncate the binlog cache, we lose the part of the binlog cache where simply truncate the binlog cache, we lose the part of the binlog cache where
@ -1615,11 +1625,14 @@ static void setup_windows_event_source()
#endif /* __NT__ */ #endif /* __NT__ */
/**************************************************************************** /**
** Find a uniq filename for 'filename.#'. Find a unique filename for 'filename.#'.
** Set # to a number as low as possible
** returns != 0 if not possible to get uniq filename Set '#' to a number as low as possible.
****************************************************************************/
@return
nonzero if not possible to get unique filename
*/
static int find_uniq_filename(char *name) static int find_uniq_filename(char *name)
{ {
@ -1833,7 +1846,7 @@ void MYSQL_LOG::close(uint exiting)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* this is called only once */ /** This is called only once. */
void MYSQL_LOG::cleanup() void MYSQL_LOG::cleanup()
{ {
@ -2160,6 +2173,11 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
} }
/**
@todo
The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
const char *MYSQL_LOG::generate_name(const char *log_name, const char *MYSQL_LOG::generate_name(const char *log_name,
const char *suffix, const char *suffix,
bool strip_ext, char *buff) bool strip_ext, char *buff)
@ -2278,17 +2296,17 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
} }
/* /**
Open a (new) binlog file. Open a (new) binlog file.
DESCRIPTION
- Open the log file and the index file. Register the new - Open the log file and the index file. Register the new
file name in it file name in it
- When calling this when the file is in use, you must have a locks - When calling this when the file is in use, you must have a locks
on LOCK_log and LOCK_index. on LOCK_log and LOCK_index.
RETURN VALUES @retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -2440,24 +2458,20 @@ int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
return 0; return 0;
} }
/* /**
Move all data up in a file in an filename index file Move all data up in a file in an filename index file.
SYNOPSIS
copy_up_file_and_fill()
index_file File to move
offset Move everything from here to beginning
NOTE
File will be truncated to be 'offset' shorter or filled up with
newlines
IMPLEMENTATION
We do the copy outside of the IO_CACHE as the cache buffers would just We do the copy outside of the IO_CACHE as the cache buffers would just
make things slower and more complicated. make things slower and more complicated.
In most cases the copy loop should only do one read. In most cases the copy loop should only do one read.
RETURN VALUES @param index_file File to move
@param offset Move everything from here to beginning
@note
File will be truncated to be 'offset' shorter or filled up with newlines
@retval
0 ok 0 ok
*/ */
@ -2498,25 +2512,25 @@ err:
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
/* /**
Find the position in the log-index-file for the given log name Find the position in the log-index-file for the given log name.
SYNOPSIS @param linfo Store here the found log file name and position to
find_log_pos()
linfo Store here the found log file name and position to
the NEXT log file name in the index file. the NEXT log file name in the index file.
log_name Filename to find in the index file. @param log_name Filename to find in the index file.
Is a null pointer if we want to read the first entry Is a null pointer if we want to read the first entry
need_lock Set this to 1 if the parent doesn't already have a @param need_lock Set this to 1 if the parent doesn't already have a
lock on LOCK_index lock on LOCK_index
NOTE @note
On systems without the truncate function the file will end with one or On systems without the truncate function the file will end with one or
more empty lines. These will be ignored when reading the file. more empty lines. These will be ignored when reading the file.
RETURN VALUES @retval
0 ok 0 ok
@retval
LOG_INFO_EOF End of log-index-file found LOG_INFO_EOF End of log-index-file found
@retval
LOG_INFO_IO Got IO error while reading file LOG_INFO_IO Got IO error while reading file
*/ */
@ -2572,25 +2586,27 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
} }
/* /**
Find the position in the log-index-file for the given log name Find the position in the log-index-file for the given log name.
SYNOPSIS @param
find_next_log()
linfo Store here the next log file name and position to linfo Store here the next log file name and position to
the file name after that. the file name after that.
@param
need_lock Set this to 1 if the parent doesn't already have a need_lock Set this to 1 if the parent doesn't already have a
lock on LOCK_index lock on LOCK_index
NOTE @note
- Before calling this function, one has to call find_log_pos() - Before calling this function, one has to call find_log_pos()
to set up 'linfo' to set up 'linfo'
- Mutex needed because we need to make sure the file pointer does not move - Mutex needed because we need to make sure the file pointer does not move
from under our feet from under our feet
RETURN VALUES @retval
0 ok 0 ok
@retval
LOG_INFO_EOF End of log-index-file found LOG_INFO_EOF End of log-index-file found
@retval
LOG_INFO_IO Got IO error while reading file LOG_INFO_IO Got IO error while reading file
*/ */
@ -2624,21 +2640,20 @@ err:
} }
/* /**
Delete all logs refered to in the index file Delete all logs refered to in the index file.
Start writing to a new log file. The new index file will only contain Start writing to a new log file.
this file.
SYNOPSIS The new index file will only contain this file.
reset_logs()
thd Thread
NOTE @param thd Thread
@note
If not called from slave thread, write start event to new log If not called from slave thread, write start event to new log
@retval
RETURN VALUES
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -2702,26 +2717,11 @@ err:
} }
/* /**
Delete relay log files prior to rli->group_relay_log_name Delete relay log files prior to rli->group_relay_log_name
(i.e. all logs which are not involved in a non-finished group (i.e. all logs which are not involved in a non-finished group
(transaction)), remove them from the index file and start on next relay log. (transaction)), remove them from the index file and start on next
relay log.
SYNOPSIS
purge_first_log()
rli Relay log information
included If false, all relay logs that are strictly before
rli->group_relay_log_name are deleted ; if true, the latter is
deleted too (i.e. all relay logs
read by the SQL slave thread are deleted).
NOTE
- This is only called from the slave-execute thread when it has read
all commands from a relay log and want to switch to a new relay log.
- When this happens, we can be in an active transaction as
a transaction can span over two relay logs
(although it is always written as a single block to the master's binary
log, hence cannot span over two master's binary logs).
IMPLEMENTATION IMPLEMENTATION
- Protects index file with LOCK_index - Protects index file with LOCK_index
@ -2730,10 +2730,27 @@ err:
- If the OS has truncate, truncate the file, else fill it with \n' - If the OS has truncate, truncate the file, else fill it with \n'
- Read the next file name from the index file and store in rli->linfo - Read the next file name from the index file and store in rli->linfo
RETURN VALUES @param rli Relay log information
@param included If false, all relay logs that are strictly before
rli->group_relay_log_name are deleted ; if true, the
latter is deleted too (i.e. all relay logs
read by the SQL slave thread are deleted).
@note
- This is only called from the slave-execute thread when it has read
all commands from a relay log and want to switch to a new relay log.
- When this happens, we can be in an active transaction as
a transaction can span over two relay logs
(although it is always written as a single block to the master's binary
log, hence cannot span over two master's binary logs).
@retval
0 ok 0 ok
@retval
LOG_INFO_EOF End of log-index-file found LOG_INFO_EOF End of log-index-file found
@retval
LOG_INFO_SEEK Could not allocate IO cache LOG_INFO_SEEK Could not allocate IO cache
@retval
LOG_INFO_IO Got IO error while reading file LOG_INFO_IO Got IO error while reading file
*/ */
@ -2811,8 +2828,8 @@ err:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Update log index_file Update log index_file.
*/ */
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads) int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
@ -2826,25 +2843,24 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
return 0; return 0;
} }
/* /**
Remove all logs before the given log from disk and from the index file. Remove all logs before the given log from disk and from the index file.
SYNOPSIS @param to_log Delete all log file name before this file.
purge_logs() @param included If true, to_log is deleted too.
to_log Delete all log file name before this file. @param need_mutex
included If true, to_log is deleted too. @param need_update_threads If we want to update the log coordinates of
need_mutex
need_update_threads If we want to update the log coordinates of
all threads. False for relay logs, true otherwise. all threads. False for relay logs, true otherwise.
freed_log_space If not null, decrement this variable of @param freed_log_space If not null, decrement this variable of
the amount of log space freed the amount of log space freed
NOTES @note
If any of the logs before the deleted one is in use, If any of the logs before the deleted one is in use,
only purge logs up to this one. only purge logs up to this one.
RETURN VALUES @retval
0 ok 0 ok
@retval
LOG_INFO_EOF to_log not found LOG_INFO_EOF to_log not found
*/ */
@ -2928,21 +2944,20 @@ err:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Remove all logs before the given file date from disk and from the Remove all logs before the given file date from disk and from the
index file. index file.
SYNOPSIS @param thd Thread pointer
purge_logs_before_date() @param before_date Delete all log files before given date.
thd Thread pointer
before_date Delete all log files before given date.
NOTES @note
If any of the logs before the deleted one is in use, If any of the logs before the deleted one is in use,
only purge logs up to this one. only purge logs up to this one.
RETURN VALUES @retval
0 ok 0 ok
@retval
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
*/ */
@ -2992,14 +3007,12 @@ err:
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
/* /**
Create a new log file name Create a new log file name.
SYNOPSIS @param buf buf of at least FN_REFLEN where new name is stored
make_log_name()
buf buf of at least FN_REFLEN where new name is stored
NOTE @note
If file name will be longer then FN_REFLEN it will be truncated If file name will be longer then FN_REFLEN it will be truncated
*/ */
@ -3013,8 +3026,8 @@ void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
} }
/* /**
Check if we are writing/reading to the given log file Check if we are writing/reading to the given log file.
*/ */
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg) bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
@ -3043,14 +3056,12 @@ void MYSQL_BIN_LOG::new_file_without_locking()
} }
/* /**
Start writing to a new log file or reopen the old file Start writing to a new log file or reopen the old file.
SYNOPSIS @param need_lock Set to 1 if caller has not locked LOCK_log
new_file_impl()
need_lock Set to 1 if caller has not locked LOCK_log
NOTE @note
The new file name is stored last in the index file The new file name is stored last in the index file
*/ */
@ -3521,8 +3532,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /**
Write an event to the binary log Write an event to the binary log.
*/ */
bool MYSQL_BIN_LOG::write(Log_event *event_info) bool MYSQL_BIN_LOG::write(Log_event *event_info)
@ -3922,27 +3933,25 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
return 0; // All OK return 0; // All OK
} }
/* /**
Write a cached log entry to the binary log Write a cached log entry to the binary log.
SYNOPSIS
write()
thd
cache The cache to copy to the binlog
commit_event The commit event to print after writing the
contents of the cache.
NOTE
- We only come here if there is something in the cache.
- The thing in the cache is always a complete transaction
- 'cache' needs to be reinitialized after this functions returns.
IMPLEMENTATION
- To support transaction over replication, we wrap the transaction - To support transaction over replication, we wrap the transaction
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log. with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
We want to write a BEGIN/ROLLBACK block when a non-transactional table We want to write a BEGIN/ROLLBACK block when a non-transactional table
was updated in a transaction which was rolled back. This is to ensure was updated in a transaction which was rolled back. This is to ensure
that the same updates are run on the slave. that the same updates are run on the slave.
@param thd
@param cache The cache to copy to the binlog
@param commit_event The commit event to print after writing the
contents of the cache.
@note
We only come here if there is something in the cache.
@note
The thing in the cache is always a complete transaction.
@note
'cache' needs to be reinitialized after this functions returns.
*/ */
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
@ -4039,17 +4048,15 @@ err:
} }
/* /**
Wait until we get a signal that the binary log has been updated Wait until we get a signal that the binary log has been updated.
SYNOPSIS @param thd Thread variable
wait_for_update() @param is_slave If 0, the caller is the Binlog_dump thread from master;
thd Thread variable
is_slave If 0, the caller is the Binlog_dump thread from master;
if 1, the caller is the SQL thread from the slave. This if 1, the caller is the SQL thread from the slave. This
influences only thd->proc_info. influences only thd->proc_info.
NOTES @note
One must have a lock on LOCK_log before calling this function. One must have a lock on LOCK_log before calling this function.
This lock will be released before return! That's required by This lock will be released before return! That's required by
THD::enter_cond() (see NOTES in sql_class.h). THD::enter_cond() (see NOTES in sql_class.h).
@ -4072,18 +4079,16 @@ void MYSQL_BIN_LOG::wait_for_update(THD* thd, bool is_slave)
} }
/* /**
Close the log file Close the log file.
SYNOPSIS @param exiting Bitmask for one or more of the following bits:
close() - LOG_CLOSE_INDEX : if we should close the index file
exiting Bitmask for one or more of the following bits: - LOG_CLOSE_TO_BE_OPENED : if we intend to call open
LOG_CLOSE_INDEX if we should close the index file
LOG_CLOSE_TO_BE_OPENED if we intend to call open
at once after close. at once after close.
LOG_CLOSE_STOP_EVENT write a 'stop' event to the log - LOG_CLOSE_STOP_EVENT : write a 'stop' event to the log
NOTES @note
One can do an open on the object at once after doing a close. One can do an open on the object at once after doing a close.
The internal structures are not freed until cleanup() is called The internal structures are not freed until cleanup() is called
*/ */
@ -4163,21 +4168,20 @@ void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
} }
/* /**
Check if a string is a valid number Check if a string is a valid number.
SYNOPSIS @param str String to test
test_if_number() @param res Store value here
str String to test @param allow_wildcards Set to 1 if we should ignore '%' and '_'
res Store value here
allow_wildcards Set to 1 if we should ignore '%' and '_'
NOTE @note
For the moment the allow_wildcards argument is not used For the moment the allow_wildcards argument is not used
Should be move to some other file. Should be move to some other file.
RETURN VALUES @retval
1 String is a number 1 String is a number
@retval
0 Error 0 Error
*/ */
@ -4318,23 +4322,18 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
#endif /* __NT__ */ #endif /* __NT__ */
/* /**
Prints a printf style message to the error log and, under NT, to the Prints a printf style message to the error log and, under NT, to the
Windows event log. Windows event log.
SYNOPSIS
vprint_msg_to_log()
event_type Type of event to write (Error, Warning, or Info)
format Printf style format of message
args va_list list of arguments for the message
NOTE
IMPLEMENTATION
This function prints the message into a buffer and then sends that buffer This function prints the message into a buffer and then sends that buffer
to other functions to write that message to other logging sources. to other functions to write that message to other logging sources.
RETURN VALUES @param event_type Type of event to write (Error, Warning, or Info)
@param format Printf style format of message
@param args va_list list of arguments for the message
@returns
The function always returns 0. The return value is present in the The function always returns 0. The return value is present in the
signature to be compatible with other logging routines, which could signature to be compatible with other logging routines, which could
return an error (e.g. logging to the log tables) return an error (e.g. logging to the log tables)
@ -4588,16 +4587,18 @@ err:
return 1; return 1;
} }
/* /**
there is no active page, let's got one from the pool there is no active page, let's got one from the pool.
two strategies here: Two strategies here:
1. take the first from the pool -# take the first from the pool
2. if there're waiters - take the one with the most free space -# if there're waiters - take the one with the most free space.
@todo
TODO page merging. try to allocate adjacent page first, TODO page merging. try to allocate adjacent page first,
so that they can be flushed both in one sync so that they can be flushed both in one sync
*/ */
void TC_LOG_MMAP::get_active_from_pool() void TC_LOG_MMAP::get_active_from_pool()
{ {
PAGE **p, **best_p=0; PAGE **p, **best_p=0;
@ -4640,6 +4641,10 @@ void TC_LOG_MMAP::get_active_from_pool()
pthread_mutex_unlock(&LOCK_pool); pthread_mutex_unlock(&LOCK_pool);
} }
/**
@todo
perhaps, increase log size ?
*/
int TC_LOG_MMAP::overflow() int TC_LOG_MMAP::overflow()
{ {
/* /*
@ -4652,10 +4657,9 @@ int TC_LOG_MMAP::overflow()
return 1; // always return 1 return 1; // always return 1
} }
/* /**
Record that transaction XID is committed on the persistent storage Record that transaction XID is committed on the persistent storage.
NOTES
This function is called in the middle of two-phase commit: This function is called in the middle of two-phase commit:
First all resources prepare the transaction, then tc_log->log() is called, First all resources prepare the transaction, then tc_log->log() is called,
then all resources commit the transaction, then tc_log->unlog() is called. then all resources commit the transaction, then tc_log->unlog() is called.
@ -4666,15 +4670,15 @@ int TC_LOG_MMAP::overflow()
threads waiting for a page, but then all these threads will be waiting threads waiting for a page, but then all these threads will be waiting
for a fsync() anyway for a fsync() anyway
IMPLEMENTATION
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
records XID in a special Xid_log_event. records XID in a special Xid_log_event.
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
log. log.
RETURN @retval
0 Error 0 - error
# "cookie", a number that will be passed as an argument @retval
\# - otherwise, "cookie", a number that will be passed as an argument
to unlog() call. tc_log can define it any way it wants, to unlog() call. tc_log can define it any way it wants,
and use for whatever purposes. TC_LOG_MMAP sets it and use for whatever purposes. TC_LOG_MMAP sets it
to the position in memory where xid was logged to. to the position in memory where xid was logged to.
@ -4785,9 +4789,9 @@ int TC_LOG_MMAP::sync()
return err; return err;
} }
/* /**
erase xid from the page, update page free space counters/pointers. erase xid from the page, update page free space counters/pointers.
cookie points directly to the memory where xid was logged cookie points directly to the memory where xid was logged.
*/ */
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid) void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
@ -4898,16 +4902,17 @@ TC_LOG *tc_log;
TC_LOG_DUMMY tc_log_dummy; TC_LOG_DUMMY tc_log_dummy;
TC_LOG_MMAP tc_log_mmap; TC_LOG_MMAP tc_log_mmap;
/* /**
Perform heuristic recovery, if --tc-heuristic-recover was used Perform heuristic recovery, if --tc-heuristic-recover was used.
RETURN VALUE @note
0 no heuristic recovery was requested
1 heuristic recovery was performed
NOTE
no matter whether heuristic recovery was successful or not no matter whether heuristic recovery was successful or not
mysqld must exit. So, return value is the same in both cases. mysqld must exit. So, return value is the same in both cases.
@retval
0 no heuristic recovery was requested
@retval
1 heuristic recovery was performed
*/ */
int TC_LOG::using_heuristic_recover() int TC_LOG::using_heuristic_recover()
@ -4925,8 +4930,9 @@ int TC_LOG::using_heuristic_recover()
/****** transaction coordinator log for 2pc - binlog() based solution ******/ /****** transaction coordinator log for 2pc - binlog() based solution ******/
#define TC_LOG_BINLOG MYSQL_BIN_LOG #define TC_LOG_BINLOG MYSQL_BIN_LOG
/* /**
TODO keep in-memory list of prepared transactions @todo
keep in-memory list of prepared transactions
(add to list in log(), remove on unlog()) (add to list in log(), remove on unlog())
and copy it to the new binlog if rotated and copy it to the new binlog if rotated
but let's check the behaviour of tc_log_page_waits first! but let's check the behaviour of tc_log_page_waits first!
@ -5017,7 +5023,7 @@ err:
return error; return error;
} }
/* this is called on shutdown, after ha_panic */ /** This is called on shutdown, after ha_panic. */
void TC_LOG_BINLOG::close() void TC_LOG_BINLOG::close()
{ {
DBUG_ASSERT(prepared_xids==0); DBUG_ASSERT(prepared_xids==0);
@ -5025,12 +5031,14 @@ void TC_LOG_BINLOG::close()
pthread_cond_destroy (&COND_prep_xids); pthread_cond_destroy (&COND_prep_xids);
} }
/* /**
TODO group commit @todo
group commit
RETURN @retval
0 - error 0 error
1 - success @retval
1 success
*/ */
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid) int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
{ {

View File

@ -154,8 +154,8 @@ static void clear_all_errors(THD *thd, Relay_log_info *rli)
} }
/* /**
Ignore error code specified on command line Ignore error code specified on command line.
*/ */
inline int ignored_error_code(int err_code) inline int ignored_error_code(int err_code)
@ -212,21 +212,20 @@ static char *pretty_print_str(char *packet, char *str, int len)
#endif /* !MYSQL_CLIENT */ #endif /* !MYSQL_CLIENT */
/* #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Creates a temporary name for load data infile:
SYNOPSIS /**
slave_load_file_stem() Creates a temporary name for load data infile:.
buf Store new filename here
file_id File_id (part of file name)
event_server_id Event_id (part of file name)
ext Extension for file name
RETURN @param buf Store new filename here
@param file_id File_id (part of file name)
@param event_server_id Event_id (part of file name)
@param ext Extension for file name
@return
Pointer to start of extension Pointer to start of extension
*/ */
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
static char *slave_load_file_stem(char *buf, uint file_id, static char *slave_load_file_stem(char *buf, uint file_id,
int event_server_id, const char *ext) int event_server_id, const char *ext)
{ {
@ -246,14 +245,12 @@ static char *slave_load_file_stem(char *buf, uint file_id,
#endif #endif
/* #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Delete all temporary files used for SQL_LOAD.
SYNOPSIS /**
cleanup_load_tmpdir() Delete all temporary files used for SQL_LOAD.
*/ */
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
static void cleanup_load_tmpdir() static void cleanup_load_tmpdir()
{ {
MY_DIR *dirp; MY_DIR *dirp;
@ -321,7 +318,7 @@ static inline int read_str(const char **buf, const char *buf_end,
} }
/* /**
Transforms a string into "" or its expression in 0x... form. Transforms a string into "" or its expression in 0x... form.
*/ */
@ -338,12 +335,14 @@ char *str_to_hex(char *to, const char *from, uint len)
return to; // pointer to end 0 of 'to' return to; // pointer to end 0 of 'to'
} }
/* #ifndef MYSQL_CLIENT
/**
Append a version of the 'from' string suitable for use in a query to Append a version of the 'from' string suitable for use in a query to
the 'to' string. To generate a correct escaping, the character set the 'to' string. To generate a correct escaping, the character set
information in 'csinfo' is used. information in 'csinfo' is used.
*/ */
#ifndef MYSQL_CLIENT
int int
append_query_string(CHARSET_INFO *csinfo, append_query_string(CHARSET_INFO *csinfo,
String const *from, String *to) String const *from, String *to)
@ -370,7 +369,7 @@ append_query_string(CHARSET_INFO *csinfo,
#endif #endif
/* /**
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
commands just before it prints a query. commands just before it prints a query.
*/ */
@ -395,8 +394,9 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
Log_event methods (= the parent class of all events) Log_event methods (= the parent class of all events)
**************************************************************************/ **************************************************************************/
/* /**
Log_event::get_type_str() @return
returns the human readable name of the event's type
*/ */
const char* Log_event::get_type_str() const char* Log_event::get_type_str()
@ -444,7 +444,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
} }
/* /**
This minimal constructor is for when you are not even sure that there This minimal constructor is for when you are not even sure that there
is a valid THD. For example in the server when we are shutting down or is a valid THD. For example in the server when we are shutting down or
flushing logs after receiving a SIGHUP (then we must write a Rotate to flushing logs after receiving a SIGHUP (then we must write a Rotate to
@ -589,12 +589,9 @@ void Log_event::pack_info(Protocol *protocol)
} }
/* /**
Log_event::net_send()
Only called by SHOW BINLOG EVENTS Only called by SHOW BINLOG EVENTS
*/ */
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos) int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
{ {
const char *p= strrchr(log_name, FN_LIBCHAR); const char *p= strrchr(log_name, FN_LIBCHAR);
@ -615,8 +612,10 @@ int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
/* /**
Log_event::init_show_field_list() init_show_field_list() prepares the column names and types for the
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
EVENTS.
*/ */
void Log_event::init_show_field_list(List<Item>* field_list) void Log_event::init_show_field_list(List<Item>* field_list)
@ -712,12 +711,9 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
} }
/* /**
Log_event::read_log_event()
This needn't be format-tolerant, because we only read This needn't be format-tolerant, because we only read
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length). LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
*/ */
int Log_event::read_log_event(IO_CACHE* file, String* packet, int Log_event::read_log_event(IO_CACHE* file, String* packet,
@ -800,14 +796,11 @@ end:
#define LOCK_MUTEX #define LOCK_MUTEX
#endif #endif
/* #ifndef MYSQL_CLIENT
Log_event::read_log_event() /**
@note
NOTE:
Allocates memory; The caller is responsible for clean-up. Allocates memory; The caller is responsible for clean-up.
*/ */
#ifndef MYSQL_CLIENT
Log_event* Log_event::read_log_event(IO_CACHE* file, Log_event* Log_event::read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock, pthread_mutex_t* log_lock,
const Format_description_log_event const Format_description_log_event
@ -905,8 +898,7 @@ err:
} }
/* /**
Log_event::read_log_event()
Binlog format tolerance is in (buf, event_len, description_event) Binlog format tolerance is in (buf, event_len, description_event)
constructors. constructors.
*/ */
@ -1233,12 +1225,13 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
/* /**
Query_log_event::pack_info()
This (which is used only for SHOW BINLOG EVENTS) could be updated to This (which is used only for SHOW BINLOG EVENTS) could be updated to
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
only an information, it does not produce suitable queries to replay (for only an information, it does not produce suitable queries to replay (for
example it does not print LOAD DATA INFILE). example it does not print LOAD DATA INFILE).
@todo
show the catalog ??
*/ */
void Query_log_event::pack_info(Protocol *protocol) void Query_log_event::pack_info(Protocol *protocol)
@ -1267,7 +1260,9 @@ void Query_log_event::pack_info(Protocol *protocol)
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
/* Utility function for the next method */ /**
Utility function for the next method (Query_log_event::write()) .
*/
static void write_str_with_code_and_len(char **dst, const char *src, static void write_str_with_code_and_len(char **dst, const char *src,
int len, uint code) int len, uint code)
{ {
@ -1279,10 +1274,10 @@ static void write_str_with_code_and_len(char **dst, const char *src,
} }
/* /**
Query_log_event::write() Query_log_event::write().
NOTES: @note
In this event we have to modify the header to have the correct In this event we have to modify the header to have the correct
EVENT_LEN_OFFSET as we don't yet know how many status variables we EVENT_LEN_OFFSET as we don't yet know how many status variables we
will print! will print!
@ -1454,9 +1449,7 @@ bool Query_log_event::write(IO_CACHE* file)
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0; my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
} }
/* /**
Query_log_event::Query_log_event()
The simplest constructor that could possibly work. This is used for The simplest constructor that could possibly work. This is used for
creating static objects that have a special meaning and are invisible creating static objects that have a special meaning and are invisible
to the log. to the log.
@ -1580,8 +1573,7 @@ static void copy_str_and_move(const char **src,
*(*dst)++= 0; *(*dst)++= 0;
} }
/* /**
Query_log_event::Query_log_event()
This is used by the SQL slave thread to prepare the event before execution. This is used by the SQL slave thread to prepare the event before execution.
*/ */
@ -1748,11 +1740,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
} }
/*
Query_log_event::print()
*/
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
/**
Query_log_event::print().
@todo
print the catalog ??
*/
void Query_log_event::print_query_header(IO_CACHE* file, void Query_log_event::print_query_header(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
@ -1937,6 +1931,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli)
} }
/**
@todo
Compare the values of "affected rows" around here. Something
like:
@code
if ((uint32) affected_in_event != (uint32) affected_on_slave)
{
sql_print_error("Slave: did not get the expected number of affected \
rows running query from master - expected %d, got %d (this numbers \
should have matched modulo 4294967296).", 0, ...);
thd->query_error = 1;
}
@endcode
We may also want an option to tell the slave to ignore "affected"
mismatch. This mismatch could be implemented with a new ER_ code, and
to ignore it you would use --slave-skip-errors...
*/
int Query_log_event::do_apply_event(Relay_log_info const *rli, int Query_log_event::do_apply_event(Relay_log_info const *rli,
const char *query_arg, uint32 q_len_arg) const char *query_arg, uint32 q_len_arg)
{ {
@ -2367,9 +2378,10 @@ bool Start_log_event_v3::write(IO_CACHE* file)
#endif #endif
/* #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Start_log_event_v3::do_apply_event()
/**
Start_log_event_v3::do_apply_event() .
The master started The master started
IMPLEMENTATION IMPLEMENTATION
@ -2378,7 +2390,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
TODO), we clean up all temporary tables that we got, if we are sure we TODO), we clean up all temporary tables that we got, if we are sure we
can (see below). can (see below).
TODO @todo
- Remove all active user locks. - Remove all active user locks.
Guilhem 2003-06: this is true but not urgent: the worst it can cause is Guilhem 2003-06: this is true but not urgent: the worst it can cause is
the use of a bit of memory for a user lock which will not be used the use of a bit of memory for a user lock which will not be used
@ -2386,11 +2398,11 @@ bool Start_log_event_v3::write(IO_CACHE* file)
other words, no deadlock problem. other words, no deadlock problem.
*/ */
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli) int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
{ {
DBUG_ENTER("Start_log_event_v3::do_apply_event"); DBUG_ENTER("Start_log_event_v3::do_apply_event");
switch (binlog_version) { switch (binlog_version)
{
case 3: case 3:
case 4: case 4:
/* /*
@ -2438,23 +2450,20 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
Format_description_log_event methods Format_description_log_event methods
****************************************************************************/ ****************************************************************************/
/* /**
Format_description_log_event 1st ctor. Format_description_log_event 1st ctor.
SYNOPSIS Ctor. Can be used to create the event to write to the binary log (when the
Format_description_log_event::Format_description_log_event server starts or when FLUSH LOGS), or to create artificial events to parse
binlog_version the binlog version for which we want to build binlogs from MySQL 3.23 or 4.x.
When in a client, only the 2nd use is possible.
@param binlog_version the binlog version for which we want to build
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
old 4.0 (binlog version 2) is not supported; old 4.0 (binlog version 2) is not supported;
it should not be used for replication with it should not be used for replication with
5.0. 5.0.
DESCRIPTION
Ctor. Can be used to create the event to write to the binary log (when the
server starts or when FLUSH LOGS), or to create artificial events to parse
binlogs from MySQL 3.23 or 4.x.
When in a client, only the 2nd use is possible.
*/ */
Format_description_log_event:: Format_description_log_event::
@ -2562,18 +2571,20 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
} }
/* /**
The problem with this constructor is that the fixed header may have a The problem with this constructor is that the fixed header may have a
length different from this version, but we don't know this length as we length different from this version, but we don't know this length as we
have not read the Format_description_log_event which says it, yet. This have not read the Format_description_log_event which says it, yet. This
length is in the post-header of the event, but we don't know where the length is in the post-header of the event, but we don't know where the
post-header starts. post-header starts.
So this type of event HAS to: So this type of event HAS to:
- either have the header's length at the beginning (in the header, at a - either have the header's length at the beginning (in the header, at a
fixed position which will never be changed), not in the post-header. That fixed position which will never be changed), not in the post-header. That
would make the header be "shifted" compared to other events. would make the header be "shifted" compared to other events.
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
versions, so that we know for sure. versions, so that we know for sure.
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
it is sent before Format_description_log_event). it is sent before Format_description_log_event).
*/ */
@ -3008,14 +3019,11 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
#endif /* !MYSQL_CLIENT */ #endif /* !MYSQL_CLIENT */
/* /**
Load_log_event::Load_log_event() @note
NOTE
The caller must do buf[event_len] = 0 before he starts using the The caller must do buf[event_len] = 0 before he starts using the
constructed event. constructed event.
*/ */
Load_log_event::Load_log_event(const char *buf, uint event_len, Load_log_event::Load_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event) const Format_description_log_event *description_event)
:Log_event(buf, description_event), num_fields(0), fields(0), :Log_event(buf, description_event), num_fields(0), fields(0),
@ -3190,17 +3198,18 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
} }
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#ifndef MYSQL_CLIENT
/* /**
Load_log_event::set_fields() Load_log_event::set_fields()
Note that this function can not use the member variable @note
This function can not use the member variable
for the database, since LOAD DATA INFILE on the slave for the database, since LOAD DATA INFILE on the slave
can be for a different database than the current one. can be for a different database than the current one.
This is the reason for the affected_db argument to this method. This is the reason for the affected_db argument to this method.
*/ */
#ifndef MYSQL_CLIENT
void Load_log_event::set_fields(const char* affected_db, void Load_log_event::set_fields(const char* affected_db,
List<Item> &field_list, List<Item> &field_list,
Name_resolution_context *context) Name_resolution_context *context)
@ -3218,31 +3227,32 @@ void Load_log_event::set_fields(const char* affected_db,
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
/* /**
Does the data loading job when executing a LOAD DATA on the slave Does the data loading job when executing a LOAD DATA on the slave.
SYNOPSIS @param net
Load_log_event::do_apply_event @param rli
net @param use_rli_only_for_errors If set to 1, rli is provided to
rli Load_log_event::exec_event only for this
use_rli_only_for_errors - if set to 1, rli is provided to function to have RPL_LOG_NAME and
Load_log_event::do_apply_event rli->last_slave_error, both being used by
only for this function to have error reports. rli's position advancing
RPL_LOG_NAME and is skipped (done by the caller which is
rli->last_slave_error, both being Execute_load_log_event::exec_event).
used by error reports. rli's If set to 0, rli is provided for full use,
position advancing is skipped (done i.e. for error reports and position
by the caller which is advancing.
Execute_load_log_event::do_apply_event).
- if set to 0, rli is provided for
full use, i.e. for error reports and
position advancing.
DESCRIPTION @todo
Does the data loading job when executing a LOAD DATA on the slave fix this; this can be done by testing rules in
Create_file_log_event::exec_event() and then discarding Append_block and
al.
@todo
this is a bug - this needs to be moved to the I/O thread
RETURN VALUE @retval
0 Success 0 Success
@retval
1 Failure 1 Failure
*/ */
@ -3619,12 +3629,11 @@ bool Rotate_log_event::write(IO_CACHE* file)
#endif #endif
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
/* /*
Rotate_log_event::do_apply_event() Got a rotate log event from the master.
Got a rotate log event from the master
IMPLEMENTATION
This is mainly used so that we can later figure out the logname and This is mainly used so that we can later figure out the logname and
position for the master. position for the master.
@ -3632,11 +3641,9 @@ bool Rotate_log_event::write(IO_CACHE* file)
in a A -> B -> A setup. in a A -> B -> A setup.
The NOTES below is a wrong comment which will disappear when 4.1 is merged. The NOTES below is a wrong comment which will disappear when 4.1 is merged.
RETURN VALUES @retval
0 ok 0 ok
*/ */
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Rotate_log_event::do_update_pos(Relay_log_info *rli) int Rotate_log_event::do_update_pos(Relay_log_info *rli)
{ {
DBUG_ENTER("Rotate_log_event::do_update_pos"); DBUG_ENTER("Rotate_log_event::do_update_pos");
@ -3994,12 +4001,12 @@ void Xid_log_event::pack_info(Protocol *protocol)
} }
#endif #endif
/* /**
NOTE it's ok not to use int8store here, @note
It's ok not to use int8store here,
as long as xid_t::set(ulonglong) and as long as xid_t::set(ulonglong) and
xid_t::get_my_xid doesn't do it either xid_t::get_my_xid doesn't do it either.
We don't care about actual values of xids as long as
we don't care about actual values of xids as long as
identical numbers compare identically identical numbers compare identically
*/ */
@ -4470,6 +4477,10 @@ void Slave_log_event::pack_info(Protocol *protocol)
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
/**
@todo
re-write this better without holding both locks at the same time
*/
Slave_log_event::Slave_log_event(THD* thd_arg, Slave_log_event::Slave_log_event(THD* thd_arg,
Relay_log_info* rli) Relay_log_info* rli)
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0) :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
@ -4565,7 +4576,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
} }
/* This code is not used, so has not been updated to be format-tolerant */ /** This code is not used, so has not been updated to be format-tolerant. */
Slave_log_event::Slave_log_event(const char* buf, uint event_len) Slave_log_event::Slave_log_event(const char* buf, uint event_len)
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0) :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
{ {
@ -4613,9 +4624,8 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#ifndef MYSQL_CLIENT
/* /*
Stop_log_event::do_apply_event()
The master stopped. We used to clean up all temporary tables but The master stopped. We used to clean up all temporary tables but
this is useless as, as the master has shut down properly, it has this is useless as, as the master has shut down properly, it has
written all DROP TEMPORARY TABLE (prepared statements' deletion is written all DROP TEMPORARY TABLE (prepared statements' deletion is
@ -4626,8 +4636,6 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
Start_log_event_v3::do_apply_event(), not here. Because if we come Start_log_event_v3::do_apply_event(), not here. Because if we come
here, the master was sane. here, the master was sane.
*/ */
#ifndef MYSQL_CLIENT
int Stop_log_event::do_update_pos(Relay_log_info *rli) int Stop_log_event::do_update_pos(Relay_log_info *rli)
{ {
/* /*
@ -5437,7 +5445,9 @@ void Execute_load_query_log_event::print(FILE* file,
print(file, print_event_info, 0); print(file, print_event_info, 0);
} }
/**
Prints the query as LOAD DATA LOCAL and with rewritten filename.
*/
void Execute_load_query_log_event::print(FILE* file, void Execute_load_query_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info, PRINT_EVENT_INFO* print_event_info,
const char *local_fname) const char *local_fname)
@ -6471,6 +6481,7 @@ void Rows_log_event::print_helper(FILE *file,
*/ */
#if !defined(MYSQL_CLIENT)
/** /**
Save the field metadata based on the real_type of the field. Save the field metadata based on the real_type of the field.
The metadata saved depends on the type of the field. Some fields The metadata saved depends on the type of the field. Some fields
@ -6479,7 +6490,8 @@ void Rows_log_event::print_helper(FILE *file,
@retval 0 Ok. @retval 0 Ok.
TODO: We may want to consider changing the encoding of the information. @todo
We may want to consider changing the encoding of the information.
Currently, the code attempts to minimize the number of bytes written to Currently, the code attempts to minimize the number of bytes written to
the tablemap. There are at least two other alternatives; 1) using the tablemap. There are at least two other alternatives; 1) using
net_store_length() to store the data allowing it to choose the number of net_store_length() to store the data allowing it to choose the number of
@ -6494,7 +6506,6 @@ void Rows_log_event::print_helper(FILE *file,
is less wasteful for space but does waste 1 byte for every field that does is less wasteful for space but does waste 1 byte for every field that does
not encode 2 parts. not encode 2 parts.
*/ */
#if !defined(MYSQL_CLIENT)
int Table_map_log_event::save_field_metadata() int Table_map_log_event::save_field_metadata()
{ {
DBUG_ENTER("Table_map_log_event::save_field_metadata"); DBUG_ENTER("Table_map_log_event::save_field_metadata");

View File

@ -13,8 +13,11 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
Cashing of files with only does (sequential) read or writes of fixed- @file
@details
Caching of files with only does (sequential) read or writes of fixed-
length records. A read isn't allowed to go over file-length. A read is ok length records. A read isn't allowed to go over file-length. A read is ok
if it ends at file-length and next read can try to read after file-length if it ends at file-length and next read can try to read after file-length
(and get a EOF-error). (and get a EOF-error).
@ -34,11 +37,15 @@
extern "C" { extern "C" {
/* /**
** Read buffered from the net. Read buffered from the net.
** Returns 1 if can't read requested characters
** Returns 0 if record read @retval
*/ 1 if can't read requested characters
@retval
0 if record read
*/
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer, int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
size_t Count __attribute__((unused))) size_t Count __attribute__((unused)))

View File

@ -18,17 +18,15 @@
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
/* /**
report result of decimal operation report result of decimal operation.
SYNOPSIS @param result decimal library return code (E_DEC_* see include/decimal.h)
decimal_operation_results()
result decimal library return code (E_DEC_* see include/decimal.h)
TODO @todo
Fix error messages Fix error messages
RETURN @return
result result
*/ */

View File

@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
typedef fp_except fp_except_t; typedef fp_except fp_except_t;
#endif #endif
/* We can't handle floating point exceptions with threads, so disable /**
this on freebsd We can't handle floating point exceptions with threads, so disable
*/ this on freebsd.
*/
inline void reset_floating_point_exceptions() inline void reset_floating_point_exceptions()
{ {
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */ /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
@ -325,7 +325,7 @@ static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread; static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created; static ulong killed_threads, thread_created;
static ulong max_used_connections; static ulong max_used_connections;
static ulong my_bind_addr; /* the address we bind to */ static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0; static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF"; static const char *sql_mode_str= "OFF";
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr; static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
*/ */
bool volatile grant_option; bool volatile grant_option;
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
my_bool opt_reckless_slave = 0; my_bool opt_reckless_slave = 0;
my_bool opt_enable_named_pipe= 0; my_bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_slave_compressed_protocol; my_bool opt_local_infile, opt_slave_compressed_protocol;
@ -430,7 +430,7 @@ TYPELIB binlog_format_typelib=
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC; ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id]; const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_INITGROUPS #ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */ static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
#endif #endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_port_timeout; uint mysqld_port_timeout;
@ -458,12 +458,12 @@ ulong specialflag=0;
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections, max_connect_errors; ulong max_connections, max_connect_errors;
uint max_user_connections= 0; uint max_user_connections= 0;
/* /**
Limit of the total number of prepared statements in the server. Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks. Is necessary to protect the server against out-of-memory attacks.
*/ */
ulong max_prepared_stmt_count; ulong max_prepared_stmt_count;
/* /**
Current total number of prepared statements in the server. This number Current total number of prepared statements in the server. This number
is exact, and therefore may not be equal to the difference between is exact, and therefore may not be equal to the difference between
`com_stmt_prepare' and `com_stmt_close' (global status variables), as `com_stmt_prepare' and `com_stmt_close' (global status variables), as
@ -499,13 +499,13 @@ uint mysql_data_home_len;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH]; char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir; char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /* Error messages */ const char **errmesg; /**< Error messages */
const char *myisam_recover_options_str="OFF"; const char *myisam_recover_options_str="OFF";
const char *myisam_stats_method_str="nulls_unequal"; const char *myisam_stats_method_str="nulls_unequal";
/* name of reference on left espression in rewritten IN subquery */ /** name of reference on left espression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>"; const char *in_left_expr_name= "<left expr>";
/* name of additional condition */ /** name of additional condition */
const char *in_additional_cond= "<IN COND>"; const char *in_additional_cond= "<IN COND>";
const char *in_having_cond= "<IN HAVING>"; const char *in_having_cond= "<IN HAVING>";
@ -555,7 +555,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables, LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
/* /**
The below lock protects access to two global server variables: The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables max_prepared_stmt_count and prepared_stmt_count. These variables
set the limit and hold the current total number of prepared statements set the limit and hold the current total number of prepared statements
@ -604,7 +604,7 @@ static char **defaults_argv;
static char *opt_bin_logname; static char *opt_bin_logname;
static my_socket unix_sock,ip_sock; static my_socket unix_sock,ip_sock;
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD() struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
struct passwd *user_info; struct passwd *user_info;
@ -628,7 +628,7 @@ static char **opt_argv;
static HANDLE hEventShutdown; static HANDLE hEventShutdown;
static char shutdown_event_name[40]; static char shutdown_event_name[40];
#include "nt_servc.h" #include "nt_servc.h"
static NTService Service; // Service object for WinNT static NTService Service; ///< Service object for WinNT
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */ #endif /* __WIN__ */
@ -1009,19 +1009,15 @@ void kill_mysql(void)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
Force server down. Kill all connections and threads and exit Force server down. Kill all connections and threads and exit.
SYNOPSIS @param sig_ptr Signal number that caused kill_server to be called.
kill_server
sig_ptr Signal number that caused kill_server to be called. @note
NOTE!
A signal number of 0 mean that the function was not called A signal number of 0 mean that the function was not called
from a signal handler and there is thus no signal to block from a signal handler and there is thus no signal to block
or stop, we just want to kill the server. or stop, we just want to kill the server.
*/ */
#if defined(__NETWARE__) #if defined(__NETWARE__)
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
#endif #endif
} }
/* #ifndef EMBEDDED_LIBRARY
cleanup all memory and end program nicely
SYNOPSIS /**
unireg_end() cleanup all memory and end program nicely.
NOTES
This function never returns.
If SIGNALS_DONT_BREAK_READ is defined, this function is called If SIGNALS_DONT_BREAK_READ is defined, this function is called
by the main thread. To get MySQL to shut down nicely in this case by the main thread. To get MySQL to shut down nicely in this case
(Mac OS X) we have to call exit() instead if pthread_exit(). (Mac OS X) we have to call exit() instead if pthread_exit().
*/
#ifndef EMBEDDED_LIBRARY @note
This function never returns.
*/
void unireg_end(void) void unireg_end(void)
{ {
clean_up(1); clean_up(1);
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* /**
This is mainly needed when running with purify, but it's still nice to This is mainly needed when running with purify, but it's still nice to
know that all child threads have died when mysqld exits know that all child threads have died when mysqld exits.
*/ */
static void wait_for_signal_thread_to_end() static void wait_for_signal_thread_to_end()
{ {
#ifndef __NETWARE__ #ifndef __NETWARE__
@ -1506,8 +1498,7 @@ static void set_effective_user(struct passwd *user_info_arg)
} }
/* Change root user if started with --chroot */ /** Change root user if started with @c --chroot . */
static void set_root(const char *path) static void set_root(const char *path)
{ {
#if !defined(__WIN__) && !defined(__NETWARE__) #if !defined(__WIN__) && !defined(__NETWARE__)
@ -1696,19 +1687,16 @@ static void network_init(void)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* /**
Close a connection Close a connection.
SYNOPSIS @param thd Thread handle
close_connection() @param errcode Error code to print to console
thd Thread handle @param lock 1 if we have have to lock LOCK_thread_count
errcode Error code to print to console
lock 1 if we have have to lock LOCK_thread_count
NOTES @note
For the connection that is doing shutdown, this is called twice For the connection that is doing shutdown, this is called twice
*/ */
void close_connection(THD *thd, uint errcode, bool lock) void close_connection(THD *thd, uint errcode, bool lock)
{ {
st_vio *vio; st_vio *vio;
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* Called when a thread is aborted */ /** Called when a thread is aborted. */
/* ARGSUSED */ /* ARGSUSED */
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
{ {
THD *thd=current_thd; THD *thd=current_thd;
@ -1877,13 +1864,13 @@ void flush_thread_cache()
} }
/*
Aborts a thread nicely. Commes here on SIGPIPE
TODO: One should have to fix that thr_alarm know about this
thread too.
*/
#ifdef THREAD_SPECIFIC_SIGPIPE #ifdef THREAD_SPECIFIC_SIGPIPE
/**
Aborts a thread nicely. Comes here on SIGPIPE.
@todo
One should have to fix that thr_alarm know about this thread too.
*/
extern "C" sig_handler abort_thread(int sig __attribute__((unused))) extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
{ {
THD *thd=current_thd; THD *thd=current_thd;
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
#elif defined(__NETWARE__) #elif defined(__NETWARE__)
// down server event callback /// down server event callback.
void mysql_down_server_cb(void *, void *) void mysql_down_server_cb(void *, void *)
{ {
event_flag= TRUE; event_flag= TRUE;
@ -1939,7 +1926,7 @@ void mysql_down_server_cb(void *, void *)
} }
// destroy callback resources /// destroy callback resources.
void mysql_cb_destroy(void *) void mysql_cb_destroy(void *)
{ {
UnRegisterEventNotification(eh); // cleanup down event notification UnRegisterEventNotification(eh); // cleanup down event notification
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
} }
// initialize callbacks /// initialize callbacks.
void mysql_cb_init() void mysql_cb_init()
{ {
// register for down server event // register for down server event
@ -1974,8 +1961,7 @@ void mysql_cb_init()
} }
/* To get the name of the NetWare volume having MySQL data folder */ /** To get the name of the NetWare volume having MySQL data folder. */
static void getvolumename() static void getvolumename()
{ {
char *p; char *p;
@ -1989,8 +1975,8 @@ static void getvolumename()
} }
/* /**
Registering with NEB for NSS Volume Deactivation event Registering with NEB for NSS Volume Deactivation event.
*/ */
static void registerwithneb() static void registerwithneb()
@ -2042,8 +2028,8 @@ static void registerwithneb()
} }
/* /**
Callback for NSS Volume Deactivation event Callback for NSS Volume Deactivation event.
*/ */
ulong neb_event_callback(struct EventBlock *eblock) ulong neb_event_callback(struct EventBlock *eblock)
@ -2075,12 +2061,11 @@ ulong neb_event_callback(struct EventBlock *eblock)
} }
/*
Function to get NSS volume ID of the MySQL data
*/
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/" #define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
/**
Function to get NSS volume ID of the MySQL data.
*/
static void getvolumeID(BYTE *volumeName) static void getvolumeID(BYTE *volumeName)
{ {
char path[zMAX_FULL_NAME]; char path[zMAX_FULL_NAME];
@ -2155,10 +2140,10 @@ static void start_signal_handler(void)
} }
/* /**
Warn if the data is on a Traditional volume Warn if the data is on a Traditional volume.
NOTE @note
Already done by mysqld_safe Already done by mysqld_safe
*/ */
@ -2419,8 +2404,7 @@ static void start_signal_handler(void)
} }
/* This threads handles all signals and alarms */ /** This threads handles all signals and alarms. */
/* ARGSUSED */ /* ARGSUSED */
pthread_handler_t signal_hand(void *arg __attribute__((unused))) pthread_handler_t signal_hand(void *arg __attribute__((unused)))
{ {
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
#endif /* __WIN__*/ #endif /* __WIN__*/
/* /**
All global error messages are sent here where the first one is stored All global error messages are sent here where the first one is stored
for the client for the client.
*/ */
/* ARGSUSED */ /* ARGSUSED */
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags); extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
@ -2689,20 +2671,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
/* /**
Initialize one of the global date/time format variables Initialize one of the global date/time format variables.
SYNOPSIS @param format_type What kind of format should be supported
init_global_datetime_format() @param var_ptr Pointer to variable that should be updated
format_type What kind of format should be supported
var_ptr Pointer to variable that should be updated
NOTES @note
The default value is taken from either opt_date_time_formats[] or The default value is taken from either opt_date_time_formats[] or
the ISO format (ANSI SQL) the ISO format (ANSI SQL)
RETURN @retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -4046,21 +4027,20 @@ static char *add_quoted_string(char *to, const char *from, char *to_end)
} }
/* /**
Handle basic handling of services, like installation and removal Handle basic handling of services, like installation and removal.
SYNOPSIS @param argv Pointer to argument list
default_service_handling() @param servicename Internal name of service
argv Pointer to argument list @param displayname Display name of service (in taskbar ?)
servicename Internal name of service @param file_path Path to this program
displayname Display name of service (in taskbar ?) @param startup_option Startup option to mysqld
file_path Path to this program
startup_option Startup option to mysqld
RETURN VALUES @retval
0 option handled 0 option handled
@retval
1 Could not handle option 1 Could not handle option
*/ */
static bool static bool
default_service_handling(char **argv, default_service_handling(char **argv,
@ -4209,7 +4189,7 @@ int main(int argc, char **argv)
#endif #endif
/* /**
Execute all commands from a file. Used by the mysql_install_db script to Execute all commands from a file. Used by the mysql_install_db script to
create MySQL privilege tables without having to start a full MySQL server. create MySQL privilege tables without having to start a full MySQL server.
*/ */
@ -4334,23 +4314,17 @@ void create_thread_to_handle_connection(THD *thd)
} }
/* /**
Create new thread to handle incoming connection. Create new thread to handle incoming connection.
SYNOPSIS
create_new_thread()
thd in/out Thread handle of future thread.
DESCRIPTION
This function will create new thread to handle the incoming This function will create new thread to handle the incoming
connection. If there are idle cached threads one will be used. connection. If there are idle cached threads one will be used.
'thd' will be pushed into 'threads'. 'thd' will be pushed into 'threads'.
In single-threaded mode (#define ONE_THREAD) connection will be In single-threaded mode (\#define ONE_THREAD) connection will be
handled inside this function. handled inside this function.
RETURN VALUE @param[in,out] thd Thread handle of future thread.
none
*/ */
static void create_new_thread(THD *thd) static void create_new_thread(THD *thd)
@ -4699,15 +4673,13 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
#endif /* __NT__ */ #endif /* __NT__ */
/*
Thread of shared memory's service
SYNOPSIS
handle_connections_shared_memory()
arg Arguments of thread
*/
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
/**
Thread of shared memory's service.
@param arg Arguments of thread
*/
pthread_handler_t handle_connections_shared_memory(void *arg) pthread_handler_t handle_connections_shared_memory(void *arg)
{ {
/* file-mapping object, use for create shared memory */ /* file-mapping object, use for create shared memory */
@ -7039,13 +7011,13 @@ To see what values a running MySQL server is using, type\n\
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
/* /**
Initialize all MySQL global variables to default values Initialize all MySQL global variables to default values.
SYNOPSIS We don't need to set numeric variables refered to in my_long_options
mysql_init_variables() as these are initialized by my_getopt.
NOTES @note
The reason to set a lot of global variables to zero is to allow one to The reason to set a lot of global variables to zero is to allow one to
restart the embedded server with a clean environment restart the embedded server with a clean environment
It's also needed on some exotic platforms where global variables are It's also needed on some exotic platforms where global variables are
@ -7771,7 +7743,7 @@ mysqld_get_one_option(int optid,
} }
/* Handle arguments for multiple key caches */ /** Handle arguments for multiple key caches. */
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length, extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
const struct my_option *option); const struct my_option *option);
@ -7822,6 +7794,10 @@ void option_error_reporter(enum loglevel level, const char *format, ...)
} }
/**
@todo
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
*/
static void get_options(int *argc,char **argv) static void get_options(int *argc,char **argv)
{ {
int ho_error; int ho_error;
@ -7953,10 +7929,11 @@ static char *get_relative_path(const char *path)
} }
/* /**
Fix filename and replace extension where 'dir' is relative to Fix filename and replace extension where 'dir' is relative to
mysql_real_data_home. mysql_real_data_home.
Return 1 if len(path) > FN_REFLEN @return
1 if len(path) > FN_REFLEN
*/ */
bool bool
@ -8061,9 +8038,11 @@ static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
} }
/* /**
Return a bitfield from a string of substrings separated by ',' @return
returns ~(ulong) 0 on error. a bitfield from a string of substrings separated by ','
or
~(ulong) 0 on error.
*/ */
static ulong find_bit_type(const char *x, TYPELIB *bit_lib) static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
@ -8122,16 +8101,16 @@ skip: ;
} /* find_bit_type */ } /* find_bit_type */
/* /**
Check if file system used for databases is case insensitive Check if file system used for databases is case insensitive.
SYNOPSIS @param dir_name Directory to test
test_if_case_sensitive()
dir_name Directory to test
RETURN @retval
-1 Don't know (Test failed) -1 Don't know (Test failed)
@retval
0 File system is case sensitive 0 File system is case sensitive
@retval
1 File system is case insensitive 1 File system is case insensitive
*/ */
@ -8162,10 +8141,11 @@ static int test_if_case_insensitive(const char *dir_name)
} }
/* Create file to store pid number */
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/**
Create file to store pid number.
*/
static void create_pid_file() static void create_pid_file()
{ {
File file; File file;
@ -8187,7 +8167,7 @@ static void create_pid_file()
} }
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* Clear most status variables */ /** Clear most status variables. */
void refresh_status(THD *thd) void refresh_status(THD *thd)
{ {
pthread_mutex_lock(&LOCK_status); pthread_mutex_lock(&LOCK_status);