Merge bk-internal.mysql.com:/home/bk/mysql-5.1-maint

into  zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-maint


sql/field.cc:
  Auto merged
sql/filesort.cc:
  Auto merged
sql/ha_ndbcluster.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_create.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_geofunc.cc:
  Auto merged
sql/item_strfunc.cc:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/item_sum.cc:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
sql/log.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/net_serv.cc:
  Auto merged
sql/opt_sum.cc:
  Auto merged
sql/protocol.h:
  Auto merged
sql/records.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp_head.h:
  Auto merged
sql/sql_cache.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/sql_trigger.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
sql/sql_view.cc:
  Auto merged
sql/structs.h:
  Auto merged
sql/unireg.h:
  Auto merged
sql/item.cc:
  manual merge
sql/log_event.cc:
  manual merge
sql/protocol.cc:
  manual merge
sql/sp_head.cc:
  manual merge
sql/sql_base.cc:
  manual merge
sql/sql_parse.cc:
  manual merge
sql/sql_select.cc:
  manual merge
This commit is contained in:
unknown 2007-12-14 10:52:10 -05:00
commit 18f5e87ed9
66 changed files with 6340 additions and 6243 deletions

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Read language depeneded messagefile */ /**
@file
@brief
Read language depeneded messagefile
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include "mysys_err.h" #include "mysys_err.h"
@ -23,20 +28,17 @@ static bool read_texts(const char *file_name,const char ***point,
uint error_messages); uint error_messages);
static void init_myfunc_errs(void); static void init_myfunc_errs(void);
/* /**
Read messages from errorfile. Read messages from errorfile.
SYNOPSIS This function can be called multiple times to reload the messages.
init_errmessage() If it fails to load the messages, it will fail softly by initializing
the errmesg pointer to an array of empty strings or by keeping the
old array if it exists.
DESCRIPTION @retval
This function can be called multiple times to reload the messages.
If it fails to load the messages, it will fail softly by initializing
the errmesg pointer to an array of empty strings or by keeping the
old array if it exists.
RETURN
FALSE OK FALSE OK
@retval
TRUE Error TRUE Error
*/ */
@ -75,7 +77,14 @@ bool init_errmessage(void)
} }
/* Read text from packed textfile in language-directory */ /**
Read text from packed textfile in language-directory.
If we can't read messagefile then it's panic- we can't continue.
@todo
Convert the character set to server system character set
*/
static bool read_texts(const char *file_name,const char ***point, static bool read_texts(const char *file_name,const char ***point,
uint error_messages) uint error_messages)
@ -178,7 +187,9 @@ err1:
} /* read_texts */ } /* read_texts */
/* Initiates error-messages used by my_func-library */ /**
Initiates error-messages used by my_func-library.
*/
static void init_myfunc_errs() static void init_myfunc_errs()
{ {

View file

@ -21,17 +21,18 @@
struct st_des_keyschedule des_keyschedule[10]; struct st_des_keyschedule des_keyschedule[10];
uint des_default_key; uint des_default_key;
/* #define des_cs &my_charset_latin1
Function which loads DES keys from plaintext file into memory on MySQL
server startup and on command FLUSH DES_KEY_FILE.
Blame tonu@spam.ee on bugs ;)
RETURN /**
0 ok Load DES keys from plaintext file into
1 Error memory on MySQL server startup and on command FLUSH DES_KEY_FILE.
@retval
0 ok
@retval
1 Error
*/ */
#define des_cs &my_charset_latin1
bool bool
load_des_key_file(const char *file_name) load_des_key_file(const char *file_name)

View file

@ -14,29 +14,33 @@
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 for discover of frm file from handler */ /**
@file
@brief
Functions for discover of frm file from handler
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include <my_dir.h> #include <my_dir.h>
/* /**
Read the contents of a .frm file Read the contents of a .frm file.
SYNOPSIS frmdata and len are set to 0 on error.
readfrm()
name path to table-file "db/name" @param name path to table-file "db/name"
frmdata frm data @param frmdata frm data
len length of the read frmdata @param len length of the read frmdata
RETURN VALUES @retval
0 ok 0 ok
1 Could not open file @retval
2 Could not stat file 1 Could not open file
3 Could not allocate data for read @retval
Could not read file 2 Could not stat file
@retval
frmdata and len are set to 0 on error 3 Could not allocate data for read. Could not read file
*/ */
int readfrm(const char *name, uchar **frmdata, size_t *len) int readfrm(const char *name, uchar **frmdata, size_t *len)
@ -87,18 +91,16 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
/* /*
Write the content of a frm data pointer Write the content of a frm data pointer
to a frm file to a frm file.
SYNOPSIS @param name path to table-file "db/name"
writefrm() @param frmdata frm data
@param len length of the frmdata
name path to table-file "db/name" @retval
frmdata frm data 0 ok
len length of the frmdata @retval
2 Could not write file
RETURN VALUES
0 ok
2 Could not write file
*/ */
int writefrm(const char *name, const uchar *frmdata, size_t len) int writefrm(const char *name, const uchar *frmdata, size_t len)

View file

@ -14,9 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/***************************************************************************** /**
** This file implements classes defined in field.h @file
*****************************************************************************/
@brief
This file implements classes defined in field.h
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -913,14 +916,13 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
} }
}; };
/* /**
Return type of which can carry value of both given types in UNION result Return type of which can carry value of both given types in UNION result.
SYNOPSIS @param a type for merging
Field::field_type_merge() @param b type for merging
a, b types for merging
RETURN @return
type of field type of field
*/ */
@ -992,14 +994,12 @@ test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend)
} }
/* /**
Detect Item_result by given field type of UNION merge result Detect Item_result by given field type of UNION merge result.
SYNOPSIS @param field_type given field type
Field::result_merge_type()
field_type given field type
RETURN @return
Item_result (type of internal MySQL expression result) Item_result (type of internal MySQL expression result)
*/ */
@ -1015,18 +1015,17 @@ Item_result Field::result_merge_type(enum_field_types field_type)
*****************************************************************************/ *****************************************************************************/
/* /**
Check whether a field type can be partially indexed by a key Check whether a field type can be partially indexed by a key.
This is a static method, rather than a virtual function, because we need This is a static method, rather than a virtual function, because we need
to check the type of a non-Field in mysql_alter_table(). to check the type of a non-Field in mysql_alter_table().
SYNOPSIS @param type field type
type_can_have_key_part()
type field type
RETURN @retval
TRUE Type can have a prefixed key TRUE Type can have a prefixed key
@retval
FALSE Type can not have a prefixed key FALSE Type can not have a prefixed key
*/ */
@ -1048,8 +1047,8 @@ bool Field::type_can_have_key_part(enum enum_field_types type)
} }
/* /**
Numeric fields base class constructor Numeric fields base class constructor.
*/ */
Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
@ -1080,23 +1079,25 @@ void Field_num::prepend_zeros(String *value)
} }
} }
/* /**
Test if given number is a int. Test if given number is a int.
SYNOPSIS @todo
Field_num::check_int Make this multi-byte-character safe
cs Character set
str String to test
end Pointer to char after last used digit
length String length
error Error returned by strntoull10rnd()
NOTE @param str String to test
@param length Length of 'str'
@param int_end Pointer to char after last used digit
@param cs Character set
@note
This is called after one has called strntoull10rnd() function. This is called after one has called strntoull10rnd() function.
RETURN @retval
0 ok 0 OK
@retval
1 error: empty string or wrong integer. 1 error: empty string or wrong integer.
@retval
2 error: garbage at the end of string. 2 error: garbage at the end of string.
*/ */
@ -1191,16 +1192,15 @@ out_of_range:
return 1; return 1;
} }
/* /**
Process decimal library return codes and issue warnings for overflow and Process decimal library return codes and issue warnings for overflow and
truncation. truncation.
SYNOPSIS @param op_result decimal library return code (E_DEC_* see include/decimal.h)
Field::warn_if_overflow()
op_result decimal library return code (E_DEC_* see include/decimal.h)
RETURN @retval
1 there was overflow 1 there was overflow
@retval
0 no error or some other errors except overflow 0 no error or some other errors except overflow
*/ */
@ -1275,10 +1275,10 @@ static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
#endif #endif
/* /**
Interpret field value as an integer but return the result as a string. Interpret field value as an integer but return the result as a string.
This is used for printing bit_fields as numbers while debugging This is used for printing bit_fields as numbers while debugging.
*/ */
String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
@ -1299,6 +1299,7 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
} }
/// This is used as a table name when the table structure is not set up
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg, uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg) utype unireg_check_arg, const char *field_name_arg)
@ -1547,17 +1548,15 @@ void Field::make_field(Send_field *field)
} }
/* /**
Conversion from decimal to longlong with checking overflow and Conversion from decimal to longlong with checking overflow and
setting correct value (min/max) in case of overflow setting correct value (min/max) in case of overflow.
SYNOPSIS @param val value which have to be converted
Field::convert_decimal2longlong() @param unsigned_flag type of integer in which we convert val
val value which have to be converted @param err variable to pass error code
unsigned_flag type of integer in which we convert val
err variable to pass error code
RETURN @return
value converted from val value converted from val
*/ */
longlong Field::convert_decimal2longlong(const my_decimal *val, longlong Field::convert_decimal2longlong(const my_decimal *val,
@ -1591,19 +1590,18 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
} }
/* /**
Storing decimal in integer fields. Storing decimal in integer fields.
SYNOPSIS @param val value for storing
Field_num::store_decimal()
val value for storing
NOTE @note
This method is used by all integer fields, real/decimal redefine it This method is used by all integer fields, real/decimal redefine it
RETURN @retval
0 OK 0 OK
!= 0 error @retval
!=0 error
*/ */
int Field_num::store_decimal(const my_decimal *val) int Field_num::store_decimal(const my_decimal *val)
@ -1615,19 +1613,17 @@ int Field_num::store_decimal(const my_decimal *val)
} }
/* /**
Return decimal value of integer field Return decimal value of integer field.
SYNOPSIS @param decimal_value buffer for storing decimal value
Field_num::val_decimal()
decimal_value buffer for storing decimal value
NOTE @note
This method is used by all integer fields, real/decimal redefine it This method is used by all integer fields, real/decimal redefine it.
All longlong values fit in our decimal buffer which cal store 8*9=72 All longlong values fit in our decimal buffer which cal store 8*9=72
digits of integer number digits of integer number
RETURN @return
pointer to decimal buffer with value of field pointer to decimal buffer with value of field
*/ */
@ -1660,22 +1656,24 @@ void Field_num::make_field(Send_field *field)
field->decimals= dec; field->decimals= dec;
} }
/* /**
Decimal representation of Field_str Decimal representation of Field_str.
SYNOPSIS @param d value for storing
Field_str::store_decimal()
d value for storing
NOTE @note
Field_str is the base class for fields like Field_enum, Field_date and some Field_str is the base class for fields like Field_enum,
similar. Some dates use fraction and also string value should be Field_date and some similar. Some dates use fraction and also
converted to floating point value according our rules, so we use double string value should be converted to floating point value according
to store value of decimal in string our rules, so we use double to store value of decimal in string.
RETURN @todo
use decimal2string?
@retval
0 OK 0 OK
!= 0 error @retval
!=0 error
*/ */
int Field_str::store_decimal(const my_decimal *d) int Field_str::store_decimal(const my_decimal *d)
@ -1748,11 +1746,11 @@ bool Field::get_time(MYSQL_TIME *ltime)
return 0; return 0;
} }
/* /**
This is called when storing a date in a string This is called when storing a date in a string.
NOTES @note
Needs to be changed if/when we want to support different time formats Needs to be changed if/when we want to support different time formats.
*/ */
int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg) int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
@ -2374,9 +2372,9 @@ String *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
return val_ptr; return val_ptr;
} }
/* /**
** Should be able to handle at least the following fixed decimal formats: Should be able to handle at least the following fixed decimal formats:
** 5.00 , -1.0, 05, -05, +5 with optional pre/end space 5.00 , -1.0, 05, -05, +5 with optional pre/end space
*/ */
int Field_decimal::cmp(const uchar *a_ptr,const uchar *b_ptr) int Field_decimal::cmp(const uchar *a_ptr,const uchar *b_ptr)
@ -2498,13 +2496,11 @@ int Field_new_decimal::reset(void)
} }
/* /**
Generate max/min decimal value in case of overflow. Generate max/min decimal value in case of overflow.
SYNOPSIS @param decimal_value buffer for value
Field_new_decimal::set_value_on_overflow(); @param sign sign of value which caused overflow
decimal_value buffer for value
sign sign of value which caused overflow
*/ */
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value, void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
@ -2523,21 +2519,19 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
} }
/* /**
Store decimal value in the binary buffer Store decimal value in the binary buffer.
SYNOPSIS Checks if decimal_value fits into field size.
store_value(const my_decimal *decimal_value) If it does, stores the decimal in the buffer using binary format.
decimal_value my_decimal Otherwise sets maximal number that can be stored in the field.
DESCRIPTION @param decimal_value my_decimal
checks if decimal_value fits into field size.
if it does, stores the decimal in the buffer using binary format.
Otherwise sets maximal number that can be stored in the field.
RETURN @retval
0 ok 0 ok
1 error @retval
1 error
*/ */
bool Field_new_decimal::store_value(const my_decimal *decimal_value) bool Field_new_decimal::store_value(const my_decimal *decimal_value)
@ -2646,6 +2640,12 @@ int Field_new_decimal::store(const char *from, uint length,
} }
/**
@todo
Fix following when double2my_decimal when double2decimal
will return E_DEC_TRUNCATED always correctly
*/
int Field_new_decimal::store(double nr) int Field_new_decimal::store(double nr)
{ {
ASSERT_COLUMN_MARKED_FOR_WRITE; ASSERT_COLUMN_MARKED_FOR_WRITE;
@ -4667,9 +4667,8 @@ void Field_double::sql_type(String &res) const
} }
/* /**
TIMESTAMP type. TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
Holds datetime values in range from 1970-01-01 00:00:01 UTC to
2038-01-01 00:00:00 UTC stored as number of seconds since Unix 2038-01-01 00:00:00 UTC stored as number of seconds since Unix
Epoch in UTC. Epoch in UTC.
@ -4702,7 +4701,7 @@ void Field_double::sql_type(String &res) const
NONE - field which is not auto-set on update with some other than NOW() NONE - field which is not auto-set on update with some other than NOW()
default value (TIMESTAMP DEFAULT 0). default value (TIMESTAMP DEFAULT 0).
Note that TIMESTAMP_OLD_FIELD's are never created explicitly now, they are Note that TIMESTAMP_OLD_FIELDs are never created explicitly now, they are
left only for preserving ability to read old tables. Such fields replaced left only for preserving ability to read old tables. Such fields replaced
with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is
because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for
@ -4748,15 +4747,11 @@ Field_timestamp::Field_timestamp(bool maybe_null_arg,
} }
/* /**
Get auto-set type for TIMESTAMP field. Get auto-set type for TIMESTAMP field.
SYNOPSIS Returns value indicating during which operations this TIMESTAMP field
get_auto_set_type() should be auto-set to current timestamp.
DESCRIPTION
Returns value indicating during which operations this TIMESTAMP field
should be auto-set to current timestamp.
*/ */
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
{ {
@ -5239,7 +5234,8 @@ longlong Field_time::val_int(void)
} }
/* /**
@note
This function is multi-byte safe as the result string is always of type This function is multi-byte safe as the result string is always of type
my_charset_bin my_charset_bin
*/ */
@ -5266,7 +5262,8 @@ String *Field_time::val_str(String *val_buffer,
} }
/* /**
@note
Normally we would not consider 'time' as a valid date, but we allow Normally we would not consider 'time' as a valid date, but we allow
get_date() here to be able to do things like get_date() here to be able to do things like
DATE_FORMAT(time, "%l.%i %p") DATE_FORMAT(time, "%l.%i %p")
@ -6385,15 +6382,12 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
} }
/* /**
Store double value in Field_string or Field_varstring. Store double value in Field_string or Field_varstring.
SYNOPSIS Pretty prints double number into field_length characters buffer.
store(double nr)
nr number
DESCRIPTION @param nr number
Pretty prints double number into field_length characters buffer.
*/ */
int Field_str::store(double nr) int Field_str::store(double nr)
@ -6801,18 +6795,18 @@ int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length,
} }
/* /**
Compare a packed key against row Compare a packed key against row.
SYNOPSIS @param key Original key
pack_cmp() @param length Key length. (May be less than field length)
key Original key @param insert_or_update 1 if this is an insert or update
length Key length. (May be less than field length)
insert_or_update 1 if this is an insert or update
RETURN @return
< 0 row < key < 0 row < key
@return
0 row = key 0 row = key
@return
> 0 row > key > 0 row > key
*/ */
@ -7056,8 +7050,9 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
} }
/* /**
NOTE: varstring and blob keys are ALWAYS stored with a 2 byte length prefix @note
varstring and blob keys are ALWAYS stored with a 2 byte length prefix
*/ */
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length) int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
@ -7077,10 +7072,10 @@ int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
} }
/* /**
Compare to key segments (always 2 byte length prefix) Compare to key segments (always 2 byte length prefix).
NOTE @note
This is used only to compare key segments created for index_read(). This is used only to compare key segments created for index_read().
(keys are created and compared in key.cc) (keys are created and compared in key.cc)
*/ */
@ -7200,21 +7195,18 @@ Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
} }
/* /**
Unpack a key into a record buffer. Unpack a key into a record buffer.
SYNOPSIS A VARCHAR key has a maximum size of 64K-1.
unpack_key() In its packed form, the length field is one or two bytes long,
to Pointer into the record buffer. depending on 'max_length'.
key Pointer to the packed key.
max_length Key length limit from key description.
DESCRIPTION @param to Pointer into the record buffer.
A VARCHAR key has a maximum size of 64K-1. @param key Pointer to the packed key.
In its packed form, the length field is one or two bytes long, @param max_length Key length limit from key description.
depending on 'max_length'.
RETURN @return
Pointer to end of 'key' (To the next key part if multi-segment key) Pointer to end of 'key' (To the next key part if multi-segment key)
*/ */
@ -7236,16 +7228,14 @@ Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
return key + length; return key + length;
} }
/* /**
Create a packed key that will be used for storage in the index tree Create a packed key that will be used for storage in the index tree.
SYNOPSIS @param to Store packed key segment here
pack_key_from_key_image() @param from Key segment (as given to index_read())
to Store packed key segment here @param max_length Max length of key
from Key segment (as given to index_read())
max_length Max length of key
RETURN @return
end of key storage end of key storage
*/ */
@ -7579,21 +7569,15 @@ uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg, bool low_by
} }
/* /**
Put a blob length field into a record buffer. Put a blob length field into a record buffer.
SYNOPSIS Depending on the maximum length of a blob, its length field is
Field_blob::put_length() put into 1 to 4 bytes. This is a property of the blob object,
pos Pointer into the record buffer. described by 'packlength'.
length The length value to put.
DESCRIPTION @param pos Pointer into the record buffer.
Depending on the maximum length of a blob, its length field is @param length The length value to put.
put into 1 to 4 bytes. This is a property of the blob object,
described by 'packlength'.
RETURN
nothing
*/ */
void Field_blob::put_length(uchar *pos, uint32 length) void Field_blob::put_length(uchar *pos, uint32 length)
@ -8094,7 +8078,7 @@ int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
insert_or_update); insert_or_update);
} }
/* Create a packed key that will be used for storage from a MySQL row */ /** Create a packed key that will be used for storage from a MySQL row. */
uchar * uchar *
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length, Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
@ -8120,26 +8104,24 @@ Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
} }
/* /**
Unpack a blob key into a record buffer. Unpack a blob key into a record buffer.
SYNOPSIS A blob key has a maximum size of 64K-1.
Field_blob::unpack_key() In its packed form, the length field is one or two bytes long,
to Pointer into the record buffer. depending on 'max_length'.
from Pointer to the packed key. Depending on the maximum length of a blob, its length field is
max_length Key length limit from key description. put into 1 to 4 bytes. This is a property of the blob object,
described by 'packlength'.
Blobs are internally stored apart from the record buffer, which
contains a pointer to the blob buffer.
DESCRIPTION
A blob key has a maximum size of 64K-1.
In its packed form, the length field is one or two bytes long,
depending on 'max_length'.
Depending on the maximum length of a blob, its length field is
put into 1 to 4 bytes. This is a property of the blob object,
described by 'packlength'.
Blobs are internally stored apart from the record buffer, which
contains a pointer to the blob buffer.
RETURN @param to Pointer into the record buffer.
@param from Pointer to the packed key.
@param max_length Key length limit from key description.
@return
Pointer into 'from' past the last byte copied from packed key. Pointer into 'from' past the last byte copied from packed key.
*/ */
@ -8166,7 +8148,7 @@ Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
} }
/* Create a packed key that will be used for storage from a MySQL key */ /** Create a packed key that will be used for storage from a MySQL key. */
uchar * uchar *
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length, Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
@ -8358,9 +8340,10 @@ void Field_enum::store_type(ulonglong value)
} }
/* /**
** Note. Storing a empty string in a enum field gives a warning @note
** (if there isn't a empty value in the enum) Storing a empty string in a enum field gives a warning
(if there isn't a empty value in the enum)
*/ */
int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
@ -8686,7 +8669,12 @@ void Field_set::sql_type(String &res) const
res.append(')'); res.append(')');
} }
/* returns 1 if the fields are equally defined */ /**
@retval
1 if the fields are equally defined
@retval
0 if the fields are unequally defined
*/
bool Field::eq_def(Field *field) bool Field::eq_def(Field *field)
{ {
@ -8696,6 +8684,10 @@ bool Field::eq_def(Field *field)
return 1; return 1;
} }
/**
@return
returns 1 if the fields are equally defined
*/
bool Field_enum::eq_def(Field *field) bool Field_enum::eq_def(Field *field)
{ {
if (!Field::eq_def(field)) if (!Field::eq_def(field))
@ -8714,6 +8706,10 @@ bool Field_enum::eq_def(Field *field)
return 1; return 1;
} }
/**
@return
returns 1 if the fields are equally defined
*/
bool Field_num::eq_def(Field *field) bool Field_num::eq_def(Field *field)
{ {
if (!Field::eq_def(field)) if (!Field::eq_def(field))
@ -9289,14 +9285,8 @@ void Field_bit_as_char::sql_type(String &res) const
Handling of field and Create_field Handling of field and Create_field
*****************************************************************************/ *****************************************************************************/
/* /**
Convert Create_field::length from number of characters to number of bytes Convert create_field::length from number of characters to number of bytes.
SYNOPSIS
Create_field::create_length_to_internal_length()
DESCRIPTION
Convert Create_field::length from number of characters to number of bytes.
*/ */
void Create_field::create_length_to_internal_length(void) void Create_field::create_length_to_internal_length(void)
@ -9346,6 +9336,9 @@ void Create_field::create_length_to_internal_length(void)
} }
/**
Init for a tmp table field. To be extended if need be.
*/
void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
uint32 length_arg, uint32 decimals_arg, uint32 length_arg, uint32 decimals_arg,
bool maybe_null, bool is_unsigned) bool maybe_null, bool is_unsigned)
@ -9364,26 +9357,26 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
} }
/* /**
Initialize field definition for create Initialize field definition for create.
SYNOPSIS @param thd Thread handle
thd Thread handle @param fld_name Field name
fld_name Field name @param fld_type Field type
fld_type Field type @param fld_length Field length
fld_length Field length @param fld_decimals Decimal (if any)
fld_decimals Decimal (if any) @param fld_type_modifier Additional type information
fld_type_modifier Additional type information @param fld_default_value Field default value (if any)
fld_default_value Field default value (if any) @param fld_on_update_value The value of ON UPDATE clause
fld_on_update_value The value of ON UPDATE clause @param fld_comment Field comment
fld_comment Field comment @param fld_change Field change
fld_change Field change @param fld_interval_list Interval list (if any)
fld_interval_list Interval list (if any) @param fld_charset Field charset
fld_charset Field charset @param fld_geom_type Field geometry type (if any)
fld_geom_type Field geometry type (if any)
RETURN @retval
FALSE on success FALSE on success
@retval
TRUE on error TRUE on error
*/ */
@ -9971,7 +9964,7 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
} }
/* Create a field suitable for create of table */ /** Create a field suitable for create of table. */
Create_field::Create_field(Field *old_field,Field *orig_field) Create_field::Create_field(Field *old_field,Field *orig_field)
{ {
@ -10059,13 +10052,10 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
} }
/* /**
maximum possible display length for blob maximum possible display length for blob.
SYNOPSIS @return
Field_blob::max_display_length()
RETURN
length length
*/ */
@ -10092,24 +10082,23 @@ uint32 Field_blob::max_display_length()
Warning handling Warning handling
*****************************************************************************/ *****************************************************************************/
/* /**
Produce warning or note about data saved into field Produce warning or note about data saved into field.
SYNOPSIS @param level - level of message (Note/Warning/Error)
set_warning() @param code - error code of message to be produced
level - level of message (Note/Warning/Error) @param cuted_increment - whenever we should increase cut fields count or not
code - error code of message to be produced
cuted_increment - whenever we should increase cut fields count or not
NOTE @note
This function won't produce warning and increase cut fields counter This function won't produce warning and increase cut fields counter
if count_cuted_fields == CHECK_FIELD_IGNORE for current thread. if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes. if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
This allows us to avoid notes in optimisation, like convert_constant_item(). This allows us to avoid notes in optimisation, like convert_constant_item().
RETURN VALUE @retval
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE 1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
@retval
0 otherwise 0 otherwise
*/ */
@ -10133,21 +10122,19 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
} }
/* /**
Produce warning or note about datetime string data saved into field Produce warning or note about datetime string data saved into field.
SYNOPSIS @param level level of message (Note/Warning/Error)
set_datime_warning() @param code error code of message to be produced
level - level of message (Note/Warning/Error) @param str string value which we tried to save
code - error code of message to be produced @param str_length length of string which we tried to save
str - string value which we tried to save @param ts_type type of datetime value (datetime/date/time)
str_len - length of string which we tried to save @param cuted_increment whenever we should increase cut fields count or not
ts_type - type of datetime value (datetime/date/time)
cuted_increment - whenever we should increase cut fields count or not @note
This function will always produce some warning but won't increase cut
NOTE fields counter if count_cuted_fields ==FIELD_CHECK_IGNORE for current
This function will always produce some warning but won't increase cut
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread. thread.
*/ */
@ -10165,20 +10152,18 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
} }
/* /**
Produce warning or note about integer datetime value saved into field Produce warning or note about integer datetime value saved into field.
SYNOPSIS @param level level of message (Note/Warning/Error)
set_warning() @param code error code of message to be produced
level - level of message (Note/Warning/Error) @param nr numeric value which we tried to save
code - error code of message to be produced @param ts_type type of datetime value (datetime/date/time)
nr - numeric value which we tried to save @param cuted_increment whenever we should increase cut fields count or not
ts_type - type of datetime value (datetime/date/time)
cuted_increment - whenever we should increase cut fields count or not @note
This function will always produce some warning but won't increase cut
NOTE fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
This function will always produce some warning but won't increase cut
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread. thread.
*/ */
@ -10199,19 +10184,17 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
} }
/* /**
Produce warning or note about double datetime data saved into field Produce warning or note about double datetime data saved into field.
SYNOPSIS @param level level of message (Note/Warning/Error)
set_warning() @param code error code of message to be produced
level - level of message (Note/Warning/Error) @param nr double value which we tried to save
code - error code of message to be produced @param ts_type type of datetime value (datetime/date/time)
nr - double value which we tried to save
ts_type - type of datetime value (datetime/date/time) @note
This function will always produce some warning but won't increase cut
NOTE fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
This function will always produce some warning but won't increase cut
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
thread. thread.
*/ */

View file

@ -14,11 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
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)
{ {

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sorts a database */ /**
@file
@brief
Sorts a database
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#ifdef HAVE_STDDEF_H #ifdef HAVE_STDDEF_H
@ -27,8 +32,7 @@
#define SKIP_DBUG_IN_FILESORT #define SKIP_DBUG_IN_FILESORT
#endif #endif
/* How to write record_ref. */ /// How to write record_ref.
#define WRITE_REF(file,from) \ #define WRITE_REF(file,from) \
if (my_b_write((file),(uchar*) (from),param->ref_length)) \ if (my_b_write((file),(uchar*) (from),param->ref_length)) \
DBUG_RETURN(1); DBUG_RETURN(1);
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
uint sortlength, uint *plength); uint sortlength, uint *plength);
static void unpack_addon_fields(struct st_sort_addon_field *addon_field, static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
uchar *buff); uchar *buff);
/**
Sort a table.
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.
*/ */
@ -594,23 +598,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
*/ */
@ -653,8 +659,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)
@ -676,7 +682,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)
@ -990,7 +996,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)
@ -1043,8 +1049,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)
@ -1066,15 +1076,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)
@ -1099,22 +1109,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,
@ -1350,23 +1360,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
*/ */
@ -1453,33 +1461,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 *
@ -1555,20 +1561,18 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
} }
/* /**
Copy (unpack) values appended to sorted fields from a buffer back to Copy (unpack) values appended to sorted fields from a buffer back to
their regular positions specified by the Field::ptr pointers. their regular positions specified by the Field::ptr pointers.
SYNOPSIS @param addon_field Array of descriptors for appended fields
unpack_addon_fields() @param buff Buffer which to unpack the value from
addon_field Array of descriptors for appended fields
buff Buffer which to unpack the value from
NOTES @note
The function is supposed to be used only as a callback function The function is supposed to be used only as a callback function
when getting field values for the sorted result set. when getting field values for the sorted result set.
RETURN @return
void. void.
*/ */

View file

@ -13,8 +13,11 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
@file
@details
@verbatim
The idea of presented algorithm see in The idea of presented algorithm see in
"The Art of Computer Programming" by Donald E. Knuth "The Art of Computer Programming" by Donald E. Knuth
Volume 3 "Sorting and searching" Volume 3 "Sorting and searching"
@ -63,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

View file

