Doxygenization of comments.
This commit is contained in:
parent
39062b7e4e
commit
d43c15b0de
@ -14,11 +14,15 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
Functions to copy data to or from fields
|
||||
This could be done with a single short function but opencoding this
|
||||
gives much more speed.
|
||||
*/
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Functions to copy data to or from fields
|
||||
|
||||
This could be done with a single short function but opencoding this
|
||||
gives much more speed.
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include <m_ctype.h>
|
||||
@ -129,22 +133,21 @@ 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
|
||||
set_field_to_null_with_conversions()
|
||||
field Field to update
|
||||
no_conversion Set to 1 if we should return 1 if field can't
|
||||
take null values.
|
||||
If set to 0 we will do store the 'default value'
|
||||
if the field is a special field. If not we will
|
||||
give an error.
|
||||
@param field Field to update
|
||||
@param no_conversions Set to 1 if we should return 1 if field can't
|
||||
take null values.
|
||||
If set to 0 we will do store the 'default value'
|
||||
if the field is a special field. If not we will
|
||||
give an error.
|
||||
|
||||
RETURN VALUES
|
||||
0 Field could take 0 or an automatic 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
|
||||
@retval
|
||||
0 Field could take 0 or an automatic conversion was used
|
||||
@retval
|
||||
-1 Field could not take NULL and no conversion was used.
|
||||
If no_conversion was not set, an error message is printed
|
||||
*/
|
||||
|
||||
int
|
||||
@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy)
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
from string
|
||||
from string.
|
||||
*/
|
||||
|
||||
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
|
||||
from string
|
||||
from string.
|
||||
*/
|
||||
|
||||
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
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
copy of field to maybe null string.
|
||||
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
|
||||
@ -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)
|
||||
{
|
||||
|
296
sql/filesort.cc
296
sql/filesort.cc
@ -14,7 +14,12 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Sorts a database */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Sorts a database
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#ifdef HAVE_STDDEF_H
|
||||
@ -27,8 +32,7 @@
|
||||
#define SKIP_DBUG_IN_FILESORT
|
||||
#endif
|
||||
|
||||
/* How to write record_ref. */
|
||||
|
||||
/// How to write record_ref.
|
||||
#define WRITE_REF(file,from) \
|
||||
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
||||
DBUG_RETURN(1);
|
||||
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
|
||||
uint sortlength, uint *plength);
|
||||
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
||||
uchar *buff);
|
||||
/**
|
||||
Sort a table.
|
||||
Creates a set of pointers that can be used to read the rows
|
||||
in sorted order. This should be done with the functions
|
||||
in records.cc.
|
||||
|
||||
/*
|
||||
Sort a table
|
||||
Before calling filesort, one must have done
|
||||
table->file->info(HA_STATUS_VARIABLE)
|
||||
|
||||
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
|
||||
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)
|
||||
examined_rows Store number of examined rows here
|
||||
@param examined_rows Store number of examined rows here
|
||||
|
||||
IMPLEMENTATION
|
||||
Creates a set of pointers that can be used to read the rows
|
||||
in sorted order. This should be done with the functions
|
||||
in records.cc
|
||||
|
||||
REQUIREMENTS
|
||||
Before calling filesort, one must have done
|
||||
table->file->info(HA_STATUS_VARIABLE)
|
||||
|
||||
NOTES
|
||||
@todo
|
||||
check why we do this (param.keys--)
|
||||
@note
|
||||
If we sort by position (like if sort_positions is 1) filesort() will
|
||||
call table->prepare_for_position().
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
HA_POS_ERROR Error
|
||||
# Number of rows
|
||||
|
||||
@retval
|
||||
\# Number of rows
|
||||
@retval
|
||||
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,
|
||||
@ -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,
|
||||
uint length, myf my_flag)
|
||||
@ -372,7 +374,7 @@ static char **make_char_array(char **old_pos, register uint fields,
|
||||
} /* 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)
|
||||
{
|
||||
@ -395,38 +397,40 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Search after sort_keys and write them into tempfile.
|
||||
SYNOPSIS
|
||||
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
|
||||
All produced sequences are guaranteed to be non-empty.
|
||||
|
||||
@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:
|
||||
while (get_next_sortkey())
|
||||
{
|
||||
if (no free space in sort_keys buffers)
|
||||
{
|
||||
sort sort_keys buffer;
|
||||
dump sorted sequence to 'tempfile';
|
||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||
}
|
||||
put sort key into 'sort_keys';
|
||||
}
|
||||
if (sort_keys has some elements && dumped at least once)
|
||||
sort-dump-dump as above;
|
||||
else
|
||||
don't sort, leave sort_keys array to be sorted by caller.
|
||||
|
||||
All produced sequences are guaranteed to be non-empty.
|
||||
RETURN
|
||||
@verbatim
|
||||
while (get_next_sortkey())
|
||||
{
|
||||
if (no free space in sort_keys buffers)
|
||||
{
|
||||
sort sort_keys buffer;
|
||||
dump sorted sequence to 'tempfile';
|
||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||
}
|
||||
put sort key into 'sort_keys';
|
||||
}
|
||||
if (sort_keys has some elements && dumped at least once)
|
||||
sort-dump-dump as above;
|
||||
else
|
||||
don't sort, leave sort_keys array to be sorted by caller.
|
||||
@endverbatim
|
||||
|
||||
@retval
|
||||
Number of records written on success.
|
||||
@retval
|
||||
HA_POS_ERROR on error.
|
||||
*/
|
||||
|
||||
@ -591,23 +595,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
} /* find_all_keys */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
Sort the buffer and write:
|
||||
1) the sorted sequence to tempfile
|
||||
2) a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||
(was: Skriver en buffert med nycklar till filen)
|
||||
SYNOPSIS
|
||||
write_keys()
|
||||
param Sort parameters
|
||||
sort_keys Array of pointers to keys to sort
|
||||
count Number of elements in sort_keys array
|
||||
buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||
The BUFFPEK::{file_pos, count} will indicate where
|
||||
the sorted data was stored.
|
||||
tempfile The sorted sequence will be written into this file.
|
||||
|
||||
RETURN
|
||||
-# the sorted sequence to tempfile
|
||||
-# a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||
|
||||
(was: Skriver en buffert med nycklar till filen)
|
||||
|
||||
@param param Sort parameters
|
||||
@param sort_keys Array of pointers to keys to sort
|
||||
@param count Number of elements in sort_keys array
|
||||
@param buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||
The BUFFPEK::{file_pos, count} will indicate where
|
||||
the sorted data was stored.
|
||||
@param tempfile The sorted sequence will be written into this file.
|
||||
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
@ -650,8 +656,8 @@ err:
|
||||
} /* 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)
|
||||
@ -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,
|
||||
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,
|
||||
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
||||
@ -1040,8 +1046,12 @@ cleanup:
|
||||
} /* 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 rec_length)
|
||||
@ -1063,15 +1073,15 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
||||
} /* read_to_buffer */
|
||||
|
||||
|
||||
/*
|
||||
Put all room used by freed buffer to use in adjacent buffer. Note, that
|
||||
we can't simply distribute memory evenly between all buffers, because
|
||||
new areas must not overlap with old ones.
|
||||
SYNOPSIS
|
||||
reuse_freed_buff()
|
||||
queue IN list of non-empty buffers, without freed buffer
|
||||
reuse IN empty buffer
|
||||
key_length IN key length
|
||||
/**
|
||||
Put all room used by freed buffer to use in adjacent buffer.
|
||||
|
||||
Note, that we can't simply distribute memory evenly between all buffers,
|
||||
because new areas must not overlap with old ones.
|
||||
|
||||
@param[in] queue list of non-empty buffers, without freed buffer
|
||||
@param[in] reuse empty buffer
|
||||
@param[in] key_length 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
|
||||
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
|
||||
/**
|
||||
Merge buffers to one buffer.
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
other - error
|
||||
@param param Sort parameter
|
||||
@param from_file File with source data (BUFFPEKs point to this file)
|
||||
@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,
|
||||
@ -1347,23 +1357,21 @@ static uint suffix_length(ulong string_length)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Calculate length of sort key
|
||||
/**
|
||||
Calculate length of sort key.
|
||||
|
||||
SYNOPSIS
|
||||
sortlength()
|
||||
thd Thread handler
|
||||
sortorder Order of items to sort
|
||||
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())
|
||||
@param thd Thread handler
|
||||
@param sortorder Order of items to sort
|
||||
@param s_length Number of items to sort
|
||||
@param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
|
||||
(In which case we have to use strxnfrm())
|
||||
|
||||
NOTES
|
||||
sortorder->length is updated for each sort item
|
||||
@note
|
||||
sortorder->length is updated for each sort item.
|
||||
@n
|
||||
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
||||
|
||||
RETURN
|
||||
@return
|
||||
Total length of sort buffer in bytes
|
||||
*/
|
||||
|
||||
@ -1450,33 +1458,31 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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
|
||||
these fields together with the value of sort values.
|
||||
If the calculated length is not greater than max_length_for_sort_data
|
||||
the function allocates memory for an array of descriptors containing
|
||||
layouts for the values of the non-sorted fields in the buffer and
|
||||
fills them.
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
these fields together with the value of sort values.
|
||||
If the calculated length is not greater than max_length_for_sort_data
|
||||
the function allocates memory for an array of descriptors containing
|
||||
layouts for the values of the non-sorted fields in the buffer and
|
||||
fills them.
|
||||
@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
|
||||
|
||||
NOTES
|
||||
@note
|
||||
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.
|
||||
|
||||
RETURN
|
||||
@return
|
||||
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 *
|
||||
@ -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.
|
||||
|
||||
SYNOPSIS
|
||||
unpack_addon_fields()
|
||||
addon_field Array of descriptors for appended fields
|
||||
buff Buffer which to unpack the value from
|
||||
@param addon_field Array of descriptors for appended fields
|
||||
@param buff Buffer which to unpack the value from
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The function is supposed to be used only as a callback function
|
||||
when getting field values for the sorted result set.
|
||||
|
||||
RETURN
|
||||
@return
|
||||
void.
|
||||
*/
|
||||
|
||||
|
@ -13,8 +13,11 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
@details
|
||||
@verbatim
|
||||
The idea of presented algorithm see in
|
||||
"The Art of Computer Programming" by Donald E. Knuth
|
||||
Volume 3 "Sorting and searching"
|
||||
@ -63,12 +66,14 @@ for optimization, link is the 16-bit index in 'symbols' or 'sql_functions'
|
||||
or search-array..
|
||||
|
||||
So, we can read full search-structure as 32-bit word
|
||||
@endverbatim
|
||||
|
||||
@todo
|
||||
use instead to_upper_lex, special array
|
||||
(substitute chars) without skip codes..
|
||||
@todo
|
||||
try use reverse order of comparing..
|
||||
|
||||
TODO:
|
||||
1. use instead to_upper_lex, special array
|
||||
(substitute chars) without skip codes..
|
||||
2. try use reverse order of comparing..
|
||||
|
||||
*/
|
||||
|
||||
#define NO_YACC_SYMBOLS
|
||||
|
File diff suppressed because it is too large
Load Diff
465
sql/handler.cc
465
sql/handler.cc
@ -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,
|
||||
bool no_substitute, bool report_error)
|
||||
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Register handler error messages for use with my_error().
|
||||
|
||||
SYNOPSIS
|
||||
ha_init_errors()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 Error
|
||||
@retval
|
||||
!=0 Error
|
||||
*/
|
||||
static int ha_init_errors(void)
|
||||
{
|
||||
@ -349,15 +347,13 @@ static int ha_init_errors(void)
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Unregister handler error messages.
|
||||
|
||||
SYNOPSIS
|
||||
ha_finish_errors()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 Error
|
||||
@retval
|
||||
!=0 Error
|
||||
*/
|
||||
static int ha_finish_errors(void)
|
||||
{
|
||||
@ -567,8 +563,9 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
don't bother to rollback here, it's done already
|
||||
/**
|
||||
@note
|
||||
don't bother to rollback here, it's done already
|
||||
*/
|
||||
void ha_close_connection(THD* thd)
|
||||
{
|
||||
@ -578,17 +575,16 @@ void ha_close_connection(THD* thd)
|
||||
/* ========================================================================
|
||||
======================= 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
|
||||
a transaction or a statement (that is it must be called both for the
|
||||
"beginning of transaction" and "beginning of statement").
|
||||
Only storage engines registered for the transaction/statement
|
||||
will know when to commit/rollback it.
|
||||
Every storage engine MUST call this function when it starts
|
||||
a transaction or a statement (that is it must be called both for the
|
||||
"beginning of transaction" and "beginning of statement").
|
||||
Only storage engines registered for the transaction/statement
|
||||
will know when to commit/rollback it.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
trans_register_ha is idempotent - storage engine may register many
|
||||
times per transaction.
|
||||
|
||||
@ -620,10 +616,11 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - error, transaction was rolled back
|
||||
/**
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error, transaction was rolled back
|
||||
*/
|
||||
int ha_prepare(THD *thd)
|
||||
{
|
||||
@ -660,11 +657,19 @@ int ha_prepare(THD *thd)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - transaction was rolled back
|
||||
2 - error during commit, data may be inconsistent
|
||||
/**
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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)
|
||||
{
|
||||
@ -757,9 +762,9 @@ end:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
NOTE - this function does not care about global read lock.
|
||||
A caller should.
|
||||
/**
|
||||
@note
|
||||
This function does not care about global read lock. A caller should.
|
||||
*/
|
||||
int ha_commit_one_phase(THD *thd, bool all)
|
||||
{
|
||||
@ -869,13 +874,16 @@ int ha_rollback_trans(THD *thd, bool all)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
This is used to commit or rollback a single statement depending on the value
|
||||
of error. Note that if the autocommit is on, then the following call inside
|
||||
InnoDB will commit or rollback the whole transaction (= the statement). The
|
||||
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
|
||||
commit.
|
||||
/**
|
||||
This is used to commit or rollback a single statement depending on
|
||||
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
|
||||
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
|
||||
commit.
|
||||
*/
|
||||
int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
{
|
||||
@ -944,7 +952,10 @@ int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
|
||||
|
||||
|
||||
#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)
|
||||
{
|
||||
int i;
|
||||
@ -996,24 +1007,21 @@ static char* xid_to_str(char *buf, XID *xid)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief
|
||||
recover() step of xa
|
||||
/**
|
||||
recover() step of xa.
|
||||
|
||||
NOTE
|
||||
there are three modes of operation:
|
||||
|
||||
- automatic recover after a crash
|
||||
in this case commit_list != 0, tc_heuristic_recover==0
|
||||
all xids from commit_list are committed, others are rolled back
|
||||
|
||||
- manual (heuristic) recover
|
||||
in this case commit_list==0, tc_heuristic_recover != 0
|
||||
DBA has explicitly specified that all prepared transactions should
|
||||
be committed (or rolled back).
|
||||
|
||||
- no recovery (MySQL did not detect a crash)
|
||||
in this case commit_list==0, tc_heuristic_recover == 0
|
||||
there should be no prepared transactions in this case.
|
||||
@note
|
||||
there are three modes of operation:
|
||||
- automatic recover after a crash
|
||||
in this case commit_list != 0, tc_heuristic_recover==0
|
||||
all xids from commit_list are committed, others are rolled back
|
||||
- manual (heuristic) recover
|
||||
in this case commit_list==0, tc_heuristic_recover != 0
|
||||
DBA has explicitly specified that all prepared transactions should
|
||||
be committed (or rolled back).
|
||||
- no recovery (MySQL did not detect a crash)
|
||||
in this case commit_list==0, tc_heuristic_recover == 0
|
||||
there should be no prepared transactions in this case.
|
||||
*/
|
||||
struct xarecover_st
|
||||
{
|
||||
@ -1146,10 +1154,10 @@ int ha_recover(HASH *commit_list)
|
||||
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,
|
||||
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
||||
It can be easily fixed later, if necessary.
|
||||
@ -1195,7 +1203,8 @@ bool mysql_xa_recover(THD *thd)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
@details
|
||||
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
|
||||
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
|
||||
there a connection can have several SELECT queries open at the same time.
|
||||
|
||||
arguments:
|
||||
thd: the thread handle of the current connection
|
||||
return value: always 0
|
||||
@param thd the thread handle of the current connection
|
||||
|
||||
@return
|
||||
always 0
|
||||
*/
|
||||
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
||||
void *unused)
|
||||
@ -1276,8 +1286,9 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
|
||||
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",
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
/** @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
|
||||
- strictly greater than "nr"
|
||||
- of the form: auto_increment_offset + N * auto_increment_increment
|
||||
|
||||
In most cases increment= offset= 1, in which case we get:
|
||||
1,2,3,4,5,...
|
||||
If increment=10 and offset=5 and previous number is 1, we get:
|
||||
1,5,15,25,35,...
|
||||
@verbatim 1,2,3,4,5,... @endverbatim
|
||||
If increment=10 and offset=5 and previous number is 1, we get:
|
||||
@verbatim 1,5,15,25,35,... @endverbatim
|
||||
*/
|
||||
inline ulonglong
|
||||
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
|
||||
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:
|
||||
Updates columns with type NEXT_NUMBER if:
|
||||
|
||||
- If column value is set to NULL (in which case
|
||||
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
|
||||
this list.
|
||||
|
||||
TODO
|
||||
|
||||
@todo
|
||||
Replace all references to "next number" or NEXT_NUMBER to
|
||||
"auto_increment", everywhere (see below: there is
|
||||
table->auto_increment_field_not_null, and there also exists
|
||||
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
|
||||
@ -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
|
||||
In case of delete table it's only safe to use the following parts of
|
||||
the 'table' structure:
|
||||
table->s->path
|
||||
table->alias
|
||||
@note
|
||||
In case of delete table it's only safe to use the following parts of
|
||||
the 'table' structure:
|
||||
- table->s->path
|
||||
- table->alias
|
||||
*/
|
||||
void handler::print_error(int error, myf errflag)
|
||||
{
|
||||
@ -2253,14 +2259,14 @@ 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
|
||||
error error code previously returned by handler
|
||||
buf Pointer to String where to add error message
|
||||
@param error error code previously returned by handler
|
||||
@param buf pointer to String where to add error message
|
||||
|
||||
Returns true if this is a temporary error
|
||||
@return
|
||||
Returns true if this is a temporary error
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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
|
||||
delete_table()
|
||||
name Base name of table
|
||||
@param name Base name of table
|
||||
|
||||
NOTES
|
||||
@note
|
||||
We assume that the handler may return more extensions than
|
||||
was actually used for the file.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 If we successfully deleted at least one file from base_ext and
|
||||
didn't get any other errors than ENOENT
|
||||
# Error
|
||||
didn't get any other errors than ENOENT
|
||||
@retval
|
||||
!0 Error
|
||||
*/
|
||||
int handler::delete_table(const char *name)
|
||||
{
|
||||
@ -2442,21 +2449,20 @@ void handler::drop_table(const char *name)
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
Performs checks upon the table.
|
||||
/**
|
||||
Performs checks upon the table.
|
||||
|
||||
SYNOPSIS
|
||||
check()
|
||||
thd thread doing CHECK TABLE operation
|
||||
check_opt options from the parser
|
||||
@param thd thread doing CHECK TABLE operation
|
||||
@param check_opt options from the parser
|
||||
|
||||
NOTES
|
||||
|
||||
RETURN
|
||||
HA_ADMIN_OK Successful upgrade
|
||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||
HA_ADMIN_NOT_IMPLEMENTED
|
||||
@retval
|
||||
HA_ADMIN_OK Successful upgrade
|
||||
@retval
|
||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||
@retval
|
||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||
@retval
|
||||
HA_ADMIN_NOT_IMPLEMENTED
|
||||
*/
|
||||
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
|
||||
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.
|
||||
@ -2559,15 +2565,12 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
** 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
|
||||
We must have a write lock on LOCK_open to be sure no other thread
|
||||
interferes with table
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
int ha_create_table(THD *thd, const char *path,
|
||||
@ -2605,17 +2608,18 @@ err:
|
||||
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.
|
||||
|
||||
RETURN VALUES:
|
||||
@retval
|
||||
-1 Table did not exists
|
||||
@retval
|
||||
0 Table created ok
|
||||
@retval
|
||||
> 0 Error, table existed but could not be created
|
||||
|
||||
*/
|
||||
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)
|
||||
*****************************************************************************/
|
||||
|
||||
/** @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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -2734,7 +2738,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Change parameters for key cache (like size)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Free memory allocated by a key cache
|
||||
/**
|
||||
Free memory allocated by a 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;
|
||||
}
|
||||
|
||||
/** @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,
|
||||
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
|
||||
-1 : Table did not exists
|
||||
0 : OK. In this case *frmblob and *frmlen are set
|
||||
>0 : error. frmblob and frmlen may not be set
|
||||
@retval
|
||||
-1 Table did not exists
|
||||
@retval
|
||||
0 OK. In this case *frmblob and *frmlen are set
|
||||
@retval
|
||||
>0 error. frmblob and frmlen may not be set
|
||||
*/
|
||||
struct st_discover_args
|
||||
{
|
||||
@ -2821,9 +2827,9 @@ int ha_discover(THD *thd, const char *db, const char *name,
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
Call this function in order to give the handler the possibility
|
||||
to ask engine if there are any new tables that should be written to disk
|
||||
/**
|
||||
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
|
||||
or any dropped tables that need to be removed from disk
|
||||
*/
|
||||
struct st_find_files_args
|
||||
@ -2866,16 +2872,15 @@ ha_find_files(THD *thd,const char *db,const char *path,
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Ask handler if the table exists in engine
|
||||
|
||||
RETURN
|
||||
/**
|
||||
Ask handler if the table exists in engine.
|
||||
@retval
|
||||
HA_ERR_NO_SUCH_TABLE Table does not exist
|
||||
@retval
|
||||
HA_ERR_TABLE_EXIST Table exists
|
||||
# Error code
|
||||
|
||||
*/
|
||||
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
struct st_table_exists_in_engine_args
|
||||
{
|
||||
const char *db;
|
||||
@ -3050,29 +3055,29 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Read the first row of a multi-range set.
|
||||
|
||||
SYNOPSIS
|
||||
read_multi_range_first()
|
||||
found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||
range_count Number of ranges in 'ranges'.
|
||||
sorted If result should be sorted per key.
|
||||
buffer A HANDLER_BUFFER for internal handler usage.
|
||||
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
@param ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||
@param range_count Number of ranges in 'ranges'.
|
||||
@param sorted If result should be sorted per key.
|
||||
@param buffer A HANDLER_BUFFER for internal handler usage.
|
||||
|
||||
NOTES
|
||||
Record is read into table->record[0].
|
||||
*found_range_p returns a valid value only if read_multi_range_first()
|
||||
@note
|
||||
- Record is read into table->record[0].
|
||||
- *found_range_p returns a valid value only if read_multi_range_first()
|
||||
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.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK, found a row
|
||||
@retval
|
||||
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,
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
read_multi_range_next()
|
||||
found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
|
||||
NOTES
|
||||
Record is read into table->record[0].
|
||||
*found_range_p returns a valid value only if read_multi_range_next()
|
||||
@note
|
||||
- Record is read into table->record[0].
|
||||
- *found_range_p returns a valid value only if read_multi_range_next()
|
||||
returns 0.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK, found a row
|
||||
@retval
|
||||
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)
|
||||
{
|
||||
@ -3176,25 +3181,24 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
||||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
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
|
||||
read_range_first()
|
||||
start_key Start key. Is 0 if no min range
|
||||
end_key End key. Is 0 if no max range
|
||||
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
|
||||
@param start_key Start key. Is 0 if no min range
|
||||
@param end_key End key. Is 0 if no max range
|
||||
@param eq_range_arg Set to 1 if start_key == end_key
|
||||
@param sorted Set to 1 if result should be sorted per key
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Record is read into table->record[0]
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Found row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
int handler::read_range_first(const key_range *start_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.
|
||||
|
||||
SYNOPSIS
|
||||
read_range_next()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Record is read into table->record[0]
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Found row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
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
|
||||
compare_key
|
||||
range range to compare to row. May be 0 for no range
|
||||
|
||||
NOTES
|
||||
See key.cc::key_cmp() for details
|
||||
@param range range to compare to row. May be 0 for no range
|
||||
|
||||
RETURN
|
||||
@seealso
|
||||
key.cc::key_cmp()
|
||||
|
||||
@return
|
||||
The return value is SIGN(key_in_row - range_key):
|
||||
|
||||
0 Key is equal to range or 'range' == 0 (no range)
|
||||
-1 Key is less than range
|
||||
1 Key is larger than range
|
||||
- 0 : Key is equal to range or 'range' == 0 (no range)
|
||||
- -1 : Key is less than range
|
||||
- 1 : Key is larger than 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.
|
||||
|
||||
SYNOPSIS
|
||||
ha_known_exts()
|
||||
|
||||
NOTES
|
||||
No mutexes, worst case race is a minor surplus memory allocation
|
||||
We have to recreate the extension map if mysqld is restarted (for example
|
||||
within libmysqld)
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
pointer pointer to TYPELIB structure
|
||||
*/
|
||||
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
||||
|
@ -14,9 +14,14 @@
|
||||
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
|
||||
checked that they doesn't resemble an ip.
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Get hostname for an IP.
|
||||
|
||||
Hostnames are checked with reverse name lookup and
|
||||
checked that they doesn't resemble an ip.
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
@ -14,7 +14,12 @@
|
||||
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 <m_ctype.h>
|
||||
|
998
sql/item.cc
998
sql/item.cc
File diff suppressed because it is too large
Load Diff
@ -14,12 +14,17 @@
|
||||
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"
|
||||
|
||||
/*
|
||||
** 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)
|
||||
@ -45,9 +50,11 @@ Cached_item *new_Cached_item(THD *thd, Item *item)
|
||||
|
||||
Cached_item::~Cached_item() {}
|
||||
|
||||
/*
|
||||
** Compare with old value and replace value with new value
|
||||
** Return true if values have changed
|
||||
/**
|
||||
Compare with old value and replace value with new value.
|
||||
|
||||
@return
|
||||
Return true if values have changed
|
||||
*/
|
||||
|
||||
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
||||
|
@ -14,7 +14,12 @@
|
||||
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
|
||||
#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.
|
||||
|
||||
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
|
||||
supposed to be used later for comparison of values of these items.
|
||||
Aggregation itself is performed by the item_cmp_type() function.
|
||||
The function also checks compatibility of row signatures for the
|
||||
submitted items (see the spec for the cmp_row_type function).
|
||||
@param[out] type the aggregated type
|
||||
@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
|
||||
@retval
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
@ -257,10 +264,11 @@ void Item_func_not::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
special NOT for ALL subquery
|
||||
/**
|
||||
special NOT for ALL subquery.
|
||||
*/
|
||||
|
||||
|
||||
longlong Item_func_not_all::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
@ -293,10 +301,13 @@ void Item_func_not_all::print(String *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Special NOP (No OPeration) for ALL subquery it is like Item_func_not_all
|
||||
(return TRUE if underlying subquery do not return rows) but if subquery
|
||||
returns some rows it return same value as argument (TRUE/FALSE).
|
||||
/**
|
||||
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
|
||||
returns some rows it return same value as argument (TRUE/FALSE).
|
||||
*/
|
||||
|
||||
longlong Item_func_nop_all::val_int()
|
||||
@ -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.
|
||||
On successful conversion the original item is substituted for the
|
||||
result of the item evaluation.
|
||||
@ -333,16 +337,21 @@ longlong Item_func_nop_all::val_int()
|
||||
also when comparing bigint to strings (in which case strings
|
||||
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.
|
||||
As all derived tables are filled only after all derived tables
|
||||
are prepared we do not evaluate items with subselects here because
|
||||
they can contain derived tables and thus we may attempt to use a
|
||||
table that has not been populated yet.
|
||||
|
||||
RESULT VALUES
|
||||
0 Can't convert item
|
||||
1 Item was replaced with an integer version of the item
|
||||
@retval
|
||||
0 Can't convert item
|
||||
@retval
|
||||
1 Item was replaced with an integer version of the item
|
||||
*/
|
||||
|
||||
static bool convert_constant_item(THD *thd, Field *field, Item **item)
|
||||
@ -1013,13 +1022,15 @@ int Arg_comparator::compare_string()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare strings byte by byte. End spaces are also compared.
|
||||
|
||||
RETURN
|
||||
< 0 *a < *b
|
||||
0 *b == *b
|
||||
> 0 *a > *b
|
||||
@retval
|
||||
<0 *a < *b
|
||||
@retval
|
||||
0 *b == *b
|
||||
@retval
|
||||
>0 *a > *b
|
||||
*/
|
||||
|
||||
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()
|
||||
{
|
||||
String *res1,*res2;
|
||||
@ -1185,7 +1197,7 @@ int Arg_comparator::compare_int_signed()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare values as BIGINT UNSIGNED.
|
||||
*/
|
||||
|
||||
@ -1208,7 +1220,7 @@ int Arg_comparator::compare_int_unsigned()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare signed (*a) with unsigned (*B)
|
||||
*/
|
||||
|
||||
@ -1233,7 +1245,7 @@ int Arg_comparator::compare_int_signed_unsigned()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare unsigned (*a) with signed (*B)
|
||||
*/
|
||||
|
||||
@ -1269,7 +1281,7 @@ int Arg_comparator::compare_e_int()
|
||||
return test(val1 == val2);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
||||
*/
|
||||
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()
|
||||
{
|
||||
@ -1709,21 +1721,18 @@ void Item_func_interval::fix_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute Item_func_interval()
|
||||
/**
|
||||
Execute Item_func_interval().
|
||||
|
||||
SYNOPSIS
|
||||
Item_func_interval::val_int()
|
||||
@note
|
||||
If we are doing a decimal comparison, we are evaluating the first
|
||||
item twice.
|
||||
|
||||
NOTES
|
||||
If we are doing a decimal comparison, we are
|
||||
evaluating the first item twice.
|
||||
|
||||
RETURN
|
||||
-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
|
||||
@return
|
||||
- -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()
|
||||
@ -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
|
||||
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
|
||||
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
|
||||
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))
|
||||
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)))
|
||||
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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
|
||||
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
|
||||
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
|
||||
a predicate/function level. Then it's easy to show that:
|
||||
@verbatim
|
||||
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
||||
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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
|
||||
first argument.
|
||||
/**
|
||||
@note
|
||||
Note that we have to evaluate the first argument twice as the compare
|
||||
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
|
||||
@ -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
|
||||
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
|
||||
0, REAL_RESULT to bit 1, so on.
|
||||
|
||||
RETURN
|
||||
NULL - Nothing found and there is no ELSE expression defined
|
||||
item - Found item or ELSE item if defined and all comparisons are
|
||||
@retval
|
||||
NULL Nothing found and there is no ELSE expression defined
|
||||
@retval
|
||||
item Found item or ELSE item if defined and all comparisons are
|
||||
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)
|
||||
{
|
||||
@ -2687,7 +2694,7 @@ void Item_func_case::cleanup()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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
|
||||
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
|
||||
a predicate/function level. Then it's easy to show that:
|
||||
@verbatim
|
||||
T0(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)))
|
||||
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 got error
|
||||
*/
|
||||
|
||||
@ -3805,25 +3811,22 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
/**
|
||||
Transform an Item_cond object with a transformer callback function.
|
||||
|
||||
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
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_cond object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
of the Item_cond object.
|
||||
|
||||
@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 *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||
@ -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
|
||||
|
||||
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
|
||||
/**
|
||||
Compile Item_cond object with a processor and a transformer
|
||||
callback functions.
|
||||
|
||||
First the function applies the analyzer to the root node of
|
||||
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
||||
the function recursively applies the compile method to member
|
||||
@ -3872,9 +3866,16 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_cond object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
|
||||
@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 *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||
@ -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
|
||||
The split is done to get an unique item for each SUM function
|
||||
so that we can easily find and calculate them.
|
||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||
sql_select.cc)
|
||||
|
||||
NOTES
|
||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||
that have or refer (HAVING) to a SUM expression.
|
||||
@param thd Thread handler
|
||||
@param ref_pointer_array Pointer to array of reference fields
|
||||
@param fields All fields in select
|
||||
|
||||
The split is done to get an unique item for each SUM function
|
||||
so that we can easily find and calculate them.
|
||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||
sql_select.cc)
|
||||
@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,
|
||||
@ -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
|
||||
result is NULL or 0. This is set for:
|
||||
- WHERE clause
|
||||
- HAVING clause
|
||||
- IF(expression)
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 If all expressions are true
|
||||
@retval
|
||||
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
|
||||
*/
|
||||
|
||||
@ -4065,24 +4066,23 @@ longlong Item_cond_or::val_int()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Create an AND expression from two expressions
|
||||
/**
|
||||
Create an AND expression from two expressions.
|
||||
|
||||
SYNOPSIS
|
||||
and_expressions()
|
||||
a expression or NULL
|
||||
b expression.
|
||||
org_item Don't modify a if a == *org_item
|
||||
If a == NULL, org_item is set to point at b,
|
||||
to ensure that future calls will not modify b.
|
||||
@param a expression or NULL
|
||||
@param b expression.
|
||||
@param org_item Don't modify a if a == *org_item.
|
||||
If a == NULL, org_item is set to point at b,
|
||||
to ensure that future calls will not modify b.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
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
|
||||
'and' over all items without modifying any of the original items.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
NULL Error
|
||||
@retval
|
||||
Item
|
||||
*/
|
||||
|
||||
@ -4140,7 +4140,9 @@ longlong Item_is_not_null_test::val_int()
|
||||
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()
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -4463,10 +4467,9 @@ void Item_func_regex::cleanup()
|
||||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
turboBM_compute_suffixes()
|
||||
/**
|
||||
Precomputation dependent only on pattern_len.
|
||||
**********************************************************************/
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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()
|
||||
{
|
||||
@ -4594,10 +4595,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
turboBM_matches()
|
||||
Search for pattern in text, returns true/false for match/no match
|
||||
**********************************************************************/
|
||||
/**
|
||||
Search for pattern in text.
|
||||
|
||||
@return
|
||||
returns true/false for match/no match
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
val_int()
|
||||
|
||||
DESCRIPTION
|
||||
If either operator is NULL, return NULL.
|
||||
|
||||
NOTE
|
||||
As we don't do any index optimization on XOR this is not going to be
|
||||
very fast to use.
|
||||
|
||||
TODO (low priority)
|
||||
Change this to be optimized as:
|
||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
|
||||
@todo
|
||||
(low priority) Change this to be optimized as: @n
|
||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
|
||||
To be able to do this, we would however first have to extend the MySQL
|
||||
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()
|
||||
@ -4716,15 +4715,12 @@ longlong Item_cond_xor::val_int()
|
||||
return (longlong) result;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Apply NOT transformation to the item and return a new one.
|
||||
|
||||
SYNOPSIS
|
||||
neg_transformer()
|
||||
thd thread handler
|
||||
|
||||
DESCRIPTION
|
||||
Transform the item using next rules:
|
||||
@verbatim
|
||||
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
||||
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
||||
NOT(a) -> a
|
||||
@ -4736,8 +4732,11 @@ longlong Item_cond_xor::val_int()
|
||||
a <= b -> a > b
|
||||
IS NULL(a) -> IS NOT NULL(a)
|
||||
IS NOT NULL(a) -> IS NULL(a)
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@param thd thread handler
|
||||
|
||||
@return
|
||||
New item or
|
||||
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= 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= 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]);
|
||||
}
|
||||
|
||||
// just fake method, should never be called
|
||||
/**
|
||||
just fake method, should never be called.
|
||||
*/
|
||||
Item *Item_bool_rowready_func2::negated_item()
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
@ -4911,19 +4916,17 @@ 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
|
||||
contains()
|
||||
field field whose occurrence is to be checked
|
||||
|
||||
DESCRIPTION
|
||||
The function checks whether field is occurred in the Item_equal object
|
||||
|
||||
RETURN VALUES
|
||||
The function checks whether field is occurred in the Item_equal object .
|
||||
|
||||
@param field field whose occurrence is to be checked
|
||||
|
||||
@retval
|
||||
1 if nultiple equality contains a reference to field
|
||||
0 otherwise
|
||||
@retval
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
bool Item_equal::contains(Field *field)
|
||||
@ -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.
|
||||
After this operation the Item_equal object additionally contains
|
||||
the field items of another item of the type Item_equal.
|
||||
If the optional constant items are not equal the cond_false flag is
|
||||
set to 1.
|
||||
|
||||
RETURN VALUES
|
||||
none
|
||||
@param item multiple equality whose members are to be joined
|
||||
*/
|
||||
|
||||
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
|
||||
object according to the criteria determined by the cmp callback parameter.
|
||||
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
||||
placed after item_fiel2.
|
||||
|
||||
IMPLEMENTATION
|
||||
The function sorts field items by the exchange sort algorithm.
|
||||
The list of field items is looked through and whenever two neighboring
|
||||
members follow in a wrong order they are swapped. This is performed
|
||||
again and again until we get all members in a right order.
|
||||
|
||||
RETURN VALUES
|
||||
None
|
||||
|
||||
@param cmp function to compare field item
|
||||
@param arg context extra parameter for the cmp function
|
||||
*/
|
||||
|
||||
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 members of multiple equalities. Each new constant item is
|
||||
compared with the designated constant item if there is any in the
|
||||
multiple equality. If there is none the first new constant item
|
||||
becomes designated.
|
||||
|
||||
RETURN VALUES
|
||||
none
|
||||
*/
|
||||
|
||||
void Item_equal::update_const()
|
||||
|
@ -13,7 +13,12 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
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 "item_create.h"
|
||||
|
297
sql/item_func.cc
297
sql/item_func.cc
@ -14,7 +14,12 @@
|
||||
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
|
||||
#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
|
||||
eval_const_cond(COND *cond)
|
||||
@ -237,25 +245,21 @@ void Item_func::traverse_cond(Cond_traverser traverser,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
/**
|
||||
Transform an Item_func object with a transformer callback function.
|
||||
|
||||
The function recursively applies the transform method to each
|
||||
argument of the Item_func node.
|
||||
If the call of the method for an argument item returns a new item
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_func object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
@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
|
||||
Item returned as the result of transformation of the root node
|
||||
*/
|
||||
|
||||
Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||
@ -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
|
||||
|
||||
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
|
||||
/**
|
||||
Compile Item_func object with a processor and a transformer
|
||||
callback functions.
|
||||
|
||||
First the function applies the analyzer to the root node of
|
||||
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
||||
the function recursively applies the compile method to each argument
|
||||
@ -306,9 +301,16 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_func object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
|
||||
@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 *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||
@ -334,7 +336,9 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||
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,
|
||||
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
|
||||
result length/precision depends on argument ones
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_decimal_length()
|
||||
result length/precision depends on argument ones.
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_only_length()
|
||||
/**
|
||||
Set max_length of if it is maximum length of its arguments.
|
||||
*/
|
||||
|
||||
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
|
||||
result length/precision depends on argument ones
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_real_length()
|
||||
result length/precision depends on argument ones.
|
||||
*/
|
||||
|
||||
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
|
||||
function of two arguments.
|
||||
|
||||
SYNOPSIS
|
||||
Item_num_op::find_num_type()
|
||||
*/
|
||||
|
||||
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
|
||||
(can be also used by a numeric function of many arguments, if the result
|
||||
type depends only on the first argument)
|
||||
|
||||
SYNOPSIS
|
||||
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
|
||||
decimal_op()
|
||||
decimal_value Buffer that can be used to store result
|
||||
@param decimal_value Buffer that can be used to store result
|
||||
|
||||
RETURN
|
||||
0 Value was NULL; In this case null_value is set
|
||||
# Value of operation as a decimal
|
||||
@retval
|
||||
0 Value was NULL; In this case null_value is set
|
||||
@retval
|
||||
\# Value of operation as a decimal
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Set precision of results for additive operations (+ and -)
|
||||
|
||||
SYNOPSIS
|
||||
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
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -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()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
@ -1585,10 +1572,11 @@ double Item_func_ln::val_real()
|
||||
return log(value);
|
||||
}
|
||||
|
||||
/*
|
||||
Extended but so slower LOG function
|
||||
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.
|
||||
/**
|
||||
Extended but so slower LOG function.
|
||||
|
||||
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.
|
||||
*/
|
||||
double Item_func_log::val_real()
|
||||
{
|
||||
@ -3014,8 +3002,10 @@ bool udf_handler::get_arguments()
|
||||
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)
|
||||
{
|
||||
uchar is_null_tmp=0;
|
||||
@ -3219,10 +3209,11 @@ String *Item_func_udf_str::val_str(String *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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.)
|
||||
*/
|
||||
/**
|
||||
@note
|
||||
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.)
|
||||
*/
|
||||
|
||||
udf_handler::~udf_handler()
|
||||
{
|
||||
@ -3320,10 +3311,10 @@ void item_user_lock_release(User_level_lock *ull)
|
||||
delete ull;
|
||||
}
|
||||
|
||||
/*
|
||||
Wait until we are at or past the given position in the master binlog
|
||||
on the slave
|
||||
*/
|
||||
/**
|
||||
Wait until we are at or past the given position in the master binlog
|
||||
on the slave.
|
||||
*/
|
||||
|
||||
longlong Item_master_pos_wait::val_int()
|
||||
{
|
||||
@ -3425,11 +3416,15 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Get a user level lock. If the thread has an old lock this is first released.
|
||||
Returns 1: Got lock
|
||||
Returns 0: Timeout
|
||||
Returns NULL: Error
|
||||
/**
|
||||
Get a user level lock. If the thread has an old lock this is first released.
|
||||
|
||||
@retval
|
||||
1 : Got lock
|
||||
@retval
|
||||
0 : Timeout
|
||||
@retval
|
||||
NULL : Error
|
||||
*/
|
||||
|
||||
longlong Item_func_get_lock::val_int()
|
||||
@ -3549,12 +3544,12 @@ longlong Item_func_get_lock::val_int()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Release a user level lock.
|
||||
Return:
|
||||
1 if lock released
|
||||
0 if lock wasn't held
|
||||
(SQL) NULL if no such lock
|
||||
@return
|
||||
- 1 if lock released
|
||||
- 0 if lock wasn't held
|
||||
- (SQL) NULL if no such lock
|
||||
*/
|
||||
|
||||
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()
|
||||
{
|
||||
@ -3835,22 +3830,22 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set value to user variable.
|
||||
|
||||
SYNOPSYS
|
||||
update_hash()
|
||||
entry - pointer to structure representing variable
|
||||
set_null - should we set NULL value ?
|
||||
ptr - pointer to buffer with new value
|
||||
length - length of new value
|
||||
type - type of new value
|
||||
cs - charset info for new value
|
||||
dv - derivation for new value
|
||||
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
|
||||
@param entry pointer to structure representing variable
|
||||
@param set_null should we set NULL value ?
|
||||
@param ptr pointer to buffer with new value
|
||||
@param length length of new value
|
||||
@param type type of new value
|
||||
@param cs charset info for new value
|
||||
@param dv derivation for new value
|
||||
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||
|
||||
RETURN VALUE
|
||||
False - success, True - failure
|
||||
@retval
|
||||
false success
|
||||
@retval
|
||||
true failure
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -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,
|
||||
uint decimals)
|
||||
@ -4025,7 +4020,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *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)
|
||||
{
|
||||
@ -4052,18 +4047,17 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *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.
|
||||
|
||||
SYNOPSYS
|
||||
Item_func_set_user_var::check()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
For now it always return OK. All problem with value evaluating
|
||||
will be caught by thd->net.report_error check in sql_set_variables().
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
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
|
||||
Item_func_set_user_var::update()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
We have to store the expression as such in the variable, independent of
|
||||
the value method used by the user
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
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
|
||||
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),
|
||||
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
|
||||
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
|
||||
@retval
|
||||
1 Failed to put appropriate record into binary log
|
||||
|
||||
*/
|
||||
@ -5104,22 +5096,20 @@ longlong Item_func_bit_xor::val_int()
|
||||
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
|
||||
get_system_var()
|
||||
thd Thread handler
|
||||
var_type global / session
|
||||
name Name of base or system variable
|
||||
component Component
|
||||
@param thd Thread handler
|
||||
@param var_type global / session
|
||||
@param name Name of base or system variable
|
||||
@param component Component.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If component.str = 0 then the variable name is in 'name'
|
||||
|
||||
RETURN
|
||||
0 error
|
||||
# constant item
|
||||
@return
|
||||
- 0 : error
|
||||
- # : 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.
|
||||
|
||||
SYNOPSIS:
|
||||
val_int()
|
||||
Sets null_value=TRUE on error.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 Available
|
||||
0 Already taken
|
||||
NULL Error
|
||||
@retval
|
||||
0 Already taken, or error
|
||||
*/
|
||||
|
||||
longlong Item_func_is_free_lock::val_int()
|
||||
|
@ -14,7 +14,12 @@
|
||||
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
|
||||
#pragma implementation // gcc: Class implementation
|
||||
@ -360,7 +365,7 @@ String *Item_func_point::val_str(String *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Concatenates various items into various collections
|
||||
with checkings for valid wkb type of items.
|
||||
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()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
@ -15,13 +15,18 @@
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
||||
/*
|
||||
/**
|
||||
Row items used for comparing rows and IN operations on rows:
|
||||
|
||||
@verbatim
|
||||
(a, b, c) > (10, 10, 30)
|
||||
(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 (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):
|
||||
|
@ -14,9 +14,15 @@
|
||||
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
|
||||
** (This shouldn't be needed)
|
||||
/**
|
||||
@file
|
||||
|
||||
@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
|
||||
@ -297,9 +303,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
|
||||
@ -430,13 +436,15 @@ void Item_func_concat::fix_length_and_dec()
|
||||
max_length= (ulong) max_result_length;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
Function des_encrypt() by tonu@spam.ee & monty
|
||||
Works only if compiled with OpenSSL library support.
|
||||
This returns a binary string where first character is CHAR(128 | key-number).
|
||||
If one uses a string key key_number is 127.
|
||||
Encryption result is longer than original by formula:
|
||||
new_length= org_length + (8-(org_length % 8))+1
|
||||
@return
|
||||
A binary string where first character is CHAR(128 | key-number).
|
||||
If one uses a string key key_number is 127.
|
||||
Encryption result is longer than original by formula:
|
||||
@code new_length= org_length + (8-(org_length % 8))+1 @endcode
|
||||
*/
|
||||
|
||||
String *Item_func_des_encrypt::val_str(String *str)
|
||||
@ -609,7 +617,7 @@ wrong_key:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
concat with separator. First arg is the separator
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
** Replace all occurences of string2 in string1 with string3.
|
||||
** Don't reallocate val_str() if not needed
|
||||
*/
|
||||
/**
|
||||
Replace all occurences of string2 in string1 with string3.
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -1837,7 +1848,7 @@ void Item_func_soundex::fix_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
If alpha, map input letter to soundex code.
|
||||
If not alpha and remove_garbage is set then skip to next char
|
||||
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'
|
||||
** This should be 'internationalized' sometimes.
|
||||
/**
|
||||
Change a number to format '3,333,333,333.000'.
|
||||
|
||||
This should be 'internationalized' sometimes.
|
||||
*/
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
@ -2349,9 +2362,9 @@ void Item_func_repeat::fix_length_and_dec()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Item_func_repeat::str is carefully written to avoid reallocs
|
||||
** as much as possible at the cost of a local buffer
|
||||
/**
|
||||
Item_func_repeat::str is carefully written to avoid reallocs
|
||||
as much as possible at the cost of a local buffer
|
||||
*/
|
||||
|
||||
String *Item_func_repeat::val_str(String *str)
|
||||
@ -2827,7 +2840,7 @@ String *Item_func_hex::val_str(String *str)
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
using in a SQL statement.
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
running commands from a file in windows.
|
||||
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
|
||||
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).
|
||||
|
||||
RETURN VALUES
|
||||
str Quoted string
|
||||
NULL Out of memory.
|
||||
@retval
|
||||
str Quoted string
|
||||
@retval
|
||||
NULL Out of memory.
|
||||
*/
|
||||
|
||||
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
||||
|
||||
String *Item_func_quote::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
@ -3326,8 +3339,10 @@ static uint nanoseq;
|
||||
static ulonglong uuid_time=0;
|
||||
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_VERSION 0x1000
|
||||
|
@ -13,12 +13,15 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
subselect Item
|
||||
/**
|
||||
@file
|
||||
|
||||
SUBSELECT TODO:
|
||||
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
||||
(sql_select.h/sql_select.cc)
|
||||
@brief
|
||||
subselect Item
|
||||
|
||||
@todo
|
||||
- add function from mysql_select that use JOIN* as parameter to JOIN
|
||||
methods (sql_select.h/sql_select.cc)
|
||||
*/
|
||||
|
||||
#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_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
|
||||
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
|
||||
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
|
||||
underlying transformation methods.
|
||||
|
||||
RETURN
|
||||
@param join JOIN object of transforming subquery
|
||||
@param func creator of condition function of subquery
|
||||
|
||||
@retval
|
||||
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
|
||||
*/
|
||||
|
||||
@ -2412,16 +2425,15 @@ void subselect_indexsubquery_engine::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
change select_result object of engine
|
||||
/**
|
||||
change select_result object of engine.
|
||||
|
||||
SYNOPSIS
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
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
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
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
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
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
|
||||
subselect_single_select_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
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
|
||||
subselect_union_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
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
|
||||
subselect_uniquesubquery_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
|
||||
|
153
sql/item_sum.cc
153
sql/item_sum.cc
@ -14,7 +14,12 @@
|
||||
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
|
||||
#pragma implementation // gcc: Class implementation
|
||||
@ -23,28 +28,25 @@
|
||||
#include "mysql_priv.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
|
||||
for a set function that are used to check validity of the set function
|
||||
occurrence.
|
||||
If the set function is not allowed in any subquery where it occurs
|
||||
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
|
||||
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 descent of this traversal.
|
||||
|
||||
RETURN
|
||||
TRUE if an error is reported
|
||||
@retval
|
||||
TRUE if an error is reported
|
||||
@retval
|
||||
FALSE otherwise
|
||||
*/
|
||||
|
||||
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
||||
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
|
||||
of any set function are met for this occurrence.
|
||||
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
|
||||
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
|
||||
conditions. They are specified in the comment before the Item_sum
|
||||
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
|
||||
in the HAVING clause of the corresponding subquery)
|
||||
Consider the query:
|
||||
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
|
||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
||||
@code
|
||||
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
|
||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
||||
@endcode
|
||||
allow_sum_func will contain:
|
||||
for SUM(t1.b) - 1 at the first 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 SUM(t1.b) - 1 at the first 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.
|
||||
|
||||
RETURN
|
||||
TRUE if an error is reported
|
||||
@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
|
||||
@retval
|
||||
FALSE otherwise
|
||||
*/
|
||||
|
||||
@ -200,15 +201,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
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
|
||||
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
|
||||
@ -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
|
||||
there the field 'ref_by' is set to ref.
|
||||
|
||||
NOTES.
|
||||
@note
|
||||
Now we 'register' only set functions that are aggregated in outer
|
||||
subqueries. Actually it makes sense to link all set function for
|
||||
a subquery in one chain. It would simplify the process of 'splitting'
|
||||
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)
|
||||
@retval
|
||||
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):
|
||||
@ -655,6 +654,10 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
|
||||
** 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_num(thd, item), hybrid_type(item->hybrid_type),
|
||||
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().
|
||||
Additionally div() converts val with this traits to a val with true
|
||||
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)
|
||||
{
|
||||
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()
|
||||
@ -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
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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()
|
||||
{
|
||||
@ -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()
|
||||
{
|
||||
@ -2851,9 +2865,8 @@ String *Item_sum_udf_str::val_str(String *str)
|
||||
Blobs doesn't work with DISTINCT or ORDER BY
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
function of sort for syntax:
|
||||
GROUP_CONCAT(DISTINCT expr,...)
|
||||
/**
|
||||
function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...)
|
||||
*/
|
||||
|
||||
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:
|
||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||
/**
|
||||
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||
*/
|
||||
|
||||
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:
|
||||
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
|
||||
is not part of the field list because tree-insert will not notice
|
||||
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)),
|
||||
@ -3025,12 +3037,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Constructor of Item_func_group_concat
|
||||
distinct_arg - distinct
|
||||
select_list - list of expression for show values
|
||||
order_list - list of sort columns
|
||||
separator_arg - string value of separator
|
||||
/**
|
||||
Constructor of Item_func_group_concat.
|
||||
|
||||
@param distinct_arg distinct
|
||||
@param select_list list of expression for show values
|
||||
@param order_list list of sort columns
|
||||
@param separator_arg string value of separator.
|
||||
*/
|
||||
|
||||
Item_func_group_concat::
|
||||
|
@ -14,7 +14,15 @@
|
||||
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
|
||||
#pragma implementation // gcc: Class implementation
|
||||
@ -24,17 +32,16 @@
|
||||
#include <m_ctype.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
|
||||
|
||||
/*
|
||||
OPTIMIZATION TODO:
|
||||
- Replace the switch with a function that should be called for each
|
||||
date type.
|
||||
- Remove sprintf and opencode the conversion, like we do in
|
||||
Field_datetime.
|
||||
/**
|
||||
@todo
|
||||
OPTIMIZATION
|
||||
- Replace the switch with a function that should be called for each
|
||||
date type.
|
||||
- Remove sprintf and opencode the conversion, like we do in
|
||||
Field_datetime.
|
||||
|
||||
The reason for this functions existence is that as we don't have a
|
||||
way to know if a datetime/time value has microseconds in them
|
||||
@ -226,37 +233,37 @@ static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0,
|
||||
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
||||
{(char *)"%H:%i:%S", 8}};
|
||||
|
||||
/*
|
||||
/**
|
||||
Extract datetime value to MYSQL_TIME struct from string value
|
||||
according to format string.
|
||||
according to format string.
|
||||
|
||||
SYNOPSIS
|
||||
extract_date_time()
|
||||
format date/time format specification
|
||||
val String to decode
|
||||
length Length of string
|
||||
l_time Store result here
|
||||
cached_timestamp_type
|
||||
It uses to get an appropriate warning
|
||||
in the case when the value is truncated.
|
||||
sub_pattern_end if non-zero then we are parsing string which
|
||||
should correspond compound specifier (like %T or
|
||||
%r) and this parameter is pointer to place where
|
||||
pointer to end of string matching this specifier
|
||||
should be stored.
|
||||
NOTE
|
||||
Possibility to parse strings matching to patterns equivalent to compound
|
||||
specifiers is mainly intended for use from inside of this function in
|
||||
order to understand %T and %r conversion specifiers, so number of
|
||||
conversion specifiers that can be used in such sub-patterns is limited.
|
||||
Also most of checks are skipped in this case.
|
||||
@param format date/time format specification
|
||||
@param val String to decode
|
||||
@param length Length of string
|
||||
@param l_time Store result here
|
||||
@param cached_timestamp_type It uses to get an appropriate warning
|
||||
in the case when the value is truncated.
|
||||
@param sub_pattern_end if non-zero then we are parsing string which
|
||||
should correspond compound specifier (like %T or
|
||||
%r) and this parameter is pointer to place where
|
||||
pointer to end of string matching this specifier
|
||||
should be stored.
|
||||
|
||||
If one adds new format specifiers to this function he should also
|
||||
consider adding them to get_date_time_result_type() function.
|
||||
@note
|
||||
Possibility to parse strings matching to patterns equivalent to compound
|
||||
specifiers is mainly intended for use from inside of this function in
|
||||
order to understand %T and %r conversion specifiers, so number of
|
||||
conversion specifiers that can be used in such sub-patterns is limited.
|
||||
Also most of checks are skipped in this case.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
@note
|
||||
If one adds new format specifiers to this function he should also
|
||||
consider adding them to get_date_time_result_type() function.
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
@ -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,
|
||||
@ -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.
|
||||
Each number is separated by 1 non digit character
|
||||
Return error if there is too many numbers.
|
||||
@ -846,16 +854,14 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
str: string value
|
||||
length: length of str
|
||||
cs: charset of str
|
||||
values: array of results
|
||||
count: count of elements in result array
|
||||
transform_msec: if value is true we suppose
|
||||
that the last part of string value is microseconds
|
||||
and we should transform value to six digit value.
|
||||
For example, '1.1' -> '1.100000'
|
||||
@param length: length of str
|
||||
@param cs: charset of str
|
||||
@param values: array of results
|
||||
@param count: count of elements in result array
|
||||
@param transform_msec: if value is true we suppose
|
||||
that the last part of string value is microseconds
|
||||
and we should transform value to six digit value.
|
||||
For example, '1.1' -> '1.100000'
|
||||
*/
|
||||
|
||||
static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
@ -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()
|
||||
{
|
||||
@ -1072,8 +1080,10 @@ longlong Item_func_minute::val_int()
|
||||
(void) get_arg0_time(<ime);
|
||||
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()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
|
||||
return week_format;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
@verbatim
|
||||
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
|
||||
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;
|
||||
Otherwise it is the last week of the previous year, and the
|
||||
next week is week 1.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
MAKEDATE(a,b) is a date function that creates a date 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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
||||
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
|
||||
time value between a start and end time.
|
||||
|
||||
@ -2874,7 +2887,7 @@ null_date:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
MAKETIME(h,m,s) is a time function that calculates a time value
|
||||
from the total number of hours, minutes, and seconds.
|
||||
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
|
||||
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
|
||||
according to format string.
|
||||
|
||||
SYNOPSIS
|
||||
get_date_time_result_type()
|
||||
format - format string
|
||||
length - length of format string
|
||||
@param format format string
|
||||
@param length length of format string
|
||||
|
||||
NOTE
|
||||
@note
|
||||
We don't process day format's characters('D', 'd', 'e') because day
|
||||
may be a member of all date/time types.
|
||||
|
||||
@note
|
||||
Format specifiers supported by this function should be in sync with
|
||||
specifiers supported by extract_date_time() function.
|
||||
|
||||
RETURN VALUE
|
||||
@return
|
||||
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
|
||||
|
86
sql/key.cc
86
sql/key.cc
@ -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.
|
||||
|
||||
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
|
||||
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
|
||||
key into to_key. If length == 0 then copy all bytes from the record that
|
||||
form a key.
|
||||
|
||||
RETURN
|
||||
None
|
||||
@param to_key buffer that will be used as a key
|
||||
@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,
|
||||
@ -163,22 +157,16 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
when we want to return a key as a result row.
|
||||
|
||||
RETURN
|
||||
None
|
||||
@param to_record record buffer where the key will be restored to
|
||||
@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,
|
||||
@ -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
|
||||
key_cmp_if_same()
|
||||
table TABLE
|
||||
key key to compare to row
|
||||
idx Index used
|
||||
key_length Length of key
|
||||
@param table TABLE
|
||||
@param key key to compare to row
|
||||
@param idx Index used
|
||||
@param key_length Length of key
|
||||
|
||||
NOTES
|
||||
@note
|
||||
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
|
||||
larger or smaller than the previous value) we can do things a bit
|
||||
faster by using memcmp() instead.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 If key is equal
|
||||
@retval
|
||||
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
|
||||
key_unpack()
|
||||
This is used mainly to get a good error message. We temporary
|
||||
change the column bitmap so that all columns are readable.
|
||||
|
||||
@param
|
||||
to Store value here in an easy to read form
|
||||
@param
|
||||
table Table to use
|
||||
@param
|
||||
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)
|
||||
@ -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
|
||||
key_cmp()
|
||||
key_part Key part handler
|
||||
key Key to compare to value in table->record[0]
|
||||
key_length length of 'key'
|
||||
@param key_part Key part handler
|
||||
@param key Key to compare to value in table->record[0]
|
||||
@param key_length length of 'key'
|
||||
|
||||
RETURN
|
||||
@return
|
||||
The return value is SIGN(key_in_row - range_key):
|
||||
|
||||
0 Key is equal to range or 'range' == 0 (no range)
|
||||
-1 Key is less than range
|
||||
1 Key is larger than range
|
||||
- 0 Key is equal to range or 'range' == 0 (no range)
|
||||
- -1 Key is less than range
|
||||
- 1 Key is larger than range
|
||||
*/
|
||||
|
||||
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
||||
|
217
sql/lock.cc
217
sql/lock.cc
@ -14,8 +14,11 @@
|
||||
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
|
||||
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.
|
||||
@ -65,7 +68,7 @@
|
||||
excluding one that caused failure. That means handler must cleanup itself
|
||||
in case external_lock() fails.
|
||||
|
||||
TODO:
|
||||
@todo
|
||||
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
*/
|
||||
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
@ -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
|
||||
mysql_lock_abort_for_thread()
|
||||
thd Thread handler
|
||||
table Table that should be removed from lock queue
|
||||
@param thd Thread handler
|
||||
@param table Table that should be removed from lock queue
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Table was not locked by another thread
|
||||
@retval
|
||||
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.
|
||||
|
||||
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.
|
||||
Temporary tables are ignored here like they are ignored in
|
||||
get_lock_data(). If we allow two opens on temporary tables later,
|
||||
both functions should be checked.
|
||||
|
||||
NOTE
|
||||
@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.
|
||||
|
||||
Temporary tables are ignored here like they are ignored in
|
||||
get_lock_data(). If we allow two opens on temporary tables later,
|
||||
both functions should be checked.
|
||||
|
||||
RETURN
|
||||
NULL No duplicate lock found.
|
||||
! NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||
@retval
|
||||
NULL No duplicate lock found.
|
||||
@retval
|
||||
!NULL First table from 'haystack' that matches a lock on '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)
|
||||
{
|
||||
@ -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
|
||||
get_lock_data()
|
||||
thd Thread handler
|
||||
table_ptr Pointer to tables that should be locks
|
||||
flags One of:
|
||||
GET_LOCK_UNLOCK: If we should send TL_IGNORE to
|
||||
store lock
|
||||
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
|
||||
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||
@param thd Thread handler
|
||||
@param table_ptr Pointer to tables that should be locks
|
||||
@param flags One of:
|
||||
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
|
||||
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
|
||||
@param 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,
|
||||
uint flags, TABLE **write_lock_used)
|
||||
{
|
||||
@ -893,31 +891,25 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Reset lock type in lock data.
|
||||
|
||||
SYNOPSIS
|
||||
reset_lock_data()
|
||||
sql_lock The MySQL lock.
|
||||
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
|
||||
cases:
|
||||
-# Locking error in lock_external() due to InnoDB timeout.
|
||||
-# Locking error in get_lock_data() due to missing write permission.
|
||||
-# Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
cache, they could be reused with the non-zero lock type set. This
|
||||
could lead to ignoring a different lock type with the next lock.
|
||||
|
||||
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
|
||||
cases: 1. Locking error in lock_external() due to InnoDB timeout.
|
||||
2. Locking error in get_lock_data() due to missing write permission.
|
||||
3. Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||
Clear the lock type of all lock data. This ensures that the next
|
||||
lock request will set its lock type properly.
|
||||
|
||||
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
|
||||
cache, they could be reused with the non-zero lock type set. This
|
||||
could lead to ignoring a different lock type with the next lock.
|
||||
|
||||
Clear the lock type of all lock data. This ensures that the next
|
||||
lock request will set its lock type properly.
|
||||
|
||||
RETURN
|
||||
void
|
||||
@param sql_lock The MySQL 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
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
Lock and wait for the named lock.
|
||||
|
||||
SYNOPSIS
|
||||
lock_and_wait_for_table_name()
|
||||
thd Thread handler
|
||||
table_list Lock first table in this list
|
||||
@param thd Thread handler
|
||||
@param table_list Lock first table in this list
|
||||
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Works together with global read lock.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
@ -982,30 +973,30 @@ end:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Put a not open table with an old refresh version in the table cache.
|
||||
|
||||
SYNPOSIS
|
||||
lock_table_name()
|
||||
thd Thread handler
|
||||
table_list Lock first table in this list
|
||||
check_in_use Do we need to check if table already in use by us
|
||||
@param thd Thread handler
|
||||
@param table_list Lock first table in this list
|
||||
@param 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
|
||||
lock_and_wait_for_table_name instead of this function as this works
|
||||
together with 'FLUSH TABLES WITH READ LOCK'
|
||||
|
||||
NOTES
|
||||
@note
|
||||
This will force any other threads that uses the table to release it
|
||||
as soon as possible.
|
||||
|
||||
REQUIREMENTS
|
||||
One must have a lock on LOCK_open !
|
||||
|
||||
RETURN:
|
||||
@return
|
||||
< 0 error
|
||||
@return
|
||||
== 0 table locked
|
||||
@return
|
||||
> 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
|
||||
lock_table_names()
|
||||
thd Thread handle
|
||||
table_list Names of tables to lock
|
||||
REQUIREMENTS
|
||||
- One must have a lock on LOCK_open when calling this
|
||||
|
||||
NOTES
|
||||
@param thd Thread handle
|
||||
@param table_list Names of tables to lock
|
||||
|
||||
@note
|
||||
If you are just locking one table, you should use
|
||||
lock_and_wait_for_table_name().
|
||||
|
||||
REQUIREMENTS
|
||||
One must have a lock on LOCK_open when calling this
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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.
|
||||
|
||||
@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,
|
||||
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.
|
||||
@ -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] 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] key
|
||||
@ -1245,23 +1236,27 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Unlock all tables in list with a name lock
|
||||
/**
|
||||
Unlock all tables in list with a name lock.
|
||||
|
||||
SYNOPSIS
|
||||
unlock_table_names()
|
||||
@param
|
||||
thd Thread handle
|
||||
@param
|
||||
table_list Names of tables to unlock
|
||||
@param
|
||||
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.
|
||||
|
||||
@note
|
||||
This function will broadcast refresh signals to inform other threads
|
||||
that the name locks are removed.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
broadcast_refresh()
|
||||
void No parameters.
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
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
|
||||
both conditions at the same time.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
When signalling COND_global_read_lock within the global read lock
|
||||
handling, it is not necessary to also signal COND_refresh.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
void broadcast_refresh(void)
|
||||
|
446
sql/log.cc
446
sql/log.cc
@ -14,8 +14,15 @@
|
||||
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 "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::
|
||||
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
|
||||
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
|
||||
init error log.
|
||||
*/
|
||||
@ -1466,9 +1473,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE: how do we handle this (unlikely but legal) case:
|
||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
||||
/**
|
||||
@note
|
||||
How do we handle this (unlikely but legal) case:
|
||||
@verbatim
|
||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
||||
@endverbatim
|
||||
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
|
||||
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__ */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Find a uniq filename for 'filename.#'.
|
||||
** Set # to a number as low as possible
|
||||
** returns != 0 if not possible to get uniq filename
|
||||
****************************************************************************/
|
||||
/**
|
||||
Find a unique filename for '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)
|
||||
{
|
||||
@ -1833,7 +1846,7 @@ void MYSQL_LOG::close(uint exiting)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* this is called only once */
|
||||
/** This is called only once. */
|
||||
|
||||
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 *suffix,
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
- 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
|
||||
on LOCK_log and LOCK_index.
|
||||
on LOCK_log and LOCK_index.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
@ -2440,24 +2458,20 @@ int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
|
||||
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
|
||||
make things slower and more complicated.
|
||||
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
|
||||
*/
|
||||
|
||||
@ -2498,25 +2512,25 @@ err:
|
||||
|
||||
#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
|
||||
find_log_pos()
|
||||
linfo Store here the found log file name and position to
|
||||
the NEXT log file name in the index file.
|
||||
log_name Filename to find in the index file.
|
||||
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
|
||||
lock on LOCK_index
|
||||
@param linfo Store here the found log file name and position to
|
||||
the NEXT log file name 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
|
||||
@param need_lock Set this to 1 if the parent doesn't already have a
|
||||
lock on LOCK_index
|
||||
|
||||
NOTE
|
||||
@note
|
||||
On systems without the truncate function the file will end with one or
|
||||
more empty lines. These will be ignored when reading the file.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
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
|
||||
find_next_log()
|
||||
@param
|
||||
linfo Store here the next log file name and position to
|
||||
the file name after that.
|
||||
@param
|
||||
need_lock Set this to 1 if the parent doesn't already have a
|
||||
lock on LOCK_index
|
||||
|
||||
NOTE
|
||||
@note
|
||||
- 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
|
||||
from under our feet
|
||||
from under our feet
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_IO Got IO error while reading file
|
||||
*/
|
||||
|
||||
@ -2624,21 +2640,20 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete all logs refered to in the index file
|
||||
Start writing to a new log file. The new index file will only contain
|
||||
this file.
|
||||
/**
|
||||
Delete all logs refered to in the index file.
|
||||
Start writing to a new log file.
|
||||
|
||||
SYNOPSIS
|
||||
reset_logs()
|
||||
thd Thread
|
||||
The new index file will only contain this file.
|
||||
|
||||
NOTE
|
||||
@param thd Thread
|
||||
|
||||
@note
|
||||
If not called from slave thread, write start event to new log
|
||||
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
@ -2702,38 +2717,40 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Delete relay log files prior to rli->group_relay_log_name
|
||||
(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.
|
||||
|
||||
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).
|
||||
(transaction)), remove them from the index file and start on next
|
||||
relay log.
|
||||
|
||||
IMPLEMENTATION
|
||||
- Protects index file with LOCK_index
|
||||
- Delete relevant relay log files
|
||||
- Copy all file names after these ones to the front of the index file
|
||||
- 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
|
||||
- Protects index file with LOCK_index
|
||||
- Delete relevant relay log files
|
||||
- Copy all file names after these ones to the front of the index file
|
||||
- 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
|
||||
|
||||
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
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_SEEK Could not allocate IO cache
|
||||
@retval
|
||||
LOG_INFO_IO Got IO error while reading file
|
||||
*/
|
||||
|
||||
@ -2811,8 +2828,8 @@ err:
|
||||
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)
|
||||
@ -2826,25 +2843,24 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Remove all logs before the given log from disk and from the index file.
|
||||
|
||||
SYNOPSIS
|
||||
purge_logs()
|
||||
to_log Delete all log file name before this file.
|
||||
included If true, to_log is deleted too.
|
||||
need_mutex
|
||||
need_update_threads If we want to update the log coordinates of
|
||||
all threads. False for relay logs, true otherwise.
|
||||
freed_log_space If not null, decrement this variable of
|
||||
the amount of log space freed
|
||||
@param to_log Delete all log file name before this file.
|
||||
@param included If true, to_log is deleted too.
|
||||
@param need_mutex
|
||||
@param need_update_threads If we want to update the log coordinates of
|
||||
all threads. False for relay logs, true otherwise.
|
||||
@param freed_log_space If not null, decrement this variable of
|
||||
the amount of log space freed
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If any of the logs before the deleted one is in use,
|
||||
only purge logs up to this one.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
LOG_INFO_EOF to_log not found
|
||||
*/
|
||||
|
||||
@ -2928,21 +2944,20 @@ err:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Remove all logs before the given file date from disk and from the
|
||||
index file.
|
||||
|
||||
SYNOPSIS
|
||||
purge_logs_before_date()
|
||||
thd Thread pointer
|
||||
before_date Delete all log files before given date.
|
||||
@param thd Thread pointer
|
||||
@param before_date Delete all log files before given date.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If any of the logs before the deleted one is in use,
|
||||
only purge logs up to this one.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
||||
*/
|
||||
|
||||
@ -2992,14 +3007,12 @@ err:
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
|
||||
/*
|
||||
Create a new log file name
|
||||
/**
|
||||
Create a new log file name.
|
||||
|
||||
SYNOPSIS
|
||||
make_log_name()
|
||||
buf buf of at least FN_REFLEN where new name is stored
|
||||
@param 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
|
||||
*/
|
||||
|
||||
@ -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)
|
||||
@ -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
|
||||
new_file_impl()
|
||||
need_lock Set to 1 if caller has not locked LOCK_log
|
||||
@param 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
|
||||
*/
|
||||
|
||||
@ -3521,8 +3532,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
|
||||
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)
|
||||
@ -3922,27 +3933,25 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
|
||||
return 0; // All OK
|
||||
}
|
||||
|
||||
/*
|
||||
Write a cached log entry to the binary log
|
||||
/**
|
||||
Write a cached log entry to the binary log.
|
||||
- To support transaction over replication, we wrap the transaction
|
||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||
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
|
||||
that the same updates are run on the slave.
|
||||
|
||||
SYNOPSIS
|
||||
write()
|
||||
thd
|
||||
cache The cache to copy to the binlog
|
||||
commit_event The commit event to print after writing the
|
||||
@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.
|
||||
- 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
|
||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||
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
|
||||
that the same updates are run on the slave.
|
||||
@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)
|
||||
@ -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
|
||||
wait_for_update()
|
||||
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
|
||||
influences only thd->proc_info.
|
||||
@param thd Thread variable
|
||||
@param 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
|
||||
influences only thd->proc_info.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
One must have a lock on LOCK_log before calling this function.
|
||||
This lock will be released before return! That's required by
|
||||
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
|
||||
close()
|
||||
exiting Bitmask for one or more of the following bits:
|
||||
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.
|
||||
LOG_CLOSE_STOP_EVENT write a 'stop' event to the log
|
||||
@param exiting Bitmask for one or more of the following bits:
|
||||
- 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.
|
||||
- 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.
|
||||
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
|
||||
test_if_number()
|
||||
str String to test
|
||||
res Store value here
|
||||
allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||
@param str String to test
|
||||
@param res Store value here
|
||||
@param allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||
|
||||
NOTE
|
||||
@note
|
||||
For the moment the allow_wildcards argument is not used
|
||||
Should be move to some other file.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 String is a number
|
||||
@retval
|
||||
0 Error
|
||||
*/
|
||||
|
||||
@ -4318,23 +4322,18 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
|
||||
#endif /* __NT__ */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prints a printf style message to the error log and, under NT, to the
|
||||
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
|
||||
This function prints the message into a buffer and then sends that buffer
|
||||
to other functions to write that message to other logging sources.
|
||||
|
||||
NOTE
|
||||
@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
|
||||
|
||||
IMPLEMENTATION
|
||||
This function prints the message into a buffer and then sends that buffer
|
||||
to other functions to write that message to other logging sources.
|
||||
|
||||
RETURN VALUES
|
||||
@returns
|
||||
The function always returns 0. The return value is present in the
|
||||
signature to be compatible with other logging routines, which could
|
||||
return an error (e.g. logging to the log tables)
|
||||
@ -4588,16 +4587,18 @@ err:
|
||||
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:
|
||||
1. take the first from the pool
|
||||
2. if there're waiters - take the one with the most free space
|
||||
Two strategies here:
|
||||
-# take the first from the pool
|
||||
-# if there're waiters - take the one with the most free space.
|
||||
|
||||
TODO page merging. try to allocate adjacent page first,
|
||||
so that they can be flushed both in one sync
|
||||
@todo
|
||||
TODO page merging. try to allocate adjacent page first,
|
||||
so that they can be flushed both in one sync
|
||||
*/
|
||||
|
||||
void TC_LOG_MMAP::get_active_from_pool()
|
||||
{
|
||||
PAGE **p, **best_p=0;
|
||||
@ -4640,6 +4641,10 @@ void TC_LOG_MMAP::get_active_from_pool()
|
||||
pthread_mutex_unlock(&LOCK_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
@todo
|
||||
perhaps, increase log size ?
|
||||
*/
|
||||
int TC_LOG_MMAP::overflow()
|
||||
{
|
||||
/*
|
||||
@ -4652,10 +4657,9 @@ int TC_LOG_MMAP::overflow()
|
||||
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:
|
||||
First all resources prepare the transaction, then tc_log->log() is called,
|
||||
then all resources commit the transaction, then tc_log->unlog() is called.
|
||||
@ -4666,18 +4670,18 @@ int TC_LOG_MMAP::overflow()
|
||||
threads waiting for a page, but then all these threads will be waiting
|
||||
for a fsync() anyway
|
||||
|
||||
IMPLEMENTATION
|
||||
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
||||
records XID in a special Xid_log_event.
|
||||
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
||||
log.
|
||||
|
||||
RETURN
|
||||
0 Error
|
||||
# "cookie", a number that will be passed as an argument
|
||||
to unlog() call. tc_log can define it any way it wants,
|
||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
||||
to the position in memory where xid was logged to.
|
||||
@retval
|
||||
0 - error
|
||||
@retval
|
||||
\# - otherwise, "cookie", a number that will be passed as an argument
|
||||
to unlog() call. tc_log can define it any way it wants,
|
||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
||||
to the position in memory where xid was logged to.
|
||||
*/
|
||||
|
||||
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
|
||||
@ -4785,9 +4789,9 @@ int TC_LOG_MMAP::sync()
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
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)
|
||||
@ -4898,16 +4902,17 @@ TC_LOG *tc_log;
|
||||
TC_LOG_DUMMY tc_log_dummy;
|
||||
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
|
||||
0 no heuristic recovery was requested
|
||||
1 heuristic recovery was performed
|
||||
|
||||
NOTE
|
||||
@note
|
||||
no matter whether heuristic recovery was successful or not
|
||||
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()
|
||||
@ -4925,8 +4930,9 @@ int TC_LOG::using_heuristic_recover()
|
||||
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
||||
#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())
|
||||
and copy it to the new binlog if rotated
|
||||
but let's check the behaviour of tc_log_page_waits first!
|
||||
@ -5017,7 +5023,7 @@ err:
|
||||
return error;
|
||||
}
|
||||
|
||||
/* this is called on shutdown, after ha_panic */
|
||||
/** This is called on shutdown, after ha_panic. */
|
||||
void TC_LOG_BINLOG::close()
|
||||
{
|
||||
DBUG_ASSERT(prepared_xids==0);
|
||||
@ -5025,12 +5031,14 @@ void TC_LOG_BINLOG::close()
|
||||
pthread_cond_destroy (&COND_prep_xids);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO group commit
|
||||
/**
|
||||
@todo
|
||||
group commit
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
1 - success
|
||||
@retval
|
||||
0 error
|
||||
@retval
|
||||
1 success
|
||||
*/
|
||||
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
||||
{
|
||||
|
295
sql/log_event.cc
295
sql/log_event.cc
@ -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)
|
||||
@ -212,21 +212,20 @@ static char *pretty_print_str(char *packet, char *str, int len)
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
Creates a temporary name for load data infile:
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
SYNOPSIS
|
||||
slave_load_file_stem()
|
||||
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
|
||||
/**
|
||||
Creates a temporary name for load data infile:.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
static char *slave_load_file_stem(char *buf, uint file_id,
|
||||
int event_server_id, const char *ext)
|
||||
{
|
||||
@ -246,14 +245,12 @@ static char *slave_load_file_stem(char *buf, uint file_id,
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Delete all temporary files used for SQL_LOAD.
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
SYNOPSIS
|
||||
cleanup_load_tmpdir()
|
||||
/**
|
||||
Delete all temporary files used for SQL_LOAD.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
static void cleanup_load_tmpdir()
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
@ -338,12 +335,14 @@ char *str_to_hex(char *to, const char *from, uint len)
|
||||
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
|
||||
the 'to' string. To generate a correct escaping, the character set
|
||||
information in 'csinfo' is used.
|
||||
*/
|
||||
#ifndef MYSQL_CLIENT
|
||||
*/
|
||||
|
||||
int
|
||||
append_query_string(CHARSET_INFO *csinfo,
|
||||
String const *from, String *to)
|
||||
@ -370,7 +369,7 @@ append_query_string(CHARSET_INFO *csinfo,
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
||||
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::get_type_str()
|
||||
/**
|
||||
@return
|
||||
returns the human readable name of the event's type
|
||||
*/
|
||||
|
||||
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
|
||||
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
|
||||
@ -589,12 +589,9 @@ void Log_event::pack_info(Protocol *protocol)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Log_event::net_send()
|
||||
|
||||
/**
|
||||
Only called by SHOW BINLOG EVENTS
|
||||
*/
|
||||
|
||||
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
||||
{
|
||||
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 */
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
@ -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
|
||||
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,
|
||||
@ -800,14 +796,11 @@ end:
|
||||
#define LOCK_MUTEX
|
||||
#endif
|
||||
|
||||
/*
|
||||
Log_event::read_log_event()
|
||||
|
||||
NOTE:
|
||||
#ifndef MYSQL_CLIENT
|
||||
/**
|
||||
@note
|
||||
Allocates memory; The caller is responsible for clean-up.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
pthread_mutex_t* log_lock,
|
||||
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)
|
||||
constructors.
|
||||
*/
|
||||
@ -1233,12 +1225,13 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
|
||||
|
||||
#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
|
||||
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
|
||||
example it does not print LOAD DATA INFILE).
|
||||
@todo
|
||||
show the catalog ??
|
||||
*/
|
||||
|
||||
void Query_log_event::pack_info(Protocol *protocol)
|
||||
@ -1267,7 +1260,9 @@ void Query_log_event::pack_info(Protocol *protocol)
|
||||
|
||||
#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,
|
||||
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
|
||||
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
Query_log_event::Query_log_event()
|
||||
|
||||
/**
|
||||
The simplest constructor that could possibly work. This is used for
|
||||
creating static objects that have a special meaning and are invisible
|
||||
to the log.
|
||||
@ -1580,8 +1573,7 @@ static void copy_str_and_move(const char **src,
|
||||
*(*dst)++= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Query_log_event::Query_log_event()
|
||||
/**
|
||||
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
|
||||
/**
|
||||
Query_log_event::print().
|
||||
|
||||
@todo
|
||||
print the catalog ??
|
||||
*/
|
||||
void Query_log_event::print_query_header(IO_CACHE* file,
|
||||
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,
|
||||
const char *query_arg, uint32 q_len_arg)
|
||||
{
|
||||
@ -2367,30 +2378,31 @@ bool Start_log_event_v3::write(IO_CACHE* file)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Start_log_event_v3::do_apply_event()
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
/**
|
||||
Start_log_event_v3::do_apply_event() .
|
||||
The master started
|
||||
|
||||
IMPLEMENTATION
|
||||
IMPLEMENTATION
|
||||
- To handle the case where the master died without having time to write
|
||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
||||
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||
can (see below).
|
||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
||||
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||
can (see below).
|
||||
|
||||
TODO
|
||||
@todo
|
||||
- Remove all active user locks.
|
||||
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
|
||||
anymore. If the user lock is later used, the old one will be released. In
|
||||
other words, no deadlock problem.
|
||||
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
|
||||
anymore. If the user lock is later used, the old one will be released. In
|
||||
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)
|
||||
{
|
||||
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
||||
switch (binlog_version) {
|
||||
switch (binlog_version)
|
||||
{
|
||||
case 3:
|
||||
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 1st ctor.
|
||||
|
||||
SYNOPSIS
|
||||
Format_description_log_event::Format_description_log_event
|
||||
binlog_version the binlog version for which we want to build
|
||||
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
|
||||
old 4.0 (binlog version 2) is not supported;
|
||||
it should not be used for replication with
|
||||
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.
|
||||
|
||||
@param binlog_version the binlog version for which we want to build
|
||||
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
|
||||
old 4.0 (binlog version 2) is not supported;
|
||||
it should not be used for replication with
|
||||
5.0.
|
||||
*/
|
||||
|
||||
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
|
||||
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
|
||||
length is in the post-header of the event, but we don't know where the
|
||||
post-header starts.
|
||||
|
||||
So this type of event HAS to:
|
||||
- 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
|
||||
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
|
||||
versions, so that we know for sure.
|
||||
|
||||
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
||||
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 */
|
||||
|
||||
|
||||
/*
|
||||
Load_log_event::Load_log_event()
|
||||
|
||||
NOTE
|
||||
/**
|
||||
@note
|
||||
The caller must do buf[event_len] = 0 before he starts using the
|
||||
constructed event.
|
||||
*/
|
||||
|
||||
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
||||
const Format_description_log_event *description_event)
|
||||
: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 */
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
/**
|
||||
Load_log_event::set_fields()
|
||||
|
||||
Note that this function can not use the member variable
|
||||
for the database, since LOAD DATA INFILE on the slave
|
||||
can be for a different database than the current one.
|
||||
This is the reason for the affected_db argument to this method.
|
||||
@note
|
||||
This function can not use the member variable
|
||||
for the database, since LOAD DATA INFILE on the slave
|
||||
can be for a different database than the current one.
|
||||
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,
|
||||
List<Item> &field_list,
|
||||
Name_resolution_context *context)
|
||||
@ -3218,32 +3227,33 @@ void Load_log_event::set_fields(const char* affected_db,
|
||||
|
||||
|
||||
#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
|
||||
Load_log_event::do_apply_event
|
||||
net
|
||||
rli
|
||||
use_rli_only_for_errors - if set to 1, rli is provided to
|
||||
Load_log_event::do_apply_event
|
||||
only for this function to have
|
||||
RPL_LOG_NAME and
|
||||
rli->last_slave_error, both being
|
||||
used by error reports. rli's
|
||||
position advancing is skipped (done
|
||||
by the caller which is
|
||||
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.
|
||||
@param net
|
||||
@param rli
|
||||
@param use_rli_only_for_errors If set to 1, rli is provided to
|
||||
Load_log_event::exec_event only for this
|
||||
function to have RPL_LOG_NAME and
|
||||
rli->last_slave_error, both being used by
|
||||
error reports. rli's position advancing
|
||||
is skipped (done by the caller which is
|
||||
Execute_load_log_event::exec_event).
|
||||
If set to 0, rli is provided for full use,
|
||||
i.e. for error reports and position
|
||||
advancing.
|
||||
|
||||
DESCRIPTION
|
||||
Does the data loading job when executing a LOAD DATA on the slave
|
||||
@todo
|
||||
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
|
||||
1 Failure
|
||||
@retval
|
||||
1 Failure
|
||||
*/
|
||||
|
||||
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
||||
@ -3619,24 +3629,21 @@ bool Rotate_log_event::write(IO_CACHE* file)
|
||||
#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
|
||||
This is mainly used so that we can later figure out the logname and
|
||||
position for the master.
|
||||
|
||||
IMPLEMENTATION
|
||||
This is mainly used so that we can later figure out the logname and
|
||||
position for the master.
|
||||
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||
in a A -> B -> A setup.
|
||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
||||
|
||||
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||
in a A -> B -> A setup.
|
||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
||||
@ -3994,12 +4001,12 @@ void Xid_log_event::pack_info(Protocol *protocol)
|
||||
}
|
||||
#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
|
||||
xid_t::get_my_xid doesn't do it either
|
||||
|
||||
we don't care about actual values of xids as long as
|
||||
xid_t::get_my_xid doesn't do it either.
|
||||
We don't care about actual values of xids as long as
|
||||
identical numbers compare identically
|
||||
*/
|
||||
|
||||
@ -4470,6 +4477,10 @@ void Slave_log_event::pack_info(Protocol *protocol)
|
||||
|
||||
|
||||
#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,
|
||||
Relay_log_info* rli)
|
||||
: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)
|
||||
: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 */
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/*
|
||||
Stop_log_event::do_apply_event()
|
||||
|
||||
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
|
||||
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
|
||||
here, the master was sane.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prints the query as LOAD DATA LOCAL and with rewritten filename.
|
||||
*/
|
||||
void Execute_load_query_log_event::print(FILE* file,
|
||||
PRINT_EVENT_INFO* print_event_info,
|
||||
const char *local_fname)
|
||||
@ -6471,15 +6481,17 @@ void Rows_log_event::print_helper(FILE *file,
|
||||
|
||||
*/
|
||||
|
||||
#if !defined(MYSQL_CLIENT)
|
||||
/**
|
||||
Save the field metadata based on the real_type of the field.
|
||||
The metadata saved depends on the type of the field. Some fields
|
||||
store a single byte for pack_length() while others store two bytes
|
||||
for field_length (max length).
|
||||
|
||||
@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
|
||||
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
|
||||
@ -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
|
||||
not encode 2 parts.
|
||||
*/
|
||||
#if !defined(MYSQL_CLIENT)
|
||||
int Table_map_log_event::save_field_metadata()
|
||||
{
|
||||
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
||||
|
@ -13,8 +13,11 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
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
|
||||
if it ends at file-length and next read can try to read after file-length
|
||||
(and get a EOF-error).
|
||||
@ -34,11 +37,15 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
** Read buffered from the net.
|
||||
** Returns 1 if can't read requested characters
|
||||
** Returns 0 if record read
|
||||
*/
|
||||
/**
|
||||
Read buffered from the net.
|
||||
|
||||
@retval
|
||||
1 if can't read requested characters
|
||||
@retval
|
||||
0 if record read
|
||||
*/
|
||||
|
||||
|
||||
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
||||
size_t Count __attribute__((unused)))
|
||||
|
@ -18,17 +18,15 @@
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/*
|
||||
report result of decimal operation
|
||||
/**
|
||||
report result of decimal operation.
|
||||
|
||||
SYNOPSIS
|
||||
decimal_operation_results()
|
||||
result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
@param result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
|
||||
TODO
|
||||
@todo
|
||||
Fix error messages
|
||||
|
||||
RETURN
|
||||
@return
|
||||
result
|
||||
*/
|
||||
|
||||
|
248
sql/mysqld.cc
248
sql/mysqld.cc
@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
|
||||
typedef fp_except fp_except_t;
|
||||
#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()
|
||||
{
|
||||
/* 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 ulong killed_threads, thread_created;
|
||||
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 const char *sql_mode_str= "OFF";
|
||||
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
||||
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
|
||||
*/
|
||||
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_enable_named_pipe= 0;
|
||||
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;
|
||||
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
||||
#ifdef HAVE_INITGROUPS
|
||||
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
|
||||
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
|
||||
#endif
|
||||
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
||||
uint mysqld_port_timeout;
|
||||
@ -458,12 +458,12 @@ ulong specialflag=0;
|
||||
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
||||
ulong max_connections, max_connect_errors;
|
||||
uint max_user_connections= 0;
|
||||
/*
|
||||
/**
|
||||
Limit of the total number of prepared statements in the server.
|
||||
Is necessary to protect the server against out-of-memory attacks.
|
||||
*/
|
||||
ulong max_prepared_stmt_count;
|
||||
/*
|
||||
/**
|
||||
Current total number of prepared statements in the server. This number
|
||||
is exact, and therefore may not be equal to the difference between
|
||||
`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 server_version[SERVER_VERSION_LENGTH];
|
||||
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_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>";
|
||||
/* name of additional condition */
|
||||
/** name of additional condition */
|
||||
const char *in_additional_cond= "<IN COND>";
|
||||
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_global_system_variables,
|
||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||
/*
|
||||
/**
|
||||
The below lock protects access to two global server variables:
|
||||
max_prepared_stmt_count and prepared_stmt_count. These variables
|
||||
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 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
|
||||
struct passwd *user_info;
|
||||
@ -628,7 +628,7 @@ static char **opt_argv;
|
||||
static HANDLE hEventShutdown;
|
||||
static char shutdown_event_name[40];
|
||||
#include "nt_servc.h"
|
||||
static NTService Service; // Service object for WinNT
|
||||
static NTService Service; ///< Service object for WinNT
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
#endif /* __WIN__ */
|
||||
|
||||
@ -1009,19 +1009,15 @@ void kill_mysql(void)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Force server down. Kill all connections and threads and exit
|
||||
/**
|
||||
Force server down. Kill all connections and threads and exit.
|
||||
|
||||
SYNOPSIS
|
||||
kill_server
|
||||
@param sig_ptr Signal number that caused kill_server to be called.
|
||||
|
||||
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
|
||||
from a signal handler and there is thus no signal to block
|
||||
or stop, we just want to kill the server.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(__NETWARE__)
|
||||
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
cleanup all memory and end program nicely
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
SYNOPSIS
|
||||
unireg_end()
|
||||
|
||||
NOTES
|
||||
This function never returns.
|
||||
/**
|
||||
cleanup all memory and end program nicely.
|
||||
|
||||
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
|
||||
(Mac OS X) we have to call exit() instead if pthread_exit().
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@note
|
||||
This function never returns.
|
||||
*/
|
||||
void unireg_end(void)
|
||||
{
|
||||
clean_up(1);
|
||||
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
/*
|
||||
/**
|
||||
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()
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#if !defined(__WIN__) && !defined(__NETWARE__)
|
||||
@ -1696,19 +1687,16 @@ static void network_init(void)
|
||||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/*
|
||||
Close a connection
|
||||
/**
|
||||
Close a connection.
|
||||
|
||||
SYNOPSIS
|
||||
close_connection()
|
||||
thd Thread handle
|
||||
errcode Error code to print to console
|
||||
lock 1 if we have have to lock LOCK_thread_count
|
||||
@param thd Thread handle
|
||||
@param errcode Error code to print to console
|
||||
@param lock 1 if we have have to lock LOCK_thread_count
|
||||
|
||||
NOTES
|
||||
@note
|
||||
For the connection that is doing shutdown, this is called twice
|
||||
*/
|
||||
|
||||
void close_connection(THD *thd, uint errcode, bool lock)
|
||||
{
|
||||
st_vio *vio;
|
||||
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/* Called when a thread is aborted */
|
||||
/* ARGSUSED */
|
||||
|
||||
/** Called when a thread is aborted. */
|
||||
/* ARGSUSED */
|
||||
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
||||
{
|
||||
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
|
||||
/**
|
||||
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)))
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
|
||||
|
||||
#elif defined(__NETWARE__)
|
||||
|
||||
// down server event callback
|
||||
/// down server event callback.
|
||||
void mysql_down_server_cb(void *, void *)
|
||||
{
|
||||
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 *)
|
||||
{
|
||||
UnRegisterEventNotification(eh); // cleanup down event notification
|
||||
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
|
||||
}
|
||||
|
||||
|
||||
// initialize callbacks
|
||||
/// initialize callbacks.
|
||||
void mysql_cb_init()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
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()
|
||||
@ -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)
|
||||
@ -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/"
|
||||
|
||||
/**
|
||||
Function to get NSS volume ID of the MySQL data.
|
||||
*/
|
||||
static void getvolumeID(BYTE *volumeName)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
||||
@ -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 */
|
||||
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||
{
|
||||
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
|
||||
#endif /* __WIN__*/
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
All global error messages are sent here where the first one is stored
|
||||
for the client
|
||||
for the client.
|
||||
*/
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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*/
|
||||
|
||||
|
||||
/*
|
||||
Initialize one of the global date/time format variables
|
||||
/**
|
||||
Initialize one of the global date/time format variables.
|
||||
|
||||
SYNOPSIS
|
||||
init_global_datetime_format()
|
||||
format_type What kind of format should be supported
|
||||
var_ptr Pointer to variable that should be updated
|
||||
@param format_type What kind of format should be supported
|
||||
@param var_ptr Pointer to variable that should be updated
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The default value is taken from either opt_date_time_formats[] or
|
||||
the ISO format (ANSI SQL)
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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
|
||||
default_service_handling()
|
||||
argv Pointer to argument list
|
||||
servicename Internal name of service
|
||||
displayname Display name of service (in taskbar ?)
|
||||
file_path Path to this program
|
||||
startup_option Startup option to mysqld
|
||||
@param argv Pointer to argument list
|
||||
@param servicename Internal name of service
|
||||
@param displayname Display name of service (in taskbar ?)
|
||||
@param file_path Path to this program
|
||||
@param startup_option Startup option to mysqld
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 option handled
|
||||
@retval
|
||||
1 Could not handle option
|
||||
*/
|
||||
*/
|
||||
|
||||
static bool
|
||||
default_service_handling(char **argv,
|
||||
@ -4209,7 +4189,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@ -4334,23 +4314,17 @@ void create_thread_to_handle_connection(THD *thd)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
connection. If there are idle cached threads one will be used.
|
||||
'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.
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
@param[in,out] thd Thread handle of future thread.
|
||||
*/
|
||||
|
||||
static void create_new_thread(THD *thd)
|
||||
@ -4699,15 +4673,13 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
||||
#endif /* __NT__ */
|
||||
|
||||
|
||||
/*
|
||||
Thread of shared memory's service
|
||||
|
||||
SYNOPSIS
|
||||
handle_connections_shared_memory()
|
||||
arg Arguments of thread
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SMEM
|
||||
|
||||
/**
|
||||
Thread of shared memory's service.
|
||||
|
||||
@param arg Arguments of thread
|
||||
*/
|
||||
pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
{
|
||||
/* 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*/
|
||||
|
||||
|
||||
/*
|
||||
Initialize all MySQL global variables to default values
|
||||
/**
|
||||
Initialize all MySQL global variables to default values.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_init_variables()
|
||||
We don't need to set numeric variables refered to in my_long_options
|
||||
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
|
||||
restart the embedded server with a clean environment
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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
|
||||
mysql_real_data_home.
|
||||
Return 1 if len(path) > FN_REFLEN
|
||||
@return
|
||||
1 if len(path) > FN_REFLEN
|
||||
*/
|
||||
|
||||
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 ','
|
||||
returns ~(ulong) 0 on error.
|
||||
/**
|
||||
@return
|
||||
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)
|
||||
@ -8122,16 +8101,16 @@ skip: ;
|
||||
} /* find_bit_type */
|
||||
|
||||
|
||||
/*
|
||||
Check if file system used for databases is case insensitive
|
||||
/**
|
||||
Check if file system used for databases is case insensitive.
|
||||
|
||||
SYNOPSIS
|
||||
test_if_case_sensitive()
|
||||
dir_name Directory to test
|
||||
@param dir_name Directory to test
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
-1 Don't know (Test failed)
|
||||
@retval
|
||||
0 File system is case sensitive
|
||||
@retval
|
||||
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
|
||||
|
||||
/**
|
||||
Create file to store pid number.
|
||||
*/
|
||||
static void create_pid_file()
|
||||
{
|
||||
File file;
|
||||
@ -8187,7 +8167,7 @@ static void create_pid_file()
|
||||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
/* Clear most status variables */
|
||||
/** Clear most status variables. */
|
||||
void refresh_status(THD *thd)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_status);
|
||||
|
Loading…
x
Reference in New Issue
Block a user