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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Functions to copy data to or from fields
|
@file
|
||||||
This could be done with a single short function but opencoding this
|
|
||||||
gives much more speed.
|
@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 "mysql_priv.h"
|
||||||
#include <m_ctype.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
|
@param field Field to update
|
||||||
set_field_to_null_with_conversions()
|
@param no_conversions Set to 1 if we should return 1 if field can't
|
||||||
field Field to update
|
take null values.
|
||||||
no_conversion Set to 1 if we should return 1 if field can't
|
If set to 0 we will do store the 'default value'
|
||||||
take null values.
|
if the field is a special field. If not we will
|
||||||
If set to 0 we will do store the 'default value'
|
give an error.
|
||||||
if the field is a special field. If not we will
|
|
||||||
give an error.
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 Field could take 0 or an automatic conversion was used
|
0 Field could take 0 or an automatic conversion was used
|
||||||
-1 Field could not take NULL and no conversion was used.
|
@retval
|
||||||
If no_conversion was not set, an error message is printed
|
-1 Field could not take NULL and no conversion was used.
|
||||||
|
If no_conversion was not set, an error message is printed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy)
|
|||||||
copy->tmp.charset());
|
copy->tmp.charset());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save blob in copy->tmp for GROUP BY */
|
/** Save blob in copy->tmp for GROUP BY. */
|
||||||
|
|
||||||
static void do_save_blob(Copy_field *copy)
|
static void do_save_blob(Copy_field *copy)
|
||||||
{
|
{
|
||||||
@ -352,9 +355,9 @@ static void do_field_decimal(Copy_field *copy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
string copy for single byte characters set when to string is shorter than
|
string copy for single byte characters set when to string is shorter than
|
||||||
from string
|
from string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void do_cut_string(Copy_field *copy)
|
static void do_cut_string(Copy_field *copy)
|
||||||
@ -374,9 +377,9 @@ static void do_cut_string(Copy_field *copy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
string copy for multi byte characters set when to string is shorter than
|
string copy for multi byte characters set when to string is shorter than
|
||||||
from string
|
from string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void do_cut_string_complex(Copy_field *copy)
|
static void do_cut_string_complex(Copy_field *copy)
|
||||||
@ -507,7 +510,7 @@ static void do_varstring2_mb(Copy_field *copy)
|
|||||||
** The different functions that fills in a Copy_field class
|
** The different functions that fills in a Copy_field class
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
copy of field to maybe null string.
|
copy of field to maybe null string.
|
||||||
If field is null then the all bytes are set to 0.
|
If field is null then the all bytes are set to 0.
|
||||||
if field is not null then the first byte is set to 1 and the rest of the
|
if field is not null then the first byte is set to 1 and the rest of the
|
||||||
@ -748,7 +751,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Simple quick field convert that is called on insert */
|
/** Simple quick field convert that is called on insert. */
|
||||||
|
|
||||||
int field_conv(Field *to,Field *from)
|
int field_conv(Field *to,Field *from)
|
||||||
{
|
{
|
||||||
|
296
sql/filesort.cc
296
sql/filesort.cc
@ -14,7 +14,12 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Sorts a database */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Sorts a database
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#ifdef HAVE_STDDEF_H
|
#ifdef HAVE_STDDEF_H
|
||||||
@ -27,8 +32,7 @@
|
|||||||
#define SKIP_DBUG_IN_FILESORT
|
#define SKIP_DBUG_IN_FILESORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* How to write record_ref. */
|
/// How to write record_ref.
|
||||||
|
|
||||||
#define WRITE_REF(file,from) \
|
#define WRITE_REF(file,from) \
|
||||||
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
|
|||||||
uint sortlength, uint *plength);
|
uint sortlength, uint *plength);
|
||||||
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
||||||
uchar *buff);
|
uchar *buff);
|
||||||
|
/**
|
||||||
|
Sort a table.
|
||||||
|
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.
|
||||||
|
|
||||||
/*
|
Before calling filesort, one must have done
|
||||||
Sort a table
|
table->file->info(HA_STATUS_VARIABLE)
|
||||||
|
|
||||||
SYNOPSIS
|
The result set is stored in table->io_cache or
|
||||||
filesort()
|
table->record_pointers.
|
||||||
table Table to sort
|
|
||||||
sortorder How to sort the table
|
@param thd Current thread
|
||||||
s_length Number of elements in sortorder
|
@param table Table to sort
|
||||||
select Condition to apply to the rows
|
@param sortorder How to sort the table
|
||||||
ha_maxrows Return only this many rows
|
@param s_length Number of elements in sortorder
|
||||||
sort_positions Set to 1 if we want to force sorting by position
|
@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)
|
(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
|
@todo
|
||||||
Creates a set of pointers that can be used to read the rows
|
check why we do this (param.keys--)
|
||||||
in sorted order. This should be done with the functions
|
@note
|
||||||
in records.cc
|
|
||||||
|
|
||||||
REQUIREMENTS
|
|
||||||
Before calling filesort, one must have done
|
|
||||||
table->file->info(HA_STATUS_VARIABLE)
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
If we sort by position (like if sort_positions is 1) filesort() will
|
If we sort by position (like if sort_positions is 1) filesort() will
|
||||||
call table->prepare_for_position().
|
call table->prepare_for_position().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
HA_POS_ERROR Error
|
HA_POS_ERROR Error
|
||||||
# Number of rows
|
@retval
|
||||||
|
\# Number of rows
|
||||||
|
@retval
|
||||||
examined_rows will be set to number of examined rows
|
examined_rows will be set to number of examined rows
|
||||||
|
|
||||||
The result set is stored in table->io_cache or
|
|
||||||
table->record_pointers
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||||
@ -351,7 +353,7 @@ void filesort_free_buffers(TABLE *table, bool full)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a array of string pointers */
|
/** Make a array of string pointers. */
|
||||||
|
|
||||||
static char **make_char_array(char **old_pos, register uint fields,
|
static char **make_char_array(char **old_pos, register uint fields,
|
||||||
uint length, myf my_flag)
|
uint length, myf my_flag)
|
||||||
@ -372,7 +374,7 @@ static char **make_char_array(char **old_pos, register uint fields,
|
|||||||
} /* make_char_array */
|
} /* make_char_array */
|
||||||
|
|
||||||
|
|
||||||
/* Read 'count' number of buffer pointers into memory */
|
/** Read 'count' number of buffer pointers into memory. */
|
||||||
|
|
||||||
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||||
{
|
{
|
||||||
@ -395,38 +397,40 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Search after sort_keys and write them into tempfile.
|
Search after sort_keys and write them into tempfile.
|
||||||
SYNOPSIS
|
All produced sequences are guaranteed to be non-empty.
|
||||||
find_all_keys()
|
|
||||||
param Sorting parameter
|
@param param Sorting parameter
|
||||||
select Use this to get source data
|
@param select Use this to get source data
|
||||||
sort_keys Array of pointers to sort key + addon buffers.
|
@param sort_keys Array of pointers to sort key + addon buffers.
|
||||||
buffpek_pointers File to write BUFFPEKs describing sorted segments
|
@param buffpek_pointers File to write BUFFPEKs describing sorted segments
|
||||||
in tempfile.
|
in tempfile.
|
||||||
tempfile File to write sorted sequences of sortkeys to.
|
@param tempfile File to write sorted sequences of sortkeys to.
|
||||||
indexfile If !NULL, use it for source data (contains rowids)
|
@param indexfile If !NULL, use it for source data (contains rowids)
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
Basic idea:
|
Basic idea:
|
||||||
while (get_next_sortkey())
|
@verbatim
|
||||||
{
|
while (get_next_sortkey())
|
||||||
if (no free space in sort_keys buffers)
|
{
|
||||||
{
|
if (no free space in sort_keys buffers)
|
||||||
sort sort_keys buffer;
|
{
|
||||||
dump sorted sequence to 'tempfile';
|
sort sort_keys buffer;
|
||||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
dump sorted sequence to 'tempfile';
|
||||||
}
|
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||||
put sort key into 'sort_keys';
|
}
|
||||||
}
|
put sort key into 'sort_keys';
|
||||||
if (sort_keys has some elements && dumped at least once)
|
}
|
||||||
sort-dump-dump as above;
|
if (sort_keys has some elements && dumped at least once)
|
||||||
else
|
sort-dump-dump as above;
|
||||||
don't sort, leave sort_keys array to be sorted by caller.
|
else
|
||||||
|
don't sort, leave sort_keys array to be sorted by caller.
|
||||||
All produced sequences are guaranteed to be non-empty.
|
@endverbatim
|
||||||
RETURN
|
|
||||||
|
@retval
|
||||||
Number of records written on success.
|
Number of records written on success.
|
||||||
|
@retval
|
||||||
HA_POS_ERROR on error.
|
HA_POS_ERROR on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -591,23 +595,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
|||||||
} /* find_all_keys */
|
} /* find_all_keys */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Sort the buffer and write:
|
Sort the buffer and write:
|
||||||
1) the sorted sequence to tempfile
|
-# the sorted sequence to tempfile
|
||||||
2) a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
-# a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||||
(was: Skriver en buffert med nycklar till filen)
|
|
||||||
SYNOPSIS
|
(was: Skriver en buffert med nycklar till filen)
|
||||||
write_keys()
|
|
||||||
param Sort parameters
|
@param param Sort parameters
|
||||||
sort_keys Array of pointers to keys to sort
|
@param sort_keys Array of pointers to keys to sort
|
||||||
count Number of elements in sort_keys array
|
@param count Number of elements in sort_keys array
|
||||||
buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
@param buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||||
The BUFFPEK::{file_pos, count} will indicate where
|
The BUFFPEK::{file_pos, count} will indicate where
|
||||||
the sorted data was stored.
|
the sorted data was stored.
|
||||||
tempfile The sorted sequence will be written into this file.
|
@param tempfile The sorted sequence will be written into this file.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 Error
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -650,8 +656,8 @@ err:
|
|||||||
} /* write_keys */
|
} /* write_keys */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Store length as suffix in high-byte-first order
|
Store length as suffix in high-byte-first order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void store_length(uchar *to, uint length, uint pack_length)
|
static inline void store_length(uchar *to, uint length, uint pack_length)
|
||||||
@ -673,7 +679,7 @@ static inline void store_length(uchar *to, uint length, uint pack_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* makes a sort-key from record */
|
/** Make a sort-key from record. */
|
||||||
|
|
||||||
static void make_sortkey(register SORTPARAM *param,
|
static void make_sortkey(register SORTPARAM *param,
|
||||||
register uchar *to, uchar *ref_pos)
|
register uchar *to, uchar *ref_pos)
|
||||||
@ -987,7 +993,7 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Merge buffers to make < MERGEBUFF2 buffers */
|
/** Merge buffers to make < MERGEBUFF2 buffers. */
|
||||||
|
|
||||||
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
|
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
|
||||||
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
||||||
@ -1040,8 +1046,12 @@ cleanup:
|
|||||||
} /* merge_many_buff */
|
} /* merge_many_buff */
|
||||||
|
|
||||||
|
|
||||||
/* Read data to buffer */
|
/**
|
||||||
/* This returns (uint) -1 if something goes wrong */
|
Read data to buffer.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
(uint)-1 if something goes wrong
|
||||||
|
*/
|
||||||
|
|
||||||
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
||||||
uint rec_length)
|
uint rec_length)
|
||||||
@ -1063,15 +1073,15 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
|||||||
} /* read_to_buffer */
|
} /* read_to_buffer */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Put all room used by freed buffer to use in adjacent buffer. Note, that
|
Put all room used by freed buffer to use in adjacent buffer.
|
||||||
we can't simply distribute memory evenly between all buffers, because
|
|
||||||
new areas must not overlap with old ones.
|
Note, that we can't simply distribute memory evenly between all buffers,
|
||||||
SYNOPSIS
|
because new areas must not overlap with old ones.
|
||||||
reuse_freed_buff()
|
|
||||||
queue IN list of non-empty buffers, without freed buffer
|
@param[in] queue list of non-empty buffers, without freed buffer
|
||||||
reuse IN empty buffer
|
@param[in] reuse empty buffer
|
||||||
key_length IN key length
|
@param[in] key_length key length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
||||||
@ -1096,22 +1106,22 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Merge buffers to one buffer
|
Merge buffers to one buffer.
|
||||||
SYNOPSIS
|
|
||||||
merge_buffers()
|
|
||||||
param Sort parameter
|
|
||||||
from_file File with source data (BUFFPEKs point to this file)
|
|
||||||
to_file File to write the sorted result data.
|
|
||||||
sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
|
||||||
lastbuff OUT Store here BUFFPEK describing data written to to_file
|
|
||||||
Fb First element in source BUFFPEKs array
|
|
||||||
Tb Last element in source BUFFPEKs array
|
|
||||||
flag
|
|
||||||
|
|
||||||
RETURN
|
@param param Sort parameter
|
||||||
0 - OK
|
@param from_file File with source data (BUFFPEKs point to this file)
|
||||||
other - error
|
@param to_file File to write the sorted result data.
|
||||||
|
@param sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
||||||
|
@param lastbuff OUT Store here BUFFPEK describing data written to to_file
|
||||||
|
@param Fb First element in source BUFFPEKs array
|
||||||
|
@param Tb Last element in source BUFFPEKs array
|
||||||
|
@param flag
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 OK
|
||||||
|
@retval
|
||||||
|
other error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||||
@ -1347,23 +1357,21 @@ static uint suffix_length(ulong string_length)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Calculate length of sort key
|
Calculate length of sort key.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
sortlength()
|
@param sortorder Order of items to sort
|
||||||
thd Thread handler
|
@param s_length Number of items to sort
|
||||||
sortorder Order of items to sort
|
@param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
|
||||||
uint s_length Number of items to sort
|
(In which case we have to use strxnfrm())
|
||||||
multi_byte_charset (out)
|
|
||||||
Set to 1 if we are using multi-byte charset
|
|
||||||
(In which case we have to use strxnfrm())
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
sortorder->length is updated for each sort item
|
sortorder->length is updated for each sort item.
|
||||||
|
@n
|
||||||
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Total length of sort buffer in bytes
|
Total length of sort buffer in bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1450,33 +1458,31 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get descriptors of fields appended to sorted fields and
|
Get descriptors of fields appended to sorted fields and
|
||||||
calculate its total length
|
calculate its total length.
|
||||||
|
|
||||||
SYNOPSIS
|
The function first finds out what fields are used in the result set.
|
||||||
get_addon_fields()
|
Then it calculates the length of the buffer to store the values of
|
||||||
thd Current thread
|
these fields together with the value of sort values.
|
||||||
ptabfields Array of references to the table fields
|
If the calculated length is not greater than max_length_for_sort_data
|
||||||
sortlength Total length of sorted fields
|
the function allocates memory for an array of descriptors containing
|
||||||
plength out: Total length of appended fields
|
layouts for the values of the non-sorted fields in the buffer and
|
||||||
|
fills them.
|
||||||
|
|
||||||
DESCRIPTION
|
@param thd Current thread
|
||||||
The function first finds out what fields are used in the result set.
|
@param ptabfield Array of references to the table fields
|
||||||
Then it calculates the length of the buffer to store the values of
|
@param sortlength Total length of sorted fields
|
||||||
these fields together with the value of sort values.
|
@param[out] plength Total length of appended fields
|
||||||
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.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The null bits for the appended values are supposed to be put together
|
The null bits for the appended values are supposed to be put together
|
||||||
and stored the buffer just ahead of the value of the first field.
|
and stored the buffer just ahead of the value of the first field.
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Pointer to the layout descriptors for the appended fields, if any
|
Pointer to the layout descriptors for the appended fields, if any
|
||||||
NULL - if we do not store field values with sort data.
|
@retval
|
||||||
|
NULL if we do not store field values with sort data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static SORT_ADDON_FIELD *
|
static SORT_ADDON_FIELD *
|
||||||
@ -1552,20 +1558,18 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Copy (unpack) values appended to sorted fields from a buffer back to
|
Copy (unpack) values appended to sorted fields from a buffer back to
|
||||||
their regular positions specified by the Field::ptr pointers.
|
their regular positions specified by the Field::ptr pointers.
|
||||||
|
|
||||||
SYNOPSIS
|
@param addon_field Array of descriptors for appended fields
|
||||||
unpack_addon_fields()
|
@param buff Buffer which to unpack the value from
|
||||||
addon_field Array of descriptors for appended fields
|
|
||||||
buff Buffer which to unpack the value from
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The function is supposed to be used only as a callback function
|
The function is supposed to be used only as a callback function
|
||||||
when getting field values for the sorted result set.
|
when getting field values for the sorted result set.
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
void.
|
void.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@details
|
||||||
|
@verbatim
|
||||||
The idea of presented algorithm see in
|
The idea of presented algorithm see in
|
||||||
"The Art of Computer Programming" by Donald E. Knuth
|
"The Art of Computer Programming" by Donald E. Knuth
|
||||||
Volume 3 "Sorting and searching"
|
Volume 3 "Sorting and searching"
|
||||||
@ -63,12 +66,14 @@ for optimization, link is the 16-bit index in 'symbols' or 'sql_functions'
|
|||||||
or search-array..
|
or search-array..
|
||||||
|
|
||||||
So, we can read full search-structure as 32-bit word
|
So, we can read full search-structure as 32-bit word
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@todo
|
||||||
|
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
|
#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,
|
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
|
||||||
bool no_substitute, bool report_error)
|
bool no_substitute, bool report_error)
|
||||||
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Register handler error messages for use with my_error().
|
Register handler error messages for use with my_error().
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
ha_init_errors()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 Error
|
@retval
|
||||||
|
!=0 Error
|
||||||
*/
|
*/
|
||||||
static int ha_init_errors(void)
|
static int ha_init_errors(void)
|
||||||
{
|
{
|
||||||
@ -349,15 +347,13 @@ static int ha_init_errors(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Unregister handler error messages.
|
Unregister handler error messages.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
ha_finish_errors()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 Error
|
@retval
|
||||||
|
!=0 Error
|
||||||
*/
|
*/
|
||||||
static int ha_finish_errors(void)
|
static int ha_finish_errors(void)
|
||||||
{
|
{
|
||||||
@ -567,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)
|
void ha_close_connection(THD* thd)
|
||||||
{
|
{
|
||||||
@ -578,17 +575,16 @@ void ha_close_connection(THD* thd)
|
|||||||
/* ========================================================================
|
/* ========================================================================
|
||||||
======================= TRANSACTIONS ===================================*/
|
======================= TRANSACTIONS ===================================*/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Register a storage engine for a transaction
|
Register a storage engine for a transaction.
|
||||||
|
|
||||||
DESCRIPTION
|
Every storage engine MUST call this function when it starts
|
||||||
Every storage engine MUST call this function when it starts
|
a transaction or a statement (that is it must be called both for the
|
||||||
a transaction or a statement (that is it must be called both for the
|
"beginning of transaction" and "beginning of statement").
|
||||||
"beginning of transaction" and "beginning of statement").
|
Only storage engines registered for the transaction/statement
|
||||||
Only storage engines registered for the transaction/statement
|
will know when to commit/rollback it.
|
||||||
will know when to commit/rollback it.
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
trans_register_ha is idempotent - storage engine may register many
|
trans_register_ha is idempotent - storage engine may register many
|
||||||
times per transaction.
|
times per transaction.
|
||||||
|
|
||||||
@ -620,10 +616,11 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
RETURN
|
@retval
|
||||||
0 - ok
|
0 ok
|
||||||
1 - error, transaction was rolled back
|
@retval
|
||||||
|
1 error, transaction was rolled back
|
||||||
*/
|
*/
|
||||||
int ha_prepare(THD *thd)
|
int ha_prepare(THD *thd)
|
||||||
{
|
{
|
||||||
@ -660,11 +657,19 @@ int ha_prepare(THD *thd)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
RETURN
|
@retval
|
||||||
0 - ok
|
0 ok
|
||||||
1 - transaction was rolled back
|
@retval
|
||||||
2 - error during commit, data may be inconsistent
|
1 transaction was rolled back
|
||||||
|
@retval
|
||||||
|
2 error during commit, data may be inconsistent
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Since we don't support nested statement transactions in 5.0,
|
||||||
|
we can't commit or rollback stmt transactions while we are inside
|
||||||
|
stored functions or triggers. So we simply do nothing now.
|
||||||
|
TODO: This should be fixed in later ( >= 5.1) releases.
|
||||||
*/
|
*/
|
||||||
int ha_commit_trans(THD *thd, bool all)
|
int ha_commit_trans(THD *thd, bool all)
|
||||||
{
|
{
|
||||||
@ -757,9 +762,9 @@ end:
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
NOTE - this function does not care about global read lock.
|
@note
|
||||||
A caller should.
|
This function does not care about global read lock. A caller should.
|
||||||
*/
|
*/
|
||||||
int ha_commit_one_phase(THD *thd, bool all)
|
int ha_commit_one_phase(THD *thd, bool all)
|
||||||
{
|
{
|
||||||
@ -869,13 +874,16 @@ int ha_rollback_trans(THD *thd, bool all)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
This is used to commit or rollback a single statement depending on the value
|
This is used to commit or rollback a single statement depending on
|
||||||
of error. Note that if the autocommit is on, then the following call inside
|
the value of error.
|
||||||
InnoDB will commit or rollback the whole transaction (= the statement). The
|
|
||||||
autocommit mechanism built into InnoDB is based on counting locks, but if
|
@note
|
||||||
the user has used LOCK TABLES then that mechanism does not know to do the
|
Note that if the autocommit is on, then the following call inside
|
||||||
commit.
|
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)
|
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
|
#ifndef DBUG_OFF
|
||||||
/* this does not need to be multi-byte safe or anything */
|
/**
|
||||||
|
@note
|
||||||
|
This does not need to be multi-byte safe or anything
|
||||||
|
*/
|
||||||
static char* xid_to_str(char *buf, XID *xid)
|
static char* xid_to_str(char *buf, XID *xid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -996,24 +1007,21 @@ static char* xid_to_str(char *buf, XID *xid)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
recover() step of xa
|
recover() step of xa.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
there are three modes of operation:
|
there are three modes of operation:
|
||||||
|
- automatic recover after a crash
|
||||||
- automatic recover after a crash
|
in this case commit_list != 0, tc_heuristic_recover==0
|
||||||
in this case commit_list != 0, tc_heuristic_recover==0
|
all xids from commit_list are committed, others are rolled back
|
||||||
all xids from commit_list are committed, others are rolled back
|
- manual (heuristic) recover
|
||||||
|
in this case commit_list==0, tc_heuristic_recover != 0
|
||||||
- manual (heuristic) recover
|
DBA has explicitly specified that all prepared transactions should
|
||||||
in this case commit_list==0, tc_heuristic_recover != 0
|
be committed (or rolled back).
|
||||||
DBA has explicitly specified that all prepared transactions should
|
- no recovery (MySQL did not detect a crash)
|
||||||
be committed (or rolled back).
|
in this case commit_list==0, tc_heuristic_recover == 0
|
||||||
|
there should be no prepared transactions in this case.
|
||||||
- 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
|
struct xarecover_st
|
||||||
{
|
{
|
||||||
@ -1146,10 +1154,10 @@ int ha_recover(HASH *commit_list)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
return the list of XID's to a client, the same way SHOW commands do
|
return the list of XID's to a client, the same way SHOW commands do.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
I didn't find in XA specs that an RM cannot return the same XID twice,
|
I didn't find in XA specs that an RM cannot return the same XID twice,
|
||||||
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
||||||
It can be easily fixed later, if necessary.
|
It can be easily fixed later, if necessary.
|
||||||
@ -1195,7 +1203,8 @@ bool mysql_xa_recover(THD *thd)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
|
@details
|
||||||
This function should be called when MySQL sends rows of a SELECT result set
|
This function should be called when MySQL sends rows of a SELECT result set
|
||||||
or the EOF mark to the client. It releases a possible adaptive hash index
|
or the EOF mark to the client. It releases a possible adaptive hash index
|
||||||
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
||||||
@ -1207,9 +1216,10 @@ bool mysql_xa_recover(THD *thd)
|
|||||||
performs another SQL query. In MySQL-4.1 this is even more important because
|
performs another SQL query. In MySQL-4.1 this is even more important because
|
||||||
there a connection can have several SELECT queries open at the same time.
|
there a connection can have several SELECT queries open at the same time.
|
||||||
|
|
||||||
arguments:
|
@param thd the thread handle of the current connection
|
||||||
thd: the thread handle of the current connection
|
|
||||||
return value: always 0
|
@return
|
||||||
|
always 0
|
||||||
*/
|
*/
|
||||||
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
||||||
void *unused)
|
void *unused)
|
||||||
@ -1276,8 +1286,9 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
note, that according to the sql standard (ISO/IEC 9075-2:2003)
|
@note
|
||||||
|
according to the sql standard (ISO/IEC 9075-2:2003)
|
||||||
section "4.33.4 SQL-statements and transaction states",
|
section "4.33.4 SQL-statements and transaction states",
|
||||||
SAVEPOINT is *not* transaction-initiating SQL-statement
|
SAVEPOINT is *not* transaction-initiating SQL-statement
|
||||||
*/
|
*/
|
||||||
@ -1573,8 +1584,9 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read first row (only) from a table
|
Read first row (only) from a table.
|
||||||
|
|
||||||
This is never called for InnoDB tables, as these table types
|
This is never called for InnoDB tables, as these table types
|
||||||
has the HA_STATS_RECORDS_IS_EXACT set.
|
has the HA_STATS_RECORDS_IS_EXACT set.
|
||||||
*/
|
*/
|
||||||
@ -1607,16 +1619,16 @@ int handler::read_first_row(uchar * buf, uint primary_key)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Generate the next auto-increment number based on increment and offset:
|
Generate the next auto-increment number based on increment and offset.
|
||||||
computes the lowest number
|
computes the lowest number
|
||||||
- strictly greater than "nr"
|
- strictly greater than "nr"
|
||||||
- of the form: auto_increment_offset + N * auto_increment_increment
|
- of the form: auto_increment_offset + N * auto_increment_increment
|
||||||
|
|
||||||
In most cases increment= offset= 1, in which case we get:
|
In most cases increment= offset= 1, in which case we get:
|
||||||
1,2,3,4,5,...
|
@verbatim 1,2,3,4,5,... @endverbatim
|
||||||
If increment=10 and offset=5 and previous number is 1, we get:
|
If increment=10 and offset=5 and previous number is 1, we get:
|
||||||
1,5,15,25,35,...
|
@verbatim 1,5,15,25,35,... @endverbatim
|
||||||
*/
|
*/
|
||||||
inline ulonglong
|
inline ulonglong
|
||||||
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
|
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
|
||||||
@ -1682,23 +1694,10 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update the auto_increment field if necessary
|
Update the auto_increment field if necessary.
|
||||||
|
|
||||||
SYNOPSIS
|
Updates columns with type NEXT_NUMBER if:
|
||||||
update_auto_increment()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
|
||||||
HA_ERR_AUTOINC_READ_FAILED
|
|
||||||
get_auto_increment() was called and returned ~(ulonglong) 0
|
|
||||||
HA_ERR_AUTOINC_ERANGE
|
|
||||||
storing value in field caused strict mode failure.
|
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
|
|
||||||
Updates the record's Field of type NEXT_NUMBER if:
|
|
||||||
|
|
||||||
- If column value is set to NULL (in which case
|
- If column value is set to NULL (in which case
|
||||||
auto_increment_field_not_null is 0)
|
auto_increment_field_not_null is 0)
|
||||||
@ -1749,13 +1748,20 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
|
|||||||
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
|
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
|
||||||
this list.
|
this list.
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
|
|
||||||
Replace all references to "next number" or NEXT_NUMBER to
|
Replace all references to "next number" or NEXT_NUMBER to
|
||||||
"auto_increment", everywhere (see below: there is
|
"auto_increment", everywhere (see below: there is
|
||||||
table->auto_increment_field_not_null, and there also exists
|
table->auto_increment_field_not_null, and there also exists
|
||||||
table->next_number_field, it's not consistent).
|
table->next_number_field, it's not consistent).
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 ok
|
||||||
|
@retval
|
||||||
|
HA_ERR_AUTOINC_READ_FAILED get_auto_increment() was called and
|
||||||
|
returned ~(ulonglong) 0
|
||||||
|
@retval
|
||||||
|
HA_ERR_AUTOINC_ERANGE storing value in field caused strict mode
|
||||||
|
failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
|
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
|
||||||
@ -2059,14 +2065,14 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Print error that we got from handler function
|
Print error that we got from handler function.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
In case of delete table it's only safe to use the following parts of
|
In case of delete table it's only safe to use the following parts of
|
||||||
the 'table' structure:
|
the 'table' structure:
|
||||||
table->s->path
|
- table->s->path
|
||||||
table->alias
|
- table->alias
|
||||||
*/
|
*/
|
||||||
void handler::print_error(int error, myf errflag)
|
void handler::print_error(int error, myf errflag)
|
||||||
{
|
{
|
||||||
@ -2253,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
|
@param error error code previously returned by handler
|
||||||
error error code previously returned by handler
|
@param buf pointer to String where to add error message
|
||||||
buf Pointer to String where to add error message
|
|
||||||
|
|
||||||
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)
|
bool handler::get_error_message(int error, String* buf)
|
||||||
{
|
{
|
||||||
@ -2367,8 +2373,10 @@ err:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Return key if error because of duplicated keys */
|
@return
|
||||||
|
key if error because of duplicated keys
|
||||||
|
*/
|
||||||
uint handler::get_dup_key(int error)
|
uint handler::get_dup_key(int error)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("handler::get_dup_key");
|
DBUG_ENTER("handler::get_dup_key");
|
||||||
@ -2381,21 +2389,20 @@ uint handler::get_dup_key(int error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Delete all files with extension from bas_ext()
|
Delete all files with extension from bas_ext().
|
||||||
|
|
||||||
SYNOPSIS
|
@param name Base name of table
|
||||||
delete_table()
|
|
||||||
name Base name of table
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
We assume that the handler may return more extensions than
|
We assume that the handler may return more extensions than
|
||||||
was actually used for the file.
|
was actually used for the file.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 If we successfully deleted at least one file from base_ext and
|
0 If we successfully deleted at least one file from base_ext and
|
||||||
didn't get any other errors than ENOENT
|
didn't get any other errors than ENOENT
|
||||||
# Error
|
@retval
|
||||||
|
!0 Error
|
||||||
*/
|
*/
|
||||||
int handler::delete_table(const char *name)
|
int handler::delete_table(const char *name)
|
||||||
{
|
{
|
||||||
@ -2442,21 +2449,20 @@ void handler::drop_table(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Performs checks upon the table.
|
Performs checks upon the table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread doing CHECK TABLE operation
|
||||||
check()
|
@param check_opt options from the parser
|
||||||
thd thread doing CHECK TABLE operation
|
|
||||||
check_opt options from the parser
|
|
||||||
|
|
||||||
NOTES
|
@retval
|
||||||
|
HA_ADMIN_OK Successful upgrade
|
||||||
RETURN
|
@retval
|
||||||
HA_ADMIN_OK Successful upgrade
|
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
@retval
|
||||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||||
HA_ADMIN_NOT_IMPLEMENTED
|
@retval
|
||||||
|
HA_ADMIN_NOT_IMPLEMENTED
|
||||||
*/
|
*/
|
||||||
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
||||||
{
|
{
|
||||||
@ -2491,7 +2497,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Tell the storage engine that it is allowed to "disable transaction" in the
|
Tell the storage engine that it is allowed to "disable transaction" in the
|
||||||
handler. It is a hint that ACID is not required - it is used in NDB for
|
handler. It is a hint that ACID is not required - it is used in NDB for
|
||||||
ALTER TABLE, for example, when data are copied to temporary table.
|
ALTER TABLE, for example, when data are copied to temporary table.
|
||||||
@ -2559,15 +2565,12 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
|||||||
** Some general functions that isn't in the handler class
|
** Some general functions that isn't in the handler class
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Initiates table-file and calls appropriate database-creator
|
Initiates table-file and calls appropriate database-creator.
|
||||||
|
|
||||||
NOTES
|
@retval
|
||||||
We must have a write lock on LOCK_open to be sure no other thread
|
|
||||||
interferes with table
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
int ha_create_table(THD *thd, const char *path,
|
int ha_create_table(THD *thd, const char *path,
|
||||||
@ -2605,17 +2608,18 @@ err:
|
|||||||
DBUG_RETURN(error != 0);
|
DBUG_RETURN(error != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Try to discover table from engine
|
Try to discover table from engine.
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If found, write the frm file to disk.
|
If found, write the frm file to disk.
|
||||||
|
|
||||||
RETURN VALUES:
|
@retval
|
||||||
-1 Table did not exists
|
-1 Table did not exists
|
||||||
|
@retval
|
||||||
0 Table created ok
|
0 Table created ok
|
||||||
|
@retval
|
||||||
> 0 Error, table existed but could not be created
|
> 0 Error, table existed but could not be created
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
|
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
|
||||||
{
|
{
|
||||||
@ -2687,8 +2691,8 @@ void st_ha_check_opt::init()
|
|||||||
call to ha_init_key_cache() (probably out of memory)
|
call to ha_init_key_cache() (probably out of memory)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Init a key cache if it has not been initied before
|
Init a key cache if it has not been initied before.
|
||||||
*/
|
*/
|
||||||
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
@ -2711,8 +2715,8 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Resize key cache
|
Resize key cache.
|
||||||
*/
|
*/
|
||||||
int ha_resize_key_cache(KEY_CACHE *key_cache)
|
int ha_resize_key_cache(KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
@ -2734,7 +2738,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Change parameters for key cache (like size)
|
Change parameters for key cache (like size)
|
||||||
*/
|
*/
|
||||||
int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
||||||
@ -2750,8 +2754,8 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Free memory allocated by a key cache
|
Free memory allocated by a key cache.
|
||||||
*/
|
*/
|
||||||
int ha_end_key_cache(KEY_CACHE *key_cache)
|
int ha_end_key_cache(KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
@ -2759,8 +2763,8 @@ int ha_end_key_cache(KEY_CACHE *key_cache)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Move all tables from one key cache to another one
|
Move all tables from one key cache to another one.
|
||||||
*/
|
*/
|
||||||
int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
||||||
KEY_CACHE *new_key_cache)
|
KEY_CACHE *new_key_cache)
|
||||||
@ -2770,13 +2774,15 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Try to discover one table from handler(s)
|
Try to discover one table from handler(s).
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
-1 : Table did not exists
|
-1 Table did not exists
|
||||||
0 : OK. In this case *frmblob and *frmlen are set
|
@retval
|
||||||
>0 : error. frmblob and frmlen may not be set
|
0 OK. In this case *frmblob and *frmlen are set
|
||||||
|
@retval
|
||||||
|
>0 error. frmblob and frmlen may not be set
|
||||||
*/
|
*/
|
||||||
struct st_discover_args
|
struct st_discover_args
|
||||||
{
|
{
|
||||||
@ -2821,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
|
Call this function in order to give the handler the possiblity
|
||||||
to ask engine if there are any new tables that should be written to disk
|
to ask engine if there are any new tables that should be written to disk
|
||||||
or any dropped tables that need to be removed from disk
|
or any dropped tables that need to be removed from disk
|
||||||
*/
|
*/
|
||||||
struct st_find_files_args
|
struct st_find_files_args
|
||||||
@ -2866,16 +2872,15 @@ ha_find_files(THD *thd,const char *db,const char *path,
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Ask handler if the table exists in engine
|
Ask handler if the table exists in engine.
|
||||||
|
@retval
|
||||||
RETURN
|
|
||||||
HA_ERR_NO_SUCH_TABLE Table does not exist
|
HA_ERR_NO_SUCH_TABLE Table does not exist
|
||||||
|
@retval
|
||||||
HA_ERR_TABLE_EXIST Table exists
|
HA_ERR_TABLE_EXIST Table exists
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct st_table_exists_in_engine_args
|
struct st_table_exists_in_engine_args
|
||||||
{
|
{
|
||||||
const char *db;
|
const char *db;
|
||||||
@ -3050,29 +3055,29 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read the first row of a multi-range set.
|
Read the first row of a multi-range set.
|
||||||
|
|
||||||
SYNOPSIS
|
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||||
read_multi_range_first()
|
corresponds to the returned row.
|
||||||
found_range_p Returns a pointer to the element in 'ranges' that
|
@param ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||||
corresponds to the returned row.
|
@param range_count Number of ranges in 'ranges'.
|
||||||
ranges An array of KEY_MULTI_RANGE range descriptions.
|
@param sorted If result should be sorted per key.
|
||||||
range_count Number of ranges in 'ranges'.
|
@param buffer A HANDLER_BUFFER for internal handler usage.
|
||||||
sorted If result should be sorted per key.
|
|
||||||
buffer A HANDLER_BUFFER for internal handler usage.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0].
|
- Record is read into table->record[0].
|
||||||
*found_range_p returns a valid value only if read_multi_range_first()
|
- *found_range_p returns a valid value only if read_multi_range_first()
|
||||||
returns 0.
|
returns 0.
|
||||||
Sorting is done within each range. If you want an overall sort, enter
|
- Sorting is done within each range. If you want an overall sort, enter
|
||||||
'ranges' with sorted ranges.
|
'ranges' with sorted ranges.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK, found a row
|
0 OK, found a row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||||
KEY_MULTI_RANGE *ranges, uint range_count,
|
KEY_MULTI_RANGE *ranges, uint range_count,
|
||||||
@ -3106,23 +3111,23 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read the next row of a multi-range set.
|
Read the next row of a multi-range set.
|
||||||
|
|
||||||
SYNOPSIS
|
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||||
read_multi_range_next()
|
corresponds to the returned row.
|
||||||
found_range_p Returns a pointer to the element in 'ranges' that
|
|
||||||
corresponds to the returned row.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0].
|
- Record is read into table->record[0].
|
||||||
*found_range_p returns a valid value only if read_multi_range_next()
|
- *found_range_p returns a valid value only if read_multi_range_next()
|
||||||
returns 0.
|
returns 0.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK, found a row
|
0 OK, found a row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No (more) rows in range
|
HA_ERR_END_OF_FILE No (more) rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
||||||
{
|
{
|
||||||
@ -3176,25 +3181,24 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read first row between two ranges.
|
Read first row between two ranges.
|
||||||
Store ranges for future calls to read_range_next
|
Store ranges for future calls to read_range_next.
|
||||||
|
|
||||||
SYNOPSIS
|
@param start_key Start key. Is 0 if no min range
|
||||||
read_range_first()
|
@param end_key End key. Is 0 if no max range
|
||||||
start_key Start key. Is 0 if no min range
|
@param eq_range_arg Set to 1 if start_key == end_key
|
||||||
end_key End key. Is 0 if no max range
|
@param sorted Set to 1 if result should be sorted per key
|
||||||
eq_range_arg Set to 1 if start_key == end_key and the range endpoints
|
|
||||||
will not change during query execution.
|
|
||||||
sorted Set to 1 if result should be sorted per key
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0]
|
Record is read into table->record[0]
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Found row
|
0 Found row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_range_first(const key_range *start_key,
|
int handler::read_range_first(const key_range *start_key,
|
||||||
const key_range *end_key,
|
const key_range *end_key,
|
||||||
@ -3230,19 +3234,18 @@ int handler::read_range_first(const key_range *start_key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read next row between two ranges.
|
Read next row between two ranges.
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
read_range_next()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
Record is read into table->record[0]
|
Record is read into table->record[0]
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Found row
|
0 Found row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_range_next()
|
int handler::read_range_next()
|
||||||
{
|
{
|
||||||
@ -3263,22 +3266,20 @@ int handler::read_range_next()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Compare if found key (in row) is over max-value
|
Compare if found key (in row) is over max-value.
|
||||||
|
|
||||||
SYNOPSIS
|
@param range range to compare to row. May be 0 for no range
|
||||||
compare_key
|
|
||||||
range range to compare to row. May be 0 for no range
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
See key.cc::key_cmp() for details
|
|
||||||
|
|
||||||
RETURN
|
@seealso
|
||||||
|
key.cc::key_cmp()
|
||||||
|
|
||||||
|
@return
|
||||||
The return value is SIGN(key_in_row - range_key):
|
The return value is SIGN(key_in_row - range_key):
|
||||||
|
|
||||||
0 Key is equal to range or 'range' == 0 (no range)
|
- 0 : Key is equal to range or 'range' == 0 (no range)
|
||||||
-1 Key is less than range
|
- -1 : Key is less than range
|
||||||
1 Key is larger than range
|
- 1 : Key is larger than range
|
||||||
*/
|
*/
|
||||||
int handler::compare_key(key_range *range)
|
int handler::compare_key(key_range *range)
|
||||||
{
|
{
|
||||||
@ -3307,18 +3308,14 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Returns a list of all known extensions.
|
Returns a list of all known extensions.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
ha_known_exts()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
No mutexes, worst case race is a minor surplus memory allocation
|
No mutexes, worst case race is a minor surplus memory allocation
|
||||||
We have to recreate the extension map if mysqld is restarted (for example
|
We have to recreate the extension map if mysqld is restarted (for example
|
||||||
within libmysqld)
|
within libmysqld)
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
pointer pointer to TYPELIB structure
|
pointer pointer to TYPELIB structure
|
||||||
*/
|
*/
|
||||||
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
||||||
|
@ -14,9 +14,14 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get hostname for an IP. Hostnames are checked with reverse name lookup and
|
@file
|
||||||
checked that they doesn't resemble an ip.
|
|
||||||
|
@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"
|
#include "mysql_priv.h"
|
||||||
|
@ -14,7 +14,12 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Init and dummy functions for interface with unireg */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Init and dummy functions for interface with unireg
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Buffers to save and compare item values */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Buffers to save and compare item values
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Create right type of Cached_item for an item
|
Create right type of Cached_item for an item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Cached_item *new_Cached_item(THD *thd, Item *item)
|
Cached_item *new_Cached_item(THD *thd, Item *item)
|
||||||
@ -45,9 +50,11 @@ Cached_item *new_Cached_item(THD *thd, Item *item)
|
|||||||
|
|
||||||
Cached_item::~Cached_item() {}
|
Cached_item::~Cached_item() {}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Compare with old value and replace value with new value
|
Compare with old value and replace value with new value.
|
||||||
** Return true if values have changed
|
|
||||||
|
@return
|
||||||
|
Return true if values have changed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
||||||
|
@ -14,7 +14,12 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all compare functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all compare functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
@ -104,7 +109,7 @@ static int cmp_row_type(Item* item1, Item* item2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Aggregates result types from the array of items.
|
Aggregates result types from the array of items.
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
@ -117,11 +122,13 @@ static int cmp_row_type(Item* item1, Item* item2)
|
|||||||
This function aggregates result types from the array of items. Found type
|
This function aggregates result types from the array of items. Found type
|
||||||
supposed to be used later for comparison of values of these items.
|
supposed to be used later for comparison of values of these items.
|
||||||
Aggregation itself is performed by the item_cmp_type() function.
|
Aggregation itself is performed by the item_cmp_type() function.
|
||||||
The function also checks compatibility of row signatures for the
|
@param[out] type the aggregated type
|
||||||
submitted items (see the spec for the cmp_row_type function).
|
@param items array of items to aggregate the type from
|
||||||
|
@param nitems number of items in the array
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 type incompatibility has been detected
|
1 type incompatibility has been detected
|
||||||
|
@retval
|
||||||
0 otherwise
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -257,10 +264,11 @@ void Item_func_not::print(String *str)
|
|||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
special NOT for ALL subquery
|
special NOT for ALL subquery.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_not_all::val_int()
|
longlong Item_func_not_all::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
@ -293,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
|
Special NOP (No OPeration) for ALL subquery. It is like
|
||||||
(return TRUE if underlying subquery do not return rows) but if subquery
|
Item_func_not_all.
|
||||||
returns some rows it return same value as argument (TRUE/FALSE).
|
|
||||||
|
@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()
|
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.
|
The function converts a constant expression or string to an integer.
|
||||||
On successful conversion the original item is substituted for the
|
On successful conversion the original item is substituted for the
|
||||||
result of the item evaluation.
|
result of the item evaluation.
|
||||||
@ -333,16 +337,21 @@ longlong Item_func_nop_all::val_int()
|
|||||||
also when comparing bigint to strings (in which case strings
|
also when comparing bigint to strings (in which case strings
|
||||||
are converted to bigints).
|
are converted to bigints).
|
||||||
|
|
||||||
NOTES
|
@param thd thread handle
|
||||||
|
@param field item will be converted using the type of this field
|
||||||
|
@param[in,out] item reference to the item to convert
|
||||||
|
|
||||||
|
@note
|
||||||
This function is called only at prepare stage.
|
This function is called only at prepare stage.
|
||||||
As all derived tables are filled only after all derived tables
|
As all derived tables are filled only after all derived tables
|
||||||
are prepared we do not evaluate items with subselects here because
|
are prepared we do not evaluate items with subselects here because
|
||||||
they can contain derived tables and thus we may attempt to use a
|
they can contain derived tables and thus we may attempt to use a
|
||||||
table that has not been populated yet.
|
table that has not been populated yet.
|
||||||
|
|
||||||
RESULT VALUES
|
@retval
|
||||||
0 Can't convert item
|
0 Can't convert item
|
||||||
1 Item was replaced with an integer version of the item
|
@retval
|
||||||
|
1 Item was replaced with an integer version of the item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool convert_constant_item(THD *thd, Field *field, Item **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.
|
Compare strings byte by byte. End spaces are also compared.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
< 0 *a < *b
|
<0 *a < *b
|
||||||
0 *b == *b
|
@retval
|
||||||
> 0 *a > *b
|
0 *b == *b
|
||||||
|
@retval
|
||||||
|
>0 *a > *b
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Arg_comparator::compare_binary_string()
|
int Arg_comparator::compare_binary_string()
|
||||||
@ -1041,10 +1052,11 @@ int Arg_comparator::compare_binary_string()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare strings, but take into account that NULL == NULL
|
Compare strings, but take into account that NULL == NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int Arg_comparator::compare_e_string()
|
int Arg_comparator::compare_e_string()
|
||||||
{
|
{
|
||||||
String *res1,*res2;
|
String *res1,*res2;
|
||||||
@ -1185,7 +1197,7 @@ int Arg_comparator::compare_int_signed()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare values as BIGINT UNSIGNED.
|
Compare values as BIGINT UNSIGNED.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1208,7 +1220,7 @@ int Arg_comparator::compare_int_unsigned()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare signed (*a) with unsigned (*B)
|
Compare signed (*a) with unsigned (*B)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1233,7 +1245,7 @@ int Arg_comparator::compare_int_signed_unsigned()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare unsigned (*a) with signed (*B)
|
Compare unsigned (*a) with signed (*B)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1269,7 +1281,7 @@ int Arg_comparator::compare_e_int()
|
|||||||
return test(val1 == val2);
|
return test(val1 == val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
||||||
*/
|
*/
|
||||||
int Arg_comparator::compare_e_int_diff_signedness()
|
int Arg_comparator::compare_e_int_diff_signedness()
|
||||||
@ -1558,7 +1570,7 @@ longlong Item_func_eq::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Same as Item_func_eq, but NULL = NULL */
|
/** Same as Item_func_eq, but NULL = NULL. */
|
||||||
|
|
||||||
void Item_func_equal::fix_length_and_dec()
|
void Item_func_equal::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
@ -1709,21 +1721,18 @@ void Item_func_interval::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute Item_func_interval()
|
Execute Item_func_interval().
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
Item_func_interval::val_int()
|
If we are doing a decimal comparison, we are evaluating the first
|
||||||
|
item twice.
|
||||||
|
|
||||||
NOTES
|
@return
|
||||||
If we are doing a decimal comparison, we are
|
- -1 if null value,
|
||||||
evaluating the first item twice.
|
- 0 if lower than lowest
|
||||||
|
- 1 - arg_count-1 if between args[n] and args[n+1]
|
||||||
RETURN
|
- arg_count if higher than biggest argument
|
||||||
-1 if null value,
|
|
||||||
0 if lower than lowest
|
|
||||||
1 - arg_count-1 if between args[n] and args[n+1]
|
|
||||||
arg_count if higher than biggest argument
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_interval::val_int()
|
longlong Item_func_interval::val_int()
|
||||||
@ -1795,32 +1804,31 @@ longlong Item_func_interval::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of a BETWEEN item tree
|
Perform context analysis of a BETWEEN item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_between as its root.
|
various attributes of the item tree with Item_func_between as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
|
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
|
||||||
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2156,30 +2164,29 @@ Item_func_ifnull::str_op(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of an IF item tree
|
Perform context analysis of an IF item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_if as its root.
|
various attributes of the item tree with Item_func_if as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
||||||
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2321,11 +2328,14 @@ Item_func_nullif::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
nullif () returns NULL if arguments are equal, else it returns the
|
@note
|
||||||
first argument.
|
|
||||||
Note that we have to evaluate the first argument twice as the compare
|
Note that we have to evaluate the first argument twice as the compare
|
||||||
may have been done with a different type than return value
|
may have been done with a different type than return value
|
||||||
|
@return
|
||||||
|
NULL if arguments are equal
|
||||||
|
@return
|
||||||
|
the first argument if not equal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double
|
double
|
||||||
@ -2397,14 +2407,7 @@ Item_func_nullif::is_null()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return the matching ITEM or NULL if all compares (including else) failed
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
find_item()
|
|
||||||
str Buffer string
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Find and return matching items for CASE or ELSE item if all compares
|
Find and return matching items for CASE or ELSE item if all compares
|
||||||
are failed or NULL if ELSE item isn't defined.
|
are failed or NULL if ELSE item isn't defined.
|
||||||
|
|
||||||
@ -2418,9 +2421,10 @@ Item_func_nullif::is_null()
|
|||||||
to it according to their int values i.e. STRING_RESULT is mapped to bit
|
to it according to their int values i.e. STRING_RESULT is mapped to bit
|
||||||
0, REAL_RESULT to bit 1, so on.
|
0, REAL_RESULT to bit 1, so on.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL - Nothing found and there is no ELSE expression defined
|
NULL Nothing found and there is no ELSE expression defined
|
||||||
item - Found item or ELSE item if defined and all comparisons are
|
@retval
|
||||||
|
item Found item or ELSE item if defined and all comparisons are
|
||||||
failed
|
failed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2645,7 +2649,10 @@ uint Item_func_case::decimal_precision() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TODO: Fix this so that it prints the whole CASE expression */
|
/**
|
||||||
|
@todo
|
||||||
|
Fix this so that it prints the whole CASE expression
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_func_case::print(String *str)
|
void Item_func_case::print(String *str)
|
||||||
{
|
{
|
||||||
@ -2687,7 +2694,7 @@ void Item_func_case::cleanup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Coalesce - return first not NULL argument.
|
Coalesce - return first not NULL argument.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3305,32 +3312,31 @@ bool Item_func_in::nulls_in_row()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of an IN item tree
|
Perform context analysis of an IN item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_in as its root.
|
various attributes of the item tree with Item_func_in as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
|
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
|
||||||
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3805,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
|
Transform an Item_cond object with a transformer callback function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
transform()
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function recursively applies the transform method to each
|
The function recursively applies the transform method to each
|
||||||
member item of the condition list.
|
member item of the condition list.
|
||||||
If the call of the method for a member item returns a new item
|
If the call of the method for a member item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_cond object.
|
of the Item_cond object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param transformer the transformer callback function to be applied to
|
||||||
Item returned as the result of transformation of the root node
|
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)
|
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
|
Compile Item_cond object with a processor and a transformer
|
||||||
|
callback functions.
|
||||||
SYNOPSIS
|
|
||||||
compile()
|
|
||||||
analyzer the analyzer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_p in/out parameter to be passed to the analyzer
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_t parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
First the function applies the analyzer to the root node of
|
First the function applies the analyzer to the root node of
|
||||||
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
||||||
the function recursively applies the compile method to member
|
the function recursively applies the compile method to member
|
||||||
@ -3872,9 +3866,16 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
|||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_cond object.
|
of the Item_cond object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param analyzer the analyzer callback function to be applied to the
|
||||||
Item returned as the result of transformation of the root node
|
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,
|
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
|
The split is done to get an unique item for each SUM function
|
||||||
split_sum_func()
|
so that we can easily find and calculate them.
|
||||||
thd Thread handler
|
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||||
ref_pointer_array Pointer to array of reference fields
|
sql_select.cc)
|
||||||
fields All fields in select
|
|
||||||
|
|
||||||
NOTES
|
@param thd Thread handler
|
||||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
@param ref_pointer_array Pointer to array of reference fields
|
||||||
that have or refer (HAVING) to a SUM expression.
|
@param fields All fields in select
|
||||||
|
|
||||||
The split is done to get an unique item for each SUM function
|
@note
|
||||||
so that we can easily find and calculate them.
|
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
that have or refer (HAVING) to a SUM expression.
|
||||||
sql_select.cc)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
@ -4010,20 +4009,22 @@ void Item_cond::neg_arguments(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Evaluation of AND(expr, expr, expr ...)
|
Evaluation of AND(expr, expr, expr ...).
|
||||||
|
|
||||||
NOTES:
|
@note
|
||||||
abort_if_null is set for AND expressions for which we don't care if the
|
abort_if_null is set for AND expressions for which we don't care if the
|
||||||
result is NULL or 0. This is set for:
|
result is NULL or 0. This is set for:
|
||||||
- WHERE clause
|
- WHERE clause
|
||||||
- HAVING clause
|
- HAVING clause
|
||||||
- IF(expression)
|
- IF(expression)
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 If all expressions are true
|
1 If all expressions are true
|
||||||
|
@retval
|
||||||
0 If all expressions are false or if we find a NULL expression and
|
0 If all expressions are false or if we find a NULL expression and
|
||||||
'abort_on_null' is set.
|
'abort_on_null' is set.
|
||||||
|
@retval
|
||||||
NULL if all expression are either 1 or NULL
|
NULL if all expression are either 1 or NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4065,24 +4066,23 @@ longlong Item_cond_or::val_int()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create an AND expression from two expressions
|
Create an AND expression from two expressions.
|
||||||
|
|
||||||
SYNOPSIS
|
@param a expression or NULL
|
||||||
and_expressions()
|
@param b expression.
|
||||||
a expression or NULL
|
@param org_item Don't modify a if a == *org_item.
|
||||||
b expression.
|
If a == NULL, org_item is set to point at b,
|
||||||
org_item Don't modify a if a == *org_item
|
to ensure that future calls will not modify b.
|
||||||
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
|
This will not modify item pointed to by org_item or b
|
||||||
The idea is that one can call this in a loop and create and
|
The idea is that one can call this in a loop and create and
|
||||||
'and' over all items without modifying any of the original items.
|
'and' over all items without modifying any of the original items.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL Error
|
NULL Error
|
||||||
|
@retval
|
||||||
Item
|
Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4140,7 +4140,9 @@ longlong Item_is_not_null_test::val_int()
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Optimize case of not_null_column IS NULL */
|
/**
|
||||||
|
Optimize case of not_null_column IS NULL.
|
||||||
|
*/
|
||||||
void Item_is_not_null_test::update_used_tables()
|
void Item_is_not_null_test::update_used_tables()
|
||||||
{
|
{
|
||||||
if (!args[0]->maybe_null)
|
if (!args[0]->maybe_null)
|
||||||
@ -4200,7 +4202,9 @@ longlong Item_func_like::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We can optimize a where if first character isn't a wildcard */
|
/**
|
||||||
|
We can optimize a where if first character isn't a wildcard
|
||||||
|
*/
|
||||||
|
|
||||||
Item_func::optimize_type Item_func_like::select_optimize() const
|
Item_func::optimize_type Item_func_like::select_optimize() const
|
||||||
{
|
{
|
||||||
@ -4463,10 +4467,9 @@ void Item_func_regex::cleanup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_suffixes()
|
|
||||||
Precomputation dependent only on pattern_len.
|
Precomputation dependent only on pattern_len.
|
||||||
**********************************************************************/
|
*/
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_suffixes(int *suff)
|
void Item_func_like::turboBM_compute_suffixes(int *suff)
|
||||||
{
|
{
|
||||||
@ -4520,10 +4523,9 @@ void Item_func_like::turboBM_compute_suffixes(int *suff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_good_suffix_shifts()
|
Precomputation dependent only on pattern_len.
|
||||||
Precomputation dependent only on pattern_len.
|
*/
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
||||||
{
|
{
|
||||||
@ -4565,10 +4567,9 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_bad_character_shifts()
|
Precomputation dependent on pattern_len.
|
||||||
Precomputation dependent on pattern_len.
|
*/
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_bad_character_shifts()
|
void Item_func_like::turboBM_compute_bad_character_shifts()
|
||||||
{
|
{
|
||||||
@ -4594,10 +4595,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_matches()
|
Search for pattern in text.
|
||||||
Search for pattern in text, returns true/false for match/no match
|
|
||||||
**********************************************************************/
|
@return
|
||||||
|
returns true/false for match/no match
|
||||||
|
*/
|
||||||
|
|
||||||
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
||||||
{
|
{
|
||||||
@ -4677,24 +4680,20 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Make a logical XOR of the arguments.
|
Make a logical XOR of the arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
val_int()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
If either operator is NULL, return NULL.
|
If either operator is NULL, return NULL.
|
||||||
|
|
||||||
NOTE
|
@todo
|
||||||
As we don't do any index optimization on XOR this is not going to be
|
(low priority) Change this to be optimized as: @n
|
||||||
very fast to use.
|
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
|
||||||
|
|
||||||
TODO (low priority)
|
|
||||||
Change this to be optimized as:
|
|
||||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
|
|
||||||
To be able to do this, we would however first have to extend the MySQL
|
To be able to do this, we would however first have to extend the MySQL
|
||||||
range optimizer to handle OR better.
|
range optimizer to handle OR better.
|
||||||
|
|
||||||
|
@note
|
||||||
|
As we don't do any index optimization on XOR this is not going to be
|
||||||
|
very fast to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_cond_xor::val_int()
|
longlong Item_cond_xor::val_int()
|
||||||
@ -4716,15 +4715,12 @@ longlong Item_cond_xor::val_int()
|
|||||||
return (longlong) result;
|
return (longlong) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Apply NOT transformation to the item and return a new one.
|
Apply NOT transformation to the item and return a new one.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
neg_transformer()
|
|
||||||
thd thread handler
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Transform the item using next rules:
|
Transform the item using next rules:
|
||||||
|
@verbatim
|
||||||
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
||||||
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
||||||
NOT(a) -> a
|
NOT(a) -> a
|
||||||
@ -4736,8 +4732,11 @@ longlong Item_cond_xor::val_int()
|
|||||||
a <= b -> a > b
|
a <= b -> a > b
|
||||||
IS NULL(a) -> IS NOT NULL(a)
|
IS NULL(a) -> IS NOT NULL(a)
|
||||||
IS NOT NULL(a) -> IS NULL(a)
|
IS NOT NULL(a) -> IS NULL(a)
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@param thd thread handler
|
||||||
|
|
||||||
|
@return
|
||||||
New item or
|
New item or
|
||||||
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
|
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
|
||||||
*/
|
*/
|
||||||
@ -4755,7 +4754,9 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* a IS NULL -> a IS NOT NULL */
|
/**
|
||||||
|
a IS NULL -> a IS NOT NULL.
|
||||||
|
*/
|
||||||
Item *Item_func_isnull::neg_transformer(THD *thd)
|
Item *Item_func_isnull::neg_transformer(THD *thd)
|
||||||
{
|
{
|
||||||
Item *item= new Item_func_isnotnull(args[0]);
|
Item *item= new Item_func_isnotnull(args[0]);
|
||||||
@ -4763,7 +4764,9 @@ Item *Item_func_isnull::neg_transformer(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* a IS NOT NULL -> a IS NULL */
|
/**
|
||||||
|
a IS NOT NULL -> a IS NULL.
|
||||||
|
*/
|
||||||
Item *Item_func_isnotnull::neg_transformer(THD *thd)
|
Item *Item_func_isnotnull::neg_transformer(THD *thd)
|
||||||
{
|
{
|
||||||
Item *item= new Item_func_isnull(args[0]);
|
Item *item= new Item_func_isnull(args[0]);
|
||||||
@ -4846,7 +4849,9 @@ Item *Item_func_le::negated_item() /* a <= b -> a > b */
|
|||||||
return new Item_func_gt(args[0], args[1]);
|
return new Item_func_gt(args[0], args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// just fake method, should never be called
|
/**
|
||||||
|
just fake method, should never be called.
|
||||||
|
*/
|
||||||
Item *Item_bool_rowready_func2::negated_item()
|
Item *Item_bool_rowready_func2::negated_item()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@ -4911,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
|
The function checks whether field is occurred in the Item_equal object .
|
||||||
contains()
|
|
||||||
field field whose occurrence is to be checked
|
@param field field whose occurrence is to be checked
|
||||||
|
|
||||||
DESCRIPTION
|
@retval
|
||||||
The function checks whether field is occurred in the Item_equal object
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
1 if nultiple equality contains a reference to field
|
1 if nultiple equality contains a reference to field
|
||||||
0 otherwise
|
@retval
|
||||||
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Item_equal::contains(Field *field)
|
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.
|
The function actually merges two multiple equalities.
|
||||||
After this operation the Item_equal object additionally contains
|
After this operation the Item_equal object additionally contains
|
||||||
the field items of another item of the type Item_equal.
|
the field items of another item of the type Item_equal.
|
||||||
If the optional constant items are not equal the cond_false flag is
|
If the optional constant items are not equal the cond_false flag is
|
||||||
set to 1.
|
set to 1.
|
||||||
|
@param item multiple equality whose members are to be joined
|
||||||
RETURN VALUES
|
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::merge(Item_equal *item)
|
void Item_equal::merge(Item_equal *item)
|
||||||
@ -4974,28 +4970,21 @@ void Item_equal::merge(Item_equal *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Order field items in multiple equality according to a sorting criteria
|
Order field items in multiple equality according to a sorting criteria.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
sort()
|
|
||||||
cmp function to compare field item
|
|
||||||
arg context extra parameter for the cmp function
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function perform ordering of the field items in the Item_equal
|
The function perform ordering of the field items in the Item_equal
|
||||||
object according to the criteria determined by the cmp callback parameter.
|
object according to the criteria determined by the cmp callback parameter.
|
||||||
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
||||||
placed after item_fiel2.
|
placed after item_fiel2.
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
The function sorts field items by the exchange sort algorithm.
|
The function sorts field items by the exchange sort algorithm.
|
||||||
The list of field items is looked through and whenever two neighboring
|
The list of field items is looked through and whenever two neighboring
|
||||||
members follow in a wrong order they are swapped. This is performed
|
members follow in a wrong order they are swapped. This is performed
|
||||||
again and again until we get all members in a right order.
|
again and again until we get all members in a right order.
|
||||||
|
|
||||||
RETURN VALUES
|
@param cmp function to compare field item
|
||||||
None
|
@param arg context extra parameter for the cmp function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
||||||
@ -5030,21 +5019,14 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check appearance of new constant items in the multiple equality object
|
Check appearance of new constant items in the multiple equality object.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
update_const()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function checks appearance of new constant items among
|
The function checks appearance of new constant items among
|
||||||
the members of multiple equalities. Each new constant item is
|
the members of multiple equalities. Each new constant item is
|
||||||
compared with the designated constant item if there is any in the
|
compared with the designated constant item if there is any in the
|
||||||
multiple equality. If there is none the first new constant item
|
multiple equality. If there is none the first new constant item
|
||||||
becomes designated.
|
becomes designated.
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::update_const()
|
void Item_equal::update_const()
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/* Functions to create an item. Used by sql_yacc.yy */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Functions to create an item. Used by sql_yac.yy
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "item_create.h"
|
#include "item_create.h"
|
||||||
|
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all numerical functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all numerical functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
@ -46,7 +51,10 @@ bool check_reserved_words(LEX_STRING *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return TRUE if item is a constant */
|
/**
|
||||||
|
@return
|
||||||
|
TRUE if item is a constant
|
||||||
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
eval_const_cond(COND *cond)
|
eval_const_cond(COND *cond)
|
||||||
@ -237,25 +245,21 @@ void Item_func::traverse_cond(Cond_traverser traverser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Transform an Item_func object with a transformer callback function
|
Transform an Item_func object with a transformer callback function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
transform()
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
argument parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function recursively applies the transform method to each
|
The function recursively applies the transform method to each
|
||||||
argument of the Item_func node.
|
argument of the Item_func node.
|
||||||
If the call of the method for an argument item returns a new item
|
If the call of the method for an argument item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_func object.
|
of the Item_func object.
|
||||||
|
@param transformer the transformer callback function to be applied to
|
||||||
RETURN VALUES
|
the nodes of the tree of the object
|
||||||
Item returned as the result of transformation of the root node
|
@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)
|
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
|
Compile Item_func object with a processor and a transformer
|
||||||
|
callback functions.
|
||||||
SYNOPSIS
|
|
||||||
compile()
|
|
||||||
analyzer the analyzer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_p in/out parameter to be passed to the processor
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_t parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
First the function applies the analyzer to the root node of
|
First the function applies the analyzer to the root node of
|
||||||
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
||||||
the function recursively applies the compile method to each argument
|
the function recursively applies the compile method to each argument
|
||||||
@ -306,9 +301,16 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
|||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_func object.
|
of the Item_func object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param analyzer the analyzer callback function to be applied to the
|
||||||
Item returned as the result of transformation of the root node
|
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,
|
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);
|
return (this->*transformer)(arg_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See comments in Item_cmp_func::split_sum_func() */
|
/**
|
||||||
|
See comments in Item_cmp_func::split_sum_func()
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &fields)
|
List<Item> &fields)
|
||||||
@ -523,12 +527,9 @@ void Item_func_numhybrid::fix_num_length_and_dec()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length/decimals of function if function is fixed point and
|
Set max_length/decimals of function if function is fixed point and
|
||||||
result length/precision depends on argument ones
|
result length/precision depends on argument ones.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_decimal_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_decimal_length()
|
void Item_func::count_decimal_length()
|
||||||
@ -548,11 +549,8 @@ void Item_func::count_decimal_length()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length of if it is maximum length of its arguments
|
Set max_length of if it is maximum length of its arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_only_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_only_length()
|
void Item_func::count_only_length()
|
||||||
@ -567,12 +565,9 @@ void Item_func::count_only_length()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length/decimals of function if function is floating point and
|
Set max_length/decimals of function if function is floating point and
|
||||||
result length/precision depends on argument ones
|
result length/precision depends on argument ones.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_real_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_real_length()
|
void Item_func::count_real_length()
|
||||||
@ -655,12 +650,9 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check arguments here to determine result's type for a numeric
|
Check arguments here to determine result's type for a numeric
|
||||||
function of two arguments.
|
function of two arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_num_op::find_num_type()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_num_op::find_num_type(void)
|
void Item_num_op::find_num_type(void)
|
||||||
@ -699,13 +691,10 @@ void Item_num_op::find_num_type(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set result type for a numeric function of one argument
|
Set result type for a numeric function of one argument
|
||||||
(can be also used by a numeric function of many arguments, if the result
|
(can be also used by a numeric function of many arguments, if the result
|
||||||
type depends only on the first argument)
|
type depends only on the first argument)
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func_num1::find_num_type()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func_num1::find_num_type()
|
void Item_func_num1::find_num_type()
|
||||||
@ -1117,16 +1106,15 @@ longlong Item_func_plus::int_op()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Calculate plus of two decimail's
|
Calculate plus of two decimals.
|
||||||
|
|
||||||
SYNOPSIS
|
@param decimal_value Buffer that can be used to store result
|
||||||
decimal_op()
|
|
||||||
decimal_value Buffer that can be used to store result
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Value was NULL; In this case null_value is set
|
0 Value was NULL; In this case null_value is set
|
||||||
# Value of operation as a decimal
|
@retval
|
||||||
|
\# Value of operation as a decimal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||||
@ -1144,11 +1132,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set precision of results for additive operations (+ and -)
|
Set precision of results for additive operations (+ and -)
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func_additive_op::result_precision()
|
|
||||||
*/
|
*/
|
||||||
void Item_func_additive_op::result_precision()
|
void Item_func_additive_op::result_precision()
|
||||||
{
|
{
|
||||||
@ -1167,7 +1152,7 @@ void Item_func_additive_op::result_precision()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The following function is here to allow the user to force
|
The following function is here to allow the user to force
|
||||||
subtraction of UNSIGNED BIGINT to return negative values.
|
subtraction of UNSIGNED BIGINT to return negative values.
|
||||||
*/
|
*/
|
||||||
@ -1199,7 +1184,9 @@ longlong Item_func_minus::int_op()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* See Item_func_plus::decimal_op for comments */
|
/**
|
||||||
|
See Item_func_plus::decimal_op for comments.
|
||||||
|
*/
|
||||||
|
|
||||||
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
@ -1238,7 +1225,7 @@ longlong Item_func_mul::int_op()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* See Item_func_plus::decimal_op for comments */
|
/** See Item_func_plus::decimal_op for comments. */
|
||||||
|
|
||||||
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
@ -1570,7 +1557,7 @@ void Item_func_abs::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Gateway to natural LOG function */
|
/** Gateway to natural LOG function. */
|
||||||
double Item_func_ln::val_real()
|
double Item_func_ln::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
@ -1585,10 +1572,11 @@ double Item_func_ln::val_real()
|
|||||||
return log(value);
|
return log(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Extended but so slower LOG function
|
Extended but so slower LOG function.
|
||||||
We have to check if all values are > zero and first one is not one
|
|
||||||
as these are the cases then result is not a number.
|
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()
|
double Item_func_log::val_real()
|
||||||
{
|
{
|
||||||
@ -3014,8 +3002,10 @@ bool udf_handler::get_arguments()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This returns (String*) 0 in case of NULL values */
|
/**
|
||||||
|
@return
|
||||||
|
(String*)NULL in case of NULL values
|
||||||
|
*/
|
||||||
String *udf_handler::val_str(String *str,String *save_str)
|
String *udf_handler::val_str(String *str,String *save_str)
|
||||||
{
|
{
|
||||||
uchar is_null_tmp=0;
|
uchar is_null_tmp=0;
|
||||||
@ -3219,10 +3209,11 @@ String *Item_func_udf_str::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This has to come last in the udf_handler methods, or C for AIX
|
@note
|
||||||
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
|
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()
|
udf_handler::~udf_handler()
|
||||||
{
|
{
|
||||||
@ -3320,10 +3311,10 @@ void item_user_lock_release(User_level_lock *ull)
|
|||||||
delete ull;
|
delete ull;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wait until we are at or past the given position in the master binlog
|
Wait until we are at or past the given position in the master binlog
|
||||||
on the slave
|
on the slave.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_master_pos_wait::val_int()
|
longlong Item_master_pos_wait::val_int()
|
||||||
{
|
{
|
||||||
@ -3425,11 +3416,15 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get a user level lock. If the thread has an old lock this is first released.
|
Get a user level lock. If the thread has an old lock this is first released.
|
||||||
Returns 1: Got lock
|
|
||||||
Returns 0: Timeout
|
@retval
|
||||||
Returns NULL: Error
|
1 : Got lock
|
||||||
|
@retval
|
||||||
|
0 : Timeout
|
||||||
|
@retval
|
||||||
|
NULL : Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_get_lock::val_int()
|
longlong Item_func_get_lock::val_int()
|
||||||
@ -3549,12 +3544,12 @@ longlong Item_func_get_lock::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Release a user level lock.
|
Release a user level lock.
|
||||||
Return:
|
@return
|
||||||
1 if lock released
|
- 1 if lock released
|
||||||
0 if lock wasn't held
|
- 0 if lock wasn't held
|
||||||
(SQL) NULL if no such lock
|
- (SQL) NULL if no such lock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_release_lock::val_int()
|
longlong Item_func_release_lock::val_int()
|
||||||
@ -3679,7 +3674,7 @@ void Item_func_benchmark::print(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is just used to create tests with time gaps */
|
/** This function is just used to create tests with time gaps. */
|
||||||
|
|
||||||
longlong Item_func_sleep::val_int()
|
longlong Item_func_sleep::val_int()
|
||||||
{
|
{
|
||||||
@ -3835,22 +3830,22 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set value to user variable.
|
Set value to user variable.
|
||||||
|
|
||||||
SYNOPSYS
|
@param entry pointer to structure representing variable
|
||||||
update_hash()
|
@param set_null should we set NULL value ?
|
||||||
entry - pointer to structure representing variable
|
@param ptr pointer to buffer with new value
|
||||||
set_null - should we set NULL value ?
|
@param length length of new value
|
||||||
ptr - pointer to buffer with new value
|
@param type type of new value
|
||||||
length - length of new value
|
@param cs charset info for new value
|
||||||
type - type of new value
|
@param dv derivation for new value
|
||||||
cs - charset info for new value
|
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||||
dv - derivation for new value
|
|
||||||
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success, True - failure
|
false success
|
||||||
|
@retval
|
||||||
|
true failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -3935,7 +3930,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as a double */
|
/** Get the value of a variable as a double. */
|
||||||
|
|
||||||
double user_var_entry::val_real(my_bool *null_value)
|
double user_var_entry::val_real(my_bool *null_value)
|
||||||
{
|
{
|
||||||
@ -3963,7 +3958,7 @@ double user_var_entry::val_real(my_bool *null_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as an integer */
|
/** Get the value of a variable as an integer. */
|
||||||
|
|
||||||
longlong user_var_entry::val_int(my_bool *null_value)
|
longlong user_var_entry::val_int(my_bool *null_value)
|
||||||
{
|
{
|
||||||
@ -3994,7 +3989,7 @@ longlong user_var_entry::val_int(my_bool *null_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as a string */
|
/** Get the value of a variable as a string. */
|
||||||
|
|
||||||
String *user_var_entry::val_str(my_bool *null_value, String *str,
|
String *user_var_entry::val_str(my_bool *null_value, String *str,
|
||||||
uint decimals)
|
uint decimals)
|
||||||
@ -4025,7 +4020,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
|
|||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value of a variable as a decimal */
|
/** Get the value of a variable as a decimal. */
|
||||||
|
|
||||||
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
||||||
{
|
{
|
||||||
@ -4052,18 +4047,17 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
|||||||
return(val);
|
return(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This functions is invoked on SET @variable or @variable:= expression.
|
This functions is invoked on SET \@variable or
|
||||||
|
\@variable:= expression.
|
||||||
|
|
||||||
Evaluate (and check expression), store results.
|
Evaluate (and check expression), store results.
|
||||||
|
|
||||||
SYNOPSYS
|
@note
|
||||||
Item_func_set_user_var::check()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
For now it always return OK. All problem with value evaluating
|
For now it always return OK. All problem with value evaluating
|
||||||
will be caught by thd->net.report_error check in sql_set_variables().
|
will be caught by thd->net.report_error check in sql_set_variables().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK.
|
FALSE OK.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4112,18 +4106,17 @@ Item_func_set_user_var::check(bool use_result_field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This functions is invoked on SET @variable or @variable:= expression.
|
This functions is invoked on
|
||||||
|
SET \@variable or \@variable:= expression.
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
Item_func_set_user_var::update()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
We have to store the expression as such in the variable, independent of
|
We have to store the expression as such in the variable, independent of
|
||||||
the value method used by the user
|
the value method used by the user
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 EOM Error
|
1 EOM Error
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -4432,24 +4425,23 @@ longlong Item_func_get_user_var::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get variable by name and, if necessary, put the record of variable
|
Get variable by name and, if necessary, put the record of variable
|
||||||
use into the binary log.
|
use into the binary log.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
get_var_with_binlog()
|
|
||||||
thd Current thread
|
|
||||||
name Variable name
|
|
||||||
out_entry [out] variable structure or NULL. The pointer is set
|
|
||||||
regardless of whether function succeeded or not.
|
|
||||||
|
|
||||||
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
||||||
stores this variable and its value in thd->user_var_events, so that it can be
|
stores this variable and its value in thd->user_var_events, so that it can be
|
||||||
written to the binlog (will be written just before the query is written, see
|
written to the binlog (will be written just before the query is written, see
|
||||||
log.cc).
|
log.cc).
|
||||||
|
|
||||||
RETURN
|
@param thd Current thread
|
||||||
|
@param name Variable name
|
||||||
|
@param[out] out_entry variable structure or NULL. The pointer is set
|
||||||
|
regardless of whether function succeeded or not.
|
||||||
|
|
||||||
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 Failed to put appropriate record into binary log
|
1 Failed to put appropriate record into binary log
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -5104,22 +5096,20 @@ longlong Item_func_bit_xor::val_int()
|
|||||||
System variables
|
System variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return value of an system variable base[.name] as a constant item
|
Return value of an system variable base[.name] as a constant item.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
get_system_var()
|
@param var_type global / session
|
||||||
thd Thread handler
|
@param name Name of base or system variable
|
||||||
var_type global / session
|
@param component Component.
|
||||||
name Name of base or system variable
|
|
||||||
component Component
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If component.str = 0 then the variable name is in 'name'
|
If component.str = 0 then the variable name is in 'name'
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
0 error
|
- 0 : error
|
||||||
# constant item
|
- # : constant item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -5159,16 +5149,15 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check a user level lock.
|
Check a user level lock.
|
||||||
|
|
||||||
SYNOPSIS:
|
Sets null_value=TRUE on error.
|
||||||
val_int()
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 Available
|
1 Available
|
||||||
0 Already taken
|
@retval
|
||||||
NULL Error
|
0 Already taken, or error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_is_free_lock::val_int()
|
longlong Item_func_is_free_lock::val_int()
|
||||||
|
@ -14,7 +14,12 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all spatial functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all spatial functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
@ -360,7 +365,7 @@ String *Item_func_point::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Concatenates various items into various collections
|
Concatenates various items into various collections
|
||||||
with checkings for valid wkb type of items.
|
with checkings for valid wkb type of items.
|
||||||
For example, MultiPoint can be a collection of Points only.
|
For example, MultiPoint can be a collection of Points only.
|
||||||
@ -542,6 +547,10 @@ longlong Item_func_isempty::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Ramil or Holyfoot, add real IsSimple calculation
|
||||||
|
*/
|
||||||
longlong Item_func_issimple::val_int()
|
longlong Item_func_issimple::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
@ -15,13 +15,18 @@
|
|||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Row items used for comparing rows and IN operations on rows:
|
Row items used for comparing rows and IN operations on rows:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
(a, b, c) > (10, 10, 30)
|
(a, b, c) > (10, 10, 30)
|
||||||
(a, b, c) = (select c, d, e, from t1 where x=12)
|
(a, b, c) = (select c, d, e, from t1 where x=12)
|
||||||
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
|
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
|
||||||
(a, b, c) IN (select c, d, e, from t1)
|
(a, b, c) IN (select c, d, e, from t1)
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@todo
|
||||||
|
think placing 2-3 component items in item (as it done for function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_row::Item_row(List<Item> &arg):
|
Item_row::Item_row(List<Item> &arg):
|
||||||
|
@ -14,9 +14,15 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all string functions
|
/**
|
||||||
** Warning: Some string functions doesn't always put and end-null on a String
|
@file
|
||||||
** (This shouldn't be needed)
|
|
||||||
|
@brief
|
||||||
|
This file defines all string functions
|
||||||
|
|
||||||
|
@warning
|
||||||
|
Some string functions don't always put and end-null on a String.
|
||||||
|
(This shouldn't be needed)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
@ -297,9 +303,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Concatenate args with the following premises:
|
Concatenate args with the following premises:
|
||||||
If only one arg (which is ok), return value of arg
|
If only one arg (which is ok), return value of arg;
|
||||||
Don't reallocate val_str() if not absolute necessary.
|
Don't reallocate val_str() if not absolute necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -430,13 +436,15 @@ void Item_func_concat::fix_length_and_dec()
|
|||||||
max_length= (ulong) max_result_length;
|
max_length= (ulong) max_result_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Function des_encrypt() by tonu@spam.ee & monty
|
Function des_encrypt() by tonu@spam.ee & monty
|
||||||
Works only if compiled with OpenSSL library support.
|
Works only if compiled with OpenSSL library support.
|
||||||
This returns a binary string where first character is CHAR(128 | key-number).
|
@return
|
||||||
If one uses a string key key_number is 127.
|
A binary string where first character is CHAR(128 | key-number).
|
||||||
Encryption result is longer than original by formula:
|
If one uses a string key key_number is 127.
|
||||||
new_length= org_length + (8-(org_length % 8))+1
|
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)
|
String *Item_func_des_encrypt::val_str(String *str)
|
||||||
@ -609,7 +617,7 @@ wrong_key:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
concat with separator. First arg is the separator
|
concat with separator. First arg is the separator
|
||||||
concat_ws takes at least two arguments.
|
concat_ws takes at least two arguments.
|
||||||
*/
|
*/
|
||||||
@ -806,12 +814,14 @@ void Item_func_reverse::fix_length_and_dec()
|
|||||||
max_length = args[0]->max_length;
|
max_length = args[0]->max_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Replace all occurences of string2 in string1 with string3.
|
Replace all occurences of string2 in string1 with string3.
|
||||||
** Don't reallocate val_str() if not needed
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO: Fix that this works with binary strings when using USE_MB */
|
Don't reallocate val_str() if not needed.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Fix that this works with binary strings when using USE_MB
|
||||||
|
*/
|
||||||
|
|
||||||
String *Item_func_replace::val_str(String *str)
|
String *Item_func_replace::val_str(String *str)
|
||||||
{
|
{
|
||||||
@ -1776,8 +1786,9 @@ String *Item_func_database::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO: make USER() replicate properly (currently it is replicated to "")
|
@todo
|
||||||
|
make USER() replicate properly (currently it is replicated to "")
|
||||||
*/
|
*/
|
||||||
bool Item_func_user::init(const char *user, const char *host)
|
bool Item_func_user::init(const char *user, const char *host)
|
||||||
{
|
{
|
||||||
@ -1837,7 +1848,7 @@ void Item_func_soundex::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
If alpha, map input letter to soundex code.
|
If alpha, map input letter to soundex code.
|
||||||
If not alpha and remove_garbage is set then skip to next char
|
If not alpha and remove_garbage is set then skip to next char
|
||||||
else return 0
|
else return 0
|
||||||
@ -1981,9 +1992,10 @@ String *Item_func_soundex::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Change a number to format '3,333,333,333.000'
|
Change a number to format '3,333,333,333.000'.
|
||||||
** This should be 'internationalized' sometimes.
|
|
||||||
|
This should be 'internationalized' sometimes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int FORMAT_MAX_DECIMALS= 30;
|
const int FORMAT_MAX_DECIMALS= 30;
|
||||||
@ -2002,8 +2014,9 @@ void Item_func_format::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO: This needs to be fixed for multi-byte character set where numbers
|
@todo
|
||||||
|
This needs to be fixed for multi-byte character set where numbers
|
||||||
are stored in more than one byte
|
are stored in more than one byte
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2349,9 +2362,9 @@ void Item_func_repeat::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Item_func_repeat::str is carefully written to avoid reallocs
|
Item_func_repeat::str is carefully written to avoid reallocs
|
||||||
** as much as possible at the cost of a local buffer
|
as much as possible at the cost of a local buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String *Item_func_repeat::val_str(String *str)
|
String *Item_func_repeat::val_str(String *str)
|
||||||
@ -2827,7 +2840,7 @@ String *Item_func_hex::val_str(String *str)
|
|||||||
return &tmp_value;
|
return &tmp_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert given hex string to a binary string */
|
/** Convert given hex string to a binary string. */
|
||||||
|
|
||||||
String *Item_func_unhex::val_str(String *str)
|
String *Item_func_unhex::val_str(String *str)
|
||||||
{
|
{
|
||||||
@ -3060,27 +3073,27 @@ String* Item_func_inet_ntoa::val_str(String* str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
||||||
|
|
||||||
|
/**
|
||||||
QUOTE() function returns argument string in single quotes suitable for
|
QUOTE() function returns argument string in single quotes suitable for
|
||||||
using in a SQL statement.
|
using in a SQL statement.
|
||||||
|
|
||||||
DESCRIPTION
|
Adds a \\ before all characters that needs to be escaped in a SQL string.
|
||||||
Adds a \ before all characters that needs to be escaped in a SQL string.
|
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
||||||
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
running commands from a file in windows.
|
||||||
running commands from a file in windows.
|
|
||||||
|
|
||||||
This function is very useful when you want to generate SQL statements
|
This function is very useful when you want to generate SQL statements.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
str Quoted string
|
str Quoted string
|
||||||
NULL Out of memory.
|
@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)
|
String *Item_func_quote::val_str(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
@ -3326,8 +3339,10 @@ static uint nanoseq;
|
|||||||
static ulonglong uuid_time=0;
|
static ulonglong uuid_time=0;
|
||||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||||
|
|
||||||
/* number of 100-nanosecond intervals between
|
/**
|
||||||
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
|
number of 100-nanosecond intervals between
|
||||||
|
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
|
||||||
|
*/
|
||||||
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
||||||
|
|
||||||
#define UUID_VERSION 0x1000
|
#define UUID_VERSION 0x1000
|
||||||
|
@ -13,12 +13,15 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
subselect Item
|
@file
|
||||||
|
|
||||||
SUBSELECT TODO:
|
@brief
|
||||||
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
subselect Item
|
||||||
(sql_select.h/sql_select.cc)
|
|
||||||
|
@todo
|
||||||
|
- add function from mysql_select that use JOIN* as parameter to JOIN
|
||||||
|
methods (sql_select.h/sql_select.cc)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
@ -403,6 +406,16 @@ void Item_singlerow_subselect::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
- We cant change name of Item_field or Item_ref, because it will
|
||||||
|
prevent it's correct resolving, but we should save name of
|
||||||
|
removed item => we do not make optimization if top item of
|
||||||
|
list is field or reference.
|
||||||
|
- switch off this optimization for prepare statement,
|
||||||
|
because we do not rollback this changes.
|
||||||
|
Make rollback for it, or special name resolving mode in 5.0.
|
||||||
|
*/
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_singlerow_subselect::select_transformer(JOIN *join)
|
Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||||
{
|
{
|
||||||
@ -1445,24 +1458,24 @@ Item_in_subselect::select_transformer(JOIN *join)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
||||||
transformation function
|
transformation function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_in_subselect::select_in_like_transformer()
|
|
||||||
join JOIN object of transforming subquery
|
|
||||||
func creator of condition function of subquery
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
To decide which transformation procedure (scalar or row) applicable here
|
To decide which transformation procedure (scalar or row) applicable here
|
||||||
we have to call fix_fields() for left expression to be able to call
|
we have to call fix_fields() for left expression to be able to call
|
||||||
cols() method on it. Also this method make arena management for
|
cols() method on it. Also this method make arena management for
|
||||||
underlying transformation methods.
|
underlying transformation methods.
|
||||||
|
|
||||||
RETURN
|
@param join JOIN object of transforming subquery
|
||||||
|
@param func creator of condition function of subquery
|
||||||
|
|
||||||
|
@retval
|
||||||
RES_OK OK
|
RES_OK OK
|
||||||
RES_REDUCE OK, and current subquery was reduced during transformation
|
@retval
|
||||||
|
RES_REDUCE OK, and current subquery was reduced during
|
||||||
|
transformation
|
||||||
|
@retval
|
||||||
RES_ERROR Error
|
RES_ERROR Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2412,16 +2425,15 @@ void subselect_indexsubquery_engine::print(String *str)
|
|||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result object of engine
|
change select_result object of engine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2434,16 +2446,15 @@ bool subselect_single_select_engine::change_result(Item_subselect *si,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result object of engine
|
change select_result object of engine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2457,16 +2468,15 @@ bool subselect_union_engine::change_result(Item_subselect *si,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result emulation, never should be called
|
change select_result emulation, never should be called.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2478,14 +2488,12 @@ bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_single_select_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
bool subselect_single_select_engine::no_tables()
|
bool subselect_single_select_engine::no_tables()
|
||||||
@ -2510,14 +2518,12 @@ bool subselect_single_select_engine::may_be_null()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_union_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
bool subselect_union_engine::no_tables()
|
bool subselect_union_engine::no_tables()
|
||||||
@ -2531,14 +2537,12 @@ bool subselect_union_engine::no_tables()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_uniquesubquery_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Sum functions (COUNT, MIN...) */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Sum functions (COUNT, MIN...)
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
@ -23,28 +28,25 @@
|
|||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare an aggregate function item for checking context conditions
|
Prepare an aggregate function item for checking context conditions.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
init_sum_func_check()
|
|
||||||
thd reference to the thread context info
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function initializes the members of the Item_sum object created
|
The function initializes the members of the Item_sum object created
|
||||||
for a set function that are used to check validity of the set function
|
for a set function that are used to check validity of the set function
|
||||||
occurrence.
|
occurrence.
|
||||||
If the set function is not allowed in any subquery where it occurs
|
If the set function is not allowed in any subquery where it occurs
|
||||||
an error is reported immediately.
|
an error is reported immediately.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the thread context info
|
||||||
|
|
||||||
|
@note
|
||||||
This function is to be called for any item created for a set function
|
This function is to be called for any item created for a set function
|
||||||
object when the traversal of trees built for expressions used in the query
|
object when the traversal of trees built for expressions used in the query
|
||||||
is performed at the phase of context analysis. This function is to
|
is performed at the phase of context analysis. This function is to
|
||||||
be invoked at the descent of this traversal.
|
be invoked at the descent of this traversal.
|
||||||
|
@retval
|
||||||
RETURN
|
TRUE if an error is reported
|
||||||
TRUE if an error is reported
|
@retval
|
||||||
FALSE otherwise
|
FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check constraints imposed on a usage of a set function
|
Check constraints imposed on a usage of a set function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
check_sum_func()
|
|
||||||
thd reference to the thread context info
|
|
||||||
ref location of the pointer to this item in the embedding expression
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The method verifies whether context conditions imposed on a usage
|
The method verifies whether context conditions imposed on a usage
|
||||||
of any set function are met for this occurrence.
|
of any set function are met for this occurrence.
|
||||||
It checks whether the set function occurs in the position where it
|
It checks whether the set function occurs in the position where it
|
||||||
@ -89,13 +85,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||||||
adds it to the chain of items for such set functions that is attached
|
adds it to the chain of items for such set functions that is attached
|
||||||
to the the st_select_lex structure for this subquery.
|
to the the st_select_lex structure for this subquery.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function is to be called for any item created for a set function
|
|
||||||
object when the traversal of trees built for expressions used in the query
|
|
||||||
is performed at the phase of context analysis. This function is to
|
|
||||||
be invoked at the ascent of this traversal.
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
A number of designated members of the object are used to check the
|
A number of designated members of the object are used to check the
|
||||||
conditions. They are specified in the comment before the Item_sum
|
conditions. They are specified in the comment before the Item_sum
|
||||||
class declaration.
|
class declaration.
|
||||||
@ -106,16 +95,28 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||||||
of set functions are allowed (i.e either in the SELECT list or
|
of set functions are allowed (i.e either in the SELECT list or
|
||||||
in the HAVING clause of the corresponding subquery)
|
in the HAVING clause of the corresponding subquery)
|
||||||
Consider the query:
|
Consider the query:
|
||||||
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
@code
|
||||||
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
|
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
||||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
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:
|
allow_sum_func will contain:
|
||||||
for SUM(t1.b) - 1 at the first position
|
- for SUM(t1.b) - 1 at the first position
|
||||||
for AVG(t1.b) - 1 at the first position, 0 at the second position
|
- for AVG(t1.b) - 1 at the first position, 0 at the second position
|
||||||
for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
- for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
||||||
|
|
||||||
RETURN
|
@param thd reference to the thread context info
|
||||||
TRUE if an error is reported
|
@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
|
FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -200,15 +201,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Attach a set function to the subquery where it must be aggregated
|
Attach a set function to the subquery where it must be aggregated.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
register_sum_func()
|
|
||||||
thd reference to the thread context info
|
|
||||||
ref location of the pointer to this item in the embedding expression
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function looks for an outer subquery where the set function must be
|
The function looks for an outer subquery where the set function must be
|
||||||
aggregated. If it finds such a subquery then aggr_level is set to
|
aggregated. If it finds such a subquery then aggr_level is set to
|
||||||
the nest level of this subquery and the item for the set function
|
the nest level of this subquery and the item for the set function
|
||||||
@ -216,14 +211,18 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||||||
inner_sum_func_list defined for each subquery. When the item is placed
|
inner_sum_func_list defined for each subquery. When the item is placed
|
||||||
there the field 'ref_by' is set to ref.
|
there the field 'ref_by' is set to ref.
|
||||||
|
|
||||||
NOTES.
|
@note
|
||||||
Now we 'register' only set functions that are aggregated in outer
|
Now we 'register' only set functions that are aggregated in outer
|
||||||
subqueries. Actually it makes sense to link all set function for
|
subqueries. Actually it makes sense to link all set function for
|
||||||
a subquery in one chain. It would simplify the process of 'splitting'
|
a subquery in one chain. It would simplify the process of 'splitting'
|
||||||
for set functions.
|
for set functions.
|
||||||
|
|
||||||
RETURN
|
@param thd reference to the thread context info
|
||||||
|
@param ref location of the pointer to this item in the embedding expression
|
||||||
|
|
||||||
|
@retval
|
||||||
FALSE if the executes without failures (currently always)
|
FALSE if the executes without failures (currently always)
|
||||||
|
@retval
|
||||||
TRUE otherwise
|
TRUE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -311,8 +310,8 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Constructor used in processing select with temporary tebles
|
Constructor used in processing select with temporary tebles.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
@ -655,6 +654,10 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
|
|||||||
** reset and add of sum_func
|
** reset and add of sum_func
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
check if the following assignments are really needed
|
||||||
|
*/
|
||||||
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
|
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
|
||||||
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
|
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
|
||||||
curr_dec_buff(item->curr_dec_buff)
|
curr_dec_buff(item->curr_dec_buff)
|
||||||
@ -833,7 +836,7 @@ Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Behaves like an Integer except to fix_length_and_dec().
|
Behaves like an Integer except to fix_length_and_dec().
|
||||||
Additionally div() converts val with this traits to a val with true
|
Additionally div() converts val with this traits to a val with true
|
||||||
decimal traits along with conversion of integer value to decimal value.
|
decimal traits along with conversion of integer value to decimal value.
|
||||||
@ -910,6 +913,10 @@ void Item_sum_distinct::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
check that the case of CHAR(0) works OK
|
||||||
|
*/
|
||||||
bool Item_sum_distinct::setup(THD *thd)
|
bool Item_sum_distinct::setup(THD *thd)
|
||||||
{
|
{
|
||||||
List<Create_field> field_list;
|
List<Create_field> field_list;
|
||||||
@ -2002,8 +2009,8 @@ void Item_sum_bit::update_field()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** calc next value and merge it with field_value
|
calc next value and merge it with field_value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_sum_sum::update_field()
|
void Item_sum_sum::update_field()
|
||||||
@ -2179,6 +2186,10 @@ Item_sum_hybrid::min_max_update_int_field()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
optimize: do not get result_field in case of args[0] is NULL
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Item_sum_hybrid::min_max_update_decimal_field()
|
Item_sum_hybrid::min_max_update_decimal_field()
|
||||||
{
|
{
|
||||||
@ -2367,7 +2378,7 @@ int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
|
|||||||
return f->cmp(key1, key2);
|
return f->cmp(key1, key2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Did not make this one static - at least gcc gets confused when
|
Did not make this one static - at least gcc gets confused when
|
||||||
I try to declare a static function as a friend. If you can figure
|
I try to declare a static function as a friend. If you can figure
|
||||||
out the syntax to make a static function a friend, make this one
|
out the syntax to make a static function a friend, make this one
|
||||||
@ -2434,7 +2445,10 @@ void Item_sum_count_distinct::cleanup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is used by rollup to create a separate usable copy of the function */
|
/**
|
||||||
|
This is used by rollup to create a separate usable copy of
|
||||||
|
the function.
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_sum_count_distinct::make_unique()
|
void Item_sum_count_distinct::make_unique()
|
||||||
{
|
{
|
||||||
@ -2801,7 +2815,7 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Default max_length is max argument length */
|
/** Default max_length is max argument length. */
|
||||||
|
|
||||||
void Item_sum_udf_str::fix_length_and_dec()
|
void Item_sum_udf_str::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
@ -2851,9 +2865,8 @@ String *Item_sum_udf_str::val_str(String *str)
|
|||||||
Blobs doesn't work with DISTINCT or ORDER BY
|
Blobs doesn't work with DISTINCT or ORDER BY
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...)
|
||||||
GROUP_CONCAT(DISTINCT expr,...)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
||||||
@ -2890,9 +2903,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
||||||
@ -2934,11 +2946,11 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax:
|
||||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ).
|
||||||
|
|
||||||
BUG:
|
@bug
|
||||||
This doesn't work in the case when the order by contains data that
|
This doesn't work in the case when the order by contains data that
|
||||||
is not part of the field list because tree-insert will not notice
|
is not part of the field list because tree-insert will not notice
|
||||||
the duplicated values when inserting things sorted by ORDER BY
|
the duplicated values when inserting things sorted by ORDER BY
|
||||||
@ -2953,8 +2965,8 @@ int group_concat_key_cmp_with_distinct_and_order(void* arg,uchar* key1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Append data from current leaf to item->result
|
Append data from current leaf to item->result.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
||||||
@ -3025,12 +3037,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Constructor of Item_func_group_concat
|
Constructor of Item_func_group_concat.
|
||||||
distinct_arg - distinct
|
|
||||||
select_list - list of expression for show values
|
@param distinct_arg distinct
|
||||||
order_list - list of sort columns
|
@param select_list list of expression for show values
|
||||||
separator_arg - string value of separator
|
@param order_list list of sort columns
|
||||||
|
@param separator_arg string value of separator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_func_group_concat::
|
Item_func_group_concat::
|
||||||
|
@ -14,7 +14,15 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all time functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all time functions
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Move month and days to language files
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
@ -24,17 +32,16 @@
|
|||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* TODO: Move month and days to language files */
|
/** Day number for Dec 31st, 9999. */
|
||||||
|
|
||||||
/* Day number for Dec 31st, 9999 */
|
|
||||||
#define MAX_DAY_NUMBER 3652424L
|
#define MAX_DAY_NUMBER 3652424L
|
||||||
|
|
||||||
/*
|
/**
|
||||||
OPTIMIZATION TODO:
|
@todo
|
||||||
- Replace the switch with a function that should be called for each
|
OPTIMIZATION
|
||||||
date type.
|
- Replace the switch with a function that should be called for each
|
||||||
- Remove sprintf and opencode the conversion, like we do in
|
date type.
|
||||||
Field_datetime.
|
- 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
|
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
|
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,
|
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
||||||
{(char *)"%H:%i:%S", 8}};
|
{(char *)"%H:%i:%S", 8}};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Extract datetime value to MYSQL_TIME struct from string value
|
Extract datetime value to MYSQL_TIME struct from string value
|
||||||
according to format string.
|
according to format string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format date/time format specification
|
||||||
extract_date_time()
|
@param val String to decode
|
||||||
format date/time format specification
|
@param length Length of string
|
||||||
val String to decode
|
@param l_time Store result here
|
||||||
length Length of string
|
@param cached_timestamp_type It uses to get an appropriate warning
|
||||||
l_time Store result here
|
in the case when the value is truncated.
|
||||||
cached_timestamp_type
|
@param sub_pattern_end if non-zero then we are parsing string which
|
||||||
It uses to get an appropriate warning
|
should correspond compound specifier (like %T or
|
||||||
in the case when the value is truncated.
|
%r) and this parameter is pointer to place where
|
||||||
sub_pattern_end if non-zero then we are parsing string which
|
pointer to end of string matching this specifier
|
||||||
should correspond compound specifier (like %T or
|
should be stored.
|
||||||
%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.
|
|
||||||
|
|
||||||
If one adds new format specifiers to this function he should also
|
@note
|
||||||
consider adding them to get_date_time_result_type() function.
|
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
|
@note
|
||||||
0 ok
|
If one adds new format specifiers to this function he should also
|
||||||
1 error
|
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,
|
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,
|
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||||
@ -838,7 +845,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Get a array of positive numbers from a string object.
|
Get a array of positive numbers from a string object.
|
||||||
Each number is separated by 1 non digit character
|
Each number is separated by 1 non digit character
|
||||||
Return error if there is too many numbers.
|
Return error if there is too many numbers.
|
||||||
@ -846,16 +854,14 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
|||||||
from the high end. This allows one to give:
|
from the high end. This allows one to give:
|
||||||
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||||
|
|
||||||
SYNOPSIS
|
@param length: length of str
|
||||||
str: string value
|
@param cs: charset of str
|
||||||
length: length of str
|
@param values: array of results
|
||||||
cs: charset of str
|
@param count: count of elements in result array
|
||||||
values: array of results
|
@param transform_msec: if value is true we suppose
|
||||||
count: count of elements in result array
|
that the last part of string value is microseconds
|
||||||
transform_msec: if value is true we suppose
|
and we should transform value to six digit value.
|
||||||
that the last part of string value is microseconds
|
For example, '1.1' -> '1.100000'
|
||||||
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,
|
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()
|
longlong Item_func_quarter::val_int()
|
||||||
{
|
{
|
||||||
@ -1072,8 +1080,10 @@ longlong Item_func_minute::val_int()
|
|||||||
(void) get_arg0_time(<ime);
|
(void) get_arg0_time(<ime);
|
||||||
return ltime.minute;
|
return ltime.minute;
|
||||||
}
|
}
|
||||||
// Returns the second in time_exp in the range of 0 - 59
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the second in time_exp in the range of 0 - 59.
|
||||||
|
*/
|
||||||
longlong Item_func_second::val_int()
|
longlong Item_func_second::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
|
|||||||
return week_format;
|
return week_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@verbatim
|
||||||
The bits in week_format(for calc_week() function) has the following meaning:
|
The bits in week_format(for calc_week() function) has the following meaning:
|
||||||
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
|
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
|
||||||
If set Monday is first day of week
|
If set Monday is first day of week
|
||||||
@ -1118,6 +1129,7 @@ uint week_mode(uint mode)
|
|||||||
four or more days in the new year, then it is week 1;
|
four or more days in the new year, then it is week 1;
|
||||||
Otherwise it is the last week of the previous year, and the
|
Otherwise it is the last week of the previous year, and the
|
||||||
next week is week 1.
|
next week is week 1.
|
||||||
|
@endverbatim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_week::val_int()
|
longlong Item_func_week::val_int()
|
||||||
@ -1281,8 +1293,9 @@ longlong Item_func_time_to_sec::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Convert a string to a interval value
|
Convert a string to a interval value.
|
||||||
|
|
||||||
To make code easy, allow interval objects without separators.
|
To make code easy, allow interval objects without separators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole CURDATE function.
|
time zone. Defines time zone (local) used for whole CURDATE function.
|
||||||
*/
|
*/
|
||||||
@ -1519,7 +1532,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
|
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
|
||||||
*/
|
*/
|
||||||
@ -1563,7 +1576,7 @@ void Item_func_curtime::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole CURTIME function.
|
time zone. Defines time zone (local) used for whole CURTIME function.
|
||||||
*/
|
*/
|
||||||
@ -1576,7 +1589,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
|
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
|
||||||
*/
|
*/
|
||||||
@ -1612,7 +1625,7 @@ void Item_func_now::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole NOW function.
|
time zone. Defines time zone (local) used for whole NOW function.
|
||||||
*/
|
*/
|
||||||
@ -1625,7 +1638,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
|
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
|
||||||
*/
|
*/
|
||||||
@ -1656,7 +1669,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole SYSDATE function.
|
time zone. Defines time zone (local) used for whole SYSDATE function.
|
||||||
*/
|
*/
|
||||||
@ -2612,7 +2625,7 @@ longlong Item_date_typecast::val_int()
|
|||||||
return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
|
return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MAKEDATE(a,b) is a date function that creates a date value
|
MAKEDATE(a,b) is a date function that creates a date value
|
||||||
from a year and day value.
|
from a year and day value.
|
||||||
|
|
||||||
@ -2722,7 +2735,7 @@ void Item_func_add_time::fix_length_and_dec()
|
|||||||
cached_field_type= MYSQL_TYPE_TIME;
|
cached_field_type= MYSQL_TYPE_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
||||||
time/datetime value
|
time/datetime value
|
||||||
|
|
||||||
@ -2824,7 +2837,7 @@ void Item_func_add_time::print(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TIMEDIFF(t,s) is a time function that calculates the
|
TIMEDIFF(t,s) is a time function that calculates the
|
||||||
time value between a start and end time.
|
time value between a start and end time.
|
||||||
|
|
||||||
@ -2874,7 +2887,7 @@ null_date:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MAKETIME(h,m,s) is a time function that calculates a time value
|
MAKETIME(h,m,s) is a time function that calculates a time value
|
||||||
from the total number of hours, minutes, and seconds.
|
from the total number of hours, minutes, and seconds.
|
||||||
Result: Time value
|
Result: Time value
|
||||||
@ -2941,7 +2954,7 @@ String *Item_func_maketime::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
|
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
|
||||||
from a.
|
from a.
|
||||||
|
|
||||||
@ -3167,25 +3180,28 @@ void Item_func_get_format::print(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get type of datetime value (DATE/TIME/...) which will be produced
|
Get type of datetime value (DATE/TIME/...) which will be produced
|
||||||
according to format string.
|
according to format string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format format string
|
||||||
get_date_time_result_type()
|
@param length length of format string
|
||||||
format - format string
|
|
||||||
length - length of format string
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
We don't process day format's characters('D', 'd', 'e') because day
|
We don't process day format's characters('D', 'd', 'e') because day
|
||||||
may be a member of all date/time types.
|
may be a member of all date/time types.
|
||||||
|
|
||||||
|
@note
|
||||||
Format specifiers supported by this function should be in sync with
|
Format specifiers supported by this function should be in sync with
|
||||||
specifiers supported by extract_date_time() function.
|
specifiers supported by extract_date_time() function.
|
||||||
|
|
||||||
RETURN VALUE
|
@return
|
||||||
One of date_time_format_types values:
|
One of date_time_format_types values:
|
||||||
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
|
- DATE_TIME_MICROSECOND
|
||||||
|
- DATE_TIME
|
||||||
|
- DATE_ONLY
|
||||||
|
- TIME_MICROSECOND
|
||||||
|
- TIME_ONLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static date_time_format_types
|
static date_time_format_types
|
||||||
|
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.
|
Copy part of a record that forms a key or key prefix to a buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
key_copy()
|
|
||||||
to_key buffer that will be used as a key
|
|
||||||
from_record full record to be copied from
|
|
||||||
key_info descriptor of the index
|
|
||||||
key_length specifies length of all keyparts that will be copied
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function takes a complete table record (as e.g. retrieved by
|
The function takes a complete table record (as e.g. retrieved by
|
||||||
handler::index_read()), and a description of an index on the same table,
|
handler::index_read()), and a description of an index on the same table,
|
||||||
and extracts the first key_length bytes of the record which are part of a
|
and extracts the first key_length bytes of the record which are part of a
|
||||||
key into to_key. If length == 0 then copy all bytes from the record that
|
key into to_key. If length == 0 then copy all bytes from the record that
|
||||||
form a key.
|
form a key.
|
||||||
|
|
||||||
RETURN
|
@param to_key buffer that will be used as a key
|
||||||
None
|
@param from_record full record to be copied from
|
||||||
|
@param key_info descriptor of the index
|
||||||
|
@param key_length specifies length of all keyparts that will be copied
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
||||||
@ -163,22 +157,16 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Restore a key from some buffer to record.
|
Restore a key from some buffer to record.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
key_restore()
|
|
||||||
to_record record buffer where the key will be restored to
|
|
||||||
from_key buffer that contains a key
|
|
||||||
key_info descriptor of the index
|
|
||||||
key_length specifies length of all keyparts that will be restored
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function converts a key into record format. It can be used in cases
|
This function converts a key into record format. It can be used in cases
|
||||||
when we want to return a key as a result row.
|
when we want to return a key as a result row.
|
||||||
|
|
||||||
RETURN
|
@param to_record record buffer where the key will be restored to
|
||||||
None
|
@param from_key buffer that contains a key
|
||||||
|
@param key_info descriptor of the index
|
||||||
|
@param key_length specifies length of all keyparts that will be restored
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
||||||
@ -255,24 +243,23 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare if a key has changed
|
Compare if a key has changed.
|
||||||
|
|
||||||
SYNOPSIS
|
@param table TABLE
|
||||||
key_cmp_if_same()
|
@param key key to compare to row
|
||||||
table TABLE
|
@param idx Index used
|
||||||
key key to compare to row
|
@param key_length Length of key
|
||||||
idx Index used
|
|
||||||
key_length Length of key
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
In theory we could just call field->cmp() for all field types,
|
In theory we could just call field->cmp() for all field types,
|
||||||
but as we are only interested if a key has changed (not if the key is
|
but as we are only interested if a key has changed (not if the key is
|
||||||
larger or smaller than the previous value) we can do things a bit
|
larger or smaller than the previous value) we can do things a bit
|
||||||
faster by using memcmp() instead.
|
faster by using memcmp() instead.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 If key is equal
|
0 If key is equal
|
||||||
|
@retval
|
||||||
1 Key has changed
|
1 Key has changed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -331,17 +318,17 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
unpack key-fields from record to some buffer
|
unpack key-fields from record to some buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
This is used mainly to get a good error message. We temporary
|
||||||
key_unpack()
|
change the column bitmap so that all columns are readable.
|
||||||
|
|
||||||
|
@param
|
||||||
to Store value here in an easy to read form
|
to Store value here in an easy to read form
|
||||||
|
@param
|
||||||
table Table to use
|
table Table to use
|
||||||
|
@param
|
||||||
idx Key number
|
idx Key number
|
||||||
|
|
||||||
NOTES
|
|
||||||
This is used mainly to get a good error message
|
|
||||||
We temporary change the column bitmap so that all columns are readable.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_unpack(String *to,TABLE *table,uint idx)
|
void key_unpack(String *to,TABLE *table,uint idx)
|
||||||
@ -419,21 +406,18 @@ bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare key in row to a given key
|
Compare key in row to a given key.
|
||||||
|
|
||||||
SYNOPSIS
|
@param key_part Key part handler
|
||||||
key_cmp()
|
@param key Key to compare to value in table->record[0]
|
||||||
key_part Key part handler
|
@param key_length length of 'key'
|
||||||
key Key to compare to value in table->record[0]
|
|
||||||
key_length length of 'key'
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
The return value is SIGN(key_in_row - range_key):
|
The return value is SIGN(key_in_row - range_key):
|
||||||
|
- 0 Key is equal to range or 'range' == 0 (no range)
|
||||||
0 Key is equal to range or 'range' == 0 (no range)
|
- -1 Key is less than range
|
||||||
-1 Key is less than range
|
- 1 Key is larger than range
|
||||||
1 Key is larger than range
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
||||||
|
217
sql/lock.cc
217
sql/lock.cc
@ -14,8 +14,11 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* locking functions for mysql */
|
/**
|
||||||
/*
|
@file
|
||||||
|
|
||||||
|
Locking functions for mysql.
|
||||||
|
|
||||||
Because of the new concurrent inserts, we must first get external locks
|
Because of the new concurrent inserts, we must first get external locks
|
||||||
before getting internal locks. If we do it in the other order, the status
|
before getting internal locks. If we do it in the other order, the status
|
||||||
information is not up to date when called from the lock handler.
|
information is not up to date when called from the lock handler.
|
||||||
@ -65,7 +68,7 @@
|
|||||||
excluding one that caused failure. That means handler must cleanup itself
|
excluding one that caused failure. That means handler must cleanup itself
|
||||||
in case external_lock() fails.
|
in case external_lock() fails.
|
||||||
|
|
||||||
TODO:
|
@todo
|
||||||
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
||||||
we are forced to use mysql_lock_merge.
|
we are forced to use mysql_lock_merge.
|
||||||
*/
|
*/
|
||||||
@ -390,10 +393,11 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unlock some of the tables locked by mysql_lock_tables
|
Unlock some of the tables locked by mysql_lock_tables.
|
||||||
|
|
||||||
This will work even if get_lock_data fails (next unlock will free all)
|
This will work even if get_lock_data fails (next unlock will free all)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
||||||
{
|
{
|
||||||
@ -405,8 +409,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** unlock all tables locked for read.
|
unlock all tables locked for read.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||||
@ -567,7 +571,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* abort all other threads waiting to get lock in table */
|
/** Abort all other threads waiting to get lock in table. */
|
||||||
|
|
||||||
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
||||||
{
|
{
|
||||||
@ -586,16 +590,15 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Abort one thread / table combination
|
Abort one thread / table combination.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
mysql_lock_abort_for_thread()
|
@param table Table that should be removed from lock queue
|
||||||
thd Thread handler
|
|
||||||
table Table that should be removed from lock queue
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Table was not locked by another thread
|
0 Table was not locked by another thread
|
||||||
|
@retval
|
||||||
1 Table was locked by at least one other thread
|
1 Table was locked by at least one other thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -663,28 +666,27 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find duplicate lock in tables.
|
Find duplicate lock in tables.
|
||||||
|
|
||||||
SYNOPSIS
|
Temporary tables are ignored here like they are ignored in
|
||||||
mysql_lock_have_duplicate()
|
get_lock_data(). If we allow two opens on temporary tables later,
|
||||||
thd The current thread.
|
both functions should be checked.
|
||||||
needle The table to check for duplicate lock.
|
|
||||||
haystack The list of tables to search for the dup lock.
|
|
||||||
|
|
||||||
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
|
This is mainly meant for MERGE tables in INSERT ... SELECT
|
||||||
situations. The 'real', underlying tables can be found only after
|
situations. The 'real', underlying tables can be found only after
|
||||||
the MERGE tables are opened. This function assumes that the tables are
|
the MERGE tables are opened. This function assumes that the tables are
|
||||||
already locked.
|
already locked.
|
||||||
|
|
||||||
Temporary tables are ignored here like they are ignored in
|
@retval
|
||||||
get_lock_data(). If we allow two opens on temporary tables later,
|
NULL No duplicate lock found.
|
||||||
both functions should be checked.
|
@retval
|
||||||
|
!NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||||
RETURN
|
|
||||||
NULL No duplicate lock found.
|
|
||||||
! NULL First table from 'haystack' that matches a lock on 'needle'.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||||
@ -768,7 +770,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* unlock a set of external */
|
/** Unlock a set of external. */
|
||||||
|
|
||||||
static int unlock_external(THD *thd, TABLE **table,uint count)
|
static int unlock_external(THD *thd, TABLE **table,uint count)
|
||||||
{
|
{
|
||||||
@ -793,21 +795,17 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get lock structures from table structs and initialize locks
|
Get lock structures from table structs and initialize locks.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
get_lock_data()
|
@param table_ptr Pointer to tables that should be locks
|
||||||
thd Thread handler
|
@param flags One of:
|
||||||
table_ptr Pointer to tables that should be locks
|
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
|
||||||
flags One of:
|
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
|
||||||
GET_LOCK_UNLOCK: If we should send TL_IGNORE to
|
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||||
store lock
|
|
||||||
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
|
|
||||||
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||||
uint flags, TABLE **write_lock_used)
|
uint flags, TABLE **write_lock_used)
|
||||||
{
|
{
|
||||||
@ -893,31 +891,25 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Reset lock type in lock data.
|
Reset lock type in lock data.
|
||||||
|
|
||||||
SYNOPSIS
|
After a locking error we want to quit the locking of the table(s).
|
||||||
reset_lock_data()
|
The test case in the bug report for Bug #18544 has the following
|
||||||
sql_lock The MySQL lock.
|
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).
|
Clear the lock type of all lock data. This ensures that the next
|
||||||
The test case in the bug report for Bug #18544 has the following
|
lock request will set its lock type properly.
|
||||||
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.
|
|
||||||
|
|
||||||
In all these cases we have already set the lock type into the lock
|
@param sql_lock The MySQL 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
||||||
@ -940,20 +932,19 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
|||||||
This is used when we need total access to a closed, not open table
|
This is used when we need total access to a closed, not open table
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Lock and wait for the named lock.
|
Lock and wait for the named lock.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
lock_and_wait_for_table_name()
|
@param table_list Lock first table in this list
|
||||||
thd Thread handler
|
|
||||||
table_list Lock first table in this list
|
|
||||||
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Works together with global read lock.
|
Works together with global read lock.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -982,30 +973,30 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Put a not open table with an old refresh version in the table cache.
|
Put a not open table with an old refresh version in the table cache.
|
||||||
|
|
||||||
SYNPOSIS
|
@param thd Thread handler
|
||||||
lock_table_name()
|
@param table_list Lock first table in this list
|
||||||
thd Thread handler
|
@param check_in_use Do we need to check if table already in use by us
|
||||||
table_list Lock first table in this list
|
|
||||||
check_in_use Do we need to check if table already in use by us
|
|
||||||
|
|
||||||
WARNING
|
@note
|
||||||
|
One must have a lock on LOCK_open!
|
||||||
|
|
||||||
|
@warning
|
||||||
If you are going to update the table, you should use
|
If you are going to update the table, you should use
|
||||||
lock_and_wait_for_table_name instead of this function as this works
|
lock_and_wait_for_table_name instead of this function as this works
|
||||||
together with 'FLUSH TABLES WITH READ LOCK'
|
together with 'FLUSH TABLES WITH READ LOCK'
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
This will force any other threads that uses the table to release it
|
This will force any other threads that uses the table to release it
|
||||||
as soon as possible.
|
as soon as possible.
|
||||||
|
|
||||||
REQUIREMENTS
|
@return
|
||||||
One must have a lock on LOCK_open !
|
|
||||||
|
|
||||||
RETURN:
|
|
||||||
< 0 error
|
< 0 error
|
||||||
|
@return
|
||||||
== 0 table locked
|
== 0 table locked
|
||||||
|
@return
|
||||||
> 0 table locked, but someone is using it
|
> 0 table locked, but someone is using it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1102,23 +1093,22 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Lock all tables in list with a name lock
|
Lock all tables in list with a name lock.
|
||||||
|
|
||||||
SYNOPSIS
|
REQUIREMENTS
|
||||||
lock_table_names()
|
- One must have a lock on LOCK_open when calling this
|
||||||
thd Thread handle
|
|
||||||
table_list Names of tables to lock
|
|
||||||
|
|
||||||
NOTES
|
@param thd Thread handle
|
||||||
|
@param table_list Names of tables to lock
|
||||||
|
|
||||||
|
@note
|
||||||
If you are just locking one table, you should use
|
If you are just locking one table, you should use
|
||||||
lock_and_wait_for_table_name().
|
lock_and_wait_for_table_name().
|
||||||
|
|
||||||
REQUIREMENTS
|
@retval
|
||||||
One must have a lock on LOCK_open when calling this
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 Fatal error (end of memory ?)
|
1 Fatal error (end of memory ?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1148,12 +1138,13 @@ end:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Lock all tables in list with an exclusive table name lock.
|
Unlock all tables in list with a name lock.
|
||||||
|
|
||||||
@param thd Thread handle.
|
@param thd Thread handle.
|
||||||
@param table_list Names of tables to lock.
|
@param table_list Names of tables to lock.
|
||||||
|
|
||||||
@note This function needs to be protected by LOCK_open. If we're
|
@note
|
||||||
|
This function needs to be protected by LOCK_open. If we're
|
||||||
under LOCK TABLES, this function does not work as advertised. Namely,
|
under LOCK TABLES, this function does not work as advertised. Namely,
|
||||||
it does not exclude other threads from using this table and does not
|
it does not exclude other threads from using this table and does not
|
||||||
put an exclusive name lock on this table into the table cache.
|
put an exclusive name lock on this table into the table cache.
|
||||||
@ -1183,7 +1174,7 @@ bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Test is 'table' is protected by an exclusive name lock.
|
Test is 'table' is protected by an exclusive name lock.
|
||||||
|
|
||||||
@param[in] thd The current thread handler
|
@param[in] thd The current thread handler
|
||||||
@param[in] table_list Table container containing the single table to be
|
@param[in] table_list Table container containing the single table to be
|
||||||
@ -1211,7 +1202,7 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Test is 'table key' is protected by an exclusive name lock.
|
Test is 'table key' is protected by an exclusive name lock.
|
||||||
|
|
||||||
@param[in] thd The current thread handler.
|
@param[in] thd The current thread handler.
|
||||||
@param[in] key
|
@param[in] key
|
||||||
@ -1245,23 +1236,27 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unlock all tables in list with a name lock
|
Unlock all tables in list with a name lock.
|
||||||
|
|
||||||
SYNOPSIS
|
@param
|
||||||
unlock_table_names()
|
|
||||||
thd Thread handle
|
thd Thread handle
|
||||||
|
@param
|
||||||
table_list Names of tables to unlock
|
table_list Names of tables to unlock
|
||||||
|
@param
|
||||||
last_table Don't unlock any tables after this one.
|
last_table Don't unlock any tables after this one.
|
||||||
(default 0, which will unlock all tables)
|
(default 0, which will unlock all tables)
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
One must have a lock on LOCK_open when calling this.
|
One must have a lock on LOCK_open when calling this.
|
||||||
|
|
||||||
|
@note
|
||||||
This function will broadcast refresh signals to inform other threads
|
This function will broadcast refresh signals to inform other threads
|
||||||
that the name locks are removed.
|
that the name locks are removed.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 Fatal error (end of memory ?)
|
1 Fatal error (end of memory ?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1565,14 +1560,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Broadcast COND_refresh and COND_global_read_lock.
|
Broadcast COND_refresh and COND_global_read_lock.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
broadcast_refresh()
|
|
||||||
void No parameters.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Due to a bug in a threading library it could happen that a signal
|
Due to a bug in a threading library it could happen that a signal
|
||||||
did not reach its target. A condition for this was that the same
|
did not reach its target. A condition for this was that the same
|
||||||
condition variable was used with different mutexes in
|
condition variable was used with different mutexes in
|
||||||
@ -1584,12 +1574,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
|||||||
in global read lock handling. But now it is necessary to signal
|
in global read lock handling. But now it is necessary to signal
|
||||||
both conditions at the same time.
|
both conditions at the same time.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
When signalling COND_global_read_lock within the global read lock
|
When signalling COND_global_read_lock within the global read lock
|
||||||
handling, it is not necessary to also signal COND_refresh.
|
handling, it is not necessary to also signal COND_refresh.
|
||||||
|
|
||||||
RETURN
|
|
||||||
void
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void broadcast_refresh(void)
|
void broadcast_refresh(void)
|
||||||
|
446
sql/log.cc
446
sql/log.cc
@ -14,8 +14,15 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* logging of commands */
|
/**
|
||||||
/* TODO: Abort logging when we get an error in reading or writing log files */
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
logging of commands
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Abort logging when we get an error in reading or writing log files
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_repl.h"
|
#include "sql_repl.h"
|
||||||
@ -689,7 +696,7 @@ void Log_to_file_event_handler::init_pthread_objects()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper around MYSQL_LOG::write() for slow log */
|
/** Wrapper around MYSQL_LOG::write() for slow log. */
|
||||||
|
|
||||||
bool Log_to_file_event_handler::
|
bool Log_to_file_event_handler::
|
||||||
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
|
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
|
||||||
@ -704,7 +711,7 @@ bool Log_to_file_event_handler::
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wrapper around MYSQL_LOG::write() for general log. We need it since we
|
Wrapper around MYSQL_LOG::write() for general log. We need it since we
|
||||||
want all log event handlers to have the same signature.
|
want all log event handlers to have the same signature.
|
||||||
*/
|
*/
|
||||||
@ -806,7 +813,7 @@ void LOGGER::cleanup_end()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform basic log initialization: create file-based log handler and
|
Perform basic log initialization: create file-based log handler and
|
||||||
init error log.
|
init error log.
|
||||||
*/
|
*/
|
||||||
@ -1466,9 +1473,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
NOTE: how do we handle this (unlikely but legal) case:
|
@note
|
||||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
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
|
The problem occurs when a savepoint is before the update to the
|
||||||
non-transactional table. Then when there's a rollback to the savepoint, if we
|
non-transactional table. Then when there's a rollback to the savepoint, if we
|
||||||
simply truncate the binlog cache, we lose the part of the binlog cache where
|
simply truncate the binlog cache, we lose the part of the binlog cache where
|
||||||
@ -1615,11 +1625,14 @@ static void setup_windows_event_source()
|
|||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/**
|
||||||
** Find a uniq filename for 'filename.#'.
|
Find a unique filename for 'filename.#'.
|
||||||
** Set # to a number as low as possible
|
|
||||||
** returns != 0 if not possible to get uniq filename
|
Set '#' to a number as low as possible.
|
||||||
****************************************************************************/
|
|
||||||
|
@return
|
||||||
|
nonzero if not possible to get unique filename
|
||||||
|
*/
|
||||||
|
|
||||||
static int find_uniq_filename(char *name)
|
static int find_uniq_filename(char *name)
|
||||||
{
|
{
|
||||||
@ -1833,7 +1846,7 @@ void MYSQL_LOG::close(uint exiting)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called only once */
|
/** This is called only once. */
|
||||||
|
|
||||||
void MYSQL_LOG::cleanup()
|
void MYSQL_LOG::cleanup()
|
||||||
{
|
{
|
||||||
@ -2160,6 +2173,11 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
The following should be using fn_format(); We just need to
|
||||||
|
first change fn_format() to cut the file name if it's too long.
|
||||||
|
*/
|
||||||
const char *MYSQL_LOG::generate_name(const char *log_name,
|
const char *MYSQL_LOG::generate_name(const char *log_name,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
bool strip_ext, char *buff)
|
bool strip_ext, char *buff)
|
||||||
@ -2278,17 +2296,17 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Open a (new) binlog file.
|
Open a (new) binlog file.
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
- Open the log file and the index file. Register the new
|
- Open the log file and the index file. Register the new
|
||||||
file name in it
|
file name in it
|
||||||
- When calling this when the file is in use, you must have a locks
|
- When calling this when the file is in use, you must have a locks
|
||||||
on LOCK_log and LOCK_index.
|
on LOCK_log and LOCK_index.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2440,24 +2458,20 @@ int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Move all data up in a file in an filename index file
|
Move all data up in a file in an filename index file.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
copy_up_file_and_fill()
|
|
||||||
index_file File to move
|
|
||||||
offset Move everything from here to beginning
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
File will be truncated to be 'offset' shorter or filled up with
|
|
||||||
newlines
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
We do the copy outside of the IO_CACHE as the cache buffers would just
|
We do the copy outside of the IO_CACHE as the cache buffers would just
|
||||||
make things slower and more complicated.
|
make things slower and more complicated.
|
||||||
In most cases the copy loop should only do one read.
|
In most cases the copy loop should only do one read.
|
||||||
|
|
||||||
RETURN VALUES
|
@param index_file File to move
|
||||||
|
@param offset Move everything from here to beginning
|
||||||
|
|
||||||
|
@note
|
||||||
|
File will be truncated to be 'offset' shorter or filled up with newlines
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2498,25 +2512,25 @@ err:
|
|||||||
|
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find the position in the log-index-file for the given log name
|
Find the position in the log-index-file for the given log name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param linfo Store here the found log file name and position to
|
||||||
find_log_pos()
|
the NEXT log file name in the index file.
|
||||||
linfo Store here the found log file name and position to
|
@param log_name Filename to find in the index file.
|
||||||
the NEXT log file name in the index file.
|
Is a null pointer if we want to read the first entry
|
||||||
log_name Filename to find in the index file.
|
@param need_lock Set this to 1 if the parent doesn't already have a
|
||||||
Is a null pointer if we want to read the first entry
|
lock on LOCK_index
|
||||||
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
|
On systems without the truncate function the file will end with one or
|
||||||
more empty lines. These will be ignored when reading the file.
|
more empty lines. These will be ignored when reading the file.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
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
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2572,25 +2586,27 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find the position in the log-index-file for the given log name
|
Find the position in the log-index-file for the given log name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param
|
||||||
find_next_log()
|
|
||||||
linfo Store here the next log file name and position to
|
linfo Store here the next log file name and position to
|
||||||
the file name after that.
|
the file name after that.
|
||||||
|
@param
|
||||||
need_lock Set this to 1 if the parent doesn't already have a
|
need_lock Set this to 1 if the parent doesn't already have a
|
||||||
lock on LOCK_index
|
lock on LOCK_index
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
- Before calling this function, one has to call find_log_pos()
|
- Before calling this function, one has to call find_log_pos()
|
||||||
to set up 'linfo'
|
to set up 'linfo'
|
||||||
- Mutex needed because we need to make sure the file pointer does not move
|
- Mutex needed because we need to make sure the file pointer does not move
|
||||||
from under our feet
|
from under our feet
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
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
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2624,21 +2640,20 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Delete all logs refered to in the index file
|
Delete all logs refered to in the index file.
|
||||||
Start writing to a new log file. The new index file will only contain
|
Start writing to a new log file.
|
||||||
this file.
|
|
||||||
|
|
||||||
SYNOPSIS
|
The new index file will only contain this file.
|
||||||
reset_logs()
|
|
||||||
thd Thread
|
|
||||||
|
|
||||||
NOTE
|
@param thd Thread
|
||||||
|
|
||||||
|
@note
|
||||||
If not called from slave thread, write start event to new log
|
If not called from slave thread, write start event to new log
|
||||||
|
|
||||||
|
@retval
|
||||||
RETURN VALUES
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2702,38 +2717,40 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Delete relay log files prior to rli->group_relay_log_name
|
Delete relay log files prior to rli->group_relay_log_name
|
||||||
(i.e. all logs which are not involved in a non-finished group
|
(i.e. all logs which are not involved in a non-finished group
|
||||||
(transaction)), remove them from the index file and start on next relay log.
|
(transaction)), remove them from the index file and start on next
|
||||||
|
relay log.
|
||||||
SYNOPSIS
|
|
||||||
purge_first_log()
|
|
||||||
rli Relay log information
|
|
||||||
included If false, all relay logs that are strictly before
|
|
||||||
rli->group_relay_log_name are deleted ; if true, the latter is
|
|
||||||
deleted too (i.e. all relay logs
|
|
||||||
read by the SQL slave thread are deleted).
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
- This is only called from the slave-execute thread when it has read
|
|
||||||
all commands from a relay log and want to switch to a new relay log.
|
|
||||||
- When this happens, we can be in an active transaction as
|
|
||||||
a transaction can span over two relay logs
|
|
||||||
(although it is always written as a single block to the master's binary
|
|
||||||
log, hence cannot span over two master's binary logs).
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
- Protects index file with LOCK_index
|
- Protects index file with LOCK_index
|
||||||
- Delete relevant relay log files
|
- Delete relevant relay log files
|
||||||
- Copy all file names after these ones to the front of the index file
|
- 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'
|
- If the OS has truncate, truncate the file, else fill it with \n'
|
||||||
- Read the next file name from the index file and store in rli->linfo
|
- Read the next file name from the index file and store in rli->linfo
|
||||||
|
|
||||||
RETURN VALUES
|
@param rli Relay log information
|
||||||
|
@param included If false, all relay logs that are strictly before
|
||||||
|
rli->group_relay_log_name are deleted ; if true, the
|
||||||
|
latter is deleted too (i.e. all relay logs
|
||||||
|
read by the SQL slave thread are deleted).
|
||||||
|
|
||||||
|
@note
|
||||||
|
- This is only called from the slave-execute thread when it has read
|
||||||
|
all commands from a relay log and want to switch to a new relay log.
|
||||||
|
- When this happens, we can be in an active transaction as
|
||||||
|
a transaction can span over two relay logs
|
||||||
|
(although it is always written as a single block to the master's binary
|
||||||
|
log, hence cannot span over two master's binary logs).
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
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
|
LOG_INFO_SEEK Could not allocate IO cache
|
||||||
|
@retval
|
||||||
LOG_INFO_IO Got IO error while reading file
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2811,8 +2828,8 @@ err:
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update log index_file
|
Update log index_file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
|
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
|
||||||
@ -2826,25 +2843,24 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove all logs before the given log from disk and from the index file.
|
Remove all logs before the given log from disk and from the index file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param to_log Delete all log file name before this file.
|
||||||
purge_logs()
|
@param included If true, to_log is deleted too.
|
||||||
to_log Delete all log file name before this file.
|
@param need_mutex
|
||||||
included If true, to_log is deleted too.
|
@param need_update_threads If we want to update the log coordinates of
|
||||||
need_mutex
|
all threads. False for relay logs, true otherwise.
|
||||||
need_update_threads If we want to update the log coordinates of
|
@param freed_log_space If not null, decrement this variable of
|
||||||
all threads. False for relay logs, true otherwise.
|
the amount of log space freed
|
||||||
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,
|
If any of the logs before the deleted one is in use,
|
||||||
only purge logs up to this one.
|
only purge logs up to this one.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
LOG_INFO_EOF to_log not found
|
LOG_INFO_EOF to_log not found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2928,21 +2944,20 @@ err:
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove all logs before the given file date from disk and from the
|
Remove all logs before the given file date from disk and from the
|
||||||
index file.
|
index file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread pointer
|
||||||
purge_logs_before_date()
|
@param before_date Delete all log files before given date.
|
||||||
thd Thread pointer
|
|
||||||
before_date Delete all log files before given date.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If any of the logs before the deleted one is in use,
|
If any of the logs before the deleted one is in use,
|
||||||
only purge logs up to this one.
|
only purge logs up to this one.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2992,14 +3007,12 @@ err:
|
|||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create a new log file name
|
Create a new log file name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param buf buf of at least FN_REFLEN where new name is stored
|
||||||
make_log_name()
|
|
||||||
buf buf of at least FN_REFLEN where new name is stored
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
If file name will be longer then FN_REFLEN it will be truncated
|
If file name will be longer then FN_REFLEN it will be truncated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3013,8 +3026,8 @@ void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if we are writing/reading to the given log file
|
Check if we are writing/reading to the given log file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
|
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
|
||||||
@ -3043,14 +3056,12 @@ void MYSQL_BIN_LOG::new_file_without_locking()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Start writing to a new log file or reopen the old file
|
Start writing to a new log file or reopen the old file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param need_lock Set to 1 if caller has not locked LOCK_log
|
||||||
new_file_impl()
|
|
||||||
need_lock Set to 1 if caller has not locked LOCK_log
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
The new file name is stored last in the index file
|
The new file name is stored last in the index file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3521,8 +3532,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Write an event to the binary log
|
Write an event to the binary log.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||||
@ -3922,27 +3933,25 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
|
|||||||
return 0; // All OK
|
return 0; // All OK
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Write a cached log entry to the binary log
|
Write a cached log entry to the binary log.
|
||||||
|
- 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
|
@param thd
|
||||||
write()
|
@param cache The cache to copy to the binlog
|
||||||
thd
|
@param commit_event The commit event to print after writing the
|
||||||
cache The cache to copy to the binlog
|
|
||||||
commit_event The commit event to print after writing the
|
|
||||||
contents of the cache.
|
contents of the cache.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
- We only come here if there is something in the cache.
|
We only come here if there is something in the cache.
|
||||||
- The thing in the cache is always a complete transaction
|
@note
|
||||||
- 'cache' needs to be reinitialized after this functions returns.
|
The thing in the cache is always a complete transaction.
|
||||||
|
@note
|
||||||
IMPLEMENTATION
|
'cache' needs to be reinitialized after this functions returns.
|
||||||
- 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
||||||
@ -4039,17 +4048,15 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wait until we get a signal that the binary log has been updated
|
Wait until we get a signal that the binary log has been updated.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread variable
|
||||||
wait_for_update()
|
@param is_slave If 0, the caller is the Binlog_dump thread from master;
|
||||||
thd Thread variable
|
if 1, the caller is the SQL thread from the slave. This
|
||||||
is_slave If 0, the caller is the Binlog_dump thread from master;
|
influences only thd->proc_info.
|
||||||
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.
|
One must have a lock on LOCK_log before calling this function.
|
||||||
This lock will be released before return! That's required by
|
This lock will be released before return! That's required by
|
||||||
THD::enter_cond() (see NOTES in sql_class.h).
|
THD::enter_cond() (see NOTES in sql_class.h).
|
||||||
@ -4072,18 +4079,16 @@ void MYSQL_BIN_LOG::wait_for_update(THD* thd, bool is_slave)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Close the log file
|
Close the log file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param exiting Bitmask for one or more of the following bits:
|
||||||
close()
|
- LOG_CLOSE_INDEX : if we should close the index file
|
||||||
exiting Bitmask for one or more of the following bits:
|
- LOG_CLOSE_TO_BE_OPENED : if we intend to call open
|
||||||
LOG_CLOSE_INDEX if we should close the index file
|
at once after close.
|
||||||
LOG_CLOSE_TO_BE_OPENED if we intend to call open
|
- LOG_CLOSE_STOP_EVENT : write a 'stop' event to the log
|
||||||
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.
|
One can do an open on the object at once after doing a close.
|
||||||
The internal structures are not freed until cleanup() is called
|
The internal structures are not freed until cleanup() is called
|
||||||
*/
|
*/
|
||||||
@ -4163,21 +4168,20 @@ void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if a string is a valid number
|
Check if a string is a valid number.
|
||||||
|
|
||||||
SYNOPSIS
|
@param str String to test
|
||||||
test_if_number()
|
@param res Store value here
|
||||||
str String to test
|
@param allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||||
res Store value here
|
|
||||||
allow_wildcards Set to 1 if we should ignore '%' and '_'
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
For the moment the allow_wildcards argument is not used
|
For the moment the allow_wildcards argument is not used
|
||||||
Should be move to some other file.
|
Should be move to some other file.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 String is a number
|
1 String is a number
|
||||||
|
@retval
|
||||||
0 Error
|
0 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4318,23 +4322,18 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
|
|||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prints a printf style message to the error log and, under NT, to the
|
Prints a printf style message to the error log and, under NT, to the
|
||||||
Windows event log.
|
Windows event log.
|
||||||
|
|
||||||
SYNOPSIS
|
This function prints the message into a buffer and then sends that buffer
|
||||||
vprint_msg_to_log()
|
to other functions to write that message to other logging sources.
|
||||||
event_type Type of event to write (Error, Warning, or Info)
|
|
||||||
format Printf style format of message
|
|
||||||
args va_list list of arguments for the message
|
|
||||||
|
|
||||||
NOTE
|
@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
|
@returns
|
||||||
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
|
|
||||||
The function always returns 0. The return value is present in the
|
The function always returns 0. The return value is present in the
|
||||||
signature to be compatible with other logging routines, which could
|
signature to be compatible with other logging routines, which could
|
||||||
return an error (e.g. logging to the log tables)
|
return an error (e.g. logging to the log tables)
|
||||||
@ -4588,16 +4587,18 @@ err:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
there is no active page, let's got one from the pool
|
there is no active page, let's got one from the pool.
|
||||||
|
|
||||||
two strategies here:
|
Two strategies here:
|
||||||
1. take the first from the pool
|
-# take the first from the pool
|
||||||
2. if there're waiters - take the one with the most free space
|
-# if there're waiters - take the one with the most free space.
|
||||||
|
|
||||||
TODO page merging. try to allocate adjacent page first,
|
@todo
|
||||||
so that they can be flushed both in one sync
|
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()
|
void TC_LOG_MMAP::get_active_from_pool()
|
||||||
{
|
{
|
||||||
PAGE **p, **best_p=0;
|
PAGE **p, **best_p=0;
|
||||||
@ -4640,6 +4641,10 @@ void TC_LOG_MMAP::get_active_from_pool()
|
|||||||
pthread_mutex_unlock(&LOCK_pool);
|
pthread_mutex_unlock(&LOCK_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
perhaps, increase log size ?
|
||||||
|
*/
|
||||||
int TC_LOG_MMAP::overflow()
|
int TC_LOG_MMAP::overflow()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -4652,10 +4657,9 @@ int TC_LOG_MMAP::overflow()
|
|||||||
return 1; // always return 1
|
return 1; // always return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Record that transaction XID is committed on the persistent storage
|
Record that transaction XID is committed on the persistent storage.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function is called in the middle of two-phase commit:
|
This function is called in the middle of two-phase commit:
|
||||||
First all resources prepare the transaction, then tc_log->log() is called,
|
First all resources prepare the transaction, then tc_log->log() is called,
|
||||||
then all resources commit the transaction, then tc_log->unlog() is called.
|
then all resources commit the transaction, then tc_log->unlog() is called.
|
||||||
@ -4666,18 +4670,18 @@ int TC_LOG_MMAP::overflow()
|
|||||||
threads waiting for a page, but then all these threads will be waiting
|
threads waiting for a page, but then all these threads will be waiting
|
||||||
for a fsync() anyway
|
for a fsync() anyway
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
||||||
records XID in a special Xid_log_event.
|
records XID in a special Xid_log_event.
|
||||||
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
||||||
log.
|
log.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Error
|
0 - error
|
||||||
# "cookie", a number that will be passed as an argument
|
@retval
|
||||||
to unlog() call. tc_log can define it any way it wants,
|
\# - otherwise, "cookie", a number that will be passed as an argument
|
||||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
to unlog() call. tc_log can define it any way it wants,
|
||||||
to the position in memory where xid was logged to.
|
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)
|
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
|
||||||
@ -4785,9 +4789,9 @@ int TC_LOG_MMAP::sync()
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
erase xid from the page, update page free space counters/pointers.
|
erase xid from the page, update page free space counters/pointers.
|
||||||
cookie points directly to the memory where xid was logged
|
cookie points directly to the memory where xid was logged.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
|
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
|
||||||
@ -4898,16 +4902,17 @@ TC_LOG *tc_log;
|
|||||||
TC_LOG_DUMMY tc_log_dummy;
|
TC_LOG_DUMMY tc_log_dummy;
|
||||||
TC_LOG_MMAP tc_log_mmap;
|
TC_LOG_MMAP tc_log_mmap;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform heuristic recovery, if --tc-heuristic-recover was used
|
Perform heuristic recovery, if --tc-heuristic-recover was used.
|
||||||
|
|
||||||
RETURN VALUE
|
@note
|
||||||
0 no heuristic recovery was requested
|
|
||||||
1 heuristic recovery was performed
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
no matter whether heuristic recovery was successful or not
|
no matter whether heuristic recovery was successful or not
|
||||||
mysqld must exit. So, return value is the same in both cases.
|
mysqld must exit. So, return value is the same in both cases.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 no heuristic recovery was requested
|
||||||
|
@retval
|
||||||
|
1 heuristic recovery was performed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int TC_LOG::using_heuristic_recover()
|
int TC_LOG::using_heuristic_recover()
|
||||||
@ -4925,8 +4930,9 @@ int TC_LOG::using_heuristic_recover()
|
|||||||
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
||||||
#define TC_LOG_BINLOG MYSQL_BIN_LOG
|
#define TC_LOG_BINLOG MYSQL_BIN_LOG
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO keep in-memory list of prepared transactions
|
@todo
|
||||||
|
keep in-memory list of prepared transactions
|
||||||
(add to list in log(), remove on unlog())
|
(add to list in log(), remove on unlog())
|
||||||
and copy it to the new binlog if rotated
|
and copy it to the new binlog if rotated
|
||||||
but let's check the behaviour of tc_log_page_waits first!
|
but let's check the behaviour of tc_log_page_waits first!
|
||||||
@ -5017,7 +5023,7 @@ err:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called on shutdown, after ha_panic */
|
/** This is called on shutdown, after ha_panic. */
|
||||||
void TC_LOG_BINLOG::close()
|
void TC_LOG_BINLOG::close()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(prepared_xids==0);
|
DBUG_ASSERT(prepared_xids==0);
|
||||||
@ -5025,12 +5031,14 @@ void TC_LOG_BINLOG::close()
|
|||||||
pthread_cond_destroy (&COND_prep_xids);
|
pthread_cond_destroy (&COND_prep_xids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO group commit
|
@todo
|
||||||
|
group commit
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - error
|
0 error
|
||||||
1 - success
|
@retval
|
||||||
|
1 success
|
||||||
*/
|
*/
|
||||||
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
||||||
{
|
{
|
||||||
|
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)
|
inline int ignored_error_code(int err_code)
|
||||||
@ -212,21 +212,20 @@ static char *pretty_print_str(char *packet, char *str, int len)
|
|||||||
#endif /* !MYSQL_CLIENT */
|
#endif /* !MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Creates a temporary name for load data infile:
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
slave_load_file_stem()
|
Creates a temporary name for load data infile:.
|
||||||
buf Store new filename here
|
|
||||||
file_id File_id (part of file name)
|
|
||||||
event_server_id Event_id (part of file name)
|
|
||||||
ext Extension for file name
|
|
||||||
|
|
||||||
RETURN
|
@param buf Store new filename here
|
||||||
|
@param file_id File_id (part of file name)
|
||||||
|
@param event_server_id Event_id (part of file name)
|
||||||
|
@param ext Extension for file name
|
||||||
|
|
||||||
|
@return
|
||||||
Pointer to start of extension
|
Pointer to start of extension
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
static char *slave_load_file_stem(char *buf, uint file_id,
|
static char *slave_load_file_stem(char *buf, uint file_id,
|
||||||
int event_server_id, const char *ext)
|
int event_server_id, const char *ext)
|
||||||
{
|
{
|
||||||
@ -246,14 +245,12 @@ static char *slave_load_file_stem(char *buf, uint file_id,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Delete all temporary files used for SQL_LOAD.
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
cleanup_load_tmpdir()
|
Delete all temporary files used for SQL_LOAD.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
static void cleanup_load_tmpdir()
|
static void cleanup_load_tmpdir()
|
||||||
{
|
{
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
@ -321,7 +318,7 @@ static inline int read_str(const char **buf, const char *buf_end,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Transforms a string into "" or its expression in 0x... form.
|
Transforms a string into "" or its expression in 0x... form.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -338,12 +335,14 @@ char *str_to_hex(char *to, const char *from, uint len)
|
|||||||
return to; // pointer to end 0 of 'to'
|
return to; // pointer to end 0 of 'to'
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
|
/**
|
||||||
Append a version of the 'from' string suitable for use in a query to
|
Append a version of the 'from' string suitable for use in a query to
|
||||||
the 'to' string. To generate a correct escaping, the character set
|
the 'to' string. To generate a correct escaping, the character set
|
||||||
information in 'csinfo' is used.
|
information in 'csinfo' is used.
|
||||||
*/
|
*/
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
int
|
int
|
||||||
append_query_string(CHARSET_INFO *csinfo,
|
append_query_string(CHARSET_INFO *csinfo,
|
||||||
String const *from, String *to)
|
String const *from, String *to)
|
||||||
@ -370,7 +369,7 @@ append_query_string(CHARSET_INFO *csinfo,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
||||||
commands just before it prints a query.
|
commands just before it prints a query.
|
||||||
*/
|
*/
|
||||||
@ -395,8 +394,9 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
|
|||||||
Log_event methods (= the parent class of all events)
|
Log_event methods (= the parent class of all events)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::get_type_str()
|
@return
|
||||||
|
returns the human readable name of the event's type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char* Log_event::get_type_str()
|
const char* Log_event::get_type_str()
|
||||||
@ -444,7 +444,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This minimal constructor is for when you are not even sure that there
|
This minimal constructor is for when you are not even sure that there
|
||||||
is a valid THD. For example in the server when we are shutting down or
|
is a valid THD. For example in the server when we are shutting down or
|
||||||
flushing logs after receiving a SIGHUP (then we must write a Rotate to
|
flushing logs after receiving a SIGHUP (then we must write a Rotate to
|
||||||
@ -589,12 +589,9 @@ void Log_event::pack_info(Protocol *protocol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::net_send()
|
|
||||||
|
|
||||||
Only called by SHOW BINLOG EVENTS
|
Only called by SHOW BINLOG EVENTS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
||||||
{
|
{
|
||||||
const char *p= strrchr(log_name, FN_LIBCHAR);
|
const char *p= strrchr(log_name, FN_LIBCHAR);
|
||||||
@ -615,8 +612,10 @@ int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
|||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::init_show_field_list()
|
init_show_field_list() prepares the column names and types for the
|
||||||
|
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
|
||||||
|
EVENTS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Log_event::init_show_field_list(List<Item>* field_list)
|
void Log_event::init_show_field_list(List<Item>* field_list)
|
||||||
@ -712,12 +711,9 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::read_log_event()
|
|
||||||
|
|
||||||
This needn't be format-tolerant, because we only read
|
This needn't be format-tolerant, because we only read
|
||||||
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
|
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||||
@ -800,14 +796,11 @@ end:
|
|||||||
#define LOCK_MUTEX
|
#define LOCK_MUTEX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
#ifndef MYSQL_CLIENT
|
||||||
Log_event::read_log_event()
|
/**
|
||||||
|
@note
|
||||||
NOTE:
|
|
||||||
Allocates memory; The caller is responsible for clean-up.
|
Allocates memory; The caller is responsible for clean-up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||||
pthread_mutex_t* log_lock,
|
pthread_mutex_t* log_lock,
|
||||||
const Format_description_log_event
|
const Format_description_log_event
|
||||||
@ -905,8 +898,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::read_log_event()
|
|
||||||
Binlog format tolerance is in (buf, event_len, description_event)
|
Binlog format tolerance is in (buf, event_len, description_event)
|
||||||
constructors.
|
constructors.
|
||||||
*/
|
*/
|
||||||
@ -1233,12 +1225,13 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
|
|||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::pack_info()
|
|
||||||
This (which is used only for SHOW BINLOG EVENTS) could be updated to
|
This (which is used only for SHOW BINLOG EVENTS) could be updated to
|
||||||
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
|
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
|
||||||
only an information, it does not produce suitable queries to replay (for
|
only an information, it does not produce suitable queries to replay (for
|
||||||
example it does not print LOAD DATA INFILE).
|
example it does not print LOAD DATA INFILE).
|
||||||
|
@todo
|
||||||
|
show the catalog ??
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Query_log_event::pack_info(Protocol *protocol)
|
void Query_log_event::pack_info(Protocol *protocol)
|
||||||
@ -1267,7 +1260,9 @@ void Query_log_event::pack_info(Protocol *protocol)
|
|||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/* Utility function for the next method */
|
/**
|
||||||
|
Utility function for the next method (Query_log_event::write()) .
|
||||||
|
*/
|
||||||
static void write_str_with_code_and_len(char **dst, const char *src,
|
static void write_str_with_code_and_len(char **dst, const char *src,
|
||||||
int len, uint code)
|
int len, uint code)
|
||||||
{
|
{
|
||||||
@ -1279,10 +1274,10 @@ static void write_str_with_code_and_len(char **dst, const char *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::write()
|
Query_log_event::write().
|
||||||
|
|
||||||
NOTES:
|
@note
|
||||||
In this event we have to modify the header to have the correct
|
In this event we have to modify the header to have the correct
|
||||||
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
||||||
will print!
|
will print!
|
||||||
@ -1454,9 +1449,7 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||||||
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
|
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::Query_log_event()
|
|
||||||
|
|
||||||
The simplest constructor that could possibly work. This is used for
|
The simplest constructor that could possibly work. This is used for
|
||||||
creating static objects that have a special meaning and are invisible
|
creating static objects that have a special meaning and are invisible
|
||||||
to the log.
|
to the log.
|
||||||
@ -1580,8 +1573,7 @@ static void copy_str_and_move(const char **src,
|
|||||||
*(*dst)++= 0;
|
*(*dst)++= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::Query_log_event()
|
|
||||||
This is used by the SQL slave thread to prepare the event before execution.
|
This is used by the SQL slave thread to prepare the event before execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1748,11 +1740,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Query_log_event::print()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
|
/**
|
||||||
|
Query_log_event::print().
|
||||||
|
|
||||||
|
@todo
|
||||||
|
print the catalog ??
|
||||||
|
*/
|
||||||
void Query_log_event::print_query_header(IO_CACHE* file,
|
void Query_log_event::print_query_header(IO_CACHE* file,
|
||||||
PRINT_EVENT_INFO* print_event_info)
|
PRINT_EVENT_INFO* print_event_info)
|
||||||
{
|
{
|
||||||
@ -1937,6 +1931,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Compare the values of "affected rows" around here. Something
|
||||||
|
like:
|
||||||
|
@code
|
||||||
|
if ((uint32) affected_in_event != (uint32) affected_on_slave)
|
||||||
|
{
|
||||||
|
sql_print_error("Slave: did not get the expected number of affected \
|
||||||
|
rows running query from master - expected %d, got %d (this numbers \
|
||||||
|
should have matched modulo 4294967296).", 0, ...);
|
||||||
|
thd->query_error = 1;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
We may also want an option to tell the slave to ignore "affected"
|
||||||
|
mismatch. This mismatch could be implemented with a new ER_ code, and
|
||||||
|
to ignore it you would use --slave-skip-errors...
|
||||||
|
*/
|
||||||
int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
||||||
const char *query_arg, uint32 q_len_arg)
|
const char *query_arg, uint32 q_len_arg)
|
||||||
{
|
{
|
||||||
@ -2367,30 +2378,31 @@ bool Start_log_event_v3::write(IO_CACHE* file)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Start_log_event_v3::do_apply_event()
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start_log_event_v3::do_apply_event() .
|
||||||
The master started
|
The master started
|
||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
- To handle the case where the master died without having time to write
|
- To handle the case where the master died without having time to write
|
||||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
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
|
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||||
can (see below).
|
can (see below).
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
- Remove all active user locks.
|
- Remove all active user locks.
|
||||||
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
||||||
the use of a bit of memory for a user lock which will not be used
|
the use of a bit of memory for a user lock which will not be used
|
||||||
anymore. If the user lock is later used, the old one will be released. In
|
anymore. If the user lock is later used, the old one will be released. In
|
||||||
other words, no deadlock problem.
|
other words, no deadlock problem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
||||||
switch (binlog_version) {
|
switch (binlog_version)
|
||||||
|
{
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
/*
|
/*
|
||||||
@ -2438,23 +2450,20 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
|||||||
Format_description_log_event methods
|
Format_description_log_event methods
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Format_description_log_event 1st ctor.
|
Format_description_log_event 1st ctor.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
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
|
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
|
server starts or when FLUSH LOGS), or to create artificial events to parse
|
||||||
binlogs from MySQL 3.23 or 4.x.
|
binlogs from MySQL 3.23 or 4.x.
|
||||||
When in a client, only the 2nd use is possible.
|
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::
|
Format_description_log_event::
|
||||||
@ -2562,18 +2571,20 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The problem with this constructor is that the fixed header may have a
|
The problem with this constructor is that the fixed header may have a
|
||||||
length different from this version, but we don't know this length as we
|
length different from this version, but we don't know this length as we
|
||||||
have not read the Format_description_log_event which says it, yet. This
|
have not read the Format_description_log_event which says it, yet. This
|
||||||
length is in the post-header of the event, but we don't know where the
|
length is in the post-header of the event, but we don't know where the
|
||||||
post-header starts.
|
post-header starts.
|
||||||
|
|
||||||
So this type of event HAS to:
|
So this type of event HAS to:
|
||||||
- either have the header's length at the beginning (in the header, at a
|
- either have the header's length at the beginning (in the header, at a
|
||||||
fixed position which will never be changed), not in the post-header. That
|
fixed position which will never be changed), not in the post-header. That
|
||||||
would make the header be "shifted" compared to other events.
|
would make the header be "shifted" compared to other events.
|
||||||
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
|
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
|
||||||
versions, so that we know for sure.
|
versions, so that we know for sure.
|
||||||
|
|
||||||
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
||||||
it is sent before Format_description_log_event).
|
it is sent before Format_description_log_event).
|
||||||
*/
|
*/
|
||||||
@ -3008,14 +3019,11 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
|||||||
#endif /* !MYSQL_CLIENT */
|
#endif /* !MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Load_log_event::Load_log_event()
|
@note
|
||||||
|
|
||||||
NOTE
|
|
||||||
The caller must do buf[event_len] = 0 before he starts using the
|
The caller must do buf[event_len] = 0 before he starts using the
|
||||||
constructed event.
|
constructed event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
||||||
const Format_description_log_event *description_event)
|
const Format_description_log_event *description_event)
|
||||||
:Log_event(buf, description_event), num_fields(0), fields(0),
|
:Log_event(buf, description_event), num_fields(0), fields(0),
|
||||||
@ -3190,17 +3198,18 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
|
|||||||
}
|
}
|
||||||
#endif /* MYSQL_CLIENT */
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Load_log_event::set_fields()
|
Load_log_event::set_fields()
|
||||||
|
|
||||||
Note that this function can not use the member variable
|
@note
|
||||||
for the database, since LOAD DATA INFILE on the slave
|
This function can not use the member variable
|
||||||
can be for a different database than the current one.
|
for the database, since LOAD DATA INFILE on the slave
|
||||||
This is the reason for the affected_db argument to this method.
|
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,
|
void Load_log_event::set_fields(const char* affected_db,
|
||||||
List<Item> &field_list,
|
List<Item> &field_list,
|
||||||
Name_resolution_context *context)
|
Name_resolution_context *context)
|
||||||
@ -3218,32 +3227,33 @@ void Load_log_event::set_fields(const char* affected_db,
|
|||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
/*
|
/**
|
||||||
Does the data loading job when executing a LOAD DATA on the slave
|
Does the data loading job when executing a LOAD DATA on the slave.
|
||||||
|
|
||||||
SYNOPSIS
|
@param net
|
||||||
Load_log_event::do_apply_event
|
@param rli
|
||||||
net
|
@param use_rli_only_for_errors If set to 1, rli is provided to
|
||||||
rli
|
Load_log_event::exec_event only for this
|
||||||
use_rli_only_for_errors - if set to 1, rli is provided to
|
function to have RPL_LOG_NAME and
|
||||||
Load_log_event::do_apply_event
|
rli->last_slave_error, both being used by
|
||||||
only for this function to have
|
error reports. rli's position advancing
|
||||||
RPL_LOG_NAME and
|
is skipped (done by the caller which is
|
||||||
rli->last_slave_error, both being
|
Execute_load_log_event::exec_event).
|
||||||
used by error reports. rli's
|
If set to 0, rli is provided for full use,
|
||||||
position advancing is skipped (done
|
i.e. for error reports and position
|
||||||
by the caller which is
|
advancing.
|
||||||
Execute_load_log_event::do_apply_event).
|
|
||||||
- if set to 0, rli is provided for
|
|
||||||
full use, i.e. for error reports and
|
|
||||||
position advancing.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@todo
|
||||||
Does the data loading job when executing a LOAD DATA on the slave
|
fix this; this can be done by testing rules in
|
||||||
|
Create_file_log_event::exec_event() and then discarding Append_block and
|
||||||
|
al.
|
||||||
|
@todo
|
||||||
|
this is a bug - this needs to be moved to the I/O thread
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 Success
|
0 Success
|
||||||
1 Failure
|
@retval
|
||||||
|
1 Failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
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
|
#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
|
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||||
This is mainly used so that we can later figure out the logname and
|
in a A -> B -> A setup.
|
||||||
position for the master.
|
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
|
@retval
|
||||||
in a A -> B -> A setup.
|
|
||||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
0 ok
|
0 ok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
||||||
@ -3994,12 +4001,12 @@ void Xid_log_event::pack_info(Protocol *protocol)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
NOTE it's ok not to use int8store here,
|
@note
|
||||||
|
It's ok not to use int8store here,
|
||||||
as long as xid_t::set(ulonglong) and
|
as long as xid_t::set(ulonglong) and
|
||||||
xid_t::get_my_xid doesn't do it either
|
xid_t::get_my_xid doesn't do it either.
|
||||||
|
We don't care about actual values of xids as long as
|
||||||
we don't care about actual values of xids as long as
|
|
||||||
identical numbers compare identically
|
identical numbers compare identically
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4470,6 +4477,10 @@ void Slave_log_event::pack_info(Protocol *protocol)
|
|||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
re-write this better without holding both locks at the same time
|
||||||
|
*/
|
||||||
Slave_log_event::Slave_log_event(THD* thd_arg,
|
Slave_log_event::Slave_log_event(THD* thd_arg,
|
||||||
Relay_log_info* rli)
|
Relay_log_info* rli)
|
||||||
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
|
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
|
||||||
@ -4565,7 +4576,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This code is not used, so has not been updated to be format-tolerant */
|
/** This code is not used, so has not been updated to be format-tolerant. */
|
||||||
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
||||||
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
||||||
{
|
{
|
||||||
@ -4613,9 +4624,8 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
|||||||
#endif /* MYSQL_CLIENT */
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
/*
|
/*
|
||||||
Stop_log_event::do_apply_event()
|
|
||||||
|
|
||||||
The master stopped. We used to clean up all temporary tables but
|
The master stopped. We used to clean up all temporary tables but
|
||||||
this is useless as, as the master has shut down properly, it has
|
this is useless as, as the master has shut down properly, it has
|
||||||
written all DROP TEMPORARY TABLE (prepared statements' deletion is
|
written all DROP TEMPORARY TABLE (prepared statements' deletion is
|
||||||
@ -4626,8 +4636,6 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
|||||||
Start_log_event_v3::do_apply_event(), not here. Because if we come
|
Start_log_event_v3::do_apply_event(), not here. Because if we come
|
||||||
here, the master was sane.
|
here, the master was sane.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
int Stop_log_event::do_update_pos(Relay_log_info *rli)
|
int Stop_log_event::do_update_pos(Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -5437,7 +5445,9 @@ void Execute_load_query_log_event::print(FILE* file,
|
|||||||
print(file, print_event_info, 0);
|
print(file, print_event_info, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Prints the query as LOAD DATA LOCAL and with rewritten filename.
|
||||||
|
*/
|
||||||
void Execute_load_query_log_event::print(FILE* file,
|
void Execute_load_query_log_event::print(FILE* file,
|
||||||
PRINT_EVENT_INFO* print_event_info,
|
PRINT_EVENT_INFO* print_event_info,
|
||||||
const char *local_fname)
|
const char *local_fname)
|
||||||
@ -6471,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.
|
Save the field metadata based on the real_type of the field.
|
||||||
The metadata saved depends on the type of the field. Some fields
|
The metadata saved depends on the type of the field. Some fields
|
||||||
store a single byte for pack_length() while others store two bytes
|
store a single byte for pack_length() while others store two bytes
|
||||||
for field_length (max length).
|
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
|
Currently, the code attempts to minimize the number of bytes written to
|
||||||
the tablemap. There are at least two other alternatives; 1) using
|
the tablemap. There are at least two other alternatives; 1) using
|
||||||
net_store_length() to store the data allowing it to choose the number of
|
net_store_length() to store the data allowing it to choose the number of
|
||||||
@ -6494,7 +6506,6 @@ void Rows_log_event::print_helper(FILE *file,
|
|||||||
is less wasteful for space but does waste 1 byte for every field that does
|
is less wasteful for space but does waste 1 byte for every field that does
|
||||||
not encode 2 parts.
|
not encode 2 parts.
|
||||||
*/
|
*/
|
||||||
#if !defined(MYSQL_CLIENT)
|
|
||||||
int Table_map_log_event::save_field_metadata()
|
int Table_map_log_event::save_field_metadata()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Cashing of files with only does (sequential) read or writes of fixed-
|
@file
|
||||||
|
|
||||||
|
@details
|
||||||
|
Caching of files with only does (sequential) read or writes of fixed-
|
||||||
length records. A read isn't allowed to go over file-length. A read is ok
|
length records. A read isn't allowed to go over file-length. A read is ok
|
||||||
if it ends at file-length and next read can try to read after file-length
|
if it ends at file-length and next read can try to read after file-length
|
||||||
(and get a EOF-error).
|
(and get a EOF-error).
|
||||||
@ -34,11 +37,15 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Read buffered from the net.
|
Read buffered from the net.
|
||||||
** Returns 1 if can't read requested characters
|
|
||||||
** Returns 0 if record read
|
@retval
|
||||||
*/
|
1 if can't read requested characters
|
||||||
|
@retval
|
||||||
|
0 if record read
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
||||||
size_t Count __attribute__((unused)))
|
size_t Count __attribute__((unused)))
|
||||||
|
@ -18,17 +18,15 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
/*
|
/**
|
||||||
report result of decimal operation
|
report result of decimal operation.
|
||||||
|
|
||||||
SYNOPSIS
|
@param result decimal library return code (E_DEC_* see include/decimal.h)
|
||||||
decimal_operation_results()
|
|
||||||
result decimal library return code (E_DEC_* see include/decimal.h)
|
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
Fix error messages
|
Fix error messages
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
result
|
result
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
248
sql/mysqld.cc
248
sql/mysqld.cc
@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
|
|||||||
typedef fp_except fp_except_t;
|
typedef fp_except fp_except_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We can't handle floating point exceptions with threads, so disable
|
/**
|
||||||
this on freebsd
|
We can't handle floating point exceptions with threads, so disable
|
||||||
*/
|
this on freebsd.
|
||||||
|
*/
|
||||||
inline void reset_floating_point_exceptions()
|
inline void reset_floating_point_exceptions()
|
||||||
{
|
{
|
||||||
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
|
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
|
||||||
@ -325,7 +325,7 @@ static my_bool opt_short_log_format= 0;
|
|||||||
static uint kill_cached_threads, wake_thread;
|
static uint kill_cached_threads, wake_thread;
|
||||||
static ulong killed_threads, thread_created;
|
static ulong killed_threads, thread_created;
|
||||||
static ulong max_used_connections;
|
static ulong max_used_connections;
|
||||||
static ulong my_bind_addr; /* the address we bind to */
|
static ulong my_bind_addr; /**< the address we bind to */
|
||||||
static volatile ulong cached_thread_count= 0;
|
static volatile ulong cached_thread_count= 0;
|
||||||
static const char *sql_mode_str= "OFF";
|
static const char *sql_mode_str= "OFF";
|
||||||
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
||||||
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
|
|||||||
*/
|
*/
|
||||||
bool volatile grant_option;
|
bool volatile grant_option;
|
||||||
|
|
||||||
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted
|
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
|
||||||
my_bool opt_reckless_slave = 0;
|
my_bool opt_reckless_slave = 0;
|
||||||
my_bool opt_enable_named_pipe= 0;
|
my_bool opt_enable_named_pipe= 0;
|
||||||
my_bool opt_local_infile, opt_slave_compressed_protocol;
|
my_bool opt_local_infile, opt_slave_compressed_protocol;
|
||||||
@ -430,7 +430,7 @@ TYPELIB binlog_format_typelib=
|
|||||||
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
|
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
|
||||||
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
||||||
#ifdef HAVE_INITGROUPS
|
#ifdef HAVE_INITGROUPS
|
||||||
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
|
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
|
||||||
#endif
|
#endif
|
||||||
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
||||||
uint mysqld_port_timeout;
|
uint mysqld_port_timeout;
|
||||||
@ -458,12 +458,12 @@ ulong specialflag=0;
|
|||||||
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
||||||
ulong max_connections, max_connect_errors;
|
ulong max_connections, max_connect_errors;
|
||||||
uint max_user_connections= 0;
|
uint max_user_connections= 0;
|
||||||
/*
|
/**
|
||||||
Limit of the total number of prepared statements in the server.
|
Limit of the total number of prepared statements in the server.
|
||||||
Is necessary to protect the server against out-of-memory attacks.
|
Is necessary to protect the server against out-of-memory attacks.
|
||||||
*/
|
*/
|
||||||
ulong max_prepared_stmt_count;
|
ulong max_prepared_stmt_count;
|
||||||
/*
|
/**
|
||||||
Current total number of prepared statements in the server. This number
|
Current total number of prepared statements in the server. This number
|
||||||
is exact, and therefore may not be equal to the difference between
|
is exact, and therefore may not be equal to the difference between
|
||||||
`com_stmt_prepare' and `com_stmt_close' (global status variables), as
|
`com_stmt_prepare' and `com_stmt_close' (global status variables), as
|
||||||
@ -499,13 +499,13 @@ uint mysql_data_home_len;
|
|||||||
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
|
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
|
||||||
char server_version[SERVER_VERSION_LENGTH];
|
char server_version[SERVER_VERSION_LENGTH];
|
||||||
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
||||||
const char **errmesg; /* Error messages */
|
const char **errmesg; /**< Error messages */
|
||||||
const char *myisam_recover_options_str="OFF";
|
const char *myisam_recover_options_str="OFF";
|
||||||
const char *myisam_stats_method_str="nulls_unequal";
|
const char *myisam_stats_method_str="nulls_unequal";
|
||||||
|
|
||||||
/* name of reference on left espression in rewritten IN subquery */
|
/** name of reference on left espression in rewritten IN subquery */
|
||||||
const char *in_left_expr_name= "<left expr>";
|
const char *in_left_expr_name= "<left expr>";
|
||||||
/* name of additional condition */
|
/** name of additional condition */
|
||||||
const char *in_additional_cond= "<IN COND>";
|
const char *in_additional_cond= "<IN COND>";
|
||||||
const char *in_having_cond= "<IN HAVING>";
|
const char *in_having_cond= "<IN HAVING>";
|
||||||
|
|
||||||
@ -555,7 +555,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
|||||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||||
LOCK_global_system_variables,
|
LOCK_global_system_variables,
|
||||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||||
/*
|
/**
|
||||||
The below lock protects access to two global server variables:
|
The below lock protects access to two global server variables:
|
||||||
max_prepared_stmt_count and prepared_stmt_count. These variables
|
max_prepared_stmt_count and prepared_stmt_count. These variables
|
||||||
set the limit and hold the current total number of prepared statements
|
set the limit and hold the current total number of prepared statements
|
||||||
@ -604,7 +604,7 @@ static char **defaults_argv;
|
|||||||
static char *opt_bin_logname;
|
static char *opt_bin_logname;
|
||||||
|
|
||||||
static my_socket unix_sock,ip_sock;
|
static my_socket unix_sock,ip_sock;
|
||||||
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
|
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
struct passwd *user_info;
|
struct passwd *user_info;
|
||||||
@ -628,7 +628,7 @@ static char **opt_argv;
|
|||||||
static HANDLE hEventShutdown;
|
static HANDLE hEventShutdown;
|
||||||
static char shutdown_event_name[40];
|
static char shutdown_event_name[40];
|
||||||
#include "nt_servc.h"
|
#include "nt_servc.h"
|
||||||
static NTService Service; // Service object for WinNT
|
static NTService Service; ///< Service object for WinNT
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
@ -1009,19 +1009,15 @@ void kill_mysql(void)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Force server down. Kill all connections and threads and exit
|
Force server down. Kill all connections and threads and exit.
|
||||||
|
|
||||||
SYNOPSIS
|
@param sig_ptr Signal number that caused kill_server to be called.
|
||||||
kill_server
|
|
||||||
|
|
||||||
sig_ptr Signal number that caused kill_server to be called.
|
@note
|
||||||
|
|
||||||
NOTE!
|
|
||||||
A signal number of 0 mean that the function was not called
|
A signal number of 0 mean that the function was not called
|
||||||
from a signal handler and there is thus no signal to block
|
from a signal handler and there is thus no signal to block
|
||||||
or stop, we just want to kill the server.
|
or stop, we just want to kill the server.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__NETWARE__)
|
#if defined(__NETWARE__)
|
||||||
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef EMBEDDED_LIBRARY
|
||||||
cleanup all memory and end program nicely
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
unireg_end()
|
cleanup all memory and end program nicely.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function never returns.
|
|
||||||
|
|
||||||
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
||||||
by the main thread. To get MySQL to shut down nicely in this case
|
by the main thread. To get MySQL to shut down nicely in this case
|
||||||
(Mac OS X) we have to call exit() instead if pthread_exit().
|
(Mac OS X) we have to call exit() instead if pthread_exit().
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
@note
|
||||||
|
This function never returns.
|
||||||
|
*/
|
||||||
void unireg_end(void)
|
void unireg_end(void)
|
||||||
{
|
{
|
||||||
clean_up(1);
|
clean_up(1);
|
||||||
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
|
|||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This is mainly needed when running with purify, but it's still nice to
|
This is mainly needed when running with purify, but it's still nice to
|
||||||
know that all child threads have died when mysqld exits
|
know that all child threads have died when mysqld exits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void wait_for_signal_thread_to_end()
|
static void wait_for_signal_thread_to_end()
|
||||||
{
|
{
|
||||||
#ifndef __NETWARE__
|
#ifndef __NETWARE__
|
||||||
@ -1506,8 +1498,7 @@ static void set_effective_user(struct passwd *user_info_arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Change root user if started with --chroot */
|
/** Change root user if started with @c --chroot . */
|
||||||
|
|
||||||
static void set_root(const char *path)
|
static void set_root(const char *path)
|
||||||
{
|
{
|
||||||
#if !defined(__WIN__) && !defined(__NETWARE__)
|
#if !defined(__WIN__) && !defined(__NETWARE__)
|
||||||
@ -1696,19 +1687,16 @@ static void network_init(void)
|
|||||||
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
/*
|
/**
|
||||||
Close a connection
|
Close a connection.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handle
|
||||||
close_connection()
|
@param errcode Error code to print to console
|
||||||
thd Thread handle
|
@param lock 1 if we have have to lock LOCK_thread_count
|
||||||
errcode Error code to print to console
|
|
||||||
lock 1 if we have have to lock LOCK_thread_count
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
For the connection that is doing shutdown, this is called twice
|
For the connection that is doing shutdown, this is called twice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void close_connection(THD *thd, uint errcode, bool lock)
|
void close_connection(THD *thd, uint errcode, bool lock)
|
||||||
{
|
{
|
||||||
st_vio *vio;
|
st_vio *vio;
|
||||||
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
|
|||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
/* Called when a thread is aborted */
|
/** Called when a thread is aborted. */
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
|
||||||
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
@ -1877,13 +1864,13 @@ void flush_thread_cache()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Aborts a thread nicely. Commes here on SIGPIPE
|
|
||||||
TODO: One should have to fix that thr_alarm know about this
|
|
||||||
thread too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||||
|
/**
|
||||||
|
Aborts a thread nicely. Comes here on SIGPIPE.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
One should have to fix that thr_alarm know about this thread too.
|
||||||
|
*/
|
||||||
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
|
|||||||
|
|
||||||
#elif defined(__NETWARE__)
|
#elif defined(__NETWARE__)
|
||||||
|
|
||||||
// down server event callback
|
/// down server event callback.
|
||||||
void mysql_down_server_cb(void *, void *)
|
void mysql_down_server_cb(void *, void *)
|
||||||
{
|
{
|
||||||
event_flag= TRUE;
|
event_flag= TRUE;
|
||||||
@ -1939,7 +1926,7 @@ void mysql_down_server_cb(void *, void *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destroy callback resources
|
/// destroy callback resources.
|
||||||
void mysql_cb_destroy(void *)
|
void mysql_cb_destroy(void *)
|
||||||
{
|
{
|
||||||
UnRegisterEventNotification(eh); // cleanup down event notification
|
UnRegisterEventNotification(eh); // cleanup down event notification
|
||||||
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// initialize callbacks
|
/// initialize callbacks.
|
||||||
void mysql_cb_init()
|
void mysql_cb_init()
|
||||||
{
|
{
|
||||||
// register for down server event
|
// register for down server event
|
||||||
@ -1974,8 +1961,7 @@ void mysql_cb_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* To get the name of the NetWare volume having MySQL data folder */
|
/** To get the name of the NetWare volume having MySQL data folder. */
|
||||||
|
|
||||||
static void getvolumename()
|
static void getvolumename()
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
@ -1989,8 +1975,8 @@ static void getvolumename()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Registering with NEB for NSS Volume Deactivation event
|
Registering with NEB for NSS Volume Deactivation event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void registerwithneb()
|
static void registerwithneb()
|
||||||
@ -2042,8 +2028,8 @@ static void registerwithneb()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Callback for NSS Volume Deactivation event
|
Callback for NSS Volume Deactivation event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulong neb_event_callback(struct EventBlock *eblock)
|
ulong neb_event_callback(struct EventBlock *eblock)
|
||||||
@ -2075,12 +2061,11 @@ ulong neb_event_callback(struct EventBlock *eblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function to get NSS volume ID of the MySQL data
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
|
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Function to get NSS volume ID of the MySQL data.
|
||||||
|
*/
|
||||||
static void getvolumeID(BYTE *volumeName)
|
static void getvolumeID(BYTE *volumeName)
|
||||||
{
|
{
|
||||||
char path[zMAX_FULL_NAME];
|
char path[zMAX_FULL_NAME];
|
||||||
@ -2155,10 +2140,10 @@ static void start_signal_handler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Warn if the data is on a Traditional volume
|
Warn if the data is on a Traditional volume.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
Already done by mysqld_safe
|
Already done by mysqld_safe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2419,8 +2404,7 @@ static void start_signal_handler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This threads handles all signals and alarms */
|
/** This threads handles all signals and alarms. */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||||
{
|
{
|
||||||
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
|
|||||||
#endif /* __WIN__*/
|
#endif /* __WIN__*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
All global error messages are sent here where the first one is stored
|
All global error messages are sent here where the first one is stored
|
||||||
for the client
|
for the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
|
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
|
||||||
|
|
||||||
@ -2689,20 +2671,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
|
|||||||
#endif /*!EMBEDDED_LIBRARY*/
|
#endif /*!EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize one of the global date/time format variables
|
Initialize one of the global date/time format variables.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format_type What kind of format should be supported
|
||||||
init_global_datetime_format()
|
@param var_ptr Pointer to variable that should be updated
|
||||||
format_type What kind of format should be supported
|
|
||||||
var_ptr Pointer to variable that should be updated
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The default value is taken from either opt_date_time_formats[] or
|
The default value is taken from either opt_date_time_formats[] or
|
||||||
the ISO format (ANSI SQL)
|
the ISO format (ANSI SQL)
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4046,21 +4027,20 @@ static char *add_quoted_string(char *to, const char *from, char *to_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Handle basic handling of services, like installation and removal
|
Handle basic handling of services, like installation and removal.
|
||||||
|
|
||||||
SYNOPSIS
|
@param argv Pointer to argument list
|
||||||
default_service_handling()
|
@param servicename Internal name of service
|
||||||
argv Pointer to argument list
|
@param displayname Display name of service (in taskbar ?)
|
||||||
servicename Internal name of service
|
@param file_path Path to this program
|
||||||
displayname Display name of service (in taskbar ?)
|
@param startup_option Startup option to mysqld
|
||||||
file_path Path to this program
|
|
||||||
startup_option Startup option to mysqld
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 option handled
|
0 option handled
|
||||||
|
@retval
|
||||||
1 Could not handle option
|
1 Could not handle option
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
default_service_handling(char **argv,
|
default_service_handling(char **argv,
|
||||||
@ -4209,7 +4189,7 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute all commands from a file. Used by the mysql_install_db script to
|
Execute all commands from a file. Used by the mysql_install_db script to
|
||||||
create MySQL privilege tables without having to start a full MySQL server.
|
create MySQL privilege tables without having to start a full MySQL server.
|
||||||
*/
|
*/
|
||||||
@ -4334,23 +4314,17 @@ void create_thread_to_handle_connection(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create new thread to handle incoming connection.
|
Create new thread to handle incoming connection.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
create_new_thread()
|
|
||||||
thd in/out Thread handle of future thread.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function will create new thread to handle the incoming
|
This function will create new thread to handle the incoming
|
||||||
connection. If there are idle cached threads one will be used.
|
connection. If there are idle cached threads one will be used.
|
||||||
'thd' will be pushed into 'threads'.
|
'thd' will be pushed into 'threads'.
|
||||||
|
|
||||||
In single-threaded mode (#define ONE_THREAD) connection will be
|
In single-threaded mode (\#define ONE_THREAD) connection will be
|
||||||
handled inside this function.
|
handled inside this function.
|
||||||
|
|
||||||
RETURN VALUE
|
@param[in,out] thd Thread handle of future thread.
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void create_new_thread(THD *thd)
|
static void create_new_thread(THD *thd)
|
||||||
@ -4699,15 +4673,13 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
|||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Thread of shared memory's service
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
handle_connections_shared_memory()
|
|
||||||
arg Arguments of thread
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
|
|
||||||
|
/**
|
||||||
|
Thread of shared memory's service.
|
||||||
|
|
||||||
|
@param arg Arguments of thread
|
||||||
|
*/
|
||||||
pthread_handler_t handle_connections_shared_memory(void *arg)
|
pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||||
{
|
{
|
||||||
/* file-mapping object, use for create shared memory */
|
/* file-mapping object, use for create shared memory */
|
||||||
@ -7039,13 +7011,13 @@ To see what values a running MySQL server is using, type\n\
|
|||||||
#endif /*!EMBEDDED_LIBRARY*/
|
#endif /*!EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize all MySQL global variables to default values
|
Initialize all MySQL global variables to default values.
|
||||||
|
|
||||||
SYNOPSIS
|
We don't need to set numeric variables refered to in my_long_options
|
||||||
mysql_init_variables()
|
as these are initialized by my_getopt.
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The reason to set a lot of global variables to zero is to allow one to
|
The reason to set a lot of global variables to zero is to allow one to
|
||||||
restart the embedded server with a clean environment
|
restart the embedded server with a clean environment
|
||||||
It's also needed on some exotic platforms where global variables are
|
It's also needed on some exotic platforms where global variables are
|
||||||
@ -7771,7 +7743,7 @@ mysqld_get_one_option(int optid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handle arguments for multiple key caches */
|
/** Handle arguments for multiple key caches. */
|
||||||
|
|
||||||
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
|
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
|
||||||
const struct my_option *option);
|
const struct my_option *option);
|
||||||
@ -7822,6 +7794,10 @@ void option_error_reporter(enum loglevel level, const char *format, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
|
||||||
|
*/
|
||||||
static void get_options(int *argc,char **argv)
|
static void get_options(int *argc,char **argv)
|
||||||
{
|
{
|
||||||
int ho_error;
|
int ho_error;
|
||||||
@ -7953,10 +7929,11 @@ static char *get_relative_path(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Fix filename and replace extension where 'dir' is relative to
|
Fix filename and replace extension where 'dir' is relative to
|
||||||
mysql_real_data_home.
|
mysql_real_data_home.
|
||||||
Return 1 if len(path) > FN_REFLEN
|
@return
|
||||||
|
1 if len(path) > FN_REFLEN
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -8061,9 +8038,11 @@ static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return a bitfield from a string of substrings separated by ','
|
@return
|
||||||
returns ~(ulong) 0 on error.
|
a bitfield from a string of substrings separated by ','
|
||||||
|
or
|
||||||
|
~(ulong) 0 on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
|
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
|
||||||
@ -8122,16 +8101,16 @@ skip: ;
|
|||||||
} /* find_bit_type */
|
} /* find_bit_type */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if file system used for databases is case insensitive
|
Check if file system used for databases is case insensitive.
|
||||||
|
|
||||||
SYNOPSIS
|
@param dir_name Directory to test
|
||||||
test_if_case_sensitive()
|
|
||||||
dir_name Directory to test
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
-1 Don't know (Test failed)
|
-1 Don't know (Test failed)
|
||||||
|
@retval
|
||||||
0 File system is case sensitive
|
0 File system is case sensitive
|
||||||
|
@retval
|
||||||
1 File system is case insensitive
|
1 File system is case insensitive
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -8162,10 +8141,11 @@ static int test_if_case_insensitive(const char *dir_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create file to store pid number */
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create file to store pid number.
|
||||||
|
*/
|
||||||
static void create_pid_file()
|
static void create_pid_file()
|
||||||
{
|
{
|
||||||
File file;
|
File file;
|
||||||
@ -8187,7 +8167,7 @@ static void create_pid_file()
|
|||||||
}
|
}
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
/* Clear most status variables */
|
/** Clear most status variables. */
|
||||||
void refresh_status(THD *thd)
|
void refresh_status(THD *thd)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_status);
|
pthread_mutex_lock(&LOCK_status);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user