@ -199,8 +199,8 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
} }
/** @brief /**
Use other database handler if databasehandler is not compiled in Use other database handler if databasehandler is not compiled in.
*/ */
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
bool no_substitute, bool report_error) bool no_substitute, bool report_error)
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
#endif #endif
/** @brief /**
Register handler error messages for use with my_error(). Register handler error messages for use with my_error().
SYNOPSIS @retval
ha_init_errors()
RETURN
0 OK 0 OK
!= 0 Error @retval
!=0 Error
*/ */
static int ha_init_errors(void) static int ha_init_errors(void)
{ {
@ -349,15 +347,13 @@ static int ha_init_errors(void)
} }
/** @brief /**
Unregister handler error messages. Unregister handler error messages.
SYNOPSIS @retval
ha_finish_errors()
RETURN
0 OK 0 OK
!= 0 Error @retval
!=0 Error
*/ */
static int ha_finish_errors(void) static int ha_finish_errors(void)
{ {
@ -567,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
*/ */
@ -1593,8 +1604,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.
*/ */
@ -1627,16 +1639,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)
@ -1702,23 +1714,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)
@ -1769,13 +1768,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
@ -2079,14 +2085,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)
{ {
@ -2273,14 +2279,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)
{ {
@ -2387,8 +2393,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");
@ -2401,21 +2409,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)
{ {
@ -2462,21 +2469,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)
{ {
@ -2511,7 +2517,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.
@ -2620,15 +2626,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,
@ -2666,17 +2669,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)
{ {
@ -2747,8 +2751,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)
{ {
@ -2771,8 +2775,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)
{ {
@ -2794,7 +2798,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)
@ -2810,8 +2814,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)
{ {
@ -2819,8 +2823,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)
@ -2830,13 +2834,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
{ {
@ -2881,9 +2887,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
@ -2926,16 +2932,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;
@ -3110,29 +3115,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,
@ -3166,23 +3171,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)
{ {
@ -3238,25 +3243,24 @@ scan_it_again:
} }
/** @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,
@ -3292,19 +3296,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()
{ {
@ -3325,22 +3328,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)
{ {
@ -3369,18 +3370,14 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
} }
/** @brief /**
Returns a list of all known extensions. Returns a list of all known extensions.
SYNOPSIS
ha_known_exts()
NOTES
No mutexes, worst case race is a minor surplus memory allocation No mutexes, worst case race is a minor surplus memory allocation
We have to recreate the extension map if mysqld is restarted (for example We have to recreate the extension map if mysqld is restarted (for example
within libmysqld) within libmysqld)
RETURN VALUE @retval
pointer pointer to TYPELIB structure pointer pointer to TYPELIB structure
*/ */
static my_bool exts_handlerton(THD *unused, plugin_ref plugin, static my_bool exts_handlerton(THD *unused, plugin_ref plugin,

View file

@ -14,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"

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all compare functions */ /**
@file
@brief
This file defines all compare functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -104,7 +109,7 @@ static int cmp_row_type(Item* item1, Item* item2)
} }
/* /**
Aggregates result types from the array of items. Aggregates result types from the array of items.
SYNOPSIS: SYNOPSIS:
@ -117,11 +122,13 @@ static int cmp_row_type(Item* item1, Item* item2)
This function aggregates result types from the array of items. Found type This function aggregates result types from the array of items. Found type
supposed to be used later for comparison of values of these items. supposed to be used later for comparison of values of these items.
Aggregation itself is performed by the item_cmp_type() function. Aggregation itself is performed by the item_cmp_type() function.
The function also checks compatibility of row signatures for the @param[out] type the aggregated type
submitted items (see the spec for the cmp_row_type function). @param items array of items to aggregate the type from
@param nitems number of items in the array
RETURN VALUES @retval
1 type incompatibility has been detected 1 type incompatibility has been detected
@retval
0 otherwise 0 otherwise
*/ */
@ -286,10 +293,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);
@ -322,10 +330,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()
@ -345,16 +356,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.
@ -362,16 +366,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)
@ -1058,13 +1067,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()
@ -1086,10 +1097,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;
@ -1230,7 +1242,7 @@ int Arg_comparator::compare_int_signed()
} }
/* /**
Compare values as BIGINT UNSIGNED. Compare values as BIGINT UNSIGNED.
*/ */
@ -1253,7 +1265,7 @@ int Arg_comparator::compare_int_unsigned()
} }
/* /**
Compare signed (*a) with unsigned (*B) Compare signed (*a) with unsigned (*B)
*/ */
@ -1278,7 +1290,7 @@ int Arg_comparator::compare_int_signed_unsigned()
} }
/* /**
Compare unsigned (*a) with signed (*B) Compare unsigned (*a) with signed (*B)
*/ */
@ -1314,7 +1326,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()
@ -1603,7 +1615,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()
{ {
@ -1757,21 +1769,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()
@ -1853,32 +1862,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
*/ */
@ -2222,30 +2230,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
*/ */
@ -2390,11 +2397,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
@ -2466,14 +2476,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.
@ -2487,9 +2490,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
*/ */
@ -2738,7 +2742,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)
{ {
@ -2780,7 +2787,7 @@ void Item_func_case::cleanup()
} }
/* /**
Coalesce - return first not NULL argument. Coalesce - return first not NULL argument.
*/ */
@ -3399,32 +3406,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
*/ */
@ -3899,25 +3905,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)
@ -3945,19 +3948,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
@ -3966,9 +3960,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,
@ -4017,23 +4018,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,
@ -4104,20 +4103,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
*/ */
@ -4159,24 +4160,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
*/ */
@ -4234,7 +4234,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)
@ -4294,7 +4296,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
{ {
@ -4580,10 +4584,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)
{ {
@ -4637,10 +4640,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)
{ {
@ -4682,10 +4684,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()
{ {
@ -4711,10 +4712,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
{ {
@ -4794,24 +4797,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()
@ -4833,15 +4832,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
@ -4853,8 +4849,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()).
*/ */
@ -4872,7 +4871,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]);
@ -4880,7 +4881,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]);
@ -4963,7 +4966,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);
@ -5028,19 +5033,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)
@ -5056,22 +5059,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)
@ -5091,28 +5087,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)
@ -5147,21 +5136,14 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
} }
/* /**
Check appearance of new constant items in the multiple equality object Check appearance of new constant items in the multiple equality object.
SYNOPSIS
update_const()
DESCRIPTION
The function checks appearance of new constant items among The function checks appearance of new constant items among
the members of multiple equalities. Each new constant item is the members of multiple equalities. Each new constant item is
compared with the designated constant item if there is any in the compared with the designated constant item if there is any in the
multiple equality. If there is none the first new constant item multiple equality. If there is none the first new constant item
becomes designated. becomes designated.
RETURN VALUES
none
*/ */
void Item_equal::update_const() void Item_equal::update_const()

View file

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

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all numerical functions */ /**
@file
@brief
This file defines all numerical functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -46,7 +51,10 @@ bool check_reserved_words(LEX_STRING *name)
} }
/* return TRUE if item is a constant */ /**
@return
TRUE if item is a constant
*/
bool bool
eval_const_cond(COND *cond) eval_const_cond(COND *cond)
@ -237,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)
{ {
@ -1574,7 +1561,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);
@ -1589,10 +1576,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()
{ {
@ -3021,8 +3009,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;
@ -3226,10 +3216,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()
{ {
@ -3327,10 +3318,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()
{ {
@ -3432,11 +3423,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()
@ -3556,12 +3551,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()
@ -3693,7 +3688,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()
{ {
@ -3849,22 +3844,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
@ -3949,7 +3944,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)
{ {
@ -3977,7 +3972,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)
{ {
@ -4008,7 +4003,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)
@ -4039,7 +4034,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)
{ {
@ -4066,18 +4061,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->is_error() check in sql_set_variables(). will be caught by thd->is_error() check in sql_set_variables().
RETURN @retval
FALSE OK. FALSE OK.
*/ */
@ -4126,18 +4120,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
*/ */
@ -4446,24 +4439,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
*/ */
@ -5118,22 +5110,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
*/ */
@ -5173,16 +5163,15 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
} }
/* /**
Check a user level lock. Check a user level lock.
SYNOPSIS: Sets null_value=TRUE on error.
val_int()
RETURN VALUES @retval
1 Available 1 Available
0 Already taken @retval
NULL Error 0 Already taken, or error
*/ */
longlong Item_func_is_free_lock::val_int() longlong Item_func_is_free_lock::val_int()

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all spatial functions */ /**
@file
@brief
This file defines all spatial functions
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -356,7 +361,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.
@ -538,6 +543,10 @@ longlong Item_func_isempty::val_int()
} }
/**
@todo
Ramil or Holyfoot, add real IsSimple calculation
*/
longlong Item_func_issimple::val_int() longlong Item_func_issimple::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);

View file

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

View file

@ -14,9 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all string functions /**
** Warning: Some string functions doesn't always put and end-null on a String @file
** (This shouldn't be needed)
@brief
This file defines all string functions
@warning
Some string functions don't always put and end-null on a String.
(This shouldn't be needed)
*/ */
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
@ -267,9 +273,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.
*/ */
@ -425,13 +431,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)
@ -604,7 +612,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.
*/ */
@ -826,12 +834,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)
{ {
@ -1796,8 +1806,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)
{ {
@ -1857,7 +1868,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
@ -2001,9 +2012,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;
@ -2022,8 +2034,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
*/ */
@ -2370,9 +2383,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)
@ -2848,7 +2861,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)
{ {
@ -3081,27 +3094,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);
@ -3347,8 +3360,10 @@ static uint nanoseq;
static ulonglong uuid_time=0; static ulonglong uuid_time=0;
static char clock_seq_and_node_str[]="-0000-000000000000"; static char clock_seq_and_node_str[]="-0000-000000000000";
/* number of 100-nanosecond intervals between /**
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */ number of 100-nanosecond intervals between
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
*/
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 ) #define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
#define UUID_VERSION 0x1000 #define UUID_VERSION 0x1000

View file

@ -13,12 +13,15 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
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
*/ */
@ -2423,16 +2436,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
*/ */
@ -2445,16 +2457,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
*/ */
@ -2468,16 +2479,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
*/ */
@ -2489,14 +2499,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()
@ -2521,14 +2529,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()
@ -2542,14 +2548,12 @@ bool subselect_union_engine::no_tables()
} }
/* /**
Report about presence of tables in subquery Report about presence of tables in subquery.
SYNOPSIS @retval
subselect_uniquesubquery_engine::no_tables()
RETURN
TRUE there are not tables used in subquery TRUE there are not tables used in subquery
@retval
FALSE there are some tables in subquery FALSE there are some tables in subquery
*/ */

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sum functions (COUNT, MIN...) */ /**
@file
@brief
Sum functions (COUNT, MIN...)
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -23,28 +28,25 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h" #include "sql_select.h"
/* /**
Prepare an aggregate function item for checking context conditions Prepare an aggregate function item for checking context conditions.
SYNOPSIS
init_sum_func_check()
thd reference to the thread context info
DESCRIPTION
The function initializes the members of the Item_sum object created The function initializes the members of the Item_sum object created
for a set function that are used to check validity of the set function for a set function that are used to check validity of the set function
occurrence. occurrence.
If the set function is not allowed in any subquery where it occurs If the set function is not allowed in any subquery where it occurs
an error is reported immediately. an error is reported immediately.
NOTES @param thd reference to the thread context info
@note
This function is to be called for any item created for a set function This function is to be called for any item created for a set function
object when the traversal of trees built for expressions used in the query object when the traversal of trees built for expressions used in the query
is performed at the phase of context analysis. This function is to is performed at the phase of context analysis. This function is to
be invoked at the descent of this traversal. be invoked at the descent of this traversal.
@retval
RETURN TRUE if an error is reported
TRUE if an error is reported @retval
FALSE otherwise FALSE otherwise
*/ */
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
return FALSE; return FALSE;
} }
/* /**
Check constraints imposed on a usage of a set function Check constraints imposed on a usage of a set function.
SYNOPSIS
check_sum_func()
thd reference to the thread context info
ref location of the pointer to this item in the embedding expression
DESCRIPTION
The method verifies whether context conditions imposed on a usage The method verifies whether context conditions imposed on a usage
of any set function are met for this occurrence. of any set function are met for this occurrence.
It checks whether the set function occurs in the position where it It checks whether the set function occurs in the position where it
@ -89,13 +85,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
adds it to the chain of items for such set functions that is attached adds it to the chain of items for such set functions that is attached
to the the st_select_lex structure for this subquery. to the the st_select_lex structure for this subquery.
NOTES
This function is to be called for any item created for a set function
object when the traversal of trees built for expressions used in the query
is performed at the phase of context analysis. This function is to
be invoked at the ascent of this traversal.
IMPLEMENTATION
A number of designated members of the object are used to check the A number of designated members of the object are used to check the
conditions. They are specified in the comment before the Item_sum conditions. They are specified in the comment before the Item_sum
class declaration. class declaration.
@ -106,16 +95,28 @@ bool Item_sum::init_sum_func_check(THD *thd)
of set functions are allowed (i.e either in the SELECT list or of set functions are allowed (i.e either in the SELECT list or
in the HAVING clause of the corresponding subquery) in the HAVING clause of the corresponding subquery)
Consider the query: Consider the query:
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;
@ -2004,8 +2011,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()
@ -2181,6 +2188,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()
{ {
@ -2369,7 +2380,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
@ -2436,7 +2447,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()
{ {
@ -2804,7 +2818,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()
{ {
@ -2854,9 +2868,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,
@ -2893,9 +2906,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)
@ -2937,11 +2949,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
@ -2956,8 +2968,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)),
@ -3028,12 +3040,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
} }
/* /**
Constructor of Item_func_group_concat Constructor of Item_func_group_concat.
distinct_arg - distinct
select_list - list of expression for show values @param distinct_arg distinct
order_list - list of sort columns @param select_list list of expression for show values
separator_arg - string value of separator @param order_list list of sort columns
@param separator_arg string value of separator.
*/ */
Item_func_group_concat:: Item_func_group_concat::

View file

@ -14,7 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all time functions */ /**
@file
@brief
This file defines all time functions
@todo
Move month and days to language files
*/
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
@ -24,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(&ltime); (void) get_arg0_time(&ltime);
return ltime.minute; return ltime.minute;
} }
// Returns the second in time_exp in the range of 0 - 59
/**
Returns the second in time_exp in the range of 0 - 59.
*/
longlong Item_func_second::val_int() longlong Item_func_second::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
return week_format; return week_format;
} }
/* /**
@verbatim
The bits in week_format(for calc_week() function) has the following meaning: The bits in week_format(for calc_week() function) has the following meaning:
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
If set Monday is first day of week If set Monday is first day of week
@ -1118,6 +1129,7 @@ uint week_mode(uint mode)
four or more days in the new year, then it is week 1; four or more days in the new year, then it is week 1;
Otherwise it is the last week of the previous year, and the Otherwise it is the last week of the previous year, and the
next week is week 1. next week is week 1.
@endverbatim
*/ */
longlong Item_func_week::val_int() longlong Item_func_week::val_int()
@ -1281,8 +1293,9 @@ longlong Item_func_time_to_sec::val_int()
} }
/* /**
Convert a string to a interval value Convert a string to a interval value.
To make code easy, allow interval objects without separators. To make code easy, allow interval objects without separators.
*/ */
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
return str; return str;
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURDATE function. time zone. Defines time zone (local) used for whole CURDATE function.
*/ */
@ -1519,7 +1532,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_DATE function. time zone. Defines time zone (UTC) used for whole UTC_DATE function.
*/ */
@ -1563,7 +1576,7 @@ void Item_func_curtime::fix_length_and_dec()
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURTIME function. time zone. Defines time zone (local) used for whole CURTIME function.
*/ */
@ -1576,7 +1589,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIME function. time zone. Defines time zone (UTC) used for whole UTC_TIME function.
*/ */
@ -1612,7 +1625,7 @@ void Item_func_now::fix_length_and_dec()
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole NOW function. time zone. Defines time zone (local) used for whole NOW function.
*/ */
@ -1625,7 +1638,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
} }
/* /**
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function. time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
*/ */
@ -1655,7 +1668,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.
*/ */
@ -2618,7 +2631,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.
@ -2728,7 +2741,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
@ -2830,7 +2843,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.
@ -2880,7 +2893,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
@ -2947,7 +2960,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.
@ -3173,25 +3186,28 @@ void Item_func_get_format::print(String *str)
} }
/* /**
Get type of datetime value (DATE/TIME/...) which will be produced Get type of datetime value (DATE/TIME/...) which will be produced
according to format string. according to format string.
SYNOPSIS @param format format string
get_date_time_result_type() @param length length of format string
format - format string
length - length of format string
NOTE @note
We don't process day format's characters('D', 'd', 'e') because day We don't process day format's characters('D', 'd', 'e') because day
may be a member of all date/time types. may be a member of all date/time types.
@note
Format specifiers supported by this function should be in sync with Format specifiers supported by this function should be in sync with
specifiers supported by extract_date_time() function. specifiers supported by extract_date_time() function.
RETURN VALUE @return
One of date_time_format_types values: One of date_time_format_types values:
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY - DATE_TIME_MICROSECOND
- DATE_TIME
- DATE_ONLY
- TIME_MICROSECOND
- TIME_ONLY
*/ */
static date_time_format_types static date_time_format_types

View file

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

View file

@ -14,8 +14,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* locking functions for mysql */ /**
/* @file
Locking functions for mysql.
Because of the new concurrent inserts, we must first get external locks Because of the new concurrent inserts, we must first get external locks
before getting internal locks. If we do it in the other order, the status before getting internal locks. If we do it in the other order, the status
information is not up to date when called from the lock handler. information is not up to date when called from the lock handler.
@ -65,7 +68,7 @@
excluding one that caused failure. That means handler must cleanup itself excluding one that caused failure. That means handler must cleanup itself
in case external_lock() fails. in case external_lock() fails.
TODO: @todo
Change to use my_malloc() ONLY when using LOCK TABLES command or when Change to use my_malloc() ONLY when using LOCK TABLES command or when
we are forced to use mysql_lock_merge. we are forced to use mysql_lock_merge.
*/ */
@ -390,10 +393,11 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
Unlock some of the tables locked by mysql_lock_tables Unlock some of the tables locked by mysql_lock_tables.
This will work even if get_lock_data fails (next unlock will free all) This will work even if get_lock_data fails (next unlock will free all)
*/ */
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count) void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
{ {
@ -405,8 +409,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
} }
/* /**
** unlock all tables locked for read. unlock all tables locked for read.
*/ */
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
@ -567,7 +571,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
} }
/* abort all other threads waiting to get lock in table */ /** Abort all other threads waiting to get lock in table. */
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
{ {
@ -586,16 +590,15 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
} }
/* /**
Abort one thread / table combination Abort one thread / table combination.
SYNOPSIS @param thd Thread handler
mysql_lock_abort_for_thread() @param table Table that should be removed from lock queue
thd Thread handler
table Table that should be removed from lock queue
RETURN @retval
0 Table was not locked by another thread 0 Table was not locked by another thread
@retval
1 Table was locked by at least one other thread 1 Table was locked by at least one other thread
*/ */
@ -663,28 +666,27 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
} }
/* /**
Find duplicate lock in tables. Find duplicate lock in tables.
SYNOPSIS 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)

View file

@ -14,8 +14,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* logging of commands */ /**
/* TODO: Abort logging when we get an error in reading or writing log files */ @file
@brief
logging of commands
@todo
Abort logging when we get an error in reading or writing log files
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_repl.h" #include "sql_repl.h"
@ -689,7 +696,7 @@ void Log_to_file_event_handler::init_pthread_objects()
} }
/* Wrapper around MYSQL_LOG::write() for slow log */ /** Wrapper around MYSQL_LOG::write() for slow log. */
bool Log_to_file_event_handler:: bool Log_to_file_event_handler::
log_slow(THD *thd, time_t current_time, time_t query_start_arg, log_slow(THD *thd, time_t current_time, time_t query_start_arg,
@ -704,7 +711,7 @@ bool Log_to_file_event_handler::
} }
/* /**
Wrapper around MYSQL_LOG::write() for general log. We need it since we Wrapper around MYSQL_LOG::write() for general log. We need it since we
want all log event handlers to have the same signature. want all log event handlers to have the same signature.
*/ */
@ -806,7 +813,7 @@ void LOGGER::cleanup_end()
} }
/* /**
Perform basic log initialization: create file-based log handler and Perform basic log initialization: create file-based log handler and
init error log. init error log.
*/ */
@ -1458,9 +1465,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
@ -1607,11 +1617,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)
{ {
@ -1825,7 +1838,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()
{ {
@ -2152,6 +2165,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)
@ -2266,17 +2284,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
*/ */
@ -2428,24 +2446,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
*/ */
@ -2486,25 +2500,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
*/ */
@ -2560,25 +2574,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
*/ */
@ -2612,21 +2628,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
*/ */
@ -2690,38 +2705,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
*/ */
@ -2799,8 +2816,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)
@ -2814,25 +2831,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
*/ */
@ -2916,21 +2932,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
*/ */
@ -2980,14 +2995,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
*/ */
@ -3001,8 +3014,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)
@ -3031,14 +3044,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
*/ */
@ -3509,8 +3520,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)
@ -3949,27 +3960,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)
@ -4066,17 +4075,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).
@ -4099,18 +4106,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
*/ */
@ -4190,21 +4195,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
*/ */
@ -4345,23 +4349,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)
@ -4615,16 +4614,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;
@ -4667,6 +4668,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()
{ {
/* /*
@ -4679,10 +4684,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.
@ -4693,18 +4697,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)
@ -4812,9 +4816,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)
@ -4925,16 +4929,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()
@ -4952,8 +4957,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!
@ -5044,7 +5050,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);
@ -5052,12 +5058,14 @@ void TC_LOG_BINLOG::close()
pthread_cond_destroy (&COND_prep_xids); pthread_cond_destroy (&COND_prep_xids);
} }
/* /**
TODO group commit @todo
group commit
RETURN @retval
0 - error 0 error
1 - success @retval
1 success
*/ */
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid) int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
{ {

View file

@ -215,8 +215,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)
@ -273,21 +273,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)
{ {
@ -307,14 +306,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;
@ -382,7 +379,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.
*/ */
@ -399,12 +396,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)
@ -431,7 +430,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.
*/ */
@ -456,8 +455,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()
@ -505,7 +505,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
@ -675,12 +675,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);
@ -701,8 +698,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)
@ -798,12 +797,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,
@ -886,14 +882,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
@ -991,8 +984,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.
*/ */
@ -1329,12 +1321,13 @@ Log_event::continue_group(Relay_log_info *rli)
#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)
@ -1363,7 +1356,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)
{ {
@ -1375,10 +1370,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!
@ -1555,9 +1550,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.
@ -1755,11 +1748,10 @@ code_name(int code)
} \ } \
} while (0) } while (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.
*/ */
Query_log_event::Query_log_event(const char* buf, uint event_len, Query_log_event::Query_log_event(const char* buf, uint event_len,
const Format_description_log_event const Format_description_log_event
*description_event, *description_event,
@ -1968,11 +1960,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)
{ {
@ -2157,6 +2151,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)
{ {
@ -2612,30 +2623,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:
/* /*
@ -2683,23 +2695,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::
@ -2807,18 +2816,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).
*/ */
@ -3253,14 +3264,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),
@ -3435,17 +3443,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)
@ -3463,32 +3472,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,
@ -3864,24 +3874,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");
@ -4233,12 +4240,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
*/ */
@ -4717,6 +4724,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)
@ -4812,7 +4823,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)
{ {
@ -4860,9 +4871,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
@ -4873,8 +4883,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)
{ {
/* /*
@ -5698,7 +5706,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)
@ -6755,15 +6765,17 @@ void Rows_log_event::print_helper(FILE *file,
type used is uint32. type used is uint32.
*/ */
#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
@ -6778,7 +6790,6 @@ void Rows_log_event::print_helper(FILE *file,
is less wasteful for space but does waste 1 byte for every field that does is less wasteful for space but does waste 1 byte for every field that does
not encode 2 parts. not encode 2 parts.
*/ */
#if !defined(MYSQL_CLIENT)
int Table_map_log_event::save_field_metadata() int Table_map_log_event::save_field_metadata()
{ {
DBUG_ENTER("Table_map_log_event::save_field_metadata"); DBUG_ENTER("Table_map_log_event::save_field_metadata");

View file

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

View file

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

View file

@ -13,7 +13,9 @@
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
It is interface module to fixed precision decimals library. It is interface module to fixed precision decimals library.
Most functions use 'uint mask' as parameter, if during operation error Most functions use 'uint mask' as parameter, if during operation error
@ -34,14 +36,14 @@ C_MODE_END
#define DECIMAL_LONG_DIGITS 10 #define DECIMAL_LONG_DIGITS 10
#define DECIMAL_LONG3_DIGITS 8 #define DECIMAL_LONG3_DIGITS 8
/* maximum length of buffer in our big digits (uint32) */ /** maximum length of buffer in our big digits (uint32). */
#define DECIMAL_BUFF_LENGTH 9 #define DECIMAL_BUFF_LENGTH 9
/* the number of digits that my_decimal can possibly contain */ /* the number of digits that my_decimal can possibly contain */
#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9) #define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
/* /**
maximum guaranteed precision of number in decimal digits (number of our maximum guaranteed precision of number in decimal digits (number of our
digits * number of decimal digits in one our big digit - number of decimal digits * number of decimal digits in one our big digit - number of decimal
digits in one our big digit decreased by 1 (because we always put decimal digits in one our big digit decreased by 1 (because we always put decimal
@ -51,13 +53,14 @@ C_MODE_END
#define DECIMAL_MAX_SCALE 30 #define DECIMAL_MAX_SCALE 30
#define DECIMAL_NOT_SPECIFIED 31 #define DECIMAL_NOT_SPECIFIED 31
/* /**
maximum length of string representation (number of maximum decimal maximum length of string representation (number of maximum decimal
digits + 1 position for sign + 1 position for decimal point) digits + 1 position for sign + 1 position for decimal point)
*/ */
#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2) #define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
/*
maximum size of packet length /**
maximum size of packet length.
*/ */
#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION #define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
@ -78,11 +81,12 @@ inline int my_decimal_int_part(uint precision, uint decimals)
} }
/* /**
my_decimal class limits 'decimal_t' type to what we need in MySQL my_decimal class limits 'decimal_t' type to what we need in MySQL.
It contains internally all necessary space needed by the instance so It contains internally all necessary space needed by the instance so
no extra memory is needed. One should call fix_buffer_pointer() function no extra memory is needed. One should call fix_buffer_pointer() function
when he moves my_decimal objects in memory when he moves my_decimal objects in memory.
*/ */
class my_decimal :public decimal_t class my_decimal :public decimal_t
@ -384,7 +388,10 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
} }
/* Returns -1 if a<b, 1 if a>b and 0 if a==b */ /**
@return
-1 if a<b, 1 if a>b and 0 if a==b
*/
inline inline
int my_decimal_cmp(const my_decimal *a, const my_decimal *b) int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
{ {

View file

@ -13,10 +13,13 @@
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
Mostly this file is used in the server. But a little part of it is used in Mostly this file is used in the server. But a little part of it is used in
mysqlbinlog too (definition of SELECT_DISTINCT and others). mysqlbinlog too (definition of SELECT_DISTINCT and others).
The consequence is that 90% of the file is wrapped in #ifndef MYSQL_CLIENT, The consequence is that 90% of the file is wrapped in \#ifndef MYSQL_CLIENT,
except the part which must be in the server and in the client. except the part which must be in the server and in the client.
*/ */
@ -253,12 +256,12 @@ protected:
Feel free to raise this by the smallest amount you can to get the Feel free to raise this by the smallest amount you can to get the
"execution_constants" test to pass. "execution_constants" test to pass.
*/ */
#define STACK_MIN_SIZE 12000 // Abort if less stack during eval. #define STACK_MIN_SIZE 12000 ///< Abort if less stack during eval.
#define STACK_MIN_SIZE_FOR_OPEN 1024*80 #define STACK_MIN_SIZE_FOR_OPEN 1024*80
#define STACK_BUFF_ALLOC 352 // For stack overrun checks #define STACK_BUFF_ALLOC 352 ///< For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT #ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int. #define MYSQLD_NET_RETRY_COUNT 10 ///< Abort read after this many int.
#endif #endif
#define TEMP_POOL_SIZE 128 #define TEMP_POOL_SIZE 128
@ -282,14 +285,14 @@ protected:
#define MIN_ROWS_TO_USE_TABLE_CACHE 100 #define MIN_ROWS_TO_USE_TABLE_CACHE 100
#define MIN_ROWS_TO_USE_BULK_INSERT 100 #define MIN_ROWS_TO_USE_BULK_INSERT 100
/* /**
The following is used to decide if MySQL should use table scanning The following is used to decide if MySQL should use table scanning
instead of reading with keys. The number says how many evaluation of the instead of reading with keys. The number says how many evaluation of the
WHERE clause is comparable to reading one extra row from a table. WHERE clause is comparable to reading one extra row from a table.
*/ */
#define TIME_FOR_COMPARE 5 // 5 compares == one read #define TIME_FOR_COMPARE 5 // 5 compares == one read
/* /**
Number of comparisons of table rowids equivalent to reading one row from a Number of comparisons of table rowids equivalent to reading one row from a
table. table.
*/ */
@ -309,17 +312,17 @@ protected:
#define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK) #define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK)
/* /**
Number of rows in a reference table when refereed through a not unique key. Number of rows in a reference table when refereed through a not unique key.
This value is only used when we don't know anything about the key This value is only used when we don't know anything about the key
distribution. distribution.
*/ */
#define MATCHING_ROWS_IN_OTHER_TABLE 10 #define MATCHING_ROWS_IN_OTHER_TABLE 10
/* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */ /** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */
#define KEY_DEFAULT_PACK_LENGTH 8 #define KEY_DEFAULT_PACK_LENGTH 8
/* Characters shown for the command in 'show processlist' */ /** Characters shown for the command in 'show processlist'. */
#define PROCESS_LIST_WIDTH 100 #define PROCESS_LIST_WIDTH 100
/* Characters shown for the command in 'information_schema.processlist' */ /* Characters shown for the command in 'information_schema.processlist' */
#define PROCESS_LIST_INFO_WIDTH 65535 #define PROCESS_LIST_INFO_WIDTH 65535
@ -335,11 +338,11 @@ protected:
/* The following can also be changed from the command line */ /* The following can also be changed from the command line */
#define DEFAULT_CONCURRENCY 10 #define DEFAULT_CONCURRENCY 10
#define DELAYED_LIMIT 100 /* pause after xxx inserts */ #define DELAYED_LIMIT 100 /**< pause after xxx inserts */
#define DELAYED_QUEUE_SIZE 1000 #define DELAYED_QUEUE_SIZE 1000
#define DELAYED_WAIT_TIMEOUT 5*60 /* Wait for delayed insert */ #define DELAYED_WAIT_TIMEOUT 5*60 /**< Wait for delayed insert */
#define FLUSH_TIME 0 /* Don't flush tables */ #define FLUSH_TIME 0 /**< Don't flush tables */
#define MAX_CONNECT_ERRORS 10 // errors before disabling host #define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
#ifdef __NETWARE__ #ifdef __NETWARE__
#define IF_NETWARE(A,B) A #define IF_NETWARE(A,B) A
@ -349,7 +352,7 @@ protected:
#if defined(__WIN__) #if defined(__WIN__)
#undef FLUSH_TIME #undef FLUSH_TIME
#define FLUSH_TIME 1800 /* Flush every half hour */ #define FLUSH_TIME 1800 /**< Flush every half hour */
#define INTERRUPT_PRIOR -2 #define INTERRUPT_PRIOR -2
#define CONNECT_PRIOR -1 #define CONNECT_PRIOR -1
@ -368,12 +371,12 @@ protected:
#define TEST_MIT_THREAD 4 #define TEST_MIT_THREAD 4
#define TEST_BLOCKING 8 #define TEST_BLOCKING 8
#define TEST_KEEP_TMP_TABLES 16 #define TEST_KEEP_TMP_TABLES 16
#define TEST_READCHECK 64 /* Force use of readcheck */ #define TEST_READCHECK 64 /**< Force use of readcheck */
#define TEST_NO_EXTRA 128 #define TEST_NO_EXTRA 128
#define TEST_CORE_ON_SIGNAL 256 /* Give core if signal */ #define TEST_CORE_ON_SIGNAL 256 /**< Give core if signal */
#define TEST_NO_STACKTRACE 512 #define TEST_NO_STACKTRACE 512
#define TEST_SIGINT 1024 /* Allow sigint on threads */ #define TEST_SIGINT 1024 /**< Allow sigint on threads */
#define TEST_SYNCHRONIZATION 2048 /* get server to do sleep in #define TEST_SYNCHRONIZATION 2048 /**< get server to do sleep in
some places */ some places */
#endif #endif
@ -423,26 +426,26 @@ protected:
/* The following is used to detect a conflict with DISTINCT */ /* The following is used to detect a conflict with DISTINCT */
#define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser #define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser
/* The following can be set when importing tables in a 'wrong order' /** The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */ to suppress foreign key checks */
#define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog #define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog
/* The following speeds up inserts to InnoDB tables by suppressing unique /** The following speeds up inserts to InnoDB tables by suppressing unique
key checks in some cases */ key checks in some cases */
#define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog #define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog
#define SELECT_NO_UNLOCK (ULL(1) << 28) // SELECT, intern #define SELECT_NO_UNLOCK (ULL(1) << 28) // SELECT, intern
#define OPTION_SCHEMA_TABLE (ULL(1) << 29) // SELECT, intern #define OPTION_SCHEMA_TABLE (ULL(1) << 29) // SELECT, intern
/* Flag set if setup_tables already done */ /** Flag set if setup_tables already done */
#define OPTION_SETUP_TABLES_DONE (ULL(1) << 30) // intern #define OPTION_SETUP_TABLES_DONE (ULL(1) << 30) // intern
/* If not set then the thread will ignore all warnings with level notes. */ /** If not set then the thread will ignore all warnings with level notes. */
#define OPTION_SQL_NOTES (ULL(1) << 31) // THD, user #define OPTION_SQL_NOTES (ULL(1) << 31) // THD, user
/* /**
Force the used temporary table to be a MyISAM table (because we will use Force the used temporary table to be a MyISAM table (because we will use
fulltext functions when reading from it. fulltext functions when reading from it.
*/ */
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32) #define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
/* /**
Maximum length of time zone name that we support Maximum length of time zone name that we support
(Time zone name is char(64) in db). mysqlbinlog needs it. (Time zone name is char(64) in db). mysqlbinlog needs it.
*/ */
@ -505,9 +508,9 @@ protected:
#define UNCACHEABLE_DEPENDENT 1 #define UNCACHEABLE_DEPENDENT 1
#define UNCACHEABLE_RAND 2 #define UNCACHEABLE_RAND 2
#define UNCACHEABLE_SIDEEFFECT 4 #define UNCACHEABLE_SIDEEFFECT 4
// forcing to save JOIN for explain /// forcing to save JOIN for explain
#define UNCACHEABLE_EXPLAIN 8 #define UNCACHEABLE_EXPLAIN 8
/* Don't evaluate subqueries in prepare even if they're not correlated */ /** Don't evaluate subqueries in prepare even if they're not correlated */
#define UNCACHEABLE_PREPARE 16 #define UNCACHEABLE_PREPARE 16
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */ /* For uncorrelated SELECT in an UNION with some correlated SELECTs */
#define UNCACHEABLE_UNITED 32 #define UNCACHEABLE_UNITED 32
@ -515,7 +518,7 @@ protected:
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1) #define UNDEF_POS (-1)
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
/* /**
Sync points allow us to force the server to reach a certain line of code Sync points allow us to force the server to reach a certain line of code
and block there until the client tells the server it is ok to go on. and block there until the client tells the server it is ok to go on.
The client tells the server to block with SELECT GET_LOCK() The client tells the server to block with SELECT GET_LOCK()
@ -551,7 +554,7 @@ void view_store_options(THD *thd, TABLE_LIST *table, String *buff);
#define portable_sizeof_char_ptr 8 #define portable_sizeof_char_ptr 8
#define tmp_file_prefix "#sql" /* Prefix for tmp tables */ #define tmp_file_prefix "#sql" /**< Prefix for tmp tables */
#define tmp_file_prefix_length 4 #define tmp_file_prefix_length 4
/* Flags for calc_week() function. */ /* Flags for calc_week() function. */
@ -586,9 +589,9 @@ enum enum_check_fields
CHECK_FIELD_WARN, CHECK_FIELD_WARN,
CHECK_FIELD_ERROR_FOR_NULL CHECK_FIELD_ERROR_FOR_NULL
}; };
/* Struct to handle simple linked lists */
/** Struct to handle simple linked lists. */
typedef struct st_sql_list { typedef struct st_sql_list {
uint elements; uint elements;
uchar *first; uchar *first;
@ -2209,16 +2212,15 @@ Item * all_any_subquery_creator(Item *left_expr,
bool all, bool all,
SELECT_LEX *select_lex); SELECT_LEX *select_lex);
/* /**
clean/setup table fields and map clean/setup table fields and map.
SYNOPSYS @param table TABLE structure pointer (which should be setup)
setup_table_map() @param table_list TABLE_LIST structure pointer (owner of TABLE)
table - TABLE structure pointer (which should be setup) @param tablenr table number
table_list TABLE_LIST structure pointer (owner of TABLE)
tablenr - table number
*/ */
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr) inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
{ {
table->used_fields= 0; table->used_fields= 0;
@ -2240,10 +2242,8 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
} }
/* /**
SYNOPSYS convert a hex digit into number.
hexchar_to_int()
convert a hex digit into number
*/ */
inline int hexchar_to_int(char c) inline int hexchar_to_int(char c)
@ -2256,11 +2256,9 @@ inline int hexchar_to_int(char c)
return -1; return -1;
} }
/* /**
is_user_table() return true if the table was created explicitly.
return true if the table was created explicitly
*/ */
inline bool is_user_table(TABLE * table) inline bool is_user_table(TABLE * table)
{ {
const char *name= table->s->table_name.str; const char *name= table->s->table_name.str;

View file

@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
typedef fp_except fp_except_t; typedef fp_except fp_except_t;
#endif #endif
/* We can't handle floating point exceptions with threads, so disable /**
this on freebsd We can't handle floating point exceptions with threads, so disable
*/ this on freebsd.
*/
inline void reset_floating_point_exceptions() inline void reset_floating_point_exceptions()
{ {
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */ /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
@ -325,7 +325,7 @@ static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread; static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created; static ulong killed_threads, thread_created;
static ulong max_used_connections; static ulong max_used_connections;
static ulong my_bind_addr; /* the address we bind to */ static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0; static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF"; static const char *sql_mode_str= "OFF";
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr; static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
*/ */
bool volatile grant_option; bool volatile grant_option;
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
my_bool opt_reckless_slave = 0; my_bool opt_reckless_slave = 0;
my_bool opt_enable_named_pipe= 0; my_bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_slave_compressed_protocol; my_bool opt_local_infile, opt_slave_compressed_protocol;
@ -430,7 +430,7 @@ TYPELIB binlog_format_typelib=
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC; ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id]; const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_INITGROUPS #ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */ static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
#endif #endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_port_timeout; uint mysqld_port_timeout;
@ -458,12 +458,12 @@ ulong specialflag=0;
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections, max_connect_errors; ulong max_connections, max_connect_errors;
uint max_user_connections= 0; uint max_user_connections= 0;
/* /**
Limit of the total number of prepared statements in the server. Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks. Is necessary to protect the server against out-of-memory attacks.
*/ */
ulong max_prepared_stmt_count; ulong max_prepared_stmt_count;
/* /**
Current total number of prepared statements in the server. This number Current total number of prepared statements in the server. This number
is exact, and therefore may not be equal to the difference between is exact, and therefore may not be equal to the difference between
`com_stmt_prepare' and `com_stmt_close' (global status variables), as `com_stmt_prepare' and `com_stmt_close' (global status variables), as
@ -499,13 +499,13 @@ uint mysql_data_home_len;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH]; char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir; char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /* Error messages */ const char **errmesg; /**< Error messages */
const char *myisam_recover_options_str="OFF"; const char *myisam_recover_options_str="OFF";
const char *myisam_stats_method_str="nulls_unequal"; const char *myisam_stats_method_str="nulls_unequal";
/* name of reference on left espression in rewritten IN subquery */ /** name of reference on left espression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>"; const char *in_left_expr_name= "<left expr>";
/* name of additional condition */ /** name of additional condition */
const char *in_additional_cond= "<IN COND>"; const char *in_additional_cond= "<IN COND>";
const char *in_having_cond= "<IN HAVING>"; const char *in_having_cond= "<IN HAVING>";
@ -555,7 +555,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables, LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
/* /**
The below lock protects access to two global server variables: The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables max_prepared_stmt_count and prepared_stmt_count. These variables
set the limit and hold the current total number of prepared statements set the limit and hold the current total number of prepared statements
@ -604,7 +604,7 @@ static char **defaults_argv;
static char *opt_bin_logname; static char *opt_bin_logname;
static my_socket unix_sock,ip_sock; static my_socket unix_sock,ip_sock;
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD() struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
struct passwd *user_info; struct passwd *user_info;
@ -628,7 +628,7 @@ static char **opt_argv;
static HANDLE hEventShutdown; static HANDLE hEventShutdown;
static char shutdown_event_name[40]; static char shutdown_event_name[40];
#include "nt_servc.h" #include "nt_servc.h"
static NTService Service; // Service object for WinNT static NTService Service; ///< Service object for WinNT
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */ #endif /* __WIN__ */
@ -1009,19 +1009,15 @@ void kill_mysql(void)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
Force server down. Kill all connections and threads and exit Force server down. Kill all connections and threads and exit.
SYNOPSIS @param sig_ptr Signal number that caused kill_server to be called.
kill_server
sig_ptr Signal number that caused kill_server to be called. @note
NOTE!
A signal number of 0 mean that the function was not called A signal number of 0 mean that the function was not called
from a signal handler and there is thus no signal to block from a signal handler and there is thus no signal to block
or stop, we just want to kill the server. or stop, we just want to kill the server.
*/ */
#if defined(__NETWARE__) #if defined(__NETWARE__)
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
#endif #endif
} }
/* #ifndef EMBEDDED_LIBRARY
cleanup all memory and end program nicely
SYNOPSIS /**
unireg_end() cleanup all memory and end program nicely.
NOTES
This function never returns.
If SIGNALS_DONT_BREAK_READ is defined, this function is called If SIGNALS_DONT_BREAK_READ is defined, this function is called
by the main thread. To get MySQL to shut down nicely in this case by the main thread. To get MySQL to shut down nicely in this case
(Mac OS X) we have to call exit() instead if pthread_exit(). (Mac OS X) we have to call exit() instead if pthread_exit().
*/
#ifndef EMBEDDED_LIBRARY @note
This function never returns.
*/
void unireg_end(void) void unireg_end(void)
{ {
clean_up(1); clean_up(1);
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* /**
This is mainly needed when running with purify, but it's still nice to This is mainly needed when running with purify, but it's still nice to
know that all child threads have died when mysqld exits know that all child threads have died when mysqld exits.
*/ */
static void wait_for_signal_thread_to_end() static void wait_for_signal_thread_to_end()
{ {
#ifndef __NETWARE__ #ifndef __NETWARE__
@ -1506,8 +1498,7 @@ static void set_effective_user(struct passwd *user_info_arg)
} }
/* Change root user if started with --chroot */ /** Change root user if started with @c --chroot . */
static void set_root(const char *path) static void set_root(const char *path)
{ {
#if !defined(__WIN__) && !defined(__NETWARE__) #if !defined(__WIN__) && !defined(__NETWARE__)
@ -1696,19 +1687,16 @@ static void network_init(void)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* /**
Close a connection Close a connection.
SYNOPSIS @param thd Thread handle
close_connection() @param errcode Error code to print to console
thd Thread handle @param lock 1 if we have have to lock LOCK_thread_count
errcode Error code to print to console
lock 1 if we have have to lock LOCK_thread_count
NOTES @note
For the connection that is doing shutdown, this is called twice For the connection that is doing shutdown, this is called twice
*/ */
void close_connection(THD *thd, uint errcode, bool lock) void close_connection(THD *thd, uint errcode, bool lock)
{ {
st_vio *vio; st_vio *vio;
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* Called when a thread is aborted */ /** Called when a thread is aborted. */
/* ARGSUSED */ /* ARGSUSED */
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
{ {
THD *thd=current_thd; THD *thd=current_thd;
@ -1877,13 +1864,13 @@ void flush_thread_cache()
} }
/*
Aborts a thread nicely. Commes here on SIGPIPE
TODO: One should have to fix that thr_alarm know about this
thread too.
*/
#ifdef THREAD_SPECIFIC_SIGPIPE #ifdef THREAD_SPECIFIC_SIGPIPE
/**
Aborts a thread nicely. Comes here on SIGPIPE.
@todo
One should have to fix that thr_alarm know about this thread too.
*/
extern "C" sig_handler abort_thread(int sig __attribute__((unused))) extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
{ {
THD *thd=current_thd; THD *thd=current_thd;
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
#elif defined(__NETWARE__) #elif defined(__NETWARE__)
// down server event callback /// down server event callback.
void mysql_down_server_cb(void *, void *) void mysql_down_server_cb(void *, void *)
{ {
event_flag= TRUE; event_flag= TRUE;
@ -1939,7 +1926,7 @@ void mysql_down_server_cb(void *, void *)
} }
// destroy callback resources /// destroy callback resources.
void mysql_cb_destroy(void *) void mysql_cb_destroy(void *)
{ {
UnRegisterEventNotification(eh); // cleanup down event notification UnRegisterEventNotification(eh); // cleanup down event notification
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
} }
// initialize callbacks /// initialize callbacks.
void mysql_cb_init() void mysql_cb_init()
{ {
// register for down server event // register for down server event
@ -1974,8 +1961,7 @@ void mysql_cb_init()
} }
/* To get the name of the NetWare volume having MySQL data folder */ /** To get the name of the NetWare volume having MySQL data folder. */
static void getvolumename() static void getvolumename()
{ {
char *p; char *p;
@ -1989,8 +1975,8 @@ static void getvolumename()
} }
/* /**
Registering with NEB for NSS Volume Deactivation event Registering with NEB for NSS Volume Deactivation event.
*/ */
static void registerwithneb() static void registerwithneb()
@ -2042,8 +2028,8 @@ static void registerwithneb()
} }
/* /**
Callback for NSS Volume Deactivation event Callback for NSS Volume Deactivation event.
*/ */
ulong neb_event_callback(struct EventBlock *eblock) ulong neb_event_callback(struct EventBlock *eblock)
@ -2075,12 +2061,11 @@ ulong neb_event_callback(struct EventBlock *eblock)
} }
/*
Function to get NSS volume ID of the MySQL data
*/
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/" #define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
/**
Function to get NSS volume ID of the MySQL data.
*/
static void getvolumeID(BYTE *volumeName) static void getvolumeID(BYTE *volumeName)
{ {
char path[zMAX_FULL_NAME]; char path[zMAX_FULL_NAME];
@ -2155,10 +2140,10 @@ static void start_signal_handler(void)
} }
/* /**
Warn if the data is on a Traditional volume Warn if the data is on a Traditional volume.
NOTE @note
Already done by mysqld_safe Already done by mysqld_safe
*/ */
@ -2419,8 +2404,7 @@ static void start_signal_handler(void)
} }
/* This threads handles all signals and alarms */ /** This threads handles all signals and alarms. */
/* ARGSUSED */ /* ARGSUSED */
pthread_handler_t signal_hand(void *arg __attribute__((unused))) pthread_handler_t signal_hand(void *arg __attribute__((unused)))
{ {
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
#endif /* __WIN__*/ #endif /* __WIN__*/
/* /**
All global error messages are sent here where the first one is stored All global error messages are sent here where the first one is stored
for the client for the client.
*/ */
/* ARGSUSED */ /* ARGSUSED */
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags); extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
@ -2694,20 +2676,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
*/ */
@ -4050,21 +4031,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,
@ -4213,7 +4193,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.
*/ */
@ -4342,23 +4322,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)
@ -4712,15 +4686,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 */
@ -7052,13 +7024,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
@ -7785,7 +7757,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);
@ -7836,6 +7808,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;
@ -7967,10 +7943,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
@ -8075,9 +8052,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)
@ -8136,16 +8115,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
*/ */
@ -8176,10 +8155,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;
@ -8201,7 +8181,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);

View file

@ -13,8 +13,11 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
Set MYSQL_SERVER_SUFFIX_STR @file
Set MYSQL_SERVER_SUFFIX_STR.
The following code is quite ugly as there is no portable way to easily set a The following code is quite ugly as there is no portable way to easily set a
string to the value of a macro string to the value of a macro
*/ */

View file

@ -13,15 +13,16 @@
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
This file is the net layer API for the MySQL client/server protocol, This file is the net layer API for the MySQL client/server protocol,
which is a tightly coupled, proprietary protocol owned by MySQL AB. which is a tightly coupled, proprietary protocol owned by MySQL AB.
@note
Any re-implementations of this protocol must also be under GPL Any re-implementations of this protocol must also be under GPL
unless one has got an license from MySQL AB stating otherwise. unless one has got an license from MySQL AB stating otherwise.
*/
/* Write and read of logical packets to/from socket.
Write and read of logical packets to/from socket
Writes are cached into net_buffer_length big packets. Writes are cached into net_buffer_length big packets.
Read packets are reallocated dynamicly when reading big packets. Read packets are reallocated dynamicly when reading big packets.
@ -111,7 +112,7 @@ extern void query_cache_insert(NET *net, const char *packet, ulong length);
static my_bool net_write_buff(NET *net,const uchar *packet,ulong len); static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
/* Init with packet info */ /** Init with packet info. */
my_bool my_net_init(NET *net, Vio* vio) my_bool my_net_init(NET *net, Vio* vio)
{ {
@ -163,7 +164,7 @@ void net_end(NET *net)
} }
/* Realloc the packet buffer */ /** Realloc the packet buffer. */
my_bool net_realloc(NET *net, size_t length) my_bool net_realloc(NET *net, size_t length)
{ {
@ -201,20 +202,17 @@ my_bool net_realloc(NET *net, size_t length)
} }
/* /**
Check if there is any data to be read from the socket Check if there is any data to be read from the socket.
SYNOPSIS @param sd socket descriptor
net_data_is_ready()
sd socket descriptor
DESCRIPTION @retval
Check if there is any data to be read from the socket. 0 No data to read
@retval
RETURN VALUES 1 Data or EOF to read
0 No data to read @retval
1 Data or EOF to read -1 Don't know if data is ready or not
-1 Don't know if data is ready or not
*/ */
#if !defined(EMBEDDED_LIBRARY) #if !defined(EMBEDDED_LIBRARY)
@ -258,16 +256,10 @@ static int net_data_is_ready(my_socket sd)
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* /**
Remove unwanted characters from connection Remove unwanted characters from connection
and check if disconnected and check if disconnected.
SYNOPSIS
net_clear()
net NET handler
clear_buffer If <> 0, then clear all data from communication buffer
DESCRIPTION
Read from socket until there is nothing more to read. Discard Read from socket until there is nothing more to read. Discard
what is read. what is read.
@ -278,6 +270,8 @@ static int net_data_is_ready(my_socket sd)
a FIN packet), then select() considers a socket "ready to read", a FIN packet), then select() considers a socket "ready to read",
in the sense that there's EOF to read, but read() returns 0. in the sense that there's EOF to read, but read() returns 0.
@param net NET handler
@param clear_buffer if <> 0, then clear all data from comm buff
*/ */
void net_clear(NET *net, my_bool clear_buffer) void net_clear(NET *net, my_bool clear_buffer)
@ -335,7 +329,7 @@ void net_clear(NET *net, my_bool clear_buffer)
} }
/* Flush write_buffer if not empty. */ /** Flush write_buffer if not empty. */
my_bool net_flush(NET *net) my_bool net_flush(NET *net)
{ {
@ -358,12 +352,13 @@ my_bool net_flush(NET *net)
** Write something to server/client buffer ** Write something to server/client buffer
*****************************************************************************/ *****************************************************************************/
/* /**
Write a logical packet with packet header Write a logical packet with packet header.
Format: Packet length (3 bytes), packet number(1 byte) Format: Packet length (3 bytes), packet number(1 byte)
When compression is used a 3 byte compression length is added When compression is used a 3 byte compression length is added
NOTE @note
If compression is used the original package is modified! If compression is used the original package is modified!
*/ */
@ -400,19 +395,9 @@ my_net_write(NET *net,const uchar *packet,size_t len)
return test(net_write_buff(net,packet,len)); return test(net_write_buff(net,packet,len));
} }
/* /**
Send a command to the server. Send a command to the server.
SYNOPSIS
net_write_command()
net NET handler
command Command in MySQL server (enum enum_server_command)
header Header to write after command
head_len Length of header
packet Query or parameter to query
len Length of packet
DESCRIPTION
The reason for having both header and packet is so that libmysql The reason for having both header and packet is so that libmysql
can easy add a header to a special command (like prepared statements) can easy add a header to a special command (like prepared statements)
without having to re-alloc the string. without having to re-alloc the string.
@ -420,11 +405,20 @@ my_net_write(NET *net,const uchar *packet,size_t len)
As the command is part of the first data packet, we have to do some data As the command is part of the first data packet, we have to do some data
juggling to put the command in there, without having to create a new juggling to put the command in there, without having to create a new
packet. packet.
This function will split big packets into sub-packets if needed. This function will split big packets into sub-packets if needed.
(Each sub packet can only be 2^24 bytes) (Each sub packet can only be 2^24 bytes)
RETURN VALUES @param net NET handler
@param command Command in MySQL server (enum enum_server_command)
@param header Header to write after command
@param head_len Length of header
@param packet Query or parameter to query
@param len Length of packet
@retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -468,33 +462,30 @@ net_write_command(NET *net,uchar command,
net_write_buff(net, packet, len) || net_flush(net))); net_write_buff(net, packet, len) || net_flush(net)));
} }
/* /**
Caching the data in a local buffer before sending it. Caching the data in a local buffer before sending it.
SYNOPSIS Fill up net->buffer and send it to the client when full.
net_write_buff()
net Network handler
packet Packet to send
len Length of packet
DESCRIPTION
Fill up net->buffer and send it to the client when full.
If the rest of the to-be-sent-packet is bigger than buffer, If the rest of the to-be-sent-packet is bigger than buffer,
send it in one big block (to avoid copying to internal buffer). send it in one big block (to avoid copying to internal buffer).
If not, copy the rest of the data to the buffer and return without If not, copy the rest of the data to the buffer and return without
sending data. sending data.
NOTES @param net Network handler
The cached buffer can be sent as it is with 'net_flush()'. @param packet Packet to send
@param len Length of packet
@note
The cached buffer can be sent as it is with 'net_flush()'.
In this code we have to be careful to not send a packet longer than In this code we have to be careful to not send a packet longer than
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
protocol as we store the length of the compressed packet in 3 bytes. protocol as we store the length of the compressed packet in 3 bytes.
RETURN @retval
0 ok 0 ok
1 @retval
1
*/ */
static my_bool static my_bool
@ -547,9 +538,12 @@ net_write_buff(NET *net, const uchar *packet, ulong len)
} }
/* /**
Read and write one packet using timeouts. Read and write one packet using timeouts.
If needed, the packet is compressed before sending. If needed, the packet is compressed before sending.
@todo
- TODO is it needed to set this variable if we have no socket
*/ */
int int
@ -726,18 +720,17 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
return 0; return 0;
} }
/* /**
Help function to clear the commuication buffer when we get a too big packet. Help function to clear the commuication buffer when we get a too big packet.
SYNOPSIS @param net Communication handle
my_net_skip_rest() @param remain Bytes to read
net Communication handle @param alarmed Parameter for thr_alarm()
remain Bytes to read @param alarm_buff Parameter for thr_alarm()
alarmed Parameter for thr_alarm()
alarm_buff Parameter for thr_alarm()
RETURN VALUES @retval
0 Was able to read the whole packet 0 Was able to read the whole packet
@retval
1 Got mailformed packet from client 1 Got mailformed packet from client
*/ */
@ -780,10 +773,13 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
#endif /* NO_ALARM */ #endif /* NO_ALARM */
/* /**
Reads one packet to net->buff + net->where_b Reads one packet to net->buff + net->where_b.
Returns length of packet. Long packets are handled by my_net_read(). Long packets are handled by my_net_read().
This function reallocates the net->buff buffer if necessary. This function reallocates the net->buff buffer if necessary.
@return
Returns length of packet.
*/ */
static ulong static ulong
@ -972,15 +968,18 @@ end:
} }
/* /**
Read a packet from the client/server and return it without the internal Read a packet from the client/server and return it without the internal
package header. package header.
If the packet is the first packet of a multi-packet packet If the packet is the first packet of a multi-packet packet
(which is indicated by the length of the packet = 0xffffff) then (which is indicated by the length of the packet = 0xffffff) then
all sub packets are read and concatenated. all sub packets are read and concatenated.
If the packet was compressed, its uncompressed and the length of the If the packet was compressed, its uncompressed and the length of the
uncompressed packet is returned. uncompressed packet is returned.
@return
The function returns the length of the found packet or packet_error. The function returns the length of the found packet or packet_error.
net->read_pos points to the read data. net->read_pos points to the read data.
*/ */

View file

@ -1,8 +1,12 @@
/* ------------------------------------------------------------------------ /**
Windows NT Service class library @file
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
This file is public domain and comes with NO WARRANTY of any kind @brief
-------------------------------------------------------------------------- */ Windows NT Service class library.
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
This file is public domain and comes with NO WARRANTY of any kind
*/
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>
#include <stdio.h> #include <stdio.h>
@ -73,12 +77,13 @@ BOOL NTService::GetOS()
} }
/* ------------------------------------------------------------------------ /**
Init() Registers the main service thread with the service manager Registers the main service thread with the service manager.
@param ServiceThread pointer to the main programs entry function
when the service is started
*/
ServiceThread - pointer to the main programs entry function
when the service is started
-------------------------------------------------------------------------- */
long NTService::Init(LPCSTR szInternName,void *ServiceThread) long NTService::Init(LPCSTR szInternName,void *ServiceThread)
{ {
@ -99,13 +104,15 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
} }
/* ------------------------------------------------------------------------ /**
Install() - Installs the service with Service manager Installs the service with Service manager.
nError values: nError values:
0 success - 0 success
1 Can't open the Service manager - 1 Can't open the Service manager
2 Failed to create service - 2 Failed to create service.
-------------------------------------------------------------------------- */ */
BOOL NTService::Install(int startType, LPCSTR szInternName, BOOL NTService::Install(int startType, LPCSTR szInternName,
LPCSTR szDisplayName, LPCSTR szDisplayName,
@ -155,14 +162,16 @@ BOOL NTService::Install(int startType, LPCSTR szInternName,
} }
/* ------------------------------------------------------------------------ /**
Remove() - Removes the service Removes the service.
nError values: nError values:
0 success - 0 success
1 Can't open the Service manager - 1 Can't open the Service manager
2 Failed to locate service - 2 Failed to locate service
3 Failed to delete service - 3 Failed to delete service.
-------------------------------------------------------------------------- */ */
BOOL NTService::Remove(LPCSTR szInternName) BOOL NTService::Remove(LPCSTR szInternName)
{ {
@ -199,10 +208,10 @@ BOOL NTService::Remove(LPCSTR szInternName)
return ret_value; return ret_value;
} }
/* ------------------------------------------------------------------------ /**
Stop() - this function should be called before the app. exits to stop this function should be called before the app. exits to stop
the service the service
-------------------------------------------------------------------------- */ */
void NTService::Stop(void) void NTService::Stop(void)
{ {
SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 60000); SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 60000);
@ -210,10 +219,11 @@ void NTService::Stop(void)
SetStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 1000); SetStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 1000);
} }
/* ------------------------------------------------------------------------ /**
ServiceMain() - This is the function that is called from the This is the function that is called from the
service manager to start the service service manager to start the service.
-------------------------------------------------------------------------- */ */
void NTService::ServiceMain(DWORD argc, LPTSTR *argv) void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
{ {
@ -264,9 +274,9 @@ error:
return; return;
} }
/* ------------------------------------------------------------------------ /**
StartService() - starts the appliaction thread starts the appliaction thread.
-------------------------------------------------------------------------- */ */
BOOL NTService::StartService() BOOL NTService::StartService()
{ {

View file

@ -1,8 +1,12 @@
/* ------------------------------------------------------------------------ /**
Windows NT Service class library @file
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
This file is public domain and comes with NO WARRANTY of any kind @brief
-------------------------------------------------------------------------- */ Windows NT Service class library
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
This file is public domain and comes with NO WARRANTY of any kind
*/
// main application thread // main application thread
typedef void (*THREAD_FC)(void *); typedef void (*THREAD_FC)(void *);
@ -13,7 +17,7 @@ class NTService
NTService(); NTService();
~NTService(); ~NTService();
BOOL bOsNT; // true if OS is NT, false for Win95 BOOL bOsNT; ///< true if OS is NT, false for Win95
//install optinos //install optinos
DWORD dwDesiredAccess; DWORD dwDesiredAccess;
DWORD dwServiceType; DWORD dwServiceType;

View file

@ -14,7 +14,9 @@
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
Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
by replacing the aggregate expression with a constant. by replacing the aggregate expression with a constant.
@ -22,6 +24,7 @@
types of queries are optimised (assuming the table handler supports types of queries are optimised (assuming the table handler supports
the required methods) the required methods)
@verbatim
SELECT COUNT(*) FROM t1[,t2,t3,...] SELECT COUNT(*) FROM t1[,t2,t3,...]
SELECT MIN(b) FROM t1 WHERE a=const SELECT MIN(b) FROM t1 WHERE a=const
SELECT MAX(c) FROM t1 WHERE a=const AND b=const SELECT MAX(c) FROM t1 WHERE a=const AND b=const
@ -29,6 +32,7 @@
SELECT MIN(b) FROM t1 WHERE a=const AND b>const SELECT MIN(b) FROM t1 WHERE a=const AND b>const
SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
@endverbatim
Instead of '<' one can use '<=', '>', '>=' and '=' as well. Instead of '<' one can use '<=', '>', '>=' and '=' as well.
Instead of 'a=const' the condition 'a IS NULL' can be used. Instead of 'a=const' the condition 'a IS NULL' can be used.
@ -36,10 +40,11 @@
If all selected fields are replaced then we will also remove all If all selected fields are replaced then we will also remove all
involved tables and return the answer without any join. Thus, the involved tables and return the answer without any join. Thus, the
following query will be replaced with a row of two constants: following query will be replaced with a row of two constants:
@verbatim
SELECT MAX(b), MIN(d) FROM t1,t2 SELECT MAX(b), MIN(d) FROM t1,t2
WHERE a=const AND b<const AND d>const WHERE a=const AND b<const AND d>const
@endverbatim
(assuming a index for column d of table t2 is defined) (assuming a index for column d of table t2 is defined)
*/ */
#include "mysql_priv.h" #include "mysql_priv.h"
@ -83,25 +88,25 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
} }
/* /**
Substitutes constants for some COUNT(), MIN() and MAX() functions. Substitutes constants for some COUNT(), MIN() and MAX() functions.
SYNOPSIS @param tables list of leaves of join table tree
opt_sum_query() @param all_fields All fields to be returned
tables list of leaves of join table tree @param conds WHERE clause
all_fields All fields to be returned
conds WHERE clause
NOTE: @note
This function is only called for queries with sum functions and no This function is only called for queries with sum functions and no
GROUP BY part. GROUP BY part.
RETURN VALUES @retval
0 no errors 0 no errors
@retval
1 if all items were resolved 1 if all items were resolved
@retval
HA_ERR_KEY_NOT_FOUND on impossible conditions HA_ERR_KEY_NOT_FOUND on impossible conditions
OR an error number from my_base.h HA_ERR_... if a deadlock or a lock @retval
wait timeout happens, for example HA_ERR_... if a deadlock or a lock wait timeout happens, for example
*/ */
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
@ -473,19 +478,18 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
} }
/* /**
Test if the predicate compares a field with constants Test if the predicate compares a field with constants.
SYNOPSIS @param func_item Predicate item
simple_pred() @param[out] args Here we store the field followed by constants
func_item Predicate item @param[out] inv_order Is set to 1 if the predicate is of the form
args out: Here we store the field followed by constants 'const op field'
inv_order out: Is set to 1 if the predicate is of the form
'const op field'
RETURN @retval
0 func_item is a simple predicate: a field is compared with 0 func_item is a simple predicate: a field is compared with
constants constants
@retval
1 Otherwise 1 Otherwise
*/ */
@ -557,34 +561,33 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
} }
/* /**
Check whether a condition matches a key to get {MAX|MIN}(field): Check whether a condition matches a key to get {MAX|MIN}(field):.
SYNOPSIS
matching_cond()
max_fl in: Set to 1 if we are optimising MAX()
ref in/out: Reference to the structure we store the key value
keyinfo in Reference to the key info
field_part in: Pointer to the key part for the field
cond in WHERE condition
key_part_used in/out: Map of matchings parts
range_fl in/out: Says whether including key will be used
prefix_len out: Length of common key part for the range
where MAX/MIN is searched for
DESCRIPTION
For the index specified by the keyinfo parameter, index that For the index specified by the keyinfo parameter, index that
contains field as its component (field_part), the function contains field as its component (field_part), the function
checks whether the condition cond is a conjunction and all its checks whether the condition cond is a conjunction and all its
conjuncts referring to the columns of the same table as column conjuncts referring to the columns of the same table as column
field are one of the following forms: field are one of the following forms:
- f_i= const_i or const_i= f_i or f_i is null, - f_i= const_i or const_i= f_i or f_i is null,
where f_i is part of the index where f_i is part of the index
- field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field - field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field
- field between const1 and const2 - field between const1 and const2
RETURN @param[in] max_fl Set to 1 if we are optimising MAX()
@param[in,out] ref Reference to the structure we store the key
value
@param[in] keyinfo Reference to the key info
@param[in] field_part Pointer to the key part for the field
@param[in] cond WHERE condition
@param[in,out] key_part_used Map of matchings parts
@param[in,out] range_fl Says whether including key will be used
@param[out] prefix_len Length of common key part for the range
where MAX/MIN is searched for
@retval
0 Index can't be used. 0 Index can't be used.
@retval
1 We can use index to get MIN/MAX value 1 We can use index to get MIN/MAX value
*/ */
@ -749,31 +752,21 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
} }
/* /**
Check whether we can get value for {max|min}(field) by using a key. Check whether we can get value for {max|min}(field) by using a key.
SYNOPSIS If where-condition is not a conjunction of 0 or more conjuct the
find_key_for_maxmin() function returns false, otherwise it checks whether there is an
max_fl in: 0 for MIN(field) / 1 for MAX(field) index including field as its k-th component/part such that:
ref in/out Reference to the structure we store the key value
field in: Field used inside MIN() / MAX()
cond in: WHERE condition
range_fl out: Bit flags for how to search if key is ok
prefix_len out: Length of prefix for the search range
DESCRIPTION -# for each previous component f_i there is one and only one conjunct
If where condition is not a conjunction of 0 or more conjuct the
function returns false, otherwise it checks whether there is an
index including field as its k-th component/part such that:
1. for each previous component f_i there is one and only one conjunct
of the form: f_i= const_i or const_i= f_i or f_i is null of the form: f_i= const_i or const_i= f_i or f_i is null
2. references to field occur only in conjucts of the form: -# references to field occur only in conjucts of the form:
field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
field BETWEEN const1 AND const2 field BETWEEN const1 AND const2
3. all references to the columns from the same table as column field -# all references to the columns from the same table as column field
occur only in conjucts mentioned above. occur only in conjucts mentioned above.
4. each of k first components the index is not partial, i.e. is not -# each of k first components the index is not partial, i.e. is not
defined on a fixed length proper prefix of the field. defined on a fixed length proper prefix of the field.
If such an index exists the function through the ref parameter If such an index exists the function through the ref parameter
@ -781,17 +774,26 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
the length of first (k-1) components of the key and flags saying the length of first (k-1) components of the key and flags saying
how to apply the key for the search max/min value. how to apply the key for the search max/min value.
(if we have a condition field = const, prefix_len contains the length (if we have a condition field = const, prefix_len contains the length
of the whole search key) of the whole search key)
NOTE @param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
@param[in,out] ref Reference to the structure we store the key value
@param[in] field Field used inside MIN() / MAX()
@param[in] cond WHERE condition
@param[out] range_fl Bit flags for how to search if key is ok
@param[out] prefix_len Length of prefix for the search range
@note
This function may set table->key_read to 1, which must be reset after This function may set table->key_read to 1, which must be reset after
index is used! (This can only happen when function returns 1) index is used! (This can only happen when function returns 1)
RETURN @retval
0 Index can not be used to optimize MIN(field)/MAX(field) 0 Index can not be used to optimize MIN(field)/MAX(field)
1 Can use key to optimize MIN()/MAX() @retval
In this case ref, range_fl and prefix_len are updated 1 Can use key to optimize MIN()/MAX().
*/ In this case ref, range_fl and prefix_len are updated
*/
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
Field* field, COND *cond, Field* field, COND *cond,
@ -884,20 +886,19 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
} }
/* /**
Check whether found key is in range specified by conditions Check whether found key is in range specified by conditions.
SYNOPSIS @param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
reckey_in_range() @param[in] ref Reference to the key value and info
max_fl in: 0 for MIN(field) / 1 for MAX(field) @param[in] field Field used the MIN/MAX expression
ref in: Reference to the key value and info @param[in] cond WHERE condition
field in: Field used the MIN/MAX expression @param[in] range_fl Says whether there is a condition to to be checked
cond in: WHERE condition @param[in] prefix_len Length of the constant part of the key
range_fl in: Says whether there is a condition to to be checked
prefix_len in: Length of the constant part of the key
RETURN @retval
0 ok 0 ok
@retval
1 WHERE was not true for the found row 1 WHERE was not true for the found row
*/ */
@ -912,16 +913,16 @@ static int reckey_in_range(bool max_fl, TABLE_REF *ref, Field* field,
} }
/* /**
Check whether {MAX|MIN}(field) is in range specified by conditions Check whether {MAX|MIN}(field) is in range specified by conditions.
SYNOPSIS
maxmin_in_range()
max_fl in: 0 for MIN(field) / 1 for MAX(field)
field in: Field used the MIN/MAX expression
cond in: WHERE condition
RETURN @param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
@param[in] field Field used the MIN/MAX expression
@param[in] cond WHERE condition
@retval
0 ok 0 ok
@retval
1 WHERE was not true for the found row 1 WHERE was not true for the found row
*/ */

View file

@ -13,7 +13,12 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Text .frm files management routines /**
@file
@brief
Text .frm files management routines
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#include <errno.h> #include <errno.h>
@ -22,17 +27,16 @@
#include <my_dir.h> #include <my_dir.h>
/* /**
write string with escaping Write string with escaping.
SYNOPSIS @param file IO_CACHE for record
write_escaped_string() @param val_s string for writing
file - IO_CACHE for record
val_s - string for writing
RETURN @retval
FALSE - OK FALSE OK
TRUE - error @retval
TRUE error
*/ */
static my_bool static my_bool
@ -77,21 +81,21 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
} }
/* /**
write parameter value to IO_CACHE Write parameter value to IO_CACHE.
SYNOPSIS @param file pointer to IO_CACHE structure for writing
write_parameter() @param base pointer to data structure
file pointer to IO_CACHE structure for writing @param parameter pointer to parameter descriptor
base pointer to data structure @param old_version for returning back old version number value
parameter pointer to parameter descriptor
old_version for returning back old version number value
RETURN @retval
FALSE - OK FALSE OK
TRUE - error @retval
TRUE error
*/ */
static my_bool static my_bool
write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
ulonglong *old_version) ulonglong *old_version)
@ -191,24 +195,24 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
} }
/* /**
write new .frm Write new .frm.
SYNOPSIS @param dir directory where put .frm
sql_create_definition_file() @param file_name .frm file name
dir directory where put .frm @param type .frm type string (VIEW, TABLE)
file .frm file name @param base base address for parameter reading (structure like
type .frm type string (VIEW, TABLE) TABLE)
base base address for parameter reading (structure like @param parameters parameters description
TABLE) @param max_versions number of versions to save
parameters parameters description
max_versions number of versions to save
RETURN @retval
FALSE - OK FALSE OK
TRUE - error @retval
TRUE error
*/ */
my_bool my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type, const LEX_STRING *type,
@ -345,21 +349,19 @@ err_w_file:
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* /**
Renames a frm file (including backups) in same schema Renames a frm file (including backups) in same schema.
SYNOPSIS @param schema name of given schema
rename_in_schema_file @param old_name original file name
schema name of given schema @param new_name new file name
old_name original file name @param revision revision number
new_name new file name @param num_view_backups number of backups
revision revision number
num_view_backups number of backups
RETURN
0 - OK
1 - Error (only if renaming of frm failed)
@retval
0 OK
@retval
1 Error (only if renaming of frm failed)
*/ */
my_bool rename_in_schema_file(const char *schema, const char *old_name, my_bool rename_in_schema_file(const char *schema, const char *old_name,
const char *new_name, ulonglong revision, const char *new_name, ulonglong revision,
@ -401,21 +403,20 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
return 0; return 0;
} }
/* /**
Prepare frm to parse (read to memory) Prepare frm to parse (read to memory).
SYNOPSIS @param file_name path & filename to .frm file
sql_parse_prepare() @param mem_root MEM_ROOT for buffer allocation
file_name - path & filename to .frm file @param bad_format_errors send errors on bad content
mem_root - MEM_ROOT for buffer allocation
bad_format_errors - send errors on bad content
RETURN @note
0 - error
parser object
NOTE
returned pointer + 1 will be type of .frm returned pointer + 1 will be type of .frm
@return
0 - error
@return
parser object
*/ */
File_parser * File_parser *
@ -506,22 +507,22 @@ frm_error:
} }
/* /**
parse LEX_STRING parse LEX_STRING.
SYNOPSIS @param ptr pointer on string beginning
parse_string() @param end pointer on symbol after parsed string end (still owned
ptr - pointer on string beginning by buffer and can be accessed
end - pointer on symbol after parsed string end (still owned @param mem_root MEM_ROOT for parameter allocation
by buffer and can be accessed @param str pointer on string, where results should be stored
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN @retval
0 - error 0 error
# - pointer on symbol after string @retval
\# pointer on symbol after string
*/ */
static char * static char *
parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
{ {
@ -539,18 +540,17 @@ parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
} }
/* /**
read escaped string from ptr to eol in already allocated str read escaped string from ptr to eol in already allocated str.
SYNOPSIS @param ptr pointer on string beginning
read_escaped_string() @param eol pointer on character after end of string
ptr - pointer on string beginning @param str target string
eol - pointer on character after end of string
str - target string
RETURN @retval
FALSE - OK FALSE OK
TRUE - error @retval
TRUE error
*/ */
my_bool my_bool
@ -598,22 +598,22 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str)
} }
/* /**
parse \n delimited escaped string parse \\n delimited escaped string.
SYNOPSIS @param ptr pointer on string beginning
parse_escaped_string() @param end pointer on symbol after parsed string end (still owned
ptr - pointer on string beginning by buffer and can be accessed
end - pointer on symbol after parsed string end (still owned @param mem_root MEM_ROOT for parameter allocation
by buffer and can be accessed @param str pointer on string, where results should be stored
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN @retval
0 - error 0 error
# - pointer on symbol after string @retval
\# pointer on symbol after string
*/ */
char * char *
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
{ {
@ -628,20 +628,19 @@ parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
} }
/* /**
parse '' delimited escaped string parse '' delimited escaped string.
SYNOPSIS @param ptr pointer on string beginning
parse_quoted_escaped_string() @param end pointer on symbol after parsed string end (still owned
ptr - pointer on string beginning by buffer and can be accessed
end - pointer on symbol after parsed string end (still owned @param mem_root MEM_ROOT for parameter allocation
by buffer and can be accessed @param str pointer on string, where results should be stored
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN @retval
0 - error 0 error
# - pointer on symbol after string @retval
\# pointer on symbol after string
*/ */
static char * static char *
@ -673,18 +672,16 @@ parse_quoted_escaped_string(char *ptr, char *end,
} }
/* /**
Parser for FILE_OPTIONS_ULLLIST type value. Parser for FILE_OPTIONS_ULLLIST type value.
SYNOPSIS @param[in,out] ptr pointer to parameter
get_file_options_ulllist() @param[in] end end of the configuration
ptr [in/out] pointer to parameter @param[in] line pointer to the line begining
end [in] end of the configuration @param[in] base base address for parameter writing (structure
line [in] pointer to the line begining like TABLE)
base [in] base address for parameter writing (structure @param[in] parameter description
like TABLE) @param[in] mem_root MEM_ROOT for parameters allocation
parameter [in] description
mem_root [in] MEM_ROOT for parameters allocation
*/ */
bool get_file_options_ulllist(char *&ptr, char *end, char *line, bool get_file_options_ulllist(char *&ptr, char *end, char *line,
@ -728,28 +725,28 @@ nlist_err:
} }
/* /**
parse parameters parse parameters.
SYNOPSIS @param base base address for parameter writing (structure like
File_parser::parse() TABLE)
base base address for parameter writing (structure like @param mem_root MEM_ROOT for parameters allocation
TABLE) @param parameters parameters description
mem_root MEM_ROOT for parameters allocation @param required number of required parameters in above list. If the file
parameters parameters description contains more parameters than "required", they will
required number of parameters in the above list. If the file be ignored. If the file contains less parameters
contains more parameters than "required", they will then "required", non-existing parameters will
be ignored. If the file contains less parameters remain their values.
then "required", non-existing parameters will @param hook hook called for unknown keys
remain their values. @param hook_data some data specific for the hook
hook hook called for unknown keys
hook_data some data specific for the hook
RETURN @retval
FALSE - OK FALSE OK
TRUE - error @retval
TRUE error
*/ */
my_bool my_bool
File_parser::parse(uchar* base, MEM_ROOT *mem_root, File_parser::parse(uchar* base, MEM_ROOT *mem_root,
struct File_option *parameters, uint required, struct File_option *parameters, uint required,
@ -935,26 +932,25 @@ list_err:
} }
/* /**
Dummy unknown key hook Dummy unknown key hook.
SYNOPSIS @param[in,out] unknown_key reference on the line with unknown
File_parser_dummy_hook::process_unknown_string() parameter and the parsing point
unknown_key [in/out] reference on the line with unknown @param[in] base base address for parameter writing
parameter and the parsing point (structure like TABLE)
base [in] base address for parameter writing (structure like @param[in] mem_root MEM_ROOT for parameters allocation
TABLE) @param[in] end the end of the configuration
mem_root [in] MEM_ROOT for parameters allocation
end [in] the end of the configuration
NOTE @note
This hook used to catch no longer supported keys and process them for This hook used to catch no longer supported keys and process them for
backward compatibility, but it will not slow down processing of modern backward compatibility, but it will not slow down processing of modern
format files. format files.
This hook does nothing except debug output. This hook does nothing except debug output.
RETURN @retval
FALSE OK FALSE OK
@retval
TRUE Error TRUE Error
*/ */

View file

@ -20,27 +20,27 @@
#define PARSE_FILE_TIMESTAMPLENGTH 19 #define PARSE_FILE_TIMESTAMPLENGTH 19
enum file_opt_type { enum file_opt_type {
FILE_OPTIONS_STRING, /* String (LEX_STRING) */ FILE_OPTIONS_STRING, /**< String (LEX_STRING) */
FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */ FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */
FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */ FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */
FILE_OPTIONS_REV, /* Revision version number (ulonglong) */ FILE_OPTIONS_REV, /**< Revision version number (ulonglong) */
FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be
allocated with length 20 (19+1) */ allocated with length 20 (19+1) */
FILE_OPTIONS_STRLIST, /* list of escaped strings FILE_OPTIONS_STRLIST, /**< list of escaped strings
(List<LEX_STRING>) */ (List<LEX_STRING>) */
FILE_OPTIONS_ULLLIST /* list of ulonglong values FILE_OPTIONS_ULLLIST /**< list of ulonglong values
(List<ulonglong>) */ (List<ulonglong>) */
}; };
struct File_option struct File_option
{ {
LEX_STRING name; /* Name of the option */ LEX_STRING name; /**< Name of the option */
int offset; /* offset to base address of value */ int offset; /**< offset to base address of value */
file_opt_type type; /* Option type */ file_opt_type type; /**< Option type */
}; };
/* /**
This hook used to catch no longer supported keys and process them for This hook used to catch no longer supported keys and process them for
backward compatibility. backward compatibility.
*/ */
@ -55,7 +55,7 @@ public:
}; };
/* Dummy hook for parsers which do not need hook for unknown keys */ /** Dummy hook for parsers which do not need hook for unknown keys. */
class File_parser_dummy_hook: public Unknown_key_hook class File_parser_dummy_hook: public Unknown_key_hook
{ {

View file

@ -68,10 +68,13 @@ my_decimal *Item_proc_real::val_decimal(my_decimal *decimal_value)
} }
/***************************************************************************** /**
** Setup handling of procedure Setup handling of procedure.
** Return 0 if everything is ok
*****************************************************************************/ @return
Return 0 if everything is ok
*/
Procedure * Procedure *
setup_procedure(THD *thd,ORDER *param,select_result *result, setup_procedure(THD *thd,ORDER *param,select_result *result,

View file

@ -20,8 +20,8 @@
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
#define PROC_NO_SORT 1 /* Bits in flags */ #define PROC_NO_SORT 1 /**< Bits in flags */
#define PROC_GROUP 2 /* proc must have group */ #define PROC_GROUP 2 /**< proc must have group */
/* Procedure items used by procedures to store values for send_fields */ /* Procedure items used by procedures to store values for send_fields */

View file

@ -13,8 +13,10 @@
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 */
/* /**
Low level functions for storing data to be send to the MySQL client @file
Low level functions for storing data to be send to the MySQL client.
The actual communction is handled by the net_xxx functions in net_serv.cc The actual communction is handled by the net_xxx functions in net_serv.cc
*/ */
@ -53,17 +55,18 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
} }
/* /**
Send a error string to client Send a error string to client.
Design note: Design note:
net_send_error is a low-level functions net_printf_error and net_send_error are low-level functions
that shall be used only when a new connection is being that shall be used only when a new connection is being
established or at server startup. established or at server startup.
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
critical that every error that can be intercepted is issued in one For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
place only, my_message_sql. critical that every error that can be intercepted is issued in one
place only, my_message_sql.
*/ */
void net_send_error(THD *thd, uint sql_errno, const char *err) void net_send_error(THD *thd, uint sql_errno, const char *err)
{ {
@ -126,32 +129,28 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/**
/*
Return ok to the client. Return ok to the client.
SYNOPSIS The ok packet has the following structure:
send_ok()
thd Thread handler
affected_rows Number of rows changed by statement
id Auto_increment id for first row (if used)
message Message to send to the client (Used by mysql_status)
DESCRIPTION - 0 : Marker (1 byte)
The ok packet has the following structure - affected_rows : Stored in 1-9 bytes
- id : Stored in 1-9 bytes
- server_status : Copy of thd->server_status; Can be used by client
to check if we are inside an transaction.
New in 4.0 protocol
- warning_count : Stored in 2 bytes; New in 4.1 protocol
- message : Stored as packed length (1-9 bytes) + message.
Is not stored if no message.
0 Marker (1 byte) If net->no_send_ok return without sending packet.
affected_rows Stored in 1-9 bytes
id Stored in 1-9 bytes
server_status Copy of thd->server_status; Can be used by client
to check if we are inside an transaction
New in 4.0 protocol
warning_count Stored in 2 bytes; New in 4.1 protocol
message Stored as packed length (1-9 bytes) + message
Is not stored if no message
If net->no_send_ok return without sending packet @param thd Thread handler
*/ @param affected_rows Number of rows changed by statement
@param id Auto_increment id for first row (if used)
@param message Message to send to the client (Used by mysql_status)
*/
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
void void
@ -207,27 +206,24 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */ static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
/* /**
Send eof (= end of result set) to the client Send eof (= end of result set) to the client.
SYNOPSIS The eof packet has the following structure:
send_eof()
thd Thread handler
no_flush Set to 1 if there will be more data to the client,
like in send_fields().
DESCRIPTION - 254 : Marker (1 byte)
The eof packet has the following structure - warning_count : Stored in 2 bytes; New in 4.1 protocol
- status_flag : Stored in 2 bytes;
For flags like SERVER_MORE_RESULTS_EXISTS.
254 Marker (1 byte) Note that the warning count will not be sent if 'no_flush' is set as
warning_count Stored in 2 bytes; New in 4.1 protocol we don't want to report the warning count until all data is sent to the
status_flag Stored in 2 bytes; client.
For flags like SERVER_MORE_RESULTS_EXISTS
Note that the warning count will not be sent if 'no_flush' is set as @param thd Thread handler
we don't want to report the warning count until all data is sent to the @param no_flush Set to 1 if there will be more data to the client,
client. like in send_fields().
*/ */
void void
send_eof(THD *thd) send_eof(THD *thd)
@ -245,7 +241,7 @@ send_eof(THD *thd)
} }
/* /**
Format EOF packet according to the current protocol and Format EOF packet according to the current protocol and
write it to the network output buffer. write it to the network output buffer.
*/ */
@ -276,15 +272,15 @@ static void write_eof_packet(THD *thd, NET *net)
VOID(my_net_write(net, eof_buff, 1)); VOID(my_net_write(net, eof_buff, 1));
} }
/* /**
Please client to send scrambled_password in old format. Please client to send scrambled_password in old format.
SYNOPSYS
send_old_password_request() @param thd thread handle
thd thread handle
@retval
RETURN VALUE 0 ok
0 ok @retval
!0 error !0 error
*/ */
bool send_old_password_request(THD *thd) bool send_old_password_request(THD *thd)
@ -338,14 +334,15 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* /**
Faster net_store_length when we know that length is less than 65536. Faster net_store_length when we know that length is less than 65536.
We keep a separate version for that range because it's widely used in We keep a separate version for that range because it's widely used in
libmysql. libmysql.
uint is used as agrument type because of MySQL type conventions: uint is used as agrument type because of MySQL type conventions:
uint for 0..65536 - uint for 0..65536
ulong for 0..4294967296 - ulong for 0..4294967296
ulonglong for bigger numbers. - ulonglong for bigger numbers.
*/ */
static uchar *net_store_length_fast(uchar *packet, uint length) static uchar *net_store_length_fast(uchar *packet, uint length)
@ -418,27 +415,26 @@ bool Protocol::flush()
#endif #endif
} }
/* #ifndef EMBEDDED_LIBRARY
/**
Send name and type of result to client. Send name and type of result to client.
SYNOPSIS Sum fields has table name empty and field_name.
send_fields()
THD Thread data object
list List of items to send to client
flag Bit mask with the following functions:
1 send number of rows
2 send default values
4 don't write eof packet
DESCRIPTION @param THD Thread data object
Sum fields has table name empty and field_name. @param list List of items to send to client
@param flag Bit mask with the following functions:
- 1 send number of rows
- 2 send default values
- 4 don't write eof packet
RETURN VALUES @retval
0 ok 0 ok
1 Error (Note that in this case the error is not sent to the client) @retval
1 Error (Note that in this case the error is not sent to the
client)
*/ */
#ifndef EMBEDDED_LIBRARY
bool Protocol::send_fields(List<Item> *list, uint flags) bool Protocol::send_fields(List<Item> *list, uint flags)
{ {
List_iterator_fast<Item> it(*list); List_iterator_fast<Item> it(*list);
@ -592,18 +588,17 @@ bool Protocol::write()
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* /**
Send \0 end terminated string Send \\0 end terminated string.
SYNOPSIS @param from NullS or \\0 terminated string
store()
from NullS or \0 terminated string
NOTES @note
In most cases one should use store(from, length) instead of this function In most cases one should use store(from, length) instead of this function
RETURN VALUES @retval
0 ok 0 ok
@retval
1 error 1 error
*/ */
@ -616,8 +611,8 @@ bool Protocol::store(const char *from, CHARSET_INFO *cs)
} }
/* /**
Send a set of strings as one long string with ',' in between Send a set of strings as one long string with ',' in between.
*/ */
bool Protocol::store(I_List<i_string>* str_list) bool Protocol::store(I_List<i_string>* str_list)
@ -669,7 +664,7 @@ bool Protocol_text::store_null()
#endif #endif
/* /**
Auxilary function to convert string to the given character set Auxilary function to convert string to the given character set
and store in network buffer. and store in network buffer.
*/ */
@ -846,13 +841,12 @@ bool Protocol_text::store(Field *field)
} }
/* /**
TODO: @todo
Second_part format ("%06") needs to change when Second_part format ("%06") needs to change when
we support 0-6 decimals for time. we support 0-6 decimals for time.
*/ */
bool Protocol_text::store(MYSQL_TIME *tm) bool Protocol_text::store(MYSQL_TIME *tm)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -890,10 +884,10 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
} }
/* /**
TODO: @todo
Second_part format ("%06") needs to change when Second_part format ("%06") needs to change when
we support 0-6 decimals for time. we support 0-6 decimals for time.
*/ */
bool Protocol_text::store_time(MYSQL_TIME *tm) bool Protocol_text::store_time(MYSQL_TIME *tm)

View file

@ -110,7 +110,7 @@ public:
}; };
/* Class used for the old (MySQL 4.0 protocol) */ /** Class used for the old (MySQL 4.0 protocol). */
class Protocol_text :public Protocol class Protocol_text :public Protocol
{ {

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions for easy reading of records, possible through a cache */ /**
@file
@brief
Functions for easy reading of records, possible through a cache
*/
#include "mysql_priv.h" #include "mysql_priv.h"
@ -31,25 +36,20 @@ static int rr_index_first(READ_RECORD *info);
static int rr_index(READ_RECORD *info); static int rr_index(READ_RECORD *info);
/* /**
Initialize READ_RECORD structure to perform full index scan Initialize READ_RECORD structure to perform full index scan (in forward
direction) using read_record.read_record() interface.
SYNOPSIS
init_read_record_idx()
info READ_RECORD structure to initialize.
thd Thread handle
table Table to be accessed
print_error If true, call table->file->print_error() if an error
occurs (except for end-of-records error)
idx index to scan
DESCRIPTION
Initialize READ_RECORD structure to perform full index scan (in forward
direction) using read_record.read_record() interface.
This function has been added at late stage and is used only by This function has been added at late stage and is used only by
UPDATE/DELETE. Other statements perform index scans using UPDATE/DELETE. Other statements perform index scans using
join_read_first/next functions. join_read_first/next functions.
@param info READ_RECORD structure to initialize.
@param thd Thread handle
@param table Table to be accessed
@param print_error If true, call table->file->print_error() if an error
occurs (except for end-of-records error)
@param idx index to scan
*/ */
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
@ -286,7 +286,7 @@ static int rr_handle_error(READ_RECORD *info, int error)
} }
/* Read a record from head-database */ /** Read a record from head-database. */
static int rr_quick(READ_RECORD *info) static int rr_quick(READ_RECORD *info)
{ {
@ -308,20 +308,19 @@ static int rr_quick(READ_RECORD *info)
} }
/* /**
Reads first row in an index scan Reads first row in an index scan.
SYNOPSIS @param info Scan info
rr_index_first()
info Scan info @retval
RETURN
0 Ok 0 Ok
-1 End of records @retval
1 Error -1 End of records
@retval
1 Error
*/ */
static int rr_index_first(READ_RECORD *info) static int rr_index_first(READ_RECORD *info)
{ {
int tmp= info->file->index_first(info->record); int tmp= info->file->index_first(info->record);
@ -332,24 +331,22 @@ static int rr_index_first(READ_RECORD *info)
} }
/* /**
Reads index sequentially after first row Reads index sequentially after first row.
SYNOPSIS Read the next index record (in forward direction) and translate return
rr_index() value.
info Scan info
@param info Scan info
DESCRIPTION
Read the next index record (in forward direction) and translate return @retval
value.
RETURN
0 Ok 0 Ok
-1 End of records @retval
1 Error -1 End of records
@retval
1 Error
*/ */
static int rr_index(READ_RECORD *info) static int rr_index(READ_RECORD *info)
{ {
int tmp= info->file->index_next(info->record); int tmp= info->file->index_next(info->record);
@ -403,22 +400,20 @@ static int rr_from_tempfile(READ_RECORD *info)
} /* rr_from_tempfile */ } /* rr_from_tempfile */
/* /**
Read a result set record from a temporary file after sorting Read a result set record from a temporary file after sorting.
SYNOPSIS The function first reads the next sorted record from the temporary file.
rr_unpack_from_tempfile() into a buffer. If a success it calls a callback function that unpacks
info Reference to the context including record descriptors the fields values use in the result set from this buffer into their
positions in the regular record buffer.
DESCRIPTION @param info Reference to the context including record descriptors
The function first reads the next sorted record from the temporary file.
into a buffer. If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN @retval
0 - Record successfully read. 0 Record successfully read.
-1 - There is no record to be read anymore. @retval
-1 There is no record to be read anymore.
*/ */
static int rr_unpack_from_tempfile(READ_RECORD *info) static int rr_unpack_from_tempfile(READ_RECORD *info)
@ -456,22 +451,20 @@ static int rr_from_pointers(READ_RECORD *info)
return tmp; return tmp;
} }
/* /**
Read a result set record from a buffer after sorting Read a result set record from a buffer after sorting.
SYNOPSIS The function first reads the next sorted record from the sort buffer.
rr_unpack_from_buffer() If a success it calls a callback function that unpacks
info Reference to the context including record descriptors the fields values use in the result set from this buffer into their
positions in the regular record buffer.
DESCRIPTION @param info Reference to the context including record descriptors
The function first reads the next sorted record from the sort buffer.
If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN @retval
0 - Record successfully read. 0 Record successfully read.
-1 - There is no record to be read anymore. @retval
-1 There is no record to be read anymore.
*/ */
static int rr_unpack_from_buffer(READ_RECORD *info) static int rr_unpack_from_buffer(READ_RECORD *info)

View file

@ -13,6 +13,16 @@
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
All of the functions defined in this file which are not used (the ones to
handle failsafe) are not used; their code has not been updated for more
than one year now so should be considered as BADLY BROKEN. Do not enable
it. The used functions (to handle LOAD DATA FROM MASTER, plus some small
functions like register_slave()) are working.
*/
#include "mysql_priv.h" #include "mysql_priv.h"
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
@ -144,12 +154,13 @@ void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
} }
/* /**
Register slave in 'slave_list' hash table Register slave in 'slave_list' hash table.
RETURN VALUES @return
0 ok 0 ok
1 Error. Error message sent to client @return
1 Error. Error message sent to client
*/ */
int register_slave(THD* thd, uchar* packet, uint packet_length) int register_slave(THD* thd, uchar* packet, uint packet_length)
@ -252,7 +263,8 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
/* Impossible */ /* Impossible */
} }
/* /**
@details
Before 4.0.15 we had a member of THD called log_pos, it was meant for Before 4.0.15 we had a member of THD called log_pos, it was meant for
failsafe replication code in repl_failsafe.cc which is disabled until failsafe replication code in repl_failsafe.cc which is disabled until
it is reworked. Event's log_pos used to be preserved through it is reworked. Event's log_pos used to be preserved through
@ -388,8 +400,8 @@ err:
} }
/* /**
Caller must delete result when done Caller must delete result when done.
*/ */
static Slave_log_event* find_slave_event(IO_CACHE* log, static Slave_log_event* find_slave_event(IO_CACHE* log,
@ -428,9 +440,11 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
return (Slave_log_event*)ev; return (Slave_log_event*)ev;
} }
/* /**
This function is broken now. See comment for translate_master(). This function is broken now.
*/
@seealso translate_master()
*/
bool show_new_master(THD* thd) bool show_new_master(THD* thd)
{ {
@ -466,20 +480,19 @@ bool show_new_master(THD* thd)
} }
} }
/* /**
Asks the master for the list of its other connected slaves. Asks the master for the list of its other connected slaves.
This is for failsafe replication:
This is for failsafe replication:
in order for failsafe replication to work, the servers involved in in order for failsafe replication to work, the servers involved in
replication must know of each other. We accomplish this by having each replication must know of each other. We accomplish this by having each
slave report to the master how to reach it, and on connection, each slave report to the master how to reach it, and on connection, each
slave receives information about where the other slaves are. slave receives information about where the other slaves are.
SYNOPSIS @param mysql pre-existing connection to the master
update_slave_list() @param mi master info
mysql pre-existing connection to the master
mi master info
NOTES @note
mi is used only to give detailed error messages which include the mi is used only to give detailed error messages which include the
hostname/port of the master, the username used by the slave to connect to hostname/port of the master, the username used by the slave to connect to
the master. the master.
@ -487,10 +500,11 @@ bool show_new_master(THD* thd)
REPLICATION SLAVE privilege, it will pop in this function because REPLICATION SLAVE privilege, it will pop in this function because
SHOW SLAVE HOSTS will fail on the master. SHOW SLAVE HOSTS will fail on the master.
RETURN VALUES @retval
1 error 1 error
@retval
0 success 0 success
*/ */
int update_slave_list(MYSQL* mysql, Master_info* mi) int update_slave_list(MYSQL* mysql, Master_info* mi)
{ {
@ -754,11 +768,16 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db,
return 0; return 0;
} }
/* /**
Load all MyISAM tables from master to this slave. Load all MyISAM tables from master to this slave.
REQUIREMENTS REQUIREMENTS
- No active transaction (flush_relay_log_info would not work in this case) - No active transaction (flush_relay_log_info would not work in this case).
@todo
- add special option, not enabled
by default, to allow inclusion of mysql database into load
data from master
*/ */
bool load_master_data(THD* thd) bool load_master_data(THD* thd)

View file

@ -13,9 +13,13 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /**
@file
@brief
Handling of MySQL SQL variables Handling of MySQL SQL variables
@details
To add a new variable, one has to do the following: To add a new variable, one has to do the following:
- Use one of the 'sys_var... classes from set_var.h or write a specific - Use one of the 'sys_var... classes from set_var.h or write a specific
@ -28,18 +32,19 @@
- Don't forget to initialize new fields in global_system_variables and - Don't forget to initialize new fields in global_system_variables and
max_system_variables! max_system_variables!
NOTES: @todo
- Be careful with var->save_result: sys_var::check() only updates Add full support for the variable character_set (for 4.1)
@todo
When updating myisam_delay_key_write, we should do a 'flush tables'
of all MyISAM tables to ensure that they are reopen with the
new attribute.
@note
Be careful with var->save_result: sys_var::check() only updates
ulonglong_value; so other members of the union are garbage then; to use ulonglong_value; so other members of the union are garbage then; to use
them you must first assign a value to them (in specific ::check() for them you must first assign a value to them (in specific ::check() for
example). example).
TODO:
- Add full support for the variable character_set (for 4.1)
- When updating myisam_delay_key_write, we should do a 'flush tables'
of all MyISAM tables to ensure that they are reopen with the
new attribute.
*/ */
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
@ -824,9 +829,9 @@ static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
} }
/* /**
If one sets the LOW_PRIORIY UPDATES flag, we also must change the If one sets the LOW_PRIORIY UPDATES flag, we also must change the
used lock type used lock type.
*/ */
static void fix_low_priority_updates(THD *thd, enum_var_type type) static void fix_low_priority_updates(THD *thd, enum_var_type type)
@ -848,8 +853,8 @@ fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
(my_off_t) global_system_variables.myisam_max_sort_file_size; (my_off_t) global_system_variables.myisam_max_sort_file_size;
} }
/* /**
Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
*/ */
static void fix_max_join_size(THD *thd, enum_var_type type) static void fix_max_join_size(THD *thd, enum_var_type type)
@ -864,7 +869,7 @@ static void fix_max_join_size(THD *thd, enum_var_type type)
} }
/* /**
Can't change the 'next' tx_isolation while we are already in Can't change the 'next' tx_isolation while we are already in
a transaction a transaction
*/ */
@ -880,7 +885,7 @@ static int check_tx_isolation(THD *thd, set_var *var)
/* /*
If one doesn't use the SESSION modifier, the isolation level If one doesn't use the SESSION modifier, the isolation level
is only active for the next command is only active for the next command.
*/ */
static void fix_tx_isolation(THD *thd, enum_var_type type) static void fix_tx_isolation(THD *thd, enum_var_type type)
{ {
@ -1452,9 +1457,12 @@ err:
} }
/* /**
Return an Item for a variable. Used with @@[global.]variable_name Return an Item for a variable.
If type is not given, return local value if exists, else global
Used with @@[global.]variable_name.
If type is not given, return local value if exists, else global.
*/ */
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
@ -1616,7 +1624,7 @@ uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
} }
/* Update a date_time format variable based on given value */ /** Update a date_time format variable based on given value. */
void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type, void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
DATE_TIME_FORMAT *new_value) DATE_TIME_FORMAT *new_value)
@ -2048,6 +2056,12 @@ end:
} }
/**
@todo
Abort if some other thread is changing the key cache.
This should be changed so that we wait until the previous
assignment is done and then do the new assign
*/
bool sys_var_key_cache_long::update(THD *thd, set_var *var) bool sys_var_key_cache_long::update(THD *thd, set_var *var)
{ {
ulong tmp= (ulong) var->value->val_int(); ulong tmp= (ulong) var->value->val_int();
@ -2758,23 +2772,20 @@ static uchar *get_error_count(THD *thd)
} }
/* /**
Get the tmpdir that was specified or chosen by default Get the tmpdir that was specified or chosen by default.
SYNOPSIS This is necessary because if the user does not specify a temporary
get_tmpdir() directory via the command line, one is chosen based on the environment
thd thread handle or system defaults. But we can't just always use mysql_tmpdir, because
that is actually a call to my_tmpdir() which cycles among possible
temporary directories.
DESCRIPTION @param thd thread handle
This is necessary because if the user does not specify a temporary
directory via the command line, one is chosen based on the environment
or system defaults. But we can't just always use mysql_tmpdir, because
that is actually a call to my_tmpdir() which cycles among possible
temporary directories.
RETURN VALUES @retval
ptr pointer to NUL-terminated string ptr pointer to NUL-terminated string
*/ */
static uchar *get_tmpdir(THD *thd) static uchar *get_tmpdir(THD *thd)
{ {
if (opt_mysql_tmpdir) if (opt_mysql_tmpdir)
@ -2789,16 +2800,16 @@ static uchar *get_tmpdir(THD *thd)
- Update loop - Update loop
****************************************************************************/ ****************************************************************************/
/* /**
Find variable name in option my_getopt structure used for command line args Find variable name in option my_getopt structure used for
command line args.
SYNOPSIS @param opt option structure array to search in
find_option() @param name variable name
opt option structure array to search in
name variable name
RETURN VALUES @retval
0 Error 0 Error
@retval
ptr pointer to option structure ptr pointer to option structure
*/ */
@ -2821,8 +2832,8 @@ static struct my_option *find_option(struct my_option *opt, const char *name)
} }
/* /**
Return variable name and length for hashing of variables Return variable name and length for hashing of variables.
*/ */
static uchar *get_sys_var_length(const sys_var *var, size_t *length, static uchar *get_sys_var_length(const sys_var *var, size_t *length,
@ -3025,17 +3036,17 @@ int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count)
} }
/* /**
Find a user set-table variable Find a user set-table variable.
SYNOPSIS @param str Name of system variable to find
intern_find_sys_var() @param length Length of variable. zero means that we should use strlen()
str Name of system variable to find on the variable
length Length of variable. zero means that we should use strlen() @param no_error Refuse to emit an error, even if one occurred.
on the variable
RETURN VALUES @retval
pointer pointer to variable definitions pointer pointer to variable definitions
@retval
0 Unknown variable (error message is given) 0 Unknown variable (error message is given)
*/ */
@ -3056,25 +3067,23 @@ sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
} }
/* /**
Execute update of all variables Execute update of all variables.
SYNOPSIS First run a check of all variables that all updates will go ok.
If yes, then execute all updates, returning an error if any one failed.
sql_set This should ensure that in all normal cases none all or variables are
THD Thread id updated.
set_var List of variables to update
DESCRIPTION @param THD Thread id
First run a check of all variables that all updates will go ok. @param var_list List of variables to update
If yes, then execute all updates, returning an error if any one failed.
This should ensure that in all normal cases none all or variables are @retval
updated
RETURN VALUE
0 ok 0 ok
@retval
1 ERROR, message sent (normally no variables was updated) 1 ERROR, message sent (normally no variables was updated)
@retval
-1 ERROR, message not sent -1 ERROR, message not sent
*/ */
@ -3103,20 +3112,19 @@ err:
} }
/* /**
Say if all variables set by a SET support the ONE_SHOT keyword (currently, Say if all variables set by a SET support the ONE_SHOT keyword
only character set and collation do; later timezones will). (currently, only character set and collation do; later timezones
will).
SYNOPSIS @param var_list List of variables to update
not_all_support_one_shot @note
set_var List of variables to update
NOTES
It has a "not_" because it makes faster tests (no need to "!") It has a "not_" because it makes faster tests (no need to "!")
RETURN VALUE @retval
0 all variables of the list support ONE_SHOT 0 all variables of the list support ONE_SHOT
@retval
1 at least one does not support ONE_SHOT 1 at least one does not support ONE_SHOT
*/ */
@ -3175,17 +3183,17 @@ int set_var::check(THD *thd)
} }
/* /**
Check variable, but without assigning value (used by PS) Check variable, but without assigning value (used by PS).
SYNOPSIS @param thd thread handler
set_var::light_check()
thd thread handler
RETURN VALUE @retval
0 ok 0 ok
@retval
1 ERROR, message sent (normally no variables was updated) 1 ERROR, message sent (normally no variables was updated)
-1 ERROR, message not sent @retval
-1 ERROR, message not sent
*/ */
int set_var::light_check(THD *thd) int set_var::light_check(THD *thd)
{ {
@ -3232,17 +3240,17 @@ int set_var_user::check(THD *thd)
} }
/* /**
Check variable, but without assigning value (used by PS) Check variable, but without assigning value (used by PS).
SYNOPSIS @param thd thread handler
set_var_user::light_check()
thd thread handler
RETURN VALUE @retval
0 ok 0 ok
@retval
1 ERROR, message sent (normally no variables was updated) 1 ERROR, message sent (normally no variables was updated)
-1 ERROR, message not sent @retval
-1 ERROR, message not sent
*/ */
int set_var_user::light_check(THD *thd) int set_var_user::light_check(THD *thd)
{ {
@ -3416,13 +3424,15 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
Functions to handle sql_mode Functions to handle sql_mode
****************************************************************************/ ****************************************************************************/
/* /**
Make string representation of mode Make string representation of mode.
SYNOPSIS @param[in] thd thread handler
thd in thread handler @param[in] val sql_mode value
val in sql_mode value @param[out] len pointer on length of string
rep out pointer pointer to string with sql_mode representation
@return
pointer to string with sql_mode representation
*/ */
bool bool
@ -3493,7 +3503,7 @@ void fix_sql_mode_var(THD *thd, enum_var_type type)
} }
} }
/* Map database specific bits to function bits */ /** Map database specific bits to function bits. */
ulong fix_sql_mode(ulong sql_mode) ulong fix_sql_mode(ulong sql_mode)
{ {

351
sql/sp.cc
View file

@ -249,19 +249,18 @@ Stored_routine_creation_ctx::load_from_db(THD *thd,
/*************************************************************************/ /*************************************************************************/
/* /**
Open the mysql.proc table for read. Open the mysql.proc table for read.
SYNOPSIS @param thd Thread context
open_proc_table_for_read() @param backup Pointer to Open_tables_state instance where information about
thd Thread context currently open tables will be saved, and from which will be
backup Pointer to Open_tables_state instance where information about restored when we will end work with mysql.proc.
currently open tables will be saved, and from which will be
restored when we will end work with mysql.proc.
RETURN @retval
0 Error 0 Error
# Pointer to TABLE object of mysql.proc @retval
\# Pointer to TABLE object of mysql.proc
*/ */
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup) TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
@ -281,19 +280,18 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
} }
/* /**
Open the mysql.proc table for update. Open the mysql.proc table for update.
SYNOPSIS @param thd Thread context
open_proc_table_for_update()
thd Thread context
NOTES @note
Table opened with this call should closed using close_thread_tables(). Table opened with this call should closed using close_thread_tables().
RETURN @retval
0 Error 0 Error
# Pointer to TABLE object of mysql.proc @retval
\# Pointer to TABLE object of mysql.proc
*/ */
static TABLE *open_proc_table_for_update(THD *thd) static TABLE *open_proc_table_for_update(THD *thd)
@ -310,19 +308,18 @@ static TABLE *open_proc_table_for_update(THD *thd)
} }
/* /**
Find row in open mysql.proc table representing stored routine. Find row in open mysql.proc table representing stored routine.
SYNOPSIS @param thd Thread context
db_find_routine_aux() @param type Type of routine to find (function or procedure)
thd Thread context @param name Name of routine
type Type of routine to find (function or procedure) @param table TABLE object for open mysql.proc table.
name Name of routine
table TABLE object for open mysql.proc table.
RETURN VALUE @retval
SP_OK - Routine found SP_OK Routine found
SP_KEY_NOT_FOUND- No routine with given name @retval
SP_KEY_NOT_FOUND No routine with given name
*/ */
static int static int
@ -357,25 +354,24 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
} }
/* /**
Find routine definition in mysql.proc table and create corresponding Find routine definition in mysql.proc table and create corresponding
sp_head object for it. sp_head object for it.
SYNOPSIS @param thd Thread context
db_find_routine() @param type Type of routine (TYPE_ENUM_PROCEDURE/...)
thd Thread context @param name Name of routine
type Type of routine (TYPE_ENUM_PROCEDURE/...) @param sphp Out parameter in which pointer to created sp_head
name Name of routine object is returned (0 in case of error).
sphp Out parameter in which pointer to created sp_head
object is returned (0 in case of error).
NOTE @note
This function may damage current LEX during execution, so it is good This function may damage current LEX during execution, so it is good
idea to create temporary LEX and make it active before calling it. idea to create temporary LEX and make it active before calling it.
RETURN VALUE @retval
0 - Success 0 Success
non-0 - Error (may be one of special codes like SP_KEY_NOT_FOUND) @retval
non-0 Error (may be one of special codes like SP_KEY_NOT_FOUND)
*/ */
static int static int
@ -1337,22 +1333,21 @@ sp_show_create_routine(THD *thd, int type, sp_name *name)
} }
/* /**
Obtain object representing stored procedure/function by its name from Obtain object representing stored procedure/function by its name from
stored procedures cache and looking into mysql.proc if needed. stored procedures cache and looking into mysql.proc if needed.
SYNOPSIS @param thd thread context
sp_find_routine() @param type type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
thd - thread context @param name name of procedure
type - type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE) @param cp hash to look routine in
name - name of procedure @param cache_only if true perform cache-only lookup
cp - hash to look routine in (Don't look in mysql.proc).
cache_only - if true perform cache-only lookup
(Don't look in mysql.proc).
RETURN VALUE @retval
Non-0 pointer to sp_head object for the procedure, or NonNULL pointer to sp_head object for the procedure
0 - in case of error. @retval
NULL in case of error.
*/ */
sp_head * sp_head *
@ -1448,7 +1443,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
} }
/* /**
This is used by sql_acl.cc:mysql_routine_grant() and is used to find This is used by sql_acl.cc:mysql_routine_grant() and is used to find
the routines in 'routines'. the routines in 'routines'.
*/ */
@ -1497,18 +1492,17 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
} }
/* /**
Check if a routine exists in the mysql.proc table, without actually Check if a routine exists in the mysql.proc table, without actually
parsing the definition. (Used for dropping) parsing the definition. (Used for dropping).
SYNOPSIS @param thd thread context
sp_routine_exists_in_table() @param name name of procedure
thd - thread context
name - name of procedure
RETURN VALUE @retval
0 - Success 0 Success
non-0 - Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND @retval
non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
*/ */
int int
@ -1530,7 +1524,7 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
} }
/* /**
Structure that represents element in the set of stored routines Structure that represents element in the set of stored routines
used by statement or routine. used by statement or routine.
*/ */
@ -1538,14 +1532,16 @@ struct Sroutine_hash_entry;
struct Sroutine_hash_entry struct Sroutine_hash_entry
{ {
/* Set key consisting of one-byte routine type and quoted routine name. */ /**
Set key consisting of one-byte routine type and quoted routine name.
*/
LEX_STRING key; LEX_STRING key;
/* /**
Next element in list linking all routines in set. See also comments Next element in list linking all routines in set. See also comments
for LEX::sroutine/sroutine_list and sp_head::m_sroutines. for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
*/ */
Sroutine_hash_entry *next; Sroutine_hash_entry *next;
/* /**
Uppermost view which directly or indirectly uses this routine. Uppermost view which directly or indirectly uses this routine.
0 if routine is not used in view. Note that it also can be 0 if 0 if routine is not used in view. Note that it also can be 0 if
statement uses routine both via view and directly. statement uses routine both via view and directly.
@ -1563,24 +1559,22 @@ extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
} }
/* /**
Check if Check if
- current statement (the one in thd->lex) needs table prelocking - current statement (the one in thd->lex) needs table prelocking
- first routine in thd->lex->sroutines_list needs to execute its body in - first routine in thd->lex->sroutines_list needs to execute its body in
prelocked mode. prelocked mode.
SYNOPSIS @param thd Current thread, thd->lex is the statement to be
sp_get_prelocking_info() checked.
thd Current thread, thd->lex is the statement to be @param[out] need_prelocking TRUE - prelocked mode should be activated
checked. before executing the statement;
need_prelocking OUT TRUE - prelocked mode should be activated FALSE - Don't activate prelocking
before executing the statement @param[out] first_no_prelocking TRUE - Tables used by first routine in
FALSE - Don't activate prelocking thd->lex->sroutines_list should be
first_no_prelocking OUT TRUE - Tables used by first routine in prelocked. FALSE - Otherwise.
thd->lex->sroutines_list should be
prelocked. @note
FALSE - Otherwise.
NOTES
This function assumes that for any "CALL proc(...)" statement routines_list This function assumes that for any "CALL proc(...)" statement routines_list
will have 'proc' as first element (it may have several, consider e.g. will have 'proc' as first element (it may have several, consider e.g.
"proc(sp_func(...)))". This property is currently guaranted by the parser. "proc(sp_func(...)))". This property is currently guaranted by the parser.
@ -1600,36 +1594,37 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
} }
/* /**
Auxilary function that adds new element to the set of stored routines Auxilary function that adds new element to the set of stored routines
used by statement. used by statement.
SYNOPSIS In case when statement uses stored routines but does not need
add_used_routine() prelocking (i.e. it does not use any tables) we will access the
lex LEX representing statement elements of LEX::sroutines set on prepared statement re-execution.
arena Arena in which memory for new element will be allocated Because of this we have to allocate memory for both hash element
key Key for the hash representing set and copy of its key in persistent arena.
belong_to_view Uppermost view which uses this routine
(0 if routine is not used by view)
NOTES @param lex LEX representing statement
@param arena Arena in which memory for new element will be
allocated
@param key Key for the hash representing set
@param belong_to_view Uppermost view which uses this routine
(0 if routine is not used by view)
@note
Will also add element to end of 'LEX::sroutines_list' list. Will also add element to end of 'LEX::sroutines_list' list.
In case when statement uses stored routines but does not need @todo
prelocking (i.e. it does not use any tables) we will access the
elements of LEX::sroutines set on prepared statement re-execution.
Because of this we have to allocate memory for both hash element
and copy of its key in persistent arena.
TODO
When we will got rid of these accesses on re-executions we will be When we will got rid of these accesses on re-executions we will be
able to allocate memory for hash elements in non-persitent arena able to allocate memory for hash elements in non-persitent arena
and directly use key values from sp_head::m_sroutines sets instead and directly use key values from sp_head::m_sroutines sets instead
of making their copies. of making their copies.
RETURN VALUE @retval
TRUE - new element was added. TRUE new element was added.
FALSE - element was not added (because it is already present in the set). @retval
FALSE element was not added (because it is already present in
the set).
*/ */
static bool add_used_routine(LEX *lex, Query_arena *arena, static bool add_used_routine(LEX *lex, Query_arena *arena,
@ -1659,24 +1654,22 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
} }
/* /**
Add routine which is explicitly used by statement to the set of stored Add routine which is explicitly used by statement to the set of stored
routines used by this statement. routines used by this statement.
SYNOPSIS To be friendly towards prepared statements one should pass
sp_add_used_routine() persistent arena as second argument.
lex - LEX representing statement
arena - arena in which memory for new element of the set
will be allocated
rt - routine name
rt_type - routine type (one of TYPE_ENUM_PROCEDURE/...)
NOTES @param lex LEX representing statement
@param arena arena in which memory for new element of the set
will be allocated
@param rt routine name
@param rt_type routine type (one of TYPE_ENUM_PROCEDURE/...)
@note
Will also add element to end of 'LEX::sroutines_list' list (and will Will also add element to end of 'LEX::sroutines_list' list (and will
take into account that this is explicitly used routine). take into account that this is explicitly used routine).
To be friendly towards prepared statements one should pass
persistent arena as second argument.
*/ */
void sp_add_used_routine(LEX *lex, Query_arena *arena, void sp_add_used_routine(LEX *lex, Query_arena *arena,
@ -1689,13 +1682,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
} }
/* /**
Remove routines which are only indirectly used by statement from Remove routines which are only indirectly used by statement from
the set of routines used by this statement. the set of routines used by this statement.
SYNOPSIS @param lex LEX representing statement
sp_remove_not_own_routines()
lex LEX representing statement
*/ */
void sp_remove_not_own_routines(LEX *lex) void sp_remove_not_own_routines(LEX *lex)
@ -1718,16 +1709,14 @@ void sp_remove_not_own_routines(LEX *lex)
} }
/* /**
Merge contents of two hashes representing sets of routines used Merge contents of two hashes representing sets of routines used
by statements or by other routines. by statements or by other routines.
SYNOPSIS @param dst hash to which elements should be added
sp_update_sp_used_routines() @param src hash from which elements merged
dst - hash to which elements should be added
src - hash from which elements merged
NOTE @note
This procedure won't create new Sroutine_hash_entry objects, This procedure won't create new Sroutine_hash_entry objects,
instead it will simply add elements from source to destination instead it will simply add elements from source to destination
hash. Thus time of life of elements in destination hash becomes hash. Thus time of life of elements in destination hash becomes
@ -1747,18 +1736,17 @@ void sp_update_sp_used_routines(HASH *dst, HASH *src)
} }
/* /**
Add contents of hash representing set of routines to the set of Add contents of hash representing set of routines to the set of
routines used by statement. routines used by statement.
SYNOPSIS @param thd Thread context
sp_update_stmt_used_routines() @param lex LEX representing statement
thd Thread context @param src Hash representing set from which routines will
lex LEX representing statement be added
src Hash representing set from which routines will be added @param belong_to_view Uppermost view which uses these routines, 0 if none
belong_to_view Uppermost view which uses these routines, 0 if none
NOTE @note
It will also add elements to end of 'LEX::sroutines_list' list. It will also add elements to end of 'LEX::sroutines_list' list.
*/ */
@ -1774,18 +1762,17 @@ sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src,
} }
/* /**
Add contents of list representing set of routines to the set of Add contents of list representing set of routines to the set of
routines used by statement. routines used by statement.
SYNOPSIS @param thd Thread context
sp_update_stmt_used_routines() @param lex LEX representing statement
thd Thread context @param src List representing set from which routines will
lex LEX representing statement be added
src List representing set from which routines will be added @param belong_to_view Uppermost view which uses these routines, 0 if none
belong_to_view Uppermost view which uses these routines, 0 if none
NOTE @note
It will also add elements to end of 'LEX::sroutines_list' list. It will also add elements to end of 'LEX::sroutines_list' list.
*/ */
@ -1798,27 +1785,28 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
} }
/* /**
Cache sub-set of routines used by statement, add tables used by these Cache sub-set of routines used by statement, add tables used by these
routines to statement table list. Do the same for all routines used routines to statement table list. Do the same for all routines used
by these routines. by these routines.
SYNOPSIS @param thd thread context
sp_cache_routines_and_add_tables_aux() @param lex LEX representing statement
thd - thread context @param start first routine from the list of routines to be cached
lex - LEX representing statement (this list defines mentioned sub-set).
start - first routine from the list of routines to be cached @param first_no_prelock If true, don't add tables or cache routines used by
(this list defines mentioned sub-set). the body of the first routine (i.e. *start)
first_no_prelock - If true, don't add tables or cache routines used by will be executed in non-prelocked mode.
the body of the first routine (i.e. *start) @param tabs_changed Set to TRUE some tables were added, FALSE otherwise
will be executed in non-prelocked mode.
NOTE @note
If some function is missing this won't be reported here. If some function is missing this won't be reported here.
Instead this fact will be discovered during query execution. Instead this fact will be discovered during query execution.
RETURN VALUE @retval
0 - success 0 success
non-0 - failure @retval
non-0 failure
*/ */
static int static int
@ -1903,21 +1891,20 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
} }
/* /**
Cache all routines from the set of used by statement, add tables used Cache all routines from the set of used by statement, add tables used
by those routines to statement table list. Do the same for all routines by those routines to statement table list. Do the same for all routines
used by those routines. used by those routines.
SYNOPSIS @param thd thread context
sp_cache_routines_and_add_tables() @param lex LEX representing statement
thd - thread context @param first_no_prelock If true, don't add tables or cache routines used by
lex - LEX representing statement the body of the first routine (i.e. *start)
first_no_prelock - If true, don't add tables or cache routines used by
the body of the first routine (i.e. *start)
RETURN VALUE @retval
0 - success 0 success
non-0 - failure @retval
non-0 failure
*/ */
int int
@ -1929,20 +1916,21 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
} }
/* /**
Add all routines used by view to the set of routines used by statement. Add all routines used by view to the set of routines used by
statement.
Add tables used by those routines to statement table list. Do the same Add tables used by those routines to statement table list. Do the same
for all routines used by these routines. for all routines used by these routines.
SYNOPSIS @param thd Thread context
sp_cache_routines_and_add_tables_for_view() @param lex LEX representing statement
thd Thread context @param view Table list element representing view
lex LEX representing statement
view Table list element representing view
RETURN VALUE @retval
0 - success 0 success
non-0 - failure @retval
non-0 failure
*/ */
int int
@ -1957,20 +1945,19 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
} }
/* /**
Add triggers for table to the set of routines used by statement. Add triggers for table to the set of routines used by statement.
Add tables used by them to statement table list. Do the same for Add tables used by them to statement table list. Do the same for
all implicitly used routines. all implicitly used routines.
SYNOPSIS @param thd thread context
sp_cache_routines_and_add_tables_for_triggers() @param lex LEX respresenting statement
thd thread context @param table Table list element for table with trigger
lex LEX respresenting statement
table Table list element for table with trigger
RETURN VALUE @retval
0 - success 0 success
non-0 - failure @retval
non-0 failure
*/ */
int int
@ -2016,10 +2003,12 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
} }
/* /**
* Generates the CREATE... string from the table information. Generates the CREATE... string from the table information.
* Returns TRUE on success, FALSE on (alloc) failure.
*/ @return
Returns TRUE on success, FALSE on (alloc) failure.
*/
static bool static bool
create_string(THD *thd, String *buf, create_string(THD *thd, String *buf,
int type, int type,

View file

@ -80,19 +80,20 @@ sp_map_item_type(enum enum_field_types type)
} }
/* /**
Return a string representation of the Item value. Return a string representation of the Item value.
NOTE: If the item has a string result type, the string is escaped @param thd thread handle
according to its character set. @param str string buffer for representation of the value
SYNOPSIS @note
item a pointer to the Item If the item has a string result type, the string is escaped
str string buffer for representation of the value according to its character set.
RETURN @retval
NULL on error NULL on error
a pointer to valid a valid string on success @retval
non-NULL a pointer to valid a valid string on success
*/ */
static String * static String *
@ -138,16 +139,12 @@ sp_get_item_value(THD *thd, Item *item, String *str)
} }
/* /**
SYNOPSIS Returns a combination of:
sp_get_flags_for_command() - sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
result in multiple result sets being sent back.
DESCRIPTION - sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
Returns a combination of: EXECUTE, DEALLOCATE.
* sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
result in multiple result sets being sent back.
* sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
EXECUTE, DEALLOCATE.
*/ */
uint uint
@ -287,17 +284,16 @@ sp_get_flags_for_command(LEX *lex)
return flags; return flags;
} }
/* /**
Prepare an Item for evaluation (call of fix_fields). Prepare an Item for evaluation (call of fix_fields).
SYNOPSIS @param thd thread handler
sp_prepare_func_item() @param it_addr pointer on item refernce
thd thread handler
it_addr pointer on item refernce
RETURN @retval
NULL error NULL error
prepared item @retval
non-NULL prepared item
*/ */
Item * Item *
@ -317,17 +313,16 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
} }
/* /**
Evaluate an expression and store the result in the field. Evaluate an expression and store the result in the field.
SYNOPSIS @param thd current thread object
sp_eval_expr() @param result_field the field to store the result
thd - current thread object @param expr_item_ptr the root item of the expression
expr_item - the root item of the expression
result_field - the field to store the result
RETURN VALUES @retval
FALSE on success FALSE on success
@retval
TRUE on error TRUE on error
*/ */
@ -410,6 +405,10 @@ sp_name::sp_name(THD *thd, char *key, uint key_len)
m_explicit_name= false; m_explicit_name= false;
} }
/**
Init the qualified name from the db and name.
*/
void void
sp_name::init_qname(THD *thd) sp_name::init_qname(THD *thd)
{ {
@ -427,16 +426,17 @@ sp_name::init_qname(THD *thd)
} }
/* /**
Check that the name 'ident' is ok. It's assumed to be an 'ident' Check that the name 'ident' is ok. It's assumed to be an 'ident'
from the parser, so we only have to check length and trailing spaces. from the parser, so we only have to check length and trailing spaces.
The former is a standard requirement (and 'show status' assumes a The former is a standard requirement (and 'show status' assumes a
non-empty name), the latter is a mysql:ism as trailing spaces are non-empty name), the latter is a mysql:ism as trailing spaces are
removed by get_field(). removed by get_field().
RETURN @retval
TRUE - bad name TRUE bad name
FALSE - name is ok @retval
FALSE name is ok
*/ */
bool bool
@ -444,7 +444,7 @@ check_routine_name(LEX_STRING *ident)
{ {
if (!ident || !ident->str || !ident->str[0] || if (!ident || !ident->str || !ident->str[0] ||
ident->str[ident->length-1] == ' ') ident->str[ident->length-1] == ' ')
{ {
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str); my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
return TRUE; return TRUE;
} }
@ -778,7 +778,7 @@ sp_head::destroy()
} }
/* /**
This is only used for result fields from functions (both during This is only used for result fields from functions (both during
fix_length_and_dec() and evaluation). fix_length_and_dec() and evaluation).
*/ */
@ -897,29 +897,23 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
*/ */
/* /**
Replace thd->query{_length} with a string that one can write to the binlog Replace thd->query{_length} with a string that one can write to
or the query cache. the binlog.
SYNOPSIS
subst_spvars()
thd Current thread.
instr Instruction (we look for Item_splocal instances in
instr->free_list)
query_str Original query string
DESCRIPTION
The binlog-suitable string is produced by replacing references to SP local The binlog-suitable string is produced by replacing references to SP local
variables with NAME_CONST('sp_var_name', value) calls. To make this string variables with NAME_CONST('sp_var_name', value) calls.
suitable for the query cache this function allocates some additional space
for the query cache flags. @param thd Current thread.
@param instr Instruction (we look for Item_splocal instances in
RETURN instr->free_list)
FALSE on success @param query_str Original query string
thd->query{_length} either has been appropriately replaced or there
is no need for replacements. @return
TRUE out of memory error. - FALSE on success.
thd->query{_length} either has been appropriately replaced or there
is no need for replacements.
- TRUE out of memory error.
*/ */
static bool static bool
@ -1038,14 +1032,17 @@ void sp_head::recursion_level_error(THD *thd)
} }
/* /**
Execute the routine. The main instruction jump loop is there Execute the routine. The main instruction jump loop is there.
Assume the parameters already set. Assume the parameters already set.
@todo
RETURN - Will write this SP statement into binlog separately
FALSE on success (TODO: consider changing the condition to "not inside event union")
TRUE on error
@retval
FALSE on success
@retval
TRUE on error
*/ */
bool bool
@ -1335,22 +1332,26 @@ sp_head::execute(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /**
set_routine_security_ctx() changes routine security context, and set_routine_security_ctx() changes routine security context, and
checks if there is an EXECUTE privilege in new context. If there is checks if there is an EXECUTE privilege in new context. If there is
no EXECUTE privilege, it changes the context back and returns a no EXECUTE privilege, it changes the context back and returns a
error. error.
SYNOPSIS @param thd thread handle
set_routine_security_ctx() @param sp stored routine to change the context for
thd thread handle @param is_proc TRUE is procedure, FALSE if function
sp stored routine to change the context for @param save_ctx pointer to an old security context
is_proc TRUE is procedure, FALSE if function
save_ctx pointer to an old security context @todo
- Cache if the definer has the right to use the object on the
RETURN first usage and only reset the cache if someone does a GRANT
TRUE if there was a error, and the context wasn't changed. statement that 'may' affect this.
FALSE if the context was changed.
@retval
TRUE if there was a error, and the context wasn't changed.
@retval
FALSE if the context was changed.
*/ */
bool bool
@ -1392,22 +1393,27 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
/** /**
Execute trigger stored program. Execute trigger stored program.
Execute a trigger: - changes security context for triggers
- changes security context for triggers; - switch to new memroot
- switch to new memroot; - call sp_head::execute
- call sp_head::execute; - restore old memroot
- restore old memroot; - restores security context
- restores security context.
@param thd Thread context. @param thd Thread handle
@param db_name Database name. @param db database name
@param table_name Table name. @param table table name
@param grant_info GRANT_INFO structure to be filled with information @param grant_info GRANT_INFO structure to be filled with
about definer's privileges on subject table. information about definer's privileges
on subject table
@return Error status. @todo
@retval FALSE on success. - TODO: we should create sp_rcontext once per command and reuse it
@retval TRUE on error. on subsequent executions of a trigger.
@retval
FALSE on success
@retval
TRUE on error
*/ */
bool bool
@ -1515,8 +1521,9 @@ err_with_cleanup:
} }
/* /**
Execute a function: Execute a function.
- evaluate parameters - evaluate parameters
- changes security context for SUID routines - changes security context for SUID routines
- switch to new memroot - switch to new memroot
@ -1525,17 +1532,25 @@ err_with_cleanup:
- evaluate the return value - evaluate the return value
- restores security context - restores security context
SYNOPSIS @param thd Thread handle
sp_head::execute_function() @param argp Passed arguments (these are items from containing
thd Thread handle statement?)
argp Passed arguments (these are items from containing @param argcount Number of passed arguments. We need to check if
statement?) this is correct.
argcount Number of passed arguments. We need to check if this is @param return_value_fld Save result here.
correct.
return_value_fld Save result here. @todo
We should create sp_rcontext once per command and reuse
RETURN it on subsequent executions of a function/trigger.
@todo
In future we should associate call arena/mem_root with
sp_rcontext and allocate all these objects (and sp_rcontext
itself) on it directly rather than juggle with arenas.
@retval
FALSE on success FALSE on success
@retval
TRUE on error TRUE on error
*/ */
@ -1752,14 +1767,8 @@ err_with_cleanup:
} }
/* /**
Execute a procedure. Execute a procedure.
SYNOPSIS
sp_head::execute_procedure()
thd Thread handle
args List of values passed as arguments.
DESCRIPTION
The function does the following steps: The function does the following steps:
- Set all parameters - Set all parameters
@ -1768,8 +1777,12 @@ err_with_cleanup:
- copy back values of INOUT and OUT parameters - copy back values of INOUT and OUT parameters
- restores security context - restores security context
RETURN @param thd Thread handle
@param args List of values passed as arguments.
@retval
FALSE on success FALSE on success
@retval
TRUE on error TRUE on error
*/ */
@ -1972,7 +1985,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
/** /**
@brief Reset lex during parsing, before we parse a sub statement. Reset lex during parsing, before we parse a sub statement.
@param thd Thread handler. @param thd Thread handler.
@ -2017,7 +2030,7 @@ sp_head::reset_lex(THD *thd)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
// Restore lex during parsing, after we have parsed a sub statement. /// Restore lex during parsing, after we have parsed a sub statement.
void void
sp_head::restore_lex(THD *thd) sp_head::restore_lex(THD *thd)
{ {
@ -2060,6 +2073,9 @@ sp_head::restore_lex(THD *thd)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/**
Put the instruction on the backpatch list, associated with the label.
*/
void void
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab) sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
{ {
@ -2073,6 +2089,10 @@ sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
} }
} }
/**
Update all instruction with this label in the backpatch list to
the current position.
*/
void void
sp_head::backpatch(sp_label_t *lab) sp_head::backpatch(sp_label_t *lab)
{ {
@ -2087,19 +2107,18 @@ sp_head::backpatch(sp_label_t *lab)
} }
} }
/* /**
Prepare an instance of Create_field for field creation (fill all necessary Prepare an instance of Create_field for field creation (fill all necessary
attributes). attributes).
SYNOPSIS @param[in] thd Thread handle
sp_head::fill_field_definition() @param[in] lex Yacc parsing context
thd [IN] Thread handle @param[in] field_type Field type
lex [IN] Yacc parsing context @param[out] field_def An instance of create_field to be filled
field_type [IN] Field type
field_def [OUT] An instance of Create_field to be filled
RETURN @retval
FALSE on success FALSE on success
@retval
TRUE on error TRUE on error
*/ */
@ -2245,18 +2264,17 @@ sp_head::restore_thd_mem_root(THD *thd)
} }
/* /**
Check if a user has access right to a routine Check if a user has access right to a routine.
SYNOPSIS @param thd Thread handler
check_show_routine_access() @param sp SP
thd Thread handler @param full_access Set to 1 if the user has SELECT right to the
sp SP 'mysql.proc' able or is the owner of the routine
full_access Set to 1 if the user has SELECT right to the @retval
'mysql.proc' able or is the owner of the routine false ok
RETURN @retval
0 ok true error
1 error
*/ */
bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
@ -2383,12 +2401,10 @@ sp_head::show_create_routine(THD *thd, int type)
/* /**
Add instruction to SP Add instruction to SP.
SYNOPSIS @param instr Instruction
sp_head::add_instr()
instr Instruction
*/ */
void sp_head::add_instr(sp_instr *instr) void sp_head::add_instr(sp_instr *instr)
@ -2406,20 +2422,20 @@ void sp_head::add_instr(sp_instr *instr)
} }
/* /**
Do some minimal optimization of the code: Do some minimal optimization of the code:
1) Mark used instructions -# Mark used instructions
1.1) While doing this, shortcut jumps to jump instructions -# While doing this, shortcut jumps to jump instructions
2) Compact the code, removing unused instructions -# Compact the code, removing unused instructions.
This is the main mark and move loop; it relies on the following methods This is the main mark and move loop; it relies on the following methods
in sp_instr and its subclasses: in sp_instr and its subclasses:
opt_mark() Mark instruction as reachable - opt_mark() : Mark instruction as reachable
opt_shortcut_jump() Shortcut jumps to the final destination; - opt_shortcut_jump(): Shortcut jumps to the final destination;
used by opt_mark(). used by opt_mark().
opt_move() Update moved instruction - opt_move() : Update moved instruction
set_destination() Set the new destination (jump instructions only) - set_destination() : Set the new destination (jump instructions only)
*/ */
void sp_head::optimize() void sp_head::optimize()
@ -2510,9 +2526,10 @@ sp_head::opt_mark()
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* /**
Return the routine instructions as a result set. Return the routine instructions as a result set.
Returns 0 if ok, !=0 on error. @return
0 if ok, !=0 on error.
*/ */
int int
sp_head::show_routine_code(THD *thd) sp_head::show_routine_code(THD *thd)
@ -2575,27 +2592,25 @@ sp_head::show_routine_code(THD *thd)
#endif // ifndef DBUG_OFF #endif // ifndef DBUG_OFF
/* /**
Prepare LEX and thread for execution of instruction, if requested open Prepare LEX and thread for execution of instruction, if requested open
and lock LEX's tables, execute instruction's core function, perform and lock LEX's tables, execute instruction's core function, perform
cleanup afterwards. cleanup afterwards.
SYNOPSIS @param thd thread context
reset_lex_and_exec_core() @param nextp out - next instruction
thd - thread context @param open_tables if TRUE then check read access to tables in LEX's table
nextp - out - next instruction list and open and lock them (used in instructions which
open_tables - if TRUE then check read access to tables in LEX's table need to calculate some expression and don't execute
list and open and lock them (used in instructions which complete statement).
need to calculate some expression and don't execute @param sp_instr instruction for which we prepare context, and which core
complete statement). function execute by calling its exec_core() method.
sp_instr - instruction for which we prepare context, and which core
function execute by calling its exec_core() method.
NOTE @note
We are not saving/restoring some parts of THD which may need this because We are not saving/restoring some parts of THD which may need this because
we do this once for whole routine execution in sp_head::execute(). we do this once for whole routine execution in sp_head::execute().
RETURN VALUE @return
0/non-0 - Success/Failure 0/non-0 - Success/Failure
*/ */
@ -3349,6 +3364,11 @@ sp_instr_cpop::print(String *str)
sp_instr_copen class functions sp_instr_copen class functions
*/ */
/**
@todo
Assert that we either have an error or a cursor
*/
int int
sp_instr_copen::execute(THD *thd, uint *nextp) sp_instr_copen::execute(THD *thd, uint *nextp)
{ {
@ -3670,24 +3690,23 @@ uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first)
} }
/* /**
Merge the list of tables used by some query into the multi-set of Merge the list of tables used by some query into the multi-set of
tables used by routine. tables used by routine.
SYNOPSIS @param thd thread context
merge_table_list() @param table table list
thd - thread context @param lex_for_tmp_check LEX of the query for which we are merging
table - table list table list.
lex_for_tmp_check - LEX of the query for which we are merging
table list.
NOTE @note
This method will use LEX provided to check whenever we are creating This method will use LEX provided to check whenever we are creating
temporary table and mark it as such in target multi-set. temporary table and mark it as such in target multi-set.
RETURN VALUE @retval
TRUE - Success TRUE Success
FALSE - Error @retval
FALSE Error
*/ */
bool bool
@ -3775,27 +3794,26 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
} }
/* /**
Add tables used by routine to the table list. Add tables used by routine to the table list.
SYNOPSIS
add_used_tables_to_table_list()
thd [in] Thread context
query_tables_last_ptr [in/out] Pointer to the next_global member of
last element of the list where tables
will be added (or to its root).
belong_to_view [in] Uppermost view which uses this routine,
0 if none.
DESCRIPTION
Converts multi-set of tables used by this routine to table list and adds Converts multi-set of tables used by this routine to table list and adds
this list to the end of table list specified by 'query_tables_last_ptr'. this list to the end of table list specified by 'query_tables_last_ptr'.
Elements of list will be allocated in PS memroot, so this list will be Elements of list will be allocated in PS memroot, so this list will be
persistent between PS executions. persistent between PS executions.
RETURN VALUE @param[in] thd Thread context
TRUE - if some elements were added, FALSE - otherwise. @param[in,out] query_tables_last_ptr Pointer to the next_global member of
last element of the list where tables
will be added (or to its root).
@param[in] belong_to_view Uppermost view which uses this routine,
0 if none.
@retval
TRUE if some elements were added
@retval
FALSE otherwise.
*/ */
bool bool
@ -3865,7 +3883,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
} }
/* /**
Simple function for adding an explicetly named (systems) table to Simple function for adding an explicetly named (systems) table to
the global table list, e.g. "mysql", "proc". the global table list, e.g. "mysql", "proc".
*/ */

View file

@ -109,7 +109,7 @@ public:
LEX_STRING m_db; LEX_STRING m_db;
LEX_STRING m_name; LEX_STRING m_name;
LEX_STRING m_qname; LEX_STRING m_qname;
/* /**
Key representing routine in the set of stored routines used by statement. Key representing routine in the set of stored routines used by statement.
Consists of 1-byte routine type and m_qname (which usually refences to Consists of 1-byte routine type and m_qname (which usually refences to
same buffer). Note that one must complete initialization of the key by same buffer). Note that one must complete initialization of the key by
@ -125,7 +125,7 @@ public:
m_qname.length= m_sroutines_key.length= 0; m_qname.length= m_sroutines_key.length= 0;
} }
/* /**
Creates temporary sp_name object from key, used mainly Creates temporary sp_name object from key, used mainly
for SP-cache lookups. for SP-cache lookups.
*/ */
@ -149,12 +149,12 @@ check_routine_name(LEX_STRING *ident);
class sp_head :private Query_arena class sp_head :private Query_arena
{ {
sp_head(const sp_head &); /* Prevent use of these */ sp_head(const sp_head &); /**< Prevent use of these */
void operator=(sp_head &); void operator=(sp_head &);
MEM_ROOT main_mem_root; MEM_ROOT main_mem_root;
public: public:
/* Possible values of m_flags */ /** Possible values of m_flags */
enum { enum {
HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s) MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
@ -170,16 +170,16 @@ public:
HAS_SQLCOM_FLUSH= 4096 HAS_SQLCOM_FLUSH= 4096
}; };
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */ /** TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
int m_type; int m_type;
uint m_flags; // Boolean attributes of a stored routine uint m_flags; // Boolean attributes of a stored routine
Create_field m_return_field_def; /* This is used for FUNCTIONs only. */ Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */
const char *m_tmp_query; // Temporary pointer to sub query string const char *m_tmp_query; ///< Temporary pointer to sub query string
st_sp_chistics *m_chistics; st_sp_chistics *m_chistics;
ulong m_sql_mode; // For SHOW CREATE and execution ulong m_sql_mode; ///< For SHOW CREATE and execution
LEX_STRING m_qname; // db.name LEX_STRING m_qname; ///< db.name
/** /**
Key representing routine in the set of stored routines used by statement. Key representing routine in the set of stored routines used by statement.
[routine_type]db.name [routine_type]db.name
@ -211,20 +211,20 @@ public:
longlong m_created; longlong m_created;
longlong m_modified; longlong m_modified;
/* Recursion level of the current SP instance. The levels are numbered from 0 */ /** Recursion level of the current SP instance. The levels are numbered from 0 */
ulong m_recursion_level; ulong m_recursion_level;
/* /**
A list of diferent recursion level instances for the same procedure. A list of diferent recursion level instances for the same procedure.
For every recursion level we have a sp_head instance. This instances For every recursion level we have a sp_head instance. This instances
connected in the list. The list ordered by increasing recursion level connected in the list. The list ordered by increasing recursion level
(m_recursion_level). (m_recursion_level).
*/ */
sp_head *m_next_cached_sp; sp_head *m_next_cached_sp;
/* /**
Pointer to the first element of the above list Pointer to the first element of the above list
*/ */
sp_head *m_first_instance; sp_head *m_first_instance;
/* /**
Pointer to the first free (non-INVOKED) routine in the list of Pointer to the first free (non-INVOKED) routine in the list of
cached instances for this SP. This pointer is set only for the first cached instances for this SP. This pointer is set only for the first
SP in the list of instences (see above m_first_cached_sp pointer). SP in the list of instences (see above m_first_cached_sp pointer).
@ -232,12 +232,12 @@ public:
For non-first instance value of this pointer meanless (point to itself); For non-first instance value of this pointer meanless (point to itself);
*/ */
sp_head *m_first_free_instance; sp_head *m_first_free_instance;
/* /**
Pointer to the last element in the list of instances of the SP. Pointer to the last element in the list of instances of the SP.
For non-first instance value of this pointer meanless (point to itself); For non-first instance value of this pointer meanless (point to itself);
*/ */
sp_head *m_last_cached_sp; sp_head *m_last_cached_sp;
/* /**
Set containing names of stored routines used by this routine. Set containing names of stored routines used by this routine.
Note that unlike elements of similar set for statement elements of this Note that unlike elements of similar set for statement elements of this
set are not linked in one list. Because of this we are able save memory set are not linked in one list. Because of this we are able save memory
@ -267,11 +267,11 @@ public:
sp_head(); sp_head();
// Initialize after we have reset mem_root /// Initialize after we have reset mem_root
void void
init(LEX *lex); init(LEX *lex);
/* Copy sp name from parser. */ /** Copy sp name from parser. */
void void
init_sp_name(THD *thd, sp_name *spname); init_sp_name(THD *thd, sp_name *spname);
@ -288,7 +288,7 @@ public:
virtual ~sp_head(); virtual ~sp_head();
// Free memory /// Free memory
void void
destroy(); destroy();
@ -325,33 +325,41 @@ public:
return i; return i;
} }
// Resets lex in 'thd' and keeps a copy of the old one. /*
Resets lex in 'thd' and keeps a copy of the old one.
@todo Conflicting comment in sp_head.cc
*/
bool bool
reset_lex(THD *thd); reset_lex(THD *thd);
// Restores lex in 'thd' from our copy, but keeps some status from the /**
// one in 'thd', like ptr, tables, fields, etc. Restores lex in 'thd' from our copy, but keeps some status from the
one in 'thd', like ptr, tables, fields, etc.
@todo Conflicting comment in sp_head.cc
*/
void void
restore_lex(THD *thd); restore_lex(THD *thd);
// Put the instruction on the backpatch list, associated with the label. /// Put the instruction on the backpatch list, associated with the label.
void void
push_backpatch(sp_instr *, struct sp_label *); push_backpatch(sp_instr *, struct sp_label *);
// Update all instruction with this label in the backpatch list to /// Update all instruction with this label in the backpatch list to
// the current position. /// the current position.
void void
backpatch(struct sp_label *); backpatch(struct sp_label *);
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr. /// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
void void
new_cont_backpatch(sp_instr_opt_meta *i); new_cont_backpatch(sp_instr_opt_meta *i);
// Add an instruction to the current level /// Add an instruction to the current level
void void
add_cont_backpatch(sp_instr_opt_meta *i); add_cont_backpatch(sp_instr_opt_meta *i);
// Backpatch (and pop) the current level to the current position. /// Backpatch (and pop) the current level to the current position.
void void
do_cont_backpatch(); do_cont_backpatch();
@ -414,7 +422,7 @@ public:
TABLE_LIST ***query_tables_last_ptr, TABLE_LIST ***query_tables_last_ptr,
TABLE_LIST *belong_to_view); TABLE_LIST *belong_to_view);
/* /**
Check if this stored routine contains statements disallowed Check if this stored routine contains statements disallowed
in a stored function or trigger, and set an appropriate error message in a stored function or trigger, and set an appropriate error message
if this is the case. if this is the case.
@ -463,19 +471,19 @@ public:
private: private:
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root
THD *m_thd; // Set if we have reset mem_root THD *m_thd; ///< Set if we have reset mem_root
sp_pcontext *m_pcont; // Parse context sp_pcontext *m_pcont; ///< Parse context
List<LEX> m_lex; // Temp. store for the other lex List<LEX> m_lex; ///< Temp. store for the other lex
DYNAMIC_ARRAY m_instr; // The "instructions" DYNAMIC_ARRAY m_instr; ///< The "instructions"
typedef struct typedef struct
{ {
struct sp_label *lab; struct sp_label *lab;
sp_instr *instr; sp_instr *instr;
} bp_t; } bp_t;
List<bp_t> m_backpatch; // Instructions needing backpatching List<bp_t> m_backpatch; ///< Instructions needing backpatching
/* /**
We need a special list for backpatching of instructions with a continue We need a special list for backpatching of instructions with a continue
destination (in the case of a continue handler catching an error in destination (in the case of a continue handler catching an error in
the test), since it would otherwise interfere with the normal backpatch the test), since it would otherwise interfere with the normal backpatch
@ -483,15 +491,16 @@ private:
which are to be patched differently. which are to be patched differently.
Since these occur in a more restricted way (always the same "level" in Since these occur in a more restricted way (always the same "level" in
the code), we don't need the label. the code), we don't need the label.
*/ */
List<sp_instr_opt_meta> m_cont_backpatch; List<sp_instr_opt_meta> m_cont_backpatch;
uint m_cont_level; // The current cont. backpatch level uint m_cont_level; // The current cont. backpatch level
/* /**
Multi-set representing optimized list of tables to be locked by this Multi-set representing optimized list of tables to be locked by this
routine. Does not include tables which are used by invoked routines. routine. Does not include tables which are used by invoked routines.
Note: for prelocking-free SPs this multiset is constructed too. @note
For prelocking-free SPs this multiset is constructed too.
We do so because the same instance of sp_head may be called both We do so because the same instance of sp_head may be called both
in prelocked mode and in non-prelocked mode. in prelocked mode and in non-prelocked mode.
*/ */
@ -506,7 +515,7 @@ private:
*/ */
void opt_mark(); void opt_mark();
/* /**
Merge the list of tables used by query into the multi-set of tables used Merge the list of tables used by query into the multi-set of tables used
by routine. by routine.
*/ */
@ -520,16 +529,16 @@ private:
class sp_instr :public Query_arena, public Sql_alloc class sp_instr :public Query_arena, public Sql_alloc
{ {
sp_instr(const sp_instr &); /* Prevent use of these */ sp_instr(const sp_instr &); /**< Prevent use of these */
void operator=(sp_instr &); void operator=(sp_instr &);
public: public:
uint marked; uint marked;
uint m_ip; // My index uint m_ip; ///< My index
sp_pcontext *m_ctx; // My parse context sp_pcontext *m_ctx; ///< My parse context
// Should give each a name or type code for debugging purposes? /// Should give each a name or type code for debugging purposes?
sp_instr(uint ip, sp_pcontext *ctx) sp_instr(uint ip, sp_pcontext *ctx)
:Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) :Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx)
{} {}
@ -538,21 +547,19 @@ public:
{ free_items(); } { free_items(); }
/* /**
Execute this instruction Execute this instruction
SYNOPSIS
execute() @param thd Thread handle
thd Thread handle @param[out] nextp index of the next instruction to execute. (For most
nextp OUT index of the next instruction to execute. (For most instructions this will be the instruction following this
instructions this will be the instruction following this one). Note that this parameter is undefined in case of
one). Note that this parameter is undefined in case of errors, use get_cont_dest() to find the continuation
errors, use get_cont_dest() to find the continuation instruction for CONTINUE error handlers.
instruction for CONTINUE error handlers.
@retval 0 on success,
RETURN @retval other if some error occured
0 on success,
other if some error occurred
*/ */
virtual int execute(THD *thd, uint *nextp) = 0; virtual int execute(THD *thd, uint *nextp) = 0;
@ -590,7 +597,7 @@ public:
virtual void backpatch(uint dest, sp_pcontext *dst_ctx) virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
{} {}
/* /**
Mark this instruction as reachable during optimization and return the Mark this instruction as reachable during optimization and return the
index to the next instruction. Jump instruction will add their index to the next instruction. Jump instruction will add their
destination to the leads list. destination to the leads list.
@ -601,7 +608,7 @@ public:
return m_ip+1; return m_ip+1;
} }
/* /**
Short-cut jumps to jumps during optimization. This is used by the Short-cut jumps to jumps during optimization. This is used by the
jump instructions' opt_mark() methods. 'start' is the starting point, jump instructions' opt_mark() methods. 'start' is the starting point,
used to prevent the mark sweep from looping for ever. Return the used to prevent the mark sweep from looping for ever. Return the
@ -612,7 +619,7 @@ public:
return m_ip; return m_ip;
} }
/* /**
Inform the instruction that it has been moved during optimization. Inform the instruction that it has been moved during optimization.
Most instructions will simply update its index, but jump instructions Most instructions will simply update its index, but jump instructions
must also take care of their destination pointers. Forward jumps get must also take care of their destination pointers. Forward jumps get
@ -626,7 +633,7 @@ public:
}; // class sp_instr : public Sql_alloc }; // class sp_instr : public Sql_alloc
/* /**
Auxilary class to which instructions delegate responsibility Auxilary class to which instructions delegate responsibility
for handling LEX and preparations before executing statement for handling LEX and preparations before executing statement
or calculating complex expression. or calculating complex expression.
@ -634,13 +641,14 @@ public:
Exist mainly to avoid having double hierarchy between instruction Exist mainly to avoid having double hierarchy between instruction
classes. classes.
TODO: Add ability to not store LEX and do any preparations if @todo
expression used is simple. Add ability to not store LEX and do any preparations if
expression used is simple.
*/ */
class sp_lex_keeper class sp_lex_keeper
{ {
/* Prevent use of these */ /** Prevent use of these */
sp_lex_keeper(const sp_lex_keeper &); sp_lex_keeper(const sp_lex_keeper &);
void operator=(sp_lex_keeper &); void operator=(sp_lex_keeper &);
public: public:
@ -660,10 +668,12 @@ public:
} }
} }
/* /**
Prepare execution of instruction using LEX, if requested check whenever Prepare execution of instruction using LEX, if requested check whenever
we have read access to tables used and open/lock them, call instruction's we have read access to tables used and open/lock them, call instruction's
exec_core() method, perform cleanup afterwards. exec_core() method, perform cleanup afterwards.
@todo Conflicting comment in sp_head.cc
*/ */
int reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables, int reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables,
sp_instr* instr); sp_instr* instr);
@ -680,7 +690,7 @@ public:
private: private:
LEX *m_lex; LEX *m_lex;
/* /**
Indicates whenever this sp_lex_keeper instance responsible Indicates whenever this sp_lex_keeper instance responsible
for LEX deletion. for LEX deletion.
*/ */
@ -693,13 +703,13 @@ private:
prelocked mode itself. prelocked mode itself.
*/ */
/* /**
List of additional tables this statement needs to lock when it List of additional tables this statement needs to lock when it
enters/leaves prelocked mode on its own. enters/leaves prelocked mode on its own.
*/ */
TABLE_LIST *prelocking_tables; TABLE_LIST *prelocking_tables;
/* /**
The value m_lex->query_tables_own_last should be set to this when the The value m_lex->query_tables_own_last should be set to this when the
statement enters/leaves prelocked mode on its own. statement enters/leaves prelocked mode on its own.
*/ */
@ -707,17 +717,17 @@ private:
}; };
// /**
// Call out to some prepared SQL statement. Call out to some prepared SQL statement.
// */
class sp_instr_stmt : public sp_instr class sp_instr_stmt : public sp_instr
{ {
sp_instr_stmt(const sp_instr_stmt &); /* Prevent use of these */ sp_instr_stmt(const sp_instr_stmt &); /**< Prevent use of these */
void operator=(sp_instr_stmt &); void operator=(sp_instr_stmt &);
public: public:
LEX_STRING m_query; // For thd->query LEX_STRING m_query; ///< For thd->query
sp_instr_stmt(uint ip, sp_pcontext *ctx, LEX *lex) sp_instr_stmt(uint ip, sp_pcontext *ctx, LEX *lex)
: sp_instr(ip, ctx), m_lex_keeper(lex, TRUE) : sp_instr(ip, ctx), m_lex_keeper(lex, TRUE)
@ -744,7 +754,7 @@ private:
class sp_instr_set : public sp_instr class sp_instr_set : public sp_instr
{ {
sp_instr_set(const sp_instr_set &); /* Prevent use of these */ sp_instr_set(const sp_instr_set &); /**< Prevent use of these */
void operator=(sp_instr_set &); void operator=(sp_instr_set &);
public: public:
@ -767,15 +777,15 @@ public:
private: private:
uint m_offset; // Frame offset uint m_offset; ///< Frame offset
Item *m_value; Item *m_value;
enum enum_field_types m_type; // The declared type enum enum_field_types m_type; ///< The declared type
sp_lex_keeper m_lex_keeper; sp_lex_keeper m_lex_keeper;
}; // class sp_instr_set : public sp_instr }; // class sp_instr_set : public sp_instr
/* /**
Set NEW/OLD row field value instruction. Used in triggers. Set NEW/OLD row field value instruction. Used in triggers.
*/ */
class sp_instr_set_trigger_field : public sp_instr class sp_instr_set_trigger_field : public sp_instr
@ -809,18 +819,19 @@ private:
}; // class sp_instr_trigger_field : public sp_instr }; // class sp_instr_trigger_field : public sp_instr
/* /**
An abstract class for all instructions with destinations that An abstract class for all instructions with destinations that
needs to be updated by the optimizer. needs to be updated by the optimizer.
Even if not all subclasses will use both the normal destination and Even if not all subclasses will use both the normal destination and
the continuation destination, we put them both here for simplicity. the continuation destination, we put them both here for simplicity.
*/ */
class sp_instr_opt_meta : public sp_instr class sp_instr_opt_meta : public sp_instr
{ {
public: public:
uint m_dest; // Where we will go uint m_dest; ///< Where we will go
uint m_cont_dest; // Where continue handlers will go uint m_cont_dest; ///< Where continue handlers will go
sp_instr_opt_meta(uint ip, sp_pcontext *ctx) sp_instr_opt_meta(uint ip, sp_pcontext *ctx)
: sp_instr(ip, ctx), : sp_instr(ip, ctx),
@ -842,14 +853,14 @@ public:
protected: protected:
sp_instr *m_optdest; // Used during optimization sp_instr *m_optdest; ///< Used during optimization
sp_instr *m_cont_optdest; // Used during optimization sp_instr *m_cont_optdest; ///< Used during optimization
}; // class sp_instr_opt_meta : public sp_instr }; // class sp_instr_opt_meta : public sp_instr
class sp_instr_jump : public sp_instr_opt_meta class sp_instr_jump : public sp_instr_opt_meta
{ {
sp_instr_jump(const sp_instr_jump &); /* Prevent use of these */ sp_instr_jump(const sp_instr_jump &); /**< Prevent use of these */
void operator=(sp_instr_jump &); void operator=(sp_instr_jump &);
public: public:
@ -881,7 +892,7 @@ public:
m_dest= dest; m_dest= dest;
} }
/* /**
Update the destination; used by the optimizer. Update the destination; used by the optimizer.
*/ */
virtual void set_destination(uint old_dest, uint new_dest) virtual void set_destination(uint old_dest, uint new_dest)
@ -895,7 +906,7 @@ public:
class sp_instr_jump_if_not : public sp_instr_jump class sp_instr_jump_if_not : public sp_instr_jump
{ {
sp_instr_jump_if_not(const sp_instr_jump_if_not &); /* Prevent use of these */ sp_instr_jump_if_not(const sp_instr_jump_if_not &); /**< Prevent use of these */
void operator=(sp_instr_jump_if_not &); void operator=(sp_instr_jump_if_not &);
public: public:
@ -921,7 +932,7 @@ public:
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
/* Override sp_instr_jump's shortcut; we stop here */ /** Override sp_instr_jump's shortcut; we stop here */
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
{ {
return m_ip; return m_ip;
@ -938,7 +949,7 @@ public:
private: private:
Item *m_expr; // The condition Item *m_expr; ///< The condition
sp_lex_keeper m_lex_keeper; sp_lex_keeper m_lex_keeper;
}; // class sp_instr_jump_if_not : public sp_instr_jump }; // class sp_instr_jump_if_not : public sp_instr_jump
@ -946,7 +957,7 @@ private:
class sp_instr_freturn : public sp_instr class sp_instr_freturn : public sp_instr
{ {
sp_instr_freturn(const sp_instr_freturn &); /* Prevent use of these */ sp_instr_freturn(const sp_instr_freturn &); /**< Prevent use of these */
void operator=(sp_instr_freturn &); void operator=(sp_instr_freturn &);
public: public:
@ -983,7 +994,7 @@ protected:
class sp_instr_hpush_jump : public sp_instr_jump class sp_instr_hpush_jump : public sp_instr_jump
{ {
sp_instr_hpush_jump(const sp_instr_hpush_jump &); /* Prevent use of these */ sp_instr_hpush_jump(const sp_instr_hpush_jump &); /**< Prevent use of these */
void operator=(sp_instr_hpush_jump &); void operator=(sp_instr_hpush_jump &);
public: public:
@ -1005,7 +1016,7 @@ public:
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads); virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
/* Override sp_instr_jump's shortcut; we stop here. */ /** Override sp_instr_jump's shortcut; we stop here. */
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
{ {
return m_ip; return m_ip;
@ -1018,7 +1029,7 @@ public:
private: private:
int m_type; // Handler type int m_type; ///< Handler type
uint m_frame; uint m_frame;
List<struct sp_cond_type> m_cond; List<struct sp_cond_type> m_cond;
@ -1027,7 +1038,7 @@ private:
class sp_instr_hpop : public sp_instr class sp_instr_hpop : public sp_instr
{ {
sp_instr_hpop(const sp_instr_hpop &); /* Prevent use of these */ sp_instr_hpop(const sp_instr_hpop &); /**< Prevent use of these */
void operator=(sp_instr_hpop &); void operator=(sp_instr_hpop &);
public: public:
@ -1052,7 +1063,7 @@ private:
class sp_instr_hreturn : public sp_instr_jump class sp_instr_hreturn : public sp_instr_jump
{ {
sp_instr_hreturn(const sp_instr_hreturn &); /* Prevent use of these */ sp_instr_hreturn(const sp_instr_hreturn &); /**< Prevent use of these */
void operator=(sp_instr_hreturn &); void operator=(sp_instr_hreturn &);
public: public:
@ -1083,10 +1094,10 @@ private:
}; // class sp_instr_hreturn : public sp_instr_jump }; // class sp_instr_hreturn : public sp_instr_jump
/* This is DECLARE CURSOR */ /** This is DECLARE CURSOR */
class sp_instr_cpush : public sp_instr class sp_instr_cpush : public sp_instr
{ {
sp_instr_cpush(const sp_instr_cpush &); /* Prevent use of these */ sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */
void operator=(sp_instr_cpush &); void operator=(sp_instr_cpush &);
public: public:
@ -1102,7 +1113,7 @@ public:
virtual void print(String *str); virtual void print(String *str);
/* /**
This call is used to cleanup the instruction when a sensitive This call is used to cleanup the instruction when a sensitive
cursor is closed. For now stored procedures always use materialized cursor is closed. For now stored procedures always use materialized
cursors and the call is not used. cursors and the call is not used.
@ -1111,14 +1122,14 @@ public:
private: private:
sp_lex_keeper m_lex_keeper; sp_lex_keeper m_lex_keeper;
uint m_cursor; /* Frame offset (for debugging) */ uint m_cursor; /**< Frame offset (for debugging) */
}; // class sp_instr_cpush : public sp_instr }; // class sp_instr_cpush : public sp_instr
class sp_instr_cpop : public sp_instr class sp_instr_cpop : public sp_instr
{ {
sp_instr_cpop(const sp_instr_cpop &); /* Prevent use of these */ sp_instr_cpop(const sp_instr_cpop &); /**< Prevent use of these */
void operator=(sp_instr_cpop &); void operator=(sp_instr_cpop &);
public: public:
@ -1143,7 +1154,7 @@ private:
class sp_instr_copen : public sp_instr class sp_instr_copen : public sp_instr
{ {
sp_instr_copen(const sp_instr_copen &); /* Prevent use of these */ sp_instr_copen(const sp_instr_copen &); /**< Prevent use of these */
void operator=(sp_instr_copen &); void operator=(sp_instr_copen &);
public: public:
@ -1163,14 +1174,14 @@ public:
private: private:
uint m_cursor; // Stack index uint m_cursor; ///< Stack index
}; // class sp_instr_copen : public sp_instr_stmt }; // class sp_instr_copen : public sp_instr_stmt
class sp_instr_cclose : public sp_instr class sp_instr_cclose : public sp_instr
{ {
sp_instr_cclose(const sp_instr_cclose &); /* Prevent use of these */ sp_instr_cclose(const sp_instr_cclose &); /**< Prevent use of these */
void operator=(sp_instr_cclose &); void operator=(sp_instr_cclose &);
public: public:
@ -1195,7 +1206,7 @@ private:
class sp_instr_cfetch : public sp_instr class sp_instr_cfetch : public sp_instr
{ {
sp_instr_cfetch(const sp_instr_cfetch &); /* Prevent use of these */ sp_instr_cfetch(const sp_instr_cfetch &); /**< Prevent use of these */
void operator=(sp_instr_cfetch &); void operator=(sp_instr_cfetch &);
public: public:
@ -1228,7 +1239,7 @@ private:
class sp_instr_error : public sp_instr class sp_instr_error : public sp_instr
{ {
sp_instr_error(const sp_instr_error &); /* Prevent use of these */ sp_instr_error(const sp_instr_error &); /**< Prevent use of these */
void operator=(sp_instr_error &); void operator=(sp_instr_error &);
public: public:

View file

@ -1982,7 +1982,7 @@ static void relink_unused(TABLE *table)
/** /**
@brief Prepare an open merge table for close. Prepare an open merge table for close.
@param[in] thd thread context @param[in] thd thread context
@param[in] table table to prepare @param[in] table table to prepare
@ -2053,8 +2053,8 @@ static void unlink_open_merge(THD *thd, TABLE *table, TABLE ***prev_pp)
/** /**
@brief Remove all instances of table from thread's open list and Remove all instances of table from thread's open list and
table cache. table cache.
@param thd Thread context @param thd Thread context
@param find Table to remove @param find Table to remove
@ -2117,7 +2117,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
/** /**
@brief Auxiliary routine which closes and drops open table. Auxiliary routine which closes and drops open table.
@param thd Thread handle @param thd Thread handle
@param table TABLE object for table to be dropped @param table TABLE object for table to be dropped
@ -2324,9 +2324,9 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
/** /**
@brief Create and insert into table cache placeholder for table Create and insert into table cache placeholder for table
which will prevent its opening (or creation) (a.k.a lock which will prevent its opening (or creation) (a.k.a lock
table name). table name).
@param thd Thread context @param thd Thread context
@param key Table cache key for name to be locked @param key Table cache key for name to be locked
@ -2375,8 +2375,8 @@ TABLE *table_cache_insert_placeholder(THD *thd, const char *key,
/** /**
@brief Obtain an exclusive name lock on the table if it is not cached Obtain an exclusive name lock on the table if it is not cached
in the table cache. in the table cache.
@param thd Thread context @param thd Thread context
@param db Name of database @param db Name of database
@ -2427,8 +2427,8 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db,
/** /**
@brief Check that table exists in table definition cache, on disk Check that table exists in table definition cache, on disk
or in some storage engine. or in some storage engine.
@param thd Thread context @param thd Thread context
@param table Table list element @param table Table list element
@ -3142,8 +3142,8 @@ bool reopen_table(TABLE *table)
/** /**
@brief Close all instances of a table open by this thread and replace Close all instances of a table open by this thread and replace
them with exclusive name-locks. them with exclusive name-locks.
@param thd Thread context @param thd Thread context
@param db Database name for the table to be closed @param db Database name for the table to be closed
@ -3212,7 +3212,7 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
/** /**
@brief Reattach MERGE children after reopen. Reattach MERGE children after reopen.
@param[in] thd thread context @param[in] thd thread context
@param[in,out] err_tables_p pointer to pointer of tables in error @param[in,out] err_tables_p pointer to pointer of tables in error
@ -3268,7 +3268,7 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
/** /**
@brief Reopen all tables with closed data files. Reopen all tables with closed data files.
@param thd Thread context @param thd Thread context
@param get_locks Should we get locks after reopening tables ? @param get_locks Should we get locks after reopening tables ?
@ -3412,8 +3412,8 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
/** /**
@brief Close handlers for tables in list, but leave the TABLE structure Close handlers for tables in list, but leave the TABLE structure
intact so that we can re-open these quickly. intact so that we can re-open these quickly.
@param thd Thread context @param thd Thread context
@param table Head of the list of TABLE objects @param table Head of the list of TABLE objects

View file

@ -1524,7 +1524,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
/** /**
@brief Synchronize the thread with any flushing operations. Synchronize the thread with any flushing operations.
This helper function is called whenever a thread needs to operate on the This helper function is called whenever a thread needs to operate on the
query cache structure (example: during invalidation). If a table flush is in query cache structure (example: during invalidation). If a table flush is in
@ -1565,7 +1565,7 @@ void Query_cache::wait_while_table_flush_is_in_progress(bool *interrupt)
/** /**
@brief Remove all cached queries that uses the given database Remove all cached queries that uses the given database.
*/ */
void Query_cache::invalidate(char *db) void Query_cache::invalidate(char *db)
@ -1675,8 +1675,8 @@ void Query_cache::flush()
/** /**
@brief Rearrange the memory blocks and join result in cache in 1 block (if Rearrange the memory blocks and join result in cache in 1 block (if
result length > join_limit) result length > join_limit)
@param[in] join_limit If the minimum length of a result block to be joined. @param[in] join_limit If the minimum length of a result block to be joined.
@param[in] iteration_limit The maximum number of packing and joining @param[in] iteration_limit The maximum number of packing and joining
@ -1946,7 +1946,7 @@ void Query_cache::make_disabled()
/** /**
@class Query_cache @class Query_cache
@brief Free all resources allocated by the cache. Free all resources allocated by the cache.
This function frees all resources allocated by the cache. You This function frees all resources allocated by the cache. You
have to call init_cache() before using the cache again. This function have to call init_cache() before using the cache again. This function
@ -1970,7 +1970,7 @@ void Query_cache::free_cache()
/** /**
@brief Flush the cache. Flush the cache.
This function will flush cache contents. It assumes we have This function will flush cache contents. It assumes we have
'structure_guard_mutex' locked. The function sets the m_cache_status flag and 'structure_guard_mutex' locked. The function sets the m_cache_status flag and
@ -2516,7 +2516,7 @@ Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
} }
/** /**
@brief Invalidate a linked list of query cache blocks. Invalidate a linked list of query cache blocks.
Each block tries to aquire a block level lock before Each block tries to aquire a block level lock before
free_query is a called. This function will in turn affect free_query is a called. This function will in turn affect
@ -2684,7 +2684,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
/** /**
@brief Insert used table name into the cache. Insert used table name into the cache.
@return Error status @return Error status
@retval FALSE On error @retval FALSE On error
@ -3413,8 +3413,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
/** /**
@brief Rearrange all memory blocks so that free memory joins at the Rearrange all memory blocks so that free memory joins at the
'bottom' of the allocated memory block containing all cache data. 'bottom' of the allocated memory block containing all cache data.
@see Query_cache::pack(ulong join_limit, uint iteration_limit) @see Query_cache::pack(ulong join_limit, uint iteration_limit)
*/ */
@ -4028,7 +4028,7 @@ void Query_cache::tables_dump()
/** /**
@brief Checks integrity of the various linked lists Checks integrity of the various linked lists
@return Error status code @return Error status code
@retval FALSE Query cache is operational. @retval FALSE Query cache is operational.

View file

@ -66,8 +66,8 @@ struct Query_cache_result;
class Query_cache; class Query_cache;
/** /**
@brief This class represents a node in the linked chain of queries This class represents a node in the linked chain of queries
belonging to one table. belonging to one table.
@note The root of this linked list is not a query-type block, but the table- @note The root of this linked list is not a query-type block, but the table-
type block which all queries has in common. type block which all queries has in common.

View file

@ -952,7 +952,7 @@ void THD::cleanup_after_query()
/** /**
Create a LEX_STRING in this connection Create a LEX_STRING in this connection.
@param lex_str pointer to LEX_STRING object to be initialized @param lex_str pointer to LEX_STRING object to be initialized
@param str initializer to be copied into lex_str @param str initializer to be copied into lex_str

View file

@ -77,10 +77,10 @@ typedef struct st_user_var_events
was actually changed or not. was actually changed or not.
*/ */
typedef struct st_copy_info { typedef struct st_copy_info {
ha_rows records; /* Number of processed records */ ha_rows records; /**< Number of processed records */
ha_rows deleted; /* Number of deleted records */ ha_rows deleted; /**< Number of deleted records */
ha_rows updated; /* Number of updated records */ ha_rows updated; /**< Number of updated records */
ha_rows copied; /* Number of copied records */ ha_rows copied; /**< Number of copied records */
ha_rows error_count; ha_rows error_count;
ha_rows touched; /* Number of touched records */ ha_rows touched; /* Number of touched records */
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
@ -1046,14 +1046,17 @@ public:
*/ */
char *catalog; char *catalog;
/* /**
WARNING: some members of THD (currently 'Statement::db', @note
Some members of THD (currently 'Statement::db',
'catalog' and 'query') are set and alloced by the slave SQL thread 'catalog' and 'query') are set and alloced by the slave SQL thread
(for the THD of that thread); that thread is (and must remain, for now) (for the THD of that thread); that thread is (and must remain, for now)
the only responsible for freeing these 3 members. If you add members the only responsible for freeing these 3 members. If you add members
here, and you add code to set them in replication, don't forget to here, and you add code to set them in replication, don't forget to
free_them_and_set_them_to_0 in replication properly. For details see free_them_and_set_them_to_0 in replication properly. For details see
the 'err:' label of the handle_slave_sql() in sql/slave.cc. the 'err:' label of the handle_slave_sql() in sql/slave.cc.
@see handle_slave_sql
*/ */
Security_context main_security_ctx; Security_context main_security_ctx;

View file

@ -24,9 +24,9 @@
Declarations. Declarations.
****************************************************************************/ ****************************************************************************/
/* /**
Sensitive_cursor -- a sensitive non-materialized server side Sensitive_cursor -- a sensitive non-materialized server side
cursor An instance of this class cursor has its own runtime cursor. An instance of this class cursor has its own runtime
state -- list of used items and memory root for runtime memory, state -- list of used items and memory root for runtime memory,
open and locked tables, change list for the changes of the open and locked tables, change list for the changes of the
parsed tree. This state is freed when the cursor is closed. parsed tree. This state is freed when the cursor is closed.
@ -69,7 +69,7 @@ public:
}; };
/* /**
Materialized_cursor -- an insensitive materialized server-side Materialized_cursor -- an insensitive materialized server-side
cursor. The result set of this cursor is saved in a temporary cursor. The result set of this cursor is saved in a temporary
table at open. The cursor itself is simply an interface for the table at open. The cursor itself is simply an interface for the
@ -96,7 +96,7 @@ public:
}; };
/* /**
Select_materialize -- a mediator between a cursor query and the Select_materialize -- a mediator between a cursor query and the
protocol. In case we were not able to open a non-materialzed protocol. In case we were not able to open a non-materialzed
cursor, it creates an internal temporary HEAP table, and insert cursor, it creates an internal temporary HEAP table, and insert
@ -107,7 +107,7 @@ public:
class Select_materialize: public select_union class Select_materialize: public select_union
{ {
select_result *result; /* the result object of the caller (PS or SP) */ select_result *result; /**< the result object of the caller (PS or SP) */
public: public:
Select_materialize(select_result *result_arg) :result(result_arg) {} Select_materialize(select_result *result_arg) :result(result_arg) {}
virtual bool send_fields(List<Item> &list, uint flags); virtual bool send_fields(List<Item> &list, uint flags);
@ -116,22 +116,21 @@ public:
/**************************************************************************/ /**************************************************************************/
/* /**
Attempt to open a materialized or non-materialized cursor. Attempt to open a materialized or non-materialized cursor.
SYNOPSIS @param thd thread handle
mysql_open_cursor() @param[in] flags create a materialized cursor or not
thd thread handle @param[in] result result class of the caller used as a destination
flags [in] create a materialized cursor or not for the rows fetched from the cursor
result [in] result class of the caller used as a destination @param[out] pcursor a pointer to store a pointer to cursor in
for the rows fetched from the cursor
pcursor [out] a pointer to store a pointer to cursor in
RETURN VALUE @retval
0 the query has been successfully executed; in this 0 the query has been successfully executed; in this
case pcursor may or may not contain case pcursor may or may not contain
a pointer to an open cursor. a pointer to an open cursor.
non-zero an error, 'pcursor' has been left intact. @retval
non-zero an error, 'pcursor' has been left intact.
*/ */
int mysql_open_cursor(THD *thd, uint flags, select_result *result, int mysql_open_cursor(THD *thd, uint flags, select_result *result,
@ -279,6 +278,14 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
} }
/**
Save THD state into cursor.
@todo
- XXX: thd->locked_tables is not changed.
- What problems can we have with it if cursor is open?
- TODO: must be fixed because of the prelocked mode.
*/
void void
Sensitive_cursor::post_open(THD *thd) Sensitive_cursor::post_open(THD *thd)
{ {
@ -334,6 +341,10 @@ Sensitive_cursor::post_open(THD *thd)
} }
/**
bzero cursor state in THD.
*/
void void
Sensitive_cursor::reset_thd(THD *thd) Sensitive_cursor::reset_thd(THD *thd)
{ {
@ -393,20 +404,13 @@ Sensitive_cursor::open(JOIN *join_arg)
} }
/* /**
SYNOPSIS Fetch next num_rows rows from the cursor and send them to the client.
Sensitive_cursor::fetch()
num_rows fetch up to this number of rows (maybe less)
DESCRIPTION Precondition:
Fetch next num_rows rows from the cursor and send them to the client - Sensitive_cursor is open
Precondition: @param num_rows fetch up to this number of rows (maybe less)
Sensitive_cursor is open
RETURN VALUES:
none, this function will send OK to the clinet or set an error
message in THD
*/ */
void void
@ -478,6 +482,11 @@ Sensitive_cursor::fetch(ulong num_rows)
} }
/**
@todo
Another hack: we need to set THD state as if in a fetch to be
able to call stmt close.
*/
void void
Sensitive_cursor::close() Sensitive_cursor::close()
{ {
@ -579,10 +588,9 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
} }
/* /**
Fetch up to the given number of rows from a materialized cursor. Fetch up to the given number of rows from a materialized cursor.
DESCRIPTION
Precondition: the cursor is open. Precondition: the cursor is open.
If the cursor points after the last row, the fetch will automatically If the cursor points after the last row, the fetch will automatically
@ -590,10 +598,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
and probably should be improved to return and probably should be improved to return
SERVER_STATUS_LAST_ROW_SENT along with the last row. SERVER_STATUS_LAST_ROW_SENT along with the last row.
RETURN VALUE
none, in case of success the row is sent to the client, otherwise
an error message is set in THD
*/ */
void Materialized_cursor::fetch(ulong num_rows) void Materialized_cursor::fetch(ulong num_rows)

View file

@ -20,12 +20,14 @@
#pragma interface /* gcc class interface */ #pragma interface /* gcc class interface */
#endif #endif
/* /**
@file
Declarations for implementation of server side cursors. Only Declarations for implementation of server side cursors. Only
read-only non-scrollable cursors are currently implemented. read-only non-scrollable cursors are currently implemented.
*/ */
/* /**
Server_side_cursor -- an interface for materialized and Server_side_cursor -- an interface for materialized and
sensitive (non-materialized) implementation of cursors. All sensitive (non-materialized) implementation of cursors. All
cursors are self-contained (created in their own memory root). cursors are self-contained (created in their own memory root).
@ -36,7 +38,7 @@
class Server_side_cursor: protected Query_arena, public Sql_alloc class Server_side_cursor: protected Query_arena, public Sql_alloc
{ {
protected: protected:
/* Row destination used for fetch */ /** Row destination used for fetch */
select_result *result; select_result *result;
public: public:
Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg) Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg)
@ -58,8 +60,7 @@ int mysql_open_cursor(THD *thd, uint flags,
select_result *result, select_result *result,
Server_side_cursor **res); Server_side_cursor **res);
/* Possible values for flags */ /** Possible values for flags */
enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 }; enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 };
#endif /* _sql_cusor_h_ */ #endif /* _sql_cusor_h_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* classes to use when handling where clause */ /**
@file
@brief
classes to use when handling where clause
*/
#ifdef USE_PRAGMA_INTERFACE #ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
@ -25,12 +30,12 @@
typedef struct keyuse_t { typedef struct keyuse_t {
TABLE *table; TABLE *table;
Item *val; /* or value if no field */ Item *val; /**< or value if no field */
table_map used_tables; table_map used_tables;
uint key, keypart, optimize; uint key, keypart, optimize;
key_part_map keypart_map; key_part_map keypart_map;
ha_rows ref_table_rows; ha_rows ref_table_rows;
/* /**
If true, the comparison this value was created from will not be If true, the comparison this value was created from will not be
satisfied if val has NULL 'value'. satisfied if val has NULL 'value'.
*/ */
@ -53,13 +58,13 @@ class store_key;
typedef struct st_table_ref typedef struct st_table_ref
{ {
bool key_err; bool key_err;
uint key_parts; // num of ... uint key_parts; ///< num of ...
uint key_length; // length of key_buff uint key_length; ///< length of key_buff
int key; // key no int key; ///< key no
uchar *key_buff; // value to look for with key uchar *key_buff; ///< value to look for with key
uchar *key_buff2; // key_buff+key_length uchar *key_buff2; ///< key_buff+key_length
store_key **key_copy; // store_key **key_copy; //
Item **items; // val()'s for each keypart Item **items; ///< val()'s for each keypart
/* /*
Array of pointers to trigger variables. Some/all of the pointers may be Array of pointers to trigger variables. Some/all of the pointers may be
NULL. The ref access can be used iff NULL. The ref access can be used iff
@ -72,18 +77,18 @@ typedef struct st_table_ref
underlying conditions is switched off (see subquery code for more details) underlying conditions is switched off (see subquery code for more details)
*/ */
bool **cond_guards; bool **cond_guards;
/* /**
(null_rejecting & (1<<i)) means the condition is '=' and no matching (null_rejecting & (1<<i)) means the condition is '=' and no matching
rows will be produced if items[i] IS NULL (see add_not_null_conds()) rows will be produced if items[i] IS NULL (see add_not_null_conds())
*/ */
key_part_map null_rejecting; key_part_map null_rejecting;
table_map depend_map; // Table depends on these tables. table_map depend_map; ///< Table depends on these tables.
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */ /* null byte position in the key_buf. Used for REF_OR_NULL optimization */
uchar *null_ref_key; uchar *null_ref_key;
} TABLE_REF; } TABLE_REF;
/* /**
CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
table table
*/ */
@ -136,18 +141,18 @@ Next_select_func setup_end_select_func(JOIN *join);
typedef struct st_join_table { typedef struct st_join_table {
st_join_table() {} /* Remove gcc warning */ st_join_table() {} /* Remove gcc warning */
TABLE *table; TABLE *table;
KEYUSE *keyuse; /* pointer to first used key */ KEYUSE *keyuse; /**< pointer to first used key */
SQL_SELECT *select; SQL_SELECT *select;
COND *select_cond; COND *select_cond;
QUICK_SELECT_I *quick; QUICK_SELECT_I *quick;
Item **on_expr_ref; /* pointer to the associated on expression */ Item **on_expr_ref; /**< pointer to the associated on expression */
COND_EQUAL *cond_equal; /* multiple equalities for the on expression */ COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
st_join_table *first_inner; /* first inner table for including outerjoin */ st_join_table *first_inner; /**< first inner table for including outerjoin */
bool found; /* true after all matches or null complement */ bool found; /**< true after all matches or null complement */
bool not_null_compl;/* true before null complement is added */ bool not_null_compl;/**< true before null complement is added */
st_join_table *last_inner; /* last table table for embedding outer join */ st_join_table *last_inner; /**< last table table for embedding outer join */
st_join_table *first_upper; /* first inner table for embedding outer join */ st_join_table *first_upper; /**< first inner table for embedding outer join */
st_join_table *first_unmatched; /* used for optimization purposes only */ st_join_table *first_unmatched; /**< used for optimization purposes only */
/* Special content for EXPLAIN 'Extra' column or NULL if none */ /* Special content for EXPLAIN 'Extra' column or NULL if none */
const char *info; const char *info;
@ -168,10 +173,10 @@ typedef struct st_join_table {
Read_record_func save_read_first_record;/* to save read_first_record */ Read_record_func save_read_first_record;/* to save read_first_record */
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */ int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
double worst_seeks; double worst_seeks;
key_map const_keys; /* Keys with constant part */ key_map const_keys; /**< Keys with constant part */
key_map checked_keys; /* Keys checked in find_best */ key_map checked_keys; /**< Keys checked in find_best */
key_map needed_reg; key_map needed_reg;
key_map keys; /* all keys with can be used */ key_map keys; /**< all keys with can be used */
/* Either #rows in the table or 1 for const table. */ /* Either #rows in the table or 1 for const table. */
ha_rows records; ha_rows records;
@ -189,7 +194,7 @@ typedef struct st_join_table {
table_map dependent,key_dependent; table_map dependent,key_dependent;
uint use_quick,index; uint use_quick,index;
uint status; // Save status for cache uint status; ///< Save status for cache
uint used_fields,used_fieldlength,used_blobs; uint used_fields,used_fieldlength,used_blobs;
enum join_type type; enum join_type type;
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
@ -203,7 +208,7 @@ typedef struct st_join_table {
TABLE_REF ref; TABLE_REF ref;
JOIN_CACHE cache; JOIN_CACHE cache;
JOIN *join; JOIN *join;
/* Bitmap of nested joins this table is part of */ /** Bitmap of nested joins this table is part of */
nested_join_map embedding_map; nested_join_map embedding_map;
void cleanup(); void cleanup();
@ -220,7 +225,7 @@ enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
end_of_records); end_of_records);
/* /**
Information about a position of table within a join order. Used in join Information about a position of table within a join order. Used in join
optimization. optimization.
*/ */
@ -264,25 +269,25 @@ typedef struct st_rollup
class JOIN :public Sql_alloc class JOIN :public Sql_alloc
{ {
JOIN(const JOIN &rhs); /* not implemented */ JOIN(const JOIN &rhs); /**< not implemented */
JOIN& operator=(const JOIN &rhs); /* not implemented */ JOIN& operator=(const JOIN &rhs); /**< not implemented */
public: public:
JOIN_TAB *join_tab,**best_ref; JOIN_TAB *join_tab,**best_ref;
JOIN_TAB **map2table; // mapping between table indexes and JOIN_TABs JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
TABLE **table,**all_tables,*sort_by_table; TABLE **table,**all_tables,*sort_by_table;
uint tables,const_tables; uint tables,const_tables;
uint send_group_parts; uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update; bool sort_and_group,first_record,full_join,group, no_field_update;
bool do_send_rows; bool do_send_rows;
/* /**
TRUE when we want to resume nested loop iterations when TRUE when we want to resume nested loop iterations when
fetching data from a cursor fetching data from a cursor
*/ */
bool resume_nested_loop; bool resume_nested_loop;
table_map const_table_map,found_const_table_map,outer_join; table_map const_table_map,found_const_table_map,outer_join;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit; ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/* /**
Used to fetch no more than given amount of rows per one Used to fetch no more than given amount of rows per one
fetch operation of server side cursor. fetch operation of server side cursor.
The value is checked in end_send and end_send_group in fashion, similar The value is checked in end_send and end_send_group in fashion, similar
@ -294,7 +299,7 @@ public:
ha_rows fetch_limit; ha_rows fetch_limit;
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
/* /* *
Bitmap of nested joins embedding the position at the end of the current Bitmap of nested joins embedding the position at the end of the current
partial join (valid only during join optimizer run). partial join (valid only during join optimizer run).
*/ */
@ -304,25 +309,25 @@ public:
List<Item> *fields; List<Item> *fields;
List<Cached_item> group_fields, group_fields_cache; List<Cached_item> group_fields, group_fields_cache;
TABLE *tmp_table; TABLE *tmp_table;
// used to store 2 possible tmp table of SELECT /// used to store 2 possible tmp table of SELECT
TABLE *exec_tmp_table1, *exec_tmp_table2; TABLE *exec_tmp_table1, *exec_tmp_table2;
THD *thd; THD *thd;
Item_sum **sum_funcs, ***sum_funcs_end; Item_sum **sum_funcs, ***sum_funcs_end;
/* second copy of sumfuncs (for queries with 2 temporary tables */ /** second copy of sumfuncs (for queries with 2 temporary tables */
Item_sum **sum_funcs2, ***sum_funcs_end2; Item_sum **sum_funcs2, ***sum_funcs_end2;
Procedure *procedure; Procedure *procedure;
Item *having; Item *having;
Item *tmp_having; // To store having when processed temporary table Item *tmp_having; ///< To store having when processed temporary table
Item *having_history; // Store having for explain Item *having_history; ///< Store having for explain
ulonglong select_options; ulonglong select_options;
select_result *result; select_result *result;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
// unit structure (with global parameters) for this select /// unit structure (with global parameters) for this select
SELECT_LEX_UNIT *unit; SELECT_LEX_UNIT *unit;
// select that processed /// select that processed
SELECT_LEX *select_lex; SELECT_LEX *select_lex;
/* /**
TRUE <=> optimizer must not mark any table as a constant table. TRUE <=> optimizer must not mark any table as a constant table.
This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..): This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
when we optimize the select that reads the results of the union from a when we optimize the select that reads the results of the union from a
@ -331,11 +336,11 @@ public:
*/ */
bool no_const_tables; bool no_const_tables;
JOIN *tmp_join; // copy of this JOIN to be used with temporary tables JOIN *tmp_join; ///< copy of this JOIN to be used with temporary tables
ROLLUP rollup; // Used with rollup ROLLUP rollup; ///< Used with rollup
bool select_distinct; // Set if SELECT DISTINCT bool select_distinct; ///< Set if SELECT DISTINCT
/* /**
If we have the GROUP BY statement in the query, If we have the GROUP BY statement in the query,
but the group_list was emptied by optimizer, this but the group_list was emptied by optimizer, this
flag is TRUE. flag is TRUE.
@ -350,42 +355,42 @@ public:
It's also set if ORDER/GROUP BY is empty. It's also set if ORDER/GROUP BY is empty.
*/ */
bool simple_order, simple_group; bool simple_order, simple_group;
/* /**
Is set only in case if we have a GROUP BY clause Is set only in case if we have a GROUP BY clause
and no ORDER BY after constant elimination of 'order'. and no ORDER BY after constant elimination of 'order'.
*/ */
bool no_order; bool no_order;
/* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ /** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
bool skip_sort_order; bool skip_sort_order;
bool need_tmp, hidden_group_fields; bool need_tmp, hidden_group_fields;
DYNAMIC_ARRAY keyuse; DYNAMIC_ARRAY keyuse;
Item::cond_result cond_value, having_value; Item::cond_result cond_value, having_value;
List<Item> all_fields; // to store all fields that used in query List<Item> all_fields; ///< to store all fields that used in query
//Above list changed to use temporary table ///Above list changed to use temporary table
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3; List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
//Part, shared with list above, emulate following list ///Part, shared with list above, emulate following list
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3; List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
List<Item> &fields_list; // hold field list passed to mysql_select List<Item> &fields_list; ///< hold field list passed to mysql_select
List<Item> procedure_fields_list; List<Item> procedure_fields_list;
int error; int error;
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
COND *conds; // ---"--- COND *conds; // ---"---
Item *conds_history; // store WHERE for explain Item *conds_history; // store WHERE for explain
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select TABLE_LIST *tables_list; ///<hold 'tables' parameter of mysql_select
List<TABLE_LIST> *join_list; // list of joined tables in reverse order List<TABLE_LIST> *join_list; ///< list of joined tables in reverse order
COND_EQUAL *cond_equal; COND_EQUAL *cond_equal;
SQL_SELECT *select; //created in optimisation phase SQL_SELECT *select; ///<created in optimisation phase
JOIN_TAB *return_tab; //used only for outer joins JOIN_TAB *return_tab; ///<used only for outer joins
Item **ref_pointer_array; //used pointer reference for this select Item **ref_pointer_array; ///<used pointer reference for this select
// Copy of above to be used with different lists // Copy of above to be used with different lists
Item **items0, **items1, **items2, **items3, **current_ref_pointer_array; Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
uint ref_pointer_array_size; // size of above in bytes uint ref_pointer_array_size; ///< size of above in bytes
const char *zero_result_cause; // not 0 if exec must return zero result const char *zero_result_cause; ///< not 0 if exec must return zero result
bool union_part; // this subselect is part of union bool union_part; ///< this subselect is part of union
bool optimized; // flag to avoid double optimization in EXPLAIN bool optimized; ///< flag to avoid double optimization in EXPLAIN
/* /*
storage for caching buffers allocated during query execution. storage for caching buffers allocated during query execution.
@ -494,14 +499,14 @@ public:
int rollup_send_data(uint idx); int rollup_send_data(uint idx);
int rollup_write_data(uint idx, TABLE *table); int rollup_write_data(uint idx, TABLE *table);
void remove_subq_pushed_predicates(Item **where); void remove_subq_pushed_predicates(Item **where);
/* /**
Release memory and, if possible, the open tables held by this execution Release memory and, if possible, the open tables held by this execution
plan (and nested plans). It's used to release some tables before plan (and nested plans). It's used to release some tables before
the end of execution in order to increase concurrency and reduce the end of execution in order to increase concurrency and reduce
memory consumption. memory consumption.
*/ */
void join_free(); void join_free();
/* Cleanup this JOIN, possibly for reuse */ /** Cleanup this JOIN, possibly for reuse */
void cleanup(bool full); void cleanup(bool full);
void clear(); void clear();
bool save_join_tab(); bool save_join_tab();
@ -556,7 +561,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
/* from sql_delete.cc, used by opt_range.cc */ /* from sql_delete.cc, used by opt_range.cc */
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b); extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
/* class to copying an field/item to a key struct */ /** class to copying an field/item to a key struct */
class store_key :public Sql_alloc class store_key :public Sql_alloc
{ {
@ -582,7 +587,7 @@ public:
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table, to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
ptr, null, 1); ptr, null, 1);
} }
virtual ~store_key() {} /* Not actually needed */ virtual ~store_key() {} /** Not actually needed */
virtual const char *name() const=0; virtual const char *name() const=0;
/** /**

View file

@ -168,7 +168,7 @@ static const LEX_STRING triggers_file_type=
const char * const TRG_EXT= ".TRG"; const char * const TRG_EXT= ".TRG";
/* /**
Table of .TRG file field descriptors. Table of .TRG file field descriptors.
We have here only one field now because in nearest future .TRG We have here only one field now because in nearest future .TRG
files will be merged into .FRM files (so we don't need something files will be merged into .FRM files (so we don't need something
@ -216,7 +216,7 @@ File_option sql_modes_parameters=
FILE_OPTIONS_ULLLIST FILE_OPTIONS_ULLLIST
}; };
/* /**
This must be kept up to date whenever a new option is added to the list This must be kept up to date whenever a new option is added to the list
above, as it specifies the number of required parameters of the trigger in above, as it specifies the number of required parameters of the trigger in
.trg file. .trg file.
@ -292,23 +292,27 @@ private:
}; };
/* /**
Create or drop trigger for table. Create or drop trigger for table.
SYNOPSIS @param thd current thread context (including trigger definition in LEX)
mysql_create_or_drop_trigger() @param tables table list containing one table for which trigger is created.
thd - current thread context (including trigger definition in LEX) @param create whenever we create (TRUE) or drop (FALSE) trigger
tables - table list containing one table for which trigger is created.
create - whenever we create (TRUE) or drop (FALSE) trigger
NOTE @note
This function is mainly responsible for opening and locking of table and This function is mainly responsible for opening and locking of table and
invalidation of all its instances in table cache after trigger creation. invalidation of all its instances in table cache after trigger creation.
Real work on trigger creation/dropping is done inside Table_triggers_list Real work on trigger creation/dropping is done inside Table_triggers_list
methods. methods.
RETURN VALUE @todo
TODO: We should check if user has TRIGGER privilege for table here.
Now we just require SUPER privilege for creating/dropping because
we don't have proper privilege checking for triggers in place yet.
@retval
FALSE Success FALSE Success
@retval
TRUE error TRUE error
*/ */
bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
@ -518,29 +522,28 @@ end:
} }
/* /**
Create trigger for table. Create trigger for table.
SYNOPSIS @param thd current thread context (including trigger definition in
create_trigger() LEX)
thd - current thread context (including trigger definition in @param tables table list containing one open table for which the
LEX) trigger is created.
tables - table list containing one open table for which the @param[out] stmt_query after successful return, this string contains
trigger is created. well-formed statement for creation this trigger.
stmt_query - [OUT] after successful return, this string contains
well-formed statement for creating this trigger.
NOTE @note
- Assumes that trigger name is fully qualified. - Assumes that trigger name is fully qualified.
- NULL-string means the following LEX_STRING instance: - NULL-string means the following LEX_STRING instance:
{ str = 0; length = 0 }. { str = 0; length = 0 }.
- In other words, definer_user and definer_host should contain - In other words, definer_user and definer_host should contain
simultaneously NULL-strings (non-SUID/old trigger) or valid strings simultaneously NULL-strings (non-SUID/old trigger) or valid strings
(SUID/new trigger). (SUID/new trigger).
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
String *stmt_query) String *stmt_query)
@ -806,19 +809,18 @@ err_with_cleanup:
} }
/* /**
Deletes the .TRG file for a table Deletes the .TRG file for a table.
SYNOPSIS @param path char buffer of size FN_REFLEN to be used
rm_trigger_file() for constructing path to .TRG file.
path - char buffer of size FN_REFLEN to be used @param db table's database name
for constructing path to .TRG file. @param table_name table's name
db - table's database name
table_name - table's name
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
static bool rm_trigger_file(char *path, const char *db, static bool rm_trigger_file(char *path, const char *db,
@ -829,19 +831,18 @@ static bool rm_trigger_file(char *path, const char *db,
} }
/* /**
Deletes the .TRN file for a trigger Deletes the .TRN file for a trigger.
SYNOPSIS @param path char buffer of size FN_REFLEN to be used
rm_trigname_file() for constructing path to .TRN file.
path - char buffer of size FN_REFLEN to be used @param db trigger's database name
for constructing path to .TRN file. @param table_name trigger's name
db - trigger's database name
table_name - trigger's name
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
static bool rm_trigname_file(char *path, const char *db, static bool rm_trigname_file(char *path, const char *db,
@ -852,17 +853,16 @@ static bool rm_trigname_file(char *path, const char *db,
} }
/* /**
Helper function that saves .TRG file for Table_triggers_list object. Helper function that saves .TRG file for Table_triggers_list object.
SYNOPSIS @param triggers Table_triggers_list object for which file should be saved
save_trigger_file() @param db Name of database for subject table
triggers Table_triggers_list object for which file should be saved @param table_name Name of subject table
db Name of database for subject table
table_name Name of subject table
RETURN VALUE @retval
FALSE Success FALSE Success
@retval
TRUE Error TRUE Error
*/ */
@ -881,21 +881,26 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
} }
/* /**
Drop trigger for table. Drop trigger for table.
SYNOPSIS @param thd current thread context
drop_trigger() (including trigger definition in LEX)
thd - current thread context @param tables table list containing one open table for which trigger
(including trigger definition in LEX) is dropped.
tables - table list containing one open table for which trigger @param[out] stmt_query after successful return, this string contains
is dropped. well-formed statement for creation this trigger.
stmt_query - [OUT] after successful return, this string contains
well-formed statement for deleting this trigger.
RETURN VALUE @todo
False - success Probably instead of removing .TRG file we should move
True - error to archive directory but this should be done as part of
parse_file.cc functionality (because we will need it
elsewhere).
@retval
False success
@retval
True error
*/ */
bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables, bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
String *stmt_query) String *stmt_query)
@ -978,18 +983,17 @@ Table_triggers_list::~Table_triggers_list()
} }
/* /**
Prepare array of Field objects referencing to TABLE::record[1] instead Prepare array of Field objects referencing to TABLE::record[1] instead
of record[0] (they will represent OLD.* row values in ON UPDATE trigger of record[0] (they will represent OLD.* row values in ON UPDATE trigger
and in ON DELETE trigger which will be called during REPLACE execution). and in ON DELETE trigger which will be called during REPLACE execution).
SYNOPSIS @param table pointer to TABLE object for which we are creating fields.
prepare_record1_accessors()
table - pointer to TABLE object for which we are creating fields.
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
bool Table_triggers_list::prepare_record1_accessors(TABLE *table) bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
{ {
@ -1018,12 +1022,10 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
} }
/* /**
Adjust Table_triggers_list with new TABLE pointer. Adjust Table_triggers_list with new TABLE pointer.
SYNOPSIS @param new_table new pointer to TABLE instance
set_table()
new_table - new pointer to TABLE instance
*/ */
void Table_triggers_list::set_table(TABLE *new_table) void Table_triggers_list::set_table(TABLE *new_table)
@ -1037,20 +1039,26 @@ void Table_triggers_list::set_table(TABLE *new_table)
} }
/* /**
Check whenever .TRG file for table exist and load all triggers it contains. Check whenever .TRG file for table exist and load all triggers it contains.
SYNOPSIS @param thd current thread context
check_n_load() @param db table's database name
thd - current thread context @param table_name table's name
db - table's database name @param table pointer to table object
table_name - table's name @param names_only stop after loading trigger names
table - pointer to table object
names_only - stop after loading trigger names
RETURN VALUE @todo
False - success A lot of things to do here e.g. how about other funcs and being
True - error more paranoical ?
@todo
This could be avoided if there is no triggers for UPDATE and DELETE.
@retval
False success
@retval
True error
*/ */
bool Table_triggers_list::check_n_load(THD *thd, const char *db, bool Table_triggers_list::check_n_load(THD *thd, const char *db,
@ -1433,24 +1441,23 @@ err_with_lex_cleanup:
} }
/* /**
Obtains and returns trigger metadata Obtains and returns trigger metadata.
SYNOPSIS @param thd current thread context
get_trigger_info() @param event trigger event type
thd - current thread context @param time_type trigger action time
event - trigger event type @param trigger_name returns name of trigger
time_type - trigger action time @param trigger_stmt returns statement of trigger
name - returns name of trigger @param sql_mode returns sql_mode of trigger
stmt - returns statement of trigger @param definer returns definer/creator of trigger. The caller is
sql_mode - returns sql_mode of trigger responsible to allocate enough space for storing
definer_user - returns definer/creator of trigger. The caller is definer information.
responsible to allocate enough space for storing definer
information.
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event, bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
@ -1616,21 +1623,20 @@ bool add_table_for_trigger(THD *thd,
} }
/* /**
Drop all triggers for table. Drop all triggers for table.
SYNOPSIS @param thd current thread context
drop_all_triggers() @param db schema for table
thd - current thread context @param name name for table
db - schema for table
name - name for table
NOTE @note
The calling thread should hold the LOCK_open mutex; The calling thread should hold the LOCK_open mutex;
RETURN VALUE @retval
False - success False success
True - error @retval
True error
*/ */
bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
@ -1680,19 +1686,18 @@ end:
} }
/* /**
Update .TRG file after renaming triggers' subject table Update .TRG file after renaming triggers' subject table
(change name of table in triggers' definitions). (change name of table in triggers' definitions).
SYNOPSIS @param thd Thread context
change_table_name_in_triggers() @param db_name Database of subject table
thd Thread context @param old_table_name Old subject table's name
db_name Database of subject table @param new_table_name New subject table's name
old_table_name Old subject table's name
new_table_name New subject table's name
RETURN VALUE @retval
FALSE Success FALSE Success
@retval
TRUE Failure TRUE Failure
*/ */
@ -1762,21 +1767,20 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
} }
/* /**
Iterate though Table_triggers_list::names_list list and update .TRN files Iterate though Table_triggers_list::names_list list and update
after renaming triggers' subject table. .TRN files after renaming triggers' subject table.
SYNOPSIS @param db_name Database of subject table
change_table_name_in_trignames() @param new_table_name New subject table's name
db_name Database of subject table @param stopper Pointer to Table_triggers_list::names_list at
new_table_name New subject table's name which we should stop updating.
stopper Pointer to Table_triggers_list::names_list at
which we should stop updating.
RETURN VALUE @retval
0 Success 0 Success
@retval
non-0 Failure, pointer to Table_triggers_list::names_list element non-0 Failure, pointer to Table_triggers_list::names_list element
for which update failed. for which update failed.
*/ */
LEX_STRING* LEX_STRING*
@ -1810,7 +1814,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
/** /**
@brief Update .TRG and .TRN files after renaming triggers' subject table. Update .TRG and .TRN files after renaming triggers' subject table.
@param[in,out] thd Thread context @param[in,out] thd Thread context
@param[in] db Old database of subject table @param[in] db Old database of subject table
@ -1972,19 +1976,17 @@ bool Table_triggers_list::process_triggers(THD *thd,
} }
/* /**
Mark fields of subject table which we read/set in its triggers as such. Mark fields of subject table which we read/set in its triggers
as such.
SYNOPSIS This method marks fields of subject table which are read/set in its
mark_fields_used() triggers as such (by properly updating TABLE::read_set/write_set)
thd Current thread context and thus informs handler that values for these fields should be
event Type of event triggers for which we are going to ins retrieved/stored during execution of statement.
DESCRIPTION @param thd Current thread context
This method marks fields of subject table which are read/set in its @param event Type of event triggers for which we are going to inspect
triggers as such (by properly updating TABLE::read_set/write_set)
and thus informs handler that values for these fields should be
retrieved/stored during execution of statement.
*/ */
void Table_triggers_list::mark_fields_used(trg_event_type event) void Table_triggers_list::mark_fields_used(trg_event_type event)
@ -2010,23 +2012,23 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
} }
/* /**
Trigger BUG#14090 compatibility hook Trigger BUG#14090 compatibility hook.
SYNOPSIS @param[in,out] unknown_key reference on the line with unknown
Handle_old_incorrect_sql_modes_hook::process_unknown_string() parameter and the parsing point
unknown_key [in/out] reference on the line with unknown @param[in] base base address for parameter writing
parameter and the parsing point (structure like TABLE)
base [in] base address for parameter writing (structure @param[in] mem_root MEM_ROOT for parameters allocation
like TABLE) @param[in] end the end of the configuration
mem_root [in] MEM_ROOT for parameters allocation
end [in] the end of the configuration
NOTE: this hook process back compatibility for incorrectly written @note
sql_modes parameter (see BUG#14090). NOTE: this hook process back compatibility for incorrectly written
sql_modes parameter (see BUG#14090).
RETURN @retval
FALSE OK FALSE OK
@retval
TRUE Error TRUE Error
*/ */
@ -2068,13 +2070,12 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/* #define INVALID_TRIGGER_TABLE_LENGTH 15
/**
Trigger BUG#15921 compatibility hook. For details see Trigger BUG#15921 compatibility hook. For details see
Handle_old_incorrect_sql_modes_hook::process_unknown_string(). Handle_old_incorrect_sql_modes_hook::process_unknown_string().
*/ */
#define INVALID_TRIGGER_TABLE_LENGTH 15
bool bool
Handle_old_incorrect_trigger_table_hook:: Handle_old_incorrect_trigger_table_hook::
process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root, process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
@ -2113,9 +2114,9 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
/** /**
Contruct path to TRN-file. Contruct path to TRN-file.
@param[in] thd Thread context. @param thd[in] Thread context.
@param[in] trg_name Trigger name. @param trg_name[in] Trigger name.
@param[out] trn_path Variable to store constructed path @param trn_path[out] Variable to store constructed path
*/ */
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path) void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
@ -2148,10 +2149,10 @@ bool check_trn_exists(const LEX_STRING *trn_path)
/** /**
Retrieve table name for given trigger. Retrieve table name for given trigger.
@param[in] thd Thread context. @param thd[in] Thread context.
@param[in] trg_name Trigger name. @param trg_name[in] Trigger name.
@param[in] trn_path Path to the corresponding TRN-file. @param trn_path[in] Path to the corresponding TRN-file.
@param[out] tbl_name Variable to store retrieved table name. @param tbl_name[out] Variable to store retrieved table name.
@return Error status. @return Error status.
@retval FALSE on success. @retval FALSE on success.

View file

@ -14,7 +14,7 @@
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 class holds all information about triggers of table. This class holds all information about triggers of table.
QQ: Will it be merged into TABLE in the future ? QQ: Will it be merged into TABLE in the future ?
@ -22,20 +22,20 @@
class Table_triggers_list: public Sql_alloc class Table_triggers_list: public Sql_alloc
{ {
/* Triggers as SPs grouped by event, action_time */ /** Triggers as SPs grouped by event, action_time */
sp_head *bodies[TRG_EVENT_MAX][TRG_ACTION_MAX]; sp_head *bodies[TRG_EVENT_MAX][TRG_ACTION_MAX];
/* /**
Heads of the lists linking items for all fields used in triggers Heads of the lists linking items for all fields used in triggers
grouped by event and action_time. grouped by event and action_time.
*/ */
Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX]; Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX];
/* /**
Copy of TABLE::Field array with field pointers set to TABLE::record[1] Copy of TABLE::Field array with field pointers set to TABLE::record[1]
buffer instead of TABLE::record[0] (used for OLD values in on UPDATE buffer instead of TABLE::record[0] (used for OLD values in on UPDATE
trigger and DELETE trigger when it is called for REPLACE). trigger and DELETE trigger when it is called for REPLACE).
*/ */
Field **record1_field; Field **record1_field;
/* /**
During execution of trigger new_field and old_field should point to the During execution of trigger new_field and old_field should point to the
array of fields representing new or old version of row correspondingly array of fields representing new or old version of row correspondingly
(so it can point to TABLE::field or to Tale_triggers_list::record1_field) (so it can point to TABLE::field or to Tale_triggers_list::record1_field)
@ -45,30 +45,30 @@ class Table_triggers_list: public Sql_alloc
/* TABLE instance for which this triggers list object was created */ /* TABLE instance for which this triggers list object was created */
TABLE *trigger_table; TABLE *trigger_table;
/* /**
Names of triggers. Names of triggers.
Should correspond to order of triggers on definitions_list, Should correspond to order of triggers on definitions_list,
used in CREATE/DROP TRIGGER for looking up trigger by name. used in CREATE/DROP TRIGGER for looking up trigger by name.
*/ */
List<LEX_STRING> names_list; List<LEX_STRING> names_list;
/* /**
List of "ON table_name" parts in trigger definitions, used for List of "ON table_name" parts in trigger definitions, used for
updating trigger definitions during RENAME TABLE. updating trigger definitions during RENAME TABLE.
*/ */
List<LEX_STRING> on_table_names_list; List<LEX_STRING> on_table_names_list;
/* /**
Grant information for each trigger (pair: subject table, trigger definer). Grant information for each trigger (pair: subject table, trigger definer).
*/ */
GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX]; GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
public: public:
/* /**
Field responsible for storing triggers definitions in file. Field responsible for storing triggers definitions in file.
It have to be public because we are using it directly from parser. It have to be public because we are using it directly from parser.
*/ */
List<LEX_STRING> definitions_list; List<LEX_STRING> definitions_list;
/* /**
List of sql modes for triggers List of sql modes for triggers
*/ */
List<ulonglong> definition_modes_list; List<ulonglong> definition_modes_list;

View file

@ -84,7 +84,7 @@ static bool check_fields(THD *thd, List<Item> &items)
/** /**
@brief Re-read record if more columns are needed for error message. Re-read record if more columns are needed for error message.
If we got a duplicate key error, we want to write an error If we got a duplicate key error, we want to write an error
message containing the value of the duplicate key. If we do not have message containing the value of the duplicate key. If we do not have

View file

@ -206,7 +206,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
/** /**
@brief Creating/altering VIEW procedure Creating/altering VIEW procedure
@param thd thread handler @param thd thread handler
@param views views to create @param views views to create

View file

@ -209,7 +209,7 @@ typedef struct user_conn {
char *user; char *user;
/* Pointer to host part of the key. */ /* Pointer to host part of the key. */
char *host; char *host;
/* /**
The moment of time when per hour counters were reset last time The moment of time when per hour counters were reset last time
(i.e. start of "hour" for conn_per_hour, updates, questions counters). (i.e. start of "hour" for conn_per_hour, updates, questions counters).
*/ */

View file

@ -20,7 +20,7 @@
#if !defined(TESTTIME) && !defined(TZINFO2SQL) #if !defined(TESTTIME) && !defined(TZINFO2SQL)
/* /**
This class represents abstract time zone and provides This class represents abstract time zone and provides
basic interface for MYSQL_TIME <-> my_time_t conversion. basic interface for MYSQL_TIME <-> my_time_t conversion.
Actual time zones which are specified by DB, or via offset Actual time zones which are specified by DB, or via offset
@ -30,7 +30,7 @@ class Time_zone: public Sql_alloc
{ {
public: public:
Time_zone() {} /* Remove gcc warning */ Time_zone() {} /* Remove gcc warning */
/* /**
Converts local time in broken down MYSQL_TIME representation to Converts local time in broken down MYSQL_TIME representation to
my_time_t (UTC seconds since Epoch) represenation. my_time_t (UTC seconds since Epoch) represenation.
Returns 0 in case of error. Sets in_dst_time_gap to true if date provided Returns 0 in case of error. Sets in_dst_time_gap to true if date provided
@ -38,19 +38,19 @@ public:
*/ */
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const = 0; my_bool *in_dst_time_gap) const = 0;
/* /**
Converts time in my_time_t representation to local time in Converts time in my_time_t representation to local time in
broken down MYSQL_TIME representation. broken down MYSQL_TIME representation.
*/ */
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0; virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0;
/* /**
Because of constness of String returned by get_name() time zone name Because of constness of String returned by get_name() time zone name
have to be already zeroended to be able to use String::ptr() instead have to be already zeroended to be able to use String::ptr() instead
of c_ptr(). of c_ptr().
*/ */
virtual const String * get_name() const = 0; virtual const String * get_name() const = 0;
/* /**
We need this only for surpressing warnings, objects of this type are We need this only for surpressing warnings, objects of this type are
allocated on MEM_ROOT and should not require destruction. allocated on MEM_ROOT and should not require destruction.
*/ */
@ -65,7 +65,7 @@ extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool
extern void my_tz_free(); extern void my_tz_free();
extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t); extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
/* /**
Number of elements in table list produced by my_tz_get_table_list() Number of elements in table list produced by my_tz_get_table_list()
(this table list contains tables which are needed for dynamical loading (this table list contains tables which are needed for dynamical loading
of time zone descriptions). Actually it is imlementation detail that of time zone descriptions). Actually it is imlementation detail that

View file

@ -155,34 +155,34 @@
#define OPEN_VIEW 8192 /* Allow open on view */ #define OPEN_VIEW 8192 /* Allow open on view */
#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view, #define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view,
but do not parse view itself */ but do not parse view itself */
/* /**
This flag is used in function get_all_tables() which fills This flag is used in function get_all_tables() which fills
I_S tables with data which are retrieved from frm files and storage engine I_S tables with data which are retrieved from frm files and storage engine
The flag means that we need to open FRM file only to get necessary data. The flag means that we need to open FRM file only to get necessary data.
*/ */
#define OPEN_FRM_FILE_ONLY 32768 #define OPEN_FRM_FILE_ONLY 32768
/* /**
This flag is used in function get_all_tables() which fills This flag is used in function get_all_tables() which fills
I_S tables with data which are retrieved from frm files and storage engine I_S tables with data which are retrieved from frm files and storage engine
The flag means that we need to process tables only to get necessary data. The flag means that we need to process tables only to get necessary data.
Views are not processed. Views are not processed.
*/ */
#define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2 #define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2
/* /**
This flag is used in function get_all_tables() which fills This flag is used in function get_all_tables() which fills
I_S tables with data which are retrieved from frm files and storage engine I_S tables with data which are retrieved from frm files and storage engine
The flag means that we need to process views only to get necessary data. The flag means that we need to process views only to get necessary data.
Tables are not processed. Tables are not processed.
*/ */
#define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2 #define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2
/* /**
This flag is used in function get_all_tables() which fills This flag is used in function get_all_tables() which fills
I_S tables with data which are retrieved from frm files and storage engine. I_S tables with data which are retrieved from frm files and storage engine.
The flag means that we need to open a view using The flag means that we need to open a view using
open_normal_and_derived_tables() function. open_normal_and_derived_tables() function.
*/ */
#define OPEN_VIEW_FULL OPEN_VIEW_ONLY*2 #define OPEN_VIEW_FULL OPEN_VIEW_ONLY*2
/* /**
This flag is used in function get_all_tables() which fills This flag is used in function get_all_tables() which fills
I_S tables with data which are retrieved from frm files and storage engine. I_S tables with data which are retrieved from frm files and storage engine.
The flag means that I_S table uses optimization algorithm. The flag means that I_S table uses optimization algorithm.